Sie sind auf Seite 1von 27

TECHNICAL ANALYSIS

OF ANDROID X-AGENT
ABOUT FOCAL POINT
Focal Point Data Risk is a new type of risk manage-
ment firm, one that delivers a unified approach to
addressing data risk through a unique combina-
tion of service offerings. Focal Point has brought
together industry-leading experts in cyber securi-
ty, identity governance, data privacy and analytics,
and hands-on cyber training services, giving com-
panies everything they need to protect, analyze,
and leverage data across any part of their organiza-
tion. Simply put, Focal Point is the next generation
of risk management.

© 2017 Focal Point Data Risk, LLC. All Rights Reserved. The Focal Point Data Risk name and logos are trademarks or registered trade-
marks of Focal Point Data Risk, LLC. All other trademarks and service marks are the property of their respective owners.
CONTENTS
ABSTRACT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
TARGET AUDIENCE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
ARCHITECTURE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
FILE AND CLASS DESCRIPTIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
IMPLANT CONTROL FLOW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
DYNAMIC ANALYSIS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
PERSISTENCE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
INTENTS, RECEIVERS AND SERVICES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
IMPLANT PERSISTENCE MECHANISMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
RECONNAISSANCE CAPABILITIES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
COMMAND AND CONTROL PROTOCOL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
URL FORMAT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
REQUEST DATA FORMAT. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
MESSAGE FORMAT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
MESSAGE VERIFICATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
MILITARY APPLICABILITY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
ATTRIBUTION. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
SIMILARITY TO OTHER SEDNIT/X-AGENT IMPLANTS . . . . . . . . . . . . . . . . 18
RELATIONSHIP TO THE DNC HACKS AND APT28 . . . . . . . . . . . . . . . . . . . 20
CONCLUSION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
ABSTRACT
In late 2016, CrowdStrike, Inc. released a report
documenting a new Android variant of the X-Agent
malware implant and attributed the attack to an
espionage group they call FancyBear (also known
as APT28).

The malware sample exhibits strong similarity to


previously known and documented instances of the
X-Agent implant across Windows, Linux, and iOS.

The goal of the sample, as CrowdStrike suggests,


appears to be traditional espionage, such as
mapping and reconnaissance of an organization.
Location data provided by the malware, only
referential position, not GPS, isn’t seemingly
reliable enough to support precise military strike
capabilities.

Current attribution of Android X-Agent to APT28


hinges on the fact that they are the sole operator of
X-Agent. However, in a 2016 report, ESET revealed
that they obtained source code for a Linux version
of the implant. It is unclear how long the source
code has been available, and who else may have
obtained it.

The presence of source, along with the age of


the implant, and its extensive documentation by
security researchers, casts significant doubt on
the premise that APT28 is an exclusive operator of
X-Agent. This assertion combined with the lack of
evidentiary similarity in other attribution categories
leads us to conclude that there is insufficient
backing to support attribution to APT28, but still
enough evidence to attribute the attack to Russia
or a Russian affiliate.

1
INTRODUCTION
X-Agent and its variants have been researched,
documented, decompiled, de-obfuscated and re-
verse engineered for many years. The first X-Agent
sample was discovered in November 2012 for the
Windows Operating System. In 2014, version 2 was
released with support for Linux. Version 3 brought
along an exploit kit and version 4 implemented ob-
fuscation. In 2015, an iOS variant of X-Agent was
discovered. In December of 2016, CrowdStrike re-
leased a report documenting the discovery of an An-
droid version of X-Agent. CrowdStrike reported that
malicious actors had modified a Ukrainian artillery
application, named POPRD30.apk to include mali-
cious functionality akin to known X-Agent variants.

Use of X-Agent is typically attributed to the Fancy


Bear espionage group (also known as APT28, Pawn
Storm, Sofacy Group, Sednit and STRONTIUM).
The Fancy Bear group was, according to reporting,
formed in 2007 with missions that closely resemble
Russian Government interests. They have been at-
tributed to the highly publicized cyber attack on
the DNC. SecureWorks Inc., ThreatConnect, Inc.,
Mandiant and CrowdStrike have all alleged that the
group is sponsored by the Russian Government.
CrowdStrike in particular, specifies the GRU, a Rus-
sian military intelligence agency, as the culprit.1 In
their report on POPRD30.apk, CrowdStrike attri-
butes the Android X-Agent to the FancyBear group.

Earlier this month, Focal Point acquired the PO-


PRD30.apk from CRYSYS Labs via Jeffrey Carr. We
were asked to provide a technical analysis, along
with our assessment of the military applicability
and attribution of the malware. The purpose of
this paper is to document these additional techni-
cal details. These findings build on top of Crowd-
Strike’s and CRYSYS’s technical discovery process. TARGET AUDIENCE
Since we are an education company, in many cases, This paper is targeted toward technical network
we may explain things a bit more than is required by defenders and malware analysts. Readers not inter-
a standard malware technical report. Our hope is ested in the nitty gritty details would do well to read
that those who are newer to the field or are looking the Dynamic Analysis and Architecture sections,
to join will read this paper and take away valuable skim the Reconnaissance Capabilities, and con-
information about the malware analysis process. tinue reading at the Military Applicability section.

1
https://en.wikipedia.org/wiki/Fancy_Bear

2
ARCHITECTURE
POPRD30.apk is a trojanized application, meaning the malware is embedded within a benign applica-
tion. In this case, the Android app was intended to help in certain artillery calculations, but the malicious
authors modified it to include a variation of the X-agent implant. With regards to the application analysis,
this means that the program was composed of both benign and malicious java classes. Below we de-
scribe those malicious classes, their responsibility, and how they are related.

FILE & CLASS DESCRIPTIONS


The following table lists only the .java files that contain Sednit related code, along with their descrip-
tion. Each class is discussed in detail in the section related to that behavior.

Filename Description

Starts the MainService class. It extends Android’s BroadcastReceiver


AlarmReceiver.java
class.

DataConstructor.java Creates HTTP request data from String input.

Duplicates functionality in DataConstructor, but takes a Byte array as


BinDataConstructor.java
input.

DataExtractor.java Parses request data from C2 server.

Primary implant class. Contains reconnaissance functionality, and


MainService.java
logic for handling C2 commands. It extends Android’s Service class.
Monitors network state. Responsible for setting up AlarmReceiver,
NetworkStateReceiver.java
and stopping the MainService class.
Contains constants required for C2 communication. Other than those
Reg.java
constants, the rest of its code is benign.
Contains functionality for constructing HTTP GET request and
ReqG.java returning the C2 Server response. It extends Android’s AsyncTask
class.
Contains functionality for constructing HTTP POST request from
ReqP.java String input and returning any C2 response. It extends Android’s
AsyncTask class.
ReqPbin.java Duplicates functionality in ReqP but takes a Byte array as input.

