CTFshow-web-红包题第二弹
打开靶场,显示如下
右键点击源代码,发现有提示
在url后添加?cmd=phpinfo(),进行远程代码执行
?cmd=phpinfo()
关键点是两个正则表达式,分别为preg_match(“/[A-Za-oq-z0-9
]
+
/
"
,
]+/",
]+/",cmd)和preg_match(”/~|!|@|#|%|^|&|*|(|)|\(|\)|-|_|{|}|[|]|'|“|:|,/”,$cmd),这两个正则将除了p字母以外的所有字母数字和一些特殊符号进行了过滤。
可以选择上传一个脚本文件进行执行,先用burpsuite抓包获取请求头
PHP文件上传机制
在Linux的PHP环境下面,客户端(页面)如果对服务器上传文件,会先生成一个临时文件,存放在根目录下面的tmp文件夹下面,也就是/tmp目录下面.之后再对临时文件进行处理,比如是否将其存储到本地.无论服务器是否存在一个上传文件的请求,只要我们上传了一个临时文件,就一定会在该目录下面生成临时文件,但是会在生成后立刻删除.这个临时文件有一个特征,就是以php开头,后面跟6个随机字符,比如php123abc.因此我们可以使用通配符*对该文件进行匹配.
在这个题里面,我们可以利用其中的时间间隙,再上传文件的同时,使用cmd命令执行脚本文件.
媒体类型multipart/form-data的数据体由多个部分组成,这些部分由一个固定边界值(Boundary)分隔。
如果我们获取了一个HTTP的数据包,我们可以通过构造一个post请求上传一个文件。先把GET文字改成POST,之后在请求头加入
Content-Type: multipart/form-data; boundary=---------------------------10242300956292313528205888 这是一个
HTTP 请求头中的一部分,用于指定请求体的格式和边界。后面上传的脚本文件内容,就是使用上方定义的边界符号进行识别和区分。
上面两行表示了文件的信息,中间用一种注释表示使用bash解释器,最后一行是文件的内容.于是数据包变成了这个样子:
这样子就可以对服务器上传一个脚本文件. 接下来就是对cmd进行绕过,使上传的文件得以执行,这就涉及php的命令执行.
php命令执行
php的上传接受multipart/form-data,然后会将它保存在临时文件中。php.ini中设置的upload_tmp_dir就是这个临时文件的保存目录。linux下默认为/tmp。也就是说,只要是php接收到上传的POST请求,就会保存一个临时文件,如果这个php脚本具有“上传功能”那么它将拷贝走,无论如何当脚本执行结束这个临时文件都会被删除。另外,这个php临时文件在linux系统下的命名规则永远是phpXXXXXX
php里面有很多执行外部命令的函数,如exec等.
反引号也可以用于执行外部命令,并把执行完成的结果以字符串的形式返回,而本题未过滤反引号,可以进行利用.除此之外,我们还需要对执行结果进行输出,但是输出函数以及全部被过滤.这就涉及段标记语法了.<?= ... ?> 是在 PHP 中的一种短标记(short tag)语法,也被称为echo短标记,它可以简化输出变量或表达式的操作。使用<?= ... ?>就相当于echo … 使用短标记需要<?标签,因此我们构造cmd=?><?=`.+/??p/p?p??????`;先把前面的<?php闭合,再与后面的?>形成一个短标签.再PHP里面.在Linux里面, .(点命令)使source命令的别名,用于读取并且在当前的shell中执行文件中的命令,加号+等价于空格,于是通过构造.+/执行后面的脚本文件.之后就是通过模糊匹配,用?通配符对上传的文件进行匹配,tmp目录写成??p,php临时文件写成p?p???,最后变成cmd=?><?=.+/??p/p?p??????
;