The Bomb Lab
The “bomb lab” is a common assignment or project in computer systems or computer architecture courses. It’s designed to teach students about reverse engineering, debugging, and understanding assembly language and low-level programming concepts.
The Bomb
: First off, you’re given this mysterious computer program, which your teacher calls the “bomb.” It’s like a puzzle box with a twist – if you don’t solve it correctly, it “explodes” (figuratively, of course!).Your Mission
: Your job is to figure out how to stop this bomb from “exploding.” But here’s the catch: it’s not as simple as pressing a button. You’ve got to dig deep into the inner workings of this program to find out what makes it tick.Deciphering the Code
: Inside the bomb is a bunch of secret instructions written in a special language that computers understand. It’s like trying to decode a secret message. You’ve got to carefully read through these instructions to understand what the bomb is trying to do.Finding Clues
: As you go through the instructions, you might find some clues – like little breadcrumbs that lead you to the solution. Maybe there are certain words or numbers that seem important, or patterns that catch your eye.Trial and Error
: Now comes the not so fun part (For most of you) – testing things out! You might try different combinations of words or numbers to see what happens. It’s like solving a puzzle – you try something, see if it works, and if it doesn’t, you try something else.Using Tools
: Sometimes, you need a little help from some special tools. Imagine having a magic magnifying glass that lets you see inside the bomb and understand what’s going on. These tools help you peek under the hood of the program and see how it works. (Referring to GDB)Success!
: After some trial and error, and maybe a few head-scratching moments, you finally figure it out! You’ve cracked the code and defused the bomb. It’s like solving a really tricky riddle – when you finally get it, there’s a sense of satisfaction and relief.
Getting Started
Save Answers
You might as well make some file, call it solutions or what i prefer: defuse_kit.txt
.
touch defuse_kit.txt
You will use this file to save answers for 6 phases you go thru, instead of typing answers on each test of bomb you will run program with this file ./bomb answers.txt
this will automatically take answers in following order: first line for first phase, second line for second phase and so on.
When you find answer, you place it inside this file.
Read Code
You will need to see the actuall assembly code so you know what you are dealing with, for this we will first dump assembly out of this bomb:
objdump -d bomb > bomb.s
This will put every assembly instruction from the bomb, into the file called bomb.s
.
you can now use text editor in terminal (Vim, Vi, Nano, NeoVim …) to see the assembly code.
Debug
-
Phase 1
:- This phase requires some string. You can try searching through the executable’s strings using the following command:
strings <file>
- Advice: Try to look for an out-of-place sentence.
-
Phase 2
:- In this phase, you’ll mostly encounter assembly code. Follow these steps:
- Read the code and use the cheatsheet below to go step by step and understand what it’s doing.
- The answer is most likely 6 numbers (It’s taking in 6 numbers). Usually, numbers start from 1, but it may vary depending on your case.
- Use “i r” often to track changes in registers.
- In this phase, you’ll mostly encounter assembly code. Follow these steps:
-
Phase 3
:- Similar to the second phase, but here you only need 2 numbers.
- The code looks like it might have a switch case, but in most cases, it skips this switch entirely.
- This phase involves simple addition and subtraction. Go through it step by step; it’s easier than it looks.
- Look for jump instructions. You can find which jump instruction means what in the cheatsheet below.
-
Phase 4
:- Similar to the previous phases, but with a slight twist: this one is not alone.
- This phase also needs 2 numbers as an answer.
- In this phase, you will have another function called func4, which will return some number. Look for that number; it might be the answer.
-
Phase 5
:- In this phase, you’ll encounter 2 addresses.
- At the first address, you’ll find 16 random characters in front of a readable string. Map these 16 characters to 0 to 16 using hexadecimal numbers.
- At the second address, you’ll find a word. Using the mapped characters, assign the correct number to each character in this word.
- After this, debug the bomb again with some random 6 characters and observe the rdx register. Write down each character you inputted and the corresponding number you get.
- This time, map out characters using the numbers you got from the last run from random input and the hexadecimal numbers you assigned to the string in the second address. Numbers may be approximated (e.g., if “e” is 5, “f” will be 6).
-
Phase 6
:- This phase requires 6 numbers as the answer.
- Answers are restricted to 1 to 6 with no repeats.
- In this phase, there’s a linked list. You need to find an address that is linked to one of the nodes.
- Check the numbers in the node addresses and turn them into decimals for simplicity.
- You’ll need to order them either from ascending or descending.
- Some of you might have a variant that has answers inverted, meaning if your answer was x, you do 7 - x. This will leave you with only 4 options, so it’s fairly simple.
-
Secret Phase
, Look closely at the assembly dump. Dr. Evil must’ve left some hidden things there… or so they say…
Common issues
permision denied
: This means that your executable doesnt have permission to execute. To give it permissions run:chmod +x bomb
WSL related issues
-
GDB doesnt come with wsl on default and you need to install it on your own. However, standard GDB might have problems when setting up Breakpoints. If you encounter this you might want to delete GDB, download source code for GDB and compile it. Easier way is to add ubuntu support teams version of GDB (remove existing GDB first):
sudo add-apt-repository ppa:ubuntu-support-team/gdb sudo apt update
if GDB is not isntalled after this just run:
sudo apt install gdb
-
Not being able to install GDB. You might wanna update your system first:
sudo apt update sudo apt upgrade
CheatSheet
GDB related
Start:
gdb
: Start gdbgdb <file>
: Start gdb with a specific file
Run:
run
: Run programrun 1 2 3
: Run program with command-line arguments 1 2 3run <file>
: Run program with a specific file
Stop:
kill
: Stop the programquit
: Exit gdbCtrl + D
: Exit gdb (Note: Ctrl + C does not exit from gdb, but halts the current gdb command)
Breakpoint
Breakpoints are stopping points, you can stop at any place in code and see what its doing behind the scenes
break sum
: Set breakpoint at the entry to function sumbreak *0x80483c3
: Set breakpoint at address 0x80483c3delete 1
: Delete breakpoint 1disable 1
: Disable the breakpoint 1 (gdb numbers each breakpoint you create)enable 1
: Enable breakpoint 1delete
: Delete all breakpointsclear sum
: Clear any breakpoints at the entry to function sum
Execute
Meaning: start debugging your program
stepi
orsi
for short: Execute one instructionsi 4
: Execute four instructionsnexti
orni
for short: Like stepi, but proceed through function calls without stoppingstep
: Execute one C statementcontinue
: Resume execution until the next breakpointuntil 3
: Continue executing until the program hits breakpoint 3until *0x80483c3
: Continue executing until the program reaches address 0x80483c3finish
: Resume execution until the current function returnscall sum(1, 2)
: Call sum(1,2) and print return value
Examine code
disas
: Disassemble current functiondisas sum
: Disassemble function sumdisas 0x80483b7
: Disassemble function around 0x80483b7disas 0x80483b7 0x80483c7
: Disassemble code within specified address rangeprint /x $rip
: Print program counter in hexprint /d $rip
: Print program counter in decimalprint /t $rip
: Print program counter in binary
Examine Data
print /d $rax
: Print contents of %rax in decimalprint /x $rax
: Print contents of %rax in hexprint /t $rax
: Print contents of %rax in binaryprint /d (int)$rax
: Print contents of %rax in decimal after sign-extending lower 32-bits.print 0x100
: Print decimal representation of 0x100print /x 555
: Print hex representation of 555print /x ($rsp+8)
: Print (contents of %rsp) + 8 in hexprint *(int *) 0xbffff890
: Print integer at address 0xbffff890print *(int *) ($rsp+8)
: Print integer at address %rsp + 8print (char *) 0xbfff890
: Examine a string stored at 0xbffff890
Examine Memory
x/w 0xbffff890
: Examine (4-byte) word starting at address 0xbffff890x/w $rsp
: Examine (4-byte) word starting at address in $rspx/wd $rsp
: Examine (4-byte) word starting at address in $rsp. Print in decimalx/2w $rsp
: Examine two (4-byte) words starting at address in $rspx/2wd $rsp
: Examine two (4-byte) words starting at address in $rsp. Print in decimalx/g $rsp
: Examine (8-byte) word starting at address in $rspx/gd $rsp
: Examine (8-byte) word starting at address in $rsp. Print in decimalx/a $rsp
: Examine address in $rsp. Print as offset from previous global symbolx/s 0xbffff890
: Examine a string stored at 0xbffff890x/20b sum
: Examine first 20 opcode bytes of function sumx/10i sum
: Examine first 10 instructions of function sum
Personal recommendation
x/2xd $rsp
: Examine first 2 decimals in $rsp
(Note: the format string for the ‘x’ command has the general form x/[NUM][SIZE][FORMAT] where NUM = number of objects to display, SIZE = size of each object (b=byte, h=half-word, w=word, g=giant (quad-word)), FORMAT = how to display each object (d=decimal, x=hex, o=octal, etc.). If you don’t specify SIZE or FORMAT, either a default value, or the last value you specified in a previous ‘print’ or ‘x’ command is used.)
Extra Information
backtrace
: Print the current address and stack backtracewhere
: Print the current address and stack backtraceinfo program
: Print current status of the programinfo functions
: Print functions in the programinfo stack
: Print backtrace of the stackinfo frame
: Print information about the current stack frameinfo registers
ori r
for short: Print registers and their contentsinfo breakpoints
: Print status of user-settable breakpointsdisplay /FMT EXPR
: Print expression EXPR using format FMT every time GDB stopsundisplay
: Turn off display modehelp
: Get information about gdb
Assembly related
Jump instructions
JMP
: Unconditional jump, doesnt need to check anything.JE
: Jump if equal.JNE
: Jump if NOT equal.JG
: Jump if greater.JGE
: Jump if greater or equal.JL
: Jump if less.JLE
: Jump if less or equal.
Complicated ones
You will most likely not use this so dont worry much.
JS
: Jump if sign flag is set, meaning, the result is negative.JNS
: Jump if sign flag is clear, meaning, the result is NOT negative.JO
: Jump if overflow flag is set, meaning, the result caused overflow.JNO
: Jump if overflow flag is clear, meaning, the result did NOT cause overflow.