Hello everyone, today I want to share an analysis of the Hak5 Cloud C2 tool.
What's Hak5 Cloud C2?
As stated on their website:
In a nutshell, this software will help you be more easily and remotely 'persistent' during engagements, red team evaluations and pentests, while using your hardware tools like:
How does it works?
This tool launches a web server with apis and a web user interface to manage the limited (no longer ) set of hardware tools.
How to setup
Take your server / pc / whatever you have ready and replace the current c2-<x.x.x>_<arch>_<os>(.exe) you used with the patched one and then do it:
And proceed with the installation at: http://<your-current-ip>:8080
You will be redirected to the configuration page.
At this point, enter your data and, as far as the licence is concerned, use the correct installation token (displayed on the terminal at first start-up) and any code.
Once the installation is complete, stop the executable and run HAK-C2-License-Toolkit and enter the crack.
Restart the executable again and you're done!
Licensing Analysis
The licence is managed with Internet support.
At installation, start-up and at certain times, it checks the licence with the API server.
I tried to force the analysis of a licence string, but it was not so easy.
I tried reversing the signature checking algorithm and, although I succeeded, it was not very helpful.
So I tried another approach, forcing the licence to the database and patching the entire licence checking function to return it.
At first glance, I noticed multiple calls to a certain local DB, but couldn't figure out which one it was.
After some research and deeper analysis, I discovered that the database in question is BoltDB ( More Info ), in a nutshell:
Together with BoltDB, all data is encoded using Golang's native encoding, called GOB.
Writing the read function is quite simple, as all that is needed is to write a wrapper to connect to and read the data from the 'c2.db' database.
Or you can use the official CLI tool from BoltDB here.
I am now able to read the data and am presented with this list of buckets:
status and setup are the ones that look most promising, so let's see their keys:
Status:
Setup:
NOTE:
Now let's take a look at the licence verification class, which is 'github.com/hak5/cc-server/licence.Verify'.
In order it does:
From IDA we can get a good idea of the licence structure, but it is not perfect, as can be seen:
Although we have the main variables used within the struct, we still don't know how to parse them from Database.
Since the software is written in Golang, I used a tool called Redress, from GoRe ToolKit [GORETK] ( More Infos ) to help me understand some of the information in the binary, such as the License and Status structures, so that I could analyse them from the BoltDB database and GOB decoding.
NOTE:
Here are the two structures:
Now we know what to do, in order:
So, to help me with this task, I wrote a "toolkit" (a lot of code) in golang to help me read/write and automate the actions on the BoltDB we have.
You can have a look at the official Bolt repository to understand how it works and how to work with it, I will skip this part because it is already in the toolkit code.
Binary Patch
All we have to do is replace the beginning of the function license.Verify with a return, so that it returns immediately.
(Using a nop instead of licence.Verify may cause crashes or memory management problems).
Here is a screenshot of the line that will be patched:
As you can see, we are going to replace the first line: cmp rsp, [r14+10h] with a simple retn.
From the HEX view, you can see that the operation is: 49 3B 66 10
We will then force it to return, replacing it with the well-known hexadecimal opcode C3, meaning retn:
NOTE:
Before:
After:
In this way, we force the tool never to check the licence and not to make any server-side calls.
After Binary Patch:
Now the tool will never check the licence, so we can set arbitrary values for our licences and it will work.
I will not dwell on how to work with BoltDB and GOB coding, as I assume you are able to read and study how they work.
I will only explain some parts of the "licence toolkit" I wrote with comments:
Now it's time to fire up our Hak5 Unlimited C2 and have some fun!
NOTE:
I hope you enjoyed this different content and that it not only intrigued you, but also helped you better understand how certain software can work.
Sometimes there is not only a need for patches/adjustments, but simply to 'undo' the licence checks and force it through a file/database.
If you have any questions, feel free to ask in the comments below!
We will release the patched binaries as soon as possible, but we are very busy lately!
Here you go the files:
c2-3.3.0_armv5_linux:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_armv5_linux
c2-3.3.0_armv6_linux:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_armv6_linux
c2-3.3.0_armv7_linux:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_armv7_linux
c2-3.3.0_armv8_linux:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_armv8_linux
c2-3.3.0_i386_windows.exe:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_i386_windows.exe
c2-3.3.0_i386_linux:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_i386_linux
c2-3.3.0_amd64_windows.exe:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_amd64_windows.exe
c2-3.3.0_amd64_linux:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_amd64_linux
c2-3.3.0_amd64_darwin:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_amd64_darwin
HAK5-C2-Toolkit-win-i386:
https://ponies.cloud/c2/hak5-cloud-c2/HAK5-C2-Toolkit-win-i386
HAK5-C2-Toolkit-lin-amd64:
https://ponies.cloud/c2/hak5-cloud-c2/HAK5-C2-Toolkit-lin-amd64
HAK5-C2-Toolkit-lin-386:
https://ponies.cloud/c2/hak5-cloud-c2/HAK5-C2-Toolkit-lin-386
HAK5-C2-Toolkit-win-amd64:
https://ponies.cloud/c2/hak5-cloud-c2/HAK5-C2-Toolkit-win-amd64
HAK5-C2-Toolkit-mac-arm64:
https://ponies.cloud/c2/hak5-cloud-c2/HAK5-C2-Toolkit-mac-arm64
HAK5-C2-Toolkit-mac-amd64:
https://ponies.cloud/c2/hak5-cloud-c2/HAK5-C2-Toolkit-mac-amd64
Or on Github:
https://github.com/Pwn3rzs/HAK5-C2-License-Toolkit/releases/tag/v3.3.0
What's Hak5 Cloud C2?
As stated on their website:
SHIP HAK5 GEAR. GET ON-SITE RESULTS.
PENTEST ANYWHERE, RIGHT FROM THE WEB
Cloud C² makes it easy for pentesters and security teams to deploy and manage Hak5 gear from the cloud.
CLOUD C² IS THE INTERSECTION OF OUR HARDWARE MASTERY, SOFTWARE EXPERTISE, AND ETERNAL AMBITION TO PROVIDE SMARTER PENTEST TOOLS.
In a nutshell, this software will help you be more easily and remotely 'persistent' during engagements, red team evaluations and pentests, while using your hardware tools like:
- WiFi Pineapple
- LAN Turtle
- Packet Squirrel
- Screen Crab
- Shark Jack
- Key Croc
How does it works?
This tool launches a web server with apis and a web user interface to manage the limited (no longer ) set of hardware tools.
How to setup
Take your server / pc / whatever you have ready and replace the current c2-<x.x.x>_<arch>_<os>(.exe) you used with the patched one and then do it:
Bash:
./c2_executable -hostname <your-current-ip>
And proceed with the installation at: http://<your-current-ip>:8080
You will be redirected to the configuration page.
At this point, enter your data and, as far as the licence is concerned, use the correct installation token (displayed on the terminal at first start-up) and any code.
Once the installation is complete, stop the executable and run HAK-C2-License-Toolkit and enter the crack.
Restart the executable again and you're done!
Licensing Analysis
The licence is managed with Internet support.
At installation, start-up and at certain times, it checks the licence with the API server.
I tried to force the analysis of a licence string, but it was not so easy.
I tried reversing the signature checking algorithm and, although I succeeded, it was not very helpful.
So I tried another approach, forcing the licence to the database and patching the entire licence checking function to return it.
At first glance, I noticed multiple calls to a certain local DB, but couldn't figure out which one it was.
After some research and deeper analysis, I discovered that the database in question is BoltDB ( More Info ), in a nutshell:
Bolt is a pure Go key/value store inspired by Howard Chu's LMDB project. The goal of the project is to provide a simple, fast, and reliable database for projects that don't require a full database server such as Postgres or MySQL.
Together with BoltDB, all data is encoded using Golang's native encoding, called GOB.
Writing the read function is quite simple, as all that is needed is to write a wrapper to connect to and read the data from the 'c2.db' database.
Or you can use the official CLI tool from BoltDB here.
I am now able to read the data and am presented with this list of buckets:
apilog
chatmessages
db_version
devices
log
migrations
news
notifications
roles
settings
setup
sites
status
unreadmessages
users
status and setup are the ones that look most promising, so let's see their keys:
Status:
status
Setup:
license
privateKey
publicKey
token
NOTE:
The tool is built on golang, so it may be difficult to reverse it at first, but fear not, we'll take care of it.When running the tool for the first time without configuration, the licence key is not created, but when writing to a bucket/key that does not exist, it is created at the time of the update.
Now let's take a look at the licence verification class, which is 'github.com/hak5/cc-server/licence.Verify'.
In order it does:
- Check the licence key and version with their apis at: https://c2.hak5.org/api/v2/verify?key=XXXX-XXXX-XXXX-XXXX&product=productType
- Obtaining the content of the response and verifying its signature
- Load public key into memory
- Check signature
- Returns whether it is valid or not
- If the signature matches, a new licence variable is started following the licence struct.
- If a valid licence is returned, it is updated/saved in the database.
From IDA we can get a good idea of the licence structure, but it is not perfect, as can be seen:
Code:
00000000 licence_License struc ; (sizeof=0x30, align=0x8, copyof_1893)
00000000 ; XREF: github.com_hak5_cc_server_database._ptr_Db.upgradeLicenseDBModel/r
00000000 ; github.com_hak5_cc_server_database._ptr_Db.ValidateAndSyncCurrentLicense/r ...
00000000 Key string ? ; XREF: github_com_hak5_cc_server_database__ptr_Db_upgradeLicenseDBModel:loc_1416CE2/w
00000000 ; github_com_hak5_cc_server_database__ptr_Db_upgradeLicenseDBModel+185/w ...
00000010 Type dq ? ; XREF: github_com_hak5_cc_server_database__ptr_Db_upgradeLicenseDBModel+14B/w
00000010 ; github_com_hak5_cc_server_database__ptr_Db_upgradeLicenseDBModel+195/w ...
00000018 UserLimit dq ? ; XREF: github_com_hak5_cc_server_database__ptr_Db_upgradeLicenseDBModel+157/w
00000018 ; github_com_hak5_cc_server_database__ptr_Db_upgradeLicenseDBModel+1E1/r ...
00000020 DeviceLimit dq ? ; XREF: github_com_hak5_cc_server_database__ptr_Db_upgradeLicenseDBModel+163/w
00000020 ; github_com_hak5_cc_server_database__ptr_Db_upgradeLicenseDBModel+19D/w ...
00000028 SiteLimit dq ? ; XREF: github_com_hak5_cc_server_database__ptr_Db_upgradeLicenseDBModel+16F/w
00000028 ; github_com_hak5_cc_server_database__ptr_Db_upgradeLicenseDBModel+1F1/r ...
00000030 licence_License ends
Although we have the main variables used within the struct, we still don't know how to parse them from Database.
Since the software is written in Golang, I used a tool called Redress, from GoRe ToolKit [GORETK] ( More Infos ) to help me understand some of the information in the binary, such as the License and Status structures, so that I could analyse them from the BoltDB database and GOB decoding.
NOTE:
You can obtain the structures of a certain golang binary with this command:
Bash:redress types struct <binary>
Here are the two structures:
Code:
/* License struct */
type licence.License struct {
Key string `json:"key"`
Type uint64 `json:"type"`
UserLimit uint64 `json:"user_limit"`
DeviceLimit uint64 `json:"device_limit"`
SiteLimit uint64 `json:"site_limit"`
}
/* Status struct */
type models.Status struct {
Hostname string `json:"hostname"`
Uptime int64 `json:"uptime"`
Version string `json:"version"`
UpdateAvailable bool `json:"update_available"`
UpdateChangelog string `json:"update_changelog"`
UpdateVersion string `json:"update_version"`
UpdateDownload string `json:"update_link"`
Updating bool `json:"updating"`
HostOS string `json:"host_os"`
Edition string `json:"edition"`
UserLimit uint64 `json:"user_limit"`
DeviceLimit uint64 `json:"device_limit"`
SiteLimit uint64 `json:"site_limit"`
}
Now we know what to do, in order:
- Patch to the binary to force licence.Verify to always return
- Perform the first configuration
- Force the update of data within the DB, namely the STATUS and LICENSE keys.
- Enjoy!
So, to help me with this task, I wrote a "toolkit" (a lot of code) in golang to help me read/write and automate the actions on the BoltDB we have.
You can have a look at the official Bolt repository to understand how it works and how to work with it, I will skip this part because it is already in the toolkit code.
Binary Patch
All we have to do is replace the beginning of the function license.Verify with a return, so that it returns immediately.
(Using a nop instead of licence.Verify may cause crashes or memory management problems).
Here is a screenshot of the line that will be patched:
As you can see, we are going to replace the first line: cmp rsp, [r14+10h] with a simple retn.
From the HEX view, you can see that the operation is: 49 3B 66 10
We will then force it to return, replacing it with the well-known hexadecimal opcode C3, meaning retn:
NOTE:
We will replace all 4 hexadecimal opcodes to make it cleaner, so we will type C3 90 90, opcode 90 is just a nop, so we will not risk execution problems anyway.
Before:
After:
In this way, we force the tool never to check the licence and not to make any server-side calls.
After Binary Patch:
Now the tool will never check the licence, so we can set arbitrary values for our licences and it will work.
I will not dwell on how to work with BoltDB and GOB coding, as I assume you are able to read and study how they work.
I will only explain some parts of the "licence toolkit" I wrote with comments:
Code:
[..SNIP..]
/* Here we create a new variable containing a License struct */
license := License{
Key: "Pwn3rzs",
Type: 2,
UserLimit: uint64(10000),
DeviceLimit: uint64(10000),
SiteLimit: uint64(10000),
}
var buf bytes.Buffer
encoder := gob.NewEncoder(&buf)
[..SNIP..]
/* Then we encode the struct as a gob buffer and we put the buffer inside the BoltDB setup bucket and license key */
bucketz := tx.Bucket([]byte("setup"))
[..SNIP..]
data := bucketz.Put([]byte("license"), buf.Bytes())
[..SNIP..]
/* After we inserted the license, we retrieve the Status data from the BoltDB */
var statusView Status
bucketz = tx.Bucket([]byte("status"))
v := bucketz.Get([]byte("status"))
decoder := gob.NewDecoder(bytes.NewReader(v))
[..SNIP..]
/* We then update the data inside, just the license one */
statusView.DeviceLimit = uint64(10000)
statusView.UserLimit = uint64(10000)
statusView.Edition = "teams"
statusView.SiteLimit = uint64(10000)
encoder = gob.NewEncoder(&buf)
_ = encoder.Encode(statusView)
/* We then encode it back to GOB encoded buffer and update the data inside the database */
_ = bucketz.Put([]byte("status"), buf.Bytes())
/* And we are done !!! */
Now it's time to fire up our Hak5 Unlimited C2 and have some fun!
NOTE:
If for ANY reason, the licence should be cancelled or corrupted, simply redo the process with our 'toolkit'!
I hope you enjoyed this different content and that it not only intrigued you, but also helped you better understand how certain software can work.
Sometimes there is not only a need for patches/adjustments, but simply to 'undo' the licence checks and force it through a file/database.
If you have any questions, feel free to ask in the comments below!
We will release the patched binaries as soon as possible, but we are very busy lately!
Here you go the files:
c2-3.3.0_armv5_linux:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_armv5_linux
c2-3.3.0_armv6_linux:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_armv6_linux
c2-3.3.0_armv7_linux:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_armv7_linux
c2-3.3.0_armv8_linux:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_armv8_linux
c2-3.3.0_i386_windows.exe:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_i386_windows.exe
c2-3.3.0_i386_linux:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_i386_linux
c2-3.3.0_amd64_windows.exe:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_amd64_windows.exe
c2-3.3.0_amd64_linux:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_amd64_linux
c2-3.3.0_amd64_darwin:
https://ponies.cloud/c2/hak5-cloud-c2/c2-3.3.0_amd64_darwin
HAK5-C2-Toolkit-win-i386:
https://ponies.cloud/c2/hak5-cloud-c2/HAK5-C2-Toolkit-win-i386
HAK5-C2-Toolkit-lin-amd64:
https://ponies.cloud/c2/hak5-cloud-c2/HAK5-C2-Toolkit-lin-amd64
HAK5-C2-Toolkit-lin-386:
https://ponies.cloud/c2/hak5-cloud-c2/HAK5-C2-Toolkit-lin-386
HAK5-C2-Toolkit-win-amd64:
https://ponies.cloud/c2/hak5-cloud-c2/HAK5-C2-Toolkit-win-amd64
HAK5-C2-Toolkit-mac-arm64:
https://ponies.cloud/c2/hak5-cloud-c2/HAK5-C2-Toolkit-mac-arm64
HAK5-C2-Toolkit-mac-amd64:
https://ponies.cloud/c2/hak5-cloud-c2/HAK5-C2-Toolkit-mac-amd64
Or on Github:
https://github.com/Pwn3rzs/HAK5-C2-License-Toolkit/releases/tag/v3.3.0
Last edited: