Analyzing the Shadow Brokers text.

There are several tools available that will examine the word choice, phrases and grammatical structure of text and provide analysis of the writers/authors. I am fairly certain that the way we express information is fairly unique and that algorithms today are linking materials posted in various venues together and attributing them to particular individuals. This analysis is baby steps on comparison and just for fun; the tools are far from precise and the text sample length is far too short. I also suspect that it was purposefully modified to try and remove identifying signatures, but let’s see what we can find.

As many know, the Shadow Brokers released a set of information that included some text (with the bitcoin address removed):

How much you pay for enemies cyber weapons? Not malware you find in networks. Both sides, RAT + LP, full state sponsor tool set? We find cyber weapons made by creators of stuxnet, duqu, flame. Kaspersky calls Equation Group. We follow Equation Group traffic. We find Equation Group source range. We hack Equation Group. We find many many Equation Group cyber weapons. You see pictures. We give you some Equation Group files free, you see. This is good proof no? You enjoy!!! You break many things. You find many intrusions. You write many words. But not all, we are auction the best files.

We auction best files to highest bidder. Auction files better than stuxnet. Auction files better than free files we already give you. The party which sends most bitcoins to address: before bidding stops is winner, we tell how to decrypt. Very important!!! When you send bitcoin you add additional output to transaction. You add OP_Return output. In Op_Return output you put your (bidder) contact info. We suggest use bitmessage or I2P-bote email address. No other information will be disclosed by us publicly. Do not believe unsigned messages. We will contact winner with decryption instructions. Winner can do with files as they please, we not release files to public.

From looking at the text, the sentences are very short and lack proper grammar. (please excuse my own) Two times commas were used correctly in poorly worded sentences and twice it was used incorrectly to join two sentences. Many of the sentences are very short but linguistically, I am not sure this points to translation issues.

The first tool is a gender analyzer:
This tool reports that there are not enough words for a good read with only 215 out of the suggested minimum of 300 words. So a point to consider, was the amount of text purposefully kept short to limit exposure. The tool rated the text author as overwhelmingly male (85.9%) for informal writing but for formal, it would be female (75.21%).

The next analysis tool starts to dig much deeper and as a result ist more interesting. It is based on IBM’s Watson services, Tone Analyzer:
Overall, the text rated highly on Anger (0.74), Extroversion (0.98) and Agreeableness (0.95) and interestingly, but probably not surprising very low on Openness (0.03).

The sentences with the highest Anger rating were:
0.47 How much you pay for enemies cyber weapons?
0.44 When you send bitcoin you add additional output to transaction.
0.38 Do not believe unsigned messages.
0.38 Winner can do with files as they please, we not release files to public.
0.36 You write many words.
0.34 No other information will be disclosed by us publicly.
0.33 We hack Equation Group.
0.32 We follow Equation Group traffic.

And those with the lowest:
0.11 You break many things.
0.10 But not all, we are auction the best files.
0.10 Auction files better than stuxnet.
0.07 We will contact winner with decryption instructions.
0.07 We auction best files to highest bidder.
0.00 You see pictures.
0.00 You enjoy!!!
0.00 Very important!!!

And the highest on Agreeableness:
0.99 We give you some Equation Group files free, you see.
0.99 We will contact winner with decryption instructions.
0.99 We hack Equation Group.
0.99 We follow Equation Group traffic.
0.98 Auction files better than free files we already give you.
0.98 We auction best files to highest bidder.

The next tools are from uClassify.
The first I tried is the Sentiment classifier and it gave it a slightly negative rating (56%) over positive (44%).
GenderAnalyzer_v5 gave the text a male (77%) classification.
Ageanalyzer struggled a bit, producing an age range of 65-100 with a 31% rating; next was a 24% rating for age range 26-35.
Mood was analyzed to be 95% Happy.
While there are a rather large number of classifiers available, this last one from uClassify, I found interesting, Value. It rated the text as Exploitive (44%) and Achieves (22%). The authors are taking advantage of what they found and bragging about it. While not surprising, it was interesting to see the tool pick up on it.

