Rich Mirch

Penetration Tester, Red Teamer, Security Researcher

sudoedit symlink fix for CVE-2021-23240 introduced new vulnerability — January 25, 2021

sudoedit symlink fix for CVE-2021-23240 introduced new vulnerability

I noticed the following changelog entry in sudo 1.9.5p1. This caught my attention so I decided to look further. I was unable to find an advisory, PoC, or CVE for this vulnerability. Using the details from the changelog message and fix, I decided to write an exploit for it.

Using an Ubuntu 20.04.1 VM, I created a low privileged user named “lowpriv” and added a sudoedit rule for a root owned file /etc/test.txt. I also downloaded the source for sudo 1.9.5, compiled it, and installed it to /opt/sudo.

Show sudoedit rule.

Show the sudo version is 1.9.5.

With the test environment ready I ran sudoedit /etc/test.txt. I executed !id as a quick test which executes the id command in a shell however privileges are dropped by bash when the UID != EUID. Back to the drawing board.

I was able to successfully edit arbitrary files simply using the :e /etc/sudoers or :e /etc/shadow commands to escalate privileges, however that was too easy.

Looking for esoteric features that could potentially be leveraged, I discovered the libcall and libcallnr functions which allow you to execute a function from an external library. The one caveat is there can only be a single argument. There are a crazy amount of functions available to vim that I never realized. Check out for the full listing.

I tried calling a variety of functions with varying degrees of success but found a simple method by calling setuid() directly.

call libcallnr("","setuid",0)

After running sudoedit, use the following vim/ex command to change the UID to zero. This will ensure that shelling out will retain privileges because now UID==EUID.

Execute a bash shell with !bash.

Interactive root shell obtained. Woot!

I tested the same proof of concept with 1.9.5p1 and sudoedit properly drops privileges as expected.


If you upgraded to sudo 1.9.5 to fix CVE-2021-23240 or CVE-2021-23239, a new privilege escalation vulnerability was introduced in sudoedit and you should upgrade to 1.9.5p1.

Once in a while I look at recently fixed vulnerabilities to see if I can bypass the fix. In this case, the sudo project knew about this vulnerably but to my knowledge no advisory or CVE was created. I think this is odd that the issue was not communicated since a valid privilege escalation was patched. It’s unclear if another researcher reported it or if maintainers discovered it during their own testing. I also could not find a proof of concept so I decided to write one as a fun exercise.

I hope you enjoyed the short write up. Hit me me up on Twitter @0xm1rch if you have any questions or comments.

Pi-hole Patches Critical Stored XSS Vulnerability — December 24, 2020

Pi-hole Patches Critical Stored XSS Vulnerability

Pi-hole v5.2.1 is vulnerable to a critical stored cross site scripting vulnerability. An attacker with the ability to directly or indirectly query DNS with a malicious hostname can cause arbitrary JavaScript to execute when the Pi-hole administrator accesses the Query Log or Long-term Query Log pages on the web portal.

The Pi-hole project released a fix on 12/24/2020 in v5.2.2. Shodan reports over 7,500 Pi-hole instances. This could be remotely exploited if these instances permit external DNS queries. Other possibilities may exist if a malformed DNS query is allowed.

No payloads are being published at this time to give users time to patch.



  • 12/16/2020 Vulnerability reported to vendor
  • 12/18/2020 Vendor acknowledged receipt of report
  • 12/22/2020 Discovered a second XSS payload that would fire on the Long-term Queries Page
  • 12/23/2020 Mitre assigns CVE-2020-35659
  • 12/24/2020 Vendor released fix in v5.2.2
Metasploit module developed for CVE-2018-18556 VyOS Privilege Escalation — September 25, 2020

Metasploit module developed for CVE-2018-18556 VyOS Privilege Escalation

Today, a Metasploit module was merged for a vulnerability I found in 2018 with VyOS. This vulnerability was my first public InfoSec blog post. I appreciate bcoles for developing the exploit/linux/ssh/vyos_restricted_shell_privesc module. Read the Metasploit Wrapup for 9/25/2020. The full write-up can can be found on this blog at CVE-2018-18556 – VyOS Privilege escalation via sudo pppd for operator users.

CVE-2018-1792 – IBM MQ Privilege Escalation: Fun with RUNPATH — August 25, 2019

CVE-2018-1792 – IBM MQ Privilege Escalation: Fun with RUNPATH

Vulnerability Summary

IBM MQ for Linux and UNIX systems is vulnerable to a privilege escalation attack by forcing a setuid root binary to load a malicious library. A local attacker with access to the mqm account can execute arbitrary code as root. In October 2018 IBM published an advisory along with patches for several versions.

The goal of this post is to show how the RPATH/RUNPATH value could potentially be leveraged for privilege escalation. When specified at compile time this path is embedded in the binary and is the first path searched when searching for a library if the dependent library specified does contain a slash. Details on how this works can be found in the man page.

As with most file path type vulnerabilities, if you control the path, you may control the application in some way. In this case the mqm user is the owner of the directories listed in the RUNPATH.


List setuid root applications.

[mqm@localhost]$ find /opt/mqm -perm -4000 -user root|xargs ls -l
-r-sr-x---. 1 root mqm 13384 Jul 9 07:09 /opt/mqm/bin/security/amqoamax
-r-sr-x---. 1 root mqm 13704 Jul 9 07:09 /opt/mqm/bin/security/amqoampx

Use readelf to read the dynamic section to extract the RPATH/RUNPATH.

[mqm@localhost ~]$ readelf -d /opt/mqm/bin/security/amqoamax |grep -e RPATH -e RUNPATH
0x000000000000001d (RUNPATH) Library runpath: [/opt/mqm/lib64:/opt/mqm/gskit8/lib64:/

Using my favorite utility strace, we can see the open() calls for fails with ENOENT under /opt/mqm/lib64 and /opt/mqm/gskit8.  We’re using for this PoC but other libraries can be used. The dependency is ultimately resolved at /usr/lib64/ This gets interesting because the mqm user owns the directories under /opt/mqm.

[mqm@localhost ~]$ strace -f /opt/mqm/bin/security/amqoamax 2>&1|grep
open("/opt/mqm/lib64/", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/opt/mqm/gskit8/lib64/", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib64/", O_RDONLY|O_CLOEXEC) = 3

Continue reading