pwnwaf
起因还得从第五空间线下赛说起,那时候darry师傅给我发了个github上的一个pwnwaf工具,当时一直装不上去,装上去后也没打过几次线下赛,所以也没怎么用过。准备在赣网杯上试试,结果早上一直没调好,也没用成。
回去后在darry师傅的帮助下,终于成功了。因此记录下该如何使用这个waf。
首先我们要找到程序的main函数地址,然后修改hpwnwaf.py文件的main_addr。patch成功后托入ida中,因为我们需要进行手动修改。
在main函数处我们先修改jmp的地址为最初main函数的入口指令,即在沙箱指令之后的某个位置(为了能最大程度的保护栈帧)。比如下面这个地方
然后紧接着改这个函数的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
接着将0x4030cf处的jmp后地址改为沙箱函数地址0x403000,最后将沙箱函数最后的leave ret改为jmp到主函数被改后的第一条指令地址