In the last post I've promised that I need to look a bit more into the Security Pwning CTF, here are a few more solutions to CTF by p4.

web 100 - Bulletproof Login Server™

In this task we are give a part of the server code and a login panel that located under https://monk.pwning2016.p4.team/login.php

by examine the code we can see that data that's being passed from a cookie is deserialized and is loosely compared with admin or demo user data. I think we can trick it to let us through. Let's use curl here.

curl -v https://monk.pwning2016.p4.team/admin.php -b 'remember_me={"login":"admin", "token":0}'

so we are passing some data in the cookie (-b) and the name will be remember_me and as the login we pass "admin" and as the token we are passing 0 as int. Since the loose comparison in PHP there will be a conversion of whatever is passed from getAuthToken to float and probably the conversion will fail (I assume the getAuthToken returns some kind of hash) and the == will evaluate to true and we will gain the access.

When we run our command we can see the flag in the output:

pwn{unserialize.happens.to.be.ivul}

pwn 150 - Nawias musi się zgadzać

In this task we are given the file and an address at which this program can be accessed nc pwning2016.p4.team 1337.

We load this program into r2.

main is quit simple. Let's analyze check_my_brackets

It is a bit more complex but the most important bits are at the beginning

Here

and here

Also by closer inspection of methods in the code we see this shell_me function.

So to sum up:

  • there's a char buffer on stack and there's no check for valid range
  • the method check brackets and in case of "correct" expression being passed returns from it
  • in case of invalid one, text is printed inside and a call to exit is made

So if we want to exploit the buffer and run shell_me function we need to provide a "correct" expression

Ok. Time to for some python. For pwning we will use pwntools. A library that makes exploitation easy. The nice feature is that you can easily switch from attacking a ELF file on your local machine to targeting over a socket.

But before that we need our payload:
payload = ''.join("()"*62)+struct.pack("I",0x0)+"AAAAAAAA"+struct.pack("Q",0x00000000004005f6)

What we are sending here? First the brackets - we fill he buffer. Next is the counter - we set it to zero so that we do not influence the counting mechanism. Then few chars and at the end we send the address of the return method. After that we call interactive() and if everything works we get the shell.

The full script

pwn{b1n4ry_expl01t1ng}

re 100 - Rex

In this task we are again given with the binary that we load to IDA (free).

We quickly locate the 'check password' code and obtain the information that expected password is 26 characters long (flag_len)

The main part of flag check is here:

and here

If we go into the do_more_with_char method we can see that it's generates some kind of values from which later we take the value at index of the input char and later we compare it with correct encoded flag:

0x7e 0xe9 0xf3 0x71 0x80 ...

We know that the flag should start with pwn{ so we input it as a flag and in fact we get few first values to be 0x73 0xe9 pxf3 0x71. What about the next ones?

We'll use gdb. Let's put a breakpoint on the line:

then we search for the searched value in the memory

and calculate the offset and the password char.

in this case r. By doing this process few ;) more times (I guess it could be somehow automated?) we extract the whole flag.

Flag: pwn{rc4_j3st_dl4_b13dnych}

Ok so next 3 tasks from Security Pwning CTF done. What's left is crypto. I'll deal with them in the last post.