Airplane writeup(iCTF2013).

Bay(Hackerdom, Russia)

Files: airplane.tar(deobfuscated)  spl.py 

1. The protocol

The service allows us to control aircrafts. It listens TCP/7331 port and has a text-based protocol.

CODE=LIST

A_0006=FLIGHT "A_0006": pos=[516,733] orig="Tokyo"([612,434]) dest="Antananarivo"([476,859])
A_0010=FLIGHT "A_0010": pos=[676,390] orig="Belgrade"([737,357]) dest="Berlin"([337,583])
A_0028=FLIGHT "A_0028": pos=[596,704] orig="Singapore"([683,650]) dest="Kabul"([236,930])
A_0037=FLIGHT "A_0037": pos=[820,850] orig="Hanoi"([963,663]) dest="Tripoli"([737,960])
A_0041=FLIGHT "A_0041": pos=[716,521] orig="Phoenix"([984,538]) dest="Philadelphia"([150,487])
A_0051=FLIGHT "A_0051": pos=[337,851] orig="Jakarta"([355,886]) dest="Philadelphia"([150,487])
A_0069=FLIGHT "A_0069": pos=[427,168] orig="Bangkok"([978,167]) dest="Tehran"([183,169])
A_0079=FLIGHT "A_0079": pos=[725,709] orig="Chicago"([105,832]) dest="Hanoi"([963,663])
A_0087=FLIGHT "A_0087": pos=[618,806] orig="Vienna"([449,109]) dest="Ankara"([624,828])
A_0098=FLIGHT "A_0098": pos=[345,668] orig="Beijing"([191,745]) dest="Rome"([865,410])
A_0109=FLIGHT "A_0109": pos=[537,472] orig="Vienna"([449,109]) dest="Ankara"([624,828])
A_0112=FLIGHT "A_0112": pos=[597,257] orig="Algiers"([688,211]) dest="Philadelphia"([150,487])
A_0129=FLIGHT "A_0129": pos=[345,924] orig="London"([475,943]) dest="Bucharest"([43,880])
A_0136=FLIGHT "A_0136": pos=[303,463] orig="Kiev"([341,556]) dest="Tehran"([183,169])
CODE=OK
FLAG=FLGRdmu34U5iPkS5


CODE=LIST
ID=A_0006

CODE=ERROR
RAND=�i�e���
SIGN=059956cd


CODE=SETPOS
ID=A_0006
RAND=IIIIIIII
SIGN=11111111
POSX=520
POSY=730

CODE=ERROR
RAND=�0H�9Y��
SIGN=3a8f5fc2

FLAG from answer - just a random string, not a real flag. SIGN from an answer is a: crc32(CODE:ERROR;RAND:<8 random bytes>;<unknown string>)

When we do SETPOS, we have to tell a valid SIGN from string: crc32(CODE:SETPOS;ID:<id>;POSX:<newx>;POSY:<newy>;RAND:<random string>;<unknown string(the same as previous)>)

RAND is not a part of protocol, we just can any strings to our request.

Each plane has a position, If the signature is valid, we can move the plane(not more than on 100 pixels a time). Our goal is to move it to make the angle between plane and orig-dest vector of that plane > 0.1 radians. After this we can ask for flag.

2. Exploitation

To exploit the service we should be able to sign our SETPOS request. We don't know <unknown string> from first example, but we do know the crc32(<some known data>;<unknown string>"). So, if we compose another string with crc32(<anther_data>")=crc32(<some_known_data>"), then the crc32 of whole string won't change. For crc32 this can be done relatively simply(see spl.py for details), four bytes is enough for this.

After that we send 20 SETPOS requests to move a plane 2000 points away from its position and send a request: CODE=LIST
FGID=A_0006

to get a flag.


If you have questions, or want to correct errors, mail me at bay@hackerdom.ru