2.1.5 二次注入代码审计
与常规注入一样,通过搜索SQL关键字定位至存在SQL语句的文件,如图2-30所示。
图2-30 搜索关键字定位至存在SQL语句的文件
跟进“UserMapper.java”文件,可以发现:其中定义了大量SQL语句,但大多数使用了#号的安全写法。通过搜索可以发现:以下语句使用了不安全的$号,如图2-31所示。
图2-31 使用了不安全的$符号的语句
通过搜索调用栈,在UserService.java中可以找到其对应的调用,如图2-32所示。
图2-32 搜索调用栈,在UserService.java中找到其对应的调用
通读代码可以发现其逻辑为:从session中取出username,随后拼入SQL语句进行查询。我们接着查找session的调用,便能找到其赋值依据。最终在login逻辑中成功地找到了session的赋值过程,如图2-33所示。
图2-33 在login逻辑中成功地找到了session的赋值过程
这里可以看到username的值来源于user.getUsername(),也就是说,username的值是通过登录时输入用户名获取的,由于前面存在if逻辑判断,因此此处取到的应是成功登录后的用户名。那么我们可以接着寻找注册逻辑,以便对漏洞进行利用,如图2-34所示。
图2-34 寻找注册逻辑对漏洞进行利用
注册逻辑直接调用UserMapper进行入库操作,并没有对用户名进行过滤。同时入库时采用的是#号的安全写法,最后会通过预编译执行SQL语句,如图2-35所示。
图2-35 通过预编译执行SQL语句
这里存在的注入为二次注入,而我们想要触发该漏洞则需先注册一个存在注入语句的用户名进行登录,随后通过触发info逻辑进行二次注入。通过查看逻辑可以知道:info是通过路由/info进行触发的,如图2-36所示。
图2-36 查看逻辑可知,info是通过路由/info进行触发的
首先,注册账号名为“'union select user(),2,3#”的用户名,如图2-37所示。
图2-37 注册账号名为“union select user(),2,3#”的用户名
登录后触发info逻辑,如图2-38所示。
图2-38 登录后触发info逻辑