shell_basic 문제
https://dreamhack.io/wargame/challenges/410/
shell_basic
Description 입력한 셸코드를 실행하는 프로그램입니다. main 함수가 아닌 다른 함수들은 execve, execveat 시스템 콜을 사용하지 못하도록 하며, 풀이와 관련이 없는 함수입니다. flag 위치와 이름은 /home/
dreamhack.io
위의 링크에 들어가면 문제를 풀 수있다.
문제 설명
main함수가 아닌 다른 함수들은 execve와 execveat와 같은 시스템 콜을 사용하지 못한다고하고, flag의 위치는 /home/shell_basic/flag_name_is_loooooong 위치에 있다.
execve와 같은 시스템콜을 사용하지 못하는 것을보면 파일을 열고 읽은 뒤 화면에 출력해주는 셸코드인 orw쉘코드를 이용하여 풀어야 하는 문제인 것 같다.
shell_basic.c 소스코드
// 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();
}
소스코드를 보면 shell코드를 0x1000만큼 입력받고 쉘코드를 실행하는 것을 알 수 있다.
바로 쉘코드를 입력하면 쉘코드가 실행될 것이다.
문제 풀이
shell_basic은 ELF파일이고 64비트로 이루어져있다는 것을 확인하였다.
pwntools의 shellcraft를 이용하여 쉘코드 추출
pwntools의 shellcraft를 이용하면 각 아키텍쳐에 맞는 execve나 orw와 같은 쉘코드를 만들 수 있다.
변수 r에 flag값이 있는 경로를 설정하여 주었다.
shellcraft.open()에 r인 경로를 넣어주어서 파일을 열고 read로 open한 파일을 읽어 write로 콘솔에 출력하도록 설정하였다.
read에서 rax가 fd로 설정이 되어있는 이유는 open에서 반환값이 rax로 return되기 때문이다. 그리고 buf의 값에 rsp가 들어가는 이유는 buf의 주소가 rsp의 위치이기 때문이다.
write 시스템콜을 호출하기 위해서 1로 설정하였고 rsp로 플래그 값들을 출력하도록 하였다.
asm(shellcode)로 어셈블리어로 변환을 한 후 쉘코드를 전송하였다.
그 결과 flag를 확인할 수 있다.
아직 pwntools이 익숙하지 않지만 많이 사용하다보면 괜찮을것 같다.