长亭百川云 - 文章详情

dom xss->半自动化 - 飘渺红尘✨

博客园 - 飘渺红尘✨

51

2024-07-19

  前几天看了两篇文章,觉得很不错,写一笔,就当笔记记录。

  第一篇文章:https://jinone.github.io/bugbounty-dom-xss/

  作者写了自己通过自动化挖dom xss,差不多赚了3w刀左右。他分享了一些不错的漏洞案例。这里很感谢作者,无私分享思路出来,也给大家有了喝口汤的机会。

  中国需要多一些这样的热爱分享的白帽子,一方面是推动安全测试水位,另一方面是带来更多的思路给他人。看这篇文章,给了我一些启发。在相当内卷的今天,选择适合自己的漏洞挖掘赛道很重要。就像不是人人都适合挖rce,一个道理。

    第一篇文章的细节点:

  访问: 

https://example.com/xsspath'%22?xssparam%27%22=xssvalue%27%22#xsshash'%22

  

结论:

location.search 会对'"编码
location.hash 不会对'编码
location.pathnme 不会对'编码
location.href hash和pathname中的'不会被编码 包含search,hash和pathname

{ 这三个可以跳出单引号
location.href
location.hash
location.pathname 
}

  因为作者文章中提到有自动化挖掘。这里就调研了下市面上的工具,记录下:

  通过查看作者写的文章,以及自己对dom xss的理解,简单写下半动化的粗略思路

  dom xss半自动化简单思路:

{
n个source
n个sink
如果有某个source和某个sink同时存在

疑似dom xss,命中
}

只检索applocation/javascript和text/html

  关于dom xss的探测,多疑似,那么误报率就会很高。

 缺陷很明显,需要尽可能的收集javascript和javscipt库的source和sink,吃经验,吃规律,需要熟悉一定的规律。

 工具1:Dom Invader 可以用于检测dom xss和postMessage xss

  

   检测postmessage+dom xss配置如下:

   

  和写dom xss的作者聊过一些,这款工具,检测dom xss很不错

  关于这个插件的学习教程:

https://www.youtube.com/watch?v=Wd2R47czzO0&t=156s
https://portswigger.net/blog/introducing-dom-

  这里简单提一嘴,burpsuite很多插件,挖洞使用很方便,有空的话,我讲下burpsuite上一些很好的辅助挖洞神器。

  这个工具我就一笔带过,他不是本文的重点,本文的重点是另一个工具:

  重点检测工具:semgrep

  semgrep? what? 

A fast, open-source, static analysis tool for profoundly improving software security and reliability.  
一种快速、开源、静态分析工具,可显著提高软件的安全性和可靠性。  
我认为它就是grep命令的升级版,更加的强大。

  优势:

1.支持本地,命令行运行,很方便
2.支持在线网站上创建和导入/新增规则  
3.支持批量检测,无需对代码进行编译

  什么场景下使用他们?

1.大量的代码,进行安全缺陷审查
2.漏洞挖掘,web代码审计
3.支持纯文本代码识别和污点跟踪
4.src/众测 部分代码需要  
5.发现某个漏洞特征,使用semgrep事半功倍

 安装:

三种安装方式
# Using Homebrew
$ brew upgrade semgrep

# Using pip
$ python3 \-m pip install --upgrade semgrep

# Using Docker
$ docker pull returntocorp/semgrep:latest

 这里我使用的是第二种,pip安装。

 referer: https://github.com/returntocorp/semgrep

 semgrep基础使用:

 1.命令行cl使用 

semgrep --pattern '127.$A.$B.$C' --lang generic /etc/hosts

#lang 是指定某种类型
参考:https://semgrep.dev/docs/supported-languages/ 很详细

 

参考:https://semgrep.dev/docs/getting-started/

—pattern是一种匹配模式。但是更推荐的是导入yaml,对某段代码/某个项目进行运行漏洞规则文件:

 漏洞yaml规则库大全 用于学习编写规则:

https://github.com/returntocorp/semgrep-rules
https://semgrep.dev/playground/new?editorMode=advanced

 涉及到的语言众多

  

  污点跟踪 这个适合漏洞挖掘,半自动化:

  污点跟踪演示教程:https://semgrep.dev/docs/writing-rules/data-flow/taint-mode/

  使用污点跟踪半动化检测dom xss:

