SQL注入与正则表达式

SQL注入:

SQL注入攻击的本质,就是把用户输入的数据当做代码执行。
这里有两个关键的条件:
1、用户能够控制输入
2、原本程序要执行的代码,拼接了用户输入的数据然后进行执行

1998年一名叫做rfp的黑客发表了一篇关于SQL注入的文章

首先查看登录处理代码:

<meta charset='utf-8'>
<?php
@$username = $_REQUEST['username']; #用户名
@$password = $_REQUEST['password']; #密码
$conn = mysqli_connect('localhost','root','root','fuli');
$sql = "select * from admin where username='$username' and password='$password'"; #必须使用双引号,解析变量
$result = mysqli_query($conn,$sql);
$result_array = mysqli_fetch_array($result);
if($result_array['username']==$username and $username!='' and $result_array['password']==$password and $password!=''){
	echo '登录成功';
}
else{
	echo '登录失败';
}
?> 

提取出$SQL变量:

select * 
from admin 
where username='$username' and password='$password'

只需要输入特定的密码

$password=' or 1=1 -- qwe

#--是注释符号,在SQL语句中可能会处理掉末尾的空格,所以需要添加qwe等字符

即可使得SQL语句成立,1=1永远是对的

select * 
from admin 
where username='$username' and password='' or 1=1 -- qwe'

或者

$password=' or 1='1
select * 
from admin 
where username='$username' and password='' or 1='1'

当然,在此处的登录处理代码中,这种简单的SQL注入并不能够绕过登录。

基础知识

漏洞的认证:要求能够获取数据、表库结构或者绕过登录

安全和体验性站在天平的两侧,越是安全的东西体验性越差,越是体验性好的东西安全性越差

过滤:防止黑客攻击的普遍手段,过滤的常用方法是正则表达式

die()终止输出

<meta charset="UTF-8">
<?php
echo 'I';
die('love');
echo 'you';
?>

/*
输出:I love
*/

正则表达式

正则表达式,又称为规则表达式(Regular Expression,简写为regex、regexp或RE),常用来检索、替换某些符合某个模式(规则)的文本。

PHP中使用正则规则一定要加代表正则的标识//

preg_match_all(正则表达式,匹配字符串,存放匹配字符串的数组) 返回匹配的次数
preg_replace(正则表达式,替换成,匹配字符串) 返回替换后
<?php
$a = '12314561';
$b = preg_match_all('/1/',$a);
var_dump($b);
?>

#输出:int(3)
#输出连续的ap

<?php
$a = 'appleappleaxpple';
$b = preg_match_all('/ap/',$a);
var_dump($b);
?>

#输出:int(2)

常用转义字符
数字:\d
非数字:\D
空白字符(空格、制表符、换页符等):\s
非空白字符:\S
单词字符(26个英文字母+数字+下划线):\w
非单词字符:\W

#一共有11个数字

<?php
$a = '123apple56aple789999apple';
$b = preg_match_all('/\d/',$a);
var_dump($b);
?>

#输出:int(11)
<meta charset="UTF-8">
<?php
$a = $_GET['a'];
$b = preg_match_all('/\d/',$a);
if($b){
	echo '非法传参';
}
?>

#输入:http://127.0.0.1/RE.php?a=123b*
#输出:非法传参

一般使用\W过滤掉非单词字符,所以一般的登录界面只允许输入单词字符

自定义字符集合
字符集合:[单个字符或字符区间],用于匹配集合内字符,例如:
[a-z]表示a-z这26个小写字母
[0-9a-z]表示0-9这10个数字和a-z这26个小写字母
[135a-h]表示包含数字1,3,5和a-h这8个字母

非集:[^单个字符或字符区间],用于匹配非集和内字符,例如:
[^0-9]表示匹配所有非数字字符
[^a-zA-Z]表示匹配所有非字母字符

#输出1-4出现的次数

<meta charset="UTF-8">
<?php
$a = 'abcdfr234ga1k677fl';
$b = preg_match_all('/[1-4]/',$a);
var_dump($b);
?>

#输出:int(4)
#找出20世纪出生,生日为9月9日的人

<meta charset="UTF-8">
<?php
$a = '13849suhaf';
$b = preg_match_all('/20[0-9][0-9]0909/',$a);
var_dump($b);
?>

关键字
():代表一个整体
^:匹配输入字符串的开始位置
$:匹配输入字符串的结尾位置
. :点代表任意字符,即通配符,但不匹配换行
* :匹配0次或者多次
+ :匹配1次或者多次
\ :转义字符
| :两项之间的一个选择

#开头为a

<meta charset="UTF-8">
<?php
$a = 'abcd';
$b = preg_match_all('/^a/',$a);
var_dump($b);
?>

#输出:int(1)
#既限制了开头,又限制了结尾,字符串只有一个数字

<meta charset="UTF-8">
<?php
$a = '123';
$b = preg_match_all('/^[0-9]$/',$a);
var_dump($b);
?>

#输出:int(0)
#一个中文代表3个字符

<meta charset="UTF-8">
<?php
$a = '牛';
$b = preg_match_all('/./',$a);
var_dump($b);
?>

#输出:int(3)
#.*代表匹配一切,$c记录匹配到的字符,同时直接写.*还会匹配到一个空

