Mon, Jul 05, 21
Welcome back to my walkthrough of hackthissite.org’s CTF missions. I will be going through my thought process of how I solved these missions, and therefore also giving away the solutions. If you came across this to give you hints, watch out for spoilers! Good luck, have fun.
This mission gives us 120 seconds take an XML document that describes an image, and draw said image. The image will show codes in different colours, which we are then supposed to enter on the website as the key for the mission.
The following code is what I wrote in python to solve this mission. In order to facilitate me, I used two different modules: xml.etree.ElemenTree to parse the XML, and matplotlib for drawing.
import xml.etree.ElementTree as ET
import matplotlib.pyplot as plt
from matplotlib.patches import Arc as matArc
class Arc:
"""
Represents an Arc that must be drawn
"""
colour = "white"
def __init__(self, xCenter, yCenter, radius, start, extend):
self.extend = extend
self.xCenter = xCenter
self.start = start
self.yCenter = yCenter
self.radius = radius
def setColour(self, colour):
self.colour = colour
def draw(self, ax):
"""
Given a subplot object, plot this Arc
"""
diam = self.radius * 2
ax.add_patch(matArc((self.xCenter, self.yCenter), diam, diam, theta1 = self.start, theta2= self.extend, color = self.colour))
class Line:
"""
Represents a Line that must be drawn
"""
colour = "white"
def __init__(self, yStart, yEnd, xStart, xEnd):
self.yStart = yStart
self.yEnd = yEnd
self.xStart = xStart
self.xEnd = xEnd
def setColour(self, colour):
self.colour = colour
def draw(self, ax):
"""
Given a subplot object, plot this Line
"""
ax.plot([self.xStart, self.xEnd], [self.yStart, self.yEnd], color = self.colour)
def extractArc(arc):
"""
Given a XML Arc tree structure, returns an Arc object.
"""
attr = {}
colourSet = False
for child in arc:
if (child.tag == "XCenter"):
attr["xCenter"] = float(child.text)
elif (child.tag == "YCenter"):
attr["yCenter"] = float(child.text)
elif (child.tag == "Radius"):
attr["radius"] = float(child.text)
elif (child.tag == "ArcStart"):
if float(child.text) < 0:
attr["start"] = 360 + float(child.text)
else:
attr["start"] = float(child.text)
elif (child.tag == "ArcExtend"):
attr["extend"] = float(child.text)
elif (child.tag == "Color"):
attr['colour'] = child.text
colourSet = True
attr["extend"] += attr["start"]
a = Arc(attr["xCenter"], attr["yCenter"], attr["radius"], attr["start"], attr["extend"])
if (colourSet):
a.setColour(attr["colour"])
return a
def extractLine(line):
"""
Given an XLM Line tree structure, returns a Line object.
"""
attr = {}
colourSet = False
for child in line:
if (child.tag == "YStart"):
attr["yStart"] = float(child.text)
elif (child.tag == "YEnd"):
attr["yEnd"] = float(child.text)
elif (child.tag == "XStart"):
attr["xStart"] = float(child.text)
elif (child.tag == "XEnd"):
attr["xEnd"] = float(child.text)
elif (child.tag == "Color"):
attr["colour"] = child.text
colourSet = True
l = Line(attr["yStart"], attr["yEnd"], attr["xStart"], attr["xEnd"])
if (colourSet):
l.setColour(attr["colour"])
return l
def parsePlotInfo():
"""
Extracts XML plot objects and retursn an array of those objects.
"""
tree = ET.parse('data')
root = tree.getroot()
plotObjects = []
for child in root:
if (child.tag == "Arc"):
arc = extractArc(child)
plotObjects.append(arc)
elif (child.tag == "Line"):
line = extractLine(child)
plotObjects.append(line)
return plotObjects
def draw(plotObjects):
"""
Given an array of plot Objects, initiate a canvas and plot them.
"""
# init the canvas
fig, ax = plt.subplots()
ax.set_facecolor("black")
# iterate through all plotObjects & draw them
for o in plotObjects:
o.draw(ax)
plt.show()
if __name__ == "__main__":
plotObjects = parsePlotInfo()
draw(plotObjects)