Table of Contents

Introduction

The team stumbles into a long-abandoned casino. As you enter, the lights and music whir to life, and a staff of robots begin moving around and offering games, while skeletons of prewar patrons are slumped at slot machines. A robotic dealer waves you over and promises great wealth if you can win – can you beat the house and gather funds for the mission?

Windows Active Directory Penetration Testing Study Notes

OSCP Study Notes

Walkthrough

Analysis: In this challenge, we were provided with a binary file that contains the flag, and our goal is to find a way to extract it. Let’s start by running the binary to gather some basic information about it.

[ ** WELCOME TO ROBO CASINO **]
     ,     ,
    (\____/)
     (_oo_)
       (O)
     __||__    \)
  []/______\[] /
  / \______/ \/
 /    /__\
(\   /____\
---------------------
[*** PLEASE PLACE YOUR BETS ***]
> 5
[ * INCORRECT * ]
[ *** ACTIVATING SECURITY SYSTEM - PLEASE VACATE *** ]

We can use Ghidra to open the binary and start reverse engineering our way to better understand how the binary works.
After displaying the banner, the binary runs a loop from 0 to 0x1c. During each iteration, srand() is called using the character we provide as input. Then, rand() is called and the result is compared to a corresponding integer from the check array. If the result matches, we receive a success message and move on to the next iteration.

If all 0x1c entries match correctly, we complete the process successfully.

int32_t main(int32_t argc, char** argv, char** envp)
  puts(str: "[ ** WELCOME TO ROBO CASINO **]")
  puts(str: "     ,     ,\n    (\____/)\n     (_oo_)\n       (O)\n     __…")
  puts(str: "[*** PLEASE PLACE YOUR BETS ***]")
  int32_t i = 0
  while (true) {
      if (i u> 0x1c) {
          puts(str: "[ ** HOUSE BALANCE $0 - PLEASE COME BACK LATER ** ]")
          return 0
      }
      printf(format: "> ")
      char inp
      if (__isoc99_scanf(format: " %c", &inp) != 1) {
          exit(status: 0xffffffff)
          noreturn
      }
      srand(x: sx.d(inp))
      if (rand() != check[sx.q(i)]) {
          break
      }
      puts(str: "[ * CORRECT *]")
      i = i + 1
  }
  puts(str: "[ * INCORRECT * ]")
  puts(str: "[ *** ACTIVATING SECURITY SYSTEM - PLEASE VACATE *** ]")
  exit(status: 0xfffffffe)

rand() is a predictable random number generator—calling srand(x) followed by rand() will always produce the same result for a given seed. So, we can script a solution to uncover the mapping.

By using the ctypes library in Python, we can easily call C functions like srand() and rand() directly from our Python code to assist in this process.

Next, we’ll use the pwntools library to interact with the binary. This will allow us to open the binary and extract each target integer that we need to compare against during the process. By automating this with pwntools, we can streamline the extraction and verification of the necessary values.

In the for loop, to index into the check array, multiply the current index by 4 to account for the size of each 32-bit integer. Then, use e.u32() (from pwntools) to extract each 32-bit integer from the binary data. This allows us to read the correct values from the check array during each iteration.

Full solution python script:

import ctypes

libc = ctypes.CDLL('libc.so.6')

mapping = {}
for i in range(255):
libc.srand(i)
mapping[libc.rand()] = chr(i)

flag = ""
from pwn import *
casino = ELF("./casino", checksec=False)
for b in range(29):
val = casino.u32(casino.sym["check"] + b * 4)
flag += mapping[val]
print(flag)

You can also watch:

About the Author

Mastermind Study Notes is a group of talented authors and writers who are experienced and well-versed across different fields. The group is led by, Motasem Hamdan, who is a Cybersecurity content creator and YouTuber.

View Articles