[攻防世界]新手区get_shell和level3
get_shell
先说这个神奇的get_shell题,我实在想不明白为什么这道题可以值7分,我还以为是新手区的压轴题,万万没想到,它真就如题所说的那样,“运行就能拿到shell呢,真的”
IDA:
这个真的是运行就能拿到flag。。没任何坑
level3
这个题,拿到文件以后还给了个libc,估计是要自己计算system地址。
先查看文件信息及保护措施
32为IDA打开
既没有system,也没有/bin/sh或cat flag,但是有read和write,所以可以利用write泄露libc中system地址,并找到’/bin/sh’让system调用
接下来计算溢出需要的偏移,用gdb的pattern脚本生成200个字符,运行level3程序,直接输入200个字符
查看溢出点
利用pattern offset计算需要填充的字符数
即’a’*140
思路:
- 因为libc开着地址随机化,所以偏移会变化,必须在同一次运行内进行两次攻击,确保offset不变
- 第一次攻击,利用write函数,泄露其真实地址,通过计算得到libc加载的基地址
- 已知libc的基地址,计算system的真实地址和字符串’/bin/sh’的真实地址
- 第二次攻击,构造system(“/bin/sh”),拿到shell
- 拿到flag
计算公式:
libc加载的基地址 = write真实地址 - write在libc中的偏移量
system真实地址 = libc加载的基地址 + system在libc中的偏移量
/bin/sh真实地址 = libc加载的基地址 + /bin/sh在libc中的偏移量
其中 “/bin/sh在libc中的偏移量” 不知道为啥我用search查不到,所以我用winhex打开了libc,搜索字符串,得到0x159020+0xb,即0x15902b
EXP:
1 | from pwn import * |
payload0解释:
- ‘a’*140:用于填充,使栈溢出,上文用pattern offset计算出140
- p32(write_plt):write在plt表中的地址,让read完后进入write
- p32(main_addr):main函数地址,是write函数的返回地址,让write执行完后,返回main函数,这样就能进行第二次攻击
- p32(1):write函数的第一个参数
- p32(write_got):write函数的第二个参数,此为write要泄露的自身真实地址
- p32(4):write函数的第三个参数
payload1解释:
- ‘a’*140:用于填充,使栈溢出,上文用pattern offset计算出140
- p32(sys_addr):system的真实地址,让read完后进入system
- p32(0x1234):随便填充一个system的返回地址
- p32(bin_sh_addr):bin/sh的地址,当system参数