Exploiting Ammyy Admin – developing an 0day


For the past few years, a number of groups of scammers have been cold-calling thousands if not millions of people in what's been referred to as the "Ammyy Scam" or the "Microsoft Tech Support Scam" among other names. The scammers pretend to be from Microsoft or another official group and claim to have detected errors on the users' computers. They have the victims pull up internal logs that show errors, and convince them to download and run the Ammyy Admin software to allow them to remotely control the system. After that point, they may install backdoors or other malware, or simply ask for hundreds of dollars to "fix" the problem. The phone scammers have prompted numerous responses from Microsoft as well as warnings from Ammyy itself on its website. Even though at least two groups have been prosecuted, many more continue to operate. Ammyy Admin is one of many remote control software programs; it is not inherently malicious. The scammers just use it because it's an entirely self-contained executable that runs without any installation, it's the easiest to use for an ad hoc connection.

The internet is also full of technical users who have trolled the scammers, wasting their time, making fun of them, or forcing them to see disgusting images. Like most of us in the security industry, I was amused, but thought little about it until the scam hit closer to home when I discovered one of these groups had managed to scam my grandparents and leave their computer an infected mess for me to clean up. So I set out to find out if I could counter an attempted scam with a full fledged remote exploit, and turn the tables on the scammers.

The Challenge

This was also a very interesting challenge, because most of the time, exploiting software begins with fuzzing the network protocol or file formats used based on format specifications like HTTP or FTP, modifying samples of legitimate files or network traffic, and/or examining source code for vulnerabilities. Exploiters often take advantage of debug symbols, which Microsoft provides for their binaries, or other public documentation. For example, for some targets, finding an exploitable vulnerability is as easy as throwing a long string in the protocol and watching a stack overflow give you control of the instruction pointer. And if your target is like that, awesome for you! But it gets harder for widely-used software (Ammyy claims that the software is used by over 36 million personal and corporate users) especially if it wasn't selected for being a weak target.

In this case, Ammyy Admin not only did not have publicly described protocols, source code, traffic samples, or debug symbols, as I found out, its traffic was also incomprensible. The first thing I did was to set up an Ammyy Admin connection between two virtual machines and capture the network traffic. I started comparing it against other well-known remote desktop protocols, such as VNC and RDP, but quickly discovered that Ammyy uses a completely proprietary network protocol. Not only is the protocol not well known, but all the network traffic was encrypted, making it impossible to reverse-engineer or even replay and reproduce with network traffic alone:
Ammyy Admin traffic
You can keep staring at that all day, but I'll save you the trouble; it's just encrypted data.

Being a reverse engineer by heart, I first set out to identify the code that parses the first few packets to see if there was any kind of vulnerability I could find in it. Ammyy Admin is a decently large (764 kilobytes) executable that does not include the C runtime library, and it appears to be written in C++, which means the call graph between functions is generally lost in a mass of vtable function pointers. But with a little debugging, it wasn't hard to find. This code snippet parses a number of flags that aren’t really important and then begins initializating the crypto functions, but it was very small and doesn't contain exploitable vulnerabilities.

Ammyy uses the same executable for sending and receiving code, and it won't connect to itself, so I decided to use two VMs. While it would be possible to patch the Ammyy code to allow connections to another instance running on the same box, the effort needed to make that work would probably mean you weren't saving any time doing it.

Instead, I focused on reverse engineering the code the sets up and handles the encryption and decryption so that I could write code in a scripting language to simulate one end of the conversation. Although following and cataloging the thousands of binary arithmetic operations is strangely addictive, I had to stop myself before I wasted any more time. Exploring the advanced settings, you can see that the crypto is based on AES-256 and optionally RSA-1024, and I'm sure someone who is bored can finish that, but I needed to get to the core protocol parsers to look for bugs.

Vulnerability Discovery

So the next direction I went was to identify the wrapper methods around send and recv that performed the encryption or decryption and sending/receiving of data. Those methods were the ones to send and receive the plaintext of the protocol, and I needed to be able to record the data passing through and be able to modify it. There are a few different options for dynamic instrumentation; some vulnerability researchers like using Intel’s Pin framework, for example. Since I had already put together a flexible hooking library for Ambush with generic function hooking library and process injection code, I just made a sniffer from a local fork of the Ambush codebase to handle hooking the internal send or receive functions and save their output to a file, each traffic chunk broken apart by four X's. The output now looked like this:
Ammyy internal traffic
Much nicer, clearly plaintext and structured, and best of all, repeatable.