3
IMPLANT CONTROL FLOW
The implant’s control flow illustrates how its classes are tied together, as well as the responsibilities of
each class:

1. On app start, NetworkReceiver is instantiated when network connectivity is obtained.


2. If the network is available, NetworkReceiver instantiates a new AlarmReceiver in
stance.
3. Periodically, AlarmReceiver starts the MainService class.
4. MainService creates a new ReqP instance passing “hello” to the constructor, and calls
ReqP.execute().
5. ReqP constructs the URL and instantiates a new DataConstructor to create the r
quest data, essentially wrapping the “hello” message according to the C2 protocol. It
then issues the POST request to the C2 server.
6. MainService creates a new ReqG instance and calls ReqG.execute().
7. ReqG constructs the URL and issues the GET request to the C2 server. Upon receiving
a response, it instantiates a new DataExtractor to validate the response, extract the
C2 command, and any corresponding data.
8. MainService executes functionality corresponding to the C2 command and sends the
response using one of ReqP or ReqPbin, depending on the type of data.
9. MainService then stops itself.
10. MainService resumes when the AlarmReceiver starts it. Execution repeats starting
with Step 4 or 6. Details are discussed later, but in general, it should only issue one
“hello” msg per AlarmReceiver instance.

It is also important to note that the NetworkReceiver executes asynchronously. Whenever


its functionality executes, it checks the network state. If a network is not available and con-
nected, it will stop the MainService. Once the network comes back on, functionality will
execute starting with step 2 above.

4
DYNAMIC ANALYSIS
The sample that CRYSYS and Focal Point acquired is disabled and will not install on any version of An-
droid tested from Marshmallow to Nougat. There is an extra byte in the ZIP header of the APK that
prevents it from being unzipped. An APK is an Android Package (technically a code signed ZIP file with
an APK file extension instead of a ZIP), which contains resources like images, SQLite databases and ex-
ecutable code file called DEX (Dalvik Executable). A repair of the ZIP file allows the APK to be installed
and decompressed for analysis. Using the zip –fixfix command fixed the ZIP header allowing the APK to
be installed once code-signed.
$ zip -FF Corrupted.zip --out New.zip

A file, named “warnings.png”, remained corrupt after fixing the archive. Testing this file with pngcheck2
produced a CRC error in the IDAT section of the PNG (computed 14f2ff44, expected 8c56d075). A valid
PNG image must contain an IHDR chunk, one or more IDAT chunks, and an IEND chunk3. This does
not produce problems during installation or runtime.

The POPRD30 application requires an activation code from the author upon launch to access its function-
ality. The provided application does not make network connections to the author, instead the program
validates the activation code provided by the author. The activation code is validated using a simple
math algorithm that is easily cracked or bypassed with intent injection4. If the application is not activat-
ed, it will not allow the user past the registration screen. However, this application does not need to be
activated to be malicious. Running it once will start a background service that provides persistence of
malicious functionality.

This application was run inside an ARM Android Emulator and all network communications were
proxied through Burp Suite5. When network connectivity begins, these GET requests were captured:

GET /open/?oe=iUlwJUEdqMcg&aq=_Kw4-OJn4Eh3aO2&utm=omjN0pA8J&lm=sFVc0_LJZjw8LxAyCdaNJgcvZjw8
GET /close/?from=4oQV5s&from=gXrvxpIo7&from=u2cDsaoXFKtU3h&lm=IYRLpw0NekVnRgxLUr-RX1xGekVn
GET /results/?lm=pRLifRguNV59XkNQSKfeREZeNV59&channel=mS9kockadBmu9
GET /search/?lm=mp8fi0U1YTQyaBc6B5GKLgloYTQy&text=OzreXLG3Tldq&ags=n-yBIwc2l-M
GET /find/?text=Ya3fu2DhwysZ_gJ&lm=--BcTT04R3BIdDF-fY2sanN0R3BI&aq=H8KKH2

HTTP GET Requests with Encoded Data


SCREENSHOTS
By creating fake intents or by cracking the Activation Code, other activities become available as shown here:

Activating the Application allows Access to the Artillery Projectile Calculation Functionality

Translation of Activation Activity:


Enter the Activation Code Введите код активации
To activate the program, you need to send me this code: Для активации программы необходимо передать
мне этот код:
If you are from Ukraine it can be done via SMS or in a Если Вы из Украины это можно сделать
way convenient for you, if you do not contact me via через СМС или удобным для Вас способом,
ICQ, Skype, Email если нет свяжитесь со мной через ICQ,
Skype, Email

2
http://www.libpng.org/pub/png/apps/pngcheck.html
3
http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html
4
https://www.owasp.org/index.php/Mobile_Top_10_2012-M4_Client_Side_Injection 5
5
https://portswigger.net/burp/
PERSISTENCE
Requirements for software on a mobile OS are different than on a desktop OS. Typically, on a Desktop
OS, malware will launch on boot, using a registry key on Windows for example, and stay running in the
background.6 Since a constantly running background service would drain the battery of a phone, mobile
software and malware will not run continuously, but install some mechanism to launch itself periodically.
Thus, when we talk of persistence on a mobile operating system, we are not only referring to how the
malware may start on boot, but also any mechanism that is used to start the malicious code.

To establish persistence on Android, an application can listen for messages that the Android Operating
System sends out once it has booted up. Android applications can register to listen for these messages
in an XML file inside the APK7 called the Android Manifest, which describes the application’s capabilities.
In Android, these messages are called Intents.

INTENTS, RECEIVERS AND SERVICES


Intents are, fundamentally, messages that Android uses to communicate inside the operating system.
Intents allow Android applications to publish information to other applications in a standardized process,
and Broadcast Receivers8 let an application subscribe for a specific Intent broadcast that was published.
There are three use cases for Intents: starting an Activity, starting a Service, or sending a Broadcast Intent.
An Activity is a single user interface inside of an Android Application. A Service is a class that is typically
used to perform background operations when the user switches away to another application or turns
the screen off.9 Broadcast Intents are sent throughout the Android system to any applications that listen
for them with a Broadcast Receiver. A Broadcast Receiver listens for intents that match the intent filter
described in the Android Manifest.10

Broadcast Intents and Broadcast Receivers

The Android Manifest is always located in the root directory of an Android Package and contains informa-
tion that is required for the program to function like a querying location over a cell network or GPS, checking
for networking availability, receiving messages (intents) and starting background services.11 When a Broad-
cast Intent occurs that matches the intent filter in the Android Manifest, the onReceive() method inside the
Broadcast Receiver Class is called.

IMPLANT PERSISTENCE MECHANISMS


In the POPRD30.APK implant, Broadcast Intents and Alarms are the main mechanisms of persistence.
“Connectivity Changed” is a type of Broadcast Intent known as a sticky Broadcast Intent. This means that
the onReceive() method of the receiver is called immediately upon application launch with the last Broad-
cast Connectivity Intent that is currently being held in the sticky cache. It attains this capability by request-
ing permissions12 for Connectivity Changed and declaring a Broadcast Receiver in the Android Manifest.

