前言:
堕落了三个月,现在因为被找实习而困扰,着实自己能力不足,从今天开始 每天沉淀一点点 ,准备秋招 加油
注意:
本文章参考qax的网络安全java代码审计,记录自己的学习过程,还希望各位博主 师傅 大佬 勿喷,还希望大家指出错误
SSRF漏洞
SSRF(Server-side Request Forge, 服务端请求伪造)。
由攻击者构造的攻击链接传给服务端执行造成的漏洞,一般用来在外网探测或攻击内网服务。
危害:
1.获取内网主机、端口、banner信息
2.对内网的应用程序 进行攻击,例如Redis、jboos
3.file等伪协议读取文件
4.造成内网程序的溢出
SSRF审计函数
SSRF漏洞一般位于远程图片加载与下载、图片或文章收藏功能、URL分享、通过URL在线翻译、转码等功能点处。当然,SSRF是由发起网络请求的方法造成。代码审计时需要关注的发起HTTP请求的类及函数,部分如下:
HttpURLConnection. getInputStream |
Java里面SSRF支持的协议:
https,https,file,ftp等
所以使得JAVA并不能像PHP中一样使用gopher 协议来拓展攻击面,gopher 协议在jdk8 中就被移除了
gopher协议在SSRF中使用可以看下面这篇文章
gopher 协议在SSRF 中的一些利用
我们直接进入Webgoat的靶场进行测试
点击第二关得到
根据提示我们输入 jerry
这时候就说明 传入的参数可控,产生了SSRF漏洞
我们看一下源代码
@RestController
@AssignmentHints({"ssrf.hint1", "ssrf.hint2"})
public class SSRFTask1 extends AssignmentEndpoint {
@PostMapping("/SSRF/task1")
@ResponseBody
public AttackResult completed(@RequestParam String url) {
return stealTheCheese(url);
}
protected AttackResult stealTheCheese(String url) {
try {
StringBuilder html = new StringBuilder();
if (url.matches("images/tom\\.png")) {
html.append(
"<img class=\"image\" alt=\"Tom\" src=\"images/tom.png\" width=\"25%\""
+ " height=\"25%\">");
return failed(this).feedback("ssrf.tom").output(html.toString()).build();
} else if (url.matches("images/jerry\\.png")) {
html.append(
"<img class=\"image\" alt=\"Jerry\" src=\"images/jerry.png\" width=\"25%\""
+ " height=\"25%\">");
return success(this).feedback("ssrf.success").output(html.toString()).build();
} else {
html.append("<img class=\"image\" alt=\"Silly Cat\" src=\"images/cat.jpg\">");
return failed(this).feedback("ssrf.failure").output(html.toString()).build();
}
} catch (Exception e) {
e.printStackTrace();
return failed(this).output(e.getMessage()).build();
}
}
}
主要看下面几行代码
public AttackResult completed(@RequestParam String url) {
return stealTheCheese(url);
}
// completed() 方法使用 @PostMapping 注解标记,表示它处理HTTP POST请求,并且映射到路径 "/SSRF/task1"。该方法接受一个名为 "url" 的请求参数,类型为字符串。
意思就是接受url的参数 并映射到到路径 "/SSRF/task1
然后看下一句
protected AttackResult stealTheCheese(String url) {
try {
StringBuilder html = new StringBuilder();
//stealTheCheese() 方法是一个受保护的方法,用于处理传入的URL并返回相应的结果。它接受一个名为 "url" 的字符串参数。
方法逻辑:stealTheCheese() 方法首先创建了一个 StringBuilder 对象 html,用于构建HTML响应。
就是很明显没有对这个url进行过滤处理等,然后 就直接进入下面的url匹配,
这段代码是一个简单的SSRF攻击任务处理器。它接受一个URL作为输入,并根据URL的不同返回不同的HTML响应。然而,代码中存在一些潜在的安全风险,因为它没有对传入的URL进行充分的验证和过滤,可能导致安全漏洞,如SSRF攻击。
我们接着看下一关
我们先点击看看会是啥样
我们还是根据提示进行输入
url=http://ifconfig.pro
验证成功
说明url参数可控,可以通过恶意语句进行对内网主机信息的获取
我们分析源代码
@RestController
@AssignmentHints({"ssrf.hint3"})
public class SSRFTask2 extends AssignmentEndpoint {
@PostMapping("/SSRF/task2")
@ResponseBody
public AttackResult completed(@RequestParam String url) {
return furBall(url);
}
protected AttackResult furBall(String url) {
if (url.matches("http://ifconfig\\.pro")) {
String html;
try (InputStream in = new URL(url).openStream()) {
html =
new String(in.readAllBytes(), StandardCharsets.UTF_8)
.replaceAll("\n", "<br>"); // Otherwise the \n gets escaped in the response
} catch (MalformedURLException e) {
return getFailedResult(e.getMessage());
} catch (IOException e) {
// in case the external site is down, the test and lesson should still be ok
html =
"<html><body>Although the http://ifconfig.pro site is down, you still managed to solve"
+ " this exercise the right way!</body></html>";
}
return success(this).feedback("ssrf.success").output(html).build();
}
var html = "<img class=\"image\" alt=\"image post\" src=\"images/cat.jpg\">";
return getFailedResult(html);
}
private AttackResult getFailedResult(String errorMsg) {
return failed(this).feedback("ssrf.failure").output(errorMsg).build();
}
}
咱们主要关注下面两行代码
public AttackResult completed(@RequestParam String url) {
return furBall(url);
}completed() 方法使用 @PostMapping 注解标记,表示它处理HTTP POST请求,并且映射到路径 "/SSRF/task2"。该方法接受一个名为 "url" 的请求参数,类型为字符串。
protected AttackResult furBall(String url) {
//furBall() 方法是一个受保护的方法,用于处理传入的URL并返回相应的结果。它接受一个名为 "url" 的字符串参数。
下面就是常规的正则匹配,总体而言,这段代码是另一个简单的SSRF攻击任务处理器。它接受一个URL作为输入,并尝试访问该URL获取HTML内容,并根据结果返回相应的响应。如果访问成功,则返回包含HTML内容的成功响应;如果访问失败,则返回一个包含特定错误消息的失败响应。
具体的JAVA中 SSRF漏洞可以访问
https://www.freebuf.com/vuls/293473.html
SSRF修复
1,过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
2, 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
3,限制请求的端口为http常用的端口,比如,80,443,8080,8090。
4,黑名单内网ip,(正确判断内网IP,正确获取host)
5,禁用不需要的协议。仅仅允许http和https请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题。
6.正确处理302跳转