Tamu19 pwn1 (32-bit)
1. Analysis
1.1 Basic
This tells us that it is a 32-bit ELF
The following security are implemented:
No-eXecute (NX) enabled
PIE enabled
1.2 Ghidra
main function (Decompile view)
main function (Decompile view) Refined main function
main function Assuming that all the inputs passes the checks, the program will initially read in 0x2b bytes of inputs twice into the input variable using the fgets function, and a final input into the same variable using the gets function. Since the gets function simply reads the input until a newline character or EOF is encountered, this means that we can overflow the buffer allocated to the input and overwrite subsequent portions of the memory.

From the variables listing, we know that the input variable has an offset of 0x43-0x18=0x2b from the target variable.
I will skip the explanation of the rest of the deassembled/decompiled code regarding the comparisons, and the reading of the flag value. Instead, I would like to focus on the calling conventions and analysis of the 32-bit architecture with GDB
1.3 GDB
The following instruction corresponds to the following line in the decompiled code:
Lets focus on the push instruction on line 0x565558a9. Recall that for x86 (32-bit) systems, function arguments are pushed via the stack. In this case, the argument value is temporarily stored in the eax register before it is pushed to the stack
We can see that the
eaxis currently storing the value0xffffccbdViewing the contents of the said address in stack, we can see that the first 3 bytes contains the value
0x206f54.

Execute the next instruction
We can see now that the value
0xffffccbdis pushed to the stack

Now, lets analyse the next instruction (
getsfunction)To make it simple, lets create an input binary, and set a breakpoint to right after the last instruction and restart the program
From analysis of the source code in Ghidra, we know that we are required to input the values Sir Lancelot of Camelot\n and To seek the Holy Grail.\n to the initial 2 inputs. Following, we can input a crafted payload to overwrite a portion of memory to bypass the checks.
We can use the following commands to create an input binary which simply overwrites the required portion of memory with \x12\x34\x56\x78:
Now, we can see that the value at
0xffffccbd(3 character from right of the0xffffccbcline) contains the value0x563412
Note that the stack view shows the MSB -> LSB from left -> right
In this case,
0x12is the LSB (lower address), while0x56is at the MSB (higher address)

Creating a test payload
Notice that the offset value (between the
inputandcompare)0x2bis equals to 43 in decimal, which is the size declared in the decompiled C code:
We can modify the python script to append additional
0x2bbytes of payload in the beginning:
The first 3 bytes at address
0xffffccbdnow contains the value0x303030which is simply the string000

Further analysis of the contents presents us with the full picture
As expected, we have overwritten 0x2b bytes of memory with 0x30s.
We can see the value
0x563412at the bottom right, this corresponds to the address of thetargetvariable for which we have overwritten
Remember the stack view: MSB -> LSB as noted before
Last updated