Type: Nation-State-Sponsored

APT3 Status: Believed Active

APT3 Other Names: Gothic Panda/ UPS/ Pirpi/ Operation Clandestine Fox/ TG-0110/ BuckEye/ Group 6/ Operation Double Tap/ Operation Clandestine Wolf

APT3 Active Since/Discovered: 2014

APT3 Last Report: June 2015

APT3 Target Sectors: energy sector, financial sector, technology industries, NGO/ International arena, aerospace and defense organizations, telecommunication companies, construction, high-tech, and transportation organizations


  • Pirpi
    • capable of gathering network adapter information, downloading files to memory, deleting files, listing directories, uploading files to the C2, executing processes, and other functionalities
  • PlugX
  • Kaba
  • PluginDetect
  • SHOTPUT backdoor (Backdoor APT CookieCutter)
  • SportsLoader

Preferred Attack Vector:  

  • Spear-phishing emails with  malicious attachment (PDF) or links (video or landing page)
  • Whale phishing attacks against specialized mailing lists
  • 0-day exploits (Adobe, IE, Firefox, etc.)
  • Full Exploit Flow
  1. Video object created
  2. Payload Fetch
  3. Video attached to a new NetStream
  4. The heap is sprayed with Adobe Flash Player Vectors
    1. Create a Vector containing 98688 Vectors containing 1022 uints
    2. Set the first two dwords in each Vector to 0x41414141, 0x42424242
  5. Create holes for the controlled FLV object
    1. Free approximately every 3rd Vector in the spray
  6. Spray custom class objects for future control transfer
    1. Define a new class CustomClass
      1. Define a function victimFunction with lots of arguments
    2. Create a Vector of 0x100 Vectors of 1007 references to an CustomClass instance
  7. Fetch and play the FLV exploit
    1. The FLV file will allocate an attacker controlled object in one of the holes from step 5
    2. The attacker controlled object will overwrite the length field of an adjacent vector
  8. Re-fill holes from step 5 with Vectors as in step 4
  9. Find the corrupted vector
    1. Search through Vectors from step 4
    2. Check the length of each Vector to find one that is abnormally large
  10. Corrupt a second Vector (Vector2)
    1. Using the corrupted Vector from step 9 to read/write relative memory addresses
      1. Search memory for an adjacent vector
      2. Overwrite the length field with 0x3fffffff
      3. Verify that a corrupted vector with length 0x3fffffff now exists in the spray
        1. If not, undo corruption and attempt to corrupt the next vector
  11. Decrypt shellcode and store it and the payload on the heap
  12. Overwrite the CustomClass.victimFunction function pointer
    1. Find the sprayed CustomClass object instance references from step 6
    2. The new function is a form of “pivot” that transfers control to the attacker
  13. Build ROP chain on the stack and call it
    1. Find ROP gadgets in memory using Vector2
      1. Including a call to kernel32!VirtualAlloc
    2. Call the corrupted CustomClass.victimFunction from step 6.a.i
      1. Arguments to the function are the gadgets of the ROP chain
      2. They are conveniently pushed onto the stack
      3. Corrupted vtable from step 12 calls a pivot
        1. The “pivot” just adds to to the stack pointer and returns because the ROP chain is on the stack
  14. ROP chain calls shellcode
    1. Call kernel32!VirtualAlloc
    2. jmp to shellcode
  15. Shellcode calls payload
    1. Shellcode searches memory for the payload, which is stored inside an image
    2. Shellcode decodes the payload by xoring each byte (that is not 0 or 0x17) with 0x17


  • CVE-2010-3962
  • CVE-2015-3113
  • CVE-2014-6332
  • CVE-2014-4113
  • IE (6,7,8) exploits, and Mozilla FireFox exploits