Hidden Program (Warmup)
Molly found this program hidden on her chip, can you help her to understand it?
Link:
https://cloud.ufscar.br:8080/v1/AUTH_c93b694078064b4f81afd2266a502511/static.pwn2win.party/hiddenprogram_d502a4418484effac415ffb57dfd658b1123dd530fd01714755958bd4b8c1289.tar.gz
Mirror:
https://static.pwn2win.party/hiddenprogram_d502a4418484effac415ffb57dfd658b1123dd530fd01714755958bd4b8c1289.tar.gz
Server: nc 200.136.213.126 1988
Id: hidden_program
Total solves: 145
Score: 82
Categories: Exploitation
After extracting we have a .c file:
1 | #include <stdio.h> |
Resuming what this program is doing, first it opens the flag file from the server and stores it in the c struct field p1.flag:1
2
3
4FILE *fp = fopen("/home/user/ctf/flag","r");
memset(p1.flag,0,sizeof(p1.flag));
fscanf(fp,"%[^\n]",p1.flag);
fclose(fp);
Then reads from the stdin using scanf for a short int (stores it in p1.n= and two strings (stores them in p1.in and p1.sub).
1 | while(1) { |
In the end we have this check:
1 | if(strcmp(&p1.in[p1.n],p1.sub)==0) |
Well the strcmp does a compares between p1.n[p1.n] character and the string p1.sub, if they are equal it prints out the string “Congratulations!! YOU WIN!!\n”, well we can see that making strcmp matching this will lead to nothing just a useless string, what we are interested what comes after else…
Since we can control the index with p1.n, we can actually make this printf to print the flag which is p1.flag we just need to get the offset between p1.in and p1.flag we can get this easily with gdb:
First lets compile the file with gcc:
1 | $ gcc hiddenprogram.c -ggdb -o lol |
The –gdb is very useful gives us alot of debugging information with gdb, we can view where we are located in the source code, breakpoints indicating the line numbers and even print variables by just using its names much easier than looking at assembly and print using addresses right?
After using gdb we know where each variable from the struct begins doing a simple subtraction we can get the offset we need to print the flag:
1 | $ python -c "print 0x5555557550a0-0x55555575d0a0" |
The real problem in all this is that we need a negative value, and there is a ABS function making us fail:
1 | p1.n = (short)abs((short)p1.n); |
For some reason actually after the negative number when >= -32768 the abs won’t do anything (I don’t really know why maybe its because the short cast? but if you know why this happens please tweet me or make a post in the comments)! this is perfect that’s what we really needed, you can see how the abs is doing with this program:
1 |
|
Running it:1
2
3
4
5
6
7$ gcc wtf.c -o wtf
wtf.c: In function ‘main’:
wtf.c:4:21: warning: implicit declaration of function ‘abs’ [-Wimplicit-function-declaration]
int below=(short)abs((short)-32767);
^~~
$ ./wtf
32767 -32768 32767
Now applying this with the service we get the flag by injection -32768:
1 | nc 200.136.213.126 1988 |