The last tool from Readability Score is one I like to use on my own works to help judge the readability and grade level of the writing. Given the short sentences, it is not too surprising that the level is approximately 6th grade and rated easy to read.


One of my favorite ways to bypass XSS input filters is with Unicode characters. What happens is the string like “%26#60;script%26#62;alert(1);%26#60;/script%26#62;” is sent to the server. The input filters find nothing wrong with it so it passes through fine. When it hits the web server, it attempts to normailze the characters and subsitutes approximates. So &#60; or &#x3c; will become “<“.

Here are a few Unicode strings that I will try out.

\074\057a\076\047\074script\076 alert(1) \074/script\076 // 


How to Recover a Lost iPad or iPhone Restrictions Pin

Too many pin and passwords and I forgot the Pin for the Restrictions setting on our family’s iPad. Apple used to store it clear text in the iTune backup, but now its just slightly harder to find.
This is for iOS 7+ and in my case 9.3.X and using iTunes on a Mac
Backup your iDevice.
Navigate to /Users/YOURACCOUNT/Library/Application Support/MobileSync/Backup/DEVICEBACKUPFOLDER
Where DEVICEBACKUPFOLDER will be a 40 randomish character string – There will be a DEVICEBACKUPFOLDER folder for each backed up device.
If you do not see the /Library/ directory, select the “Go” tool bar menu and then press and hold the “Option” key; it should toggle/show a “Library” option you need to select.
Find and open the file 398bc9c2aeeab4cb0c12ada0f52eea12cf14f40b in TextEdit
You will find the following:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

The two data values will be different for your device; this is the stored pin. I did not change the values in the above; I set a temporary key to use in this example so you can test this yourself.

Go to Recover iOS7+ Restrictions Password and copy and paste the PasswordKey data string, this the above case: zm+4u+x37mZZb4wxEJxcYKNqvfo=
and copy and paste the PasswordSalt data string: ZOsf/w==
and select “Search for Code.” It will attempt to brute force all possible code combinations until it finds a match; this could take a while to grab a coffee. In the above case, pin it will find should be “1111”.

Playing with XSS

Want to learn more about XSS attacks – well the best way is probably to try some yourself. Here are two sites that offer XSS games that allow you to test and improve your skills.

One of my favorite strings to use in testing XSS when I am doing pen testing is the following:
<iframe src=//></iframe>
It will add an embedded iframe for the youtube video Rick Roll. 🙂 Its always amusing to see all the places I can get a Rick Roll to appear.
BTW, to keep the link from rendering, I had to HTML endode < to &lt;, and for good measure also change > to &gt; and change the & in &lt; to &amp;.

ShellShock Worm hitting QNAP NAS devices

Several months later and now a worm has been released hitting QNAP devices. It spreads by connecting to QNAP devices open to the internet (yeh, brilliant thing to do) that have not been patched. (just as brilliant) 🙂

How can I tell if my device is infect?
Look in /etc/shadow and /etc/passwd for an account named “request” If you find it, your infected.

I am infected! Help!
To delouse your system, go to QNap’s page.

How can I tell if my device is vulnerable to ShellShock?
SSH into your device and run the following command: (use at your own risk)
curl | bash
More information can be found at

How do I patch my device if it is vulnerable?
If your already infected, the worm nicely patches your system. How considerate. 🙂
Else, go to QNap’s page for instructions on how to update your device.

Test Your Server for the Poodle Vulnerablity

The latest crypto issue to hit is the “Poodle” attack. A good explanation of poodle can be found at the openssl website.

