© Aditya Gupta 2019
Aditya GuptaThe IoT Hacker's Handbookhttps://doi.org/10.1007/978-1-4842-4300-8_8

8. Exploiting Mobile, Web, and Network for IoT

Aditya Gupta1 
(1)
Walnut, CA, USA
 

In this chapter, we look at some of the additional ways of exploiting IoT devices, which are through the mobile application, web application, and network penetration testing skills.

Most of the IoT devices that you will see will have either a web or mobile component to it so users can access the device. This also opens a huge attack vector for security researchers if we want to identify vulnerabilities in the target IoT device. If we can identify vulnerabilities in the web, mobile, or network component of any given IoT device solution, chances are that it could lead to the entire system being vulnerable. There have been books written about each of these individual topics, so I keep this chapter focused on specifically how we can use those vulnerabilities to compromise IoT devices.

We start by looking at mobile applications, then move to the web applications, and finally move to network-based exploitation for IoT devices.

Mobile Application Vulnerabilities in IoT

The mobile applications are an integral part of most of the IoT devices around us. Pretty much any device that you find will have a mobile application that helps you control the IoT device or analyze the data collected by the IoT device. However, unless enough attention is paid to the security of these applications, there chances are high that the applications will be vulnerable, leading to the insecurity of the entire IoT solution.

In this section, we cover some of the common mobile application security issues typically seen in IoT devices. We won’t cover all the vulnerabilities in detail, as that would require a separate book of its own, you will gain insight into how to start analyzing mobile applications for the Android platform and what key information can be extracted from them. You can also use the same concepts to analyze iOS applications, too.

Inside an Android Application

Android applications are ZIP archive files, which have the standard extension of .apk or Android packages. All the compiled class files, native libraries, and additional resources are packaged within this APK file, which then finally gets installed, and the executable file (classes.dex) is run on the device.

Because it’s a ZIP archive file, the usual notion that comes to mind to analyze these files is to use an archive extractor or decompressor to view them. However, because the files are also compiled before being packaged, the usual decompression routine will result in unreadable files.

For this reason, we use a special set of tools called a decompiler. These tools help us extract the Android APK and also decompile the various files within it to make it readable. These are two of the most popular decompilation tools:

APKTool converts the class files of the Android application into another format called Smali, which can then be analyzed and modified. Smali code looks like assembly instructions and requires more effort to understand, compared to the standard Java syntax. The only advantage of Smali code is that we are able to modify the Smali code and repackage the new code to create a new malicious application. This is the exact same thing we did with firmware modification in the previous chapter in the terms of Android applications.

JADx is an open source tool written by Skylot that performs the decompilation in two steps. The first step is decompiling the classes.dex file, which is a compiled file inside the package containing all the class files, to a JAR file. The next step simply converts the JAR file classes to readable Java class files. The Java class files are much simpler to understand compared to smali files, and the only limitation is that we can’t modify the code here and repackage the application. In the next section I show how to use JADx to reverse an Android application and identify sensitive values from it.

Reversing an Android Application

Let’s start with a real-world Android application called SmartWifi.apk. This is the Android application for the Kankun smart plug, and is present in your book Downloads folder. A smart plug is a device that can be connected to a power socket and can be controlled and turned on and off with the use of a smartphone.

In this case, I was able to find the mobile application from the product documentation that came along with the smart plug. Go ahead and install the application on your Android device (or emulator). Because this application came from the Google Play Store, I didn’t have the original APK, which is why I pulled the installed app from the Android device, which is given in the steps later.

We use a utility called the Android Debug Bridge (adb) that comes along with the Android SDK and helps us interact with the Android devices.

The first thing that we will do is pull the application binary from the device. This can be done by first identifying the package name with adb shell ps and then pulling the binary from the device using adb pull .
adb pull /data/app/com.smartwifi.apk-1.apk

Now we have the APK file on our local system, which we can use to analyze the application for security issues.

The first action that we will perform on the APK file is to decompile it using JADx. Let’s go ahead and install JADx first as shown here.
$ wget https://github.com/skylot/jadx/releases/download/v0.6.1/jadx-0.6.1.zip
$ unzip jadx-0.6.1.zip
$ cd jadx/bin/

