├── .nojekyll ├── 爬虫 ├── 系统设计 │ ├── 分布式爬虫.md │ ├── 动态爬虫.md │ └── 反爬虫对抗.md ├── README.md ├── 验证码绕过 │ ├── README.md │ └── 滑动验证.md ├── 反爬虫 │ ├── README.md │ └── 人机识别.md ├── .DS_Store ├── 去重 │ ├── 文本相似度.md │ └── URL 归一化.md └── Scrapy │ └── README.md ├── Web 安全 ├── CSRF │ ├── 漏洞检测.md │ ├── 防御修复.md │ ├── README.md │ └── 攻击实例.md ├── XSS │ ├── 漏洞检测.md │ ├── README.md │ ├── 防御修复.md │ └── examples.html ├── 浏览器安全 │ └── README.md ├── .DS_Store ├── SQL 注入 │ ├── SQL 注入工具.md │ └── README.md ├── 编码校验 │ ├── 代码混淆.md │ └── 自动填充.md ├── README.md ├── 点击劫持 │ └── README.md └── 文件上传漏洞 │ └── README.md ├── 渗透测试 ├── 分布式扫描器 │ ├── 分布式扫描调度.md │ ├── 半自动化扫描.md │ ├── 基础扫描.md │ ├── 数字资产管理.md │ └── README.md └── README.md ├── 软件安全 ├── 安全更新 │ ├── README.md │ └── TUF │ │ └── README.md ├── .DS_Store ├── 逆向工程 │ ├── .DS_Store │ └── 99~参考资料 │ │ ├── js 破解之补浏览器环境的两种监控方式.md │ │ ├── Proxy 代理(二次修改).md │ │ ├── 某乎请求头签名算法分析.md │ │ ├── Protobuf 协议逆向解析 - APP 爬虫 .md │ │ ├── 分享一个 Android 通用 svc 跟踪以及 hook 方案——Frida-Seccomp.md │ │ ├── 逆向分析反调试 + ollvm 混淆的 Crackme.md │ │ ├── Python 爬虫进阶必备 _ Js 逆向之补环境到底是在补什么?.md │ │ ├── frida 免 root hook.md │ │ ├── 某咖啡 app 加密参数分析进阶版.md │ │ ├── app 逆向 平头哥实战(某农产品 app).md │ │ ├── 爬虫之 - 某生鲜 APP 加密参数逆向分析.md │ │ ├── 大猿搜题 sign so 加密参数分析|unidbg.md │ │ └── 【2021 春节】安卓中级题逆向总结.md └── 邮件安全 │ └── 99~参考资料 │ └── 2024~Understanding SPF, DKIM, and DMARC: A Simple Guide.md ├── INTRODUCTION.md ├── .DS_Store ├── 99~参考资料 ├── 2023~《云安全攻防入门》 │ └── README.md └── 斯托林斯~《密码编码学与网络安全》 │ ├── 信息安全(一)——概述.md │ ├── 信息安全(四)——公私钥密码体制.md │ ├── 信息安全(二)——密码学.md │ └── 信息安全(三)——对称密码体制.md ├── 密码与编码 ├── .DS_Store ├── 数据安全 │ └── README.md └── 公钥 │ └── PKI.md ├── .gitattributes ├── 网络安全 ├── TCP 安全.md └── README.md ├── .gitignore ├── README.md ├── _sidebar.md ├── index.html └── LICENSE /.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /爬虫/系统设计/分布式爬虫.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /爬虫/系统设计/动态爬虫.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Web 安全/CSRF/漏洞检测.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /渗透测试/分布式扫描器/分布式扫描调度.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /渗透测试/分布式扫描器/半自动化扫描.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /渗透测试/分布式扫描器/基础扫描.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /渗透测试/分布式扫描器/数字资产管理.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /爬虫/README.md: -------------------------------------------------------------------------------- 1 | # 爬虫 2 | -------------------------------------------------------------------------------- /软件安全/安全更新/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /INTRODUCTION.md: -------------------------------------------------------------------------------- 1 | # 本篇导读 2 | -------------------------------------------------------------------------------- /Web 安全/XSS/漏洞检测.md: -------------------------------------------------------------------------------- 1 | # XSS 漏洞检测 2 | -------------------------------------------------------------------------------- /Web 安全/浏览器安全/README.md: -------------------------------------------------------------------------------- 1 | # 浏览器与网络安全 2 | -------------------------------------------------------------------------------- /爬虫/验证码绕过/README.md: -------------------------------------------------------------------------------- 1 | # 爬虫中的验证码绕过 2 | -------------------------------------------------------------------------------- /爬虫/反爬虫/README.md: -------------------------------------------------------------------------------- 1 | # 反爬虫 2 | 3 | - Web 防爬指南 https://cubox.pro/c/ky3i7T -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wx-chevalier/InfoSecurity-Notes/master/.DS_Store -------------------------------------------------------------------------------- /99~参考资料/2023~《云安全攻防入门》/README.md: -------------------------------------------------------------------------------- 1 | > [原文地址](https://github.com/EvilAnne/lzCloudSecurity) 2 | -------------------------------------------------------------------------------- /爬虫/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wx-chevalier/InfoSecurity-Notes/master/爬虫/.DS_Store -------------------------------------------------------------------------------- /软件安全/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wx-chevalier/InfoSecurity-Notes/master/软件安全/.DS_Store -------------------------------------------------------------------------------- /Web 安全/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wx-chevalier/InfoSecurity-Notes/master/Web 安全/.DS_Store -------------------------------------------------------------------------------- /密码与编码/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wx-chevalier/InfoSecurity-Notes/master/密码与编码/.DS_Store -------------------------------------------------------------------------------- /爬虫/去重/文本相似度.md: -------------------------------------------------------------------------------- 1 | # 文本相似度 2 | 3 | # Links 4 | 5 | - https://www.cnblogs.com/maybe2030/p/5203186.html 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.xmind filter=lfs diff=lfs merge=lfs -text 2 | *.pdf filter=lfs diff=lfs merge=lfs -text 3 | -------------------------------------------------------------------------------- /Web 安全/SQL 注入/SQL 注入工具.md: -------------------------------------------------------------------------------- 1 | # SQL 注入工具 2 | 3 | # Links 4 | 5 | - https://zhuanlan.zhihu.com/p/139737334 6 | -------------------------------------------------------------------------------- /软件安全/逆向工程/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wx-chevalier/InfoSecurity-Notes/master/软件安全/逆向工程/.DS_Store -------------------------------------------------------------------------------- /渗透测试/分布式扫描器/README.md: -------------------------------------------------------------------------------- 1 | # 分布式扫描器 2 | 3 | 本章我们会以 [Chaos-Scanner](https://github.com/wx-chevalier/Chaos-Scanner) 为例,讨论分布式扫描器的设计与实现。 4 | -------------------------------------------------------------------------------- /Web 安全/编码校验/代码混淆.md: -------------------------------------------------------------------------------- 1 | # 代码混淆 2 | 3 | # Links 4 | 5 | - [Protect your DOM from third-party tampering.](https://github.com/elierotenberg/react-armor) 6 | -------------------------------------------------------------------------------- /爬虫/反爬虫/人机识别.md: -------------------------------------------------------------------------------- 1 | # 人机识别 2 | 3 | # Links 4 | 5 | - [2019~Bot detection 101: How to detect web bots? #Series#](https://cubox.pro/c/91gFli): In this blog post, we present the main techniques used to detect them. 6 | -------------------------------------------------------------------------------- /软件安全/邮件安全/99~参考资料/2024~Understanding SPF, DKIM, and DMARC: A Simple Guide.md: -------------------------------------------------------------------------------- 1 | > [原文地址](https://github.com/nicanorflavier/spf-dkim-dmarc-simplified) 2 | 3 | # Understanding SPF, DKIM, and DMARC: A Simple Guide 4 | -------------------------------------------------------------------------------- /软件安全/安全更新/TUF/README.md: -------------------------------------------------------------------------------- 1 | # TUF 2 | 3 | TUF 是一项用于保护软件更新系统的开源安全技术,亦是从云原生计算基金会毕业的第一个以规范与安全性为重点的项目。纽约大学丹顿工程学院计算机科室与工程学副教授 Justin Cappos 于 2009 年启动 TUF 项目开发,由此成为第一位领导 CNCF 毕业项目的学术研究人员;与此同时,TUF 亦是首个源自高校的 CNCF 毕业项目。 4 | 5 | TUF 项目的主要设计目标包括: 6 | 7 | - 建立一套可用于保护现有及新型软件更新系统的框架(框架中包含多种库、文件格式及实用工具)。 8 | - 降低各类高强度攻击行为的潜在影响。 9 | - 提供出色的灵活性,满足多种软件更新系统的不同需求。 10 | - 可轻松与各类现有软件更新系统相集成。 11 | -------------------------------------------------------------------------------- /Web 安全/README.md: -------------------------------------------------------------------------------- 1 | # Web 应用安全基础 2 | 3 | 现代的软件开发者已经有点像瑞士军刀了,首先,你需要来保证完成用户的功能或者业务需求,并且要保证又快又好地完成。其次,你希望你的代码能够拥有充分的可理解性或者可扩展性:能够随着 IT 需求的快速变迁而有着充分的扩展空间,与此同时还需要稳定与可用。开发者必须列举出有用的接口,优化数据库,以及频繁地建立或者维护一个交付渠道。不过,当我们审视这长长的需求列表的时候,在快速、低成本以及灵活可扩展之下的,即是安全性。或许直到一些东西出了问题,或者你构建的系统被攻击了之后才能深刻感受到安全才是最重要的。安全这个概念有点像性能,是个泛化的跨越了多个领域的概念。所以一个开发者怎么才能在模糊的安全需求与未知的风险面前选择合适的开发规划呢?当然如果能够明确这些安全需求与定位到威胁的话毫无疑问非常值得推荐,但是这个准备本身就需要耗费大量的时间与金钱。 4 | -------------------------------------------------------------------------------- /Web 安全/XSS/README.md: -------------------------------------------------------------------------------- 1 | # XSS 跨站脚本详解 2 | 3 | 跨网站脚本(Cross-site scripting,通常简称为 XSS 或跨站脚本或跨站脚本攻击)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了 HTML 以及用户端脚本语言。 4 | 5 | XSS 攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是 JavaScript,但实际上也可以包括 Java,VBScript,ActiveX,Flash 或者甚至是普通的 HTML。攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、私密网页内容、会话和 cookie 等各种内容。 6 | 7 | 对于任何的参数请求以及页面中涉及到的用户信息全部都要进行特殊字符的过滤,进行 HTML 转义,防止触发恶意脚本。 8 | -------------------------------------------------------------------------------- /Web 安全/点击劫持/README.md: -------------------------------------------------------------------------------- 1 | # 点击劫持 2 | 3 | 点击劫持(ClickJacking)是一种视觉上的欺骗手段。大概有两种方式,一是攻击者使用一个透明的 iframe,覆盖在一个网页上,然后诱使用户在该页面上进行操作,此时用户将在不知情的情况下点击透明的 iframe 页面;二是攻击者使用一张图片覆盖在网页,遮挡网页原有位置的含义。 4 | 5 | 对网站设置 X-Frame-Options 的 http 头可以阻止一个网站被加载到标签。具体为设置值为: 6 | 7 | - DENY 时,禁止在任何的网页中加载此页面 8 | - SAMEORIGIN 时,只允许在同一域名页面的 中展示 9 | - ALLOW-FROM uri 时,允许制定 Uri 的页面的中展示 10 | 11 | # Links 12 | 13 | - https://kebingzao.com/2018/05/05/web-forbidden-iframe-embed/ 14 | -------------------------------------------------------------------------------- /Web 安全/文件上传漏洞/README.md: -------------------------------------------------------------------------------- 1 | # 文件上传漏洞 2 | 3 | 文件上传漏洞,指的是用户上传一个可执行的脚本文件,并通过此脚本文件获得了执行服务端命令的能力。许多第三方框架、服务,都曾经被爆出文件上传漏洞,比如很早之前的 Struts2,以及富文本编辑器等等,可能被一旦被攻击者上传恶意代码,有可能服务端就被人黑了。 4 | 5 | - 文件上传的目录设置为不可执行。 6 | - 判断文件类型。在判断文件类型的时候,可以结合使用 MIME Type,后缀检查等方式。因为对于上传文件,不能简单地通过后缀名称来判断文件的类型,因为攻击者可以将可执行文件的后缀名称改为图片或其他后缀类型,诱导用户执行。 7 | - 对上传的文件类型进行白名单校验,只允许上传可靠类型。 8 | - 上传的文件需要进行重新命名,使攻击者无法猜想上传文件的访问路径,将极大地增加攻击成本,同时向 shell.php.rar.ara 这种文件,因为重命名而无法成功实施攻击。 9 | - 限制上传文件的大小。 10 | - 单独设置文件服务器的域名。 11 | -------------------------------------------------------------------------------- /Web 安全/SQL 注入/README.md: -------------------------------------------------------------------------------- 1 | # SQL 注入 2 | 3 | 攻击者在 HTTP 请求中注入恶意的 SQL 代码,服务器使用参数构建数据库 SQL 命令时,恶意 SQL 被一起构造,并在数据库中执行。 4 | 用户登录,输入用户名 test,密码 `'or '1'='1`,如果此时使用参数构造的方式,就会出现: 5 | 6 | ```sql 7 | select * from user where name = 'zach' and password = '' or '1'='1' 8 | ``` 9 | 10 | 不管用户名和密码是什么内容,使查询出来的用户列表不为空。其防护手段主要为: 11 | 12 | - Web 端进行有效性检验,限制字符串输入的长度。 13 | - 服务端不用拼接 SQL 字符串,使用预编译的 PrepareStatement,进行有效性检验,过滤 SQL 需要的参数中的特殊字符,比如单引号、双引号等。 14 | 15 | # Links 16 | 17 | - https://www.zhihu.com/question/335706717/answer/756929373 18 | -------------------------------------------------------------------------------- /网络安全/TCP 安全.md: -------------------------------------------------------------------------------- 1 | # TCP Security 2 | 3 | ## SYN 攻击 4 | 5 | 在三次握手过程中,Server 发送 SYN-ACK 之后,收到 Client 的 ACK 之前的 TCP 连接称为半连接(half-open connect),此时 Server 处于 SYN_RCVD 状态,当收到 ACK 后,Server 转入 ESTABLISHED 状态。SYN 攻击就是 Client 在短时间内伪造大量不存在的 IP 地址,并向 Server 不断地发送 SYN 包,Server 回复确认包,并等待 Client 的确认,由于源地址 是不存在的,因此,Server 需要不断重发直至超时,这些伪造的 SYN 包将产时间占用未连接队列,导致正常的 SYN 请求因为队列满而被丢弃,从而引起网 络堵塞甚至系统瘫痪。SYN 攻击时一种典型的 DDOS 攻击,检测 SYN 攻击的方式非常简单,即当 Server 上有大量半连接状态且源 IP 地址是随机的,则可以断定遭到 SYN 攻击了,使用如下命令可以让之现行: 6 | 7 | ``` 8 | # netstat -nap | grep SYN_RECV 9 | ``` 10 | -------------------------------------------------------------------------------- /爬虫/Scrapy/README.md: -------------------------------------------------------------------------------- 1 | # Scrapy CheatSheet 2 | 3 | # 递归爬取 4 | 5 | ```py 6 | class DmozSpider(CrawlSpider): 7 | name = "dmoz" 8 | allowed_domains = ["mydomain.nl"] 9 | start_urls = [ 10 | "http://www.mydomain.nl/Zuid-Holland" 11 | ] 12 | 13 | rules = (Rule(SgmlLinkExtractor(allow=('*Zuid-Holland*', )), callback='parse_winkel', follow=True),) 14 | 15 | def parse_winkel(self, response): 16 | sel = Selector(response) 17 | sites = sel.xpath('//ul[@id="itemsList"]/li') 18 | items = [] 19 | 20 | for site in sites: 21 | item = WinkelItem() 22 | item['adres'] = site.xpath('.//a/text()').extract(), site.xpath('text()').extract(), sel.xpath('//h1/text()').re(r'winkel\s*(.*)') 23 | items.append(item) 24 | return items 25 | ``` 26 | -------------------------------------------------------------------------------- /网络安全/README.md: -------------------------------------------------------------------------------- 1 | # 网络安全 2 | 3 | 面对与日增长的网络连接设备,越来越多的人开始担心网络的安全性,尤其当高速、低延迟、大容量的 5G 网络即将落地,在给我们带来网络速度享受的同时,它所使用的网络切片技术似乎对安全提出了更高的要求。针对这个问题,姜向前认为,网络切片并不是一个单独的技术,它是基于云计算、虚拟化、软件定义网络、分布式云架构等几大技术群而实现,通过上层统一的编排让网络具备管理、协同的能力。因此,需要通过面向未来的安全解决方案保护 5G 网络安全。 4 | 5 | 未来网络安全问题会变得愈加复杂,解决个人和企业网络安全就成为了迫在眉睫的问题。针对这方面,姜向前分别提出了自己的想法,针对个人来说,第一,建立网络安全意识,就像人身安全意识,先增强安全意识。举个例子,有些同学可能习惯电脑不锁屏,或者使用弱口令,亦或者多平台使用相同账号密码等等,这些行为是很容易被盗取信息的。因此,对于个人来说,安全意识养成很重要;第二,不断学习网络安全专业知识。身处于信息化时代,每个人都需要不断加强网络知识学习和网络安全技巧的训练,成为网络安全中的一份子;第三,使用专业的安全产品保障我们的信息安全。 6 | 7 | 而针对企业来说,可以参考信息安全领域中的安全滑动标尺,在不同阶段有不同的防御手段。第一个阶段是架构的安全,此阶段应做好系统规划、构建和维护阶段,将所有的安全因素给考虑进去;第二个阶段是被动的防御,这是代表已经有攻击者进行攻击,需要被动地进行防御,需要在架构安全阶段添加系统,提供可靠防御或洞察威胁,但无需持续的人类互动;第三个阶段是主动防御,企业有目的的做一些部署,安全分析师对攻击者的内部网络进行监控,做出响应以及学习的过程;第四个阶段是威胁情报,通过一些手段收集数据,进行加工信息,最后形成一些有效的安全情报,并开始有效处置;第五个阶段是针对攻击者的反制,也就是大家常说的通过溯源进入攻击,这是针对攻击者的合法反制措施和自我防御措施。 8 | 9 | “亡羊补牢”式安全无法给用户创造安全的环境,突破核心技术是解决网络安全问题的关键。网络安全从业者只有站在技术的制高点,比攻击者想的更远更深,与攻击者形成一个高低式的优势,从安全的本质出发,以技术驱动为核心才能真正实现网络安全。 10 | -------------------------------------------------------------------------------- /99~参考资料/斯托林斯~《密码编码学与网络安全》/信息安全(一)——概述.md: -------------------------------------------------------------------------------- 1 | # 信息安全的目标 2 | 3 | ## 保密性 Confidentiality 4 | 5 | 数据保密性:对于未授权的个体而言,信息不可用 6 | 隐私性:确保个人能控制或确定自身那些信息可以被收集、保存,这些信息可以被谁公开及向谁公开 7 | 8 | ## 完整性 Integrity 9 | 10 | 信息的完整性、一致性,分为 11 | 数据完整性,未被未授权篡改或者损坏;系统完整性,系统未被非法操纵,按既定的目标运行 12 | 13 | ## 可用性 Availability 14 | 15 | 服务连续性,对授权用户不能拒绝服务 16 | 17 | ## 真实性Authenticity 18 | 19 | 能够验证用户是他声称的那个人 20 | 确保系统的输入来源于可信任的源 21 | 22 | ## 可追溯性Accountability 23 | 24 | 实体的行为可以唯一追溯到该实体 25 | 26 | # 安全攻击 27 | 28 | ## 被动攻击:窃听和检测 29 | 信息内容泄露攻击——隐藏信息:加密 30 | 流量分析 31 | 难察觉,关键:预防 32 | 33 | ## 主动攻击: 34 | 伪装:假装别的实体。如:捕获认证信息,进行重播 35 | 重播:将获得的信息再次发送以产生非授权效果 36 | 消息修改:修改合法消息的一部分或者延迟消息,或改变消息的顺序以获得非授权效果 37 | 拒绝服务:阻止或禁止对通信设施的增产使用和管理。 38 | 39 | # 安全服务 40 | ITU-T X.800,安全服务目的在于利用一种或者多种安全机制进行反攻击。 41 | 42 | ## 1)认证 43 | 44 | 同等实体认证 45 | 数据源认证:电子邮件的应用 46 | 47 | ## 2)访问控制:阻止对资源的非授权使用 48 | 49 | ## 3)数据保密性:防止被动攻击 50 | 51 | 数据免于非授权泄露 52 | 流量保密性 53 | 54 | ## 4)数据完整性: 55 | 保证收到的数据没有修改、插入、删除或重播 56 | 57 | ## 5)不可否认性 58 | 59 | 源不可否认 60 | 宿不可否认 61 | 62 | ## 6)可用性服务 63 | 64 | # 安全机制 65 | 1. 加密 66 | 2. 数字签名 67 | 3. 访问控制 68 | 4. 数据完整性 69 | 5. 认证交换 70 | 6. 流量填充 71 | 7. 路由控制 72 | 8. 公证 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all 2 | * 3 | 4 | # Unignore all with extensions 5 | !*.* 6 | 7 | # Unignore all dirs 8 | !*/ 9 | 10 | .DS_Store 11 | 12 | # Logs 13 | logs 14 | *.log 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | 19 | # Runtime data 20 | pids 21 | *.pid 22 | *.seed 23 | *.pid.lock 24 | 25 | # Directory for instrumented libs generated by jscoverage/JSCover 26 | lib-cov 27 | 28 | # Coverage directory used by tools like istanbul 29 | coverage 30 | 31 | # nyc test coverage 32 | .nyc_output 33 | 34 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 35 | .grunt 36 | 37 | # Bower dependency directory (https://bower.io/) 38 | bower_components 39 | 40 | # node-waf configuration 41 | .lock-wscript 42 | 43 | # Compiled binary addons (https://nodejs.org/api/addons.html) 44 | build/Release 45 | 46 | # Dependency directories 47 | node_modules/ 48 | jspm_packages/ 49 | 50 | # TypeScript v1 declaration files 51 | typings/ 52 | 53 | # Optional npm cache directory 54 | .npm 55 | 56 | # Optional eslint cache 57 | .eslintcache 58 | 59 | # Optional REPL history 60 | .node_repl_history 61 | 62 | # Output of 'npm pack' 63 | *.tgz 64 | 65 | # Yarn Integrity file 66 | .yarn-integrity 67 | 68 | # dotenv environment variables file 69 | .env 70 | 71 | # next.js build output 72 | .next 73 | -------------------------------------------------------------------------------- /爬虫/系统设计/反爬虫对抗.md: -------------------------------------------------------------------------------- 1 | # 反爬虫与绕过对抗 2 | 3 | 毫无疑问,爬虫破坏了网站的正常访问,造成了系统的额外负载。而反爬虫还能够保护数据,放置恶意的商业竞争。 4 | 5 | # IP 限流与代理 6 | 7 | 当网站发现某个 IP 访问的速度不仅飞快,而且都是在同一个 IP 段的时候,会认为该 IP 在进行爬虫操作,因此会对该 IP 进行限制访问,拒绝传输数据。 8 | 9 | 解决方法:首先通过设置 User-Agent 来模拟正常的访问流程,同时通过获取代理 IP 来爬取数据。 10 | 11 | # 权限认证 12 | 13 | 必须登录才能访问。 14 | 我们在之前的文章中,通过设置 User-Agent 模拟浏览器,让服务器认为我们是一个正常的访问过程。当网站发现服务器压力非常大,而且都是正常的 User-Agent 时,往往会对部分比价重要的数据,设置为必须登录才能访问。 15 | 16 | 解决方法:我们可以首先注册一个账号,带上账号的 Cookie 爬取数据。 17 | 18 | 保存 cookies,记录用户的状态,在模拟登陆十分麻烦的情况下,我们不妨直接在 web 上登陆之后取下 cookie 并保存然后带上 cookie 做爬虫,但这不是长久的方法,而且 cookie 隔一段时间可能失效。有的网站会根据 cookie 中的一些值去判断是否机器人,这个需要自己不断测试,比如豆瓣。 19 | 20 | 注意配合移动端、web 端以及桌面版,其中 web 端包括 m 站即手机站和 pc 站,往往是 pc 站的模拟抓取难度大于手机站,所以在 m 站和 pc 站的资源相同的情况下优先考虑抓取 m 站。同时如果无法在 web 端抓取,不可忽略在 app 以及桌面版的也可以抓取到目标数据资源。 21 | 22 | # 验证码 23 | 24 | 滑动滑块。 25 | 这是目前比较流行的验证方法。即只有用户通过鼠标,将一部分的图像移动到对应的区域,才能够正常访问 26 | 解决方法:目前的解决方法,大部分是首先对图像进行处理,然后模拟人工滑动的方式。(难) 27 | 28 | 对于处理验证码,爬虫爬久了通常网站的处理策略就是让你输入验证码验证是否机器人,此时有三种解决方法: 29 | 30 | 第一种把验证码 down 到本地之后,手动输入验证码验证,此种成本相对较高,而且不能完全做到自动抓取,需要人为干预。第二种图像识别验证码,自动填写验证,但是现在的情况是大部分验证码噪声较多复杂度大,对于像我这样对图像识别不是很熟悉的人很难识别出正确的验证码。第三种也是最实用的一种,接入自动打码平台,个人感觉比上两种方法好些。2、多账号反爬,有很多的网站会通过同一个用户单位时间内操作频次来判断是否机器人,比如像新浪微博等网站。这种情况下我们就需要先测试单用户抓取阈值,然后在阈值前切换账号其他用户,如此循环即可。当然,新浪微博反爬手段不止是账号,还包括单 ip 操作频次等。 31 | 32 | 使用验证码验证登录。 33 | 网站使用验证码进行登录验证,查看网站必须在登录界面输入相应的验证码才能够访问。 34 | 解决方法:使用机器学习算法,对验证码进行训练。或者是通过打码平台以及人工打码的方式进行处理。 35 | 36 | # 数据编码 37 | 38 | 使用异步加载的方式加载数据。 39 | 网站的数据并不全部加载,只有当用户查看到最底部时,网站才会将剩下的数据加载出来。 40 | 解决方法:正如我们之前学到的一样,AJAX 技术的确难以处理。我们需要通过不断地请求,去分析其规律,根据规律模拟出 AJAX 所请求的网页链接。 41 | 42 | 重要数据图像化。 43 | 网站在传输数据之前,将数据编码为图片的格式,通过图片来展示认为重要的数据。 44 | 解决方式:使用 OCR 识别技术,识别图像中的数据。(难) 45 | 46 | # 行为识别 47 | 48 | 行为识别。 49 | 目前大型的网站,例如阿里巴巴等,会对用户在网站上操作的每一个动作进行判断。当用户的动作具有间歇性、鼠标停留时间等特征与正常访问时的数据产生误差时,系统会判定为爬虫程序,并且拒绝相应的请求。 50 | 51 | 发送错误信息。 52 | 当网站识别出发出的请求是来自于爬虫程序时,并不会拒绝连接,而是为该请求提供一个错误的信息或者数据,一方面让爬虫程序误认为爬取到了想要的数据,另一方面,也降低了服务器的请求压力。 53 | 解决方法:抽取 50%或者以上的数据进行抽查或者再次爬取。 54 | -------------------------------------------------------------------------------- /爬虫/去重/URL 归一化.md: -------------------------------------------------------------------------------- 1 | # URL 归一化 2 | 3 | 出于各种各样的原因,在 Web 应用中,路径会做随机串处理,这些形式相似的 URL 实质上是在访问同一资源,譬如下面的 URL 应该泛化为一同个模式,即 `/jiage/CODE.html`。URL 归一化就是将同一资源下被随机串处理的路径泛化成同一个模式。 4 | 5 | ```sh 6 | /jiage/AA.html 7 | /jiage/BB.html 8 | /jiage/CC.html 9 | /jiage/DD.html 10 | ``` 11 | 12 | 目前业内对 URL 归一化有很多种解法,传统的做法有正则表达式法和基于统计的方法,算法的做法有基于模式树的方法。 13 | 14 | | **算法** | **优点** | **缺点** | 15 | | ---------------- | -------------------------------- | -------------------------------- | 16 | | 正则表达式 | 速度最快 | 欠拟合 | 17 | | 模式树方法 | 提供一个自顶向下树形结构的思路 | 欠拟合、过拟合问题并存,速度最慢 | 18 | | 基于流量画像方法 | 针对不同站点做流量画像,速度较快 | 存在过拟合现象 | 19 | 20 | 在实际的工程实践中,单看一个 URL 的字面信息是无法准确判断其是否应该进行归一化,需要看到更多接口的流量才能做到准确的判断。一般来说框架也会由离线训练和在线使用两部分组成: 21 | 22 | - 离线训练是指算法的训练过程,通过不断迭代和采样创建接近实际的训练池,从全局看到每个接口的全部流量以及其周围全部的接口,输出待归一化接口的聚类中心点表供线上使用,这部分需要保证准确率。 23 | - 在线使用是指来一条 URL 过来就可以判断出其是否需要进行归一化处理,如果需要归一化则给出正确的 URL Pattern,这部分需要保证高效率。 24 | 25 | # 文本聚类 26 | 27 | 使用 URL 的 simhash 值作为特征,再结合改进的层次聚类 BIRCH 算法,生成聚类特征树(Clustering Feature Tree,简称 CF Tree)森林。选择该算法主要原因是它适用于类别数比较大的情况,并且不用预先输入类别数,基于 BIRCH 算法基础上我们做了一些优化,目的是提高短文本聚类的稳定性和准确性,具体优化如下: 28 | 29 | - BIRCH 算法是一种流式建立 CF Tree 过程,每读入一个样本点计算它与现有 CF 节点海明距离,如果在半径为 T 的超球体范围内,则更新样本到该 CF 节点中,反之,再建立一个新的 CF 节点。但是这种方法会因为样本读入顺序导致树结构不合理,因此在本算法中第一步使用 K-Means,将原本建立一棵 CF Tree 改为建立 CF Forest,对训练池所有样本进行一次 K-Means,生成若干个簇,在每个簇内再建立一颗 CF Tree; 30 | 31 | - K-Means 后先对每个簇进行评估,簇满足以下两个条件则认为该簇的 URL 可以进行归一化,则该簇停止节点分裂并将中心点加入到聚类中心点表:一个簇的 SSE(Sum of Squares for Error,残差平方和) 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码,原文地址 [mp.weixin.qq.com](https://mp.weixin.qq.com/s?__biz=MzU5ODgyOTUzNw==&mid=2247484039&idx=1&sn=0de1ee2e3d201b4b5e2823c1b7975b5a&chksm=febf7209c9c8fb1fb4f8feedd37e223a35887526548564462bd846cc41b954541fe53ac5e0ed&mpshare=1&scene=1&srcid=0302cSUvBnRqvw2ComEobKZP&sharer_sharetime=1646203623636&sharer_shareid=56da189f782ce62249ab4f6494feca50&version=3.1.20.90367&platform=mac#rd) 2 | 3 | 1,首先要说的肯定是 Proxy 了,介绍就不说了,直接上代码: 4 | 5 | ``` 6 | window = new Proxy(global, { 7 | get: function (target, key, receiver) { 8 | console.log("window.get", key, target[key]); 9 | if (key=="location"){ 10 | location = new Proxy(target[key], { 11 | get: function (_target, _key, _receiver) { 12 | console.log("window.get", key, _key, _target[_key]); 13 | if (_key=="port"){console.log("关注公众号【妄为写代码】")} 14 | return _target[_key]; 15 | } 16 | }) 17 | } 18 | return target[key]; 19 | }, 20 | set: function (target, key, value, receiver) { 21 | console.log("window.set", key, value); 22 | target[key] = value; 23 | } 24 | }); 25 | window.a = {}; 26 | window.a; 27 | window.location = {a: 2}; 28 | window.location.a; 29 | window.b = {a: 2}; 30 | window.b.a; 31 | location.port; 32 | console.log("--------------"); 33 | window.location.port; 34 | 35 | ``` 36 | 37 | node 环境执行结果: 38 | 39 | ![](https://mmbiz.qpic.cn/mmbiz_png/PicMqQs6T6MNerXH5LUe0WPbwcutymn72M4H3yicw6ibWh4NYhQyOrqScX6zZvMLNBt3P5nSHRQ4gI6hmOtKqqzDQ/640?wx_fmt=png) 40 | 41 | 重点关注【嵌套 Proxy】和【重复 Proxy】 42 | 43 | 2,对象属性的 hook 方式 44 | 45 | 在浏览器中执行: 46 | 47 | ![](https://mmbiz.qpic.cn/mmbiz_png/PicMqQs6T6MNerXH5LUe0WPbwcutymn72NpUd6aVfbRdf5j3icqr0EsEPM49wmyjY77pYNADx5DRlxibqTEvC4HsQ/640?wx_fmt=png) 48 | 49 | ![](https://mmbiz.qpic.cn/mmbiz_png/PicMqQs6T6MNerXH5LUe0WPbwcutymn72C2ydR961aTluSG8ibICClkNiaUJypLI0FHGxJCwtXP5l1XZl6S3hU0cw/640?wx_fmt=png) 50 | 51 | 重点关注【未在固定范围的新增属性】和【对比两种方式的  location.port】和【多层属性的获取  window.location.port】 52 | 53 | 3,这个监控的作用就不用说了吧,就是大家常说的缺哪补哪需要用到的,现在补环境的场景越来越多了,一些知名 js 反爬产品,就可以用这个思路,环境补的好,可以到处用,还能省好多事,一举多得。 54 | 55 | 嗯,我也准备学大家开始【佛系】社群运营了,大家可以扫码进群一起交流技术,nice to meet you. 56 | 57 | ![](https://mmbiz.qpic.cn/mmbiz_png/PicMqQs6T6MNerXH5LUe0WPbwcutymn72c05JlHHVWUoEQCabAghOvicFz9OsF3lbH8h5uDm0W7ZJYDYiav5CeawQ/640?wx_fmt=png) 58 | -------------------------------------------------------------------------------- /Web 安全/CSRF/防御修复.md: -------------------------------------------------------------------------------- 1 | # CSRF 漏洞防御与修复 2 | 3 | ## 服务端防御 4 | 5 | ### 遵循标准的 GET 动作 6 | 7 | 只允许 GET 请求检索数据,但是不允许它修改服务器上的任何数据。这个修改可以防止利用 {img} 标签或者其它的类型的 GET 请求的 CSRF 攻击。另外,这个建议遵循 RFC 2616(HTTP/1.1):具体说来,按照约定,GET 和 HEAD 方法不应该进行检索之外的动作。这些方法应该被认为是 “ 安全的 ”。虽然这个保护措施无法阻止 CSRF 本身,因 为攻击者可以使用 POST 请求,但是它却可以与 (2) 结合来全面防止 CSRF 漏洞。这里,我们假定对手无法修改用户的 cookie。 8 | 9 | ### 为页面增加随机数 10 | 11 | 当用户访问站点时,该站点应该生成一个(密码上很强壮的)伪随机值,并在用户的计算机上将其设为 cookie。站点应该要求每个表单都包含该伪随机 值(作为表单值和 cookie 值)。当一个 POST 请求被发给站点时,只有表单值和 cookie 值相同时,该请求才会被认为是有效的。当攻击者以一个用户的名义提交表单时,他只能修改该表单的值。攻击者不能读取任何发自该服务器的数据或者修改 cookie 值,这是同源策略的缘故。这意味着,虽然攻击者可以用表单发送任何他想要的值,但是他却不能修改或者读取存储在该 cookie 中的值。因为 cookie 值和表单值必须是相同的,所 以除非攻击者能猜出该伪随机值,否则他就无法成功地提交表单。以 PHP 为例,我们可以在服务端首先生成随机数: 12 | 13 | ```php 14 |   19 | ``` 20 | 21 | 在表单里增加 Hash 值,以认证这确实是用户发送的请求。 22 | 23 | ``` 24 | 27 |   
28 |      29 |      30 |     ”> 31 |      32 |   
33 | ``` 34 | 35 | 然后在服务器端进行 Hash 值验证: 36 | 37 | ```php 38 | 50 | ``` 51 | 52 | 当然,我们也可以强制要求用户进行任何增删改的操作时都需要输入验证码,即进行用户交互,不过这样也就意味着很差的用户体验。 53 | 54 | ## 客户端防御 55 | 56 | 由于使攻击者成功地执行 CSRF 攻击的请求是由浏览器发出的,所以可以创建客户端工具来保护用户不受此种攻击。现有的工具 RequestRodeo 通过在客户和服务器之间充当代理来防止 CSRF 攻击。如果 RequestRodeo 发现了一个它认为是非法的请求,它会从该请求剥离验证信息。虽然这种方 式在很多情况下都能有效,但是它具有一些局限性。具体地说,当客户端使用了 SSL 认证或者使用 JavaScript 生成部分页面(因为 RequestRodeo 分析的是在浏览器显示之前的流经代理的那些数据)时,它就不起作用了。人们已经开发了一个浏览器插件,不仅可以使用户可以免受某些类型的 CSRF 攻击,并且还能克服以上所述的局限性,这个工具是作为 Firefox 浏览器的扩展实现的,其地址是http://www.cs.princeton.edu/˜wzeller/csrf/protector/。为了有效地防范 CSRF 攻击,用户需要下载安装这个扩展。该扩展会拦截所有的 HTTP 请求,并判断是否允许该 HTTP 请求。这个判断要用到下列规则。首 先,POST 请求之外的任何要求都是允许的。第二,如果发出请求的站点和目标站点符合同源策略的要求,那么该请求被允许。第三,如果发出请求的站点被允许 使用 Adobe 的跨域政策来建立一个请求的话,那么该请求也会被允许。如果我们的扩展拒绝一个请求,该扩展会通过一个常见的界面来提示用户(即 Firefox 所使用的 popup blocker)该请求已经被阻止,并且让用户选择是否将站点添加到一个白名单中。该扩展仅仅拦截 POST 请求。这意味着,它无法保护用户免受使用 GET 请求的 CSRF 攻击 阻止这种类型的攻击的唯一方法是不允许任何跨域 GET 请求,或只允许用户一次只能登录到一个站点,但是这两个限制可能是用户无法忍受的。 57 | -------------------------------------------------------------------------------- /Web 安全/CSRF/README.md: -------------------------------------------------------------------------------- 1 | # CSRF 跨站请求详解 2 | 3 | CSRF(Cross-Site Request Forgery,跨站点伪造请求)是一种网络攻击方式,该攻击可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击站点,从而在未授权的情况下执行在权限保护之下的操作,具有很大的危害性。具体来讲,可以这样理解 CSRF 攻击:攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。 4 | 5 | - token 机制。在 HTTP 请求中进行 token 验证,如果请求中没有 token 或者 token 内容不正确,则认为 CSRF 攻击而拒绝该请求。 6 | 7 | - 验证码。通常情况下,验证码能够很好的遏制 CSRF 攻击,但是很多情况下,出于用户体验考虑,验证码只能作为一种辅助手段,而不是最主要的解决方案。 8 | 9 | - referer 识别。在 HTTP Header 中有一个字段 Referer,它记录了 HTTP 请求的来源地址。如果 Referer 是其他网站,就有可能是 CSRF 攻击,则拒绝该请求。但是,服务器并非都能取到 Referer。很多用户出于隐私保护的考虑,限制了 Referer 的发送。在某些情况下,浏览器也不会发送 Referer,例如 HTTPS 跳转到 HTTP。 10 | 11 | CSRF (Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。CSRF 与 XSS 在攻击手段上有点类似,都是在客户端执行恶意代码,有些文章中认为 CSRF 与 XSS 的区别在于 CSRF 不注重于获取用户 Cookie,笔者认为可能还有区别在于 CSRF 不仅可以在源站发起攻击,还可以引导用户访问其他危险网站的同时发起攻击。XSS 全程是跨站脚本攻击,即攻击者向某个 Web 页面中插入恶意的 JavaScript 脚本,而当普通用户访问时,该恶意脚本自动执行而从盗取用户的 Cookie 等信息。对于 XSS 的防御手段主要就是输入检查与输出检查,譬如对用户输入的文本框内容进行 <、> 这样的特殊字符检查。而输出检查则是指对于输出到网页的内容进行过滤或者编解码,譬如使用 HTML 编码将 < 转义。CSRF 为跨站请求伪造,其与 XSS 有点类似,不过区别在于 CSRF 不一定依赖于 JavaScript,并且不仅可以在源站发起攻击,还有可能当用户访问恶意网站时引导其访问原网站。CSRF 攻击是源于 WEB 的隐式身份验证机制,WEB 的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的。对于 CSRF 的防御也分为服务端防御与客户端防御两种,服务端防御典型的譬如给某个页面添加随机数,使得无法从第三方页面直接提交。在客户端防御的话可以利用譬如 Firefox 提供的一些检查工具。注意,CSRF 并没有打破同源策略。 12 | 13 | 以下面的这个例子来说:银行网站 A,它以 GET 请求来完成银行转账的操作,如:`http://www.mybank.com/Transfer.php?toBankId=11&money=1000`危险网站 B,它里面有一段 HTML 的代码如下: 14 | 15 | ``` 16 | 17 | ``` 18 | 19 | 银行网站 A 违反了 HTTP 规范,使用 GET 请求更新资源。在访问危险网站 B 的之前,你已经登录了银行网站 A,而 B 中的``以 GET 的方 式请求第三方资源(这里的第三方就是指银行网站了,原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站 A 的 Cookie 发出 Get 请求,去获取资源 “http://www.mybank.com/Transfer.php?toBankId=11& money=1000”,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作。参考[深入解析跨站请求伪造漏洞:原理剖析 (](http://netsecurity.51cto.com/art/200812/102951_1.htm)中所述,XSS 与 CSRF 的区别在于: 20 | 21 | - XSS 攻击需要 JavaScript,而 CSRF 攻击不需要。 22 | - XSS 攻击要求站点接受恶意代码,而对于 CSRF 攻击来说,恶意代码位于第三方站点上。过滤用户的输入可以防止恶意代码注入到某个站点,但是它无阻止法恶意代码在第三方站点上运行。 23 | 24 | ## 原因浅析 25 | 26 | CSRF 攻击是源于 WEB 的隐式身份验证机制,WEB 的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的。假设 Alice 访问了一个恶意站点 M,该站点提供的内容中的 JavaScript 代码或者图像标签会导致 Alice 的浏览器向站点 T 发送一个 HTTP 请求。由于该请求是发给站点 T 的,所以 Alice 的浏览器自动地给该请求附上与站点 T 对应的该会话 cookie 的 sid。站点 T 看到该请求时,它就能通过该 cookie 的推断出:该请求来自 Alice,所以站点 T 就会对 Alice 的帐户执行所请求的操作。这样,CSRF 攻击就能得逞了。其他大多数 Web 认证机制也面临同样的问题。例如,HTTP BasicAuth 机制会要求 Alice 告诉浏览器她在站点 T 上的用户名和口令,于是浏览器将用户名和口令附加到之后发给站点 T 的请求中。当然,站点 T 也 可能使用客户端 SSL 证书,但这也面临同样的问题,因为浏览器也会将证书附加到发给站点 T 的请求中。类似的,如果站点 T 通过 IP 地址来验证 Alice 的身 份的话,照样面临 CSRF 攻击的威胁。总之,只要身份认证是隐式进行的,就会存在 CSRF 攻击的危险,因为浏览器发出请求这一动作未必是受用户的指使。原则上,这种威胁可以通过对每个发送至该 站点的请求都要求用户进行显式的、不可欺骗的动作(诸如重新输入用户名和口令)来消除,但实际上这会导致严重的易用性问题。大部分标准和广泛应用的认证机 制都无法防止 CSRF 攻击,所以我们只好另外探求一个实用的解决方案。 27 | -------------------------------------------------------------------------------- /密码与编码/公钥/PKI.md: -------------------------------------------------------------------------------- 1 | PKI ( Public Key Infrastructure )指的是公钥基础设施。CA ( Certificate Authority )指的是认证中心。PKI 从技术上解决了网络通信安全的种种障碍。CA 从运营、管理、规范、法律、人员等多个角度来解决了网络信任问题。由此,人们统称为 “ PKI/CA ”。从总体构架来看,PKI/CA 主要由最终用户、认证中心和注册机构来组成。 2 | 3 | KCS 全称是 Public-Key Cryptography Standards,是由 RSA 实验室与其它安全系统开发商为促进公钥密码的发展而制订的一系列标准,PKCS 目前共发布过 15 个标准。常用的有: PKCS#7 Cryptographic Message Syntax Standard PKCS#10 Certification Request Standard PKCS#12 Personal Information Exchange Syntax Standard 4 | 5 | X.509 是常见通用的证书格式。所有的证书都符合为 Public Key Infrastructure (PKI) 制定的 ITU-T X509 国际标准。 6 | 7 | PKCS#7 常用的后缀是: .P7B .P7C .SPC PKCS#12 常用的后缀有: .P12 .PFX X.509 DER 编码 (ASCII) 的后缀是: .DER .CER .CRT X.509 PAM 编码 (Base64) 的后缀是: .PEM .CER .CRT .cer/.crt 是用于存放证书,它是 2 进制形式存放的,不含私钥。.pem 跟 crt/cer 的区别是它以 Ascii 来表示。pfx/p12 用于存放个人证书 / 私钥,他通常包含保护密码,2 进制方式 p10 是证书请求 p7r 是 CA 对证书请求的回复,只用于导入 p7b 以树状展示证书链 (certificate chain),同时也支持单个证书,不含私钥。 8 | 9 | 一 用 openssl 创建 CA 证书的 RSA 密钥 (PEM 格式 ): openssl genrsa -des3 -out ca.key 1024 10 | 11 | 二用 openssl 创建 CA 证书 (PEM 格式, 假如有效期为一年 ): openssl req -new -x509 -days 365 -key ca.key -out ca.crt -config openssl.cnf openssl 是可以生成 DER 格式的 CA 证书的,最好用 IE 将 PEM 格式的 CA 证书转换成 DER 格式的 CA 证书。 12 | 13 | 三 x509 到 pfx pkcs12 -export –in keys/client1.crt -inkey keys/client1.key -out keys/client1.pfx 14 | 15 | 四 PEM 格式的 ca.key 转换为 Microsoft 可以识别的 pvk 格式。pvk -in ca.key -out ca.pvk -nocrypt -topvk 五 PKCS#12 到 PEM 的转换 openssl pkcs12 -nocerts -nodes -in cert.p12 -out private.pem 验证 openssl pkcs12 -clcerts -nokeys -in cert.p12 -out cert.pem 六 从 PFX 格式文件中提取私钥格式文件 (.key) openssl pkcs12 -in mycert.pfx -nocerts -nodes -out mycert.key 七 转换 pem 到到 spc openssl crl2pkcs7 -nocrl -certfile venus.pem -outform DER -out venus.spc 用 -outform -inform 指定 DER 还是 PAM 格式。例如: openssl x509 -in Cert.pem -inform PEM -out cert.der -outform DER 八 PEM 到 PKCS#12 的转换,openssl pkcs12 -export -in Cert.pem -out Cert.p12 -inkey key.pem 16 | 17 | 密钥库文件格式【Keystore 】 18 | 19 | 格式 : JKS 扩展名 : .jks/.ks 描述 : 【Java Keystore 】密钥库的 Java 实现版本,provider 为 SUN 特点 : 密钥库和私钥用不同的密码进行保护 20 | 21 | 格式 : JCEKS 扩展名 : .jce 描述 : 【JCE Keystore 】密钥库的 JCE 实现版本,provider 为 SUN JCE 特点 : 相对于 JKS 安全级别更高,保护 Keystore 私钥时采用 TripleDES 22 | 23 | 格式 : PKCS12 扩展名 : .p12/.pfx 描述 : 【PKCS #12 】个人信息交换语法标准 特点 : 1、包含私钥、公钥及其证书 2、密钥库和私钥用相同密码进行保护 24 | 25 | 格式 : BKS 扩展名 : .bks 描述 : Bouncycastle Keystore】密钥库的 BC 实现版本,provider 为 BC 特点 : 基于 JCE 实现 26 | 27 | 格式 : UBER 扩展名 : .ubr 描述 : 【Bouncycastle UBER Keystore 】密钥库的 BC 更安全实现版本,provider 为 BC 28 | 29 | 证书文件格式【Certificate 】 格式 : DER 扩展名 : .cer/.crt/.rsa 30 | 31 | 描述 : 【ASN .1 DER 】用于存放证书 特点 : 不含私钥、二进制 32 | 33 | 格式 : PKCS7 扩展名 : .p7b/.p7r 描述 : 【PKCS #7 】加密信息语法标准 34 | 35 | 特点 : 1、p7b 以树状展示证书链,不含私钥 2、p7r 为 CA 对证书请求签名的回复,只能用于导入 36 | 37 | 格式 : CMS 扩展名 : .p7c/.p7m/.p7s 描述 : 【Cryptographic Message Syntax 】 特点 : 1、p7c 只保存证书 2、p7m : signature with enveloped data 3、p7s:时间戳签名文件 38 | 39 | 格式 : PEM 扩展名 : .pem 描述 : 【Printable Encoded Message 】 特点 : 1、该编码格式在 RFC1421 中定义,其实 PEM 是【Privacy-Enhanced Mail 】的简写,但他也同样广泛运用于密钥管理 2、ASCII 文件 3、一般基于 base 64 编码 4. Apache 用到的 CA 证书链就是 PEM 格式, 它实际上可保存普通多个 X509 证书 (.cer), 将每个证书简单加在一起就可以了 40 | 41 | 格式 : PKCS10 扩展名 : .p10/.csr 描述 : 【PKCS #10 】公钥加密标准【Certificate Signing Request 】 特点 : 1、证书签名请求文件 2、ASCII 文件 3、CA 签名后以 p7r 文件回复 42 | 43 | 格式 : SPC 扩展名 : .pvk/.spc 描述 : 【Software Publishing Certificate 】 特点 : 微软公司特有的双证书文件格式,经常用于代码签名,其中 1、pvk 用于保存私钥 2、spc 用于保存公钥 44 | -------------------------------------------------------------------------------- /Web 安全/XSS/防御修复.md: -------------------------------------------------------------------------------- 1 | # XSS 防御与修复 2 | 3 | # Content Security Policy 4 | 5 | Github 使用 Electron 构建编辑器 Atom,其使用了 CSP 来限制潜在的 XSS 代码执行: 6 | 7 | ```html 8 | // index.html 9 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | ``` 21 | 22 | The script-src 'self' 'unsafe-eval', means that JavaScript from the same origin as well as code created using an eval like construct will by be executed. However, any inline JavaScript is forbidden. 23 | 24 | In a nutshell, the JavaScript from “index.js” would be executed in the following sample, the alert(1) however not, since it is inline JavaScript: 25 | 26 | ```js 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | ``` 38 | 39 | # React 40 | 41 | 笔者一直是坚定地 React 技术栈的使用者,因此也会关注 React 应用安全相关的话题。笔者在我自己的脚手架的第三层级也使用了大量的服务端渲染/同构直出的技术,而本文即是阐述该方法可能存在的某个 XSS 漏洞。服务端渲染即允许我们在服务端进行 HTML 渲染,并且在服务端请求部分应用数据追加到页面上然后随着页面一起返回给用户,从而减少用户的首屏等待时间,并且对于搜索引擎有更友好的优化。 42 | 43 | 不过如果有安全背景的朋友肯定已经能够察觉到问题了,直接将数据不经过滤地放到页面上势必会带来潜在的安全问题,譬如我们最常用的同构页面的代码: 44 | 45 | ```js 46 | export default (html, initialState = {}, scripts = [], styles = []) => { 47 | return ` 48 | 49 | 50 | 51 | 52 | 53 | ${styleMapper(styles)} 54 | 55 | 56 |
${html}
57 | 58 | ${scriptMapper(scripts)} 59 | 62 | 63 | `; 64 | }; 65 | ``` 66 | 67 | 我们直接使用`JSON.stringfy`将 JavaScript 对象转化为了 JSON 字符串,然后以全局变量的方式插入到了页面中。不过如果你要序列化的对象是如下这样呢: 68 | 69 | ```json 70 | { 71 | "user": { 72 | "username": "NodeSecurity", 73 | "bio": "as" 74 | } 75 | } 76 | ``` 77 | 78 | 你就会很开心的看到你得到了某个弹窗。关于 XSS 的知识点笔者不在这里赘述,虽然我们的后台开发人员肯定也在他们的接口层与数据库层完成了敏感字段过滤,不过千里之堤毁于蚁穴,我们不能放过任何一处有可能产生问题的地方。 79 | 80 | 对于 XSS 的防御也并不是新鲜的话题,著名的[Open Web Application Security Project](https://www.owasp.org/index.php/About_OWASP)项目就为我们提供了很多关于[防止 XSS 攻击](https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet)的建议,概括而言,我们需要在应用中做到如下几点: 81 | 82 | - 所有的用户输入都需要经过 HTML 实体编码,这里 React 已经帮我们做了[很多](https://facebook.github.io/react/docs/introducing-jsx.html#jsx-prevents-injection-attacks),它会在运行时动态创建 DOM 节点然后填入文本内容(你也可以强制设置 HTML 内容,不过这样比较危险) 83 | 84 | - 当你打算序列化某些状态并且传给客户端的时候,你同样需要进行 HTML 实体编码 85 | 86 | Yahoo 的工程师已经提供了一个 [Serialize JavaScript](https://github.com/yahoo/serialize-javascript) 模块帮我们轻松地进行 JSON 转码与过滤,我们可以直接使用 `npm install --save serialize-javascript` 导入该模块,然后使用`serialize`方法替代内置的`JSON.stringify`方法: 87 | -------------------------------------------------------------------------------- /软件安全/逆向工程/99~参考资料/Proxy 代理(二次修改).md: -------------------------------------------------------------------------------- 1 | > 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码,原文地址 [mp.weixin.qq.com](https://mp.weixin.qq.com/s?__biz=MzIyMjQ3OTE5MA==&mid=2247483738&idx=1&sn=1d53007e7805d88e5841a582718f0e16&chksm=e82d9763df5a1e75e59b27c3b6772b78eeb2b9ccd219df09362b8a4ac7f455766d8e76f6b362&mpshare=1&scene=1&srcid=030205ef041Dql3QXB3GY2bT&sharer_sharetime=1646203661515&sharer_shareid=56da189f782ce62249ab4f6494feca50&version=3.1.20.90367&platform=mac#rd) 2 | 3 | ### Proxy(二次修改) 4 | 5 | > `Proxy` 二次封装,js 逆向补环境,修复了昨天的 **bug**,挺尴尬的 6 | 7 | ``` 8 | (function () { 9 | function set_traverse_object(tarrget, obj, recursion_layers) { 10 | recursion_layers -= 1; 11 | console.log(); 12 | for (let prop in obj) { 13 | const value = obj[prop]; 14 | const tg_name = `${tarrget}.${prop.toString()}`; 15 | const value_type = get_value_type(value); 16 | if (value && value_type === "object" && recursion_layers >= 1) { 17 | set_traverse_object(tg_name, value, recursion_layers); 18 | continue 19 | } 20 | if (value && value.toString() !== '[object Object]') { 21 | console.log(`setter hook->${tg_name}; value-> ${value}; typeof-> ${value_type}`); 22 | continue 23 | } 24 | console.log(`setter hook->${tg_name}; value-> ${value}; typeof-> ${value_type}\n`) 25 | 26 | } 27 | } 28 | 29 | function new_handel(target_name, obj, number) { 30 | returnnewProxy(obj, my_handler(target_name, number)) 31 | } 32 | 33 | function get_value_type(value) { 34 | if (Array.isArray(value)) { 35 | return'Array' 36 | } 37 | returntypeof value; 38 | } 39 | 40 | function my_handler(target_name, number) { 41 | return { 42 | set: function (obj, prop, value) { 43 | const value_type = get_value_type(value); 44 | const tg_name = `${target_name}.${prop.toString()}`; 45 | 46 | if (value && value_type === "object") { 47 | set_traverse_object(tg_name, value, number) 48 | } else { 49 | console.log(`setter hook->${tg_name}; value-> ${value}; typeof-> ${value_type}`) 50 | } 51 | returnReflect.set(obj, prop, value); 52 | }, 53 | get: function (obj, prop) { 54 | const tg_name = `${target_name}.${prop.toString()}`; 55 | const value = Reflect.get(obj, prop); 56 | let value_type = get_value_type(value); 57 | if (value && value_type === 'object') { 58 | return new_handel(tg_name, value, number) 59 | } 60 | console.log(`getter hook->${tg_name}; value-> ${value}; typeof-> ${value_type}\n`); 61 | return value 62 | } 63 | } 64 | } 65 | 66 | window = newProxy(window, my_handler(Object.keys({window})[0], 30)); 67 | }()); 68 | 69 | 70 | ``` 71 | 72 | > 代理效果如下,深层代理,更直观 73 | 74 | ``` 75 | getter hook->window.document.cookie; value-> undefined; typeof-> undefined 76 | 77 | getter hook->window.location.href; value-> https://mobile.pinduoduo.com/; typeof-> string 78 | 79 | getter hook->window.location.port; value-> ; typeof-> string 80 | 81 | { addEventListener: [Function: addEventListener] } addEventListener 82 | getter hook->window.document.addEventListener; value-> function () { 83 | }; typeof-> function 84 | 85 | getter hook->window.document.addEventListener; value-> function () { 86 | }; typeof-> function 87 | 88 | getter hook->window.document.addEventListener; value-> function () { 89 | }; typeof-> function 90 | 91 | 92 | ``` 93 | -------------------------------------------------------------------------------- /Web 安全/编码校验/自动填充.md: -------------------------------------------------------------------------------- 1 | # AutoComplete | 自动填充 2 | 3 | 自动填充(Autofill )是个非常重要的特性,它能帮助用户节省很多填写表单的时间,Google 也曾调查得出过结论[users complete forms up to 30% faster](https://developers.google.com/web/updates/2015/06/checkout-faster-with-autofill?hl=en)。我们首先来讨论下自动填充的工作原理,以及如何构建跨浏览器的自动填充表单。 4 | 5 | 早年各个浏览器之间对于自动填充并没有统一的标准,后来 HTML5 标准中加入了对于`autocomplete`属性的支持,以协调浏览器对于表单域的识别。最初`autocomplete`属性仅支持`on`与`off`两种取值,默认情况下是会启动自动填充功能以方便浏览器会将用户提交过的表单值记录下来以便复用。后续 HTML 标准中允许加入更多的[标识值](https://html.spec.whatwg.org/multipage/forms.html#autofill),这些标识值会更加精确地告诉浏览器应将哪些记录值对应到哪些表单。譬如我们经常需要在网页上填写地址信息,如果我们希望浏览器能够记录下常用地址信息并且自动补全,那么可以使用如下声明方式: 6 | 7 | ```html 8 | 12 | 17 | 22 | 27 | 32 | ``` 33 | 34 | 其他常见的自动填充的使用场景还包括电话号码、邮箱地址、即时通信账户等,完整的自动填充标识声明规范为: 35 | 36 | ``` 37 | [section-](optional) [shipping|billing](optional) [home|work|mobile|fax|pager](optional) [autofill field name] 38 | ``` 39 | 40 | 其中`[home|work|mobile|fax|pager]`仅被用于电话、邮箱等场景。而完整的应用场景譬如是填写收货地址的收件人电话时: 41 | 42 | ``` 43 | 44 | 45 | ``` 46 | 47 | 最后,我们来看下自动填充在笔者电脑上的现实效果: 48 | 49 | ## 安全威胁 50 | 51 | 自动填充是个非常方便地浏览器特性,不过该特性在 Chrome 上也会存在一定的信息泄露的风险。Chrome 最近才修复了某个久负盛名[漏洞](https://yoast.com/autocomplete-security/)。简单而言,黑客能够利用自动填充窃取你并不想提交给该网站的信息,就如下面这个动图: 52 | 53 | Github 用户 [haampie](https://gist.githubusercontent.com/haampie/3ba6ebb5fd9f71d2f8e9fb841e52740d/raw/d2278671539ab5987a184603b0b3dd9942ba66e0/inject.js) 使用如下脚本演示了该漏洞: 54 | 55 | ```js 56 | var autocompletes = [ 57 | "name", 58 | "honorific-prefix", 59 | "given-name", 60 | "additional-name", 61 | "family-name", 62 | "honorific-suffix", 63 | "nickname", 64 | "username", 65 | "new-password", 66 | "current-password", 67 | "organization-title", 68 | "organization", 69 | "street-address", 70 | "address-line1", 71 | "address-line2", 72 | "address-line3", 73 | "address-level4", 74 | "address-level3", 75 | "address-level2", 76 | "address-level1", 77 | "country", 78 | "country-name", 79 | "postal-code", 80 | "cc-name", 81 | "cc-given-name", 82 | "cc-additional-name", 83 | "cc-family-name", 84 | "cc-exp", 85 | "cc-exp-month", 86 | "cc-exp-year", 87 | "cc-csc", 88 | "cc-type", 89 | "transaction-currency", 90 | "transaction-amount", 91 | "language", 92 | "bday", 93 | "bday-day", 94 | "bday-month", 95 | "bday-year", 96 | "sex", 97 | "url", 98 | "photo", 99 | "tel", 100 | "tel-country-code", 101 | "tel-national", 102 | "tel-area-code", 103 | "tel-local", 104 | "tel-local-prefix", 105 | "tel-local-suffix", 106 | "tel-extension", 107 | "impp", 108 | ]; 109 | 110 | emailField.addEventListener("focus", function () { 111 | var wrap = autocompletes.reduce(function (wrapper, field) { 112 | var input = document.createElement("input"); 113 | 114 | // Make them not focussable 115 | input.tabIndex = -1; 116 | input.autocomplete = field; 117 | 118 | wrapper.appendChild(input); 119 | return wrapper; 120 | }, document.createElement("div")); 121 | 122 | // Hide the wrapper 123 | wrap.classList.add("hidden"); 124 | form.appendChild(wrap); 125 | 126 | // Inject the autocompletes once 127 | this.removeEventListener("focus", arguments.callee); 128 | }); 129 | ``` 130 | 131 | 作者是建议大家关闭 Chrome 的自动填充功能,主要步骤为: 132 | 133 | - 进入 Chrome 设置:`chrome://settings/autofill` 134 | - 关闭当前模态窗口 135 | - 反选自动填充选项 136 | -------------------------------------------------------------------------------- /渗透测试/README.md: -------------------------------------------------------------------------------- 1 | # 渗透测试 2 | 3 | 本部分我们会讨论常见的综合渗透测试工具,常用的渗透测试流程,技巧等内容。 4 | 5 | 渗透测试可以从不同的维度进行分类, 6 | 7 | ## 按信息获取方式分类 8 | 9 | | 黑盒渗透(BlackBox ) | 从目标网络的外部进行渗透模拟的,除了被测试目标的已知公开信息外,不提供任何其他信息 | 10 | | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | 11 | | 白盒渗透(White Box ) | 渗透测试者可以通过正常的渠道,向请求测试的机构获得目标网络系统的各种资料,包括网络拓扑结构、用户账户、操作系统、服务器类型、网络设备、代码片段等信息 | 12 | | 灰盒测试(Gray Box ) | 介于二者之间, | 13 | 14 | ## 按目标对象分类 15 | 16 | | 主机操作系统渗透 | 对目标网络中的 Windows、Linux、Unix 等操作系统主机进行渗透测试 | 17 | | ---------------- | ---------------------------------------------------------------------- | 18 | | 数据库渗透测试 | 对 MS-SQL、Oracle、MySQL 等数据库系统进行渗透测试, | 19 | | 网站程序渗透 | 渗透的目标网络系统都对外提供了 Web 网页、E-Mail 邮箱等网络程序应用服务 | 20 | | 网络设备渗透 | 对各种硬件防火墙、入侵检测系统、路由器和交换机等网络设备进行渗透测试 | 21 | 22 | ## 按网络环境分类 23 | 24 | | 外网 | | 25 | | ---- | --- | 26 | | 内网 | | 27 | 28 | # 渗透测试步骤 29 | 30 | ### 1. 分析目标网站内容及功能步骤 31 | 32 | (1) 首先确定网站采用何种语言编写 . 或者是否有混用的情况 . 此处可以通过查看网站源文件, 观察网站链接, 捕获提交请求等方式获取 . 33 | 34 | (2) 爬行网站目录, 使用工具对网站目录进行爬行, 可以辅助上一步让结果更加精准 . 将爬行结果存档, 如果可以, 此处应分析出网站是否使用通用程序, 如果是, 记录下来 . 进行下一步 . 35 | 36 | (3) 根据上一步的爬行结果, 对网站根目录或者关键目录进行暴力目录探测, 如果网站为通用程序, 判读是否有过二次开发, 如非通用程序, 在探测到的目录中寻找关键目录及文件 . 37 | 38 | 此步骤详细测试方法 39 | 40 | ①  输入并访问一些不可能存在的文件或目录名, 再输入并访问一些通过目录爬行已知存在的目录及文件名, 从而得知服务器如何处理无效资源 . 41 | 42 | ②  使用网站爬行到的结果作为此步骤暴力目录探测的依据, 扫描关键目录或全部 . 43 | 44 | ③  确定服务器如何处理文件无法找到的回应, 并使用关键字技术来处理这些回应 . 从而判断有效资源及无效资源 . 45 | 46 | ④  收集此步骤暴力扫描得到的结果, 并手工检测探测到目录的有效性 . 47 | 48 | ⑤  重复以上步骤, 得到更多更关键的目录及文件 . 49 | 50 | (4) 通过上面步骤, 得到一个完整的网站目录结构, 以及枚举到的所有目录名称, 文件名称及文件扩展名 . 了解网站开发人员的命名思路, 确定其命名规则, 推测出更多的目录及文件名 . 51 | 52 | 此步骤详细测试方法 53 | 54 | ² 检查整个列表中的文件命名规则, 判读其命名依据, 如发现几个部分内容相同的文件名 ,addnews.php,viewnews.php, 那么我们就可以尝试是否存在 editnews.php,delnews.php, 通常只要查看几个文件名, 就可以推测出网站开发人员的命名习惯, 根据其个人风格, 开发者可能采用各种命名方法, 如冗长式 (addnewuser.php), 简洁式 (adduser.php), 缩写式 (addusr.php), 或者更加模糊的命名方式 (addu.php). 了解开发者使用的命名习惯有助于推测出尚未确定内容的准确名称 . 55 | 56 | ² 有些不同内容的命名方案使用数字和日期作为标识符, 通过他们可以轻易推测出隐藏的内容 . 静态页面经常采用这种命名方式 . 例如 PKAV.NET 的团队博客中, 文章里所展示的图片的文件名没有被重新定义, 采用了日期加数字递增的命名方案, 如 2012 年 12 月 12 号发布的文章中的图片分别为 1.jpg,2.jpg,3.jpg. 那么这些图片的路径就是 /2012-12-12/1.jpg,/2012-12-12/2.jpg, /2012-12-12/3.jpg, 此时我们在博客上发布了一篇内容加密的文章, 只有团队成员才知道密码, 但是黑客们根据博客以往发布文章的命名规则推测出了这些图片的准确地址, 从而通过图片内容泄漏了文章的大致概念 . 57 | 58 | ² 检查所有客户端代码, 如 HTML 及 JS 代码, 寻找任何隐藏了服务器端的线索, 以及隐藏的表单元素等 . 认证检查注释内容, 往往能带给我们惊喜, 如部分通用程序会在网站首页放置一个通向网站管理后台的链接, 但网站管理人员不希望这个链接被正常访问者所得知, 于是将内容注释, 我们可以通过查看 HTML 代码得知此具体地址, 还有大多数的管理后台中所调用的 JS 中常常会存储着后台所有功能模块的链接地址, 但在判断了当前用户权限后将其隐藏起来, 我们也可以通过直接查看 JS 代码的方式得知具体的内容, 还有一些开发者会在注释内容中记录一些敏感信息, 我多次从注释信息中得到数据库的名称, 甚至可以得到数据库的具体连接信息 ,SQL 查询语句等 . 59 | 60 | ² 把我们通过推测枚举出来的内容放在其他地方进行尝试。如文件 a.php 在 /111/ 这个目录下存在, 那么我们可以尝试在 /222/ 这个目录下尝试是否存在相同文件, 把所有枚举出来的文件名使用一些常规后缀来尝试访问, 如 index.php 这个文件已知存在, 我们可以使用 txt,bak,src,inc,tmp 等后缀进行尝试, 如尝试 index.txt,index.bak 或者添加在原有后缀基础上 ,index.php.bak 等 . 这样可以帮助我们获取这些文件的未编译版本, 开发版本或者备份文件, 还可以通过网站使用的语言来推测, 如 java 使用的 .cs 后缀等 . 61 | 62 | ² 搜索开发者使用的开发工具或者文本编辑器创建的临时文件。如 SVN 的 .svn/entries, 又或者 Ultraedit 这类文本编辑器的自动备份功能创建的 .bak 文件, 被大量使用的 .tmp 后缀, 以及 index.php~1 这样的遗留文件, 这些都是可能会发现重要线索的细节, 测试中一定不要遗漏这些步骤 . 63 | 64 | ² 将上述的步骤自动化, 提取所有存在的文件名以及目录, 后缀的词干信息, 在所有目录下进行自动化批量探测 . 65 | 66 | ² 如果通过以上步骤已经确定一种统一的命名方案, 那么就可以使用此命名规则在整个站点下进行测试 . 67 | 68 | ² 不断重复以上步骤, 获取更多的关键信息, 根据时间及个人想象力尽情发挥 ! 69 | 70 | (5) 利用公共信息, 如搜索引擎, 站点快照信息, 以及其网站所使用的程序开发商公布的一些使用文档等信息近一步获取目标站点更多信息 . 71 | 72 | a. 使用几种不同的搜索引擎和网站快照来获取目标站点的索引和历史内容记录 . 73 | 74 | b. 使用高级搜索技巧如 75 | 76 | site:www.hao123.com ( 返回此目标站点被搜索引擎抓取收录的所有内容 ) 77 | 78 | site:www.hao123.com 关键词 ( 返回此目标站点被搜索引擎抓取收录的包含此关键词的所有页面 . 此处我们可以将关键词设定为, 网站后台, 管理后台, 密码修改, 密码找回等 .) site:www.hao123.com inurl:admin.php ( 返回目标站点的地址中包含 admin.php 的所有页面, 可以使用 admin.php,manage.php 或者其他关键词来寻找关键功能页面 ) 79 | 80 | link:www.hao123.com ( 返回所有包含目标站点链接的页面, 其中包括其开发人员的个人博客, 开发日志, 或者开放这个站点的第三方公司, 合作伙伴等 ) 81 | 82 | related:www.hao123.com ( 返回所有与目标站点 ” 相似 ” 的页面, 可能会包含一些通用程序的信息等 .) 83 | 84 | c. 在搜索时不要只使用网页的搜索功能, 可以尝试如图片, 新闻等功能来定位具体信息 . 85 | 86 | d. 从搜索引擎的快照中寻找一些关键信息, 如程序报错信息可以会泄漏网站具体路径, 或者一些快照中会保存一些测试用的测试信息, 比如说某个网站在开发了后台功能模块的时候, 还没给所有页面增加权限鉴别, 此时被搜索引擎抓取了快照, 即使后来网站增加了权限鉴别, 但搜索引擎的快照中仍会保留这些信息 . 87 | 88 | e. 通过搜索引擎获取目标站点的子域名, 得到更多的功能, 如有些网站经常使用 admin 这个子域名作为其管理后台, 如 admin.hao123.com 等 . 89 | 90 | (6) 收集网站开发者信息, 如网站的开发人员, 管理维护人员等在互联网上的一些信息 . 91 | 92 | ①  列出网站中得到的所有开发及维护人员的姓名和邮件地址及其他联系方式, 其中包含从网站联系功能中获取到的, 从 HTML 或 JS 中的注释信息中得到的, 已经内容页面上获取到的。 93 | 94 | ②  使用上面介绍的一些高级搜索技巧, 查找这些人在互联网上发布的与目标站点有关的一切信息, 分析并发现有用的信息, 如我曾经在用这个方法获取某国内大型网站的开发人员的信息时, 竟发现他把他开发过的所有功能页面的源代码都放在一个公开的网站中, 可以随意下载, 包含了这个网站的数据库链接信息等关键内容, 从而导致我轻松获取到这个大型网站的权限 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Contributors][contributors-shield]][contributors-url] 2 | [![Forks][forks-shield]][forks-url] 3 | [![Stargazers][stars-shield]][stars-url] 4 | [![Issues][issues-shield]][issues-url] 5 | [![license: CC BY-NC-SA 4.0](https://img.shields.io/badge/license-CC%20BY--NC--SA%204.0-lightgrey.svg)][license-url] 6 | 7 | 8 |
9 |

10 | 11 | Logo 12 | 13 | 14 |

InfoSecurity & PenTest

15 | 16 |

17 | 信息安全与渗透测试 18 |
19 | 在线阅读 >> 20 |
21 |
22 | 速览手册 23 | · 24 | InfoSecurity-Notesrt Bug 25 | · 26 | 参考资料 27 |

28 |

29 | 30 | 31 | 32 | # Introduction | 前言 33 | 34 | 安全是当今 IT 相关头条新闻的一个重要话题。经常出现的系统漏洞和安全补丁以及病毒和蠕虫是每个使用计算机的人都耳熟能详的名词。因为几乎每台计算机系统都连接到另外的计算机或者连接到 Internet,因此确保这些计算机的安全,对于减少入侵、数据窃取或丢失、误用甚至对第三方的责任而言是至关重要的。确保安全即使对于没有连接到网络的独立的计算机也是很重要的。必须自可信赖的来源安装应用程序,比如 经过验证的并检查过病毒的光盘。对应用程序数据也必须同样小心。例如,对于可以执行强大的宏语言 或者引入非法数据的软件程序包(office 套件等等),其软件缺陷可能会被利用来执行任意的代码。因此,应用程序数据在拷贝到计算机之前必须经过完整性检查。可以通过将数据放置在一个安全的地方来控制对 系统的访问(当然,不考虑来自已授权人员的攻击)。 35 | 36 | 当系统连接到网络并向其他计算机提供服务(有意地或无意地)时,事情会变得更为棘手。在那种情况下,数据可能不只是来自系统管理员,因为客户机程序要使用所提供的服务,而系统漏洞可能会让入侵者控制 计算机。这就是为什么安全是从开始计划直到拆除系统的整个系统生命周期中最基本的问题。 37 | 38 | ![mindmap](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/item/20230418154054.png) 39 | 40 | > 本书的精排目录导航版请参考 [https://ng-tech.icu/books/InfoSecurity-Notes](https://ng-tech.icu/books/InfoSecurity-Notes)。 41 | 42 | ## 数据安全与系统安全 43 | 44 | 从宏观层面上,安全可以被分为系统安全与数据安全两个层面。数据安全和系统安全可以分开来考虑。数据安全通常被认为是确保以下方面的所有努力: 45 | 46 | - 机密性(Confidentiality )。 47 | - 完整性(Integrity )。 48 | - 可用性(Availability )。 49 | 50 | 综合起来,这些被称作是存储在计算机上的数据的 CIA。对 `/etc/passwd` 等配置数据的保护可以归类为数据安全。 51 | 52 | 系统安全指的是计算机平台本身。美国 NationalInformation Systems Security Glossary 以获得链接)对系统安全的定义如下:对信息系统的保护,防止未授权的访问及对信息(不论是存储中的、正在处理的还是正在传输的)的修改,并防止对授权用户服务的拒绝或对未授权用户服务的允许,包括那些检测、记录和反击此类威胁的措施。重要的是要认识到系统安全强调的是一个反复的过程,这个过程包括应用安全补丁、经常审计、控制,同时最起码要有一个安全的系统配置。就此而言,不可能保证绝对的安全,也不可能提供百分之百安全的服务。目标更应该是在安全性、系统可用性和维护这个安全层级所需要的努力这三者之间找到一个折衷点。这个折衷取决于安全对于存储在计算机中的数据来说的重要性以及这些数据预期的使用情形。 53 | 54 | # Nav | 关联导航 55 | 56 | # About | 关于 57 | 58 | 59 | 60 | ## Contributing 61 | 62 | Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. 63 | 64 | 1. Fork the Project 65 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 66 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 67 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 68 | 5. Open a Pull Request 69 | 70 | 71 | 72 | ## Acknowledgements 73 | 74 | - [Awesome-Lists](https://github.com/wx-chevalier/Awesome-Lists): 📚 Guide to Galaxy, curated, worthy and up-to-date links/reading list for ITCS-Coding/Algorithm/SoftwareArchitecture/AI. 💫 ITCS-编程/算法/软件架构/人工智能等领域的文章/书籍/资料/项目链接精选。 75 | 76 | - [Awesome-CS-Books](https://github.com/wx-chevalier/Awesome-CS-Books): :books: Awesome CS Books/Series(.pdf by git lfs) Warehouse for Geeks, ProgrammingLanguage, SoftwareEngineering, Web, AI, ServerSideApplication, Infrastructure, FE etc. :dizzy: 优秀计算机科学与技术领域相关的书籍归档。 77 | 78 | ## Copyright & More | 延伸阅读 79 | 80 | 笔者所有文章遵循[知识共享 署名 - 非商业性使用 - 禁止演绎 4.0 国际许可协议](https://creativecommons.org/licenses/by-nc-nd/4.0/deed.zh),欢迎转载,尊重版权。您还可以前往 [NGTE Books](https://ng-tech.icu/books-gallery/) 主页浏览包含知识体系、编程语言、软件工程、模式与架构、Web 与大前端、服务端开发实践与工程架构、分布式基础架构、人工智能与深度学习、产品运营与创业等多类目的书籍列表: 81 | 82 | [![NGTE Books](https://s2.ax1x.com/2020/01/18/19uXtI.png)](https://ng-tech.icu/books-gallery/) 83 | 84 | 85 | 86 | 87 | [contributors-shield]: https://img.shields.io/github/contributors/wx-chevalier/InfoSecurity-Notes.svg?style=flat-square 88 | [contributors-url]: https://github.com/wx-chevalier/InfoSecurity-Notes/graphs/contributors 89 | [forks-shield]: https://img.shields.io/github/forks/wx-chevalier/InfoSecurity-Notes.svg?style=flat-square 90 | [forks-url]: https://github.com/wx-chevalier/InfoSecurity-Notes/network/members 91 | [stars-shield]: https://img.shields.io/github/stars/wx-chevalier/InfoSecurity-Notes.svg?style=flat-square 92 | [stars-url]: https://github.com/wx-chevalier/InfoSecurity-Notes/stargazers 93 | [issues-shield]: https://img.shields.io/github/issues/wx-chevalier/InfoSecurity-Notes.svg?style=flat-square 94 | [issues-url]: https://github.com/wx-chevalier/InfoSecurity-Notes/issues 95 | [license-shield]: https://img.shields.io/github/license/wx-chevalier/InfoSecurity-Notes.svg?style=flat-square 96 | [license-url]: https://github.com/wx-chevalier/InfoSecurity-Notes/blob/master/LICENSE.txt 97 | -------------------------------------------------------------------------------- /_sidebar.md: -------------------------------------------------------------------------------- 1 | - 1 99~参考资料 [2] 2 | - [1.1 2023~《云安全攻防入门》](/99~参考资料/2023~《云安全攻防入门》/README.md) 3 | 4 | - [1.2 斯托林斯~《密码编码学与网络安全》 [5]](/99~参考资料/斯托林斯~《密码编码学与网络安全》/README.md) 5 | - [1.2.1 信息安全(一)——概述](/99~参考资料/斯托林斯~《密码编码学与网络安全》/信息安全(一)——概述.md) 6 | - [1.2.2 信息安全(三)——对称密码体制](/99~参考资料/斯托林斯~《密码编码学与网络安全》/信息安全(三)——对称密码体制.md) 7 | - [1.2.3 信息安全(二)——密码学](/99~参考资料/斯托林斯~《密码编码学与网络安全》/信息安全(二)——密码学.md) 8 | - [1.2.4 信息安全(五)——消息认证、数字签名及PGP](/99~参考资料/斯托林斯~《密码编码学与网络安全》/信息安全(五)——消息认证、数字签名及PGP.md) 9 | - [1.2.5 信息安全(四)——公私钥密码体制](/99~参考资料/斯托林斯~《密码编码学与网络安全》/信息安全(四)——公私钥密码体制.md) 10 | - [2 INTRODUCTION](/INTRODUCTION.md) 11 | - [3 Web 安全 [7]](/Web%20安全/README.md) 12 | - [3.1 CSRF [3]](/Web%20安全/CSRF/README.md) 13 | - [3.1.1 攻击实例](/Web%20安全/CSRF/攻击实例.md) 14 | - [3.1.2 漏洞检测](/Web%20安全/CSRF/漏洞检测.md) 15 | - [3.1.3 防御修复](/Web%20安全/CSRF/防御修复.md) 16 | - [3.2 SQL 注入 [1]](/Web%20安全/SQL%20注入/README.md) 17 | - [3.2.1 SQL 注入工具](/Web%20安全/SQL%20注入/SQL%20注入工具.md) 18 | - [3.3 XSS [2]](/Web%20安全/XSS/README.md) 19 | - [3.3.1 漏洞检测](/Web%20安全/XSS/漏洞检测.md) 20 | - [3.3.2 防御修复](/Web%20安全/XSS/防御修复.md) 21 | - [3.4 文件上传漏洞](/Web%20安全/文件上传漏洞/README.md) 22 | 23 | - [3.5 浏览器安全](/Web%20安全/浏览器安全/README.md) 24 | 25 | - [3.6 点击劫持](/Web%20安全/点击劫持/README.md) 26 | 27 | - [3.7 编码校验 [2]](/Web%20安全/编码校验/README.md) 28 | - [3.7.1 代码混淆](/Web%20安全/编码校验/代码混淆.md) 29 | - [3.7.2 自动填充](/Web%20安全/编码校验/自动填充.md) 30 | - 4 密码与编码 [2] 31 | - 4.1 公钥 [1] 32 | - [4.1.1 PKI](/密码与编码/公钥/PKI.md) 33 | - [4.2 数据安全](/密码与编码/数据安全/README.md) 34 | 35 | - [5 渗透测试 [1]](/渗透测试/README.md) 36 | - [5.1 分布式扫描器 [4]](/渗透测试/分布式扫描器/README.md) 37 | - [5.1.1 分布式扫描调度](/渗透测试/分布式扫描器/分布式扫描调度.md) 38 | - [5.1.2 半自动化扫描](/渗透测试/分布式扫描器/半自动化扫描.md) 39 | - [5.1.3 基础扫描](/渗透测试/分布式扫描器/基础扫描.md) 40 | - [5.1.4 数字资产管理](/渗透测试/分布式扫描器/数字资产管理.md) 41 | - [6 爬虫 [5]](/爬虫/README.md) 42 | - [6.1 Scrapy](/爬虫/Scrapy/README.md) 43 | 44 | - 6.2 去重 [2] 45 | - [6.2.1 URL 归一化](/爬虫/去重/URL%20归一化.md) 46 | - [6.2.2 文本相似度](/爬虫/去重/文本相似度.md) 47 | - [6.3 反爬虫 [1]](/爬虫/反爬虫/README.md) 48 | - [6.3.1 人机识别](/爬虫/反爬虫/人机识别.md) 49 | - 6.4 系统设计 [3] 50 | - [6.4.1 分布式爬虫](/爬虫/系统设计/分布式爬虫.md) 51 | - [6.4.2 动态爬虫](/爬虫/系统设计/动态爬虫.md) 52 | - [6.4.3 反爬虫对抗](/爬虫/系统设计/反爬虫对抗.md) 53 | - [6.5 验证码绕过 [1]](/爬虫/验证码绕过/README.md) 54 | - [6.5.1 滑动验证](/爬虫/验证码绕过/滑动验证.md) 55 | - [7 网络安全 [1]](/网络安全/README.md) 56 | - [7.1 TCP 安全](/网络安全/TCP%20安全.md) 57 | - 8 软件安全 [2] 58 | - [8.1 安全更新 [1]](/软件安全/安全更新/README.md) 59 | - [8.1.1 TUF](/软件安全/安全更新/TUF/README.md) 60 | 61 | - 8.2 逆向工程 [1] 62 | - 8.2.1 99~参考资料 [24] 63 | - [8.2.1.1 2022 某安卓 Crackme 流程分析](/软件安全/逆向工程/99~参考资料/2022%20某安卓%20Crackme%20流程分析.md) 64 | - [8.2.1.2 Frida Android hook _ Sakura の blog](/软件安全/逆向工程/99~参考资料/Frida%20Android%20hook%20_%20Sakura%20の%20blog.md) 65 | - [8.2.1.3 Js Ast 一部曲:高完整度还原某 V5 的加密](/软件安全/逆向工程/99~参考资料/Js%20Ast%20一部曲:高完整度还原某%20V5%20的加密.md) 66 | - [8.2.1.4 Js Ast 二部曲:某 V5 “绝对不可逆加密” 一探究竟](/软件安全/逆向工程/99~参考资料/Js%20Ast%20二部曲:某%20V5%20“绝对不可逆加密”%20一探究竟.md) 67 | - [8.2.1.5 Protobuf 协议逆向解析 APP 爬虫 ](/软件安全/逆向工程/99~参考资料/Protobuf%20协议逆向解析%20-%20APP%20爬虫%20.md) 68 | - [8.2.1.6 Proxy 代理(二次修改)](/软件安全/逆向工程/99~参考资料/Proxy%20代理(二次修改).md) 69 | - [8.2.1.7 Python 爬虫进阶必备 _ Js 逆向之补环境到底是在补什么?](/软件安全/逆向工程/99~参考资料/Python%20爬虫进阶必备%20_%20Js%20逆向之补环境到底是在补什么?.md) 70 | - [8.2.1.8 app 逆向 平头哥实战(某农产品 app)](/软件安全/逆向工程/99~参考资料/app%20逆向%20平头哥实战(某农产品%20app).md) 71 | - [8.2.1.9 frida 免 root hook](/软件安全/逆向工程/99~参考资料/frida%20免%20root%20hook.md) 72 | - [8.2.1.10 getByte 算法分析与还原 SeeFlowerX](/软件安全/逆向工程/99~参考资料/getByte%20算法分析与还原%20-%20SeeFlowerX.md) 73 | - [8.2.1.11 js 破解之补浏览器环境的两种监控方式](/软件安全/逆向工程/99~参考资料/js%20破解之补浏览器环境的两种监控方式.md) 74 | - [8.2.1.12 mtgsig2.1 版本之 a5 算法分析](/软件安全/逆向工程/99~参考资料/mtgsig2.1%20版本之%20a5%20算法分析.md) 75 | - [8.2.1.13 unidbg 算法还原术 · 某民宿 app 篇 · 上卷](/软件安全/逆向工程/99~参考资料/unidbg%20算法还原术%20·%20某民宿%20app%20篇%20·%20上卷.md) 76 | - [8.2.1.14 unidbg 算法还原术 · 某民宿 app 篇 · 下卷](/软件安全/逆向工程/99~参考资料/unidbg%20算法还原术%20·%20某民宿%20app%20篇%20·%20下卷.md) 77 | - [8.2.1.15 unidbg 算法还原术 · 某民宿 app 篇 · 中卷](/软件安全/逆向工程/99~参考资料/unidbg%20算法还原术%20·%20某民宿%20app%20篇%20·%20中卷.md) 78 | - [8.2.1.16 【2021 春节】安卓中级题逆向总结](/软件安全/逆向工程/99~参考资料/【2021%20春节】安卓中级题逆向总结.md) 79 | - [8.2.1.17 【转载】Unidbg Hook 大全 SeeFlowerX](/软件安全/逆向工程/99~参考资料/【转载】Unidbg%20Hook%20大全%20-%20SeeFlowerX.md) 80 | - [8.2.1.18 分享一个 Android 通用 svc 跟踪以及 hook 方案——Frida Seccomp](/软件安全/逆向工程/99~参考资料/分享一个%20Android%20通用%20svc%20跟踪以及%20hook%20方案——Frida-Seccomp.md) 81 | - [8.2.1.19 大猿搜题 sign so 加密参数分析|unidbg](/软件安全/逆向工程/99~参考资料/大猿搜题%20sign%20so%20加密参数分析|unidbg.md) 82 | - [8.2.1.20 某乎请求头签名算法分析](/软件安全/逆向工程/99~参考资料/某乎请求头签名算法分析.md) 83 | - [8.2.1.21 某咖啡 app 加密参数分析进阶版](/软件安全/逆向工程/99~参考资料/某咖啡%20app%20加密参数分析进阶版.md) 84 | - [8.2.1.22 深度剖析 ja3 指纹及突破](/软件安全/逆向工程/99~参考资料/深度剖析%20ja3%20指纹及突破.md) 85 | - [8.2.1.23 爬虫之 某生鲜 APP 加密参数逆向分析](/软件安全/逆向工程/99~参考资料/爬虫之%20-%20某生鲜%20APP%20加密参数逆向分析.md) 86 | - [8.2.1.24 逆向分析反调试 + ollvm 混淆的 Crackme](/软件安全/逆向工程/99~参考资料/逆向分析反调试%20+%20ollvm%20混淆的%20Crackme.md) -------------------------------------------------------------------------------- /软件安全/逆向工程/99~参考资料/某乎请求头签名算法分析.md: -------------------------------------------------------------------------------- 1 | > 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码,原文地址 [mp.weixin.qq.com](https://mp.weixin.qq.com/s?__biz=Mzg5NTY3MTc2Mg==&mid=2247483704&idx=1&sn=8e08162f0768fa6a793de5d761eff369&chksm=c00d8d85f77a04939dd5ce0481c8a8ca4426c25c7a1cd037f4568803f479bef2b355b80e6ee5&mpshare=1&scene=1&srcid=0201FpqYNSfgJft3lH6ugVUI&sharer_sharetime=1646873400933&sharer_shareid=56da189f782ce62249ab4f6494feca50&version=3.1.20.90367&platform=mac#rd) 2 | 3 | ## 前言 4 | 5 | - 小小白在这里给各位大佬拜个年了,祝各位大佬新年快乐,大吉大利,身体健康,技术更上一层楼 6 | - 本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除! 7 | 8 | ## 网站 9 | 10 | aHR0cHM6Ly93d3cuemhpaHUuY29tL3NlYXJjaD90eXBlPWNvbnRlbnQmcT1weXRob24= 11 | 12 | 加密定位 13 | 14 | 需要分析的接口以及加密参数  x-zse-96  如下图 15 | 16 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqP261tbMCynIBPQt7MibYoTg7w6oaJE391znh2kuGgvV1geA26cmTuicQ/640?wx_fmt=png) 17 | 18 | 直接搜关键字  x-zse-96,发现一个文件,点进去 19 | 20 | ![](https://mmbiz.qpic.cn/mmbiz_jpg/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqianSPE7iccYfRAmChrT8Pb5fr7uh6ASNwrvuudHicaPP5kuOcTMMSkCGw/640?wx_fmt=jpeg) 21 | 22 | 格式化后再搜索 x-zse-96,发现两个可疑入口,分别是这两个 23 | 24 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqibEE3P1z6zLKZgPX2wv25BwZxibQHQHV49ux1B4oKicGUEOnDou35IvUA/640?wx_fmt=png) 25 | 26 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqsyAnqgTljo9eq82vpN3EsulzjxAFK65IoLJQlibFoRrcg2cF5dwaWVQ/640?wx_fmt=png) 27 | 28 | 重新刷新网站,可以看到断点断在下图这个地方,选中执行函数可以发现加密入口就是这里 29 | 30 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqibF7O8e1MYGeHWDJ30Anzhbuc3RVVjSRJK0xLEyfJwiaMZqkXwc7l4Ow/640?wx_fmt=png) 31 | 32 | 加密分析 33 | 34 | s 明文数据: 35 | 36 | ``` 37 | s = '101_3_2.0+'(版本号) + 38 |     '/api/v4/search_v3?t=general&q=python&correction=1&offset=0&limit=20&filter_fields=&lc_idx=0&show_all_topics=0&search_source=Normal+'(接口后缀) + 39 |     '"AIAf1GdgbRSPTtoYPsJrpvRp_MB-_8SxwGQ=|1643717522"'(dc0 cookie) 40 | 41 | ``` 42 | 43 | 第一层加密 44 | 45 | ``` 46 |  l()(s) = '7dd6414484df2c210ddbb996c55cf64c' -> md5_str 47 | 48 | ``` 49 | 50 | 根据 js 逆向的一些小经验,32 位密文很容易想到 md5 签名加密,拿到在线 md5 加密测试网站去试试 51 | 52 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqmDktpMQiakWPUtWAbZ5sxcHJV5hLXSXQuIs8WkHUz5WFRPJgViaImNpA/640?wx_fmt=png) 53 | 54 | perfect,完美对应上,由此可知,第一层加密就是原生的 md5 加密 55 | 56 | 第二层加密 57 | 58 | ``` 59 | a()(md5_str) = 'a0xqSQe8cLYfSHYyThxBHD90k0xxN9xqf_tqr6UqH9Op' 60 | 61 | ``` 62 | 63 | 选中 a(),点进去,会进入到这个函数,加密参数正是第一层加密得到的 md5 字符串,如图所示 64 | 65 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqicQ18dvO6q7hh3Nkh67FnK8N4pezrRpR6Q3MJLlnaIzCyk8gzwz8exQ/640?wx_fmt=png) 66 | 67 | 然后就单步跟,跟到这里就先别跟了,这里正是 jsvmp 循环一条条执行指令的地方,下面的代码会根据时间来检测调试 68 | 69 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqElkf0BictGG3jAZ4xicVZmX4icAyibp5yUMH2puf8pBHBZfyx6Od8Jiboqg/640?wx_fmt=png) 70 | 71 | 然后就在 35865 行打上 log 输出断点,把 this.C 索引值跟 this 对象里面的值都给打印出来,注意要把 window 除去,不然会缺数据,索引值方便后序调试可用 72 | 73 | ``` 74 | "索引:", this.C, " 值:", JSON.stringify(this, function(key, value) {if (value == window) {return undefined} return value}) 75 | 76 | ``` 77 | 78 | 慢慢等待输出结束,掉头发的逆向之路就可以开始了 79 | 80 | 直接在输出的 log 日志里面搜索加密生成的密文 81 | 82 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqqBedKV7Or179TRnwf5tVblVYTiaTyNb7PV77MgliaT6HTExzPCc40BxQ/640?wx_fmt=png) 83 | 84 | 这个 vmp 生成的加密参数是分成 11 组来计算的,每 4 个一组 85 | 86 | 这里面有一个固定不变的字符串,就是这个玩意 87 | 88 | ``` 89 | fix_str = "RuPtXwxpThIZ0qyz_9fYLCOV8B1mMGKs7UnFHgN3iDaWAJE-Qrk2ecSo6bjd4vl5" 90 | 91 | ``` 92 | 93 | 拿第一部分  a0xq 举个例子,看看他是如何生成的,其他的都差不多 94 | 95 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqnkKicqyvUDjf4jEiabbYtHe2hiaUEQzBzryR0w5E5nm82QibjU7iciaeuhEQ/640?wx_fmt=png) 96 | 97 | fix_str[13] = 'q' 98 | 99 | q 就是这样来的,每一个字符都是通过索引那个固定字符串得到的,所以,接下来,就该来寻找索引下标是怎么生成的,向上寻找,看到这个 100 | 101 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPq2WS6CopzpBAXicVGIhzONuUCJmzMy6HtU6VNs6eicyLmwibk4ORLs4vSQ/640?wx_fmt=png) 102 | 103 | 3433258 >> 18 = 13 104 | 105 | 这里的 18 是固定的,其实判断是不是固定的数字,只需要对比两个控制台里面 log 输出的对应分析就可以很清楚的知道哪些是固定不变的了 106 | 107 | 再来搜索 3433258  这个数字怎么来的 108 | 109 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqGCD3GB5xTEDU7sYdxKozljpbPYJvrDONwBqia4eD90drKfic4lfiaAhoQ/640?wx_fmt=png) 110 | 111 | 可以很清晰的看得到,下面这几种运算都可以得到这个数字,那怎么判断是哪一种运算得到的,我的办法是:调试 112 | 113 | ``` 114 | 1. 25386 + 3407872 = 3433258 115 | 2. 25386 ^ 3407872 = 3433258 116 | 3. 25386 | 3407872 = 3433258 117 | 118 | ``` 119 | 120 | 重新打开一个浏览器打开链接,在 log 输出相同地方换上一个条件断点,断点的条件是 this.C = 342,具体跟进去看看他到底是进行的什么运算 121 | 122 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqPFfM2tE8tHVwt5WCCUs24IVqL0fplic07c9KSzCkia2Sv1Xib29vOeBBg/640?wx_fmt=png) 123 | 124 | 这里这一步我就直接说了,是第三种,| 运算得到的,知道运算符之后,又要去分析两个参与运算的值是怎么得到的,这里就需要慢慢去一步步去逆向搜索分析了,所有参与运算的值都可以用这种同样的方法搜索分析得到 125 | 126 | 这部分所有的运算流程都在下面了,请各位大佬们自行慢慢对比 log 输出去参悟,理解 127 | 128 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqlSua5j0qpucYCb4k33FK0eVLwQfYPCdy6KYj55phlME30owTVAnVaw/640?wx_fmt=png) 129 | 130 | 最后验证: 131 | 132 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqJzhLgSsIW2WyP9xgeOPovrUIrwJibwkGuVO81toNlGI3dJu2EQVNTrg/640?wx_fmt=png) 133 | 134 | ![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqic5ibgIQVlBOjYKCP6VTalmSUMUrxLsXv5P5c2T76feqnZmDyHhaW45A/640?wx_fmt=png) 135 | 136 | 可以发现,算法还原下来只有短短的 50 几行,而且最后本地生成的加密参数跟浏览器生成的完全一致,完结撒花![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqqozA2Q2bROFIyQf9pNECcly4F8z9gvicniciagmbt63mYSdsBKFfyDxFw/640?wx_fmt=png)![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqqozA2Q2bROFIyQf9pNECcly4F8z9gvicniciagmbt63mYSdsBKFfyDxFw/640?wx_fmt=png)![](https://mmbiz.qpic.cn/mmbiz_png/EiaqCy3pb5k3LlZI6mUqIP5k6v7cPBHPqqozA2Q2bROFIyQf9pNECcly4F8z9gvicniciagmbt63mYSdsBKFfyDxFw/640?wx_fmt=png) 137 | -------------------------------------------------------------------------------- /软件安全/逆向工程/99~参考资料/Protobuf 协议逆向解析 - APP 爬虫 .md: -------------------------------------------------------------------------------- 1 | > 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码,原文地址 [www.yuanrenxue.com](https://www.yuanrenxue.com/app-crawl/parse-protobuf.html) 2 | 3 | > 在做 APP 抓取时,会发现有的 APP Response 回来的数据有 “加密”。不知道返回的内容是什么。 4 | 5 | 在做 APP 抓取时,会发现有的 APP Response 回来的数据有 “加密”。不知道返回的内容是什么。 6 | 7 | 本文偏长,理论基础偏多。 8 | 9 | 如下: 10 | 11 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress0-1583398723.jpg)![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress2-1583398724.png) 12 | 13 | 如上,内容不是明文的,没办法解析数据。 14 | 15 | APP 常见的对数据加密有三种情况: 16 | 17 | 第一种是,用诸如 AES 这类加密算法对数据加密,然后在 APP 里用 key 进行解密,这类的数据解密的难度不是很大,弄清楚是用的什么加密算法就能反解。 18 | 19 | 第二种是,用 “私有” 协议把数据序列化,只有了解该协议的细节才有可能把数据反序列化出来。这个的难度较大,没有功底,头发撸白都不一定撸出来。游戏和大厂 APP 盛行搞一个自己的私有协议来交换数据。 20 | 21 | 第三种是,用第三方厂商的协议来数据序列化,自己搞不出来私有协议的就选用第三方厂商的。比如用 Google 的 Protobuf ,来做数据序列化,也就是数据 “加密”。 22 | 23 | **今天聊的就是第三种,Protobuf 的数据反解析。** 24 | 25 | 先来看一个 Protobuf ,做数据序列化的直观例子。 26 | 27 | 比如一个 APP 的 Response 原先是以 json 格式返回的: 28 | 29 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress10-1583398725.png) 30 | 31 | 这样很容易被解析,用 Protobuf 把上面数据序列化再传输就变成类似这样: 32 | 33 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress10-1583398725-1.png) 34 | 35 | 这张图片只是样例这样就没法直接解析数据,如果了解 Protobuf 协议的话就能加快反解速度。 36 | 37 | 所以还得从头来聊 Protobuf 。 38 | 39 | ## 一、什么是 Protobuf? 40 | 41 | Protobuf 是 Google 开发的一套数据存储传输协议,跟 xml 和 json 一样的,都是用来储存和传输数据的。  因为 Protobuf 能够把数据压缩得很小,所以传输数据就比 xml 和 json 快几倍,Protobuf 解析数据的速度也比它两快,所以在数据网络传输上,用 Protobuf 而不用 json 就有点受欢迎了。 42 | 43 | 不过 Protobuf 储存、压缩、传输效率比 json 好,付出的代价就是用法麻烦,不像 json.loads() json.dumps()  一下就搞定了这么简单。Protobuf 有一套自己的语法。不了解 Protobuf 协议语法和用法的话也无法反解数据。 44 | 45 | **先了解下 Protobuf 序列化和反序列化的整个流程:** 46 | 47 | **1.1. 先定义一个 Protobuf  语法文件( .proto 文件)** 48 | 49 | 该语法文件用来说明要传输哪些字段、字段的数据类型、数据间的嵌套关系这些。比如一个 APP 要返回的数据有电话号码,姓名,年龄这三个字段,你就需要把这三个字段定义在 .proto 文件里,并且指明他们的数据类型,比如姓名和电话是字符串,年龄是整型。 50 | 51 | **1.2. 使用 Protobuf 提供的工具编译该语法文件。** 52 | 53 | 用工具编译 .proto 文件的目的是,把 .proto 文件编译成代码,工具会根据该 .proto 文件自动生产代码。  这个代码就是用来做数据序列化和反序列化的。 54 | 55 | **1.3. 服务端用第 2 步中的代码,把 “明文” 数据序列化,变成 “密文” 后,返回给 APP。** 56 | 57 | **1.4. APP 客户端用第 2 步中的代码,把 “密文” 数据反序列化,就 “解密” 成明文拉。** 58 | 59 | 理论说多了很迷糊,再整个完整的直观例子: 60 | 61 | ## 二、Protobuf 正向开发流程 62 | 63 | 2.1. 先配置 Protobuf 环境 https://github.com/protocolbuffers/protobuf/releases/ 64 | 65 | 在 Google 官方 github 地址下载 Protobuf  。 66 | 67 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress8-1583398725.png) 68 | 69 | 下载一个 Protobuf 编译器和一个调用编译器的接口程序,我们这里用 Python 版的。如上图,箭头所示,解压 protoc.win64.zip 里有个 protoc 命令就是编译器。PS:注意要给 protoc 配置上环境变量,不然没法全局调用该命令。 70 | 71 | 解压 protobuf-python-3.11.4.zip 这是 Python 模块,cd 到 python 目录里运行 Python setup.py build 和 Python setup.py install 安装 Python 模块。Python 编辑器里运行 import google.protobuf 可以检测是否安装成功。 72 | 73 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress4-1583398726.png) 74 | 75 | example 目录里有官方写好的 Python 示例程序 和   示例 .proto 文件。 76 | 77 | 2.2. 写一个 .proto  语法文件语法文件怎么写,要根据具体的传输数据来定制, 78 | 79 | 比如按照 example 里的示例,如果要传输的数据是如下格式: 80 | 81 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress6-1583398730.png) 82 | 83 | 那么定义的 .proto 语法文件就如下: 84 | 85 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress6-1583398731.png) 86 | 87 | 这样就定义好了一个 .proto 语法文件,语法文件如何定义要根据传输数据的不同而变。更全的 protobuf 语法 可以看这个,有网友翻译成了中文版的。https://colobu.com/2017/03/16/Protobuf3-language-guide/ 88 | 89 | 2.3. 使用第一步中下载的 protoc 编译器来编译 .proto 文件 90 | 91 | protoc –python_out=. addressbook.proto 92 | 93 | 上述表示把 addressbook.proto 文件编译成 Python 版的。如果文件语法错误,在编译的时候会有提示。编译完后,会多出一个. py 文件 94 | 95 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress1-1583398731.png) 96 | 97 | 我们就可以调用这个 .py 来序列化上面的数据。2.4. 开始序列化数据 98 | 99 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress5-1583398732.png) 100 | 101 | print 里输出的就是序列化(“加密”)后的数据。2.5. 对序列化后的数据进行反序列化(“解密”) 102 | 103 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress0-1583398732.png) 104 | 105 | 反序列化就把数据又还原啦。 106 | 107 | 上述过程就是一个完整的正向数据 protobuf 序列化过程。我们可以看出来,主要是定义一个 .proto 文件,然后把它编译生成代码。  后面就主要用这个代码来做序列化和反序列化工作。 108 | 109 | ## 三、逆向解析 Protobuf 110 | 111 | 正向过程比较轻松,因为对方即有 .proto 文件,也有序列化代码,也知道要传输的数据样式。但是逆向这个过程,APP 里是没有 .proto 文件的,APP 里是有反序列化的代码,但是看得也头晕。那该怎么办呢? 112 | 113 | 借助工具,我们使用上面下载的 protoc 编译工具,这个工具提供反解析参数 114 | 115 | protoc –decode_raw < people.bin 116 | 117 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress10-1583398732.png) 118 | 119 | 如上,使用 –decode_raw 参数就能把序列化后的数据,反序列化(解密)出来。上面只是把数据还原了,那如果我们要完全把 .proto 文件也还原出来该怎么办呢? 120 | 121 | 如果 APP 发送 request 的数据要先序列化后再发送给服务端的话,那爬虫要做的事情就不只反序列化,还要能序列化。做序列化是一个正向的过程,按照上面流程,必须先要有 .proto 文件才行。 122 | 123 | 所以继续还原 .proto 文件,还原 .proto 是个体力活和细致活。就是参照反解析出来的数据,还原出 .proto 文件。 124 | 125 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress9-1583398733.jpg) 126 | 127 | 上面这张图是关键,看懂了就能还原出来。上图左边是反解析出来的数据,中中间是参照左边写出来的 .proto 文件,右边是人家原本的 .proto 文件。左边和中间图对比可以看出,就是根据左边的字段,挨个把字段重新定义出来就 OK 啦。 128 | 129 | 遇到  “{” 就定义一个 message。中间和右边图对比可以看出,变量的名字是无关紧要的,数据类型还原正确就行。变量赋值的那些 1,2,3 是标识号,message 里同一层级的标识号不能重复,一般是按照变量顺序从 1 开始递增。标识号的数字是个关键,数字写错了反解析出来的数据会不对。这样就把 .proto 文件还原出来了,然后按照正向流程又去编译,就可以使用它去序列化(“加密”)和反序列化(“解密”)APP 数据了。 130 | 131 | **APP 逆向抓取相关阅读** 132 | 133 | [爬虫之 - 某生鲜 APP 加密参数逆向分析](https://www.yuanrenxue.com/app-crawl/app-crawl-1.html) 134 | 135 | [搞定某 APP 的 TCP 抓包,并实现 Hook 抓取](https://www.yuanrenxue.com/crawler/frida-call-so-directly.html) 136 | 137 | [不还原 token 算法抓取 APP 最简单的 Hook 方法](https://www.yuanrenxue.com/crawler/crawl-app-frida-rpc.html) 138 | 139 | **PS: 再广而告之一声** 140 | 141 | 我有在系统性的教爬虫技术 APP 逆向抓取技术 JS 高阶逆向技术群控抓取技术 142 | 143 | 利用爬虫技术年挣 10 万被动收入的思维和实践方法如果你想爬虫技术进阶,或找一份不错的爬虫工作,我想是能够有帮助的。感兴趣可以加我私人微信,备注:学习。PS,费用不便宜,非诚勿扰。 144 | 145 | ![](https://www.yuanrenxue.com/wp-content/uploads/2020/03/beepress0-1583398733.jpeg) 146 | 147 | ![](https://www.yuanrenxue.com/wp-content/uploads/2019/05/yrx_banner_pic.jpg) 148 | 149 | _我的公众号:**猿人学 Python** 上会分享更多心得体会,敬请关注。_ 150 | 151 | _*** 版权申明: 若没有特殊说明,文章皆是猿人学 yuanrenxue.com 原创,没有猿人学授权,请勿以任何形式转载。***_ 152 | -------------------------------------------------------------------------------- /爬虫/验证码绕过/滑动验证.md: -------------------------------------------------------------------------------- 1 | # 爬虫中滑动验证的绕过 2 | 3 | 验证是常见的反爬虫策略之一,在现在的很多站点中我们会引入滑动验证的方式,来校验访问者的真实性。譬如下面著名的 jQuery 滑动插件: 4 | 5 | ![](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/item/20230418222010.png) 6 | 7 | 在模拟登陆时,我们往往需要绕过这样的滑动验证,而基于 Puppeteer 的动态爬虫也给予了便利;往往我们需要进行以下步骤:移动到滑条中间,按下鼠标,移动鼠标,释放鼠标。 8 | 9 | ```js 10 | const puppeteer = require("puppeteer"); 11 | 12 | async function run() { 13 | const browser = await puppeteer.launch({ 14 | headless: false, 15 | defaultViewport: { width: 1366, height: 768 }, 16 | }); 17 | const page = await browser.newPage(); 18 | 19 | await page.goto("http://kthornbloom.com/slidetosubmit/"); 20 | await page.type('input[name="name"]', "Puppeteer Bot"); 21 | await page.type('input[name="email"]', "js@automation.com"); 22 | 23 | let sliderElement = await page.$(".slide-submit"); 24 | let slider = await sliderElement.boundingBox(); 25 | 26 | let sliderHandle = await page.$(".slide-submit-thumb"); 27 | let handle = await sliderHandle.boundingBox(); 28 | 29 | await page.mouse.move( 30 | handle.x + handle.width / 2, 31 | handle.y + handle.height / 2 32 | ); 33 | await page.mouse.down(); 34 | await page.mouse.move(handle.x + slider.width, handle.y + handle.height / 2, { 35 | steps: 10, 36 | }); 37 | await page.mouse.up(); 38 | 39 | await page.waitFor(3000); 40 | 41 | // success! 42 | 43 | await browser.close(); 44 | } 45 | 46 | run(); 47 | ``` 48 | 49 | 在实际的案例中,我们可以以淘宝的注册界面为例: 50 | 51 | ```js 52 | const puppeteer = require("puppeteer"); 53 | 54 | async function run() { 55 | const browser = await puppeteer.launch({ 56 | headless: false, 57 | defaultViewport: { width: 1366, height: 768 }, 58 | }); 59 | const page = await browser.newPage(); 60 | 61 | await page.evaluateOnNewDocument(() => { 62 | Object.defineProperty(navigator, "webdriver", { 63 | get: () => false, 64 | }); 65 | }); 66 | 67 | await page.goto("https://world.taobao.com/markets/all/sea/register"); 68 | 69 | let frame = page.frames()[1]; 70 | await frame.waitForSelector(".nc_iconfont.btn_slide"); 71 | 72 | const sliderElement = await frame.$(".slidetounlock"); 73 | const slider = await sliderElement.boundingBox(); 74 | 75 | const sliderHandle = await frame.$(".nc_iconfont.btn_slide"); 76 | const handle = await sliderHandle.boundingBox(); 77 | await page.mouse.move( 78 | handle.x + handle.width / 2, 79 | handle.y + handle.height / 2 80 | ); 81 | await page.mouse.down(); 82 | await page.mouse.move(handle.x + slider.width, handle.y + handle.height / 2, { 83 | steps: 50, 84 | }); 85 | await page.mouse.up(); 86 | 87 | await page.waitFor(3000); 88 | 89 | // success! 90 | 91 | await browser.close(); 92 | } 93 | 94 | run(); 95 | ``` 96 | 97 | ![](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/item/20230418223711.png) 98 | 99 | 另一种常见的滑块则是如下这种拼图性质的滑块: 100 | 101 | ![](https://ngte-superbed.oss-cn-beijing.aliyuncs.com/item/20230418223738.png) 102 | 103 | ```js 104 | const puppeteer = require("puppeteer"); 105 | const Rembrandt = require("rembrandt"); 106 | 107 | async function run() { 108 | const browser = await puppeteer.launch({ 109 | headless: false, 110 | defaultViewport: { width: 1366, height: 768 }, 111 | }); 112 | const page = await browser.newPage(); 113 | 114 | let originalImage = ""; 115 | 116 | await page.setRequestInterception(true); 117 | page.on("request", (request) => request.continue()); 118 | page.on("response", async (response) => { 119 | if (response.request().resourceType() === "image") 120 | originalImage = await response.buffer().catch(() => {}); 121 | }); 122 | 123 | await page.goto("https://monoplasty.github.io/vue-monoplasty-slide-verify/"); 124 | 125 | const sliderElement = await page.$(".slide-verify-slider"); 126 | const slider = await sliderElement.boundingBox(); 127 | 128 | const sliderHandle = await page.$(".slide-verify-slider-mask-item"); 129 | const handle = await sliderHandle.boundingBox(); 130 | 131 | let currentPosition = 0; 132 | let bestSlider = { 133 | position: 0, 134 | difference: 100, 135 | }; 136 | 137 | await page.mouse.move( 138 | handle.x + handle.width / 2, 139 | handle.y + handle.height / 2 140 | ); 141 | await page.mouse.down(); 142 | 143 | while (currentPosition < slider.width - handle.width / 2) { 144 | await page.mouse.move( 145 | handle.x + currentPosition, 146 | handle.y + handle.height / 2 + Math.random() * 10 - 5 147 | ); 148 | 149 | let sliderContainer = await page.$(".slide-verify"); 150 | let sliderImage = await sliderContainer.screenshot(); 151 | 152 | const rembrandt = new Rembrandt({ 153 | imageA: originalImage, 154 | imageB: sliderImage, 155 | thresholdType: Rembrandt.THRESHOLD_PERCENT, 156 | }); 157 | 158 | let result = await rembrandt.compare(); 159 | let difference = result.percentageDifference * 100; 160 | 161 | if (difference < bestSlider.difference) { 162 | bestSlider.difference = difference; 163 | bestSlider.position = currentPosition; 164 | } 165 | 166 | currentPosition += 5; 167 | } 168 | 169 | await page.mouse.move( 170 | handle.x + bestSlider.position, 171 | handle.y + handle.height / 2, 172 | { steps: 10 } 173 | ); 174 | await page.mouse.up(); 175 | 176 | await page.waitFor(3000); 177 | 178 | // success! 179 | 180 | await browser.close(); 181 | } 182 | 183 | run(); 184 | ``` 185 | 186 | 这里我们采用了简单的图片对比的方式,即在滑动过程中,如果发现了有符合阈值的差异,则认为是已经滑动成功。 187 | 188 | # Cendertron 189 | 190 | 在 [Cendertron](https://github.com/wx-chevalier/Chaos-Scanner/tree/master/cendertron) 中,提供了一类特殊的 Slider Captcha Monkey,在传入的 SpiderOption 中添加如下参数即可: 191 | 192 | ```ts 193 | export interface SpiderOption { 194 | allowRedirect: boolean; 195 | depth: number; 196 | // 页面插件 197 | monkies?: { 198 | sliderCaptcha: { 199 | sliderElementSelector: string; 200 | sliderHandleSelector: string; 201 | }; 202 | }; 203 | } 204 | ``` 205 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | InfoSecurity-Series 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 34 | 38 | 40 | 45 | 46 |
47 | 64 | 97 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 143 | 144 | 145 | 146 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /软件安全/逆向工程/99~参考资料/分享一个 Android 通用 svc 跟踪以及 hook 方案——Frida-Seccomp.md: -------------------------------------------------------------------------------- 1 | > 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码,原文地址 [bbs.pediy.com](https://bbs.pediy.com/thread-271815.htm) 2 | 3 | > [原创] 分享一个 Android 通用 svc 跟踪以及 hook 方案——Frida-Seccomp 4 | 5 | # [](#一个android通用svc跟踪以及hook方案——frida-seccomp)一个 Android 通用 svc 跟踪以及 hook 方案——Frida-Seccomp 6 | 7 | # [](#效果:)效果: 8 | 9 | ## 对 openat 进行跟踪 10 | 11 | ![](https://bbs.pediy.com/upload/attach/202203/903162_55EERQXHHTXD4FW.jpg) 12 | 13 | ## 对 recvfrom 进行跟踪 14 | 15 | ![](https://bbs.pediy.com/upload/attach/202203/903162_AE84XGKCDB8RBY6.jpg) 16 | **在这里感谢珍惜大佬介绍的 seccomp 机制,推荐一波珍惜大佬的课程能学到很多有趣的骚操作。** 17 | 18 | # 什么是 seccomp 19 | 20 | [seccomp 沙箱机制介绍文章](http://pollux.cc/2019/09/22/seccomp%E6%B2%99%E7%AE%B1%E6%9C%BA%E5%88%B6%20&%202019ByteCTF%20VIP/#%E9%80%9A%E8%BF%87%E4%BD%BF%E7%94%A8%E8%AF%A5%E5%BA%93%E7%9A%84%E5%87%BD%E6%95%B0%E5%AE%9E%E7%8E%B0%E7%A6%81%E7%94%A8execve%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8) 21 | seccomp 是 Linux 内核提供的一种应用程序沙箱机制,主要通过限制进程的系统调用来完成部分沙箱隔离功能。seccomp-bpf 是 seccomp 的一个扩展,它可以通过配置来允许应用程序调用其他的系统调用。 22 | 23 | # 如何和 frida 结合 24 | 25 | ## 基本原理 26 | 27 | ``` 28 | 这是一个bpf规则: 29 | struct sock_filter filter[] = { 30 |         BPF_STMT(BPF_LD + BPF_W + BPF_ABS, 31 |                  (offsetof(struct seccomp_data, nr))), 32 |         BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1), 33 |         BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_TRAP), 34 |         BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW), 35 | }; 36 | 37 | ``` 38 | 39 | seccomp 的具体用法可以参考「**什么是 seccomp**」中的 seccomp 介绍文章。当返回规则设置为「SECCOMP_RET_TRAP」,目标系统调用时 seccomp 会产生一个 SIGSYS 系统信号并软中断,这时就可以通过捕获这个 SIGSYS 信号获得 svc 调用和打印具体参数。 40 | 41 | ## 如何脚本化安装 seccomp 规则呢 42 | 43 | 这里使用 Frida 的 API「CModule」,CModule 提供强大的动态编译功能可以让你在 JS 中写 C, 44 | **frida 文档中的示例** 45 | 46 | ``` 47 | const cm = new CModule(` 48 | #include void hello(void) { 49 |   printf("Hello World from CModule\\n"); 50 | } 51 | `); 52 | const hello = new NativeFunction(cm.hello, 'void', []); 53 | hello(); 54 | ``` 55 | 56 | ## 如何捕获异常 57 | 58 | 使用 Frida 的 API「**Process.setExceptionHandler**」即可捕获异常并在自己写的回调中进行数据处理。 59 | 数据处理的逻辑解释写在注释里啦。 60 | 61 | ``` 62 | // 异常处理 63 |     Process.setExceptionHandler(function (details) { 64 |         const current_off = details.context.pc - 4; 65 |         // 判断是否是seccomp导致的异常 读取opcode 010000d4 == svc 0 66 |         if (details.message == "system error" && details.type == "system" && hex(ptr(current_off).readByteArray(4)) == "010000d4") { 67 |             // 上锁避免多线程问题 68 |             lock(syscall_thread_ptr) 69 |             // 获取x8寄存器中的调用号 70 |             const nr = details.context.x8.toString(10); 71 |             let loginfo = "\n==================" 72 |             loginfo += `\nSVC[${syscalls[nr][1]}|${nr}] ==> PC:${addrToString(current_off)} P${Process.id}-T${Process.getCurrentThreadId()}` 73 |             // 构造线程syscall调用参数 74 |             const args = Memory.alloc(7 * 8) 75 |             args.writePointer(details.context.x8) 76 |             let args_reg_arr = {} 77 |             for (let index = 0; index < 6; index++) { 78 |                 eval(`args.add(8 * (index + 1)).writePointer(details.context.x${index})`) 79 |                 eval(`args_reg_arr["arg${index}"] = details.context.x${index}`) 80 |             } 81 |             // 获取手动堆栈信息 82 |             loginfo += "\n" + stacktrace(ptr(current_off), details.context.fp, details.context.sp).map(addrToString).join('\n') 83 |             // 打印传参 84 |             loginfo += "\nargs = " + JSON.stringify(args_reg_arr) 85 |             // 调用线程syscall 赋值x0寄存器 86 |             details.context.x0 = call_task(syscall_thread_ptr, args, 0) 87 |             loginfo += "\nret = " + details.context.x0.toString() 88 |             // 打印信息 89 |             call_thread_log(loginfo) 90 |             // 解锁 91 |             unlock(syscall_thread_ptr) 92 |             return true; 93 |         } 94 |         return false; 95 |     }) 96 | 97 | ``` 98 | 99 | ## 还有什么坑 100 | 101 | ### 1.syscall 调用 resume 102 | 103 | #### 问题描述 104 | 105 | 根据 Frida 文档介绍「**setExceptionHandler**」捕获异常后只需要让回调返回 true 就会 resume 原本的线程,但是其只是跳过了 svc 指令继续执行,实际上并不会执行 svc,这时候如果不执行 syscall 轻则导致 APP 数据异常,重则导致 APP 直接崩溃。所以在异常的回调中需要手动调用了 syscall 并赋值给 x0。 106 | 但这时候会发生个新的问题,因为在主线程开启 seccomp 后,主线程和其后创建出来的线程都会被 seccomp 规则约束,在异常处理函数直接调用 syscall 同样会被 seccomp 约束再次抛出异常,就形成了” 死锁 “了。 107 | 108 | #### 如何解决 109 | 110 | 可以注意到上面 “死锁” 部分描述,那我们在主线程被约束前,提前创建一个线程,这个线程就是不被约束的,同时受到线程池启发,我们让这个 syscall 线程循环接受任务,就能完成在一个没有约束的线程里进行 syscall 调用。 111 | 112 | ### 2. 堆栈回溯 113 | 114 | #### 问题描述 115 | 116 | 直接使用 Frida 的 API「**Thread.backtrace**」很容易导致崩溃,原因可能是 seccomp 规则或者「prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)」导致的权限收紧和 Frida 实现堆栈回溯功能冲突。 117 | 118 | #### 如何解决 119 | 120 | 手动实现堆栈回溯,原理是 Arm64 中每个函数都会在函数头部位置对 x29、x30 寄存器存入栈中,所以可以对 x29 不断读取往上回溯,最后得到完整的堆栈信息。 121 | **实现** 122 | 123 | ``` 124 | function stacktrace(pc, fp, sp) { 125 |     let n = 0, stack_arr = [], fp_c = fp; 126 |     stack_arr[n++] = pc; 127 |     const mem_region = call_thread_read_maps(sp); 128 |     while (n < MAX_STACK_TRACE_DEPTH) { 129 |         if (parseInt(fp_c.toString()) < parseInt(sp.toString()) || fp_c < mem_region.start || fp_c > mem_region.end) { 130 |             break 131 |         } 132 |         let next_fp = fp_c.readPointer() 133 |         let lr = fp_c.add(8).readPointer() 134 |         fp_c = next_fp 135 |         stack_arr[n++] = lr 136 |     } 137 |     return stack_arr; 138 | } 139 | 140 | ``` 141 | 142 | ### 3.「**Process.findModuleByAddress**」「**Process.enumerateModules**」类的 API 导致崩溃或找不到 Module 信息 143 | 144 | #### 问题描述 145 | 146 | 疑似同坑 2 的原因 147 | 148 | #### 如何解决 149 | 150 | 在 CModule 中手动实现了通过地址查 soinfo 信息「base, size, soname」等 151 | 152 | ### 4.write 调用约束下调用 Frida 的 API「send」崩溃 153 | 154 | #### 问题描述 155 | 156 | 同坑 2 的原因 157 | 158 | #### 如何解决 159 | 160 | 直接改用 syscall 线程使用「**\_\_android_print_log**」打印信息 161 | 162 | # 还可以实现什么 163 | 164 | 在调用线程 syscall 前后可以更改传参、返回值、地址等更改,达到 HOOK 的效果 165 | 166 | # GITHUB 167 | 168 | **求 star** 169 | [https://github.com/Abbbbbi/Frida-Seccomp](https://github.com/Abbbbbi/Frida-Seccomp) 170 | 171 | # 如何使用 172 | 173 | ``` 174 | pip3 install frida 175 | python3 multi_frida_seccomp.py 176 | 177 | ``` 178 | 179 | log 信息可以在 logcat 过滤 “seccomp” 查看 180 | 同时也自动保存到了「包名*pid*时间戳」文件夹内(支持多进程) 181 | ![](https://bbs.pediy.com/upload/attach/202203/903162_DSYWMSBGQMMVBJ8.png) 182 | 183 | [【公告】看雪团队招聘安全工程师,将兴趣和工作融合在一起!看雪 20 年安全圈的口碑,助你快速成长!](https://job.kanxue.com/position-read-1104.htm) 184 | 185 | [#基础理论](forum-161-1-117.htm) [#NDK 分析](forum-161-1-119.htm) [#HOOK 注入](forum-161-1-125.htm) [#系统相关](forum-161-1-126.htm) [#工具脚本](forum-161-1-128.htm) 186 | -------------------------------------------------------------------------------- /Web 安全/XSS/examples.html: -------------------------------------------------------------------------------- 1 | 2 | ';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//-->">'> 3 | '';!--"=&{()} 4 | 0\"autofocus/onfocus=alert(1)-->