The simplest way to test your server is an online scanner at .
Putting results in the following report:
Scan results ( - Vulnerable

This server supports the SSL v3 protocol.

But how does one test a server that is not online or exposed to the world? OWASP’s website has some great information on how to extract a servers SSL/TLS information.
I ran a slightly modified version of the test (without the cert information dump) against Its a bit verbose but lets see the output:
nmap --script ssl-enum-ciphers -p 443

Starting Nmap 6.40 ( ) at 2014-10-28 15:20 EDT
Nmap scan report for (
Host is up (0.037s latency).
Other addresses for (not scanned):
rDNS record for
443/tcp open https
| ssl-enum-ciphers:
|  SSLv3:
|  ciphers:
|   TLS_ECDHE_RSA_WITH_RC4_128_SHA - strong
|   TLS_RSA_WITH_AES_128_CBC_SHA - strong
|   TLS_RSA_WITH_AES_256_CBC_SHA - strong
|   TLS_RSA_WITH_RC4_128_MD5 - strong
|   TLS_RSA_WITH_RC4_128_SHA - strong
|  compressors:
|  TLSv1.0:
|  ciphers:
|   TLS_ECDHE_RSA_WITH_RC4_128_SHA - strong
|   TLS_RSA_WITH_AES_128_CBC_SHA - strong
|   TLS_RSA_WITH_AES_256_CBC_SHA - strong
|   TLS_RSA_WITH_RC4_128_MD5 - strong
|   TLS_RSA_WITH_RC4_128_SHA - strong
|  compressors:
|  TLSv1.1:
|  ciphers:
|   TLS_ECDHE_RSA_WITH_RC4_128_SHA - strong
|   TLS_RSA_WITH_AES_128_CBC_SHA - strong
|   TLS_RSA_WITH_AES_256_CBC_SHA - strong
|   TLS_RSA_WITH_RC4_128_MD5 - strong
|   TLS_RSA_WITH_RC4_128_SHA - strong
|  compressors:
|  TLSv1.2:
|  ciphers:
|   TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - strong
|   TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - strong
|   TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - strong
|   TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - strong
|   TLS_ECDHE_RSA_WITH_RC4_128_SHA - strong
|   TLS_RSA_WITH_AES_128_CBC_SHA - strong
|   TLS_RSA_WITH_AES_128_CBC_SHA256 - strong
|   TLS_RSA_WITH_AES_128_GCM_SHA256 - strong
|   TLS_RSA_WITH_AES_256_CBC_SHA - strong
|   TLS_RSA_WITH_AES_256_CBC_SHA256 - strong
|   TLS_RSA_WITH_AES_256_GCM_SHA384 - strong
|   TLS_RSA_WITH_RC4_128_MD5 - strong
|   TLS_RSA_WITH_RC4_128_SHA - strong
|  compressors:
|_  least strength: strong

Nmap done: 1 IP address (1 host up) scanned in 2.39 seconds
While its a very long list of supporting ciphers, the culprits are the ones highlighted in red – those that support the *_CBC_* block cipher in SSLv3. If you find any of those then your server supports the vulnerability.

Crypto and Security Brain Teaser

Assuming this code works, what is wrong with the functionality from a security and crypto perspective?

#!/usr/bin/env ruby
# This program encrypts and decrypts messages at the command line.
# It runs setuid root, so that it can be used by users without giving
# them access to the (root-owned) secret encryption key.

require ‘openssl’


cipher =‘aes-256-ecb’)

case ARGV.shift
when ‘encrypt’
when ‘decrypt’
  puts “Usage: $0 [encrypt|decrypt] ”
  exit 1

input =
output =, “w”)

input.each_line do |l|
  output.write(cipher << l)

Here are a few hints…
I found 4 crypto related problems and one security/privilege escalation issue.

More Bugs in OpenSSL – DTLS Packet Injection

Another round of vulnerabilities for OpenSSL were published on June 5th, so I ended up spending a chunk of my weekend going over the diffs to make sure they did things right. They have made errors before with some of their fixes.
One of the vulnerabilities peaked my interest:
DTLS invalid fragment vulnerability (CVE-2014-0195)
A buffer overrun attack can be triggered by sending invalid DTLS fragments
to an OpenSSL DTLS client or server. This is potentially exploitable to
run arbitrary code on a vulnerable client or server.

There is a great writeup on why the code failed that can be found here.
So, I grabbed the latest and prior versions of the code and loaded up the diffs so I could see the impact.
Now, before I go to far, it is probably important that you familiarize yourself with the blog post “OpenSSL is written by monkeys.
Digging through the code, it easy to sympathize with the monkeys belief. From d1_both.c:
if (item == NULL)
  goto err;
  i = -1; <<===—— ????????????????????????????? }
Yes, the above was fixed but this was in the code base how long???

