Skip to content

Commit 00af873

Browse files
committed
Spamming email analysis
1 parent 62decf6 commit 00af873

File tree

6 files changed

+169
-17
lines changed

6 files changed

+169
-17
lines changed

plugins/login_wall/ring_decoded/README.md

+18
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ It might be a rewrite or distant descendant of a [c99](/webshells/claw.php) web
1818

1919
`ring.php` gets used to download [gsptg.php](/gsptg.php), some kind of SEO campaign injector.
2020

21+
It's possible that antivirus companies call this webshell one of the following names:
22+
23+
* Backdoor:PHP/Fobushell.D (Microsoft);
24+
* PHP/WebShell-M (Sophos);
25+
* PHP.Backdoor.Trojan (Symantec);
26+
* Trojan.PHP.Crypt.n (Kaspersky);
27+
* PHP/Kryptik.AJ!tr (Fortinet);
28+
* PHP/Kryptik.AJ (ESET-NOD32)
29+
* PHP_WEBSHELL.YWG
30+
2131
### IP Address 192.154.105.154
2232

2333
192.154.105.154 → 192-154-105-154.static.gorillaservers.com.
@@ -75,10 +85,18 @@ execute the web shell code.
7585

7686
<form method= "post" action= ""> <input type= "input" name= "_f_wp" value= ""/><input type= "submit" value= "&gt;"/></form>
7787

88+
It's possible that the `_f_wp` name can be `l__l_` in variants.
89+
7890
Entering "G0YgIaXqx" and clicking the button shows us `ring.php` as a web shell:
7991

8092
![ring screenshot](ring_screenshot.png?raw=true)
8193

94+
Other passwords used for `ring.php` appear to be:
95+
96+
* root
97+
* pass
98+
* avto
99+
82100
The web shell source code is compressed via gzip and Xor-encoded with the 9-byte key "G0YgIaXqx".
83101
Gzipping the PHP is a pretty good way to conceal the Xor bytes,
84102
and even makes it hard to guess the Xor byte key length,

vigilante_suspected/scenery_4.jpg/README.md

+97-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ The HTTP parameter named "p1" should contain PHP code for WSO
4141
to eval, [and it does](dc1.php).
4242

4343
The HTTP request carried a file download as well as the HTTP POST data.
44-
This is pretty unusual, and suggests a programmatic access of the URL.
44+
This suggests a programmatic access of the URL.
4545

4646
The file would have gotten uploaded as "scenery_4.jpg".
4747

@@ -76,7 +76,8 @@ The Xor-encoding key bytes are the ASCII values of the string
7676
The attackers seem to have used an Xor-key individualized for each
7777
site they attacked.
7878

79-
I edited the immediate-eval-code to obtain [decode the image file](data_decode.php),
79+
I edited `function type1_send()`
80+
in the immediate-eval-code to obtain [decode the image file](data_decode.php),
8081
a small program that decodes the data in the image file,
8182
and prints it out.
8283
This seemed like the easiest way to obtain the decoded bytes.
@@ -90,6 +91,25 @@ they did not rename variables, eliminate extraneous while space,
9091
or any of the other methods that attacker(s) use to obscure their
9192
code and its function.
9293

94+
We see consistently "snake_case" named functions and variables.
95+
The code looks good, but has both ASCII space and ASCII tab
96+
indentation.
97+
It mostly has Unix-style newline line endings,
98+
but a few stray carriage-return characters appear.
99+
This indicates that a lot of cut-n-paste programming
100+
went on, but the programmer took some care to make the
101+
pasted code appear consistent.
102+
103+
The code includes 3 object-oriented class definitions,
104+
classes PHPMailer, phpmailerException and SMTP.
105+
This code is obviously borrowed.
106+
[Class SMTP 5.2.10](https://github.com/PHPMailer/PHPMailer/releases/tag/v5.2.10)
107+
dates to May, 2015, consistent with the date of this attack.
108+
109+
I give this code a grade of B - workmanlike, and solid.
110+
It's consistent with the way PHP is usually deployed,
111+
built on a foundation of utility classes and code.
112+
93113
### Data in "image" file
94114

95115
The deobfuscated data looks like this:
@@ -122,4 +142,79 @@ The deobfuscated data looks like this:
122142
}
123143
}
124144

