当前位置:首页|资讯

【pwn13 2022网鼎杯 boom1】

作者:K3yB0ard发布时间:2024-09-30

2022网鼎杯的一道pwn,好像是青龙组的赛题。后面还有一个boom2虚拟机。

首先看一下程序保护:

checksec

保护全开。

libc版本为2.23好像。

看一下程序逻辑:

main

main函数太长了,这里给出一部分,笔者认为像这样的题最主要的是去手动摸一摸程序逻辑,静态分析非常难看。直接手动fuzz。

可以知道程序是让我们输入一些东西,然后它去做一些事情。

rodata

看程序自带的一些字符串,也可以猜测出来,这应该是一个类似虚拟机的东西,并且注意到这里还有一个是main not defined的字符串,猜测可能是输入c语言源码去执行?

手动试一试;

fuzz1

可以看到,输入的代码被成功执行了。进一步手动fuzz,看看代码执行有没有限制:

fuzz2

尝试直接执行getshell,发现爆了bad function call。说明还不是什么函数都能用的。

进一步fuzz,其实可以发现,不管什么函数,代码中只能有一次函数调用存在,那样的话感觉shellcode也不好弄,可以考虑用malloc hook和free hook,这俩hook都是可以写的。

试一试这俩函数可以用不:

fuzz3

发现没有类似上面的报错,那么free是可以正常执行的,现在问题就是怎么找到free hook地址和system的地址了,试一下指针的使用:

fuzz4

这里随便定义一个变量,然后用printf打印出它的地址,在gdb看一下:

gdb vmmap

发现我们定义的局部变量实际上地址位于libc固定偏移段,这下好了,直接计算偏移即可得到free hook地址和system地址了

payload

计算并构造上述payload,借助我们的局部变量a,通过指针方式操作free hook,将其赋值为system地址。跑一下看看:

gdb error

发现程序寄了,出现了一个段错误,看到执行的这个汇编 ,这不就是我们的*(&__free_hook)=&system这个赋值操作吗,看到rdx和rax两个寄存器的地址都变为非法地址了。算一下看看怎么回事:

这里如果正确,我们的rdx应该是free hook地址,rax应该是system地址,算一下差多少

gdb 调试

发现实际上程序操作的地址,偏移变为了8倍,这里笔者认为是程序执行c语言的指针操作时,用了8字节对齐,那么我们把偏移全都除以8再试试。

payload
exp result

发现这次成功getshell。

重新理一下攻击思路:

1、由于程序过于复杂,通过一些字符串特征猜测出其为c语言源码执行的虚拟机。

2、手动fuzz看一下程序的源码执行都有哪些限制。例如不能直接system("/bin/sh")来getshell以及函数调用只能存在一次等等。此外,手动测试也通过printf泄露信息,发现程序中可以使用c语言指针,且定义的局部变量与libc地址存在固定偏移。

3、虚拟机的malloc和free可以使用,则考虑通过局部变量与libc地址有固定偏移入手,通过调试获取偏移,借助c语言指针实现修改__free_hook为system地址,最后直接free("/bin/sh")即可。 值得注意的是,指针偏移要以0x8为单位,相当于实际地址偏移除以8后的结果。

这种算是比较复杂的虚拟机,笔者自己认为手动fuzz去摸程序逻辑更好一点,一直静态分析可能也发现不了什么,像普通的虚拟机静态分析去得到opcode表啊这种,并且与程序交互也是输入opcode来执行虚拟机指令,那种会多画一些时间去静态分析。像这种题,包括一些自实现malloc、free的变种堆题,笔者认为都是要先手动fuzz,gdb调起来,看一下程序具体有哪些限制、内存布局如何,这比静态分析更加迅速地让pwn手摸清程序的逻辑和可能的漏洞。

明天更新boom2,也是一个虚拟机。

By  Del0n1x

Keyboard


Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1