rules:
  - id: domxss-insertAdjacentHTML
    languages:
      - javascript
      - typescript
    message: Found dangerous HTML output
    mode: taint
    pattern-sources:
      - pattern: document.location.href
      - pattern: document.location
      - pattern: window.location
      - pattern: window.location.href
    pattern-sinks:
      - pattern: $X.insertAdjacentHTML(...)
      - pattern: $X.innerHTML(...)
      - pattern: $X.innerHTML = ...
    severity: WARNING

 不想聊规则细节,我说下这段yaml哪里来的。

 参考:https://netsec.expert/posts/automating-dom-xss/

 一定要看,这篇文章作者是谷歌的一位安全工程师,这是他写的规则。

 他还写了一个辅助工具,用于爬虫网站上的js:https://github.com/the-xentropy/dump-scripts/blob/main/dump-scripts.py

 

  

  然后调用semgrep批量检测script目录里的js。

  这个规则,会漏掉很多dom xss,这里简单调研了下,source和sink非常多,这里只总结了一些常见的,整合了前面的几位作者的思路和官方规则:

  总结了下用于检测js open redirect_url和其他类型的dom xss规则:

rules:
  - id: dom\_xss
    message: dom\_xss
    metadata:
      cwe:
        - "dom\_xss"
      owasp:
        - A03:2021 - Injection
      asvs:
        section: V5 Validation, Sanitization and Encoding
        control\_id: 5.2.4 Dynamic Code Execution Features
        control\_url: https://github.com/OWASP/ASVS/blob/master/4.0/en/0x13-V5-Validation-Sanitization-Encoding.md#v52-sanitization-and-sandboxing
        version: "4"
      category: security
      technology:
        - browser
      subcategory:
        - audit
      likelihood: LOW
      impact: MEDIUM
      confidence: LOW
      references:
        - https://owasp.org/Top10/A03\_2021-Injection
      license: Commons Clause License Condition v1.0\[LGPL-2.1-only\]
    languages:
      - javascript
      - typescript
    severity: WARNING
    mode: taint
    pattern-sources:
      - patterns:
          - pattern-inside: |
              url.split('...')
      - patterns:
          - pattern-inside: |
              getURLParameter('...')
      - patterns:
          - pattern-inside: |
              $PROPS.get('...')
      - patterns:
          - pattern-inside: |
              getUrlParameter('...')
      - patterns:
          - pattern-inside: |
              GetQueryString('...')
      - patterns:
          - pattern-inside: |
              $PROPS.get('...')
      - patterns:
          - pattern-inside: |
              $PROPS.split("...")
      - patterns:
          - pattern-either:
              - pattern-inside: >
                  $PROP = new URLSearchParams($WINDOW. ...
                  .location.search).get('...')

                  ...
              - pattern-inside: |
                  $PROP = new URLSearchParams(location.search).get('...')
                  ...
              - pattern-inside: >
                  $PROP = new URLSearchParams($WINDOW. ...
                  .location.hash.substring(1)).get('...')

                  ...
              - pattern-inside: >
                  $PROP = new
                  URLSearchParams(location.hash.substring(1)).get('...')

                  ...     
              - pattern-inside: | 
                  $PROP = window.location.search.substr(1).match(...)  

                  ...
          - pattern: $PROP
      - patterns:
          - pattern-either:
              - pattern-inside: |
                  $PROPS = new URLSearchParams($WINDOW. ... .location.search)
                  ...
              - pattern-inside: |
                  $PROPS = new URLSearchParams(location.search)
                  ...
              - pattern-inside: >
                  $PROPS = new URLSearchParams($WINDOW. ...
                  .location.hash.substring(1))

                  ...
              - pattern-inside: |
                  $PROPS = new URLSearchParams(location.hash.substring(1))
                  ...
          - pattern: $PROPS.get('...')
      - patterns:
          - pattern-either:
              - pattern-inside: |
                  $PROPS = new URL($WINDOW. ... .location.href)
                  ...
              - pattern-inside: |
                  $PROPS = new URL(location.href)
                  ...
          - pattern: $PROPS.searchParams.get('...')
      - patterns:
          - pattern-either:
              - pattern-inside: >
                  $PROPS = new URL($WINDOW. ...
                  .location.href).searchParams.get('...')

                  ...
              - pattern-inside: |
                  $PROPS = new URL(location.href).searchParams.get('...')
                  ...
          - pattern: $PROPS

    pattern-sinks:
      - patterns:
          - pattern-either:
              - pattern: $WINDOW. ... .location.href = $SINK
              - pattern: $WINDOW. ... .location = $SINK
              - pattern: location.href = $SINK
              - pattern: $THIS. ... .location.href = $SINK
              - pattern: $THIS. ... .location.replace($SINK)
              - pattern: $WINDOW. ... .replace($SINK)
              - pattern: $PROPS.replace($SINK)
              - pattern: $X.insertAdjacentHTML($SINK)
              - pattern: $X.innerHTML($SINK)
              - pattern: $X.innerHTML = $SINK
              - pattern: $X.innerHTML += $SINK
              - pattern: $X.prepend($SINK)
              - pattern: $X.prepend("..."+$SINK)
              - pattern: $X.append($SINK)
              - pattern: $X.append("..."+$SINK)
              - pattern: $X.before($SINK)
              - pattern: $X.before("..."+$SINK)
              - pattern: $X.after($SINK)
              - pattern: $X.after("..."+$SINK)
              - pattern: $X.html($SINK)
              - pattern: $X.html("..."+$SINK)
              
          - metavariable-pattern:
              patterns:
                - pattern-not: |
                    "..." + $VALUE
                - pattern-not: |
                    \`...${$VALUE}\`
              metavariable: $SINK

   如何实战利用?

  使用一个漏洞规则批量检测多个项目:

 

   使用多个规则检测多个项目:

semgrep -c rules/  jstest/\*

  

  对于semgrep,我并不陌生。早在今年log4j2漏洞刚爆发的时候,我们团队内部就使用了semgrep编写log4j2规则去批量检测,效果很好。 

  工具很强大,写好匹配规则即可。语言都是次要的,主要是要多收集source和sink。剩下的就是套娃~~ 

TRANSLATE with x

English

Arabic

Hebrew

Polish

Bulgarian

Hindi

Portuguese

Catalan

Hmong Daw

Romanian

Chinese Simplified

Hungarian

Russian

Chinese Traditional

Indonesian

Slovak

Czech

Italian

Slovenian

Danish

Japanese

Spanish

Dutch

Klingon

Swedish

English

Korean

Thai

Estonian

Latvian

Turkish

Finnish

Lithuanian

Ukrainian

French

Malay

Urdu

German

Maltese

Vietnamese

Greek

Norwegian

Welsh

Haitian Creole

Persian

 

TRANSLATE with

COPY THE URL BELOW

Back

EMBED THE SNIPPET BELOW IN YOUR SITE

Enable collaborative features and customize widget: Bing Webmaster Portal

Back

此页面的语言为英语

翻译为中文(简体)

  • 中文(简体)
  • 中文(繁体)
  • 丹麦语
  • 乌克兰语
  • 乌尔都语
  • 亚美尼亚语
  • 俄语
  • 保加利亚语
  • 克罗地亚语
  • 冰岛语
  • 加泰罗尼亚语
  • 匈牙利语
  • 卡纳达语
  • 印地语
  • 印尼语
  • 古吉拉特语
  • 哈萨克语
  • 土耳其语
  • 威尔士语
  • 孟加拉语
  • 尼泊尔语
  • 布尔语(南非荷兰语)
  • 希伯来语
  • 希腊语
  • 库尔德语
  • 德语
  • 意大利语
  • 拉脱维亚语
  • 挪威语
  • 捷克语
  • 斯洛伐克语
  • 斯洛文尼亚语
  • 旁遮普语
  • 日语
  • 普什图语
  • 毛利语
  • 法语
  • 波兰语
  • 波斯语
  • 泰卢固语
  • 泰米尔语
  • 泰语
  • 海地克里奥尔语
  • 爱沙尼亚语
  • 瑞典语
  • 立陶宛语
  • 缅甸语
  • 罗马尼亚语
  • 老挝语
  • 芬兰语
  • 英语
  • 荷兰语
  • 萨摩亚语
  • 葡萄牙语
  • 西班牙语
  • 越南语
  • 阿塞拜疆语
  • 阿姆哈拉语
  • 阿尔巴尼亚语
  • 阿拉伯语
  • 韩语
  • 马尔加什语
  • 马拉地语
  • 马拉雅拉姆语
  • 马来语
  • 马耳他语
  • 高棉语

随时将英语翻译为中文(简体)PRO
一律不翻译英语
一律不翻译i.cnblogs.com

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2