0%

pwnwaf

pwnwaf

起因还得从第五空间线下赛说起,那时候darry师傅给我发了个github上的一个pwnwaf工具,当时一直装不上去,装上去后也没打过几次线下赛,所以也没怎么用过。准备在赣网杯上试试,结果早上一直没调好,也没用成。

回去后在darry师傅的帮助下,终于成功了。因此记录下该如何使用这个waf。

首先我们要找到程序的main函数地址,然后修改hpwnwaf.py文件的main_addr。patch成功后托入ida中,因为我们需要进行手动修改。

在main函数处我们先修改jmp的地址为最初main函数的入口指令,即在沙箱指令之后的某个位置(为了能最大程度的保护栈帧)。比如下面这个地方

image-20211217215702845

然后紧接着改这个函数的jmp地址为沙箱地址(0x402000),最后再将沙箱函数的leave|ret改为jmp到程序的主函数处的地址。(写的比较绕,因为是写给我自己看的😁)。

发现这个工具可以自定义规则,参考这篇博客

简单来说就是将下面的代码gcc编译运行一下,规则自行添加和修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//gcc -g simple_syscall_seccomp.c -o simple_syscall_seccomp -lseccomp
#include <unistd.h>
#include <seccomp.h>
#include <linux/seccomp.h>
#include <fcntl.h>
int main(void){
scmp_filter_ctx ctx;
ctx = seccomp_init(SCMP_ACT_ALLOW);

seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(socket), 0);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(connect), 0);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(bind), 0);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(listen), 0);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(clone), 0);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 0);
int fd = open("./bpf.out",O_WRONLY|O_CREAT);
seccomp_export_bpf(ctx,fd);
close(fd);
seccomp_load(ctx);
system("/bin/sh");
}

然后用下面这个命令,导出数据

1
2
3
4
5
6
7
8
$hexdump bpf.out -C
00000000 20 00 00 00 04 00 00 00 15 00 00 09 3e 00 00 c0 | ...........>...| //A = arch if (A != ARCH_X86_64)
00000010 20 00 00 00 00 00 00 00 35 00 07 00 00 00 00 40 | .......5......@| //A = sys_number
00000020 15 00 06 00 29 00 00 00 15 00 05 00 2a 00 00 00 |....).......*...|
00000030 15 00 04 00 31 00 00 00 15 00 03 00 32 00 00 00 |....1.......2...|
00000040 15 00 02 00 38 00 00 00 15 00 01 00 3b 00 00 00 |....8.......;...|
00000050 06 00 00 00 00 00 ff 7f 06 00 00 00 00 00 00 00 |................| //return ALLOW return KILL
00000060

然后根据这些数据将其改为汇编指令

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
   push rbp;
mov rbp,rsp;
mov r15,6;
push r15;
mov r15,7FFF000000000006H;
push r15;
mov r15,3B00010015H;
push r15;
mov r15 , 3800020015h;
push r15;
mov r15 , 3200030015h;
push r15;
mov r15 , 3100040015h;
push r15;
mov r15 , 2A00050015h;
push r15;
mov r15 , 2900060015h;
push r15;
mov r15 , 4000000000070035h;
push r15;
mov r15 , 20h;
push r15;
mov r15 , 0C000003E09000015h;
push r15;
mov r15 , 400000020h;
push r15;
mov r15,rsp;
push r15;
mov r15 , 0ch;//这里表示的是有多少行指令
push r15;
mov r15,rsp;
push r15;
mov rdi,38;
mov rsi,1;
mov rdx,0;
mov rcx,0;
mov r8,0;
mov rax,157;
syscall;
mov rdi,22;
mov rsi,2;
mov rdx,r15;
mov rax,157;
syscall;
leave;
ret;

补:对于开了pie的程序操作过程相似,先将hpwnwaf.py的main_addr改成主函数地址,运行./patch。

接着将主函数地址处后的jmp地址改为程序最后多出的已push esp开头的地址如0x4030c6

image-20220619110559353

image-20220619110630291

接着将0x4030cf处的jmp后地址改为沙箱函数地址0x403000,最后将沙箱函数最后的leave ret改为jmp到主函数被改后的第一条指令地址

image-20220619111006341

image-20220619111109368