给黑客的jq指南

admin 2026-07-10 07:20:18 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文面向黑客和系统管理员,介绍了JSON处理工具jq的核心用法。文章从基础概念讲起,涵盖美化输出、提取特定字段、使用select过滤数据等操作,并通过解析ldapdomaindump输出等实战示例展示其应用。作者强调掌握点号引用、数组遍历、select过滤等心智模型即可应对大部分场景,鼓励读者放弃传统CSV工具,拥抱JSON。 综合评分: 88 文章分类: 安全工具,实战经验,红队,渗透测试


cover_image

给黑客的 jq 指南

Justin Bollinger Justin Bollinger

securitainment

2026年7月6日 12:50 新加坡

在小说阅读器读本章

去阅读

| 原文链接 | 作者 | | — | — | | https://trustedsec.com/blog/jq-for-hackers | Justin Bollinger |

当我第一次接触 jq时,它让人感到既不知所措又困惑。我试过直接硬上,没意识到它其实是一个非常复杂且强大的程序。随着越来越多的工具开始输出 JSON,我觉得是时候真正学一学它了。结果发现,一旦上手,它其实相当简单。

这篇博客写给黑客、系统管理员,以及任何没有被变态大学教授逼着学 JavaScript 的人。它试图说服你——这位留着灰胡子的黑客——放下 CSV 文件和 cut命令,拥抱 JSON。

如果你熟悉 Python 字典,这些内容应该会自然而然地理解。

一些可以玩的 JSON

幸运的是,ProjectDiscovery 的 httpx是一个完美的简单示例工具。运行以下命令来获取一个 JSON 对象:

echo www.trustedsec.com | httpx -j

输出大概长这样:

httpx 原始 JSON 输出截图

这很难读——数据量很大,而且全挤在一行上。如果没有自动换行,你甚至看不全整个内容。你也无法干净利落地用 grep筛选它。

用 jq 美化输出

把同样的命令通过管道传给 jq.,输出就变得可读了:

echo www.trustedsec.com | httpx -j | jq .
{
"timestamp": "2025-03-14T17:19:03.813358-04:00",
"cdn_name": "cloudflare",
"cdn_type": "waf",
"port": "443",
"url": "https://www.trustedsec.com",
"input": "https://www.trustedsec.com",
"title": "TrustedSec | Your Trusted Cybersecurity Partner | Protecting What…",
"scheme": "https",
"webserver": "cloudflare",
"content_type": "text/html",
"method": "GET",
"host": "172.67.70.133",
"path": "/",
"time": "762.046417ms",
"a": [
"172.67.70.133",
"104.26.15.63",
"104.26.14.63"
  ],
"aaaa": [
"2606:4700:20::ac43:4685",
"2606:4700:20::681a:f3f",
"2606:4700:20::681a:e3f"
  ],
"tech": [
"Alpine.js",
"Cloudflare",
"Craft CMS",
"Google Tag Manager",
"HSTS",
"SEOmatic"
  ],
"words": 22245,
"lines": 779,
"status_code": 200,
"content_length": 258423,
"failed": false,
"cdn": true,
"knowledgebase": {
"PageType": "other",
"pHash": 0
  },
"resolvers": [
"8.8.4.4:53",
"1.1.1.1:53"
  ]
}

好多了,但仍然有很多我现在不需要的信息。怎么用 jq 来限制输出呢?

JSON 快速入门

在继续之前,你需要了解一点 JSON 的知识。如果你想要完整的规范,请参阅 JSON Schema:核心定义和术语。我们今天只讲够用的最少知识。

JSON 有七种原始类型:array* (数组)、boolean* (布尔值)、integer* (整数)、number* (数字)、NULL* (空值)、object* (对象) 和 string* (字符串)。我们将聚焦于objects* (对象) 和 arrays(数组)。

object(对象) 用花括号 {}表示,包含映射到值的属性 (键):

{
"Name": "John"
}

这个对象有一个属性 Name*,其字符串值为John*。

属性的值也可以是一个 array(数组),用 []表示:

{
"Names": ["John", "Jane", "Jason"]
}

这就是你目前需要知道的全部内容了。

提取特定字段

比方说,我只要 httpx* 输出中的host* 值。用 jq,你可以通过在属性名前加一个点号来引用它:

echo www.trustedsec.com | httpx -j | jq '.host'
"172.67.70.133"

不想要那些双引号?没问题,加个 -r就行。

echo www.trustedsec.com | httpx -j | jq -r '.host'
172.67.70.133

想要多个字段?即时构建一个新对象:

echo www.trustedsec.com | httpx -j | jq '{url: .url, ip: .host_ip, tech: .tech}'

{
"url": "https://www.trustedsec.com",
"ip": "172.67.70.133",
"tech": ["Alpine.js", "Cloudflare", "Craft CMS", "Google Tag Manager", "HSTS", "SEOmatic"]
}

