0

PlaidCTF 2013 – Crypto 250 Compression Writeup

-

On the recently concluded PlaidCTF (which was an awesome competition) by PPP there was a problem.  Here it goes:

Question: We managed to get the source code for an encryption service running at 54.234.224.216:4433.

I have listed the python source provided below:

#!/usr/bin/python
import os
import struct
import SocketServer
import zlib
from Crypto.Cipher import AES
from Crypto.Util import Counter

# Not the real keys!
ENCRYPT_KEY = '0000000000000000000000000000000000000000000000000000000000000000'.decode('hex')
# Determine this key.
# Character set: lowercase letters and underscore
PROBLEM_KEY = 'XXXXXXXXXXXXXXXXXXXX'

def encrypt(data, ctr):
    aes = AES.new(ENCRYPT_KEY, AES.MODE_CTR, counter=ctr)
    return aes.encrypt(zlib.compress(data))

class ProblemHandler(SocketServer.StreamRequestHandler):
    def handle(self):
        nonce = os.urandom(8)
        self.wfile.write(nonce)
        ctr = Counter.new(64, prefix=nonce)
        while True:
            data = self.rfile.read(4)
            if not data:
                break

            try:
                length = struct.unpack('I', data)[0]
                if length > (1<<20):
                    break
                data = self.rfile.read(length)
                data += PROBLEM_KEY
                ciphertext = encrypt(data, ctr)
                self.wfile.write(struct.pack('I', len(ciphertext)))
                self.wfile.write(ciphertext)
            except:
                break

class ReusableTCPServer(SocketServer.ForkingMixIn, SocketServer.TCPServer):
    allow_reuse_address = True

if __name__ == '__main__':
    HOST = '0.0.0.0'
    PORT = 4433
    SocketServer.TCPServer.allow_reuse_address = True
    server = ReusableTCPServer((HOST, PORT), ProblemHandler)
    server.serve_forever()

The key on this challenge is to see that the stream encryption is being done on the compressed input. In the source provided, if the user input is similar to the secret value in the PROBLEM_DATA variable then the zlib.compress() function would show a reduced length ciphertext. This is somewhat (and I use the term loosely) similar to the CRIME vulnerability. The AES Counter mode RFC has the implementation details of the cipher. So I wrote the following script.

import socket
import sys
from itertools import *
import struct
def display(msg,numbytes):
	#print >>sys.stderr, 'received "%s"' % msg
	#print >>sys.stderr, 'bytes "%d"' % numbytes
	print >>sys.stderr, 'bytes %d ' % numbytes + msg.encode('hex')
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = ('54.234.224.216', 4433)
print >>sys.stderr, 'connecting to %s port %s' % server_address
sock.connect(server_address)
#mesage len = 20 lowercase and underscore letters
try:
	amount_received = 0
	nonce = sock.recv(8)
	amount_received += len(nonce)
	# Send data
	#strng = 'crime_some'
	#minciphlen = 1000
	#strng = 'crimes_pays'
	#strng = 'so_'
	#strng = 'crime_some_times_pays'
	#strng = 'somet_'
	strng = 'cr'
	minchar = ''
	ciphlen = 1000
	sampleset = 'hijklmnopqrstuvwxyz_abdefgc'
	#while True:
	strng = strng + minchar	
	minciphlen = ciphlen
	minchar = ''
	for s in map("".join,permutations(sampleset,1)):
		#message = nonce +  (strng + s)*10  #'\x00'*11 + s
		message = strng + s
		datalen = struct.pack('I',len(message))  # datalen = '\xe4\x00\x00\x00'
		sock.sendall(datalen)
		#print >>sys.stderr, 'sending '+ message
		sock.sendall(message)
		#print >>sys.stderr, 'message sent'
		amount_received = 0
		# Look for the response
		data = sock.recv(4)
		amount_received += len(data)
		ciphlen = struct.unpack('I', data)[0]
		#print >>sys.stderr, message + ' ' 
		amount_received = 0
		if ciphlen <= minciphlen:
			minciphlen = ciphlen
			minchar = s
			print str(ciphlen) + ' It is ' + strng + minchar
		data = sock.recv(ciphlen)
		#display(data,ciphlen)		
finally:
    print >>sys.stderr, 'closing socket'
    sock.close()

When you connect to the service it provides you the nonce, so I prepended the nonce to the plaintext. The above script shows the plaintext and the length of the cipher text. To start off with this, you start with a string of length 1, and see which is the smallest length response, that gives your first character. Then in the

strng

variable above, you add that character and run again, and the lowest length ciphertext tells you the next character and so on. I noticed that sometimes the output had a few characters with the lowest length. So I tried each of them and ended up with the following flag:

