Recently, while scrounging around our spam traps, I spotted this ordinary piece of malicious spam. It uses a very simple social engineering trick, speculating about Obama’s sexual orientation and a link to a supposed picture to prove it.
There was nothing special about this spam but the link with a double extension file named “you.jpg.exe” was something worth investigating. So out of curiosity, I downloaded the file and checked out what it does.
First thing I did was to find out what the file really was. Of course, it was not an image file of Obama but rather a self-extracting RAR file.
Opening the file through a RAR extracting tool revealed the files inside it.
I extracted “you.jpg.exe” and inspected each of the files inside it but found they were actually encoded. So I run “you.jpg.exe” in our test machine and observed. When run, the image below popped up. Hmmm, definitely not Obama.
In the background, the following files were installed in the Windows System32 folder:
- bpk.dat
- bpk.exe
- bpkhk.dll
- bpkr.exe
- inst.dat
- pk.bin
Also an autorun registry was created:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run bpk = <%windir%\System32\bpk.exe>
Googling for the dropped files gave me a hint that what was installed was a keylogger and in particular a commercial version from Blazing Tools called Perfect Keylogger (PK). This keylogger program can be legitimately purchased and used, ostensibly for monitoring your kids’ or employees’ browsing habits, etc. As you can imagine, PK can also be used for badness.
I almost ended the analysis here. But a moment later, more interesting stuff appeared. The keylogger connected to a remote FTP server, and this allowed me to intercept the attacker’s FTP credentials.
Using the intercepted credentials, I logged in to the FTP server and found many folders containing monitoring logs and screenshots of victim’s desktop. That number of logs shows just how effective the spammer’s social engineering trick was.
Here is the WHOIS info of the FTP server:
Not wanting to stop here, I did a little more investigation on the PK installation files in my hope to uncover who was behind the campaign.
According to PK’s Online Help webpage, the program uses a hotkey to unhide the admin window or the system tray icon. The default hotkey combination is CTRL+ALT+L, but this didn’t work. So brute forcing different hotkey combinations enabled me to retrieve the correct hotkey. But to my dismay, this window popped up:
Before getting dirty by reverse engineering the keylogger and trying to crack the password, I scrounged around the net for more clues. I found a personal blog by Chris Pogue who happens to be a colleague here at Trustwave SpiderLabs who previously encountered this keylogger. In his blog, he noted that the password and other configurations were stored in an encoded file named PK.BIN, and the monitored data is stored in an encoded file named BPK.DAT. He also noted that the files can be decoded with a simple XOR using the key 0xAA.
I supposed that the PK version that Chris analysed was an older version, hence the XOR key 0xAA didn’t decode our configuration file. Well, for the dump file BPK.DAT, the XOR key partially worked, but to make it more readable I XORed it using two bytes 0xAA, 0x00:
But I was more interested in the file PK.BIN, because it stores the configuration details of the keylogger including perhaps the details of the attacker. But the file needed some extra work because of the fact that it can’t be decoded by simply XORing it with 0xAA. So my best guess was that it used a different XOR key.
This is what the file looks like in text mode, hhmmm look at that repetitive pattern!
In HEX mode, I took that repetitive string and made it our XOR key:
With the help of some python script, it helped me decode the file:
if len(sys.argv) > 1:
pkhandle = open(sys.argv[1],'rb')
pkbuffer = pkhandle.read()
pkhandle.close()
key=[0x0D,0x0A,0x08,0x05,0x01,0x02,0x06,0x03,0x03,0x0E,0x01,0x08,0x03,0x0C,0x09,0x07,0x05,0x0D,0x0C,0x0B,0x03]
dec = ''
ctr = 0
for i in range(11,len(pkbuffer)):
a= ord(pkbuffer[i])
b =key[ctr%len(key)]
x = a^b
dec = dec+(chr(x))
ctr+=1
dechandle = open('pk.dec','wb')
dechandle.write(dec)
dechandle.close()
And voila! (note: I needed to blur some details to protect the victim’s data in the FTP server)
The decoded PK.BIN shows enough details to get inside the PK admin panel, including the keylogger's admin password, FTP server/credentials, PK license name and license key. I typed in the admin password and it was successful, giving me more understanding about what the attacker is capturing and more of his keylogger configuration.
In the configuration file, it revealed the name Charles Onuigbo as the PK license name.
Now, I don’t conclude that Charles Onuigbo is the attacker or indeed if he is a legitimate person. The only thing interesting about the name is that it appears to be fairly common in Nigeria, the home of email scams!
I have reported the FTP site to its ISP through abuse email, and am looking forward to this site being taken down ASAP.
UPDATE: I have received an email from the company who hosted the FTP server in question and they wrote :
"Hello- I'm unsure if my co-workers wrote you back regarding this. We have stopped access to the account being used for this on the server in question... "
I have checked the FTP server and can confirm that the malicious FTP account has been disabled. Thank you Alex Kwiecinski of Liquid Web Inc. and your team for taking immediate action.

