Web安全培训

工具介绍

Burp 抓包,改包工具, 基于java,运行,需要JRE
需要搭梯子才能登录其网站主页,美国公司,商业软件,年费399年费,有社区开源版本

Burp未启动时,网络的路由环境
本地(浏览器) — 服务器
Burp启动后,网络的路由环境
本地(浏览器 — Burp) — 服务器
Burp extensions — https://github.com/snoopysecurity/awesome-burp-extensions

DVWA靶场,里面是各种漏洞攻击的介绍和说明,是一个入门的联系资源,英文资源。

Pikachu 漏洞练习平台,同理,中文资源。

https://www.kali.org/ , 一个Linux发行版本,是专门针对各种信息安全任务或者练习而准备的。

前端一切不可靠,如上Burp在客户端做网络流量拦截,做中间人攻击

对应的措施:
1.后端校验;2.前端不做逻辑判断;3.前端加密混淆;4.移动端加壳;5.反调试检测,防止逆向工程; 6.后台数据库存储字段最好经过KMS后端密文,常见的服务器本地算法 — hash(明文+盐值)
通常,www.website.com/robots.txt,如 https://www.bilibili.com/robots.txt ,很多网站都有这样子一个网站URL的列表,表示本网站允许访问的URL。

Burp 启动浏览器,在网站的http://burp/地址,
在网页右上角点击CA Certificate 下载Burp颁发的证书。

Burp暴力破解,尝试用户名和密码时,可以使用“Repeater”和“Intruder”两个菜单的功能。
通常登录成功后,response 的长度会有不同。

暴力破解的本质是 自动化,大量发送请求,猜测密码。
应对方法:
1.要求用户密码设置的复杂度;
2.识别爬虫/机器人:验证码,滑块,随机验证码;
3.限制登录频率:每次登录n秒以上方可,错误m次后冻结该用户x分钟,这样会带来问题:
A.前端限制,通过重置本地数据可以绕过;
B.IP地址限制,可能会误封正常用户,攻击者租用地址池拥有大量IP。
C.账号限制,会造成正常用户无法登录,恶意攻击者可以制造拒绝服务攻击。
4.增加密码强度,特别是增加密码长度是最有效的强度。
A.密码一户一用,避免一个密码到处使用,避免撞库攻击。
密码的本质是进行身份验证的手段。
密码的应用场景是基于以下假设:只有用户和服务器知道该密码
其他方式验证身份:短信验证码,指纹,面部识别,USBKEY,2FA,多因子验证等等。

社会工程

黑客通过社会工程学(Social Engineering)实现攻击的手法多种多样,主要是利用人类的心理弱点和信任机制来获取信息或访问权限。
钓鱼攻击,尾随攻击,假冒身份,电话攻击,非技术性攻击,社交媒体欺骗,媒体投影攻击,关系建立攻击等等。

OWASP — Open Web Application Security Project

OWASP Top 10 提供了Web 安全领域发生最频繁的10种事故。最新版本是 2021 年发布的 — https://owasp.org/Top10/zh_CN/

WebShell - 以网页形式实现shell的功能,能够对系统进行操作。例如,文件读写,命令执行等。也被称为网页木马。
首先,网站如果对用户上传的文件,不做控制,黑客则有可能会上传木马文件,黑客通过木马文件控制后台服务器,如下,
通过 https://github.com/AntSwordProject/ 工具可以执行网页木马。

执行木马 成功,成功访问到后端服务器的目录和文件。

仅仅依赖客户端 JavaScript 验证和服务器端 MIME 类型检查仍然不够安全,因为客户端验证很容易被绕过,而且 MIME 类型本身也可能被伪造,尽管概率较低。 为了构建一个更加严谨的文件上传系统,需要采取更全面的安全措施,将验证和安全检查融入整个上传流程的各个阶段。

