Undetectable Keylogger in 30 minutes

I noticed that all 60 out of 60 popular Windows anti-virus and anti-malware solutions do not catch the simplest keylogger.

For the test I created a windows application using the popular UserActivityHook.cs library.   It took me about 30 minutes of mostly copy and pasting.  I didn’t have to obfuscate the nature of my program nor did I have to pack it’s binary contents.    The program runs as plain user – it doesn’t need privilege escalation either.  In other words, it is very dangerous.   I scanned the executable through virustotal as well as few popular anti-virus and anti-malware programs on various workstations locally and they all passed the keylogger as 100% ok.

This doesn’t illustrate my hacking abilities (I used none).   What this does illustrate is the poor state of anti-malware and anti-virus tools at the moment.  No matter what the marketing materials tell you, the only protection these tools offer you is against specific white-listed instances of malware. For any other attack you’re on your own.


I couldn’t believe my eyes, either, so I decided to dig deeper.

Why was this so easy?

To understand that let’s dig into the various detection methods antivirus programs have at their disposal (thanks Wikipedia) and why each method fails

  • Signature-based detection: is the most common method. To identify viruses and other malware, the antivirus engine compares the contents of a file to its database of known malware signatures. Since this malware is new, there is nothing to compare to.   This is also another reason why I’m not posting the keylogger for everyone to download.   Days after I release it, it will get picked up by one of the many anti-malware teams and a signature will be made out of it in a hurry.   I don’t want to be tagged as distributing malware down the road.   This approach is mediocre, but it’s not good enough – definitely not as good as the various vendors would have you believe.   It’s trivial to bypass the anti-malware scan if you spend 30 minutes making your own.   Even if you copy and paste bunch of stuff together.  On the other hand if you’re using someone else’s tool it will get picked up as malware sooner or later.
  • Heuristic based detection: is generally used together with signature-based detection. It detects malware based on characteristics typically used in known malware code.   I was kind of rooting for the anti-malware programs to catch it based on heuristics,  if they can’t catch my test, how are they catching the keyloggers that others are trying to use against me?    Sadly none did.   This is most likely due to the fact that the Windows security architecture allows keylogging as a very routine function that is used by many legitimate applications.   In particular the keylogger depends on GetKeyboardState API call that’s used for many other benign reasons by other applications.   I still think if the anti-virus companies tried harder, they could catch this based on heuristics.  Currently they obviously don’t.
  • Behavioural-based detection: is similar to heuristic-based detection and used also in Intrusion Detection System. The main difference is that, instead of characteristics hardcoded in the malware code itself, it is based on the behavioural fingerprint of the malware at run-time. Clearly, this technique is able to detect (known or unknown) malware only after they have starting doing their malicious actions.    Once again anti-malware products didn’t live up to this promise.  They could have noticed the writes to disk milliseconds after each key press – they didn’t.   Then again, it is tricky.  There are lot of legitimate programs out there that do write to disk after key strokes and they aren’t key loggers.  
  • Data mining techniques: are one of the latest approach applied in malware detection.   Data mining and machine learning algorithms are used to try to classify the behaviour of a file (as either malicious or benign) given a series of file features, that are extracted from the file itself.    Data mining should have been a no-brainer for an anti-malware tool.    I was doing all sorts of suspicious stuff in my code and not hiding it one bit.   I guess we have to wait until this matures a bit, but given how miserably the other methods failed, I’m not holding my breath for that.

So….  this sucks.   How do you protect myself then?    Right now, you probably can’t.   Anti-malware companies have to step up and detect these kind of things.    Be skeptical, just because you see 57 green check marks on virus total, doesn’t mean it’s safe.   And no, don’t stop using your anti-virus, virustotal or whatever else you have.   Even if anti-virus is 90% effective.  That’s better than 0% without it.

ASP.NET dll download vulnerability


  1. Guess what the dll of the core application is called.  By default it will be called the same name as the ASP.NET project created by the programmer.   Other than taking a guess based on the name of the web site, often it’s possible to determine the name by browsing HTML source or by triggering errors.
  2. Download the main dll by requesting the following URL:  http://domain.com/bin/application.dll
  3. Once you’ve got the .dll downloaded you can decompile it using ILSpy or your own favorite reversing tool.   If you’re lucky, you may find hardcoded passwords.  If not, you can now look for SQL and Linq injection opportunities that the source code is likely to reveal.


  • Most IIS installations restrict access to /bin/ folder by default, but I’ve noticed that for some reason, some don’t.   One way to block this attack is by adding a hidden segment “bin”.


  • I found at least one Linux system running Apache with Mono that was vulnerable.  Linux is not immune, if anything I’d say it’s more likely to allow this attack.

Asterisk – Seamless dialing of remote extension through DTMF

Problem Description:

