BugkuCTF:never give up(web)

题目描述:

                                BugkuCTF:never give up(web)_第1张图片

查看源码之后发现有个1p.html,访问一下,转到这???

BugkuCTF:never give up(web)_第2张图片

  • view-source方式进行访问,这什么操作???(知识点view-source协议)

               

               BugkuCTF:never give up(web)_第3张图片
 

  1. "%3Cscript%3Ewindow.location.href%3D%27http%3A//www.bugku.com%27%3B%3C/script%3E%20%0A%3C%21--转化为ASCII去掉%后为(中间有换行符):
    " 
  2. 猜想中间的字符带上后面的两个等号后是base64编码,解码一下:BugkuCTF:never give up(web)_第4张图片
  3. 对其进行URL解码,得到php源码:
    ";if(!$_GET['id'])    //id不能为空和为0
    {
    	header('Location: hello.php?id=1');    //如果id为空,则我们看到的URL加上hello.php?id=1
    	exit();
    }
    $id=$_GET['id'];
    $a=$_GET['a'];
    $b=$_GET['b'];
    if(stripos($a,'.'))    //查找'.'在$a中出现的位置,只有a中没有'.'才会绕过这个if
    {
    	echo 'no no no no no no no';
    	return ;
    }
    $data = @file_get_contents($a,'r');
    if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
    {    //核心语句,$a为一个文件名,文件内容是"bugku is a nice plateform!",$id为0,$b要求为第一个字符为'4',长度大于5。
    	require("f4l2a3g.txt");
    }
    else
    {
    	print "never never never give up !!!";
    }
    
    ?>
  4. 两种解题思路:
            1.构造url进行访问,让php自动将文件加载出来
            2.直接访问  http://123.206.87.240:8006/test/f4l2a3g.txt 
                                 

构造payload 的思路(学习)

  • 有矛盾的条件是:
  1. id要求为0,但是下面要求id为整数0才能加载
  2. $a要求服务器端存在一个文件名,文件内容是"bugku is a nice plateform!",但是我们不是服务器端
  3. 要求$b的第一个字符既等于字符'4',又不等于整数4
  • 其他条件是
  1. $a中不含 '.'
  2. 字符串1114要与字符串111连接变量 $b 的第一个字符构成的正则表达式匹配
  3. $b长度大于5

首先是id弱类型,如图,只要将id赋值为任意字符串解释器就会判定其与0相等为TRUE,先假设id="aa":

               BugkuCTF:never give up(web)_第5张图片

file_get_contents() 函数读取变量 $a 的值而得,所以 $a 的值必须为数据流

php://input 可以访问原始请求数据中的只读流。这里令 $a = "php://input",并在请求body中提交字符串 bugku is a nice plateform!,php://input会将其读入$a。

ereg()函数和eregi()函数存在空字符截断漏洞,即在参数与中的正则表达式和待匹配字符串中遇到了空格,则截断并丢弃后面的数据。

在本题里面eregi("111".substr($b,0,1),"1114") ,即111拼接上substr($b,0,1),之后与"1114"比较,只要让"111"后面拼接上一个空格即"\x00" 就可以让eregi函数对后面的进行截断,造成的结果就是"111"等于"1114"。这里可以构造 $b="\x00abcdef" 满足长度大于5即可。

最后,构造payload 

满足上面的条件,构造:

http://123.206.87.240:8006/test/hello.php?id=aa&b=\x00abcdef&a=php://input

但是这样得不到相应,之后还要将\x改成%,因为请求过程中编码会自动进行URL的编码,在提交请求时导致请求头截断。这个具体过程是由于,如果填的是\x00,在url编码阶段就会被截断b还没被传送至php后台时已经成为了空(即b=''),到了后台$b为空,就不符合要求了。这个时候如果直接把URL编码的过程手动做了,就不会被截断,就能顺利将数据传送至后台了。