6
https://attack.mitre.org/wiki/Persistence
7
https://en.wikipedia.org/wiki/Android_application_package
8
https://developer.android.com/reference/android/content/BroadcastReceiver.html 6
9
https://developer.android.com/guide/components/services.html
10
https://developer.android.com/guide/components/intents-filters.html
11
https://developer.android.com/guide/topics/manifest/manifest-intro.html
12
https://developer.android.com/guide/topics/permissions/requesting.html
<receiver
android:name=”mil.poprD30.NetworkStateReceiver”android:enabled=”true”>
<intent-filter>
<action android:name=”android.net.conn.CONNECTIVITY_CHANGE” />
<action android:name=”android.net.wifi.WIFI_STATE_CHANGED” />
</intent-filter>
</receiver>

Android Manifest containing Intent Filters to Trigger the


NetworkStateReceiver Class

If the implant application has connectivity, a Broadcast Intent will be dispatched to the method
onReceive() in the NetworkStateReceiver class which extends the Android BroadcastReceiver class. In
other words, the NetworkStateReceiver Class is listening for a network state change and connectivity.
The NetworkStateReceiver.onReceive() method is executed when a Wi-Fi or Cell network is available
and connected, otherwise the malware remains inactive.

If the network is available, it will instantiate a new AlarmReceiver Class, call AlarmReceiver.setAlarm() and
enter “true” in the applications XML preferences file. If there is no network connection available, “false”
will be entered in the preferences file and any previous instances of a running service will be stopped.

Once in AlarmReceiver.setAlarm(), a repeating alarm is setup. In this context, the alarm behaves like a
time-based scheduler to wake the malware up instead of an audible alarm.

arg9.getSystemService(“alarm”).setRepeating(0,
System.currentTimeMillis(), 30000, PendingIntent.getBroadcast(arg9,0,
new Intent(“mil.poprD30.START_ALARM”), 0));

Setting Alarm to Trigger Persistence

// Schedule a repeating alarm.

setRepeating(int type, long triggerAtMillis, long intervalMillis,


PendingIntent operation)

Method Signature for Android AlarmManager:setRepeating()

When an alarm is triggered, an intent is sent to the AlarmReceiver.onReceive() method.The Intent can
find its way to the to the AlarmReceiver Class since a second receiver definition was setup in the An-
droid Manifest for Alarm events from the AlarmReceiver.setAlarm() call.

<receiver android:name=”mil.poprD30.AlarmReceiver” android:exported=”false”>


<intent-filter>
<action android:name=”mil.poprD30.START_ALARM” />
</intent-filter>
</receiver>

Android Manifest containing Intent Filter to Trigger AlarmReceiver Class

7
Once the onReceive() in AlarmReceiver is called, it sets up a wake lock to prevent the interruption of
malicious activity such as when a user changes the application or puts the device in their pocket. This
ensures that the CPU will remain active, even if the screen is turned off, until all the partial wake locks
have been released.

<uses-permission android:name=”android.permission.WAKE_LOCK” />

Android Manifest Wake Lock Permission

Once the wake lock is acquired, it checks to see if the malware service is already running. If it is not then
it starts the service.

public void onReceive(Context arg5, Intent arg6) {


PowerManager$WakeLock lock = arg5.getSystemService(“power”).newWakeLock(1, “”);
lock.acquire(); // set wakelock
if(!MainService.isServiceRunning(arg5)) {
arg5.startService(new Intent(arg5, MainService.class));
}
Log.e(“ALARM”, “WORK”); // logging enabled
lock.release(); // release wakelock
}

Acquiring Wake Lock before Background Service Begins

The service class intent filter is setup here allowing the MainService Class to be instantiated.

<service android:name=”.MainService” android:exported=”false”>


<intent-filter>
<action android:name=”mil.poprD30.MAIN_SERVICE_START” />
</intent-filter>
</service>

Service Declaration in Android Manifest

When the background MainService is started, the first method that is called when an Android service
starts is the MainService.onStartCommand() method which begins the malicious activity. The wake lock
is released and the service is shut down after each malicious command is executed, reducing battery
drain and making it slightly more difficult to detect. The alarm will continue to trigger the creation of the
service until such a time as there is no network connection. In this case, the NetworkReceiver will stop
the service and turn off the alarm. When the OS sends another intent indicating a change in network
state, NetworkStateReceiver.onReceive() is called again resulting in continued persistence and remote
accessibility.

8
RECONNAISSANCE CAPABILITIES
MainService contains most of the recon functionality. This section will describe the reconnaissance ca-
pabilities and the how the author leverages Android Classes to obtain information. Reconnaissance on
mobile devices frequently involves information gathering from communication records, sensors like GPS
and the camera as well as operating system information like installed applications and internet connec-
tivity. In order to access this information, permissions must be requested during the installation of the
application. Mobile applications do not run continuously like on a desktop, instead they are paused to
preserve battery life when not in use. However, Android can allow background processes to perform
when the device is sleeping or when the application is not in the foreground. This implant queries sen-
sors, databases and files on the device to gather information about its target. It accomplishes these
tasks in the background using Android Services. The service contains many commands that when called,
construct HTML formatted strings based on information it gathers from the device. The format for the
construction of these commands is:

<pre><font size=4 color=green><br>CMD CommandID success</font>


<font size=4 color=blue><br> LogData <font size=4 col-
or=blue><br>
WiFi Network is available</font></pre>
HTML Logs

An example of command 107, GetWifiStatus() which obtains data pertaining to the Wi-Fi connection
formats to the following HTML string:

<pre><font size=4 color=green><br>CMD 107 success</font>


<font size=4 color=blue><br>WiFi Network is available</font><br>
LinkSpeed: “ + WifiInfo.getLinkSpeed() + “<br> NetworkID: “ +
WifiInfo.getNetworkId() + “<br> MacAddress: “ + WifiInfo.getMacAd-
dress()
+ “<br> IPaddress: “ + WifiInfo.getIpAddress() + “<br> Rssi: “ +
WifiInfo.getRssi() + “</pre>” : String.valueOf(v5) + “<font size=4
color=blue><br>WiFi Network is available</font></pre>

Generating HTML Response from Command

Once the command is constructed, it is base64 encoded and sent off to a new instance of the RegP or
RegG Class as a parameter. POPRD30 implant contains capabilities like any remote access trojan. The
following table describes the capabilities that can be issued remotely to the installed implant on the
Android device, their command ID, the class and methods it uses to obtain data.

9
Recon Function   CMD ID  Data Obtained  Class  Method/Data Source
101  Google Account  AccountManager  getAccountsByType() 

  Device ID  TelephonyManager  getDeviceId() 


 
GSM Cell Location  TelephonyManager  getCellLocation()
 
GsmCellLocation  getLac(), getCid()  
 
