---
# System prepended metadata

title: picoCTF/pwn/Unsubscriptions Are Free
tags: [pwn, heap]

---

picoCTF/pwn/Unsubscriptions Are Free
===
Release date: `Friday, July 22, 2022`
#### Before start:
After a couple of month don't play ctf, or writing something. Recently, I feel like i lost my passion in Sec. So i begin post again as my new routine.

Beginning is always hard, so i starting with beginner pwn challenge from picoCTF.

#### Initial Analysis:
##### checksec:
```
Arch:     i386-32-little
RELRO:    Partial RELRO
Stack:    Canary found
NX:       NX enabled
PIE:      No PIE (0x8048000)
```
As the name describe, this challenge relates to Use After Free (UAF) bug. Some functions you need to concern about:
```c
typedef struct {
	uintptr_t (*whatToDo)(); // function pointer
	char *username;
} cmd;

cmd *user;

void hahaexploitgobrrr(){
    // jist print flag for us
}

char * getsline(void) {
    getchar();
    char * line = malloc(100), * linep = line;
    size_t lenmax = 100, len = lenmax;
    int c;
    if(line == NULL)
        return NULL;
    for(;;) {
        c = fgetc(stdin);
        if(c == EOF)
            break;
        if(--len == 0) {
            len = lenmax;
            char * linen = realloc(linep, lenmax *= 2);

            if(linen == NULL) {
                free(linep);
                return NULL;
            }
            line = linen + (line - linep);
            linep = linen;
        }

        if((*line++ = c) == '\n')
            break;
    }
    *line = '\0';
    return linep;
}

// 'i' option
void i(){
    char response;
    puts("You're leaving already(Y/N)?"); scanf(" %c", &response);
    if(toupper(response)=='Y'){
        free(user);
    }else
        puts("Ok. Get premium membership please!");
}

// 'l' option
void leaveMessage(){
    char* msg = (char*)malloc(8);
    read(0, msg, 8);
}

int main(){
    user = (cmd *)malloc(sizeof(user));
    while(1){
        printMenu();
        processInput(); 
        /*
        choice = toupper(choice)
        case 'M':
 	    user->whatToDo = (void*)m; // m - junk function
	    user->username = getsline();
        case 'S':
            printf("OOP! Memory leak...%p\n",hahaexploitgobrrr);
         */
        (user->whatToDo)();
    }
    return 0;
}
```
Okay, so we have:
- Only one struct var keep by `user` (stored in heap).
- Leak win function with 's' option.
- free(user) with 'i' option, but not set `user` to NULL => UAF
- 'l' option: malloc a 0x20 heap chunk, then edit first 8 byte.

The target of us is set `user->whatToDo` to our win function.
#### Solution:
```
1. Leak win funct
2. free user chunk, user still point here
3. create new chunk, same position as freed chunk, then edit function pointer
```
###### tags: `pwn` `heap`