Java pwn_2020网鼎杯部分WEB&&PWN题解

今年网鼎杯不说啥了,没打进前130,我是菜B比不过各位师傅

274f9bea6f76ca8db01ab4a2605fb196.png

本文包括四场网鼎的部分WEB和PWN,本着菜鸡应该多练习的原则四场都看了看,除第一场外均为复现。

青龙组

PWN-boom1

2e250b8ec3752c16ec1d835193848633.png

[*] '/home/Railgun/Desktop/2020wdb/pwn1'

Arch: amd64-64-little

RELRO: Full RELRO

Stack: Canary found

NX: NX enabled

PIE: PIE enabled

86a87969320505b25ed5524a663e1a65.png

有点复杂,但是大概是实现了一个编译器的功能,有点像这个

c9fd6f4f1efbfa722d5b2a3538793584.png

但是可以看到全局变量限制了次数,只能用一个函数,并且只有一次机会。

思路:定义变量,调出变量相对于free_hook、libc_base偏移,定义另一个变量地址为free_hook,然后覆写为one_shot即可。

版本是libc-2.23,但是好像不同2.23的libc中偏移也稍微有点差别。

7bca0fc7ba242a13a9169b6f79bf6345.png

关于变量地址,printf调试下断在这里即可。

e25a37e406b2d57b55e6eeec44dd9cc6.png

计算libc_base以及free_hook即可。

f52829c5d0e724edeb7036a63c016bc7.png

我本地强加libc同pwndbg调试的有点问题,但是最后用pwngdb还是可以调出来的。

PWN-boom2

64c701173782047ef95aadfa6d1e32dc.png

又是一个VM PWN,下面大概可以看出模拟了栈,上图部分是栈的初始化,一个用chunk来存储指令,一个用来模拟栈,其中v3为模拟栈,看到模拟栈底(stack_bp )指向30(0x1e),stack_bp – 1指向13(0xd)。同时可以看出v37=v3,v37也就是stack+0x8000,在栈最底部(stack_bp + 1)。

总觉得干看有点复杂,调试看一下。

9e699cc21c90fbad2a36727f81b99bf2.png真实栈

上图是输入指令14后模拟栈初始化完成后的真实栈,对比一下:

d92bb4666eb8be62ffa6a2e425f47468.png

34cfc1e0af17255219a076da31e5270e.png模拟栈

真实栈中的buf确实存储了14,以它为基准且同时分析代码可以确定:

v37--->stack_bp

var_38(v36)--->stack_sp(根据每次stack都--并且最后再-1确定为sp) ---> stack_bp - 4

stack_bp - 1 = 0x1e

stack_bp - 2 = 0xd

stack_bp - 3 = 0

stack_bp - 4 = 真实栈地址

5098973343cf3ca53bc869953abcd6f5.png

接着就分析下面的具体的指令,我是结合代码和动态调试确定功能。

菜鸡第一次分析这种,如果有错误请各位师傅斧正:

ee23b1322a1f9418b6d378cb0b3c4766.png

365df71378b6293679421b8749e230e8.png

ec24b789c5b325ca34dda46315fa8da7.png

30d1048522e3b60d7aa2e01c1670ebc8.png

动调观察真实栈、虚拟栈并结合代码分析得出如上结果(其中command 11为leave ret).

后补,觉得应该给出一个调试例,以11为例把:

2b96810ba58b12c40389b5a9cfb9e84c.png

给出此时真实栈与虚拟栈环境,此时是刚刚通过指令25计算出one_gadget地址。

28419e390f25f4db0b6cc318ca616584.png

55b7e08cb3637ef703476153ff7a6228.png

可以看到,此时是取出了sp的值也就是刚刚使sp指向栈上libc_start_main的地址(ret)给RAX。

然后把RAX给了RDX

43ae1bfcb0c5fa27f29639ac01889132.png

可以看到RDX此时就是ret了,接下来是将rbp – 0x28处地址的值(one_gadget)赋给rax:

6357384e7c3ace14ce6c5068a864cfa9.png

再然后就是将RAX的值赋给RDX指向的地址,也就是完成了把one_gadget写入ret的操作。

思考如何利用,再看一下初始化后虚拟栈环境。

74bf83c90b350f2a3a4fa5dd0ddae130.png

可以看到,初始化完成后的虚拟栈sp指向0x7ffff7fd8fe8,而0x7ffff7fd8ff0处有存放着一个真实栈的地址,而真实栈上存在__libc_start_main+offset,我们虽然不能打印,但是可以运算,考虑把这个真实栈的地址经过运算变为指向libc_start_main的地址。

先pop一下,令sp指向真实栈地址然后使其减0xe8(相对libc_start_main):

b7f7165895032a9c97126c54cbc475db.png

pwndbg> distance 0x00007fffffffdd80 0x7fffffffdc98

0x7fffffffdd80->0x7fffffffdc98 is -0xe8 bytes (-0x1d words)

使用指令1令v38为0xe8,再用指令26让sp减0xe8,同时执行了pop,再用指令13执行push把刚才的地址再push进去。

d48048456240578abd8645699db3779f.png

可以看到虚拟栈sp指向了指向libc_start_main的地址(同时是ret地址)。

此时用指令9取得libc_start_main的地址,然后计算出偏移,指令1存储偏移,再用指令26让它减去偏移得到libc基地址,然后用13入栈,再用指令25使sp加one_gadget偏移,再用13入栈。

60deb8aa1e541e4389239885ecb62fe5.png此时sp指向了libc基地址

0d7604827fcf6c1f26617c558a2fe8f9.pngone_gadget入栈成功

现在我们拿到了one_gadget,考虑覆盖ret,使用指令11,发现出错了,后面看是不应该把one_gadget入虚拟栈。

04da2bee479e2ecf166338730bb75b17.png

总结就是这种题多调试。

PWN-fast0

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值