http://123.206.87.240:8006/test/hello.php?id=aa&b=%00abcdef&a=php://input

写个脚本
 

import requests
import json

payload = "http://123.206.87.240:8006/test/hello.php?id=aa&b=%00abcdef&a=php://input"
mysession = requests.session()
# headers = {'Content-Type': 'application/json'}
# b = {'value': 'bugku is a nice plateform!'}
r = mysession.get(payload, data='bugku is a nice plateform!')   # 不用构造成json格式了,直接发送data参数就行了
print(r.text)

                                                       

 

 

 


中间方向错了的操作:

使用御剑后台扫描:

      BugkuCTF:never give up(web)_第6张图片

两个URL如下:

  1. http://123.206.87.240:8006/index.php

    查看网页源码,这个变量$code指的应该就是表单提交的内容了:
    BugkuCTF:never give up(web)_第7张图片
    substr(md5($code),0,4) ==='d3d7'是对于$code的md5加密之后取前4位,然后让它等于d3d7,刷新之后d3d7字符串会改变,需要进行动态读取。做不下去了。

     
  2. http://123.206.87.240:8006/admin.php,这个明显是爆破,不知道这是哪个题目的。

知识点:

  • view-source
    view-source是一种协议,早期基本上每个浏览器都支持这个协议。后来Microsoft考虑安全性,对于WindowsXP pack2以及更高版本以后IE就不再支持此协议。但是这个方法在FireFox和Chrome浏览器都还可以使用。 如果要在IE下查看源代码,只能使用查看中的"查看源代码"命令.
      以前的使用方法:在浏览器地址栏中输入
              view-source: sURL   之后回车即可看到当前网页的源代码了。 
           JS用法:
                    window.location="view-source:" + window.location
  • js中的  unescape(string)  
    过找到形式为 %xx 和 %uxxxx 的字符序列(x 表示十六进制的数字),用 Unicode 字符 \u00xx 和 \uxxxx 替换这样的字符序列进行解码。
  • stripos(string,find,start)      //查找字符串在另一字符串中第一次出现的位置(不区分大小写)
    string 必需。规定要搜索的字符串。
    find 必需。规定要查找的字符。
    start 可选。规定开始搜索的位置。
    strpos() - 查找字符串在另一字符串中第一次出现的位置(区分大小写)
    strripos() - 查找字符串在另一字符串中最后一次出现的位置(不区分大小写)
    strrpos() - 查找字符串在另一字符串中最后一次出现的位置(区分大小写)
  • file_get_contents(path,include_path,context,start,max_length)      //把整个文件读入一个字符串中
    参数 描述
    path 必需。规定要读取的文件。
    include_path 可选。如果也想在 include_path 中搜寻文件的话,可以将该参数设为 "1"。
    context

    可选。规定文件句柄的环境。

    context 是一套可以修改流的行为的选项。若使用 null,则忽略。

    start 可选。规定在文件中开始读取的位置。该参数是 PHP 5.1 新加的。
    max_length 可选。规定读取的字节数。该参数是 PHP 5.1 新加的。
  • @  用于阻止警告输出
  • int eregi(string pattern, string string, [array regs])            //成功返回true,第一个是搜索规则,第二个是被搜索字符串
    在一个字符串搜索指定的模式的字符串。搜索不区分大小写。Eregi()可以特别有用的检查有效性字符串,如密码。 
    可选的输入参数规则包含一个数组的所有匹配表达式,他们被正则表达式的括号分组。
  • include 和 require 的区别       //相当于直接显示文件执行之后的内容
    require 一般放在 PHP 文件的最前面,程序在执行前就会先导入要引用的文件;
    include 一般放在程序的流程控制中,当程序执行时碰到才会引用,简化程序的执行流程。
    require 引入的文件有错误时,执行会中断,并返回一个致命错误;
    include 引入的文件有错误时,会继续执行,并返回一个警告。

 

你可能感兴趣的:(web安全)