The next step was to turn the injected internal protocol sniffer into a fuzzer. I took a brief look at some of the publicly available fuzzers, but none of them appeared to make the process any easier. Fuzzers like minifuzz are easy for fuzzing file-parsing programs, and Peach can easily generate network traffic starting from a protocol specification, but I'm not aware of how to set up any to perform modifications via injected code, while synchronizing and looking for crashes across multiple VM's. So I accomplished this by using the "hookfuzzer" I had written. I modified it to receive a seed over the network and generate pseudorandom numbers to flip about one out of every two hundred bits. I set up the “controlled” end to send the manipulated data back to the “controller” side. There’s not really any point in trying to crash the controlled side, since the controller already owns it.

After running the fuzzer manually a few times, the Ammyy controller crashed! Ammyy caught the error and displayed an error message with the faulting instruction. I modified the injecting sniffer/fuzzer to replay that transcript and verified that the crash was reproducible.

The instruction was an invalid memory access, which didn’t appear immediately easily exploitable, since it didn’t show control of the instruction pointer and the functions responsible seemed extra-awful to reverse, so I decided to automate the fuzzer and run it until I got a better crash.

This is that awfully complicated flow graph for that awful function.

This is some of that awfully complicated flow graph for that awful function.

I wrote a few helper executables and two PowerShell scripts, one on the controller side and one on the controlled side, to form my ad hoc fuzzing framework. They automated starting a new instance of Ammyy Admin, injecting the fuzzer, clicking the appropriate buttons to connect, waiting a few seconds for a crash, detect whether or not a crash had happened, saving the crash address and transcripts of the plaintext traffic that had caused the crash, and restarting the whole process. Next, I cloned a bunch of Windows Vista VM’s, loaded the fuzzers on there, and let them go.

After running for a few days on 5 pairs of VM's, the fuzzer had collected a few thousand crashes, at 11 unique addresses. The vast majority of them fell on the same address as the first crash, and most of the unique crashing addresses were in different functions in the same executable, but two of the crashes demonstrated control of the instruction pointer.

I pulled up the saved transcript and loaded a debugger into my test VM, and traced back the crashing code. For all the effort I had put into building the fuzzing framework, the flaw was the same root vulnerability in the same awful function as the first crash I found. Oh well, looked like I needed to get back into RE and find out exactly how the protocol worked.


After a few days tracing the code, the protocol became clearer. Upon negotiating a successful connection, the controller spawns a thread to handle rendering the remote screen. The first data sent from the controlled end includes header data and global flags for the connection. It then contains system information such as operating system and system name. Finally it includes screen dimensions and various other fields. The controller then allocates a screen buffer using Windows GDI functions based on the screen dimensions, stored in RGBA format; four bytes to a pixel. After a chunk of data describing the cursor, the data stream sends what I call "stroke sets" which draw or update a rectangle on the screen buffer, which could be the entire screen or could just be a portion of it; each defines a start X and Y and width and height. Each stroke set then contains a list of strokes, each of which describes the pixels in up to a 16x16 pixel area. I won't go into full detail, as there are many forms the stroke can take to, for example, paint the entire block the same color in just a few bytes or draw each pixel individually, but in each case, the stroke defines the red, green, and blue portions of the pixels. The protocol uses a flipped coordinate system from GDI; the low index rows that come first are in the last memory addresses and vice versa.

Whew! All of this is important, because the crashing data in the fuzzed transcript is a stroke set that draws a rectangle just off the end of the image buffer. Since the image buffer is not in a heap or stack or other structure, if it was randomized sufficiently, there might not be any data reliably at a given offset to overwrite. However, because of the peculiarities of Windows memory allocation, even though the stack and heaps are nominally randomized, the stack of the renderer thread is allocated in 1MB of reserved memory directly before the image buffer; the last and highest allocations of the "low" allocations in the process. (the high addresses are where the DLLs are mapped) They are not randomized in relation to each other.

Memory layout of AA during exploitation

Memory layout of AA during exploitation

Thankfully for us, the Ammyy Admin executable does not opt-in to ASLR or DEP, which makes exploitation far simpler once you have the initial vulnerability discovered. The simplest plan of attack is to first write shellcode into the image buffer, then write the address of a pair of push esp; ret instructions over the return address of the stroke set parser function in the rendering thread followed by a jmp to the start of the buffer with an out-of-bounds array write. An alternate plan of attack is to write a ROP payload that will return to a LoadLibraryW call that will load a DLL from a remote UNC path, which will bypass Always-On DEP. However, this relies on the Web Client service to be enabled and requires waiting for a DLL to be pulled from a UNC path to load which usually takes 30 seconds to a minute.