Anyways, looking at the actual fix, the following message length check was added. From d1_both.c:
unsigned long frag_len = msg_hdr->frag_len, max_len;
  frag = (hm_fragment*) item->data;
  if (frag->msg_header.msg_len != msg_hdr->msg_len) <<==— THIS CHECK WAS ADDED   {     item = NULL;     frag = NULL;     goto err;   } }
Don’t even get me started on the convention used to declare these variables. Yes, this is still in the code! The new check validates that the fragment length of the incoming packet matches the claimed length in the prior fragment.
Digging further into the code we can find some interesting gems:

i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE, devnull,

Why??? Why would anyone program this??? sizeof(devnull)?? This is the code that monkey legends are made of. Yes, this is still in the code!

As for the exploit, an attacker can inject a DTLS packet fragments (its pretty trivial to inject DTLS packets) into an existing stream with a length larger then prior fragment declared, causing a write of data across the heap. Since OpenSSL uses pointers to functions in structs for overloading all over the place (monkeys?), there is a slight chance it could be exploited to run arbitrary code. I say slight because the attacker would need to figure out where the malloc for the data packet aligned to in the heap; with the way OpenSSL is always allocating memory, and with other incoming packets, this would be hard to exploit. It would be trivial to create a system crash.

The monkeys reference is harsh on the OpenSSL folks, who have been nothing but courteous and helpful in all my interactions but I must note that the same programmer for this bug is also responsible for the Heartbleed commit. At least it made for an interesting weekend...

Adobe Password Breach – Did They Really Do It Wrong?

A few months back, attackers got the email addresses and passwords of 130 million Adobe users. Adobe encrypted the passwords and was ridiculed for not hashing the values (considered best practice), but were they wrong?
As of late, I have been digging into passwords breaches, hashing, etc. I have been trying to grab as many of the breached password datasets as possible (please let me know if you have any) and came across the leaked adobe passwords. Normally, passwords are hashed; a one way transformation of the password that is stored on the system.

HashFunction(Password) -> PasswordHash

When the user authenticates, the provided password is hashed in the same manner and the hashed value is checked against the stored value for a match. Passwords are stored like this because if the hashed value is lost, there is no way to “decrypt” the data / get back to the original password. The first problem is if two users have the same password, it will result in the same hashed value, so each user has a unique salt value that is concatenated with the password before the hash function.

HashFunction(concatenateString(Salt, Password)) -> PerUserUniquePasswordHash

So, when the lists of these hashes are broken, how do attackers get the passwords? Classily, the hashing mechanisms were a single pass of algorithms like MD5 or SHA. The attackers will attempt to hash a large number (trillions) of various possible passwords combinations to see if they can find a match. The classic hash functions are computationally simple. Computing power in Graphics Processing Units (GPU), aka graphics cards, has reached the point, that it is not very expensive to build a machine that can check 60+ billion hashes a second.
So, to help thwart this problem, systems will use hash functions and iterate several thousand times, increasing the cost to break.

ItterationCount*HashFunction(concatenateString(Salt, Password)) -> PerUserUniquePasswordHash

Another technique (like scrypt) is to use algorithms that are computationally hard for GPUs, usually requiring lots of memory. Although scrypt usage must be carefully chosen to make it computationally hard for GPU – but that is for another post. Even with these computationally hard algorithms, targeted attacks can still breach passwords, but again, that’s for another post.

So, back to the original premise! Adobe had a breach where the attackers gained access and published the email addresses, passwords and password hints for 130 million of their users. Adobe did something “bad”; they encrypted the passwords (as opposed to hashing) so the values could all be reversed/decrypted. The security community ridiculed Adobe for storing the passwords in a reversible / decryptable format. But was Adobe wrong?

Now, I need to point something out at this time. Usually, when hashed password databases are leaked, researchers end up breaking 70%+ through various brute force methods and thus far, no Adobe passwords have been broken. The only way to break Adobe’s leaked passwords is to figure out the key used in encrypting which, thus far, is not publicly known. Well, almost none, as some have been “broken” through data inference but not by decrypting.
Lets look at some of their mistakes:

