String id=request.getParameter("id");
开发者的个人习惯,没有按照PrepreStatement正确的 开发方式进行数据库连接查询,再预编译语句中也sql语句拼接
String id="2";
String username="user%' 'or'='1'#";
String sql="SELECT * FROM user where id=?";
sql+="and username like '%" +username+"%";
PrepareStatement ps=conn.prepareStatement(sql);
ps.setString(1,id);
ps.setString(1,id);
"会自动给值加引号,会导致order by子句失效。动态表名,列名作为参数时,必须使用${}
此时的防注入手段
1)order by查询:只能用${}
2)like查询:只能用${}
可使用concat函数进行拼接,依然能用#{}
3)in参数
in子句中使用#{}会将多个参数当作一个整体。只能用${}
示例:二次注入代码审计
搜索select关键字,在UserMapper.java找到不安全的$号.UserService.java中找到对应的调用。
发现其逻辑为从session中取出username,随后拼接到sql语句进行查询。
接着照哦session的调用,找到session的赋值依据。
在login逻辑中找到username值是登陆后的用户名获取的。
接着找注册逻辑,并没有对用户名进行过滤。
存在二次注入。
需注册一个存在注入语句的用户名进行登录。
sql注入防御:
常见文件上传方式,主要讲解三种
一、文件流方式
文件上传漏洞的本质还是未对文件名做校验。
常见的有:未对文件做任何过滤,仅在前端通过js检验,只判断了Content-Type,后缀过滤补全,读取后缀方式错误等。
如:通过suffixName=filename.substring(fileName.indexOf("."));
获取后缀,是不安全的。当文件名是abc.jpg.jsp时,suffixName将等于.jpg.jsp
漏洞修复:
限制上传类型并对文件进行重命名:采取白名单策略限制上传的类型;对文件名进行重命名;去除文件名中特殊字符;上传图片时,通过图片库检测上传文件是否为图片。
一、常见触发位置
输入/输出点
java中常使用request.getParameter(param) 或者 ${param} 获取用户的 输入 信息。
输出 主要表现为前端的渲染,定位前端中一些常见的标识,再根据后端逻辑来判断漏洞是否存在。
二、 反射型XSS
通过搜索特定关键字找到数据的交互点,判断这些数据是否可控及输出 位置。
resp.getWriter().print(),直接将数据传入到前端html页面进行展示。
三、 存储型XSS
常见攻击点:文章编辑、用户留言,个性签名等。
审计示例:/show 路由会打印用户的留言,根据web.xml 找到对应类servlet。
。。。。。找到最开始数据存储的时候是req.getParameter("xxx");
XSS漏洞修复
一般出现在需要用户提供路径或文件名时,如文件下载。
访问者提供需要下载的文件后,web应用程序没有去检验文件名是否存在…/等特殊字符,没有对访问的文件进行限制。
优先查找java.io.File引用。根据经验判断Paths,path,System.getProperty(“user.dir”)等各类可能会用来构造路径的关键字。
漏洞修复:
对文件名进行过滤,防止出现 ./ 等特殊字符;采用id索引的方法来下载文件,而不是通过文件名;对目录进行限制;合理配置权限等。
针对已知路径的,如 .jpg 后缀,可直接在路径后拼接 .jpg 后缀来防止用户逃逸。
修复:严格控制要跳转的域名
执行系统命令的函数
危害
:继承web服务程序的权限去执行系统命令,或读 / 写文件,反弹shell,控制整个网站甚至控制服务器,进一步实现内网渗透。
ProcessBuilder命令执行漏洞
Java.lang.ProcessBuilder 类用于创建操作系统进程,每个实例管理一个进程属性集。
start()方法利用这些属性 创建一个新的Process实例,可以利用ProcessBuilder执行命令。
通过ProcessBuilder执行“ls -al"命令
//执行系统命令
ProcessBuilder p=new ProcessBuilder("ls","-al");
Process pb=p.start();
//获取执行完成命令后的结果并输出
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(pd.getInputStream(),"GBK"));
while((line=reader.readLine())!=null){
System.out.println(line);
}
reader.close();
}
}
Runtime exec 命令执行漏洞
为什么传入字符串 与 传入数组 会有不同的执行结果呢?
跟入exec函数进行分析。
其调用的是exec(command,null,null)
方法,发现其调用的是exec(String command,String[] envp,File dir)
这个数组参数的方法。
综上所述,exec(string command)
这个字符串参数 实际调用的是exec(String command,String[] envp,File dir)
这一数组参数的方法。
\t 制表符 \r 回车符 \n 换行符 \f 换页符
原理:解析xml输入时,没有禁止外部实体的加载 而 导致加载了外部文件及代码。
XXE漏洞 可通过file协议或FTP协议来读取文件源码,也可以对内网进行探测或攻击。
漏洞危害有:任意文件读取,内网探测,攻击内网站点,命令执行,DOS攻击等。
web应用程序提供一些能够从远程获取图片 或 文件的接口,在这些接口上用户使用指定的url便能完成远程获取图片,下载文件等。
攻击者可以通过使用file协议读取服务器本地 /etc/password 和 /proc/self/cmdline 等敏感文件,也可以利用被攻击的服务器绕过防火墙直接对处于内网的机器发起进一步攻击。
SSRF常见接口
通常出现在社交分享、远程图片加载 或 下载、图片或文章收藏、转码、通过网址在线翻译、网站采集、从远程服务器请求资源等功能点处。
审计示例:
SSRF修复:
Spring表达式语言,用于在运行时查询和操作对象图。
SpEL表达式语法
Expression exp = parser.parseExpression("new Spring('Hello World')");
parser.parseExpression("T(Integer).MAX_VALUE");
在SpEL中可以使用 #bean_id 来获取容器内的变量。
同时还存在两个特殊的变量,#this 和 #root,分别用来表示使用当前的上下文和引用容器的root对象。
修复:
在使用readObject()反序列化时,首先会调用resolveClass 方法读取序列化的类名,可以通过重写ObjectInputStream对象的resolveClass方法来实现对反序列化类的校验。
服务器端模板注入Server-Side Template Injection
模板引擎支持使用静态模板文件,在运行时用 HTML 页面中的实际值替换变量 / 占位符,使HTML页面设计更容易。
广泛使用的模板引擎有 Smarty,Twig,Jinja2,Freemarker及Velocity。
若攻击者可以完全控制输入模板的指令,并且模板能够在服务器端被成功解析,则会造成模板注入漏洞。
SSTI漏洞的危害:任意代码执行,获取shell,破坏服务器完整性等。
修复:
应避免用户能够直接控制模板的输入并对其进行过滤。
如需相关用户公开模板,可以选择无逻辑的模板引擎,入Handlebars、Moustache等。