Writing the shellcode for the direct attack entails a little bit of difficulty, since every fourth byte will be a 0, we can only control the RG and B bytes of the pixels. The good news is that we have no byte restrictions and we have plenty of room, since we can easily reserve a million pixels (4MB) or more if we want. So I just used the Metasploit Unicode encoder to create shellcode that will work when every other byte is a 0, which will work with basically any shellcode.

As far as the out of bounds write, the stroke set parser return address is at 0325FEBC when pixel data starts at 03360000. That's a 0x144 or 324 byte OOB overwrite from start of image, which is 81 pixels. So, with an 800x600 screen buffer, a stroke set with X offset 719 and Y offset 600 (since rows go down in address) will write to the appropriate offset.

With this work done, I put together a metasploit module that will generate a plaintext transcript to send to the remote end via the injected DLL into a running Ammyy instance that will exploit the remote end trying to take over your computer. In order to run it, you still need to run Ammyy Admin, save the plaintext transcript in its directory, and inject the DLL into the process which will load up the transcript. So I put together an executable package to automate this. I wrote the exploit for Ammyy Admin 3.4, including both the direct and ROP targets, and I updated for 3.5 when it was released. The vulnerability has been present for as long as I checked, at least back to 3.0, and probably before then.

You can download the complete package here, including a fully commented metasploit module and detailed README with more information on running it: https://www.scriptjunkie.us/aaa.html The one remaining caveat is that Ammyy can connect in two main ways; either by ID, which routes a connection through relay servers run by Ammyy (rl.ammyy.com), or directly by IP. I have only written and used the exploit with a direct IP connection to avoid sending it over the internet, so although the vulnerability should be present either way, I recommend blocking rl.ammyy.com in a hosts file and simply using direct IP connections. Or at this point, feel free to look into making it work over the relays, but I have not.