145+
Pretty clearly some email spamming material, a fake from address, a destination address,
146+
and a template to customize the email body.
147+
125148
### Immediate-eval spamming code
149+
150+
There's a problem in the spamming code.
151+
Looks like a cut-n-paste got done twice.
152+
The file(s)-accompanying the download get processed twice,
153+
once without actually decoding them,
154+
near the beginning of the code,
155+
and a second time twoards the bottom of the code.
156+
My guess is that encoded-accompanying-files are a later add-on.
157+
Originally the "image files" contained only the template for spam
158+
email's bodies.
159+
160+
The spamming code gets eval'ed by the destination WSO instance.
161+
The looks through any files that arrived along
162+
with the POST request.
163+
If the files have ".jpg" in their file name,
164+
the spamming code uses the accompaying file(s) as data,
165+
passing the file name to `function type1_send()`,
166+
which is the "business logic" of this malware.
167+
168+
After decoding and deserializing the data in the "image file",
169+
`function type1_send()` checks the value of the key "ak"
170+
in the deserialized PHP array.
171+
Above, you can see that 'ak' has the value "[AUTH_KEY]".
172+
`type1_send()` checks if this is present, and does not proceed
173+
if it isn't.
174+
It checks the data to see if some entity has "authorized" the spam.
175+
176+
There may be a problem with the code if the deserialized array has a key named 'c'
177+
in it. It looks like it would try to serialize and base64-encode an array named `$res`
178+
which is not mentioned otherwise in `type1_send()`.
179+
This looks like stray code left behind during a refactor.
180+
The data sent along in this capture didn't include a key named 'c', so it probably would have worked.
181+
182+
After that, `function type1_send()` creates an email from
183+
the data in the deserialized array.
184+
185+
|Array key|Meaning|
186+
|:---------:|-------|
187+
|e|"uid", To address|
188+
|s|Array of email Subject strings|
189+
|l|message body template|
190+
|f|Array of From addresses|
191+
|lt|text or HTML email selector|
192+
193+
The "macro expansion" gets run over email subject, body and from address
194+
195+
1. `function alter_macros()` - partially create string by choosing from alternative phrases.
196+
The above data could end up with a partially filled in string like this:
197+
oh hey cutie... if you're still single and free we could meetup for fun?? [FTEIL]
198+
2. Insert a random number if substrings like `[RAND-12-45]` appear. The random number should be between 12 and 45 in this case.
199+
3. Insert another random number if substrings like `[NUM-5]` appear.
200+
I believe that substring would put a random number between 1000 and 9999.
201+
202+
The message body gets one more substitution:
203+
The substring `[FTEIL]` gets replaced by the "uid",
204+
in this email data, the string "#fec691067cad63a1f115c5d21f8c01bb#".
205+
206+
`function type1_send()` returns a serialized array that contains any SMTP erros,
207+
and a count of "good" and "bad" emails, where "good" emails did not cause a problem
208+
in the code of `function sendSmtpMail()`.
209+
210+
This has all the features we've come to hate over the years:
211+
212+
* A randomly-chosen email body that has a come-on in it.
213+
* An obviously wrong "from" address
214+
* Randomly-chosen strings of digits, probably in an attempt to pass signature scanners and such.
215+
216+
This particular email seems odd in that it isn't advertising anything.
217+
No URLs would appear in the email body.
218+
Based on the body template and the "from address",
219+
the senders probably intended this email as a cold-call, an introduction to see who they
220+
could get to respond to it, and then try to get cash from those responders in other ways.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
$body = "{well|oh} {hello|hey|hey there|hello there} {mister|sir|cutie}{,|..|...} if {your|you're|ur} {single|still single|willing|up to it|down for it} and {free|avail|available|around} we {could|can} meetup for fun?? [FTEIL]";
4+
5+
function alter_macros($content)
6+
{
7+
preg_match_all('#{(.*)}#Ui', $content, $matches);
8+
for($i = 0; $i < count($matches[1]); $i++)
9+
{
10+
$ns = explode("|", $matches[1][$i]);
11+
$c2 = count($ns);
12+
$rand = rand(0, ($c2 - 1));
13+
$content = str_replace("{".$matches[1][$i]."}", $ns[$rand], $content);
14+
}
15+
return $content;
16+
}
17+
$newbody = alter_macros($body);
18+
19+
print $newbody."\n";

vigilante_suspected/scenery_4.jpg/dc2.php

+14-15
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,6 @@
2626
}
2727
}
2828
}
29-
30-
if (isset($_FILES))
31-
{
32-
foreach($_FILES as $key => $file)
33-
{
34-
if(strpos($file['name'], ".jpg"))
35-
{
36-
$res = type1_send($file['tmp_name']);
37-
if ($res)
38-
{
39-
echo $res;
40-
}
41-
}
42-
}
43-
}
4429

4530
function custom_strip_tags($text)
4631
{
@@ -2855,6 +2840,20 @@ function sendSmtpMail($from_email, $from_name, $to, $subject, $body, $type, $con
28552840
return Array(1, 0);
28562841
}
28572842
}
2843+
if (isset($_FILES))
2844+
{
2845+
foreach($_FILES as $key => $file)
2846+
{
2847+
if(strpos($file['name'], ".jpg"))
2848+
{
2849+
$res = type1_send($file['tmp_name']);
2850+
if ($res)
2851+
{
2852+
echo $res;
2853+
}
2854+
}
2855+
}
2856+
}
28582857
function mx_lookup($hostname)
28592858
{
28602859
@getmxrr($hostname, $mxhosts, $precedence);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
function num_macros($content)
3+
{
4+
preg_match_all('#\[RAND\-([[:digit:]]+)\-([[:digit:]]+)\]#', $content, $matches);
5+
print "count(\$matches[0]) = ".count($matches[0])."\n";
6+
for($i = 0; $i < count($matches[0]); $i++)
7+
{
8+
$min = $matches[1][$i];
9+
$max = $matches[2][$i];
10+
print "$i: min $min, max $max\n";
11+
$rand = rand($min, $max);
12+
$content = str_replace($matches[0][$i], $rand, $content);
13+
}
14+
return $content;
15+
}
16+
17+
$x = num_macros($argv[1]);
18+
print $argv[1]."\n";
19+
print $x[1]."\n";

webshells/222.77.242.65-2019-07-10a/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,6 @@ The preferred language of the computer's user was Chinese:
4949
That matches the attack coming from a China Telecom address,
5050
but that's a pretty weak link.
5151

52+
## Analysis
53+
5254
![webshell screenshot](chinese_webshell.png?raw=true)

0 commit comments

Comments
 (0)