1. Along with the passwords were also listed the password hints that, in many cases, contained the passwords themselves. These should have also been encrypted.

So it can be assumed that the encrypted value of “EQ7fIpT7i/Q” is 123456; as a result, the person with the above .net password probably uses 123456 at other sites.

2. The individual passwords were not salted (in this case no IV) so users with the same password had the same encrypted value.

Raw data from the adobe break file:

Both of these users have the same hint of 123456 and the same encrypted value. a grep for ‘EQ7fIpT7i/Q’, the encrypted string piped into wc -l shows 1911938 matches.

3. Adobe was also using an eight byte block cipher which was probably DES which encrypts the data in eight byte increments. Because they did not use a salt, the first eight bytes of encrypted text for password and password123 would be the same.

Value DES ECB Encrypted Value in Hex
password1234 0x8a65e0e80532b5fa bf67cab8afccfa27
P@55w0Rd1234 0xfdf058ce01785b90 bf67cab8afccfa27

Looking at all the Adobe password hints beginning with the string ‘password’ results some interesting patterns in the encrypted values. I added what I believe the cleartext value is:

Count Encrypted Value in Hex Suspected Cleartext
521 EQ7fIpT7i/Q 123456
662 pIjmc+3/mLzioxG6CatHBw pa55word
726 STWrgIvDDp3ioxG6CatHBw P@ssw0rd
729 ygtKdMXm1tHioxG6CatHBw drowssap
1466 IbF1vGcYjCrioxG6CatHBw passw0rd
2726 L8qbAD3jl3jSPm/keox4fA password1
5890 L8qbAD3jl3jioxG6CatHBw password
102 g+/hUkh3HrbioxG6CatHBw Password

So, the next question becomes, if the algorithm is using an eight byte boundary, why do all these passwords with length 8 have the encrypted text ‘ioxG6CatHBw’?

Doing a grep for password hint of ‘1-8’ resulted in:

1484 j9p+HwtWWT/ioxG6CatHBw 12345678

I can only assume the password system was including a null or other extra character? Searching for the string ‘ioxG6CatHBw’ turns up 36,045,481 occurrences, thus is can be assumed these password all have a string length of eight. More testing about the extra character, looking for password hint with the string ‘1-7’ results in 2343 occurrences with the majority having the encrypted string of ‘dQi0asWPYvQ’. Digging further, there are 124,253 passwords with the exact string of ‘dQi0asWPYvQ’; no passwords had this a partial. If the extra character is a null, then it would not be typeable.

So they did not properly normalize their passwords; I am sure that made for great portability.

Most of Adobe’s problems were crypto related – doing cryptography right is hard and they failed. Even with this failure, they still ended up with better protection then regular hashing because the attackers did not get the symmetric key with the data. Could they have done better, without a doubt, but had followed industry best practices many more of the passwords would have been broken. If the attackers had attained the password with the dataset, then it would have been trivial to get the cleartext values for all of the passwords.

DTLS Packet Structure and Fields

I’ve been digging into the DTLS packet structure, looking for free bytes for some security related ideas I have been playing with.
This following is the DTLS packet structure:
| Type | Version | Epoch | Sequence Number | Length | IV | Data | MAC | Padding |
Type = (1 byte), Version (2 byte)
Epoch is incremented each rekey (2 byte)
Seq Num incremented per packet (6 byte)
Epoch + sequence number = IV for MAC
Length (2 byte) = IV + MAC + Padding
IV = Initial Vector = randomizer / seed used by encryption
Encrypted section: Data, MAC, Padding
MAC uses epoch and seq number for its sequence number (similar to an IV)
Padding added to get block size for crypto (16 or AES, 8 for DES)
According to the RFC’s, the type field supports the same types as the TLS version – this basically translates to:
SSL3_RT_ALERT 21 (x’15’)
SSL3_RT_HANDSHAKE 22 (x’16’)

Back to the DTLS packet structure… The encrypted portion of the packet is the Data, Mac and Padding fields. Hence, when a packet is decrypted, the padding is checked first, then the MAC for data authenticity. This is a design flaw in TLS/DTLS allowing for Padding Oracle Attack if CBC block mode encryption is used.