No scammer group has ever called me, and I have never used this except to test it and in demonstrations. I don't normally release zero day exploits, but I made an exception in this case because given the reporting and usage of Ammyy Admin I consider it highly unlikely to be used to compromise innocent victims. The primary users at risk of compromise are the scammer groups. Hopefully, it will be a deterrent to those who would attempt to compromise and take advantage of innocent victims.

  1. #1 by Braden Thomas on September 11, 2014 - 10:43 am

    You win the internet.

  2. #2 by ret5et on September 11, 2014 - 12:11 pm


  3. #3 by Kale on September 11, 2014 - 1:15 pm


  4. #4 by ret5et on September 11, 2014 - 1:37 pm

    Could you public your tool – hookfuzzer, plz :3

  5. #5 by John on September 11, 2014 - 4:53 pm

    Bravo!!! This is great. I fully support this effort. Phone scammers are a scourge upon this earth. From all of us who have grandparents and elderly people in our lives, THANK YOU.

  6. #6 by R Foreman on September 11, 2014 - 5:27 pm

    Ok you’re evil.. that’s all.. just a smart kind of evil 🙂 Nice write-up. Makes me want to take a closer look at metasploit.

  7. #7 by Aaron on September 11, 2014 - 10:04 pm

    I want to be like you when I grow up. Do you need an apprentice?

  8. #8 by drwolf on September 11, 2014 - 10:30 pm

    Great write up, Matt. Wish we could have collaborated on more projects. Please keep in touch.

  9. #9 by lizzie on September 12, 2014 - 8:54 am

    I’m not much of a computer savvy person but I know that Microsoft does not call people about computer issues and software fixes. There are also tons of complaints lodged at Callercenter.com that serve as a warning to those who are not yet aware. So I don’t think this scam stands a chance.

  10. #10 by Ed on September 12, 2014 - 8:33 pm

    Amazing homeslice! If I can make enough sense of this and attempt to use it I CANNOT WAIT to mess with one of these pieces of shit pulling these scams. I’ve worked with a number of people that have been victims and it boils my blood on their behalf. Rock on!

  11. #11 by JERINE WATSON on September 13, 2014 - 12:02 am


  12. #12 by Mike on September 13, 2014 - 6:23 pm

    Ammyy is a light and powerful useful tool customer support is diligent in fixing problems. I purchased it and branded it as a customized support tool and use it everyday to build my business. I paid a very reasonable onetime fee for several copies.

    It seems irresponsible for anyone to release an unauthorized patch for any software, that might compromise its legitimate use.

    This is clearly a social engineering issue, as many other products are used in the same scams by the same scammers.

  13. #13 by Wyn Williams on September 13, 2014 - 6:56 pm

    Words fail me, although I fully support fighting back the ammyy software IS legit and I personally know of some social orgs and colleges who use it.

    They are not scum so pretty much you just gave out a zero day exploit which will probably never be used by the kind of people who fall for these scams (what, how many times do you think the random scammers will run into a tech expert?) well done dude.. well done

  14. #14 by Paul M on September 14, 2014 - 1:33 am

    It would be cool to combine this attack with you l33t hack where you were able to remotely install linux!
    Thus you remotely install linux onto the attackers PC, with a vpn tunnel set up to an intermediate box of your choice. Force a reboot into linux and gain control of the scammer’s PC.

  15. #15 by Jimmy on September 15, 2014 - 7:18 am

    You da real MVP. (Seriously, thank you for the exploit)

  16. #16 by chad on September 15, 2014 - 10:36 pm

    I just had one of these calls ( I get many) anyways lookup hxxp:\\fixmycomputerdude.net they have the phone number listed and you can even schedule a call back with them. I have already reported it to the host Godaddy. we will see what happens

  17. #17 by Benj on September 16, 2014 - 3:12 pm

    Great read, understood 70% of the technicality but an enjoyable read none the less. Currently trying to get into pen testing career and if I can get anywhere near you I will be happy.

    Thanks again.

  18. #18 by Twat Killer on September 22, 2014 - 9:37 pm

    @Wyn Williams: Go FUCK yourself you anally retentive bar steward. He has stated his reasoning, and every single person here agrees with that except you. Close the door on your way out you asshole.

  19. #19 by karim on September 25, 2014 - 3:03 pm

    Thank you very much. From someone whose grandparents were robbed twice in a week and banks refused to cancel the charge.

  20. #20 by brian on September 27, 2014 - 2:35 pm

    I noticed that INFOSIS dot NET, the site I have been directed to in four fake MS Technical support calls, no longer hosts AMMYY. Whether they are acting in their own defense, or are protecting the scammers, it is now “REMOVED FOR SAFETY”.

  21. #21 by blablabla on October 11, 2014 - 1:11 pm

    So just got a 2nd call from them within 3 weeks of the last time (in which I threatened that I traced his number and sent it to Interpol – so I wasn’t expecting them to call again). I just tried getting your script up and running but I realized I don’t have a VM installed so I told her to call back while I get this script set up. Will report back.

  22. #22 by Ryan on November 27, 2014 - 7:43 pm

    I use ammyy pro, different operators come in behind every one of my log ons asking for access. My thinking was the ammyy servers have been compromised, ammyy support denies it of course. Am I misunderstanding your exploit or could this be the reason the above scenario is occurring? Have I been hacked? I just can’t explain why the different operators know when logons are initiated…

    • #23 by scriptjunkie on November 28, 2014 - 12:49 am

      This exploit does not tell you who is connected to the Ammyy servers, so I would guess they are brute-forcing the ID’s or found a weak way they are generated or maybe have some exploit against the Ammyy relays.

  23. #24 by Jason on December 2, 2014 - 9:47 pm

    I heard about the metasploit module for this when it first came out, and still haven’t decided to mess with it, figuring “they’ll never call me.” Well, they have called twice since I first heard about it on Hak5, DTNS, or Security Now. I have an unused system just sitting here, that I usually use for Handbrake, SpinRite, Recuva, jacking around with different distros, etc, but I should find something else to do with it.

    What about when they’re using another system, though. Anyone working on a module for LogMeIn, TeamViewer, etc?

    :BigThumb: on your exploit!

  24. #25 by NKT on January 21, 2015 - 3:41 pm

    Just had two on the phone. Tired them up for about 45 minutes.

    Sadly I hadn’t taken the time to set this up. 🙁 I did live tweet it though, from the point the girl gave up and handed me over to a guy who at least knew both English & at least a little about Windows.

    Given how he insisted I get the newest version I’m thinking the hole is plugged. It is blocked on my system anyway, so next he tried me on Teamviewer. At the point of that coming up, I killed the call.

(will not be published)