LES: Linux privilege escalation auditing tool
LES security tool, developed and maintained by Z-Labs is the next generation version of the tool designed to assist the security tester/analyst in looking for critically vulnerable (i.e. locally exploitable) Linux machines during manual red tem/pentest engagement. In this post I will describe how the tool works and how to use it effectively.
Too often during the penetration testing engagements or testing drills/maneuvers I observe peer operators just running ./les.sh
(without any parameters) then doing cursory analysis of results and moving forward to other testing techniques if none of the exploit stands out from the crowd. Yet, the tool has much more to offer, then that. But first, let’s do a little deep dive into how the LES actually works as it will help us to understand how to use it effectively.
Under the hood
That being said, to do its job and handle many different Linux distributions LES has employed number of heuristic method(s) to achieve its main objectives: generate the list of candidate exploits for a given Linux box in the same time minimizing false postives and false negatives. Additionally - for the sake of practicallity and smooth maintenance - following assumptions has been made while implementing (and maintaining) the tool:
- ‘tagging’ subsystem (more on it later) focuses on most popular Linux distributions used on the servers: Debian, Ubuntu, RHEL/CentOS
- userspace analysis subsytem fully supports deb-based and rpm-based distributions. Support for other distrubtions (e.g. Arch) is only partial
Orginally to achieve its goal LES, was processing solely the kernel version (skiping the distro versioning scheme altogether), this approach was inherited from LES predecessor Linux_Exploit_Suggester script. However, this method wasn’t very effective as it was susceptible to false positives problems, yielding the long list of exploits for manual analysis.
As time passed the tool was improved and currently the approach, it takes to generate list of candidate exploits looks like this:
- Generate initial exploits list based on kernel version
- Check for ‘Tags’ hits for every exploit
- Discard exploits that are not applicable based on ‘additional checks’
- Calculate internal metric (‘Rank’) for each candidate exploit and order the list based on the calculation
Let’s discuss each step one by one:
Generating list based on kernel version
As already mentioned this is the first step in reducing the number of candidate exploits applicable for the given machine. LES parses the output of uname
command to take the exact kernel version installed and compares it with requirements defined for the exploit, e.g. Reqs: pkg=linux-kernel,ver>=4.4,ver<=4.13,...
.
Checking Tags for match
To limit false positives and further shortlist exploits that are applicable for the system at hand, LES introduces concept of Tags
. Tags are simple statements that describe the kernel versions on which given exploit is known to work and could have form of regex, e.g.: Tags: RHEL=6,RHEL=7{kernel:3.10.0-514.21.2|3.10.0-514.26.1}
. Tags do not discard the exploits from the candidate list but rather cause the exploit to “go up” in the list in case of tag hit (more on it below).
Discarding exploits that are not applicable
To further condense the canditate exploits list, additional set of requirements (Reqs
field) have been introduced to LES: now when adding the exploit to the tool, one can define additional conditions that are required to be met by the exploit, for example:
Reqs: pkg=linux-kernel,ver>=3.2,ver<=4.10.6,CONFIG_USER_NS=y, \
sysctl:kernel.unprivileged_userns_clone==1
Requirements set from above states that the kernel version needs to be > 3.2 and <= 4.10.6 but also kernel needs to have usernamespace fucntionality compiled in (CONFIG_USER_NS=y
) and enabled (sysctl:kernel.unprivileged_userns_clone==1
).
For less typical checking, also the ability to run arbitrary Bash command(s) was provided to see if the exploit is applicables for given system, for example:
Reqs: pkg=linux-kernel,ver>=4.4.0,ver<=4.4.0,cmd:grep -qi ip_tables /proc/modules
In above scenario command grep -qi ip_tables /proc/modules
is run to verify if ip_tables
module is loaded (as this is required for the exploit to work) and exploit is meant applicable for the given system only if this command will return TRUE
.
Ordering list based on dynamically generated rank
Finally the exploits that made it so far, are ordered and displayed based on the dynamically calculated Rank
the higher the rank (and therefore the position in the list) the higher probability the exploit is applicable for given system.
Rank
calculation is based on following simple rules:
- Initial rank for “normal” exploit is 1
- Initial rank for “great” exploits i.e. (very reliable, applicable for range of distros/kernel versions, includes SMEP/SMAP/KASLR bypass, etc.) is 5. Examples of such exploits:
dirtycow
,eBPF_verifier
. - Initial rank for “poor” exploits (not reliable, known to work only in testing environment, etc.). Examples:
keyring
exploit. - Add 2 to the current exploit’s initial rank if there’s tested OS distribution version match witch the one from
Tags
. - Add 5 to current exploit’s rank when there’s a tested OS kernel version regex match with the one from
Tags
.
So the value of Rank
calculated by LES for dirtycow
exploit (Tags: ...,ubuntu=16.04{kernel:4.4.0-21-generic},...
) and run on Ubuntu 16.04
machine with the kernel in version 4.4.0-21-generic
installed is:
Inital rank: 5
Distribution version match: +2 to rank
kernel version regex match: +5 to rank
final rank: 12
Functionality
Okay, we know how the LES works, now lets use it.
Basic use case, all steps (as discussed previously) are performed in order to generate candidate exploits list:
$ ./les.sh
--cvelist-file
switch should be used whenever possible (i.e. we have complete listing of CVEs by which our target is affected (for popular Linux distros such list could be generated via https://api-ksplice.oracle.com/api/1/update-list/
):
$ ./les.sh --cvelist-file <cve-listing-file>
During red team engagements, on strictly monitored targets (e.g. HIDS) we could be forced to run LES indirectly:
victim-host$ dpkg -l > pkgsListing.txt
pentester-host$ ./les.sh --uname "<uname-a-from-victim>" --pkglist-file pkgsListing.txt
Often before exploiting target machine, its worth to check whether any additional/non-default kernel hardening measure is enabled (e.g. exploit does not have SMEP
bypass so lets actually make sure that its disabled):
$ ./les.sh --checksec
For more usage scenarios see README.md in LES Github repository.
Contributing
LES is useful tool used by the security professionals around the globe during their red team/pentest engagements. To make it even better and more effective you can help in 4 ways:
- Add newly published Linux privilege escalation exploits to it.
- Test existing exploits on various Linux distributions with multiple kernel versions, then document your findings in a form of
Tags
in LES, e.g. of a tag:ubuntu=12.04{kernel:3.(2|5).0-(23|29)-generic}
which states: tagged exploit was verifed to work correctly on Ubuntu 12.04 with kernels: 3.2.0-23-generic, 3.2.0-29-generic, 3.5.0-23-generic and 3.5.0-29-generic;. With this tag added LES will automatically highlight and bump dynamicRank
of the exploit when run on Ubuntu 12.04 with one of listed kernel versions. This will help you (and others) during pentests to rapidly identify critically vulnerable Linux machines. - Published exploits are often written only for PoC purposes only for one (or couple of) specific Linux distributions and/or kernel version(s). Pick sources of the exploit of choice and customize it to run on different kernel version(s). Then add your customized version of exploit as
ext-url
entry to LES and modifyTags
to reflect newly added targets. - Conduct analysis of chosen kernel hardening security measure then add it to the
FEATURES
array (if not already there) and publish your analysis at:https://github.com/mzet-/les-res/blob/master/features/<feature-name>.md
.