Inside the bin folder we have two useful binaries, namely jadx and jadx-gui. The jadx binary decompiles the application class files and stores them as individual Java files, which we can then analyze manually. The jadx-gui will decompile the application class files and show us in a GUI window where we could analyze the individual class files.

Let’s go ahead and run jadx on smartwifi.apk and see if we are able to find any interesting data from it.
➜  additional material ~/tools/jadx/bin/jadx smartwifi.apk
INFO  - output directory: smartwifi
INFO  - loading ...
INFO  - processing ...
WARN  - Can't detect out node for switch block: B:29:0x0043 in android.support.v4.app.FragmentManagerImpl.moveToState(android.support.v4.app.Fragment, int, int, int, boolean):void
-- output snipped --
ERROR -   Method: com.google.gson.internal.Excluder.withModifiers(int[]):com.google.gson.internal.Excluder
ERROR -   Method: hangzhou.kankun.DeviceActivity.GetThread.run():void
ERROR -   finished with errors

You might notice that there are a couple of warnings and errors, which is perfectly safe to ignore at this point because it simply indicates that there were some parts of the application that weren’t successfully decompiled.

Once the decompilation process is completed, it will create a new directory for us with the name of the APK file, which in this case is the smartwifi directory.

Inside the smartwifi directory , we will have the files and folders shown here.
~/tools/jadx/bin/smartwifi » tree
.
├── android
│   └── support
│       └── v4
├── AndroidManifest.xml
├── com
│   └── google
│       └── gson
├── custom
│   └── CustomDialog2.java
├── hangzhou
│   ├── kankun
│   │   ├── AlertUtil.java
│   │   ├── ArrayWheelAdapter.java
│   │   ├── Config.java
│   │   ├── ControlHelpActivity.java
│   │   ├── dbHelper.java
│   │   ├── DBManager.java
│   │   ├── DeviceActivity.java
│   │   ├── DeviceTaskActivity.java
│   │   ├── GetElectricityService.java
│   │   ├── GuideActivity.java
│   │   ├── JudgeDate.java
│   │   ├── NetStateUtil.java
│   │   ├── NetworkTool.java
│   │   ├── NumericWheelAdapter.java
│   │   ├── OnWheelChangedListener.java
│   │   ├── OnWheelScrollListener.java
│   │   ├── ProtectService.java
│   │   ├── ScreenInfo.java
│   │   ├── SelectPicPopupWindow.java
│   │   ├── ShowDialogActivity.java
│   │   ├── SmartwifiActivity.java
│   │   ├── UpdateModel.java
│   │   ├── ViewPagerAdapter.java
│   │   ├── WheelAdapter.java
│   │   ├── WheelMain.java
│   │   ├── WheelView.java
│   │   ├── WifiAdmin.java
│   │   └── WifiJniC.java
│   └── zx
│       ├── BuildConfig.java
│       ├── PreferencesUtil.java
│       └── R.java
└── res
├── anim
├── drawable
├── drawable-hdpi
├── drawable-zh-hdpi
└── layout
34 directories, 286 files

To save space, I have omitted many files and folders in the listing that are not useful for us. The interesting bits are in bold, which we analyze now.

The first point of interest is the AndroidManifest.xml file, which is a required file for any Android application. AndroidManifest.xml contains important information about the application such as the package name, the different components of the applications, the various SDKs and third-party libraries, the Android versions it is supposed to run, the permissions needed by the application, and more. Having a look at the AndroidManifest.xml file usually gives us insight into what the application is about and helps us in the further analysis phases.

Let’s go ahead and open AndroidManifest.xml and see what it contains in this case, as shown in Figure 8-1.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig1_HTML.png
Figure 8-1

Analyzing Android application using AndroidManifest.xml

It gives us information such as the package name, hangzhou.zx, which we are already aware of, the list of permissions, and so on. Let’s go ahead and see if we can get any useful information—such as the firmware download URL—by looking at the Java files in the application.

Hard-Coded Sensitive Values

