Knot is a machine focused around some of the newer technologies being utilised within web development, specifically Knot.js, Express.js and mongodb. Initial exploitation and escalation puts a loterijlot of emphasis on enumeration of misconfigurations within the custom-built software, rather than looking for publicly known exploits.
Spil there is only one externally facing service available to the user, their initial point of enumeration will be the web application.
Attempts to run an “out of the box” scan using dirb, DirBuster and gobuster will cause failures ter said applications. The reason for this, is that the Knot.js service which is serving the web application has a basic user-agent blacklist te place which will react to all requests from thesis applications with some ASCII kunst and a randomly generated string at the end.
To bypass this mitigation, a user can specify a custom-made user-agent to be used, but further activity would then be required te some implements, spil any unmatched routes will always serve up the application opstopping, resulting ter status code 200 being sent back for every request.
Ter the case of dirb, switching the user juut permits for successful scraping:
An initial look at the webstek will expose three user accounts, mark, tom and rastating.
By examining the XHR requests being made, or by analysing the source, it is possible to identify where thesis accounts are being pulled from, which is /api/users/latest
At this point, the attacker has two options:
- Start enumerating the API that is found under the /api/ route
- Start brute forcing to attempt and get access to a low level user account
The only option that will lead to a useful result is option 1, but should the attacker choose option Two, they will find that the login pagina, found at /login , does not use a standard HTTP form postbode. Instead, it posts JSON to the web service asynchronously and checks the terugwedstrijd value, spil can be seen te lines 7 to 21 of /assets/js/app/controllers/login.js
Spil can be seen te the source code, a successful login will contain a property named “success” which will be truthy, should the login be successful.
By submitting a Postbode request to /api/session/authenticate with the figure:
The attacker would be able to test the credentials tom:test , this could then be automated using Burp or any other similar application to enumerate through a password list such spil rockyou.txt, which contains all the passwords for all web users, except rastating.
An alternative to brute forcing the passwords, would be to simply take a look at the output from the API that is called to get the latest users, spil the attacker would then see that the entire user document is being output, exposing the hash.
Spil the passwords for the users are feeble, except rastating, they can lightly be found te a switch sides SHA-256 lookup.
Should the attacker build up access to one of the three low level web accounts, they will soon find out they have no functionality available to them, spil vanaf the below screenshot:
However, knowing how to brute force the accounts is needed for the next step, so will still provide the user something of use.
Examining the code behind the admin controller, will voorstelling that if the account has the is_admin property set to true, it will permit them to access a “Download Backup” button.
An attacker at this point can attempt to access the route that is called to download the backup, /api/admin/backup , however, there is validation on the server to ensure only admin users can actually access it.
This brings the attacker back to the point of needing to enumerate the web service (spil mentioned earlier).
The process of this is very plain, If the attacker examines the various XHR requests being made, they will see that all user related API requests have a base address of /api/users/ e.g. the profile gegevens is retrieved from /api/users/:username , the latest users are retrieved from /api/users/latest . If the attacker visits the route with no parameter, i.e. /api/users/ , they’ll see they are given the output for the entire user list, which includes an admin user, myP14ceAdm1nAcc0uNT.
Once the attacker has the admin username, they can then repeat the previous steps and brute force the feeble password ( manchester ), login, and download a backup of the webstek
The verkeersopstopping generated by the backup function ter the web application is named “myplace.backup”. Upon examination, the attacker will be able to see it contains one large base64 string.
This string can be decoded back into a ZIP opstopping by running base64 -d >, backup.zip.
Once back te the original ZIP format, the password for the ZIP opstopping ( magicword ) can be lightly cracked using a contraption such spil fcrackzip:
Once the attacker has the password and can unzip the archive, they’ll have a utter copy of the source code to the web application. The verkeersopstopping that has the significant information is app.js ter the root folder of the application.
On line 11 they’ll find the mongodb connection string, which contains credentials that are collective with the local system account of mark.
Once the attacker uses thesis credentials overheen SSH, they’ll be introduced with a bash shell for mark:
Once the attacker is logged ter spil mark, they’ll soon realise they have no sudo privileges, and the system is fully patched. There is a vulnerable, non-standard SUID binary that can be exploited, but it is possessed by root:admin, and spil mark is not te the admin group, cannot execute it with it’s current permissions.
Taking a look at the users of the admin group will voorstelling that tom is ter this group, and spil tom is also the account that has access to user.txt , it is this account that the attacker should very first attempt to escalate to.
The only intended way to reach this account, is by looking at the presently running services. Running ps aux will display a process which is spawned from the instruction /usr/bin/knot /var/scheduler/app.js
Upon inspection of the systemd configuration files, the attacker can also see the description of the scheduler service is, ",A mongo powered task scheduler",
The service is very puny, and consists of a single verkeersopstopping (app.js), upon inspection of it, the attacker will see it is connecting to mongodb using the same credentials spil earlier, but with a different database spil the target, scheduler.
Once connected to the database, it will open the tasks collection, find all the documents contained within it, iterate through them, and pass the value of the cmd property to the exec function, and then deleted the task to prevent re-execution.
This process is repeated every 30 seconds, indefinitely. Spil the service is running spil tom, this gives the attacker an effortless means of escalating to the tom account.
To exploit this, very first, the attacker vereiste connect to the mongodb example using the previously identified credentials by running mongo -p -u mark scheduler and then coming in the password when prompted.
From here, the attacker should simply create a fresh document te the tasks collection, with their desired payload spil the cmd property.
After the scheduler service picks up this task on its next run, a fresh SUID binary will be te the /tmp directory:
Now that the attacker is ter the setting of tom, they can read user.txt and begin moving on to the root user.
To escalate at this point, the attacker needs to revisit some of the information found previously. Now that there is access to tom, who is part of the admin group, the SUID found ter /usr/local/bin can be accessed, depending on how the shell wasgoed accessed.
If it wasgoed accessed using a SUID spil vanaf the previous section, an extra step will have to be taken, which will be modifying the SUID binary to also set the GID bit, and to switch the group possessor to admin for example by adding another task te mongodb like this:
Once the GID bit is set, the shell will also inherit the admin group:
The reason this is required is spil an earlier section pointed out – the SUID within /usr/local/bin can only be executed by root and members of the admin group.
Once the attacker has access to this binary, running it with no parameters will result ter nothing being output to stdout.
At this point, the attacker can either start fuzzing the application to find the usage, or can rewind back to the Knot.js application that wasgoed serving the web application. Spil this binary is what the Knot.js application is using for the backup functionality.
Examining the code te /var/www/myplace/app.js will voorstelling that it’s calling it with the following effective guideline:
The parameter list, te order from left to right, is:
- The output mode, -q for quiet, or any other string for a verbose output
- The access token
- The directory to archive
Should the user fuzz the application, they’ll not be able to progress without a valid access token:
The access tokens can be found, ter plain text, within the /etc/myplace directory, if the user determines to go the fuzzing route.
From here, there are numerous ways to get the root flag and a root shell.
Method 1 – Using Wildcards (Effortless)
The easiest route to getting the root flag, is to use wildcards to work around the blacklisted keywords. If attempting to use the backup contraption to backup the /root directory, users will be introduced with a fake backup:
Upon decoding and extracting this backup, root.txt won’t be fairly what it seems:
By substituting some characters with wildcards, however, it is possible to evade the blacklist and grab the root flag:
Method Two – Directive Injection (Medium)
The 2nd method is directive injection, but with a bit of a work around needed. Albeit the user is incapable to chain two directions together, due to the usual characters being blacklisted ( &, , , etc.), it is possible to manhandle the printf instruction to inject a fresh line into the instruction.
Upon normal usage of the backup program, the instruction that would be executed internally, if the user were to backup /var/www/myplace would be say:
By using printf to force a fresh line te the instruction, the system function call ter the C program will execute whatever proceeds it spil a separate instruction.
Running the backup program using /usr/local/bin/backup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 ",$(printf ‘aaa\n/bin/sh’)", , will result te the following being passed to system :
The problem with this, is that all output is being redirected to /dev/null , so albeit a shell has bot acquired, no output can be seen:
To work around this, the attacker voorwaarde simply chain two directives into the injection, ensuring that /bin/sh is not the last one. Ter the example below, zip is executed, then sh and ultimately ls is executed, with only the output of ls being redirected:
Method Three – Buffer Overflow (Hard[est])
The most involved privilege escalation method requires the attacker to analyseren the application te order to find where a buffer overflow exists. There are a number of ways that this can be approached, so for simpleness’s sake, this document will simply explain where the vulnerability exists, and how it can be exploited, rather than the process of identifying it.
Within the application, there are a number of times which strcpy is used with no validation of the bounds of the gegevens. Within the displayTarget function, this will cause an overflow and a segfault, should the following criteria be met:
- The application is not being executed ter quiet mode (anything other than -q is passed spil the very first argument), spil the function is not called te quiet mode
- A valid access token has bot passed spil the 2nd argument
- A string of 508 characters is passed spil the third argument
Spil ASLR and NX are both present, ter order to exploit this, the attacker will be required to create a basic ret2libc script. Ter order to do this, the attacker vereiste acquire a few lumps of information very first.
Very first, a check should be done to find one of the addresses that libc is assigned. Spil ASLR will switch this each time the application is run, any can be picked, spil the exploit will attempt to run numerous times until the same address gets re-used. This can be done by running ldd /usr/local/bin/backup | grep libc.so.6
Next, the attacker should find the offsets of the following libc functions:
To do this, the instruction readelf -s /lib32/libc.so.6 | grep system should be executed.
From the output of this instruction, wij can find the offset on the line with the function [email protected]@GLIBC_2.0 (ter this case 0003a940 ). Wij then repeat this step but with “exit” ter the grep directive instead of “system”, and take the offset for the [email protected]@GLIBC_2.0 function ( 0002e7b0 ).
One last lump of information is now needed, which is the offset of the string /bin/sh within libc, which can be retrieved by running strings -a -t x /lib32/libc.so.6 | grep /bin/sh . Te this case, the offset is 15900b .
With all this information, a fresh script can be created to exploit the vulnerability:
The script will sometimes fail to get a shell, spil it is reliant on the same base address being re-used, but executed enough times, it will catch it and get the elevated shell: