> For the complete documentation index, see [llms.txt](https://ret2basic.gitbook.io/ctfwriteup/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ret2basic.gitbook.io/ctfwriteup/web2-ctf/pwnable.kr/passcode.md).

# passcode

## Challenge

Mommy told me to make a passcode based login system. My initial C code was compiled without any error! Well, there was some compiler warning, but who cares about that?

ssh <passcode@pwnable.kr> -p2222 (pw:guest)

## Code Review

```c
#include <stdio.h>
#include <stdlib.h>

void login(){
        int passcode1;
        int passcode2;

        printf("enter passcode1 : ");
        scanf("%d", passcode1);
        fflush(stdin);

        // ha! mommy told me that 32bit is vulnerable to bruteforcing :)
        printf("enter passcode2 : ");
        scanf("%d", passcode2);

        printf("checking...\n");
        if(passcode1==338150 && passcode2==13371337){
                printf("Login OK!\n");
                system("/bin/cat flag");
        }
        else{
                printf("Login Failed!\n");
                exit(0);
        }
}

void welcome(){
        char name[100];
        printf("enter you name : ");
        scanf("%100s", name);
        printf("Welcome %s!\n", name);
}

int main(){
        printf("Toddler's Secure Login System 1.0 beta.\n");

        welcome();
        login();

        // something after login...
        printf("Now I can safely trust you that you have credential :)\n");
        return 0;
}
```

## Solution

There is an error in the code: instead of `scanf("%d", passcode1)`, it should be `scanf("%d", *passcode1)`. Because of this error, `passcode1` and `passcode2` are considered **addresses** instead of **values**. In fact, there are three erros in the code:

```c
scanf("%100s", name);
...
scanf("%d", passcode1);
...
scanf("%d", passcode2);
```

For each `scanf()`, we are able to write some data directly to the address of the variables `name`, `passcode1`, and `passcode2`. Let's read through the assembly to figure out the exact location of each variable:

![welcome()](/files/-M_nG-HZWbtJdOHVi5v1)

![login()](/files/-M_nG1mNmy7HsJ0dMJPG)

The location for each variable:

```
name => ebp-0x70
passcode1 => ebp-0x10
passcode2 => ebp-0xc
```

The distance between `name` and `passcode1` is `0x60`, which is 96 in decimal. We are able to input at most 100 bytes for `name`, so it is possible to overwrite `passcode1`.

Note that the function `fflush()` is called right after `scanf("%d", passcode1)`:

```c
void login(){
        ...
        printf("enter passcode1 : ");
        scanf("%d", passcode1);
        fflush(stdin);
        ...
}
```

Let's see its disassembly:

![fflush()](/files/-M_nG4iHev9xQW_FqIJp)

This `fflush()` is `fflush@PLT`, and the first `jmp` instruction jumps to `fflush@GOT`. The idea is:

1. Send 96 bytes of junk data to fill the buffer.
2. Overwrite `password1` with `0x804a004`, then the `scanf()` statement becomes `scanf("%100s", 0x804a004)`. This would allow us to input arbitrary data to the memory location `0x804a004`, which is `fflush@GOT`.
3. Once the `scanf()` function is called, send the integer representation (because of `"%100s"`) of `system("/bin/cat")`. Once `fflush@PLT` is called, the `jmp` instruction will jump to `system("/bin/cat")` and execute it.

Essentially, this is a **GOT overwrite attack**. The last task is finding the address of `system("/bin/cat")`. Take another look at the disassembly of `login()`:

![login()](/files/-M_nG6tRvlPko5jGWxCa)

Here `0x80485d7` is the address of `system("/bin/cat")`. To get its integer representation, use `str(0x80485d7)` in Python.

## Get Flag

![Get flag](/files/-M_nG9AK79Z-sO6qZWEy)

## Exploit

```python
```