Because there is not anything of high interest in AndroidManifest.xml, let’s look at the Java files and see if we can find something worth looking into. We start looking in the hangzhou/zx folder, as that is what the package name indicates.

In the zx folder, there are three files: PreferencesUtil.java, R.java, and BuildConfig.java. Because R.java is simply an auto-generated file and BuildConfig.java looks like it is storing the building configuration, the only file that is of interest is PreferencesUtil.java. Let’s open this file in a code editor and see what it contains.

During the initial few lines, after the imports, we have the variable filePathString that points to a remote URL, http://app.jkonke.com/kkeps.bin . This looks like a possible firmware download URL and might hold the firmware of the smart plug that is first downloaded to the mobile application and then flashed to the smart plug over either Wi-Fi or Bluetooth. Let’s download this firmware binary from the URL found in the mobile application.
wget http://app.jkonke.com/kkeps.bin
We can now go ahead and extract the file system using Binwalk as shown in Figure 8-2.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig2_HTML.png
Figure 8-2

Extracting file system from the smart plug firmware

As we can see in Figure 8-2, the kkeps.bin file has the entire firmware with the complete file system.

At this point, we can start exploring various files and directories inside the firmware file system. One interesting place to look for binaries is the sbin directory. Looking at sbin, we see that we have a couple of interesting binaries, as shown in Figure 8-3.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig3_HTML.png
Figure 8-3

Looking at binaries inside the firmware

Digging Deep in the Mobile App

Apart from sensitive hard-coded values, such as the firmware download URL, we can also look in the application and try to identify and understand its functionality. This understanding could be useful if we are writing an exploit for the application or want to understand how a certain component such as encryption of the network communication works.

To understand the application’s functionality, we would have to look into all of the different Java files one after the other. Here are some of the findings that we can get from analyzing various Java files.

Finding 1: App Download URL

From the file Config.java, we see that the variable UPDATE_SERVER points to the URL http://kk.huafeng.com:8081/none/android/ as shown in Figure 8-4.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig4_HTML.png
Figure 8-4

UPDATE_SERVER URL found in the mobile application

As shown in Figure 8-5, if we navigate to this URL in our web browser, we see that this indeed holds the APK file that would be downloaded from the server and then installed on the mobile application based on the version that is specified in the ver.json file indicated by the variable UPDATE_VERJSON.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig5_HTML.jpg
Figure 8-5

Vendor’s web site for downloading new packages

Finding 2: Local Database Details

In the file dbHelper.java, one of the initial interesting things to notice is this line:
private static final String DATABASE_NAME = "smartwifi_device_db3";
As shown in Figure 8-6, in the preceding line, we can see that the name of the database where everything is being stored is smartwifi_device_db3. In the next code block, we see the various columns, which will be in the database’s table with the name smartwifi_device_list.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig6_HTML.jpg
Figure 8-6

Analyzing database setup and various fields in the database

This gives us full information about the local database, including the database name, the table name, and the individual column names. All the database-related actions are specified in the file DBManager.java.

Finding 3: Command Properties

In the file DeviceActivity.java, we find a number of interesting items. First of all, we see that there is a cmd variable that is being used a number of times, which could possibly indicate the command that is being sent to the smart plug from the Android application.

The open and close commands might mean that the device needs to be turned on and off in the lines shown in Figure 8-7.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig7_HTML.jpg
Figure 8-7

Understanding smart plug commands

Moving further in the same file, we notice other commands such as REQUEST_ENABLE_BT , which simply stands for asking the user to enable Bluetooth to use the application.

The most interesting observation is made in the following two lines, as shown in Figure 8-8. We have the mention of two variables, udp_cmd and cmd_buf, which are used for different commands throughout the code. It also mentions the usage of jnic, which stands for Java Native Interface and is used when the Android application interacts with one of its native libraries.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig8_HTML.png
Figure 8-8

Command structure for controlling the smart plug

This entire code block helps us know three useful items:
  1. 1.

    The commands are being sent over User Datagram Protocol (UDP).

     
  2. 2.

    The format of the command that is being used.

     
  3. 3.

    Usage of a function called encode in the native library located in our Android application.

     