AllAboutPhoneCmd()  CDMA Cell Location  TelephonyManager  getCellLocation() 
  CdmaCellLocation  getBaseStationId()
getBaseStationLongitude() 
getBaseStationLatitude() 
SIM State TelephonyManager  getSimState()
Country   getSimCountryIso() 
Operator  getSimOperator() 
102  Call Logs ContentResolver  getContentResolver()
getCallDetails()  Date Context query(),moveToNext() 
Duration  Cursor 
106  Installed Apps  PackageManager  getPackageManager()
getAppList() 
getInstalledApplications()
111  SDCard Files List  Environment  getExternalStorageDirectory()
GetFiles() 
getPath() 
112  SDCard Files  Environment,  getExternalStorageDirectory()
Download File 
FileInputStream  getPath(), read(), close() 
104  Address Book  ContentResolver getContentResolver()
FetchContacts()  Context query()
Cursor  getColumnIndexOrThrow() 
107  Availability NetworkInfo isAvailable()
Speed WifiInfo  getConnectionInfo() 
Network ID getLinkSpeed() 
Mac Address getNetworkId()
GetWifiStatus() 
IP Address getMacAddress()
RSSI  getIpAddress()
getRssi() 
getDetailedState() 
100  SMS History  ContentResolver getContentResolver()
Context query()
SMS History  Uri content://sms
Cursor  moveToFirst() 
 
109  Browser History and Browser getContentResolver()
Browser History and
Bookmarks  ContentResolver  query()
Bookmarks 
Context  Browser.BOOKMARKS_URI 
103 Not implemented in Service  stopSelf() 
Stop Service  105 switch 
108 

After each command is processed, the HTML string is sent off to the Command and Control classes
RegG and RegP which process the data before sending data to the server.

10
COMMAND & CONTROL PROTOCOL
Command and Control Protocol (C2C) refers to the format, encryption, and/or encoding of the messag-
es sent between the implant and server, as well as the actual commands that the malware will respond
to. The POPRD30.apk implant uses a C2C protocol that is very similar to other X-Agent/Sednit variants
reported previously, particularly the report published in late 2016 by ESET13, and the IOS variant reported
on by TrendMicro14. Generally speaking, the implant issues a GET request to receive a command from the
C2 server, and issues a POST to send back the results.

The classes responsible for sending and receiving data are: ReqP.java, ReqPbin.java, ReqG.java, Data-
Constructor.java, BinDataConstructor.java, and DataExtractor.java. ReqG, ReqP, and ReqPbin, are respon-
sible for constructing the URL for the GET and POST requests. ReqG handles GET, and ReqP handles
the POST. ReqPbin duplicates the functionality in ReqP but works with the Byte[] type instead of String.

DataExtractor handles the parsing, validation, decoding, and decrypting of responses from the server.
DataConstructor is the converse. It handles the encoding and encryption of data for the POST requests
to the command server. Similar to the relationship with ReqP and ReqPbin, BinDataConstructor behaves
the same as DataConstructor, but on the Byte[] type.

URL FORMAT
The implant constructs URL In such a way that it will look different each time a new message is sent. Likely
this is done to discourage the creation of network traffic signatures based on the headers:

http://<IP>/<path>/?<param1>=<value1>&..<paramN>=<valueN>&lm=<token>

URL Breakdown

The only IP address the implant communicates with is 69.90.132.215. <path> is selected randomly from
the reqURI String array in ReqP, ReqG, or ReqPbin, depending on the type of request. Regardless, the
array contains the same values.

String[] reqURI = {“watch/?”, “search/?”, “find/?”, “results/?”,


“open/?”, “search/?”, “close/?”};

Possible URL paths

There can be anywhere between 1 and 5 <param><value> pairs in the URL. <param> is chosen random-
ly from the “params” String array in ReqP, ReqG, or ReqPbin depending on the type of request. The array
contains the same values in all three classes.

string[] params = {“text”, “from”, “ags”, “oe”, “aq”,


“btnG”, “oprnd”, “utm”, “channel”};

Possible URL parameters

The <value> component is anywhere from 5 to 15 randomly generated printable characters. Its data
comes from the RandValueMaker method in each of the Req classes.

13
https://www.welivesecurity.com/wp-content/uploads/2016/10/eset-sednit-part-2.pdf
11
14
http://blog.trendmicro.com/trendlabs-security-intelligence/pawn-storm-update-ios-espionage-app-found/
public String RandValueMaker(int len) {
Random r = new Random();
String result = “”;
String possibleChars =
“0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-
_”;
int count;
char c;
for(count = 0; count < len; ++count) {
c = possibleChars.charAt(r.nextInt(possibleChars.length()));
result = result + c;
}
return result;
}

Possible URL parameters

The “lm=<token>” parameter/value pair is the only consistent part of the URL besides the actual IP
address. It is guaranteed to be somewhere inside of the parameter list (not necessarily at the end).
<token> is generated by calling the aiURLConstructor() function present in each of the Req classes and
prepending the result with 8 chars of random data generated via RandValueMaker. In detail, the <token>
is constructed as follows:

1. Generate a 4 byte XOR key from a set of printable characters: “0123456789ABC-


DEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/-*(){}~^<>#!_[]@”

2. Fetch the last four bytes of the device id from .Context.getSharedPreferenc-


es(“setdid”, 0). This field is set by the MainService on start using Context.getSys-
temService(“phone”).getDeviceId(). It stores these bytes in a byte array in lit-
tle endian order. From here, we will simply refer to this field as the DeviceID.

3. Fetch the 7 byte static URL request token (Reg.URL_TOKENrq). This field is ini-
tialized in the Reg.java class. It always has the value: 76 0E 35 F9 EB 1A 3B.

4. Append the DeviceID to Reg.URL_TOKENrq forming an 11 byte RequestToken

<7Byte Reg.URL_TOKENrq><4 Byte DeviceID>


11 Byte RequestToken Format

5. XOR the RequestToken with the 4 byte key generated in step 1.

6. Append the XOR’d RequestToken to the 4Byte XOR key, creating a 15 byte array.

7. Base64 encode the 15 byte array, creating a 20 character EncodedToken for the URL.

Base64.encodeToString(<4Byte XOR Key><XORd RequestToken>)


20 character EncodedToken returned by aiURLConstructor

8. Call RandValueMaker(8) and prepend to the result of step 7

“lm=” + RandValueMaker(8) + EncodedToken


Full token param/value pair format for URL

12
REQUEST DATA FORMAT
Like the URL, the actual HTTP request data also uses a combination of static tokens, XOR encoding, base
64 encoding, as well as RC4 Encryption. The creation of the request data is fairly complex, so we will start
with the basic format, and deep dive each piece in order. This format applies to both data sent and data
received by the implant. The general request data format is:

<8 Random Chars>