<meta charset="UTF-8">
<?php
$a = 'absv039457';
$b = preg_match_all('/.*/',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(2)
array(1) { [0]=> array(2) { [0]=> string(10) "absv039457" [1]=> string(0) "" } }
*/
#匹配到一次

<meta charset="UTF-8">
<?php
$a = 'absv039457';
$b = preg_match_all('/.+/',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(1)
array(1) { [0]=> array(1) { [0]=> string(10) "absv039457" } }
*/
<meta charset="UTF-8">
<?php
$a = 'aaaa';
$b = preg_match_all('/a*/',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(2)
array(1) { [0]=> array(2) { [0]=> string(4) "aaaa" [1]=> string(0) "" } }
*/
<meta charset="UTF-8">
<?php
$a = 'aabc';
$b = preg_match_all('/a*/',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(4)
array(1) { [0]=> array(4) { [0]=> string(2) "aa" [1]=> string(0) "" [2]=> string(0) "" [3]=> string(0) "" } }
*/
<meta charset="UTF-8">
<?php
$a = 'abcbbbbcb';
$b = preg_match_all('/ab*/',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(1)
array(1) { [0]=> array(1) { [0]=> string(2) "ab" } }
*/
<meta charset="UTF-8">
<?php
$a = 'aaa';
$b = preg_match_all('/a+/',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(1)
array(1) { [0]=> array(1) { [0]=> string(3) "aaa" } }
*/
<meta charset="UTF-8">
<?php
$a = 'aabcd';
$b = preg_match_all('/a+/',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(1)
array(1) { [0]=> array(1) { [0]=> string(2) "aa" } }
*/
<meta charset="UTF-8">
<?php
$a = 'abcabcaaaabc';
$b = preg_match_all('/(abc)+/',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(2)
array(2) { [0]=> array(2) { [0]=> string(6) "abcabc" [1]=> string(3) "abc" } [1]=> array(2) { [0]=> string(3) "abc" [1]=> string(3) "abc" } }
*/
<meta charset="UTF-8">
<?php
$a = 'http://127.0.0.1/RE.php?a=123bhttp://127.0.0.2';
$b = preg_match_all('/http(.*)/',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(1)
array(2) { [0]=> array(1) { [0]=> string(46) "http://127.0.0.1/RE.php?a=123bhttp://127.0.0.2" } [1]=> array(1) { [0]=> string(42) "://127.0.0.1/RE.php?a=123bhttp://127.0.0.2" } }
*/
<meta charset="UTF-8">
<?php
$a = '127.0.0.1';
$b = preg_match_all('/\./',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(3)
array(1) { [0]=> array(3) { [0]=> string(1) "." [1]=> string(1) "." [2]=> string(1) "." } }
*/
<meta charset="UTF-8">
<?php
$a = 'a55bcbca9';
$b = preg_match_all('/a[0-9]|bc/',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(4)
array(1) { [0]=> array(4) { [0]=> string(2) "a5" [1]=> string(2) "bc" [2]=> string(2) "bc" [3]=> string(2) "a9" } }
*/

网站可以获取访问者的IP,访问者可以通过一些方法来修改自己的IP,写了IP合法的正则表达式

限定符
{n} :0{8}只有连续的8个0才会被匹配
{n,} :0{2,}只有2个及其以上连续的0才会被匹配
{n,m} :0{2,4}最少匹配2个0,最多匹配4个0
默认匹配最多的次数

修饰符
/i:不区分大小写
/A:匹配规则必须从头开始匹配
/s:将匹配一切字符
/x:正则表达式中的空白字符会被忽略

<meta charset="UTF-8">
<?php
$a = 'AaA';
$b = preg_match_all('/a/i',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(3)
array(1) { [0]=> array(3) { [0]=> string(1) "A" [1]=> string(1) "a" [2]=> string(1) "A" } }
*/
<meta charset="UTF-8">
<?php
$a = 'baA';
$b = preg_match_all('/a/iA',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(0)
array(1) { [0]=> array(0) { } }
*/
<meta charset="UTF-8">
<?php
$a = 'aabaA';
$b = preg_match_all('/a/iA',$a,$c);
var_dump($b);
echo "<br />";
var_dump($c);
?>

/*
输出:
int(2)
array(1) { [0]=> array(2) { [0]=> string(1) "a" [1]=> string(1) "a" } }
*/

匹配网址

<meta charset="UTF-8">
<?php
$a = '192.123.1.1';
$b = preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/",$a);
if($b){
	echo '匹配成功';
}
else{
	echo '输入非法';
}
?>

/*
输出:匹配成功
*/
#SQL注入
<meta charset="UTF-8">
<?php
$a = "192.123.1.1) or sleep(5) -- qwe";
#$a = "192.123.1.1') or sleep(5) -- qwe"; 单引号实际上可以去掉
$b = preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/",$a);
if($b){
	echo '匹配成功';
}
else{
	echo '输入非法';
}
?>

/*
输出:匹配成功
*/

当然,这只是一个例子,写得并不严谨,只是为了方便理解。

例题

#输入:http://127.0.0.1/RE.php?id=apple11pea222:/3/orangeeeorange

<meta charset="UTF-8">
<?php
$a = 'flag{regular}';
$b = preg_match("/apple.*pea.{2,9}:\/.*\/(orange*orange)/i", trim($_GET["id"]), $c); 
#trim()去除首尾的空格
if($b){
	die('a: '.$a);
}
?>
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弈-剑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值