crime_sometimes_pays 
0

ASA Fails to parse certificates

-

Last night I was trying to get a VeriSign issued SSL certificate installed on my ASA using Cisco ASDM 6.2. I installed the Intermediate CA and the CA certificates all installed. I then imported the SSL certificate into the “Configuration -> Device Management -> Manage Certificates -> Identity Certificates” but it did not seem to work. I kept getting an error “Failed to parse or verify imported certificate”. The certificate was in the .p7b form. Changing the format of the certificate to X.509 Base64 Encoded format resulted in acceptance of the certificate.
I sincerely hope that Cisco alters its error messages to accurately reflect that .p7b is not a format supported by them.

Update: This link has the information on how to install SSL certificates on ASA:

http://www.cisco.com/en/US/products/ps6120/products_configuration_example09186a00809fcf91.shtml

0

Converting Java Key Store into X.509 certificates

-

Web services security has been very much talked about in the recent times. Especially, with the Service Oriented Architecture (SOA) gaining increasing importance. One of the interesting ways to protect these web services encapsulated in SOAP (Simple Object Access Protocol) is using digital client-side authentication certificates. Programmers typically use Java Key Store (.JKS) files to establish connectivity to these applications. However, if we want to create a custom client using some scripting it creates an issue as we tend to use languages such as perl, bash, etc. to create connectivity. So I ran into this excellent tool called KeyTool IUI. This tool helps you import the Java Key Store (Tools -> Keystore Manager -> JKS Keystore) and export it in the PKCS#12, X.509 PEM, and DER formats. You can further use OpenSSL to change the formats as you please or separate out the components of the certificates.
You could even take these certificates in X.509 or PFX formats and convert into JCEKS, JKS formats! Pretty cool huh? :-) Nice software!

0

NTLM Rainbow Tables generation

-

What www.hak5.org started was quite commendable and I’m really not sure what the status of the Community Rainbow Tables project is at hak5.
They are generating the rainbow tables with the following configuration:


* NTLM
* mixalpha-numeric-all-space
* [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_+=~`[]{}|\:;"'<>,.?/ ]
* 26 indexes, 22 files/index
* 572 tables total
* 340.93GB
* 96.07% probability of successful crack

I’m currently generating index 13 and index 26 on this configuration. It would be cool to have multiple people generate it and upload it. I know many people are already doing that as we speak. We should also have SHA1, MD5 project for mixalpha-numberic-all-space configurations.

2

John the Ripper 1.7.2 – Jumbo patch

-

I’ve been struggling to find the best working version of John so that it can crack MS Cache outputs from Cachedump (of course, this functionality is now included in fgdump). Running fgdump gives two files host.pwdump and hostname.cachedump. I’ve found 127.0.0.1.pwdump and 127.0.0.1.cachedump files upon using fgdump without any parameters.
So now you have the Cached credentials but then comes the big problem of cracking those. So there’s the jumbo patch for john-1.7.2.
Following commands need to be executed to get this patch going:


$ tar zxvf john-1.7.2.tar.gz
$ cd john-1.7.2/
$ wget http://www.openwall.com/john/contrib/john-1.7.2-all-9.diff.gz
$ gzip -d john-1.7.2-all-9.diff.gz
$ patch -p1 <john-1.7.2-all-9.diff
$ cd src/
$ make linux-x86-sse2


You get some warnings upon compilations but the executable works very well.

Go ahead and get cracking:
$ cd run/
$ ./john –format=mscash

2

Using Certificates with cURL

-

The problem: Using Digital Certificates issued by a Certification Authority (CA) with curl.

The situation: I have a .cer (Digital Certificate) file, .pfx (Personal Information Exchange file i.e., the private key for the certificate). I cannot use either of these to authenticate to the web service as curl would not accept these formats.

The solution:
1) Convert it into PEM format (X.509 certificate) using openssl.
openssl pkcs12 -in abcd.pfx -out abcd.pem
Enter a passphrase and a password.
2) Still you cannot use this with curl because you’d get a few errors.
3) Convert this PEM certificate into three different certificates for the client, the private key and the certification authority certificate.
openssl pkcs12 -in abcd.pfx -out ca.pem -cacerts -nokeys
openssl pkcs12 -in abcd.pfx -out client.pem -clcerts -nokeys
openssl pkcs12 -in abcd.pfx -out key.pem -nocerts
4) Use the following command:
curl -k https://www.thesitetoauthenticate.com/test -v –key key.pem –cacert ca.pem –cert client.pem:

This stuff is also mentioned on curl forum at http://curl.haxx.se/mail/archive-2005-09/0138.html