• VauditDemo靶场代码审计


    靶场搭建

    将下载好的VAuditDemo_Debug目录复制到phpstudywww目录下,然后将其文件名字修改成VAuditDemo,当然你也可以修改成其他的

    1


    运行phpstudy并且访问install目录下的install.php,这里我访问的是http://127.0.0.1/VAuditDemo/install/install.php

    查看以上服务是否支持后点击安装,数据库的默认账户密码均为root

    image-20220829133702705


    打开phpstudy修改网页站点域名, 修改网站目录为靶场文件目录, 修改网站端口为88端口

    1

    1


    重启phpstudy后访问127.0.0.1:88, 出现如下页面代表搭建成功

    1


    一、代码审计初步认识

    ini文件配置

    启用全局变量

    register_globals = off
    
    • 1

    设置为on时,php会将$_POST,$_GET,$_COOKIE,$_ENV,$_SESSION直接注册成全局变量,例如$_POST['user']会注册成$user

    因此要将此选项设置成off


    短标签

    short_open_tag = On
    
    • 1

    决定是否允许php开启缩写形式(),本指令也会影响到缩写形式,它和 等价,例如下图所示

    img


    安全模式

    safe_mode = on
    
    • 1

    php的安全模式能针对php中的一些函数作权限控制,例如system(),但是默认的php.ini是没有打开的,安全模式从5.4.0已被移除


    禁用类/函数

    disable_classes = 
    disable_functions = 
    disable_functions = opendir,readdir,fopen
    
    • 1
    • 2
    • 3

    禁用某些类以及函数,接受逗号分隔的函数名列表作为参数


    文件上传权限以及目录设置

    上传设置及上传文件大小

    file_uploads = on   //设置是否开启文件上传功能
    
    upload_max_filesize = 4M   //设置文件上传大小
    
    • 1
    • 2
    • 3

    文件上传临时目录

    upload_tmp_dir = 
    
    • 1

    如果没设置,则采用系统临时目录(/tmp,c://windows/tmp)


    用户访问目录限制

    open_basedir = .:/tmp/
    
    • 1

    该设置可以控制php脚本只能访问指定目录,从而在一定程度上限制了webshell的危害。一般设置成只能访问网站目录或者临时目录,从而有效防止webshell跨站执行


    错误信息配置

    错误信息控制

    display_error = off
    
    • 1

    将错误信息输出,站点发布后应该关闭此功能


    设置错误报告级别

    error_reporting = E_ALL
    
    • 1

    这个设置的作用是将错误级别设置为最高,利用写出高质量代码


    错误日志

    error_log =     //错误日志位置,若不设置则默认写到web服务器错误日志中去
    
    log_errors = on  //错误日志开关
    
    log_errors_max_length = 1024    //错误日志关联信息的最大长度,设置为0表示无限长度
    
    • 1
    • 2
    • 3
    • 4
    • 5

    魔术引号以及远程文件

    魔术引号

    magic_quotes_gpc = On   
    
    magic_quotes_runtime = Off
    
    • 1
    • 2
    • 3

    设置为on时开启自动转义功能,将单引号,双引号,反斜杠等等转义掉


    是否允许打开远程文件

    allow_url_fopen  = off
    
    • 1

    本选项激活了url形式的fopen封装协议使得可以访问url对象例如文件。默认的封装协议提供用ftp和http协议来访问远程文件。一般开启后配合文件包含函数可使用伪协议进行攻击


    是否允许包含远程文件

    allow_url_include = off   
    
    • 1

    本选项激活允许include、include_once、requirerequire_once等函数使用url形式的fopen封装协议,会造成远程包含漏洞


    网站结构及重要文件

    img


    危险函数

    代码执行函数

    eval()

    eval() //将字符串转换成php代码并执行
    
    • 1

    assert()

    判断语句逻辑是否为真,为假则返回false,但还是会执行代码,常被利用到制作免杀webshell

     
    $a = 1;
    $b = 2;
    assert("$a == $b");  //返回false
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    preg_replace()

    参数一为正则表达式,依照 php的格式,表达式在两个/之间,如果在表达式末尾加上一个 e,则参数二就会被当做 php代码执行

    注意: 参数二需要在正则匹配成功后才能执行

    
    preg_replace('/test/e',"phpinfo()","only test")	  //执行phpinfo()
    ?>
    
    • 1
    • 2
    • 3

    create_function()

    创建一个匿名函数给test变量, 此变量可调用匿名函数, 参数一为匿名函数的参数, 参数二为匿名函数的执行代码

    
    $test = create_function('$a', 'return system($a);');
    $test('whoami');	//相当于执行system('whoami')
    ?>
    
    • 1
    • 2
    • 3
    • 4

    call_user_func()

    调用函数,参数一为被调函数名,参数二为被调用函数的参数

    img


    文件包含函数

    requireincluderequire_onceinclude_once


    命令执行函数

    Exec()passthru()proc_open()shell_exec()system()popen()


    文件操作函数

    函数作用
    copy拷贝文件
    file_get_contents读取文件内容转换为字符串
    file_put_contents将字符串写入文件
    file把整个文件读入到数组中
    fopen打开文件或者url
    move_uploaded_file(file,newloc)将上传的文件移动到新的位置
    readfile输出文件内容
    rename重命名一个文件或者目录
    rmdir删除目录
    unlink & delete删除文件

    读取可以读取配置信息,写入可以写入shell,删除可以删除.lock文件实现重新覆盖


    其他特殊函数

    信息泄露

    bool phpinfo()    //输出php大量配置信息
    
    • 1

    软连接-读取文件内容(linux生效)

    bool symlink(str $target,str $link)  //对已有的target建立一个名为link的符号链接 
    
    str readlink(str $path)     //readlink返回文件内容
    
    • 1
    • 2
    • 3

    环境变量

    str getenv(str $varname)         //getenv获取一个环境变量
    bool putenv(str setting)         //putenv将参数设置到环境变量里面
    
    • 1
    • 2
    putenv("test=123")    //设置test变量为123
    getenv("test")       //输出环境变量
    
    • 1
    • 2

    配置函数

    str ini_get(str $varname) //返回配置选项的值
    
    str ini_set(str $varname,str newvalue)       //设置配置选项的值
    str ini_alter(str $varname,str newvalue)     //设置配置选项的值
    
    void ini_restore(str $varname)    //将配置选项恢复到原始值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    数字判断函数

    bool is_numeric($varname)   //该函数容易导致sql注入,因为16进制内容也会被判断成数字类型
    bool intval($varname)     //判断数字类型应该用这个函数
    
    • 1
    • 2

    变量覆盖

    $str = "name=faker&time=10";
    parse_str($str);  //将字符串解析成变量并作用于当前域
    echo $name';     //输出$name变量
    
    • 1
    • 2
    • 3

    输出当前目录文件

    print_r(glob("*.txt"))    //按照特定规则匹配相对于的文件名
    
    • 1

    无参数获取信息

    array get_defined_vars() //获取已定义的所有变量,包含cookie,get,post
    
    array get_defined_constants() //获取已定义的常量
    
    array get_defined_functions() //获取已定义的所有函数
    
    array get_included_files()  //获取所有被文件包含的文件名
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    二、安装漏洞

    导致安装漏洞的原因

    • 无验证功能,任意重装覆盖
    • $_GET[‘step’]跳过限制步骤
    • 变量覆盖导致重装
    • 判断lock后跳转无exit
    • 解析install.php.bak漏洞

    审计思路图

    1


    审计例子

    分析install目录下的install.php文件,判断lock文件后是否执行exit函数

    img


    追踪变量,发现$str_tmp变量写入到config.php文件中

    img


    寻找$str_tmp变量的可控点,最后发现$dbname变量参与了$str_tmp变量值的生成

    img

    img


    进入config.php文件,发现$dbname变量的值赋给了$database变量

    img


    构造exp进行攻击

    install.php页面构造php代码注入,exp如下所示

    exp;-- -";phpinfo();//
    
    • 1

    img


    利用此exp能够组成含有注入的变量,如下

    mysql_query("CREATE DATABASE exp;-- -";phpinfo();//")
    
    $database = "exp;-- -";phpinfo();//"
    
    • 1
    • 2
    • 3

    img


    三、命令执行漏洞

    命令执行常用函数

    • system()
    • exec()
    • passthru()
    • shell_exec()

    审计思路

    ctrl+F追踪危险函数所涉及到的页面以及变量


    审计流程

    全局搜索危险函数及其所在文件,发现ping.php包含危险函数

    img

    img


    跳转到ping.php文件,发现$cmd变量与危险函数shell_exec有关联, $cmd值的组成与$target有关联

    $target变量是可控的,也就是说可以在$target写入payload

    img


    漏洞利用

    网站转到ping.php页面, 输入127.0.0.1 | whoami, 构成命令执行注入

    img


    防御措施

    采用filter_var()函数来判断变量是否是标准的ip格式

    if(filter_var($target,FILTER_VALIDATE_IP)){
    }
    
    • 1
    • 2

    img


    四、任意文件读取

    文件读取函数

    • echo file_get_contents()
    • readfile()

    审计例子

    全局搜索文件读取函数,在user/avatar.php发现file_get_contents()函数以及其关联变量$_SESSION['avatar']

    img


    全局搜索$_SESSION[‘avatar’],发现在user/logCheck.php存在此函数, 并且发现$row['user_avatar']构成了此变量,

    image-20210518182544308


    全局搜索user_avatar字段, 发现其在user/updateAvatar.php文件中, user_avatar$avatar组成的, 而$avatar是可控的, 其值由文件上传的名字和其他字符所组成, 也就是说可以在上传的文件名里构造payload

    1


    如果上传的文件名为',user_avatar = '../sys/config.php'#.png,那么$avatar的值为../uploads/u_11111_',user_avatar = '../sys/config.php'#.png

    构造的sql语句为UPDATE users SET user_avatar = '../uploads/u_11111_',user_avatar = '../sys/config.php'#.png' WHERE user_name='{$_SESSION['user_id']}'

    在update语句中SET最后一个字段名才生效, 还有mysql插入数据字段值时会自动除去反斜杠 ,因此把配置文件路径改成16进制, 最终上传的文件名字为: ',user_avatar = 0x2E2E2F7379732F636F6E6669672E706870#.png

    image-20210518182944006


    漏洞利用

    通过以上对代码的审计, 确定了漏洞利用的页面有3个,先后顺序分别是updateAvatar.phplogcheck.phpavatar.php

    updateavatar.php页面上传图片并修改文件名,然后查看数据库表的字段值,发现其被修改成配置文件的路径

    image-20210518201022361

    image-20210518201120800


    随后依次访问logcheck.php,avatar.php

    20210518201540

    20210518201621


    五、XSS攻击漏洞

    涉及函数

    • echo

    审计例子

    追踪echo函数寻找可控点,在admin/manageUser.php发现一处输出用户ip: echo $users['login_ip']

    image-20210521165943834


    追踪login_ip字段名,在admin/logCheck.php发现其涉及两个函数, 分别是get_client_ip()sqlwaf()

    1


    追踪get_client_ip()sqlwaf(),跳转到其代码定义处lib.php,发现可以通过伪造ip进行xss注入攻击

    1

    1

    漏洞利用

    logcheck.php页面伪造ip,修改x-forwarded-for的值为xss语句,随后登录账号

    image-20210521182425528


    xss语句也成功插入了数据库,且管理员访问mange.php页面也触发了xss攻击

    image-20210521183012059

    image-20210521183054654


    xss接收平台也收到了管理员的cookie信息

    image-20210521183235251


    六、登录爆破漏洞

    登录爆破漏洞是属于撞库的一种,爆破账号密码时要考虑是否需要输入验证码,若需要输入验证码,则从绕过验证码入手


    审计例子

    从登录页面logCheck.php开始分析

    img


    追踪$_session['captcha'],在admin/captcha.php找到生成验证码的代码, 发现其采用的是随机数机制

    若想要$_session['captcha']值为空,只需清空cookie即可

    img


    漏洞利用

    burpsuite抓包logCheck.php,清空cookie值, 将验证码的post数据更改为空, 随后进行爆破
    1
    1


    修复建议

    在登录页面的验证代码处添加判断验证码是否为空的代码

    img


    七、越权

    可以操作(更改、删除、添加等)用户的信息


    审计例子

    通常越权漏洞存在于涉及用户操作的页面, 例如修改密码, 更新用户数据等等, 此处转到更改用户名字页面updateName.php

    发现$_POST['id']是可控的, 也就说如果我们把ID修改成别人的, 那么相当于把别人的账号给覆盖了

    1


    漏洞利用

    点击更新用户名抓包,修改post数据里的id

    image-20220904172630143

    image-20220904173404004


    修复建议

    将ID参数设置成不可控,将ID设置成session[‘user_id’]变量,即代表当前登录账号的ID

    img


    八、Sql注入

    涉及函数

    addslashes()   //对get,post,cookie传来的数据进行转义,转义内容:单引号双引号、反斜杠,null
    
    • 1

    对于PHP magic_quotes_gpc=on的情况, 我们可以不对输入和输出数据库的字符串数据作addslashes()stripslashes()的操作,数据也会正常显示, stripslashes()的作用是删除addslashes()函数添加的反斜杠

    mysql_real_escape_string()  //转义sql语句中字符串中的敏感字符, 例如\x00, \n, \r, \x1a, 单引号和双引号
    
    • 1
    intval()  //将变量转化成整数型
    
    • 1

    审计例子

    messageSub.php文件发现一处可能存在sql注入的查询语句,SESSION['username']$_POST['message']这两个变量虽然经过魔术引号过滤, 但是依然是可控的, 接下来就寻找给这两个变量赋值的地方

    06O59D6}OA@A{3}R}W44PEB


    通过字符串搜索SESSION['username'], 在登录检验界面logCheck.php发现SESSION['username']的值来源于 $row['user_name']变量,而这个$row['user_name']是数据库中列名为user_name的值,接下来追踪在哪处给数据库插入user_name的值

    1


    在用户注册页面updateName.php页面设置了数据库中列名为user_name的值, 可在注册用户名框插入sql注入语句,现在我们找到了构造SESSION['username']变量的地方,接着寻找构造$_POST['message']的地方

    1


    查看留言页面message.php ,此处有个表单上传的html, 将$_POST['message']的值提交到messageSub.php, 由此可知$_POST['message']的值是留言的内容, 在留言内容框注入sql注入语句

    image-20220901112130035


    漏洞利用

    1.在用户注册页面插入payload: kkk\

    注册后记得要重新登陆, 因为要刷新下$_SESSION['username']的值

    image-20220901113102303

    通过查询数据库的user表发现user_name的值为kkk\,这是因为魔术引号的过滤所导致

    image-20220901171921465


    在注册kkk\这个账号的同时查看mysql监控, 经过转义后插入数据库的值为kkk\

    image-20220901192115975


    2.在用户留言处插入payload:,(select admin_pass from admin limit 0,1),1);#

    sql注入后会显示md5加密后的用户密码

    image-20220901113623765

    image-20220901113633317


    在留言处插入sql语句后查看mysql监控,可知此处执行的sql语句是:INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('kkk\',',(select admin_pass from admin limit 0,1),1);#',now())

    真正执行的sql语句是:INSERT INTO comment(user_name,comment_text,pub_date) VALUES ('kkk\',',(select admin_pass from admin limit 0,1),1);#

    image-20220901192646854


    修复建议

    regCheck.phpupdateName.php插入正则表达式来排除非数字字母字符

    if (!preg_match("/^\w+$/",$clean_username)) {
    		die('用户名只允许\w+');
    	}
    
    • 1
    • 2
    • 3

    1
    1

  • 相关阅读:
    C++ opencv图像存储和MAT容器
    小白零基础自学Java,究竟如何才能学的透彻!
    Unity Shader 溶解效果
    Linux环境下fastdfs部署
    设计模式之观察者模式学习笔记
    webpack 打包 CSS 文件,解析器兼容性问题
    论文精读:Feature Pyramid Networks for Object Detection
    机器学习05|一万五字:SVM支持向量机01 【原理详解篇】
    JVM高频知识合集(面试)【1】
    Zookeeper部署运行_伪集群安装
  • 原文地址:https://blog.csdn.net/xf555er/article/details/128090233