➜ ~

Playing Hacks and Stuffs!


Project maintained by h4ckyou Hosted on GitHub Pages — Theme by mattgraham

GreyHat 2023 CTF

Here are the writeups to the pwn challenges I solved:

Babypwn

After downloading the attached file checking the file type shows this

image

So we’re working with a x64 binary which is dynamically linked, not stripped and has all protections enabled

I’ll run the binary to know what it does: image

Seems to be some banking system that allows us withdraw & deposit money

We can’t find the vuln yet so let us look at the decompiled code

I’ll be using ghidra

Here’s the main function image image

int main(void)

{
  long in_FS_OFFSET;
  short option;
  int accountBalance;
  uint tmp;
  long withdrawalAmount;
  long canary;
  
  canary = *(long *)(in_FS_OFFSET + 0x28);
  accountBalance = 100;
  puts("==== Secure Banking System ====");
  puts("Welcome to the banking system.\nEarn $1000 to get the flag!\n");
menu:
  if (999 < accountBalance) {
    printf("\nCongratulations! You have reached the required account balance ($%d).\n",
           (ulong)(uint)accountBalance);
    puts("The flag is: grey{fake_flag}");
exit:
    if (canary == *(long *)(in_FS_OFFSET + 0x28)) {
      return 0;
    }
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  puts("1. Check account balance");
  puts("2. Withdraw money");
  puts("3. Deposit money");
  puts("4. Exit\n");
  puts("Enter your option:");
  __isoc99_scanf("%hu",&option);
  if (option == 4) {
    puts("Thank you for banking with us.");
    goto exit;
  }
  if (option < 5) {
    if (option == 3) {
      puts("Deposit is still work in progress.");
      goto menu;
    }
    if (3 < option) goto LAB_00101344;
    if (option == 1) {
      printf("Your account balance is: $%d\n",(ulong)(uint)accountBalance);
      goto menu;
    }
    if (option == 2) {
      printf("Enter the amount to withdraw: ");
      __isoc99_scanf("%ld",&withdrawalAmount);
      tmp = accountBalance - (int)withdrawalAmount;
      if ((int)tmp < 0) {
        puts("You cannot withdraw more than your account balance.");
      }
      else {
        accountBalance = tmp;
        printf("Withdrawal successful. New account balance: $%d\n",(ulong)tmp);
      }
      goto menu;
    }
  }
LAB_00101344:
  puts("Invalid option.");
  goto menu;
}

I won’t explain what that all does. But basically.

The aim of this program is to earn $1000 to get the flag

puts("Welcome to the banking system.\nEarn $1000 to get the flag!\n")

How can we achieve that?

Take a look at the withdrawal option

if (option == 2) {
  printf("Enter the amount to withdraw: ");
  __isoc99_scanf("%ld",&withdrawalAmount);
  tmp = accountBalance - (int)withdrawalAmount;
  if ((int)tmp < 0) {
    puts("You cannot withdraw more than your account balance.");
  }
  else {
    accountBalance = tmp;
    printf("Withdrawal successful. New account balance: $%d\n",(ulong)tmp);
  }

After it receives the amount we want to withdraw, It will set a temp variable holding the difference between our current account balance and the withdrawalamount

If the temp variable is less than 0 we get the error message that basically means we can’t withdraw an amount greater than our current account balance

Else it sets our current account balance to the temp variable and prints out the current balance

The vulnerability in this program is that it doesn’t check if the amount to be withdrawed is a negative number

With that if we give it a number less than our balance it will sum up to a positive number greater than our current balance

accountBalance = 100
withdrawalAmount = -10000
tmp = accountBalance - withdrawalAmount
# tmp = 100 - (-10000) --> 100 + 10000

That logic is one of the vulnerability of this program and with that we can get the flag image

Another way we can exploit this is via Integer Overflow

I won’t explain that but here’s a good sample payload: 0xffffffff - 10000

That will sum our account balance to 0 then 10000 will be added since the negative sign will turn to positive image

We can try that on the remote server image

Flag: grey{b4by_pwn_df831aa280e25ed6c3d70653b8f165b7}

Easypwn

We are provided with the binary and the source code

➜  easypwn ls -l  
-rwxr-xr-x 1 mark mark 8696 Sep  6 23:01 easypwn
-rw-r--r-- 1 mark mark  309 Sep  6 22:35 easypwn.c
➜  easypwn

First thing I’ll check is the source code image

#include <stdio.h>
#include <stdlib.h>

void win() {
    system("cat flag.txt");
    exit(0);
}

int main() {
    setbuf(stdout, NULL);
    setbuf(stdin, NULL);
    setbuf(stderr, NULL);
    char str[8];
    printf("Type your string: ");
    read(0, str, 1024);
    printf(str);
    puts("");
    return 0;
}

The program doesn’t have much function in it

Here’s what it does:

That’s all what the program does

But where’s the vulnerability?

Well there are two vulns which are:

The buffer overflow occurs here:

read(0, str, 1024);

We are reading 1024 bytes into a buffer that can only hold up 8 bytes

The second vulnerability is format string vuln which occurs here:

printf(str);

After receiving our input it will use printf to to prints it’s content and it doesn’t use a format specifier while doing so

How do we exploit??

We can’t know now until we check the binary

Here’s the binary file type and mitigations present image

So this isn’t the normal x86/x64 binaries this is a binary whose architecture is RISC-V

I haven’t worked with other archicture before so this my first time

First I’ll try to run it

Normally it wont’ work but I have qemu installed which basically allows us run other archicture binary on our device

When I tried running it I got this error image

It seems I don’t have the library for this binary to run available

To download it I searched it first image

libc6-riscv64-cross: /usr/riscv64-linux-gnu/lib/ld-linux-riscv64-lp64d.so.1

Now to install it we can just run this:

sudo apt-get install libc6-riscv64-cross

After that we will see the file is on our device image

Next thing to do is to patch the binary to use the library required and the tool used is patchelf

Why I’m patching it is because the directory where it wants to get the library isn’t on my laptop image

I can maybe just copy the the library or make a symbolic link to that directory but I prefer patching it

Here’s the way to do it image

patchelf --set-interpreter /usr/riscv64-linux-gnu/lib/ld-linux-riscv64-lp64d.so.1 --set-rpath /usr/riscv64-linux-gnu/lib easypwn 

Now I should be able to run the binary image

Back to the exploitation, since there’s no stack canary that means we don’t need to leak any canary address

And therefore we can just overwrite the instruction pointer and jump to the win function

I tried debugging with gdb-multiarch and gef, but couldn’t completely disassemble RISC-V.

Therefore, I made the Exploit code by referring to the C code.