ctf-web:文件包含漏洞和举例-HCTF2018 WarmUp「建议收藏」

ctf-web:文件包含漏洞和举例-HCTF2018 WarmUp「建议收藏」我又回来更新了,这次是关于web方面的文件包含漏洞.我会在后面以详细的角度来写清楚这个漏洞的利用方法.当然,以下都是我自己的理解,表述什么的都有些野人化了.所以希望各位大佬手下留情.一.漏洞产生的原因这个漏洞可以追溯到很久.更准确来说,其实是人为产生的.由于我php学的不是很专业,所以我就拿c语言来举例了.php里面使用的是include命令,c语言使用的是#include预处理命令.作用是相似的.我新建了两个文件,内容如图.wzc.h:#include”stdio.h”voidpri.

大家好,又见面了,我是你们的朋友全栈君。

我又回来更新了,这次是关于web方面的文件包含漏洞.我会在后面以详细的角度来写清楚这个漏洞的利用方法.
当然,以下都是我自己的理解,表述什么的都有些野人化了.所以希望各位大佬手下留情.

一.漏洞产生的原因

这个漏洞可以追溯到很久.更准确来说,其实是人为产生的.由于我php学的不是很专业,所以我就拿c语言来举例了.php里面使用的是include命令,c语言使用的是#include预处理命令.作用是相似的.
我新建了两个文件,内容如图.
wzc.h:

#include "stdio.h"
void print_f(){ 
   
	printf("this is test file");
}

main.c:

#include "wzc.h"
int main(){ 
   
    print_f();
    return 0;
}

程序运行结果如图:
在这里插入图片描述
学过c语言的应该都知道我刚才干了件什么事情.我先写了一个自己创建的头文件库,里面存放了一个”print_f”函数,作用是在屏幕上显示一句话.
然后我使用预处理命令将文件进行了一个包含的操作,这样我后面就可以多次调用这个print_f函数了.
这么做在工程量少的情况下是看不出来有什么作用的,但是当你在做一个大工程时,需要多次实现某个功能的时候,就可以派上用场了,很完美的一个操作,对吧?
但是,凡事都有例外.
假如我是黑客,然后我在某个公司开发的c语言程序的被包含文件中,偷偷把被包含的文件中添加一些后门命令,是不是就产生问题了呢?最起码能让你这个程序崩溃不能运行.
不过这并不是我们文件包含漏洞主要被利用的地方,我们要说的是利用语法来钻空子.
观察我们的代码第一行:

#include "stdio.h"

在c语言中,被包含的文件名左右的包含符号有两种.
第一种是两个尖括号.(<>)
这种写法编译器会在系统自带的头文件库中寻找所需要的文件进行包含.例如:

#include <stdio.h>

第二种是两个双引号(“”)
这种写法编译器会首先在c文件目录下寻找需要被包含的文件,如果没有,就会去系统文件夹下寻找.
ok,了解这两种写法以后,我们可以继续往下走了.
虽然说如果使用(“”)这种写法,机器会自动寻找当前目录下的规定文件,但是有时候我们的头文件库特别多,需要专门建一个文件夹来存放,那这时候该怎么引用呢?
比如我们如图的形式.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
就像这样,当我们文件存放在不同地方的时候,我们的c程序在引用的时候就需要改变一下形式了.
main.c:

#include <stdio.h>
#include "..\\include\\wzc.h"
#include "..\\include\\wzc2.h"
int main(){ 
   
    print_one();
    print_two();
    return 0;
}

像这样,类似于cmd命令中写路径的时候一样的,”…“代表上一级目录.不过由于需要考虑c语言的转义字符的关系,所以我们需要把反斜杠打成两个才可以.
很好,我想你们应该已经认识到了关于使用c语言的预处理命令来进行文件包含了.
但是,想一想这个问题,假如说被包含的文件名如果可以通过用户自己输入的话,那是不是就很恐怖?如果我在被包含的文件多写几个”…/”,是不是就代表着我们就可以没有限制的访问任何目录下的某个文件的内容了?
当然,由于c语言是编译器处理这个事情的,所以不会产生这个问题.
但是php就不一样了,因为它可以直接使用类似于echo的方法直接使用include,甚至允许用户自己输入被包包含的内容,这样做的后果就不需要我说了吧?十分危险.
因此.一些网站在需要使用这个命令的时候,就会对用户的输入进行一个过滤,从而防止用户使用这个漏洞进行一些非法操作.

