Sebastian's Blog

software developer. security enthusiast.

HACKVent 2019

HV19.13 TrieMe

Sebastian
Challenge Description

So this time we got an web application and the corresponding – following – source code.

package com.jwt.jsf.bean;
import org.apache.commons.collections4.trie.PatriciaTrie;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.io.StringWriter;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import static org.apache.commons.lang3.StringEscapeUtils.unescapeJava;
import org.apache.commons.io.IOUtils;

@ManagedBean(name="notesBean")
@SessionScoped
public class NotesBean implements Serializable {

	/**
	 * 
	 */
	private PatriciaTrie<Integer> trie = init();
	private static final long serialVersionUID = 1L;
	private static final String securitytoken = "auth_token_4835989";

	public NotesBean() {
	    super();
	    init();
	}

	public String getTrie() throws IOException {
		if(isAdmin(trie)) {
			InputStream in=getStreamFromResourcesFolder("data/flag.txt");
			StringWriter writer = new StringWriter();
			IOUtils.copy(in, writer, "UTF-8");
			String flag = writer.toString();

			return flag;
		}
		return "INTRUSION WILL BE REPORTED!";
	}

	public void setTrie(String note) {
		trie.put(unescapeJava(note), 0);
	}
		
    private static PatriciaTrie<Integer> init(){
        PatriciaTrie<Integer> trie = new PatriciaTrie<Integer>();
        trie.put(securitytoken,0);

        return trie;
    }

    private static boolean isAdmin(PatriciaTrie<Integer> trie){
        return !trie.containsKey(securitytoken);
    }

    private static InputStream getStreamFromResourcesFolder(String filePath) {
    	  return Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
    	 }

}

The code creates a trie and stores the security token auth_token_4835989 and a string entered by the user in it. Later it checks if the trie contains the security token, if not, the flag is returned.

I had a closer look on input validation and found the method unescapeJava (line 43). I googled for the method and found the following stack overflow post https://stackoverflow.com/questions/3537706/how-to-unescape-a-java-string-literal-in-java. The first respond says that It forgets about \0 for null. So I just put \0 as user input and got the flag: HV19{get_th3_chocolateZ}.

The actual bug, which is in the patrician trie implementation – not the unescape java function – can be found here.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top