+ B64Encode(<XORKey><EncodedToken><CRCPoly><2ByteCRC> <RC4Data><4ByteKeyEnd>)

Request Data Breakout

Much like the “lm” param in the URL, the implant prepends 8 random characters to the actual data.
When sending data, the implant using the RandJunkMaker() function in ReqP and ReqPbin to create
these characters.

The <XORKey><EncodedToken> pair are generated using the technique described to generate the En-
codedToken in the URL. It takes a static token value, appends the last 4 bytes of the DeviceID, and XORs
those bytes with the 4 byte randomly selected XORKey. The only difference is that it uses a different static
token value. In this case, it uses Reg.DATA_TOKEN, which has a value of C4 85 A8 33 4F E5 A3.

The <CRCPoly><2ByteCRC> contain a 16bit polynomial as well as the CRC16 checksum of the <RC4Da-
ta> field. The CRC is generated using a CRC16 function, dubbed make2ByteCRC16() present in both
DataConstructor, BinDataConstructor, and DataExtractor. It takes as its arguments, the 16bit polynomial,
and the data to calculate the CRC checksum over.

. .private
. . . . . . .char
. . . . make2byteCRC16(char
. . . . . . . . . . . . . . . . . . poly,
. . . . . byte[]
. . . . . . .input)
. . . . . .{. .
char crc = ‘\u0000’;
int v2;
for(v2 = 0; v2 < input.length; ++v2) {
int bInput = input[v2];
int v3;
for(v3 = 0; v3 < 8; ++v3) {
int lsbcrc = (crc & 1) == 1 ? 1 : 0;
int lsbinput = (bInput & 1) == 1 ? 1 : 0;
crc = (lsbcrc ^ lsbinput) != 0 ?
((char)(crc >> 1 ^ poly)) :
((char)(crc >> 1));
bInput = (bInput >> 1);
}
}
return crc;
}

make2ByteCRC16() algorithm

In this case, the implant passes the <RC4Data> in as the “input” argument, and a randomly selected
polynomial as the “poly” argument. The polynomial is randomly selected from a string of printable char-
acters similar to the XOR key described earlier.

13
Random r = new Random()
String possibleChars = “0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/-*()
{}~^<>#!_[]@”
char poly = possibleChars.charAt(r.nextInt(possibleChars.length()));

Polynomial selection

It’s important to note that characters in Java are 16 bits wide, so only one character needs to be selected
for the polynomial.

The polynomial goes in the <CRCPoly> field, and the CRC checksum gets placed in the <2ByteCRC>
field. These fields are to ensure the RC4 data isn’t corrupted in transmission. Since the result of CRC
algorithms are directly dependent on the polynomial, the protocol is required to send it. Without the
polynomial, the receiver would be unable to verify the checksum for the <RC4Data>.

<RC4Data> contains the RC4 encrypted message intended to be sent or received. As an example, this
message could contain the data generated by any one of the Recon capabilities described previously (i.e.
SMS history, call logs), or it could contain any data sent from the server. The message will also contain
some extra metadata such as the command ID. We will break out the full format of the message in the
next section.

The RC4 encryption algorithm used is the standard algorithm, and is implemented in the cryptRc4()
function located in DataConstructor, DataExtractor, and BinDataConstructor.

private byte[] cryptRc4(byte[] plainText, byte[] keyEnd)

cryptRc4 method signature

The RC4 key is a 50 byte base key concatenated with 4 randomly generated bytes. These 4 bytes are
created in the same way as the previously described XOR key. These random 4 bytes get placed in the
<4ByteKeyEnd> field following <RC4Data>. Thus, the RC4 key is 54 bytes long in total.

<50 byte Base Key><4ByteKeyEnd>

54 Byte RC4 Key Format

The 50 byte base key is as follows:

3B C6 73 0F 8B 07 85 C0 74 02 FF CC DE C7 04 3B FE 72 F1 5F 5E C3 8B
FF 56 B8 D8 78 75 07 50 E8 B1 D1 FA FE 59 5D C3 8B FF 55 8B EC 83 EC
10 A1 33 35

54 Byte RC4 Key Format

Due to the <4ByteKeyEnd>, each message will get encrypted with a different key. Thus, to decrypt a
message, the <4ByteKeyEnd> must be transmitted, and the receiver must already know the 50 byte base
in order to form the full 54 byte key.

14
MESSAGE FORMAT
As previously mentioned, prior to being RC4 encrypted, the message data is formatted according to a
structure. The structure is as follows:

<ModuleID><CommandID><MessageData><Reg.DATA_DATA_TOKEN>

Plaintext Message Structure

<ModuleID> is a 2 byte field. The <ModuleID> will be 0x0002 when sending the initial “hello” post re-
quest. For all other messages, it will be 0x4102. Note: these bytes are stored in little endian inside the
code’s byte arrays.

<CommandID> is a 1 byte field. It contains the Command ID, as noted in the “Recon Ca-
pabilities”. When receiving a response from a previously issued GET, it denotes the func-
tion to execute. When sending a POST, it indicates the content of the <MessageData> field.

<MessageData> is the binary blob of data being sent or received. When receiving a response
from a previously issued GET, it contains any arguments required to execute the command. For
example, when executing the DownloadFile command, it contains the path to the file on the
SD Card. When sending a POST, it contains the results of whichever command was executed.

<Reg.DATA_DATA_TOKEN> is a static token value stored in the Reg class. Unlike the tokens used in
the URL, and Request Data, it undergoes no transformation. Likely, this is due to the fact that the entire
message will be RC4 encrypted. It’s unclear why this extra token is included. It may just be a “fancy”
punctuation mark signifying the end of the message. Or it may be some extra authentication component.
Despite the reasoning, we know it’s a required portion of the protocol. It’s value is always: 30 C8 9E EB
6B 34 9E FA 8B

MESSAGE VERIFICATION
The DataExtractor class handles the parsing, decoding, decryption, and validation of request data from
the C2 server. This request data is part of the HTTP OK responses to a previously issued GET request.
The decoding and decryption is straightforward – it essentially unpacks each piece according to the
RequestData format, applying whichever decode/decryption operation is necessary to get the piece of
data. Verification of the message works differently than might be expected. Verification of a message is
as follows:

1. Extract the <EncodedToken> from the beginning of the RequestData.