二.漏洞的实际利用

1)分析源码

这个是我偶然遇到的一个web题,来自于buuctf网站的web的第一题.如图,我们首先访问靶机,显示的是一张图片.
在这里插入图片描述
右键查看源码.
在这里插入图片描述
发现在注释中有个source.php,我们尝试进行访问发现成功.
在这里插入图片描述
很好,又到了我们喜闻乐见的代码审计环节.我对代码的分析放在了下面.

<?php
highlight_file(__FILE__);
//这个函数是将文件按照语法的高亮来显示.后面那个__FILE__我没有查到,应该是代表本文件的意思
class emmm
//新建一个emmm类
{ 

public static function checkFile(&$page)
//类中的checkFile函数
{ 

$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
//新建一个列表,列表中添加了两个key,并且有两个对应关系.这个列表的作用类似于白名单
if (! isset($page) || !is_string($page)) { 

echo "you can't see it";
return false;
}
//这是第一个对page进行判断的地方.检查page变量,判断是否是空变量和判断是否是字符串
if (in_array($page, $whitelist)) { 

return true;
}
//判断page变量是否存在于白名单之中
$_page = mb_substr($page,0,mb_strpos($page. '?','?'));
//_page变量储存在page变量中从第一个字符开始搜索"?"号出现的位置,"."代表将"?"号和字符串相连.
if (in_array($_page, $whitelist)) { 

return true;
}
//也就是说,这个其实是实现了一个截断的方法,因为我们下面会使用get的方法进行提交参数,但是将我们的"?"号和"?"号后面的内容给截断了,因此就造成了我们无法提交参数的尴尬情况.想想看该怎么办.
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) { 

return true;
}
//这也是进行了一个截断,不过这个是进行一次url解码以后的截断.
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) { 

include $_REQUEST['file'];
exit;
} else { 

echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}  
//我们看到有include这个命令,因此我们就可以利用这个漏洞.
//我们观察发现,脚本使用get的方式提交file变量的内容,然后进行检查.假如我们能绕过这三个检查,我们就能成功读取到flag.
?>

2)解法分析

我们大概走了一遍这个流程,大概知道了怎么运行的.因此,就需要更深入的研究了.
我们的目的是为了过三个if保护,代码:

    if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])

这三个条件是:
1)判断file变量是否为空
2)判断file变量是否为字符
3)用checkFile函数进行检查
前两个比较简单,关键是最后一个.刚才分析的过程中,我们最主要过的保护其实的就是关于那个截断的保护.
要知道,我们的目的就是为了使checkFile函数返回ture才可以。四个判断我们经过观察发现,最后一个判断是最容易过的保护。
因此,我们想想该如何绕过这个截断?
其实很简单,我们找一个和”?”作用像同的符号但是不是问号的符号不就行了么?
所以,我们要学会一个最简单的绕过方法–url编码绕过
首先,当我们在百度搜索一些东西的时候,我们会发现我们输入的汉字都变成了一些由百分号开头的奇怪编码.
这些编码就是经过浏览器url编码以后得到的结果.但是假如我们直接在网址栏输入编码后的代码,浏览器是不会进行url编码的.
最后服务器那头解码一次,就得到我们输入的结果了.
因此,我们就可以利用这个原理来进行一个简单的绕过.详细来看下过程.

            $_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) { 

return true;
}

