ORW
seccomp
参考:
- 【你想有多PWN(不再更新)】 https://www.bilibili.com/video/BV1mr4y1Y7fW/?p=40&share_source=copy_web&vd_source=cf06702a0298aa3dc99cbebc78590fa6
- Seccomp从0到1 | CN-SEC 中文网
用处
用于添加白/黑名单,允许/禁止某些系统调用,以达到保护系统的目的
Seccomp-BPF
比较原始的写法
把那些宏当做一个虚拟机的汇编来看就好理解了
例如以下这个C程序
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <sys/prctl.h>
#include <seccomp.h>
#include <linux/seccomp.h>
#include <linux/filter.h>
int main()
{
struct sock_filter filter[] = {
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, 4),
BPF_JUMP(BPF_JMP + BPF_JEQ, 0xc000003e, 0, 2),
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, 0),
BPF_JUMP(BPF_JMP + BPF_JEQ, 59, 0, 1),
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_KILL),
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW),
};
struct sock_fprog prog = {
.len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
.filter = filter,
};
prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
printf("start!n");
system("id");
return 0;
}
用seccomp-tools可以把那一堆结构体翻译成人话
$ seccomp-tools dump ./seccomp
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x02 0xc000003e if (A != ARCH_X86_64) goto 0004
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x15 0x00 0x01 0x0000003b if (A != execve) goto 0005
0004: 0x06 0x00 0x00 0x00000000 return KILL
0005: 0x06 0x00 0x00 0x7fff0000 return ALLOW
进阶写法
用seccomp库函数
sudo apt install libseccomp-dev libseccomp2 seccomp
#include <unistd.h>
#include <seccomp.h>
#include <linux/seccomp.h>
int main(void){
scmp_filter_ctx ctx;
ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 0);
seccomp_load(ctx);
char * str = "/bin/sh";
write(1,"hello worldn",12);
syscall(59,str,NULL,NULL);//execve
return 0;
}
open(file,oflag)`,`read(fd,buf,n_bytes)`和`write(fd,buf,n_bytes)
如何构造函数
open(file,oflag),read(fd,buf,n_bytes)和write(fd,buf,n_bytes)
open
file就是我们要读取的文件名,CTF中一般为flag,或者flag.txt。
而oflag则是我们以何种方式打开文件,如只读,只写,可读可写。一般来说我们都设置oflag=0,以默认方式打开文件,一般来说都是只读,我们并不需要对flag进行其它操作,所以只读的权限就够了
read和write
这两个是大同小异的。fd是文件描述符,通过设置它来决定函数的操作。在大多数时候,我们常常设置read的fd为0,代表标准输入,但在ORW中,我们需要设置read的fd为3,表示从文件中读取,buf就是我们读取出的flag值存放的地址,n_bytes就是能输入多少字节的数据。write的fd还是如常,依旧为1.
源码

打开第一个文件,它的描述符是2之后的数,由于是第一个打开的,所以文件描述符是3
栈可执行的ORW
用shellcreft模块构造ORW的shellcode
shellcraft.open('/flag')
shellcraft.read(3,buf,n_bytes)
shellcraft.write(1,buf,n_bytes)

浙公网安备 33010602011771号