2. Split the Token into the 7 Byte DATA_TOKEN, and 4 Byte Device ID.
3. Sum the bytes of the received DATA_TOKEN and compare to the sum of the stored Reg.DATA_
TOKEN. If the sum is different, reject the message and return a “INVALID_DATA_TOKEN”
message to the function caller.
4. Sum the bytes of the DeviceID and compare to the sum of the bytes of the stored DeviceID.
If the sum is different, reject the message, and return “INVALID_AGENT_ID” to the function
caller.
5. Extract the <CRCPoly>, <2ByteCRC>, and <RC4Data>. Using the CRCPoly as input, calculate
the CRC checksum over the <RC4Data>. If the received checksum is different than the calculat-
ed one, reject the message, and return “CORRUPTED_DATA” to the function caller.
6. Extract the ModuleID from the decrypted Message. Sum the first byte of the stored ModuleID
with the second byte from the received ID. Compare to the sum of the bytes of the stored ID. If
they are different, reject the message, and return “INVALID_MODULE_ID” to the caller.
7. Extract the DATA_DATA_TOKEN from the decrypted Message. Sum the bytes and compare
to the sum of bytes of the stored DATA_DATA_TOKEN. If they are different, return “INVAL-
ID_DATA_DATA_TOKEN” to function caller.
8. If all the checks pass, return a String Array containing [“CORRECT_REQUEST”, <Comman- 15
dID>,<MessageData>].
MILITARY APPLICABILITY
When initially planning this report, we were asked to assess the military applicabili-
ty of this implant, and whether it may have posed a threat to Ukrainian Artillery. Specifi-
cally, we sought to find out whether the location data in the application could directly sup-
port a military strike on artillery and the application’s overall purpose. After our analysis, we
believe the app to be a traditional espionage application that lacks the capability for precise targeting.

The location data that this malware retrieves is very coarse locational data that amounts to col-
lecting the location of the cell tower (or group of cell towers) to which the phone is connect-
ed. The location data comes from the following classes and APIs, depending on the type of phone:

• GSMCellLocation:: getCellLocation(), getLac(), getCid()


• CDMACellLocation:: getCellLocation(), getBaseStationId(),
getBaseStationLongitude(), getBaseStationLatitude()

Using the results of these APIs, one could locate a phone in an area ranging from 50 to 550 me-
ters, depending on the density of cell towers in the area.15 This is hardly the reliable, precise kind of
data needed to conduct a strike on a piece of equipment, and it is unlikely that a military organiza-
tion would rely solely on this data for planning. It is much more likely, given the malware’s capabili-
ties, that the implant serves a traditional espionage role. The ability to collect call logs, contacts and
SMS messages, in particular, could aid in mapping an organization and locating potential new tar-
gets for monitoring. Our conclusion corroborates the conclusion in CrowdStrike’s report on this APK.16

Some reports have attempted to link this malware with strikes on Ukrainian Artillery.17 We believe that
any attempt to draw a direct link between the existence of the POPRD30 malware and Ukrainian military
loss would be unfounded. Let’s suppose POPRD30 provided precise locational data, we would still need
evidence of the following to draw a link:

1. The trojanized application was installed on an Artillery service member’s phone.


2. That service member had the infected phone in the field near a piece of artillery equipment.
3. The phone sent the location of the service member, and thus a piece of equipment, to the
C2 service.
4. A corresponding strike occurred at that location.

We know from CrowdStrike’s analysis that the original benign application was available in late April
2013 and that the trojanized application first appeared in December of 2014. We also know that up
to 9,000 service members downloaded the benign application. However, there has been no pub-
lic reporting revealing how many Android devices, if any, contained the infected application and
much less information on specific phones or tablets that were infected. This directly challenges [1].

Without knowing who was carrying an infected phone, there is no good way to obtain informa-
tion for [2] or [3], unless there was some kind of sensor network deployed scanning for network traf-
fic associated with this malware around that time, or the attacker’s C2 infrastructure was being moni-
tored at the time of infection or later. No public data has been released suggesting this was the case.

Regarding [4], while it is likely possible to find data on where strikes occurred on Ukrainian artillery, with-
out having any information on what location data was sent to the attacker, we really cannot say that the
strike occurred due to the trojanized application.

16
15
http://cellphonetrackers.org/mobile-gsm-tracking-base-stations.html
16
https://www.crowdstrike.com/resources/reports/idc-vendor-profile-crowdstrike-2/
17
http://securityaffairs.co/wordpress/54635/cyber-warfare-2/implant-ukrainian-artillery-units.html
To further muddle the issue, the first known instance of the trojanized application appeared in December
2014, while tactical strikes occurred between July and August 2014, roughly 3 months before release of
the malware. While it is possible that the malware was distributed before December 2014, there is no
public evidence suggesting such is the case.

In conclusion, the fact that the malware only provides referential data is in some ways irrelevant, as there
is still an astounding lack of evidence establishing a causal link between the malware and strikes on
Ukrainian artillery. Lack of knowledge with regard to the success of the attack (number of infected devic-
es) and the date of the malware’s release, only serve to further obscure the issue. Any reporting regarding
losses suffered by Ukraine should be treated as context, providing background on the events during
which this malware may have been developed.

17
ATTRIBUTION
When speaking of intrusions and malware, attribution refers to the identification of the adversary re-
sponsible for conducting the attack. To attribute POPRD30, we compared it to other known X-Agent
Implants, and then investigated what, if any, relationship exists between this attack and previous attacks
attributed to APT28, such as the DNC Hacks. Since we do not conduct on-going threat intelligence, the
following analysis is solely based on publicly available data and our examination of the POPRD30 APK.

SIMILARITY TO OTHER SEDNIT/X-AGENT IMPLANTS


During the process of analyzing POPRD30.apk, we also looked at some recent reporting on this implant
family. In particular, we looked at ESET’s report, titled, “En Route with Sednit: Part 218, and TrendMicro’s report
on an iOS variant of Sednit19.

The iOS version shares similar functionality, such as collecting SMS history, call logs, contacts list, loca-
tion data, etc. We are not sure if the location functionality is the same kind of coarse location data that
we observed in POPRD30.apk. We tried to obtain the X-Agent sample reported by TrendMicro but it
was unavailable in all the major malware databases, including VirusTotal, VirusShare, and OpenMalware.
Further, the iOS application shares a similar C2C structure in that it randomly constructs the URL and pa-
rameter list from the same path and parameter strings present in the Android version. They also share a
similar HTML log format to display the results of various commands on the C2 Server.

When comparing our results to the analysis conducted by ESET, we found many of the same similar-
ities with the C2C Protocol with regard to the URL generation, data request format, and construction
of the RC4 key (50 byte base + Random 4Bytes). We also noticed that in the URL, instead of using
“lm=” to signify the encoded URLToken, the samples ESET investigated, used the string “ai=”. In PO-
PRD30, the method that constructs the encoded URLToken is named “aiURLConstructor”. Note the use
of the “ai” prefix. In IDA, we also saw a couple other references to “ai” with regard to the naming of
certain locals inside of the aiURLConstructor, as well as the local variable name denoting the return
value. Likely, “ai” is simply shorthand for AgentID:

AI prefixes inside of aiURLConstructor()

AI_VARIABLE local name for aiURLConstructor() return value