impressive..
Posted by: Sabriii 2509 | 25 November 2012 at 04:49
In a scenario where "Cool, Huge brains" successfully installs his/her malware on a host PC, how much protection does an encrypted anti-keylogging program like Keyscrambler provide?
Posted by: Rick Vecchio | 06 October 2012 at 11:53
How the did you know where the key started and ended?
Posted by: Sly3 | 11 September 2012 at 02:02
Sir can you teach me how to do this? I just need to know who is hacking my accounts and the situation is same on my side. Kindly reply pls!
Posted by: Bangenge3293 | 09 August 2012 at 10:49
Pretty bad ass. I too was expecting with your skills that you were going to track him all the way back to his terminal, engage his webcam and post a video of him.
Anyway something else that is probably nothing; Charles Onuigbo is an anagram for "Cool, Huge brains!"
Posted by: Roadesteve | 02 July 2012 at 17:22
I am disappointed. I expected you to reverse the situation, get into his computer and disable it at least. But something like blowing it up or making him send something to the FBI that would completely fuck him up would have been more in the orgasmic category. Guess hackers are that cool only in the movies.
Posted by: Videoamarama | 02 July 2012 at 12:37
My mind was just blown. I for one, know nothing about hacking or anything, but i tried to understand it. Good job!
Posted by: Kell Patrick | 23 June 2012 at 10:44
You sir, are a gentleman and a scholar.
Posted by: Avinash Arora | 13 June 2012 at 12:45
Awesome man! I hope your research can help us start to fight back agains these fuckers
Posted by: Michael Hoitomt | 09 May 2012 at 19:35
I'm laughing out LOUD. Good job, sir.
I would really love to get the actual person, though.
Posted by: João Cunha | 27 April 2012 at 13:38
Fascinating, and nice to see a win like that.
Posted by: Andrew Burns | 27 April 2012 at 13:08
@David: I assumed that those repetitive string were whitespaces when decoded and those would be 0x00s. The repetitive string was 21 bytes long. The pattern is more obvious when viewing in text mode because part of the repetitive string contains 0x0D,0x0A (line termination). So i took that 21 bytes string starting with 0x0D,0x0A and xor it against PK.BIN starting at the offset where i took my XOR key.
@jeremy.collake: thank you for that advice.
Posted by: Rodel Mendrez | 25 April 2012 at 21:13
You made one error in your analysis. When you say the key '0xAA' did not work, and you had to add an additional byte of 0x00. Actually, you set the word size to 16 bits instead of 8 bits (your first try). This is important, as XOR'ing by 00 results in the same value you input. Thus, to say you XOR by 0x00 is redundant, and overlooks the fact that 0xAA is the correct key. In short, X xor 0=X (X^0=X). The original decode value given to you was likely simply not specified with a word size.
Posted by: jeremy.collake | 25 April 2012 at 20:36
How did you decide on what key to use to decode the PK.BIN file? Was the key being repeated just white space in the file?
Posted by: David | 25 April 2012 at 18:46
Nice detective work! As someone who has cleaned 1000 PCs from this sort of thing, I really appreciate that someone is tracking it down and stopping it.
Next I hope someone will trace the money trail from those fake Windows/2012 Antivirus Scan programs and seize their accounts.
Posted by: James Bell | 25 April 2012 at 08:37
You said "That number of logs shows just how effective the spammer’s social engineering trick was." Didn't you mean "That number of logs shows just how many idiots are out there."?
Posted by: Russell Campbell | 25 April 2012 at 08:28
@A Facebook User
Umm, because that would be illegal?
Doesn't matter that they are committing a crime (or not, depends on their jurisdictions laws), as soon as you intentionally start deleting those logs, files that you do not own on a server that you do not own and do not have a legitimate reason to access, you are just as liable for computer crimes as your jurisdictions laws make you for any other computer crime.
Posted by: Adrian Pavone | 25 April 2012 at 07:43
@Matthias Brugger i actually did. If you read the blog and noticed the Wireshark screenshot, that is how i intercepted the FTP credentials. My objective of decoding the configuration file (PK.BIN) is to retrieve the PK admin panel password and other useful details such as the license name.
Posted by: Rodel Mendrez | 25 April 2012 at 01:28
One question, why didn't you use a network sniffer to get the ftp credentials? I think it would have been much easier.
Posted by: Matthias Brugger | 25 April 2012 at 01:09
That was awesome!!! Thanks for the step by step and explanations with pictures.
Posted by: A Facebook User | 24 April 2012 at 14:19
Why didn't you delete all of the other logs off of his server?
Posted by: A Facebook User | 24 April 2012 at 12:22
@Ali Khalid
If you look at the original encoded bpk.dat you will notice that every other byte is already 0x00 (mostly). Unicode takes 2 bytes per character but for most English character sets the high order byte is always 0x00. In order to keep the decoded output somewhat readable Rodel left them alone (XOR 0x00) during decoding so that in the right hand part of the decoded output they remain spaces rather than junk.
Note that there are a lot of intricacies to Unicode. I've grossly oversimplified here but I think that should explain it.
Posted by: Chris Miller | 24 April 2012 at 10:22
Great post. BTW how did you know that XORing bpk with 0xAA, 0x00 will produce the correct result. Was it a guess ?
Posted by: Ali Khalid | 24 April 2012 at 10:04
Nice one.
You're a genius.
Posted by: _Danyez | 24 April 2012 at 09:24