Write-ups: Program Security (Shellcode Injection) series (Completed)
Table of contents
Open Table of contents
Level 1
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag!
Write-up
够简单的吧,stack rwx,((void (*)(void))shellcode)();
把 buf
的地址强制转换为函数指针,执行我们的输入内容。
Exploit
由于是 SUID 程序,以程序所有者权限运行。所以我们的思路是通过 sendfile(0x1, open("/flag", 0x0, 0x0), 0x0, 0x1000)
直接输出 /flag
的内容:
还可以用 pwntools 的 shellcraft 来完成:
如果要 shell 的话可以这样写,-p
参数确保使用真实 uid
、gid
启动 /bin/sh
:
Flag
Flag: pwn.college{s4taPKpK1SzfB3gWK--PDuB4Xwx.01NxIDL5cTNxgzW}
Level 2
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but a portion of your input is randomly skipped.
Write-up
这题在上一题的基础之上加了一个简单的限制:随机生成一个 [0, 2048)
之内的随机数,将 shellcode 地址设置为 buf
起始地址加上这个随机数。所以我们要避免把实际攻击代码放在 [0, 2048)
这个地址区间内,通过 nop sled
滑过这块区间就可以轻松绕过~
Exploit
Flag
Flag: pwn.college{ws9aMHkG9tAyi31HLrmkc2LoE35.0FOxIDL5cTNxgzW}
Level 3
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but your inputted data is filtered before execution.
Write-up
这次的限制是 shellcode 的机器指令中不允许出现 \x00
字节。这就需要我们好好利用各种指令组合来构造数据了。
Exploit
pwntools 自动生成的代码已经避免了 \x00
,非常方便~
Flag
Flag: pwn.college{gZQWA0hDKCz5Xn8KrcsIiwIX2aZ.0VOxIDL5cTNxgzW}
Level 4
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but your inputted data is filtered before execution.
Write-up
显然,这次不允许我们使用 64-bit 汇编写 shellcode。Why?Cuz 64-bit 汇编指令本质上就是 32-bit 汇编的拓展,大多数指令都以前缀 0x48
开始。easy peasy!
push
、pop
指令没有 0x48
前缀,可以正常使用。
Exploit
这里再提供一种写法:
由于这题只是不想让我们用 64-bit 的指令,所以我们不能简单的通过 pwntools 生成 32-bit 指令来解决。这样生成出来的指令无法执行,我估计是内存对齐问题导致?因为这个程序本生是 amd64 的。
Flag
Flag: pwn.college{wqf2fgp7CVvoI3yhbzzsqtw5OC3.0FMyIDL5cTNxgzW}
Level 5
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but the inputted data cannot contain any form of system call bytes (syscall, sysenter, int), can you defeat this?
Write-up
不让出现系统调用原语的机器码,绕过方法非常 ez 啊,请看 exp。
Exploit
Flag
Flag: pwn.college{AJ-22D5IQdnex2KL8LxB8zOq02R.0VMyIDL5cTNxgzW}
Level 6
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but the inputted data cannot contain any form of system call bytes (syscall, sysenter, int), this challenge adds an extra layer of difficulty!
Write-up
还是没难度。首先不允许出现系统调用原语的机器码,其次会在执行 shellcode 前移除前 0x1000
字节区块的写权限。由于我们的 shellcode 会去修改自生的指令来绕过不允许出现系统调用原语的机器码,所以肯定不能把 shellcoded 写在前 0x1000
字节的区块中,因为程序读了 0x2000
字节,所以我们把核心代码写到前 0x1000
字节之后即可。至于这前 0x1000
字节,我们一个 nop
滑铲滑过去就好了。
Exploit
Flag
Flag: pwn.college{kfVRmOzEaLCMSxdS_zQkxZr6BEv.0lMyIDL5cTNxgzW}
Level 7
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but all file descriptors (including stdin, stderr and stdout!) are closed.
Write-up
开玩笑,没有输入输出错误流还能困得住我不成 LOL
请原谅我肚子饿了,实在懒得写思路了,现在只想快快恰饭,所以请师傅看 exp。
Exploit
其实这题用 chmod
写起来更简单一点呢。
Flag
Flag: pwn.college{Y3UgyYnfUmoR24PWDDkCs1W8h92.01MyIDL5cTNxgzW}
Level 8
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but you only get 18 bytes.
Write-up
这题在读取数据大小上做了限制,只允许读入 18 bytes。并且读完后把 buf
的写权限移除了,因此我们不能通过类似 read
的这种 shellcode 把再读数据到别的地方之类的。execve
肯定也不可能了,明显会超过 18 bytes。这时候我们发现 chmod
是一个很不错的候选,但是不能直接对 /flag
使用 chmod
,不然还是会超。不过既然超的原因是文件名太长,那我们不妨试试建立一个名称短一点的软链接,对软链接进行操作。实测发现对软链接使用 chmod
会影响到源文件的权限。
Exploit
Flag
Flag: pwn.college{swqZOtc9CdQUIFCMwrec4E5WBCi.0FNyIDL5cTNxgzW}
Level 9
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but your input has data inserted into it before being executed.
Write-up
这题每隔 0xa
字节使用 0xa
个 int3
中断替换 0xa
字节的指令。简单吧,每隔 0xa
字节给它塞 0xa
个 nop
好了,随它换。在此之前使用一条 jmp
跳转到 int3
之后确保不被 int3
干扰,继续执行就好了。
Exploit
Flag
Flag: pwn.college{YzFX3cOrT5abYZfD8oqct1wr3xc.0VNyIDL5cTNxgzW}
Level 10
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but your input is sorted before being executed!
Write-up
如果你的 shellcode 足够长的话会对部分指令进行冒泡排序,但是如果比较短的话这个限制就形同虚设了。这里我直接用之前的 exp 了。
Exploit
Flag
Flag: pwn.college{g5e9JB4cUp4THYN75FdmwWgVFA3.0lNyIDL5cTNxgzW}
Level 11
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but your input is sorted before being executed and stdin is closed.
Write-up
就算你把 stdin
也关了又如何,不还是无法阻止我使用之前的 exp 哈哈哈哈哈哈哈。
Exploit
Flag
Flag: pwn.college{Ed61x95iAxED3sEmx4x19WauOCW.01NyIDL5cTNxgzW}
Level 12
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but every byte in your input must be unique.
Write-up
就你要每一个字节都得唯一是吧,execve
调用外部 shellcode 秒了!
cdq
是一字节指令,有时候用来取代 xor edx, edx
很不错。它的作用请参考 CWD/CDQ/CQO — Convert Word to Doubleword/Convert Doubleword to Quadword.
Exploit
我们的 shellcode 的目的就是加载外部脚本完成剩余攻击步骤。注意把下面脚本编译为 a
(文件名)。
Flag
Flag: pwn.college{g4UdtC88x4ayx2CjkFQNdxcSBsC.0FOyIDL5cTNxgzW}
Level 13
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but this time you only get 12 bytes!
Write-up
12 bytes 是吧,巧了,哥们上一个 exp 就压在 12 bytes 上了。
Exploit
Flag
Flag: pwn.college{s_8hupYRZPagLrq6OX3Dd--4PYY.0VOyIDL5cTNxgzW}
Level 14
Information
- Category: Pwn
Description
Write and execute shellcode to read the flag, but this time you only get 6 bytes :)
Write-up
6 bytes,看似好像是一件不可能完成的任务,butttt,如果你尝试动态调试会就会发现,rax
的值正好可以用于 syscall
来调用 read
;rdx
的值正好可以用做 read
的第二个参数,指定 buf
地址;rsi
的值足够大,正好用作 read
的第三个参数,指定输入大小。
来来来,我们看看 stage_1 的 shellcode 编译出来占多少字节:
GG 正好 6 bytes!笑不动了哈哈哈。
现在,有了 stage_1 的辅助,stage_2 该怎么办不用多说了吧 xD
唯一有一点需要注意的就是执行 stage_2 之前应该使用 nop
填充 stage_1 所用的所有指令位,这样才能确保从正确的地方接着执行,因为 rip
的值一直在改变。
Exploit
Flag
Flag: pwn.college{0PaZanWijSYussIikuZaDrCAj1-.0FMzIDL5cTNxgzW}
后记
没想到时隔三天又要写后记了。这章 3 天就打完了,爽快!
Shellcode Injection 应该是最简单的一章了,不接受反驳。
Well. 接下来我想嗨几天,虽然不知道可以干什么,但是我清楚的知道我这个小苦逼之后的 roadmap 是刷 ROP -> FmtStr ……