There are two offices.  Office A runs Asterisk / FreePBX while office B runs a closed system with auto attendant.

The guys at office A would like to be able to dial office B extensions as if they were local.


Solution Overview:

Program the office A extensions in this way:

  1. Local extension picks up
  2. Remote office number is called
  3. When the remote office picks up
  4. DTMF key presses are sent to select the right extension
  5. Call is connected

Solution Details:

First I attempted to program this into freePBX through the GUI, but I wasn’t having any luck because the default macros were not letting me craft the dial command in such a way that it sends the key presses after the call is placed.   Although it would have been nice to have everything in the GUI, the FreePBX GUI method seems to be a dead end.  I ended up relying on good old /etc/asterisk/extensions_custom.conf configuration file, and I just created my own extensions there.

exten => 102,1,Dial(SIP/v-outbound/4031112222,30,rD(ww11))
exten => 103,1,Dial(SIP/v-outbound/4032223333,30,rD(ww12))

[ext-local] sets the right context so that these extensions are picked up as if they were local.  You could also put these into other contexts like [ivr-1] etc.

D tells the Dial command to send DTMF button presses after the remote end picks up

w tells the Dial command to wait 0.5 seconds


Speed and Latency from Calgary to the Internet

I’ve always been fascinated by the relationship between internet speed and latency.   I know that for a given a specific latency you can calculate the maximum speed of an internet connection:

TCP-Window-Size-in-bits / Latency-in-seconds = Bits-per-second-throughput

It’s described in more detail here

But will that hold up in real world tests?  I decided to measure it.  Here are the results:



To do this I did the following:

  •  Created a script that tested each of the ~3000 speedtest.net servers by wget’ing a large test image from each.   Ran this off of a 1 Gbs connection, on Centos 7 server with default window size.
  • Summarized the data by country
  • Uploaded to openheatmap.com to make it pretty

Here are some interesting things that came out of this little experiment:

  • Countries in the same geographic region that have slower throughput are not running at their full potential.  Examples include: Guatemala, Brazil, Libya, Latvia, Lithuania, Iceland, Portugal, etc.    Take these results with a grain of salt, because some of these suffer from small sample size.  For example, I had to remove Japan from the data set because the only server Japan  was a unusually slow one.
  • Vast majority of the countries do run at their theoretical max throughput.   That means that most of the time, as long as you know your TCP window size, you can easily calculate the throughput with confidence.
  • You can roughly deduce route paths by looking at the map.  Take Iceland for example.  Even though it’s closer to Canada than Great Britain, the route clearly traverses through Great Britain, Ireland or Norway before heading to Iceland.

Unexpected results:

  • I got an impossible latency for Pakistan.  (47 milliseconds)  With that latency there is no way to even get to Europe, much less China.  The closest country with that kind of latency is Mexico.  I eliminated that from the data set as an anomaly.
  • I got impossible latency for Morocco.   (64 milliseconds).  Again, that’s way too quick.  I’m guessing both Morocco and Pakistan have been  mis-classified and are actually somewhere in the USA.

Remaining questions:

  • If you noticed, I haven’t said what my Centos 7 default TCP window size was.   That’s because I’m not really sure my self.  Working back from the real-life results, I’m sure the window size is approx 1,000 KB.  However, that doesn’t seem to match these parameters on my system: net.core.wmem_max = 212992 and net.ipv4.tcp_wmem = 4096 16384 3915616 … there must be some multiplication division factor involved.  Or maybe I’m looking at the wrong parameter altogether?

Am I a white hat or a black hat hacker?

Every time I hack or crack something, I face a tough ethical dilemma. I wonder, am I hurting people’s security and privacy by doing this? When I improve the code that is designed to simplify the cloning of RFID access cards, am I helping the society? Am I helping criminals break into buildings? When I write a tutorial that explains “how to hack in”, am I helping the society? Or am I helping the criminals send phishing spam?
To untangle this, let’s start with definitions. White hat hacker is defined as someone who improves security, while a black hat hacker is defined as someone who harms security. This isn’t very helpful. Whose security are we talking about? Is a hacker working for a government security organization considered white hat or black hat? After all, they are improving *their* organization’s security. Are our guys the white guys, while “the other” guys are black hat? And how do we define harm or benefit? Is a hacker who releases info about 0-day exploit causing harm, or benefit? It seems these definitions shift the ethics off to another level avoiding the deeper philosophical implications.

Here is a more useful definition:

  • White hat hacker: Hacker who shares their tools and knowledge in a public and open manner for the purpose of enabling everyone to gain privacy and control.
  • Black hat hacker: Hacker who secretively guards their tools and knowledge for the purpose of relinquishing privacy and control from others.

This definition allows us to ask us another interesting question. What would happen if majority of hackers were white hat? What would happen if majority of hackers were black hat?