18
18 https://www.welivesecurity.com/wp-content/uploads/2016/10/eset-sednit-part-2.pdf
19 http://blog.trendmicro.com/trendlabs-security-intelligence/pawn-storm-update-ios-espionage-app-found/
Because ESET was able to obtain a copy of the source code for this implant, we were also able to spot
a couple other local variable similarities. DataConstructor shares similar argument names to the Mod-
uleMsg class in the Linux source, such as cmdID, modID, and data. These classes share similar function-
ality in that they encapsulate Sednit’s message format.

We also saw references to a variable called “KERNEL_MAIN_CRYPTO_KEY” in both ESET’s report and
the Android malware, in reference to the cryptographic portion of both implants:

KERNEL_CRYPTO_MAIN_KEY variable in cryptRC4()

Due to the similarity of C2C protocols with both the iOS and desktop versions of known X-Agent im-
plants, and the similarity in variable names to known source, we can say with high confidence that PO-
PRD30.apk contains a variant, maybe even a port, of the X-Agent implant.

19
RELATIONSHIP TO THE DNC HACKS
AND APT28
While we do think the C2C protocol and variable
naming in this sample tie it to other X-Agent im-
plants and tools commonly attributed to APT28,
FancyBear etc., it’s difficult to say solely based on
this sample that this tool was used by the same
people that conducted the DNC hacks and oth-
er attacks that have been attributed to APT28.

Attribution is a rigorous scientific process, requiring


a lot of time and effort, and even still one can never Diamond Model Layout
be 100% sure that the attribution is correct with-
Diamond model structures an intrusion as a Dia-
out some considerably telling evidence. For this
mond Event with the following components:
reason, threat intel groups say things like, “We as-
sess with low/medium/high confidence,” because • Adversary is the actor or organization respon-
absolute certainty is nearly impossible to attain. sible for the intrusion

This sample poses quite the challenge because • Capability describes the tools and techniques
mobile malware investigations are not the same of the adversary used in this intrusion. This in-
as the typical APT discovery and intrusion analysis cludes the type of malware used, as well as the
process. When analyzing an APT intrusion on a tra- C2C protocols.
ditional network, analysts can collect plenty of fo-
rensics data, monitor the network activity, discover • Infrastructure describes the logical and/or
the type of data that most interests the adversary, as physical communications channels used by
well as study that adversary’s behavior on the net- the adversary. Examples include: IP addresses,
work. For example, analysts can examine how they domain names, email addresses, USB drives.
pivot to different systems, the variety of tools used, Type 1 infrastructure denotes infrastructure
how the adversary responds when remediation that is fully controlled and owned by the ad-
begins, and the adversary’s hours of operations. versary, and maybe even located in physical
proximity. Type 2 infrastructure denotes in-
In this case, we simply know that an Android vari- frastructure controlled by some intermediary.
ant of X-Agent exists, but we have none of the oth- This is usually the server that the victim sees
er behavioral data required to attribute the attack as the adversary. In many cases, this is the C2
with a high degree of confidence. server that receives the initial malware beacon.
It serves to disguise the actual origin of attack.
Diamond Model
The Diamond Model, developed by Caltagirone • Victim describes the adversary’s target. This can
and Pendergast20, provides a good way to model be an entire organization or just one person.
the information we know about an intrusion and
provides a basis for tackling the attribution prob- The simplest way to describe the relationship be-
lem. While it is beyond the scope of this document tween all four components is to say that an adver-
to provide a full introduction to the model, we will sary deploys a capability over some infrastructure
provide a very basic definition and try to fit what we against a victim. During the analysis process, we
know to the model. pivot along the vertices of the model, filling in the
information that we discover. For example, when
analyzing POPRD30’s C2 protocol, we discovered
an IP address. This would be a pivot between Ca-
pability and Infrastructure.

20
20
https://www.threatconnect.com/wp-content/uploads/ThreatConnect-The-Diamond-Model-of-Intrusion-Analysis.pdf
While there are various ways to establish attribu- The full Diamond model description also includes
tion, generally speaking, it boils down to a couple an extended Diamond model that introduces ex-
things: tra socio-political and technology relationships
between the adversary/victim pair, and capabil-
1. Does the evidence in this attack point to a ity/infrastructure pair respectively. It goes on to
specific attacker? For example, is there a user- describe different approaches to analysis, activity
name in a pdb string with the name of some- threads, and more. We highly recommend reading
one affiliated with an adversary organization? the original paper, as it provides an excellent mod-
Or is an IP address registered to a person or el for describing and structuring intrusion analysis
company affiliated with a known adversary? and attribution.

2. Given the evidence from this event, does it POPRD30.apk Diamond Event and Attribution
look similar to a previously attributed attack? Now that we’ve introduced a structured way to an-
In other words, does the collection of evi- alyze the POPRD30 attack, let’s fit what we know to
dence in each of the Capability, Infrastructure, a Diamond Event.
and Victim categories match in large part with
evidence in another attributed attack? Usu-
The victim, or at least the intended victim, is the
ally, you need a combination of categories to
Ukrainian Artillery. Capability would include the
establish a high confidence attribution. For
Android Variant of X-Agent, along with the C2 Pro-
example, simply seeing the same IP address
tocol, and RC4 key creation. Infrastructure includes
in two attacks is not enough information, un-
the IP Address, 69.90.132.215 (Type 2), and an un-
less you are certain the IP address hasn’t been
disclosed Russian Military Forum (Type 2). At this
re-assigned in the time between attacks. Con-
point, we will leave the Adversary as unknown, as
versely, if we have an attack against an energy
making any judgement as to the adversary is put-
company that shares an IP address and implant
ting the cart before the horse. Let’s first examine
with a previous attack against another compa-
the evidence we know, and see if we can pivot from
ny in that sector, it’s much more likely that we
any of other vertices back to the Adversary.
are dealing with the same adversary, since we
have high similarity across all of the Infrastruc-
ture, Capability, and Victim categories.

POPRD30 Diamond Event: Applying the Diamond Model to POPRD30 attack


