picoCTF 2018
i know it’s kinda old but i really love this kind of rop challenge.
1. Source code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdbool.h>#define BUFSIZE 16bool win1 = false;
bool win2 = false;void win_function1() {
win1 = true;
}void win_function2(unsigned int arg_check1) {
if (win1 && arg_check1 == 0xBAAAAAAD) {
win2 = true;
}
else if (win1) {
printf("Wrong Argument. Try Again.\n");
}
else {
printf("Nope. Try a little bit harder.\n");
}
}void flag(unsigned int arg_check2) {
char flag[48];
FILE *file;
file = fopen("flag.txt", "r");
if (file == NULL) {
printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
exit(0);
}fgets(flag, sizeof(flag), file);
if (win1 && win2 && arg_check2 == 0xDEADBAAD) {
printf("%s", flag);
return;
}
else if (win1 && win2) {
printf("Incorrect Argument. Remember, you can call other functions in between each win function!\n");
}
else if (win1 || win2) {
printf("Nice Try! You're Getting There!\n");
}
else {
printf("You won't get the flag that easy..\n");
}
}void vuln() {
char buf[16];
printf("Enter your input> ");
return gets(buf);
}int main(int argc, char **argv){setvbuf(stdout, NULL, _IONBF, 0);
// Set the gid to the effective gid
// this prevents /bin/sh from dropping the privileges
gid_t gid = getegid();
setresgid(gid, gid, gid);
vuln();
}
2. Way of thinking
first of all, i audit the source a little bit and i notice that there are 4func that we need to focus on: vuln
,win_function1
, win_function2
, flag
.
to get to the flag, you have to line up the GOT win1
, win2
and pass an arg 0xdeadbaad
before calling the flag function.
ok then, let’s jump to the m4g1k!!!
3. Hacking
first, let’s check if there are any protection on the binary (because the remote server don’t have gdb-peda, which have checksec
, and of course from myself don’t have enough knowledge about testing the binary)
you can see, only NX on (and the ASLR off too), it’s make our exploit a lot easier
Now let dump disassembler mnemonics of those function we notice before
Now, let’s build our payload (i’m a one-liner command ^.^)
We got our offset from vuln
which is 0x18 + 4
. The next 4 bytes is win_function1
to set the GOT win1
to true.
next the the win_function2
, we have to push 0xBAAAAAAD
to set win2
to true (remember the flag
address after the win_function2
)
and when you came to the flag
function, push 0xDEADBAAD
to stack
now, our final payload become
28 byte offset + '\xcb\x85\x04\x08' + '\xd8\x85\x04\x08' + '\x2b\x86\x04\x08' + '\xad\xaa\xaa\xba' + '\xad\xba\xad\xde'
enjoy hacking!!!