Thursday, May 21, 2009

Detecting Malicious PDFs

Last night at the NE Ohio Information Security Forum I gave a presentation on Detecting Malicious PDFs. I'm still not sure if I'm going to release the presentation, but I am going to release a Snort signature that I've found useful for detecting evil PDFs.

alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"Potential Malicious PDF (OpenAction JavaScript)"; flow:from_server,established; content:"%PDF-"; content:"<</OpenAction <</JS"; within:128; nocase; classtype:trojan-activity;)

This signature looks for the PDF header (indicating we're dealing with a PDF) then an /OpenAction followed by /JS. This indicates that JavaScript will be executed as soon as the document is open.

Yes, I realize this signature can be easily bypassed with PDF obfuscation. However, I've found that attackers are not yet using this very much. Let me know if this is useful to you.

Thursday, May 7, 2009

Automating Malware Analysis article

In the latest Hakin9 issue (3/2009), I have an article on automating malware analysis. The article discusses how one can set up their own malware analysis automation system using VMWare, some analysis tools and two scripts. The article uses a Linux system as the base system and a Windows XP Pro as the guest/analysis OS, but I don't see why one couldn't use Cygwin on Windows for a base system with a few tweaks.

The scripts I created for the article are meant to be used as a base for your own automated analysis system - they are meant to be expanded upon. I encourage others to add other tools and capabilities to the scripts and share them here on the blog. The scripts used are available on Hakin9's site. However, if anyone wants the actual files let me know and I'll send them out.

I should point out that the system and scripts in this article assume you are in VMWare's host-only network mode. This is to prevent malware from accidentally infecting other systems on your network, the Internet, etc. However, since the system is set up host-only mode your malware will not be able to communicate with any hosts. The only network traffic you will see are DNS requests and probes to systems that go unanswered.

I encourage others to implement this into their automation system using software such as Truman, fakedns, or InetSim to create a virtual network. Don't want to take the time? Then you'll have to wait for the next issue of Hakin9 where I have part 2 to this article and show how to set this up (along with some other cool things).

I'd love to hear any feedback on the scripts, tools, or the article...including anything you use to expand upon it.

Friday, April 24, 2009

The more things change, the more they stay the same

A few weeks ago, the library at my daughter's school had a sale to get rid of some of their old books. That day, my daughter came home with a computer book published in 1984 entitled Computer Kids. The book is essentially interviews with children of various ages who use computers in school and at home. Its a very interesting read as it shows how computers were thought of back then.

One chapter in particular caught my eye because it was about computer security. The chapter focuses on a boy, who at the time was a senior in high school. In the chapter, the boy talks about copying games with his Vic20 and wardialing into other computers. At the end of the chapter, the author asks him what advice he would give to companies:

If someone were to ask me what else companies can do to protect their computer systems, I'd tell them to use passwords that are as long as possible. Most passwords are made up of eight-digit numbers. A ten-, twelve-, or even a thirty-digit number would be better. More secure. And companies shouldn't use individual words for their passwords. It's better to use a combination of words that are unlikely together.

Companies can also change passwords often, or they require the approval of one of more persons to gain access to the computer.

Interesting how advice 25 years ago is still valid today.

Friday, March 27, 2009

PHP Anti-analysis Technique

I was looking through a PHP web attack toolkit yesterday and found one of the scripts was obfuscated in an attempt to prevent others from figuring out what the code does. In short, the obfuscation worked by decoded a long base64 encoded string, applying some modifications to each letter based on where it was, and then executing the final output (thru an eval command).

No problem, I thought. There are three options to decode this:

1. Figure out what the code is doing and write a translation program. Nah, too long.
2. Modify the source for PHP itself to print any eval statements to a file. Hmmmm...maybe, but not now.
3. Add a print statement to the obfuscated script to print out the unobfuscated code instead of eval'ing it. Yep...easy.

So I changed the eval statement to a print and ran the PHP code. Nothing.

After ensuring my PHP wasn't borked I decided something was going on and I needed to look at the code. After a few minutes, I found the following:
$file = __FILE__;
$file = file_get_contents($file);
$var8 = 0;
preg_match(base64_decode("LyhwcmludHxzcHJpbnR8ZWNobykv"), $file, $var8);

for (;$interator_1<$enc_str_len;) {
if (count($var8)) exit;
Note that the for loop is the loop to decode each character of the PHP code.

This is a nice little anti-analysis function. First, it grabs the contents of itself in the first two lines. Then, it initializes $var8 to 0. Next, it looks for a regular expression in the contents of the current file, setting $var8 to the number of occurences found. The regular expression is a base64 encoded string. What does it decode to?
/(print|sprint|echo)/
So, its looking for any occurence of print, sprint or echo within the file. Then, in the decoding loop, if any occurences ($var8 > 0) are present the program exits. Simple technique to make analysis more difficult.

Of course, its pretty easy to bypass as well. :)

Monday, March 9, 2009

Another Odd SQL Injection Attack

In my last post, I talked about a large SQL injection attacked launched against a site I help run. Well, last night it happened again.

On 3/8/09 from 10:56 GMT to 11:40 GMT, the website I help run received over 3100 SQL injection attacks from close to 2 dozen IP addresses. The query received this time was:

/modules.php?name=-1+AND+2=2+UNION+ALL+SELECT+0x3065376332613738353864303833656636636535323337343330636466343033,
0x3a3a7865512d312d7465643a3a,0x3a3a7865512d322d7465643a3a,0x3a3a7865512d332d7465643a3a,0x3a3a7865512d342d7465643a3a,
0x3a3a7865512d352d7465643a3a,0x3a3a7865512d362d7465643a3a,0x3a3a7865512d372d7465643a3a,0x3a3a7865512d382d7465643a3a,
0x3a3a7865512d392d7465643a3a,0x3a3a7865512d31302d7465643a3a,0x3a3a7865512d31312d7465643a3a,0x3a3a7865512d31322d7465643a3a,
0x3a3a7865512d31332d7465643a3a,0x3a3a7865512d31342d7465643a3a,0x3a3a7865512d31352d7465643a3a,0x3a3a7865512d31362d7465643a3a,
0x3a3a7865512d31372d7465643a3a,0x3a3a7865512d31382d7465643a3a,0x3a3a7865512d31392d7465643a3a,0x3a3a7865512d32302d7465643a3a,
0x3a3a7865512d32312d7465643a3a,0x3a3a7865512d32322d7465643a3a,0x3a3a7865512d32332d7465643a3a,0x3a3a7865512d32342d7465643a3a,
0x3a3a7865512d32352d7465643a3a,0x3a3a7865512d32362d7465643a3a,0x3a3a7865512d32372d7465643a3a,0x3a3a7865512d32382d7465643a3a,
0x3a3a7865512d32392d7465643a3a,0x3a3a7865512d33302d7465643a3a,0x3a3a7865512d33312d7465643a3a,0x3a3a7865512d33322d7465643a3a,
0x3a3a7865512d33332d7465643a3a,0x3a3a7865512d33342d7465643a3a,0x3a3a7865512d33352d7465643a3a,0x3a3a7865512d33362d7465643a3a,
0x3a3a7865512d33372d7465643a3a,0x3a3a7865512d33382d7465643a3a,0x3a3a7865512d33392d7465643a3a,0x3a3a7865512d34302d7465643a3a,
0x3a3a7865512d34312d7465643a3a,0x3a3a7865512d34322d7465643a3a,0x3a3a7865512d34332d7465643a3a,0x3a3a7865512d34342d7465643a3a,
0x3a3a7865512d34352d7465643a3a,0x3a3a7865512d34362d7465643a3a,0x3a3a7865512d34372d7465643a3a--

The User-Agent this time was Mozilla/5.0.

There are a couple interesting things to note on this attack. First is the use of the double-dashes at the end of the SQL injection. Double-dashes are used in MySQL and SQL Server queries to comment out and ignore the rest of the line.

Next, if we assume that the hex values decode into the attack then the database being attacked must decode them somehow. Since the SQL does not use a CAST operator, which SQL Server requires to convert hex into characters, and only has the hex values, then we can infer the database being attacked is MySQL. (Note that I'm basing some of this on my knowledge and previous use of SQL injection attacks from my job - I could very well be wrong on this.)

The hex encoded values are interesting. If we decode them from hex into ASCII characters, we get the following query:

/modules.php?name=-1+AND+2=2+UNION+ALL+SELECT+0e7c2a7858d083ef6ce5237430cdf403,
::xeQ-1-ted::,::xeQ-2-ted::,::xeQ-3-ted::,::xeQ-4-ted::,::xeQ-5-ted::,::xeQ-6-ted::,
::xeQ-7-ted::,::xeQ-8-ted::,::xeQ-9-ted::,::xeQ-10-ted::,::xeQ-11-ted::,::xeQ-12-ted::,
::xeQ-13-ted::,::xeQ-14-ted::,::xeQ-15-ted::,::xeQ-16-ted::,::xeQ-17-ted::,::xeQ-18-ted::,::xeQ-19-ted::,::xeQ-20-ted::,::xeQ-21-ted::,
::xeQ-22-ted::,::xeQ-23-ted::,::xeQ-24-ted::,::xeQ-25-ted::,::xeQ-26-ted::,::xeQ-27-ted::,::xeQ-28-ted::,
::xeQ-29-ted::,::xeQ-30-ted::,::xeQ-31-ted::,::xeQ-32-ted::,::xeQ-33-ted::,::xeQ-34-ted::,::xeQ-35-ted::,
::xeQ-36-ted::,::xeQ-37-ted::,::xeQ-38-ted::,::xeQ-39-ted::,::xeQ-40-ted::,::xeQ-41-ted::,::xeQ-42-ted::,
::xeQ-43-ted::,::xeQ-44-ted::,::xeQ-45-ted::,::xeQ-46-ted::,::xeQ-47-ted::--


I'll admit that this has me stumped. Due to the pattern, the hex appears to be decoded correctly. However, I cannot make heads or tails of what is being attempted here. Interestingly, googling for "::xeQ-1-ted::" brings up a number of entries which look like an attack similiar to this one may have succeeded on other sites.

So, anyone have any ideas for this one?


Tuesday, March 3, 2009

Odd SQL Injection Attack

Updated 3/9/09.

Last night, from 21:21 EST to 21:41 EST a website I help run received over 1300 SQL injection attempts from less than a dozen IP addresses. This is a pretty popular site so its not uncommon for us to get hit with injection attacks, but its rare for us to get this hard.

Normally I would brush it off as an unsuccessful botnet attack, but the SQL injection is bugging me as I can't figure out what the purpose is. The query we recieved was as follows:

/modules.php?name=news&new_topic=9\' and 1=2 union select
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),CONCAT(0x27,0x7c,0x5f,0x7c),
CONCAT(0x27,0x7c,0x5f,0x7c) and \'1\'=\'1
The user-agent was "NV32ts".

This is an attack on PostNuke, which the site does run. However, the number of CONCAT's are what I'm stumped on (as well as some others I've asked).

The CONCAT(0x27,0x7c,0x5f,0x7c) statement decodes to:
'|_|
When you combine them all together, you get the following statement:
/modules.php?name=news&new_topic=9\' and 1=2 union select
'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,
'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,
'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,'|_|,
'|_| and \'1\'=\'1
The underscore in MySQL can be used as a single-character wildcard, which could further decode the injection to:
/modules.php?name=news&new_topic=9\' and 1=2 union select
'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,
'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,'||,
'||,'||,'||,'||,'||,'||,'|| and \'1\'=\'1
In reading that, its potentially a bunch of logical OR statements (the double pipes) with some single quotes. But to me it still looks like it will generate at error.

I've googled the CONCAT statement and the user-agent and there are a bunch of hits, but nothing which gives me any information. In fact, it looks like there have been a number of attacks using this string. But, that doesn't give me the purpose of the injection string above. This is what I (and some others) have come up with:
  1. This was meant to generate a SQL error to see if a site is vulnerable. If thats the case, why so many hits in such a short period of time?
  2. The attacker was trying to evade IDS/IPS/protections, but made a mistake.
  3. The attacker just doesn't know what they are doing at all.
I'm open to any ideas.

UPDATE

I received alot of responses on my previous SQL Injection. Thanks to everyone who did. For the most part, most came to the same conclusion as I did that the injection was either to generate an error or it was a mistake on the attacker's part.

As for the user agent, NV32ts, I've confirmed that it is a known signature of a botnet. I am currently trying to dig up any samples on it.

Wednesday, February 11, 2009

InetSim Installation

For a project I'm working on*, I've been looking at network simulation software to use in malware analysis. The most common one out there is Truman, written by Joe Stewart. However, Truman has some shortcomings - the biggest being it doesn't have an HTTP server and it hasn't been updated since it was released. So, I wanted to try a different one and that let me to InetSim.

InetSim has a number of software packages that need to be installed before it works. For my benefit, and I guess others as well, I'm documenting the process I took to install it on my Gentoo Linux system.
  1. InetSim has the capability to do connection redirection, but some options have to be compiled into the kernel first. Specifically, the Netfilter NQUEUE over NFNETLINK interface (CONFIG_NETFILTER_NETLINK_QUEUE) and IP Userspace queueing via NETLINK (CONFIG_IP_NF_QUEUE) need to be compiled in. I compiled them directly into the kernel, but they could be modules as well.

    Obviously, after re-compiling and installing your kernel (if needed), you should make sure that iptables is installed.

  2. A number of Perl modules need to be installed. Fortunately, most of these are in the Portage repository and can just be emerged:
    # emerge -av perl-Getopt-Long perl-libnet perl-Digest-SHA perl-digest-base perl-Digest-MD5 MIME-Base64 Net-DNS net-server
  3. There were two Perl libraries which were not in Portage that needed to be installed from source. The first was IPC::Sharable which is located in CPAN here. Once downloaded, installation was easy:
    # tar zxvf IPC-Shareable-0.60.tar.gz
    # cd IPC-Shareable-0.60
    # perl Makefile.PL
    # make
    # make test
    # make install
  4. The next required Perl library, Perlipq, took a little longer. This is a library used to interface with the packet queueing on the system for redirection. Initially, it could not find the libipq.h file in the correct location but a manual edit of the Makefile (shown below) fixed that. Perlipq is downloaded from here.
    # tar zxvf perlipq-1.25.tar.gz
    # cd perlipq-1.25
    # perl Makefile.PL
    At this point, the Makefile.PL prompts you for the location of the iptables development components. Specifically, its looking for libipq.h. It doesn't matter what we enter here as the Makefile will not find it in the correct place. Enter in some text and let the script finish.

    Once the script is finished, edit the Makefile. On line 145 is the following include line:
    INC = -I
    This is the directory which will find libipq.h. Change it to the following:
    INC = -I/usr/include/libipq
    /usr/include/libipq is where libipq.h should be located. If you are unsure, run 'locate libipq.h' to see where its at. After saving the Makefile, installation can continue.
    # make
    # make install
  5. Optional: If you want to make sure you have all of the necessary Perl modules loaded, run the following Perl script:
    use Getopt::Long;
    use Net::Server;
    use Net::DNS;
    use IO::Socket;
    use IO::Select;
    use IPC::Shareable;
    use Digest::SHA1;
    If there are no failures, you're good to go.

  6. At this point, all of the pre-requisites should be installed and InetSim installation can proceed. The latest version of InetSim at the time of this writing is 1.1 and is located here. Download it an untar it into a central location - I chose /usr/local.
    # tar zxvf inetsim-1.1.tar.gz
    # mv inetsim-1.1 inetsim
    # cd inetsim
    Note: I renamed the default directory for my own benefit, this is not necessary.

  7. InetSim uses the nobody user to run its servers. Nobody should be installed by default - but you better make sure.

  8. A group named inetsim is also required by InetSim to run. This should be created as follows:
    # groupadd inetsim
  9. InetSim comes with a setup.sh script which modifies permissions of all the files as needed.
    # sh setup.sh
  10. If you plan on running InetSim from a script, chances are you will need to modify a small piece of the inetsim program. On line 12 of the inetsim script is the use lib Perl code which tells the script where to find the InetSim modules. In its original form, it is a relative path to the lib directory. It should be changed to an absolute path similar to the following:
    use lib "/usr/local/inetsim/lib";
At this point, InetSim should be installed and ready to run. The default configuation file is located in conf/inetsim.conf and I highly recommend reading and modifying it to fit your environment. However, you should be able to use the default configuration file to test out your installation.
# /usr/local/inetsim/inetsim --session test
A number of messages of servers starting will stream by. If you don't see any errors, you are good to go!

* My new project - thanks ax0n!: