【CTF题解-0x01】mini-LCTF write up by arttnba3

0x00.绪论

mini-LCTF,前身是makerCTF,是西电校内享誉盛名(?)的CTF,作为菜鸡CTFer也尝试着参加了一手

因为咱主攻PWN的原因,所以这一篇应该只有PWN(

(不过主要还是因为我太菜了XD

0x01.Sign in

Starting Point

点进页面就可以直接获得flag了

0x02.PWN

hello

点击下载

证明了我真的是菜鸡的一道pwn题,搞了半天才明白XD

做题环境Manjaro-KDE

首先使用checksec指令查看保护,可以发现保护基本都是关的,只有Partial RELRO,那么基本上是可以为所欲为了wwww

1
2
3
4
5
6
7
8

![image.png](https://i.loli.net/2020/05/11/f4qnCg65NPxT2D9.png)

可以发现在```vul函数```存在明显的栈溢出

![image.png](https://i.loli.net/2020/05/11/67tk1FiacXVR8ou.png)

```main```函数中调用了```vul

image.png

那么程序漏洞很明显了:

  • 使用fgets读入最大为72个字节的字符串,但是只分配给了48字节的空间,存在栈溢出

又有一个可疑的bd函数,那么第一时间想到ret2text——构造payload跳转到bd

但是很明显,bd函数基本是是空的(悲)

image.png

然后我就在这里卡了半天,证明我真的菜XD,感谢cor1e大佬的耐心解答

那么我们该如何利用这个bd呢?

可以看到在bd中存在操作jmp rsp,那么其实我们可以利用这个指令跳转回栈上,执行我们放在栈上的shellcode

也就是说这其实是一道ret2shellcode的题

ret2text执行过程:

  • rsp永远指向栈顶

  • 当我们用常规的ret2text构造48字节字符串+8字节rbp+8字节bd函数地址(覆盖掉原返回地址)的payload时,rsp指向的其实是bd函数地址的位置

  • ret指令进入bd后弹出bd地址,rsp指向栈内储存的rbp的值(预期内)

  • bd函数将rbp再push入栈中,此时rsp再加8,指向被新压入的rbp(预期内)

  • bd函数执行rsp上的指令
    那么我们就可以在rsp预期内指向的地址上覆盖上我们的shellcode使其被执行

接下来就是ret2shellcode的:

ret2shellcode修正过程:

  • 在rsp最终指向的地址放上我们待执行的shellcode

  • 由于长度不够,我们可以把getshell的shellcode放在读入的字符串的最开始的地方,再通过汇编指令进行跳转

  • 在rsp所指向的位置覆盖上shellcode,改变rsp的值使其指向getshell的shellcode并再次进行跳转,完成getshell

那么payload就很容易构造出来了:

注:第一次盲打payload居然错了,我还是太菜了Or2

注2:其实可以不需要跳转到bd,直接跳转到

1
2
3
4
5
6
context.arch = 'amd64'
sc1 = asm(shellcraft.sh())
sc2 = asm('sub rsp,56')//48字节的字符串+8字节的rbp,跳回开头
sc3 = asm('jmp rsp')
elf = ELF('hello')
payload = sc1 + b'a'*(56-len(sc1)) + p64(elf.symbols['bd']) + sc2 + sc3

image.png

高阶解法:栈迁移

假如说这道题并不存在供我们进行跳转的bd函数,给我们的溢出长度就只有72-48=24个字节,但是仅仅是asm(sellcraft.sh())就已经需要48个字节,那么我们该如何通过仅仅24字节的溢出完成pwn呢

答案是使用栈迁移技术

注:赛期因为各种ddl导致只解出了这一道题XD 后面的题解是在赛后写的 参照了Lunatic大佬的题解

ezsc

我暂且被蒙在鼓里…

noleak

我暂且被蒙在鼓里…