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

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • k8s安装使用_setup error怎么解决

    k8s安装使用_setup error怎么解决安装GPG秘钥:curlhttps://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg|sudoapt-keyadd-错误消失

    2022年10月10日
    2
  • Java_万年历(简单)

    Java_万年历(简单)1、方法,需要一个年份,一个月份。然后在控制台输出日历2、MainTest测试类3、运行结果:有帮助,就点个推荐吧,让更多人看到

    2022年7月2日
    21
  • 计算机一志愿保护,如何判断学校是否保护一志愿!?那些保护一志愿的学校都……

    计算机一志愿保护,如何判断学校是否保护一志愿!?那些保护一志愿的学校都……保护第一志愿,顾名思义就是保护以第一志愿报考该校的学生,即一志愿学生相对于调剂考生优先录取。不保护第一志愿的院校,是指这些调剂生和一志愿报考本专业的学生一起复试,再统一排名,统一录取。但由于每年自划线的高校基本上先于其他院校复试,导致考研调剂时,可能有一批本科是211/985的考生考研失利,选择调剂到那些有名额的211院校或者普通一本院校,有些接受调剂的学校更倾向于接收211/985院校的调剂生,…

    2022年6月7日
    75
  • ASPCMS 错误号:-2147467259 解决办法

    ASPCMS 错误号:-2147467259 解决办法运行网站的时候,居然提示:提示:【】错误号:-2147467259错误描述:未指定的错误其实说白了,出现这种情况,就是权限问题,解决方法如下:A、打开系统目录下的windows/temp属性;(注意:这里是temp文件夹的属性)B、切换到安全标签,在安全标签里面的所有用户组,你都赋予完全控制权限就OK了;如果没有出现安全选项标签的话,请根据以下方法让安全标签出现:1、打开“我的电脑”→工具菜单→文件夹选项→取消“使用简单文件夹共享”前面的打钩√…

    2022年7月13日
    56
  • 如何将 apache2 URL 映射到 /var/www/ 以外的目录

    如何将 apache2 URL 映射到 /var/www/ 以外的目录

    2021年4月28日
    120
  • linux局域网不同网段ip互通,linux环境中,两个不同网段的机器互通「建议收藏」

    linux局域网不同网段ip互通,linux环境中,两个不同网段的机器互通「建议收藏」环境如下:host1单网卡eth0172.24.100.15/16host2双网卡eth0172.24.100.14/16eth1192.168.122.214/24host3单网卡eth0192.168.122.215/24整个环境如下图:要求:让host1和host3互通,也就是host1能ping通host3,host3也能ping通host1解决:第一,在hos…

    2025年11月1日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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