So, our commands exchanged between the Android application and the smart plug are in the format specified by the datapacket variable . It is also worth noting that the initial command specified by udp_cmd is being sent to the encode function and stored in the cmd_buf variable, which is then finally being sent in the following code line. The port that is used in this case is Port 45398.

Similarly, at line 394, instead of the value wan_phone, it says lan_phone, which is the value that will be used if the device is operated in the same local area network (LAN).

Finding 4: Goldmine In SmartwifiActivity.java

If we start looking in SmartwifiActivity.java , we will see that it gets a value called encrypt_info from the shared preferences, as shown in Figure 8-9. Shared preferences are simply a way of storing data in the local Android device.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig9_HTML.png
Figure 8-9

Data storage on the device

In the following lines, it says that if there is no password specified, the default password that will be used is nopassword.

Moving further, this file has additional details such as specifying that the Wi-Fi access point name will begin with the character 0k_SP3 as specified by this line.
SmartwifiActivity.this.wifiAdmin.addNetwork(SmartwifiActivity.this.wifiAdmin.CreateWifiInfo("0K_SP3", "", SmartwifiActivity.REQUEST_ENABLE_GD, 0));
Later, in line 1052, it also specifies a command format to be used when sending information via UDP and things such as HeartBeat, which is sent over Port 27431, as shown in Figure 8-10.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig10_HTML.png
Figure 8-10

HeartBeat messages between the device and mobile application

In the code block starting from line 1103, it also confirms one of our earlier findings of the kkeps.bin being used as firmware. In these lines, we can see that the firmware binary is being downloaded and stored in the ExternalStorage (SD card) , as shown in Figure 8-11.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig11_HTML.png
Figure 8-11

Downloaded firmware is stored in external storage of smartphone

The application also changes the firmware of the smart plug using the command phone%changefirm% as shown in Figure 8-12.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig12_HTML.png
Figure 8-12

Changing firmware command structure

Later on, it also specifies many other things, such as the command in use, call to JNI, and other typical expected code.

As shown in Figure 8-13, in line 1780, it gives us again a useful piece of information, the SERVER_HOST_IP, which in this case would be the static IP of the smart plug when it acts as an AP and has the Android device connected to it.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig13_HTML.png
Figure 8-13

Default IP address of the smart plug

That is all for our findings in the smart plug Android application. As you can see, just from the Android application we were able to identify a number of interesting findings. These findings will also be useful later on for us once we reverse the mobile application communication and reverse the encryption that is being used in this IoT device communication with its mobile application.

Reversing Encryption

One of the other things we can do with the mobile application is analyze the native library. Remember that we saw an instance of a function named encode being called from the application code. We look into this function and disassemble the ARM library in Chapter 10 on binary exploitation. However, in this section, we can simply run strings on our native library and look at the password.

To get access to the native library, instead of decompiling the application, we can simply unzip it and look inside the lib folder. Let’s go ahead and unzip smartwifi.apk using the unzip command with -d to specify the destination as shown in Figure 8-14.
unzip smartwifi.apk -d smartwifiunzipped/
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig14_HTML.png
Figure 8-14

Unzipping the Android application

Once the extraction completes, we will have a new folder named smartwifiunzipped that will hold all our files and folders from the APK archive. We can now go inside the lib folder and then inside the armeabi which is for ARM-based libraries. Here you will notice that there is a library called libNDK_03.so.
$ cd lib/armeabi
$ ls
libNDK_03.so
Let’s go ahead and run strings on this particular ARM library and see if there are any interesting strings or functions that stand out. Initially, start by looking for encryptions that have been possibly implemented within the library function, as shown in Figure 8-15.
strings libNDK_03.so | grep –i aes
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig15_HTML.png
Figure 8-15

Encryption functions inside the native library

