Lab 網址 前言 今天我們將介紹一些簡單的知識,並在最後提供一個練習 Lab。看完前面的內容,大家可能會想:「如果我們可以調用 execve,那是否就能拿到 shell 呢?」這確實沒錯,但還有一種方法可以防止使用者調用 execve 系統呼叫 (syscall),這就是 seccomp 的機制。
Seccomp (secure computing mode) seccomp 是 Linux 核心用來禁用特定系統呼叫的機制,透過 Seccomp BPF 可以設定對某些 syscall 的過濾規則。例如,可以限制 execve,甚至 open、read、write 等等。
但在實作這些規則後,逆向工程的過程可能變得不直觀且困難理解。為了簡化分析,one gadget 工具的作者還開發了一個工具,叫做 seccomp-tools,非常適合這類情況。
seccomp-tools 筆者提供的環境中已經安裝了該工具
這個工具能分析程式的 seccomp 規則,並將結果轉換成直觀的 if-else 形式的 pseudo code。這讓我們能輕鬆看出程式允許或限制了哪些 syscall,非常適合處理複雜的 seccomp 規則。
使用方式如下:
1seccomp-tools dump ./[binary] Lab 查看以下原始碼:
1#include <stdio.h> 2#include <sys/mman.h> 3#include <unistd.h> 4#include "seccomp-bpf.h" 5 6void apply_seccomp() { 7 struct sock_filter filter[] = { 8 VALIDATE_ARCHITECTURE, 9 EXAMINE_SYSCALL, 10 ALLOW_SYSCALL(read), 11 ALLOW_SYSCALL(write), 12 ALLOW_SYSCALL(open), 13 KILL_PROCESS, 14 }; 15 16 struct sock_fprog prog = { 17 .len = (unsigned short)(sizeof(filter) / sizeof(struct sock_filter)), 18 .filter = filter, 19 }; 20 21 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { 22 perror("Seccomp Error"); 23 exit(1); 24 }; 25 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { 26 perror("Seccomp Error"); 27 exit(1); 28 }; 29} 30char shellcode[0x100]; 31int main() { 32 setvbuf(stdin, 0, 2, 0); 33 setvbuf(stdout, 0, 2, 0); 34 setvbuf(stderr, 0, 2, 0); 35 unsigned long addr = (unsigned long)&shellcode & ~0xfff; 36 mprotect((void *)addr, 0x1000, PROT_EXEC | PROT_READ | PROT_WRITE); 37 apply_seccomp(); 38 printf("I add new rule to prevent you from using system().\n"); 39 printf("Give me shellcode: "); 40 read(0, shellcode, 0x100); 41 printf("Overflow me: "); 42 char buffer[0x10]; 43 gets(buffer); 44 printf("Bye!\n"); 45 return 0; 46} 使用以下指令進行編譯:
...