21
Pivoting along the Infrastructure-Adversary bound- tions. If ESET was able to gain access to the source
ary proves troublesome. It’s difficult using public code, who else might have had access? And for
reporting to relate the IP address we have to pre- how long? Were past versions of the source code
vious attacks, since in many cases public reports accessible? Could someone else have obtained
will not release the IP address. As far as we can the source code within the development period of
tell, there is no public evidence relating the IP in April to December 2014 reported by CrowdStrike?
this attack to a previous event. Further, the report The presence of source code is enough evidence
by CrowdStrike makes no mention of the IP being to throw into doubt attribution based on Capability
used as evidence for attribution to APT28, so we alone and the idea that X-Agent is associated with
think it’s unlikely that there’s a relationship between a single organization.
this IP and a known adversary.
To make things worse, the presence of the Android
The military forum that was used to distribute this malware could further muddle future attribution at-
malware was not disclosed, and we are unsure if tempts. Since higher-level compiled languages like
that forum is commonly used as a distribution plat- Java retain much of their type information, decom-
form for any of the known APT sets. Again, since pilation produces good source code that could be
CrowdStrike makes no mention of this relationship used to produce a new variation of X-Agent, or if
in their report, we assume that this is not evidence wanted, a variant in another C-based language.
pointing to a particular APT, but at the very least
it means that the adversary was fluent in Russian. That being said, since previous uses of X-Agent are
commonly associated with attacks of Russian inter-
Pivoting along the sociopolitical boundary of Vic- est, seeing X-Agent used still suggests Russia as a
tim-Adversary yields Russia, or a Russian affiliate/ likely adversary, even if we can’t identify a particular
ally, as the most likely suspect, since they would APT group. Now it may be tempting to look at the
have obvious interest in the Ukrainian military giv- current threat landscape, see that there are only a
en the conflict between the two countries. Please handful APTs associated with Russia, and conclude
note that this is not evidence that APT28 is respon- that it must be one of those, or more specifically
sible, just that someone with Russian interest is the APT 28, due to previous affiliation with X-Agent.21
most likely suspect. However, this process of elimination leaves out
the possibility of a new or unknown threat group.
Pivoting along the Capability-Adversary relation- Again, due to the length of time this implant has
ship proves the most interesting and, currently, it been in operation and the presence of source, this
seems that attribution of this sample to APT28 is is a real possibility.
based on this approach. POPRD30 is definitely a
variant of X-Agent, and X-Agent has been used Thus, by simply examining the data directly relat-
in previous attacks attributed to APT28. However, ed to this attack, it is very hard to establish a link
in order to use this information to firmly estab- between the POPRD30 sample and a specific ad-
lish a link between this attack and APT28, we also versary. The best we can do is conclude with some
need evidence that X-Agent is exclusively used by confidence, low to medium at best, that the adver-
APT28. As it turns out this is a very hard statement sary is Russia or a Russian ally, based on the socio-
to prove. political relationship between the Victim and Adver-
sary and previous uses of X-Agent in other attacks.
X-Agent has been in the wild since at least 2012.
Its command and control protocol has been well As we mentioned previously, it can also be help-
documented, and it’s easy to obtain a copy of the ful to compare data from an attack to previously
implant. It’d be fairly easy to reverse engineer a attributed attacks. We’ve already touched on this
known sample and re-implement its protocol and when discussing previous uses of X-Agent. We
functionality. Furthermore, in late 2016, researchers don’t possess a database of all known Russian-af-
at ESET reported that they had obtained the source filiated APT attacks. However, since POPRD30 is
for X-Agent on Linux. This leads us to several ques- currently affiliated with APT28, we focused on pub-

22
21
https://docs.google.com/spreadsheets/d/1H9_xaxQHpWaa4O_Son4Gx0YOIzlcBWMsdvePFX68EKU/edit#gid=1636225066
lished reporting about that group to make a com- 2. Researchers identify an APT28 attack on a tra-
parison, and judge whether this attack looked like ditional network, coupled with a simultaneous
other attacks attributed to that actor. Specifically, attack using the mobile variant of X-Agent. For
we used the dump of malware and reports provid- example, APT28 compromises a company’s
ed by Contagio.22 network. Using data retrieved from this attack,
they deploy X-Agent against key company em-
The closest thing we found was the iOS sample ployee mobile devices.
attributed by TrendMicro to PawnStorm, another
name for APT28. The iOS sample was very similar Both these possibilities would provide much stron-
to the POPRD30 sample in terms of functionality. ger evidence linking usage of mobile X-Agent back
However, the report provided no other evidence to APT28.
that we would need for comparison. It did not de-
scribe any of the victims, infrastructure, or even In conclusion, based on public data, we did not
how they found the malware. In fact, TrendMicro’s find enough evidence to attribute the POPRD30
report does not make it clear why they attributed Android malware to a known APT. At best we can
the iOS sample to APT28, beyond its similarity to conclude that the attackers were likely Russian or
other known X-Agent samples. As we have already Russian allies. Due to the presence of X-Agent
established that attribution by capability alone is source, X-Agent’s length of operation, and a lack
not sufficient to establish a link between X-Agent of historical data on APT28 mobile attacks, we do
and APT28, the report does not really add any ex- not think there is enough evidence to attribute PO-
tra evidence that would link the Android variant of PRD30.apk with APT28 or to establish a relation-
X-Agent to those attackers. ship with the DNC hacks. However, now that the
industry is aware of this variant, it will allow for bet-
Simply put, the collection of public data we have ter data collection on incidents involving Android
about this attack is not similar enough to previous X-Agent, so that in the future, a better attribution
incidents attributed to APT28 to establish with any assessment can be made when this variant is seen
sort of confidence that it is the same set of actors. in the wild. The fact is with any of these well-known
The primary contributing factor is that the history of APTs, the longer they operate, the more likely it is
attacks up to this point have been for desktop op- that someone else could try to re-use their tool-
erating systems. Besides an iOS sample for which chain to obscure attribution, especially if they
there is no public attribution data, this attack is the share common interests with the original authors/
first of its kind, and trying to make a comparison is operators. On the other hand, this could also in-
akin to comparing “Apples and Oranges.” centivize the original attackers to continue to use
the same toolchain, as the longer they operate,
This begs the question, “How would you establish the less credible attribution to them will seem.
a link between the mobile variant and APT28?” We
offer up two possibilities.

1. Researchers identify APT28’s Type 1 infrastruc-


ture and identify data from mobile X-Agent
variants inside of it. However, it’s unlikely that
such identification will get reported publicly.
If a vendor discloses that it has found APT28’s
primary infrastructure, more than likely, APT28
will immediately tear it down and set up new
infrastructure. This would result in the loss of a
valuable intelligence source, which for a secu-
rity vendor would mean less protection for its
customers. If attribution of the mobile X-Agent
was done in this way, we, as independent re-
searchers, would have no way to verify it.
23
22
http://contagiodump.blogspot.com/2017/02/russian-apt-apt28-collection-of-samples.html
CONCLUSION
By conducting a full in-depth analysis of the Tro-
janized POPRD30.apk, we have found that it con-
tains a variant of the X-Agent implant, commonly
employed by APT28. The implant contains func-
tionality for harvesting SMS history, call logs, con-
tact information, and referential location data.
Despite being intended for military targets, the im-
plant seems to be a traditional espionage implant
supporting the ability to map out an organization,
and identify further targets for exploitation. The lo-
cation data harvested by the malware is not precise
enough to support a precise military strike, like the
ones carried out by Russia against Ukraine. Upon ex-
amining the data surrounding the attack and other
attacks attributed to APT28, we find that the pres-
ence of X-Agent source code and the lack of evi-
dence in other important attribution categories call
into question attribution of this sample to APT28.
Using available public data, we assess that the An-
droid X-Agent attack was likely carried out by an
entity affiliated with Russia, but a lack of identifying
evidence prevents us from more specific attribution.

24

Das könnte Ihnen auch gefallen