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`