0

PCI SSC Forbids SSL and “Early TLS”

-

On April 15, 2015 the PCI SSC released the PCI DSS v3.1.  The main cause for concern for most merchants and other entities (called “entities” hereonforth) that store, transmit and process cardholder data is the prohibition of using SSL and “Early TLS”.  The PCI SSC also released a supplement to assist entities in mitigating the issue.   The supplement references the NIST guideline SP800-52 rev1 for determining which are good ciphers and which are not.

The key point being what does “Early TLS” mean?  Does it mean TLSv1.0 and TLSv1.1 OR does it mean only TLSv1.0?  Are the entities supposed to disable all ciphers except anything that’s TLSv1.2?

Answer is (in consultant speak) “it depends”. 🙂

TLSv1.1 does theoretically have ciphers that are not ideal.  Example: CBC mode ciphers that are TLSv1.1 but there may be a potential for attacks on them given that in the past couple of years CBC has fallen multiple times (BEAST, POODLE).

Google Chrome lists the use of CBC-based ciphers (despite the fact that they’re TLSv1.1) to be obsolete.  Google Chrome essentially makes “obsolete cryptography” a function of using TLS v1.2-based ciphers.

Untitled2

Firefox allows the configuration of disabling TLSv1.0 and that can be done by typing “about:config” in the address bar.  The security.tls.version.min = 0 (means SSLv3), 1 (means TLSv1.0), 2 (means TLSv1.1) and 3 (means TLSv1.2).  The following screenshot shows the configuration snapshot (here the lowest allowed version is TLSv1.0).

Untitled3

Let’s start with what is definitely ok for PCI:

https://www.openssl.org/docs/apps/ciphers.html#TLS-v1.2-cipher-suites

 TLS_RSA_WITH_NULL_SHA256                  NULL-SHA256
 TLS_RSA_WITH_AES_128_CBC_SHA256           AES128-SHA256
 TLS_RSA_WITH_AES_256_CBC_SHA256           AES256-SHA256
 TLS_RSA_WITH_AES_128_GCM_SHA256           AES128-GCM-SHA256
 TLS_RSA_WITH_AES_256_GCM_SHA384           AES256-GCM-SHA384

 TLS_DH_RSA_WITH_AES_128_CBC_SHA256        DH-RSA-AES128-SHA256
 TLS_DH_RSA_WITH_AES_256_CBC_SHA256        DH-RSA-AES256-SHA256
 TLS_DH_RSA_WITH_AES_128_GCM_SHA256        DH-RSA-AES128-GCM-SHA256
 TLS_DH_RSA_WITH_AES_256_GCM_SHA384        DH-RSA-AES256-GCM-SHA384

 TLS_DH_DSS_WITH_AES_128_CBC_SHA256        DH-DSS-AES128-SHA256
 TLS_DH_DSS_WITH_AES_256_CBC_SHA256        DH-DSS-AES256-SHA256
 TLS_DH_DSS_WITH_AES_128_GCM_SHA256        DH-DSS-AES128-GCM-SHA256
 TLS_DH_DSS_WITH_AES_256_GCM_SHA384        DH-DSS-AES256-GCM-SHA384

 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256       DHE-RSA-AES128-SHA256
 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256       DHE-RSA-AES256-SHA256
 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256       DHE-RSA-AES128-GCM-SHA256
 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384       DHE-RSA-AES256-GCM-SHA384

 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256       DHE-DSS-AES128-SHA256
 TLS_DHE_DSS_WITH_AES_256_CBC_SHA256       DHE-DSS-AES256-SHA256
 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256       DHE-DSS-AES128-GCM-SHA256
 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384       DHE-DSS-AES256-GCM-SHA384

 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256      ECDH-RSA-AES128-SHA256
 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384      ECDH-RSA-AES256-SHA384
 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256      ECDH-RSA-AES128-GCM-SHA256
 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384      ECDH-RSA-AES256-GCM-SHA384

 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256    ECDH-ECDSA-AES128-SHA256
 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384    ECDH-ECDSA-AES256-SHA384
 TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256    ECDH-ECDSA-AES128-GCM-SHA256
 TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384    ECDH-ECDSA-AES256-GCM-SHA384

 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256     ECDHE-RSA-AES128-SHA256
 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384     ECDHE-RSA-AES256-SHA384
 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256     ECDHE-RSA-AES128-GCM-SHA256
 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384     ECDHE-RSA-AES256-GCM-SHA384

 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256   ECDHE-ECDSA-AES128-SHA256
 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384   ECDHE-ECDSA-AES256-SHA384
 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256   ECDHE-ECDSA-AES128-GCM-SHA256
 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384   ECDHE-ECDSA-AES256-GCM-SHA384

 TLS_DH_anon_WITH_AES_128_CBC_SHA256       ADH-AES128-SHA256
 TLS_DH_anon_WITH_AES_256_CBC_SHA256       ADH-AES256-SHA256
 TLS_DH_anon_WITH_AES_128_GCM_SHA256       ADH-AES128-GCM-SHA256
 TLS_DH_anon_WITH_AES_256_GCM_SHA384       ADH-AES256-GCM-SHA384
 TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 ECDHE-ECDSA-CAMELLIA128-SHA256
 TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 ECDHE-ECDSA-CAMELLIA256-SHA384
 TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256  ECDH-ECDSA-CAMELLIA128-SHA256
 TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384  ECDH-ECDSA-CAMELLIA256-SHA384
 TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256   ECDHE-RSA-CAMELLIA128-SHA256
 TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384   ECDHE-RSA-CAMELLIA256-SHA384
 TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256    ECDH-RSA-CAMELLIA128-SHA256
 TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384    ECDH-RSA-CAMELLIA256-SHA384