一个更严谨的文件上传系统应该包含以下措施:

  1. 客户端验证 (加强):
    文件类型检查 (加强): 虽然 file.type 相对可靠,但仍然不是绝对安全的。 可以考虑结合一些额外的检查:
    文件头部信息检查: 读取文件的前几个字节,检查是否符合已知的文件格式规范。 这需要对不同文件类型的头部结构有深入的了解。 但这仍然只能作为辅助手段,不能完全依赖。
    更严格的正则表达式: 使用更精确的正则表达式来验证文件名,但这仍然不能防止恶意文件伪装。
    文件大小限制: 设置一个合理的文件大小限制,并进行客户端验证。
    用户反馈: 提供清晰的用户反馈,告知用户文件上传失败的原因,例如文件类型不允许、文件大小超过限制等。
    禁止直接拖拽上传: 避免用户直接拖拽文件到上传区域,强制用户通过“选择文件”按钮选择文件,这样可以更好地控制文件上传过程。
  2. 服务器端验证 (多层防御):
    文件类型检查 (多重验证): 不要仅仅依靠 MIME 类型,结合多种方法进行验证:
    文件签名: 检查文件的魔术数字 (magic number),这是一种非常可靠的方法。 不同的文件格式通常有独特的魔术数字。
    文件内容分析: 对于一些关键的文件类型,可以进行更深入的内容分析,检查文件结构是否符合规范。 这需要根据具体的文件类型定制相应的分析方法。 这可能需要耗费较多资源。
    文件大小限制: 设置严格的文件大小限制,防止资源耗尽攻击(Denial of Service,DoS)。
    临时文件存储: 将上传的文件先保存到一个临时目录,然后再进行后续处理,这样可以避免恶意文件直接影响服务器。
    文件扩展名检查 (补充): 虽然不完全可靠,但作为附加的检查,可以辅助判断文件的类型。
    内容安全扫描 (关键): 使用专业的安全扫描工具,扫描上传的文件是否包含恶意代码、病毒或其他有害内容。 这可能是最关键的安全步骤,但会增加系统复杂性和成本。 一些云服务提供商提供此类服务。
    白名单机制: 只允许特定类型的文件上传。 尽量避免使用黑名单,因为黑名单很难完全覆盖所有的恶意文件类型。
    沙盒环境: 在沙盒环境中执行文件分析,以最大程度地限制恶意代码对服务器的影响。
    日志记录: 记录所有的文件上传事件,包括文件名、MIME 类型、文件大小、上传时间以及验证结果。 这有助于追踪和分析安全事件。
  3. 其他安全措施:
    HTTPS: 使用 HTTPS 加密上传过程,防止数据被窃取。
    输入验证: 对所有用户输入进行严格的验证,防止注入攻击。
    代码安全审计: 定期对代码进行安全审计,查找和修复潜在的安全漏洞。
    服务端代码示例,如下:
    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
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    package main

    import (
    "fmt"
    "io"
    "mime/multipart"
    "net/http"
    "os"
    "path/filepath"
    "regexp"
    "strings"

    "github.com/gabriel-vasile/mimetype" // 用于更准确的 MIME 类型检测
    "github.com/google/uuid" // 用于生成唯一的文件名
    )

    // AllowedMimeTypes 定义允许上传的文件类型
    var AllowedMimeTypes = map[string]bool{
    "image/jpeg": true,
    "image/png": true,
    "image/gif": true,
    // 添加其他允许的 MIME 类型
    }

    // MaxFileSize 定义允许上传的最大文件大小 (字节)
    const MaxFileSize = 10 * 1024 * 1024 // 10MB

    // uploadHandler 处理文件上传请求
    func uploadHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodPost {
    http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
    return
    }

    file, handler, err := r.FormFile("file") // 假设表单字段名为 "file"
    if err != nil {
    http.Error(w, err.Error(), http.StatusBadRequest)
    return
    }
    defer file.Close()

    // 客户端验证 (加强)
    fileName := handler.Filename
    if !isValidFileName(fileName) { // 检查文件名是否合法
    http.Error(w, "Invalid file name", http.StatusBadRequest)
    return
    }

    fileSize := handler.Size
    if fileSize > MaxFileSize {
    http.Error(w, "File too large", http.StatusRequestEntityTooLarge)
    return
    }

    // 服务器端验证 (多层防御)
    detectedMimeType, err := mimetype.DetectReader(file)
    if err != nil {
    http.Error(w, "Failed to detect MIME type", http.StatusInternalServerError)
    return
    }

    if !AllowedMimeTypes[detectedMimeType.String()] {
    http.Error(w, "Invalid file type", http.StatusBadRequest)
    return
    }

    // 使用 UUID 生成唯一的文件名,避免文件名冲突
    newFileName := uuid.New().String() + filepath.Ext(fileName)
    uploadPath := "./uploads/" + newFileName // 定义上传文件的存储路径

    // 创建上传目录,如果不存在
    os.MkdirAll("./uploads/", 0755)

    // 创建文件并保存
    newFile, err := os.Create(uploadPath)
    if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
    }
    defer newFile.Close()

    _, err = io.Copy(newFile, file)
    if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
    }

    // 此处添加更严格的安全检查,例如:
    // 1. 使用第三方库进行病毒扫描 (ClamAV, VirusTotal API 等)
    // 2. 更深入的文件内容分析,根据文件类型进行特定检查

    fmt.Fprintf(w, "File uploaded successfully: %s\n", newFileName)
    }

    // isValidFileName 检查文件名是否合法,防止目录遍历攻击等
    func isValidFileName(fileName string) bool {
    re := regexp.MustCompile(`^[a-zA-Z0-9._-]+$`) // 只允许字母、数字、点、下划线和短横线
    return re.MatchString(fileName)
    }

    func main() {
    http.HandleFunc("/upload", uploadHandler)
    fmt.Println("Server listening on port 8080")
    http.ListenAndServe(":8080", nil)
    }
    AllowedMimeTypes: 定义了允许上传的文件类型,使用 map[string]bool 更易于管理。
    MaxFileSize: 设置了最大文件大小限制。
    mimetype 库: 使用了 github.com/gabriel-vasile/mimetype 库来更准确地检测 MIME 类型。 这比只依赖 handler.Header.Get(“Content-Type”) 更可靠。
    UUID 生成文件名: 使用 UUID 生成唯一的文件名,避免文件名冲突和潜在的安全问题。
    isValidFileName 函数: 对文件名进行简单的验证,防止目录遍历等攻击。 这只是一个基本的示例,实际应用中可能需要更复杂的验证规则。
    临时文件存储 (缺失但建议): 为了更安全,应该先将文件保存到临时目录,验证通过后再移动到最终存储位置。
    安全扫描 (缺失但必须): 代码中用注释标注了需要添加安全扫描的地方。 你需要集成一个专业的安全扫描库或服务 (例如 ClamAV, VirusTotal API 等) 来扫描上传的文件是否包含恶意代码。 这是至关重要的安全步骤。