There are several instances of AES, which signifies that an AES encryption is being used. The next step is to try to find the AES key. As mentioned earlier, we could do an in-depth disassembly of the libNDK_03.so binary using a tool such as radare2 or IDA Pro. However, to keep things simple here, we can identify the key just by performing strings on it and looking for strings that stand out, and using a brute-force approach to figure out whether it’s a valid key or not.
$ strings libNDK_03.so
pp|B>>q
aaj_55
UUPx((
Zw--
fdsl;mewrjope456fds4fbvfnjwaugfo
java/lang/String
GB2312
getBytes
(Ljava/lang/String;)[B
append String
pointer is null
pucInputData dataLen is incorrect
pucOutPutData is too small
pucOutputData too small
aeabi
GCC: (GNU) 4.4.3
aes_set_key
aes_encrypt
aes_decrypt
EncryptData16
Java_hangzhou_kankun_WifiJniC_add
Jstring2CStr
Java_hangzhou_kankun_WifiJniC_codeMethod
DecryptData
Java_hangzhou_kankun_WifiJniC_decode
EncryptData
Java_hangzhou_kankun_WifiJniC_encode
_Unwind_VRS_Get
_Unwind_VRS_Set
_Unwind_GetCFA
_Unwind_Complete

The string fdsl;mewrjope456fds4fbvfnjwaugfo in this case is our actual AES key. Once we have identified the correct AES key, we can proceed to decrypting the communication between the smart device and the mobile application.

To capture communication between the two endpoints, you can use tools such as Wireshark or tcpdump and save the entire communication in a Packet Capture (PCAP) file that we can then analyze. As shown in Figure 8-16, we have a packet capture between the two endpoints—SmartPlug and the mobile application—with the IPs being 192.168.3.5 and 192.168.3.6.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig16_HTML.png
Figure 8-16

Network communication between smart plug and the mobile application

Notice that in the data section of the packet, we have an encrypted value inside the current data value. Because we know the kind of encryption being used and the encryption key, though, we can write our own AES decryption script and decrypt this. Figure 8-17 shows how the decryptaes.py script looks.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig17_HTML.png
Figure 8-17

AES decryption script

We can replace packet-data-value with the value that we got from the data parameter from Wireshark in the previous step. Once we execute this, we can see in Figure 8-18 that we are able to successfully decrypt the network traffic packets, which were previously encrypted with AES encryption.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig18_HTML.png
Figure 8-18

Successful decryption of encrypted network packets

The next step that we can do is use additional exploitation techniques, such as crafting our own packets to take control of the smart plug, cracking the password from the firmware, and logging in via SSH. This is what we are going to see in the next section.

Network-Based Exploitation

Let’s take a fresh approach and look at the smart plug again. Because it is connected to our network, we can find out the IP and MAC addresses of our target smart plug, and then perform various network-based exploitation techniques on it. Also, the IP and MAC addresses will be useful for us if we want to take control of the smart plug, as the commands that the mobile application sends to the device will require both these values.

Go ahead and connect the smart plug to your network, and connect your laptop and the VM to the same network using a bridged networking configuration.

Next, to find the device we can use the command arp -a, which will give us the result shown in Figure 8-19.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig19_HTML.png
Figure 8-19

Finding the IP and MAC addresses of smart plug

We can also navigate to the IP address found in the earlier step to see if there are any interesting web dashboards for this device. In this case, we can see that there are no files being served over the web server and it is merely running.

The next step, as for any other pentest, would be to perform a network scan of the device and discover the different ports that are open and what services are running.

To scan the smart plug, we use nmap , which is a powerful network scanner allowing us to see open ports, running services, and also in specific cases perform additional exploitation. We can install nmap using sudo apt install nmap and then run a scan using this command:
sudo nmap -sS -T4 192.168.0.253
As we can see from Figure 8-20, a couple of ports are open, including Port 22 which is running SSH.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig20_HTML.jpg
Figure 8-20

Open ports on the smart plug

Because the SSH port is open, we can perform a brute-force attack and test the SSH credential using the username and password combination from a dictionary. The SSH password has already been cracked by a security researcher and posted online. We have provided that in the file passwd.list in the Downloads bundle for this book for the sake of simplicity, and so that you don’t need to keep running the brute forcer for six or seven hours.

We can choose between any of the various tools that would allow us to perform brute forcing on the SSH service running on the smart plug. Two of the most popular tools for this purpose are Hydra and Medusa.

Another option to crack the password is using etc/passwd and the etc/shadow file, with the unshadow utility.
unshadow etc/passwd etc/shadow > smartplug_crack
The new created file could then be run with John the Ripper with the passwd.list to crack the password. Once done, you will now see that the password has been cracked and the password is p9ztc, as shown in Figure 8-21.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig21_HTML.png
Figure 8-21

Cracking SSH password from the smart plug

Once we have cracked the password, we can now use these credentials to log in to the SSH of the smart plug, as shown in Figure 8-22.
ssh root@ip-address
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig22_HTML.jpg
Figure 8-22

Root access on the smart plug device

As you can see from Figure 8-22, we have successfully been able to log in to our target smart plug.

Web Application Security for IoT

IoT devices, as mentioned earlier, will in some cases also have a web interface for users to interact with. It is essential for us to understand how to analyze web interfaces for IoT devices for security issues and how to exploit them.

Because web application security is a commonly discussed topic, and there are tons of resources available online, we keep this section to a minimum and focus on a couple of scenarios in which we can use the web application security vulnerabilities to exploit IoT devices.

Assessing Web Interface

Once you have a web interface of an IoT device, to see what communication is happening between the interface on your browser and the other web endpoint, we use a proxy tool, in this case Burp Suite. The first step is to ensure that you have the proxy listener active and running. You can also change it to listen to all interfaces, as shown in Figure 8-23.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig23_HTML.png
Figure 8-23

Burp configuration

Scroll down and ensure that both intercept client requests and client responses are selected, as shown in Figure 8-24. This is important for you to be able to look at the traffic and modify it for both the ones coming from the other endpoint and the ones that are going from your browser to the remote server.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig24_HTML.jpg
Figure 8-24

Intercepting client request and server responses

The next step is to set up the proxy in your browser. If you are not familiar with how to set up a proxy in your browser, open Firefox and navigate to Settings | Preferences | Advanced | Network | Connection Settings | Manual. Type 127.0.0.1 and 8080, which are the IP and Port settings for where our Burp instance is running.

Next open the web interface of the target device you are trying to assess. In this case, we have Netgear WNAP320 firmware up and running, with the default login screen visible, as shown in Figure 8-25.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig25_HTML.png
Figure 8-25

Emulated firmware’s web interface

If we enter any credential here, and click Login, we will be able to see the traffic in Burp Suite in the Proxy | Intercept tab shown in Figure 8-26.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig26_HTML.png
Figure 8-26

Intercepted traffic in Burp

We can also send this request to Repeater as shown in Figure 8-27, where we can try modifying arguments and performing additional security analysis.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig27_HTML.png
Figure 8-27

Captured traffic request data in Burp

Note

If you want to perform a brute-force attack on the various parameters, it is a better option to send it to the Intruder rather than the Repeater. The Repeater is where we can modify various arguments manually and see the results of our modifications.

Next, let’s try the default credential of username=admin, and password=password, and send it to the web endpoint, as shown in Figure 8-28.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig28_HTML.png
Figure 8-28

Analyzing traffic in Burp’s Repeater

As we can see in Figure 8-28, we are able to successfully log in and the response message said loginok.

Now that we have a basic understanding of how to work with a proxy, we can move on to performing additional exploitation using our web application security knowledge.

Exploiting Command Injection

One of the most common vulnerabilities in web interfaces of IoT devices is command injection. This is also because there are many user inputs that need to be executed on the device and when not sanitized properly, will lead to a vulnerability like this.

Let’s have a look at the WNAP320 firmware and how we can identify and exploit a command injection vulnerability in it. The first step would be to unzip the tar archive file and extract the root file system. In this case, we can either use binwalk, or even unsquashfs, to extract the squashfs image, as shown in Figure 8-29.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig29_HTML.jpg
Figure 8-29

Extracting Netgear’s firmware file system

Let’s now navigate to rootfs.squashf.extracted and inside the squashfs-root directory to look for all the PHP files, depicted in Figure 8-30.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig30_HTML.jpg
Figure 8-30

Extracted file system

As we can see from Figure 8-30, the PHP files are located inside the home/www/ directory, where we can then look for different files that might have command injection vulnerability. You can also try grepping for sensitive functions, which are typically used in command injection, such as passsthru(), exec(), eval(), and so on.

In this case, we open up a file called boardDataWW.php . As you can see from Figure 8-31, there is a command injection vulnerability where it is taking values from the request parameters, namely macAddress and reginfo, and then passing them to an exec code block. This is a command injection because it is not sanitizing the user input that is finally passed to the exec block.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig31_HTML.jpg
Figure 8-31

Accepting user inputs from the web page and passing it to exec

We can now navigate to the address in the browser—192.168.0.100/boardDataWW.php—and type an initial MAC address to capture the request in Burp, as shown in Figure 8-32.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig32_HTML.png
Figure 8-32

Netgear’s vulnerable web interface

We can see in Figure 8-33 the request being intercepted in Burp with the format that we expected.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig33_HTML.png
Figure 8-33

Analyzing the command injection in Repeater

Let’s send this to Repeater and try by adding an additional comment to verify the command injection. In this case, let’s add ls and see what the output looks like. If you are performing it for the first time, though, you can use commands such as ping or sleep, and then note the delay in the response coming back to you, which will also indicate a valid command injection vulnerability in the target system, as shown in Figure 8-34.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig34_HTML.png
Figure 8-34

Checking for command injection

Unexpectedly, instead of seeing the result of the command ls, we simply see a message: Update Success. This means that instead of a normal type of command injection, this is a blind command injection, where we won’t be able to see the output in the response, even if the command is executed successfully. We can verify this by executing a command that will create a file, and then request a file, as shown in Figure 8-35.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig35_HTML.png
Figure 8-35

Copying files using command injection vulnerability

Let’s now see if this file has been created by sending a request to ip/attify. As you can see in Figure 8-36, the initial command did succeed and we are able to get the content of the file that we created in the first command.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig36_HTML.jpg
Figure 8-36

Successful command injection

We can take this a step further by doing the same with the etc/passwd file and then requesting it via the browser, as shown in Figure 8-37.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig37_HTML.png
Figure 8-37

Obtaining etc/passwd using command injection

Firmware Diffing

Diffing is one of the other things that we can do with firmware to identify all sorts of various vulnerabilities—be it web, mobile, or any other binary. This is extremely useful for understanding the various security issues that might have existed in the previous version of the firmware, even if they are not publicly revealed. In addition, in the IoT ecosystem, the update process is usually not immediate—because of the dependence on the hardware and manual effort combined with technical skill set—so finding a vulnerability in the previous version of a component is extremely useful.

For this exercise, we take two different versions of the MR-3020 firmware. Let’s first extract them both, and then extract their file system using Binwalk, as shown in Figure 8-38.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig38_HTML.jpg
Figure 8-38

Extracting different versions of firmware for diffing

Once both the firmware file systems have been extracted, we use a utility called kdiff3 to see the changes between the entire files located inside both the firmware versions. In this case, we are concerned about web files, but in cases where you are performing a much deeper diffing—such as the diffing of two different binaries—it would be useful to use tools such as Bindiff for the analysis.

Load up both the squashfs-root directories in kdiff3 and you will see that it has compared both of the directories and their individual files, as shown in Figure 8-39.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig39_HTML.png
Figure 8-39

Using kdiff3 for diffing

If you go a bit further and look at the file LanDhcpServerRpm.htm inside the web/userRpm/ directory, you will see that TP-Link has recently added a Cross Site Request Forgery (CSRF) protection code in the new version of the firmware, which was missing in the previous versions, as shown in Figure 8-40.
../images/473264_1_En_8_Chapter/473264_1_En_8_Fig40_HTML.png
Figure 8-40

Identifying CSRF vulnerability using diffing

Given that this is an extremely critical file that allows the user to take actions on their web configurations, a CSRF vulnerability in this case would be extremely useful if exploited by attackers.

Conclusion

In this chapter, we covered several topics—all the way from mobile applications, to web applications, to even a bit of network-based exploitation. All of these exploitation and vulnerability research techniques will be useful when you are pentesting a real-world device, as most of the devices that you will encounter will have more than one (or all) of these components.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.160.216