要从数组中取单个值,像 Python 一样用索引:

echo www.trustedsec.com | httpx -j | jq '.a[0]'
"94.247.142.1"

要遍历数组中的每个值,用 .[]

echo www.trustedsec.com | httpx -j | jq -r '.tech[]'
Alpine.js
Cloudflare
CookieYes
Craft CMS
Google Analytics
Google Tag Manager
HSTS
HTTP/3
SEOmatic

用 select 过滤

一旦你有了一个对象流,select就是过滤它们的方式。模式是 select(<条件>)

比如,你扫描了一个 favicon 目录,只想要那些确实有 favicon 哈希的条目:

cat favicon.json&nbsp;|&nbsp;jq&nbsp;'. | select(.favicon != null) | {favicon: .favicon, url: .url}'

或者你跑了 TruffleHog,想找到包含特定密钥的文件:

cat results.json&nbsp;|&nbsp;jq -r&nbsp;'. | select(.Raw == "SuperSecretPassword") | .SourceMetadata.Data.Filesystem.file'

实战示例:解析 ldapdomaindump 输出

这才是 jq在实际项目中真正大显身手的地方。运行 ldapdomaindump后,你会得到用户、计算机和组的 JSON 文件。

ldapdomaindump -u&nbsp;'support\ldap'&nbsp;-p&nbsp;'p@ssw0rd'&nbsp;dc.trustedsec.com

下面来看看怎么拆解它们。

提取所有 SAM 账户名 (用户名)

cat domain_users.json&nbsp;|&nbsp;jq -r&nbsp;'.[].attributes.sAMAccountName[]'>&nbsp;users.txt

提取所有 UPN,跳过没有 UPN 的用户

cat domain_users.json&nbsp;|&nbsp;jq -r&nbsp;'.[] | select(.attributes.userPrincipalName != null) | .attributes.userPrincipalName[]'>&nbsp;upns.txt

select(.attributes.userPrincipalName != null)这个过滤器很重要——没有它,jq一碰到没有 UPN 的用户就会报错。或者,你可以用 ?来表示零次或多次,就像正则表达式一样。

cat domain_users.json&nbsp;|&nbsp;jq -r&nbsp;'.[] | .attributes.userPrincipalName[]?'>&nbsp;upns.txt

列出域中所有 DNS 主机名

cat domain_computers.json&nbsp;|&nbsp;jq -r&nbsp;'.[] | select(.attributes.dNSHostName != null) | .attributes.dNSHostName[]'>&nbsp;computer_dns.txt

提取特定用户的完整记录 (区分大小写)

cat domain_users.json&nbsp;|&nbsp;jq&nbsp;'.[].attributes | select(.sAMAccountName[] == "username_case_sensitive")'

当你找到某个特定账户的哈希,想看看它在哪些组里、上次登录时间等信息时,这个命令很有用。

查找所有域管理员

这是我用得最多的一个。第一次在项目中需要它时,我心想:”肯定有更优雅的方法吧。”结果发现,并没有。但它确实管用。

cat domain_users.json&nbsp;|&nbsp;jq -r&nbsp;'.[] | select( (.attributes?.memberOf // []) | any(contains("Domain Admins")) ) | .attributes.sAMAccountName[]'>&nbsp;domain_admins.txt

这里有几个要点:

  • .attributes?

    ?会在 attributes不存在时抑制错误,跟前面 UPN 的例子一样。

  • // []

    ,如果 memberOf是 NULL,就回退到空数组,这样 any就不会卡住。

  • any(contains("Domain Admins"))

    ,如果 memberOf中有任何元素包含字符串 Domain Admins,就返回 true。

心智模型

jq乍一看令人生畏,但核心心智模型其实很小:

  • .

    是当前对象。

  • .foo

    钻取某个属性。

  • .foo[]

    遍历数组。

  • select(...)

    过滤。

  • {a: .x, b: .y}

    构建新对象。

  • -r

    去掉字符串输出的引号。

  • ?

    使元素变为可选。

这就足够应对你在实际项目中遇到的 90% 的情况了。所以,放下电子表格吧——90 年代打来电话了,他们想要回他们的 cut命令。拥抱 JSON 吧。


免责声明:本博客文章仅用于教育和研究目的。提供的所有技术和代码示例旨在帮助防御者理解攻击手法并提高安全态势。请勿使用此信息访问或干扰您不拥有或没有明确测试权限的系统。未经授权的使用可能违反法律和道德准则。作者对因应用所讨论概念而导致的任何误用或损害不承担任何责任。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:securitainment Justin Bollinger Justin Bollinger《给黑客的 jq 指南》

给黑客的jq指南 网络安全文章

给黑客的jq指南

文章总结: 本文面向黑客和系统管理员,介绍了JSON处理工具jq的核心用法。文章从基础概念讲起,涵盖美化输出、提取特定字段、使用select过滤数据等操作,并通
评论:0   参与:  0