Linux 系统排查

1.查看用户行为
/etc/passwd,/etc/shadow 中存储了account和密码信息,黑客可能会增加高权限用户在如上两个文件夹中
如 macOS 中,
➜  ~ sudo dscl . -list /Users | while read user; do sudo dscl . -read /Users/“$user” UserShell | grep -q ‘/bin/bash’ && echo $user; done
_mbsetupuser
postgres
➜  ~ last
Zzz  ttys000                         Tue Dec 10 14:05   still logged in
Zzz  ttys000                         Mon Dec  9 11:29 - 11:29  (00:00)
Zzz  ttys000                         Sat Dec  7 19:35 - 19:35  (00:00)
Zzz  console                         Tue Dec  3 14:51   still logged in
reboot time                                Tue Dec  3 14:50
还有,如查看用户的密码是否为空,用户执行过的命令,等等。
3.查看进程,例如,黑客通过服务器在挖矿等异常。lspf, top等命令。
更多可以查看 Linux 应急响应手册 — https://github.com/Just-Hack-For-Fun/Linux-INCIDENT-RESPONSE-COOKBOOK

威胁情报中心:

Windows 系统工具 - https://learn.microsoft.com/en-us/sysinternals/
腾讯威胁情报中心 - https://tix.qq.com/
可疑文件分析 - https://www.virustotal.com/gui/home/upload