Black Hat Majority:


Information security is in a very bleak state. Black hats have all kinds of back doors, and everyday users can only throw up their arms and say “privacy is dead”, “liberty is dead”, “I do not have control over my devices – others do”. This is a state we are in now.


White Hat Majority:


Information security is in a good state. Published exploit is a defensible exploit. Black hats still have the fringes to operate in. However, overall, every day users are fairly certain that they have the control over their systems and that they are not just puppets within a system controlled by others.

This makes it easy for me to say: I’m proud to be a white hat hacker.  I’m also proud to be on the right side of the race between the two sides.

I hope this makes others who have been on the sidelines, wondering what’s the right thing to do, jump right in.

Improved proxmark3 scanning of ioProx / Kantech fobs

I’ve been playing with my new proxmark3. It works great for HID cards, but ioProx code is still in its infancy. I made some improvements to it based on analysis by marshmellow:

  • Better accuracy: You no longer have to worry about centering your fob on the antenna or scan it repeatedly to get a “good” reading. Now you can just hold it in your fingers to scan. Before this update I was averaging 10 – 70% accuracy depending on how I held the fob. This version is pretty much 100% – I haven’t had a bad scan yet.
  • Correct decoding of human readable XSF number: Previous version had a bug that displayed the wrong unique code and the wrong facility IDs.


Download the binary firmware (including source code patch if you want to build it yourself) .

There is still more work to be done. For example, there appears to be CRC or checksum near the end – it’s still a mystery.

Quick and easy iptables based proxy

Today was a busy day dealing with power outage that affected 2100 businesses in downtown Calgary. Of course, couple of my clients were in the zone that went dark. I offered them to run their key infrastructure from my place for couple of days. Everything went great, except I have only 1 IP address on my connection. That’s not good when both clients want to come in on port 443. What to do?

Call up my ISP and order another IP? Nope: Takes too long, too expensive, I just need this temporarily. Also, ISP might mess it up and take me offline for a while.

Get VM with IPv4 IP and proxy the traffic over? Yes, but why go with something heavy handed like nginx?

I prefer this elegant solution brought to you by iptables:

# echo 1 >| /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A PREROUTING -p tcp -d $IP_OF_VM --dport 443 -j DNAT --to $IP_WHERE_IM_FORWARDING_TO:8443
# iptables -t nat -A POSTROUTING -j MASQUERADE

New Quantum Key Distribution Record by LANL

NIST, LANL and Albion College set two significant distance records for distributing “keys” (or codes) for quantum encryption.

Press release

Why does this matter?

– Will make it impossible for adversaries to “sniff” network traffic without being detected.
– Until now prototypes were specialized (read expensive) equipment. This technology is inexpensive so it could soon be mainstream.
– With the real possibility of quantum computing developing the point of making all SSL and VPN encryption methods obsolete, this technology is one piece of the puzzle in replacing current encryption technology with the next generation.

[Solved] Linux PPTP client NATed behind pfsense firewall

When migrating my PPTP client configuration from an older Linux server to a new one, I could not get a PPTP tunnel up and running on the new server.   I kept getting this error flow:

using channel 15
Using interface ppp0
Connect: ppp0 <--> /dev/pts/1
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xxxxx6a93> <pcomp> <accomp>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xxxxx6a93> <pcomp> <accomp>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xxxxx6a93> <pcomp> <accomp>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xxxxx6a93> <pcomp> <accomp>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xxxxx6a93> <pcomp> <accomp>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xxxxx6a93> <pcomp> <accomp>]
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0xxxxx6a93> <pcomp> <accomp>]
Script pptp vpn.xxxxxxxx.com --nolaunchpppd finished (pid 23704), status = 0x0
Modem hangup

So I was sending, but getting nothing back.

I tripple checked my configuration, and tweaked a few settings.  No luck.  Then I stumbled on an article that talked about the challenges of PPTP behind NAT devices.    I already knew about the common issue of not being able to dial out with more than one client session to a remote PPTP server.  For that reason I was careful not to have  more than one open at the same time,  but I thought I’d dig a bit deeper to see if NAT was the culprit.

Long story short, I noticed that pfsense -> diagnostics -> pftop was showing a GRE state from old server to the destination VPN server.  It showed age of 3+ hours (forgot the exact number) even though I was sure that the PPTP session on the old server was shut down.   I reset the firewall state on pfsense, and it started to work immediately.

The moral of the story is that pfsense likes to keep the GRE state open for hours after it’s been disconnected.   That is a problem.   Packets go out, but they are NATed to the wrong server when they come back.

Version details:

Pfsense: 2.1.4-RELEASE (i386)
PPTP: 1.7.2
Linux: Ubuntu 14.04.1 LTS