In this demo you will
This tutorial explains how to setup a "cage" system for a Java 11 application
- Prepare the HAM container
- Prepare the Application container
- Docker with proxy access On the same machine (e.g. local docker or Docker Desktop)
- Docker with VPN access When the client accessing the app is on a physically different machine or in a VM
- What's next
Suppose you have an application named... testapp
Create a directory "master" and inside it
Prepare the configuration file, e.g. here you can find the default template external.json
Just setup a "Dockerfile" like the following for the HAM master
FROM ham.master:latest # Copy the configuration COPY .external.json /etc/app/ham/app/external.json
And create the image
docker build --rm -t testapp.master .
Create a directory "testapp" and inside it
Create the startup file, testapp.sh
#!/bin/sh # Reach the application directory cd /etc/app/testapp # Set the java home and path export JAVA_HOME=/usr/lib/jvm/java-8-openjdk/ export PATH="${JAVA_HOME}/bin:${PATH}" # Run your jar. Here with the agentlib line to allow remote debugging # and the server port for Spring Boot java -jar -Dserver.port=80 \ -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005 \ /etc/app/testapp/app-1.0.0.jar
Prepare the Dockerfile. Note that the client images already handles all basic initializations like DNS resolution, services initializations and certificates management
FROM ham.client:latest # Update the image # Create the application dir # Install Jdk 8 RUN apk update && apk upgrade && mkdir -p /etc/app/testapp && apk add --no-cache openjdk8 # Copy the jars COPY /[jarAbsoluteDirTarget]/*.jar /etc/app/testapp/ # Copy the run script COPY .testapp.sh /etc/app/testapp/ # Set the .sh as executable # Start the application in foreground with runit RUN chmod +x /etc/app/testapp/*.sh && /etc/startservice.sh --app=testapp --run=/etc/app/testapp/testapp.sh
And create the image
docker build --rm -t testapp.app .
Prepare a docker compose to connect to the application
version: "2" networks: testappnet: # Setup a network for the system: driver: bridge ipam: config: - subnet: 172.25.7.0/24 # Define a subnet not already used services: testapp.master: # The HAM instance container_name: testapp.master # The DNS name of the instance privileged: true # Needed for DNS hijacking environment: - ROOT_PWD=root cap_add: # Needed for DNS hijacking - NET_ADMIN - DAC_READ_SEARCH dns: - 127.0.0.1 image: testapp.master networks: - testappnet ports: - "5025:5025" # Ham debug port (optional) - "1080:1080" # Socks5 Proxy - "1081:1081" # Http/s Proxy testapp.app: # The application container_name: www.testapp.com # The DNS name of the instance environment: - DNS_HIJACK_SERVER=testapp.master # Use HAM as final DNS server - ROOT_PWD=root privileged: true # Needed for DNS hijacking cap_add: # Needed for DNS hijacking - NET_ADMIN - DAC_READ_SEARCH dns: - 127.0.0.1 image: testapp.app ports: - "8080:80" # To expose the application directly (optional) networks: - testappnet depends_on: # Wait for HAM to start - testapp.master
To make the test "real" we will add a DNS and SSL entry to the configuration.
In the section DNS of the "external.json" we tells that HAM should intercept all requests to our application. They will then be forwarded to the real instance
[ { "id": "dns", ..., "resolved": [ ..., { "id": "123456", "dns": "www.testapp.com", "ip": "127.0.0.1" } ] ...
In the section SSL of the "external.json" we tells that HAM should build certificates for all testapp.com domains
{ "id": "ssl", ..., "domains": [ { "id": "123456", "address": "*.testapp.com" } ] ...
Run the compose
docker-compose up
Setup the proxy on Firefox or Chrome (For the latter install Switch Omega) or for the application you are using to stimulate the application, like Postman
First complete the common steps:
- Prepare the HAM container
- Prepare the Application container
- Docker with proxy access On the same machine (e.g. local docker or Docker Desktop)
Install OpenVpn Connect Client on the client machine
Download the connection script and change the following line with the address of the machine running docker.
remote 127.0.0.1 3000 udp
Install the .ovpn file in your OpenVPN connect
Add the following instance to the docker compose. There is a custom image ready for that :)
testapp.vpn: # The application container_name: testapp.vpn # The DNS name of the instance environment: - DNS_HIJACK_SERVER=testapp.master # Use HAM as final DNS server - ROOT_PWD=root privileged: true # Needed for DNS hijacking cap_add: # Needed for DNS hijacking - NET_ADMIN - DAC_READ_SEARCH dns: - 127.0.0.1 image: ham.openvpn/latest ports: - "3000:1194/udp" # To expose the OpenVpn port networks: - testappnet depends_on: # Wait for HAM to start - testapp.master
Start the composer wait for the whole system to start and connect the client machine :) Now you are completely inside the HAM cage!
Running the application you can now
- Intercept the DNS calls and add them as HAM resolved, with the local CA
- Add custom Javascript filters and APIs
- Record/Replay/Test the app automatically and without coding
- Rewrite any url to anything
- Intercept ALL http/s interactions dynamically