Now let’s see what may potentially be good from TLSv1.1 perspective (from NIST SP8000-52 rev1):

TLS_RSA_WITH_3DES_EDE_CBC_SHA           DES-CBC3-SHA
TLS_RSA_WITH_AES_128_CBC_SHA            AES128-SHA

Here’s a problem though per OpenSSL man page:
Untitled

If you’re using OpenSSL, how do you ensure that the browser is not negotiating the vulnerable TLSv1.0 ciphers? The only real answer seems to be by providing a cipher order for negotiation and hoping the client doesn’t cheat.  Most likely, the browser will negotiate a better cipher when it exists in the server and on the client and you’d avert the possibility of negotiation of a bad cipher.

According to experts, anything that uses CBC is inherently broken.  But disabling TLSv1.0 may make the server inaccessible to various older Android devices.  Also, if you’re using older Java Development Kits (JDK7 and below), do remember that the default ciphers may not hit the spot for PCI.

There’s an excellent site to help you configure each type of the server so you could become PCI compliant. This is an excellent site by Ivan Ristic to test your Internet-facing servers for configuration of SSL/TLS encryption.

In conclusion, configure browsers to minimally allow TLSv1.1 and configure servers to use TLSv1.2 to be PCI DSS compliant.  The road to TLSv1.1 compatibility and PCI DSS is filled with potholes and death-falls so do it at your own risk.

0

Genymotion and libhoudini.so Error

-

I recently started using Genymotion for emulating an Android image so I could test an app.  To install the app I simply dragged and dropped the apk file into the running Genymotion VM of the phone.  But for some reason the app just kept crashing with the error “unfortunately, your application has stopped”.

Running the following gave me a ton of output but this was what was the relevant bit:

$ adb -e logcat

java.lang.UnsatisfiedLinkError: Cannot load library: load_library(linker.cpp:750): library “/system/lib/libhoudini.so” not found

What in the world is libhoudini??? Some googling brought me to this post.

According to this I needed an ARM translation library so the app still thinks it’s running on an ARM processor (which it isn’t because it’s running in x86 Virtualbox hypervisor).  Simply drag-n-drop the ARM translation.zip file into the Genymotion VM and boom, you should be good to go!

0

Setting up a Windows 7 Kernel Development Environment

-

If you are writing some Ring0 (or privileged mode code), say something like device drivers in Windows you’d probably be better served with a separate development machine and a deployment machine. This helps you to write poor code and still not lose hair because your development machine blue screens! 🙂

My setup was using a Windows 8.1 development machine and a Hyper-V based Windows 7 machine for debugging. You will need to execute different tasks on the “guest” (Hyper-V based Windows 7 virtual machine) and some other tasks on the development machine.  I followed many of the things from the MSDN blog post here

On your guest machine you would want to setup a named pipe and setup debug settings. To do that this is what you need to do:

Setup a virtual com port in the Hyper-V Settings (File -> Settings) , this port will be used to communicate from the host machine to the guest to communicate the Kernel debugging commands.
Untitled

 

Now make sure that your target guest machine is configured to “listen” those commands.  Inside the guest VM, start a command shell (cmd.exe -> Run as Administrator).

Untitled2

 

Configure the bcdedit commands so that the machine can now be debugged.  Right after the 2nd command, reboot your Virtual Machine.