这个是进行url解码以后进行的一个判断.此处就是我们要利用的地方.
假如我们将编码一次后的问号传过来,服务器解码一次得到问号.
然后网站后台脚本会进行一次解码,上一步出来的是问号,解码出来依然是问号,仍旧能发现我们的操作.因此,我们需要编码两次.
第一次,服务器将编码解码,得到问号编码一次的结果.
第二次解码是由后台脚本解码的.仔细研究一下这段代码的逻辑就明白了.
先解码,解出来是问号,然后将问号后面的都截掉,放到白名单里面一判断,成功返回truth,我们就成功了.
很好,此刻我们已经成功将三个判断都绕过了,接下来执行的就是include命令,将我们需要的文件包含进来就行了.这个用法和我前面说的c语言类似,就不赘述了.这个是关于这个漏洞的官方描述,被收录在了cve上面,英语好的同学可以看看.
在这里插入图片描述
文章参考链接:https://www.jianshu.com/p/36eaa95068ca

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/136121.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • lcd1602模块的基本组成_1602液晶显示模块P0口

    lcd1602模块的基本组成_1602液晶显示模块P0口LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。下图即是该模块:(百度百科)一般来说,在嵌入式开发领域显示模块是非常重要的一部分,所以发展出了许多种应用在不同场合的集成显示模块。LCD1602由于出现较早,所以即便出现了应用更广泛的、…

  • 跳跃表(skiplist )详解及其C++编程实现

    跳跃表(skiplist )详解及其C++编程实现跳表SkipList跳表SkipList1、背景2、定义2.1、SkipList基本数据结构及其实现3、实现4、使用方法4.1、跳表的创建4.2、跳表插入操作参考跳表SkipList1、背景为什么选择跳表?目前经常使用的平衡数据结构有:B树,红黑树,AVL树,SplayTree,Treep等。跳表是平衡树的一种替代的数据结构,但是和红黑树不相同的是,跳表对于树的平衡的实现是基于一种随机化的算法的,这样也就是说跳表的插入和删除的工作是比较简单的。用跳表吧,跳表是一种随机化的数据结构,目前开源软件

    2022年10月19日
  • googlenet网络模型简介_网络参考模型

    googlenet网络模型简介_网络参考模型一、GoogleNet模型简介  GoogleNet和VGG是2014年imagenet竞赛的双雄,这两类模型结构有一个共同特点是godeeper。跟VGG不同的是,GoogleNet做了更大胆的网络上的尝试而不是像VGG继承了Lenet以及AlexNet的一些框架,该模型虽然有22层,但大小却比AlexNet和VGG都小很多,性能优越。深度学习以及神经网络快速发展,人们容易通过更高性能的

  • 证书认证过程_过程装备与控制工程可考证书

    证书认证过程_过程装备与控制工程可考证书现在很多的网站都会用​​https证书申请​​了,因为https证书好处现在越来越受到人们的认知,https安全证书的好处不仅仅对于客户的信息隐私数据有保护,对于维护网站的知名度以及安全可信度也是大有帮助。这也是很多人用申请https证书,但是他们首先遇到的难题就是申请https证书的过程是怎么样的?申请​​https证书​​的步骤是怎样的呢?1、要想完成https证书的申请,要先确定申请什么类型的https:大体来说有安全等级可以分为域名型证书,企业型证书以及增强型证书。根据自己网站.

  • Ubuntu 定时执行脚本

    Ubuntu 定时执行脚本一、关于crontabcron是一个Linux定时执行工具,可以在无需人工干预的情况下运行作业。在Ubuntu中,cron是被默认安装并启动的。二、例子直接上例子,来看看怎么用。需求:定时每天8点,自动执行保存在/root目录下hello.sh脚本1、方法很简单,只需编辑ect下crontab文件就行了,这个文件里存放的就是cron要执行的命令,以及定时执行的时间…

  • FFM算法 Python实现

    FFM算法 Python实现本算法是CTR中的系列算法之一,具体的原理就不说了。网上其他的博客一大堆。都是互相抄来抄去,写上去之后容易让人误会。因此我只传上代码实现部分。大家做个参考。这里我们的FFM算法是基于Tensorflow实现的。为什么用Tensorflow呢?观察二次项,由于field的引入,Vffm需要计算的参数有nfk个,远多于FM模型的nk个,而且由于每次计算都依赖于乘以的xj的field,所以…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号