核心内容摘要
深度解析Non-Local、CBAM与ECA:awesome-attention-mechanism-in-cv经典模块原理解析
SQL 注入的函数武器库字符串截取系列substr,substring,left,right,mid长度与数值处理系列length,ceil,floorascii()字符转码器if(11,条件为真条件为假)逻辑分支器concat(str1, str2, ...)行内拼接器group_concat(expr)跨行聚合器查询当前状态database()当前使用的数据库名user()当前数据库连接用户version()数据库版本SQL 注入的“导航地图”information_schema是一个虚拟数据库它存储了关于所有其他数据库的元数据例如库名、表名、字段名、访问权限等。
SCHEMATA表库的索引核心字段SCHEMA_NAME。
注入应用用于获取服务器上所有数据库的名称。
Payload 示例?id-1 union select 1,group_concat(schema_name),3 from information_schema.schemata--
TABLES表表的索引核心字段TABLE_SCHEMA所属库名,TABLE_NAME表名。
注入应用在确定了目标库名后通过指定TABLE_SCHEMA来查询该库下的所有表。
Payload 示例?id-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schemasecurity--
COLUMNS表列的索引核心字段TABLE_SCHEMA库名,TABLE_NAME表名,COLUMN_NAME列名。
注入应用在确定了目标表名后获取该表的所有字段名为最后一步提取数据做准备。
Payload 示例?id-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_nameusers and table_schemasecurity--探测与类型判定
寻找注入点观察 URL 参数如?id1或 POST 表单提交位。
判断注入类型数字型输入and 12页面异常即存在漏洞。
字符型输入单引号引起报错或用and 12判断。
注释符的作用--或--SQL标准注释。
#MySQL特有注释。
post请求类型必用/**/常用于绕过空格过滤。
目的切断原脚本后续的LIMIT或引号使我们的 Payload 生效。
判断列数针对联表查询使用order by N。
如果order by 3正常order by 4报错说明有 3 列。
寻找回显位根据列数使用UNION SELECT 1,2,3看页面上显示的是哪个数字那个数字对应的位置就是回显位。
注入类型
基础注入类型联合查询注入利用UNION操作符将恶意查询结果合并到原始查询中前提是页面必须有直接的数据回显位。
sqli-labs 示例Less 1 ?id-1 union select 1,2,database()--。
关键步骤先用order by找列数再用union select定位显示位。
报错注入通过构造特定函数如updatexml或floor故意引发数据库错误使数据随错误信息一起显示出来。
sqli-labs 示例Less 5and updatexml(1, concat(0x7e, (select database()), 0x7e),
--。
补充数据显示不全可结合limit使用多行结果可用group_concat函数回显。
盲注类型当服务器不返回错误或数据仅通过页面差异判断时使用。
布尔盲注利用AND或OR构造逻辑判断根据页面返回的是“正常”还是“异常/缺失”来逐字符猜解。
sqli-labs 示例Less 8探测示例?id1 and length(database())8--。
猜解字符?id1 and ascii(substr(database(),1,
)115--。
时间盲注利用IF和SLEEP函数如果条件成立则触发延迟以此判断数据内容。
sqli-labs 示例Less 9通用 Payload?id1 and if(11, sleep(
,
--。
进阶与特殊注入二次注入第一步将带有引号的恶意数据存入数据库此时被转义安全第二步应用调用该存储数据拼接 SQL 语句时转义失效触发注入。
sqli-labs 示例Less 24(二次注入修改管理员密码)。
宽字节注入针对 GBK 编码,在单引号前加入%df使其与转义符\(%5c) 结合成汉字%df%5c(运)从而让引号逃逸。
sqli-labs 示例Less 32 - Less 36。
技巧?id1%df union select...。
into outfile注入三个前提条件
身份必须为root权限2必须知道网站的实际物理地址也就是 D:/php/www/sql/webshell.php3: secure_file_priv 必须为空需要在my.cnf下修改这个是设置导出文件路径的。
然后我们需要用outfile函数将一段php代码写入到一个php脚本文件中并导出到网站上级目录下。
sqli-labs 示例Less 17。
堆叠注入利用分号 ; 同时执行多条 SQL 语句。
不仅能查询还能执行 UPDATE、DROP 等操作。
sqli-labs 示例Less 38 - Less 41。
sql绕过技巧
字符与符号目标绕过技巧补充要点空格/**/、%0a换行、%0b、、括号包裹、单引号在某些环境中%a0不换行空格也能奇效。
引号十六进制 (0x...)、CHAR()函数WHERE user CHAR(97,100,109,105,
等同于admin。
逗号JOIN联表、LIMIT 1 OFFSET
MID(str FROM 1 FOR
MID和SUBSTR都有FROM...FOR语法完美避开逗号。
比较符GREATEST()、LEAST()、BETWEENGREATEST(a,b)返回较大值可用于二分查找判断 ASCII 码。
逻辑操作符的等价替换WAF 通常会死盯SELECT、UNION、AND、OR。
逻辑符AND$\rightarrow$OR$\rightarrow$||XOR$\rightarrow$^(异或)NOT$\rightarrow$!关键字变形大小写混淆SeLeCt针对规则不严的旧 WAF。
双写绕过selselectect针对只删除一次关键字的过滤逻辑。
内联注释MySQL特有/*!50000Select*/。
这表示如果数据库版本高于
5.
0.
0则执行 Select。
盲注中的高级绕过LIKE与正则LIKE绕过在布尔盲注中极具杀伤力。
LIKE模式匹配使用%通配符或_单个占位符。
REGEXP正则匹配select user regexp ^r。
优点比LIKE更强大可以匹配复杂的字符串规则且常被忽略。
INSTR()或LOCATE()IF(INSTR(database(),s), sleep(
,
。
如果库名包含 s返回其位置非0即真从而触发延迟。
https://regex
com/https://jex.im/regulex/正则表达式回溯绕过因为回溯的限制为1000000个字符所以我们在我们输入的字符串的后面加上1000000个字符就可以使正则无效而且不影响正文地绕过。
补充缓冲区溢出与特殊编码十六进制/URL双重编码有些 WAF 只解码一次。
尝试将%编码为%25例如%2527双重编码后的单引号。
超长字符串溢出构造极长的无用参数如aaaaa...连续几千个某些 WAF 为了性能会跳过后续内容的检查此时将 Payload 放在最后即可。
反引号 () 绕过在 MySQL 中反引号用于包裹标识符表名、列名。
如果users被过滤尝试使用users。
perg_match()函数绕过这个函数只检查字符串提供一个只有一个字符串的数组即可绕过。
渗透实战策略信息收集与密码喷洒
信息收集利用工具对渗透网站进行信息收集
密码喷洒 vs 暴力破解暴力破解死磕一个用户尝试 10000 个密码易触发布控被封 IP。
密码喷洒死磕一个弱密码如123456尝试 10000 个用户名如admin,root,zhangwei。
喷洒优势每个用户只错一次极大概率绕过账户锁定的风控机制。
自动化与效率优化针对盲注
BP 爆破
Python 暴力破解
Python 二分查找sql预防预编译PDO在 SQL 注入的逻辑里我们是把攻击代码伪装成数据传进去而预编译则像是一个模具它先定死 SQL 语句的结构后续传进去的任何东西都只会被当作“纯文字”处理。
它的核心思想非常简单“把代码和数据分开”。
虚假预编译只是高级点的“字符串拼接”这是许多 Web 环境如 PHP 的 PDO 默认配置为了性能或兼容性采取的方案。
?php $username $_POST[username]; $db new PDO(mysql:hostlocalhost;dbnametest, root, root
; $stmt $db-prepare(SELECT password FROM test where username :username); $stmt-bindParam(:username, $username); $stmt-execute(); $result $stmt-fetchAll(PDO::FETCH_ASSOC); var_dump($result); $db null; ?工作机制PHP 在本地客户端先将 SQL 模板和参数拿到然后根据设置的字符集自动给参数加上单引号并对内部的敏感字符进行转义。
最后把拼好的完整 SQL 语句发给数据库。
本质它没有改变 SQL 执行的逻辑只是把手动addslashes的活儿交给了 PDO 驱动自动完成。
风险点宽字节注入如果字符集设置不当如使用了SET NAMES gbk而不是在 DSN 连接串中指定%df依然可以吞掉自动加上的转义符。
非参数化位由于它本质还是拼接对于ORDER BY或表名位置它依然无能为力。
真实预编译逻辑与数据的“物理隔离”这才是数据库层面的原生支持也是防御 SQL 注入的终极手段。
?php $username $_POST[username]; $db new PDO(mysql:hostlocalhost;dbnametest, root, root
; $db - setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $stmt $db-prepare(SELECT password FROM test where username :username); $stmt-bindParam(:username, $username); $stmt-execute(); $result $stmt-fetchAll(PDO::FETCH_ASSOC); var_dump($result); $db null; ?执行顺序底层三步走建立连接 (Connect)客户端与数据库握手。
构建语法树 (Prepare)数据库收到带有?占位符的语句进行词法解析、语法分析。
此时SQL 语句的结构干什么已经定死了。
执行 (Execute)客户端发送参数数据是什么数据库将参数填入语法树的槽位中运行。
核心优势数据永远是数据参数里的任何引号、注释符、OR 11都会被当作普通的“文本值”绝对不会被当作 SQL 指令解析。
性能如果执行 1000 次相同的查询数据库只需构建 1 次语法树效率极高。
order by || group by因为order by 如果后面的参数跟了引号order by会失效即order by的参数是不能被参数化的。
如果允许预编译绑定列名或表名那么SQL结构部分会影响查询计划比如下面的代码$stmt $db-prepare(SELECT * FROM users ORDER BY :column); $stmt-bindParam(:column, $column); $stmt-execute();首先这样的写法会导致查询优化失败数据库的查询优化器在预编译阶段无法确定ORDER BY :column具体会如何执行不同列索引可能导致不同的查询计划其次这样会导致无法复用执行计划如果:column可能是id、username、email不同列的索引和排序方式不同数据库必须为每个不同的列生成新的执行计划失去了预编译的优势因此预编译绑定的值始终是数据值不会影响 SQL 结构。
实际上order by和group by的地方是固定的并不会被传值。
因报错未退出而导致未授权访问内容溢出走私注入启发PDO预编译有个明显的缺陷可以消除sql歧义但是无法真正的消除sql注入。