Iuhrey

一个常年被吊打的Web手 一个唱歌不好指弹垃圾的吉他手

关于sql注入的一些学习心得

写在前面

说实话,很久以前就有着想归纳sql注入的冲动了,但是自己的实力不够,对mysql不太了解,对于一些sql注入的题目也是一知半解,久而久之就开始对sql注入产生了逃避以及厌恶之情,最近慢慢的才发现,不会sql注入那和我吉他不会大横按一样,所以我最近恶补了一些sql注入方面的知识,写在这里一方面是为了分享一下自己的学习心得,另一方面,则是为我自己做个笔记。

sql基础知识

初入sql注入呢,我们需要了解一下我们进行sql注入的目的是什么,以及如何使用sql注入来达到我们需要得到的效果。
sql注入是我们通过我们自己可控的输入恶意的插入一些代码执行语句来使得源代码错误的执行我们的语句从而反馈给我们一些有用的信息。sql注入主要的原因是因为在使用php与mysql进行交互的时候,代码写得不严谨或是过滤不太完整。
那如何通过sql注入的注入点来读取数据库的一些信息呢?目前主要接触到的有以下几种注入:
1 get形注入,我们在测试的时候,关注一下网站的url如何出现了形如:

www.xxxxxx.xxx/?id=x

这时我们就可以考虑sql注入了。
2 post形注入,如果网站直接给你一个输入框那可以考虑考虑post形的注入
3 cookies注入,这一种主要是通过抓包观察cookies的一些规律,如果出现一些特殊的cookies类型那可以考虑试试构造sql语句的cookies来进行注入
4 其他类型的注入,比如在headers里面的一些参数可以进行注入,通过x-forwarded-for构造ip来进行注入

sql注入的基础函数

user() :当前使用者的用户名
database():当前数据库名
version():数据库版本
datadir:读取数据库的绝对路径
@@vasedir:mysql安装路径
@@version_compile_os:操作系统
concat():连接一个或者多个字符串
group_concat():连接一个组的所有字符串,并以逗号分隔每一条数据
length():返回字符串的长度
substr():截取字符串
mid():截取字符串
ascii():返回字符的ascii码
sleep(): 函数延迟代码执行若干秒

sql注入的基础语句

1 万能语句

‘ or ‘1’=’1 #
admin’) #

类似这种短小的语句是在sql注入前先试试的,不过绝大部分的网站是不可能有这种注入给我们利用的。只可能在做题里面用到。
2 union语句

union select * from where

这是我们最基本的一种查询语句。一般这种注入方式叫做联合查询注入方式。
ps 我也只会知道这两种,其他的会后续补上。

sql注入基本流程

1 首先自然是观察哪里可能存在注入点,上述我们提到的四种可能存在注入的地方需要特别注意,接下来以get形式注入为例子进行操作。
2 碰到像这种应该测试一下是什么类型的注入

xxxx/?id=1

我们可以这样来判断这是什么类型

xxxx/?id=1 and 1=1
xxxx/?id=1 and 1=2

如果第一次返回正常,第二次返回错误,或者不返回,那么可以判断这是数字型的注入,那如两次都是错误那就可以判断是字符型注入了,这只是一种区分方式,感兴趣可以去百度一波。区分不同类型对我们注入是有所帮助的。
3 如果判断为了字符型注入,那么我们接下去查询它的列数,如果我们后面查询的列数与数据库的列数不同,那么是无法正常显示我们查询的东西的。一般具体的查询我们是通过order by来查询的。

xxxx/?id=1’ order by x –+

这样一直试,知道可以判断x为止。然后再判断其显示位

xxxx/?id=-1’ union select 1,2…,x –+

注意id我们需要赋一个数据库不存在的值,这样才能显示我们要查的内容,不然的话,原来的数据可能会覆盖掉我们查询的内容。此刻回显的数字即为显示位。
4 这个时候我们就可以利用显示位和联合查询来依次爆破数据库名,表名,列名,字段了(以2为显示位)。

xxxx/?id=-1’ union select 1,database()….. –+ 或者 union select 1,schema_name… from information_schema.schemata –+
xxxx/?id=-1’ union select 1,table_name… from information_schema.tables where table_schema=’库名’ –+
xxxx/?id=-1’ union select 1,column_name… from information_schema.columns where table_name=’表名’ –+
xxxx/?id=-1’ union select 1,列名… from 表名 –+

由于在查询的时候会有很多表名列名,但是返回的数据只有一条,那我们怎么办呢?
第一我们可以使用limit m,1这个语句,作用是限制查询为第m+1条数据,我们可以通过多次查询出所有结果,或者还可以使用limit n offset m,这个语句则是查询第m条数据之后的n条数据。
第二我们可以使用concat(),以及group_concat()或是concat_ws()函数来把所查询的内容连接成字符串输出。

这些都是最基本的操作,如果在某些题目中出现过滤某些关键词的话,我们可以考虑通过绕过来注入,这是借鉴大师傅bypass的一些思路的地址:http://www.cnblogs.com/joy-nick/p/5774462.html

接下来是一些过滤了关键词但是可以注入的其他方式。

宽字节注入

在某些加了转义的sql语句中,我们无法通过’或是”闭合语句来达到我们的目的,但是如果网站使用了GBK编码的话,我们是可以通过

%df%27

来构造一个’闭合语句的,因为GBK编码是双字节编码,也就是说,如果我们构造了与%5c相关的编码,那么前两个编码会被识别为一个字符也就是汉字,然后我们的%27就被独立了出来,这是一个实例这样就成功绕过了转义语句构造出了我们需要的’
接着跟着流程走就行了,但是值得注意的一点是在后面这句查询语句where table_schema=’表名’应该使用where table_schema =数据库十六进制来代替。

本站总访问量