Untitled3

 

With the VM now configured to listen the debug commands via the COM1 port, and the debug mode on in the bootup settings, now start the WinDbg x64 on the host (using “Run as administrator”; you need administrative privileges for communication via Serial port).  In your kernel debugger on the host or the development machine (I’m assuming that these are both on the same physical hardware here).  Click on File -> Kernel Debug and you should see the following screen in the WinDbg window:

Untitled4

Hit Ctrl+Break or Debug -> Break and you will see something like this:

Untitled5

Just remember that when you break in the debugger, your guest in Hyper-V should become “unresponsive”.  The only thing is that it is not really unresponsive, its just being debugged.  Just to make sure, that you have the symbols package that is quite useful for debugging run the following command:

!process 0 0

If you see something like the following screen show up:

Untitled6

The following error means that the symbols are not defined.  Symbols help the debugger give more information about the commands that you are going to execute in the debugger.

**** NT ACTIVE PROCESS DUMP ****
NT symbols are incorrect, please fix symbols

To fix this, use the following commands:

kd> .sympath SRV*c:\symcache*http://msdl.microsoft.com/download/symbols
kd> .symfix
kd> .symfix c:\symcache
kd> !sym noisy
kd> .reload /o

Then again try the command: !process 0 0 and see if you get a good response.  A good response looks like the following:

Untitled7

With this you should be good to go! Happy debugging and writing cool Ring0 code.

 

 

0

DefCon CtF Quals 2014 writeup – hackertool

-

hey, we need to check that your connection works, torrent this file and md5 it

http://services.2014.shallweplayaga.me/hackertool.torrent_fe3b8b75e9639d35e8ac1d9809726ee2

The torrent file when loaded into Vuze showed that the file name was every_ip_address.txt. So I downloaded some of the file and observed the format. The format of the file was “0.0.0.1\n0.0.0.2\n…. “.

So I wrote a quick python script to calculate the md5:

#!/bin/python
import hashlib
m = hashlib.md5()
fsize = 0
a = ''
for i in xrange(256):
    for j in xrange(256):
        for k in xrange(256):
            for l in xrange(256):
                a = str(i)+'.'+str(j)+'.'+str(k)+'.'+str(l)+'\n'
                fsize += len(a)
                m.update( a )
print m.hexdigest()

The flag was “1a97f624cc74e4944350c04f5ae1fe8d”.

0

Cisco IPSec VPN Client Reason442: Failed to Enable Virtual Adapter

-

If you use Windows 8 x64 and when you launch the Cisco VPN Client adapter and you see the following error:
Reason 442: Failed To Enable Virtual Adapter Here’s how to fix it.
Open your command prompt in Administrator mode by right clicking at the left lower corner of the screen and going to “Command Prompt (Administrator)”. You will have to log in as an administrator. Launch registry editor by typing “regedit.exe”. Browse to “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CVirtA“. In the DisplayName key, you will see something like @oem8.inf,%CVirtA_Desc%;Cisco Systems VPN Adapter. Edit that to just say Cisco Systems VPN Adapter. Try to connect again by launching the VPN Client. It should work!

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

Verizon FiOS and PS3 Media Server Streaming Issues

-

If you’re like me and recently upgraded to Verizon FiOS and you have your PS3 on the wired segment and the Media Server (such as PS3 Media Server, TVersity, etc.) on the wireless segment, you’re in for a ride with the configuration.
By default, you can’t route the traffic between the wired and wireless segments over UDP! You can send ICMP echo packets (i.e., ping) but the PS3 just won’t detect the Media server. You may disable the Host-based firewall (e.g., Norton, Kaspersky, McAfee, etc.) but it still won’t work.

If you happen to read posts like these, you will see that you have to disable “IGMP proxy”. IGMP Proxy basically reduces the traffic on the multicast addresses to a bare minimum. Unfortunately for you, this causes the traffic between PS3 Media Server and PS3 to drop.

So you log into your FiOS router’s administration console typically located at 192.168.1.1. Click on Advanced -> Yes -> Firmware Upgrade and check the firmware version. You will see that it is an ActionTec router (based on the Auto-update URL). But nowhere do you see the option to update the “IGMP Proxy” settings. That’s because that feature is “hidden” in the latest firmwares.

So you just need to copy/paste the following URL into the browser address bar and you will see the option to disable “IGMP proxy”.
http://192.168.1.1/index.cgi?active_page=6059
Disable it and Voila! The PS3 Media Server and PS3 can now talk to each other.