classloader

problem

image

image

source.py

#!/usr/bin/env python3

from subprocess import run

from flask import Flask, request, Response, redirect
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
app = Flask(__name__)
limiter = Limiter(
    get_remote_address,
    app=app,
    default_limits=["5000 per hour"],
    storage_uri="memory://",
)

@app.route('/', methods=["GET"])
@limiter.limit("5/second")
def index():
    if "source" in request.args:
        return Response(open(__file__).read(), mimetype='text/plain')
    if "dockerfile" in request.args:
        return Response(open('Dockerfile').read(), mimetype='text/plain')
    return open("index.html").read()

@app.route('/java', methods=["POST"])
@limiter.limit("1/second")
def java():
    java_class = request.form['class']
    proc = run(['java', '-jar', 'challenge.jar', java_class], capture_output=True, timeout=1)
    return {'stdout': proc.stdout.decode(), 'stderr': proc.stderr.decode()}

if __name__ == "__main__":
    app.run('0.0.0.0', 5000)

Dockerfile

FROM amazoncorretto:20-alpine

ENV PYTHONUNBUFFERED=1
RUN apk add --update --no-cache python3 && ln -sf python3 /usr/bin/python
RUN python3 -m ensurepip
RUN pip3 install --no-cache --upgrade pip setuptools

WORKDIR /app 

COPY Dockerfile .
COPY requirements.txt .
RUN pip3 install -r requirements.txt 

COPY challenge.jar .

COPY index.html .
COPY app.py .

CMD python3 app.py

solution

here, we dont know the challenge.jar source code, but we can side channel this (i think that is what it is called)

input: 2

image

it says that the class name must contain a ., so i put in a .

input: Test.2

image

then, it says invalid base 64, so i put it some base64

input: Test.dGVzdA==

image

then it says truncated class file, so i assume that the base64 encoded thing has to be a class.

i then put in a compiled java class file which has an empty class

public class Hack { }

input: Hack.yv66vgAAADQADQoAAwAKBwALBwAMAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAClNvdXJjZUZpbGUBAAlIYWNrLmphdmEMAAQABQEABEhhY2sBABBqYXZhL2xhbmcvT2JqZWN0ACEAAgADAAAAAAABAAEABAAFAAEABgAAAB0AAQABAAAABSq3AAGxAAAAAQAHAAAABgABAAAAAQABAAgAAAACAAk=

image

so it looks like we have to have a printFlag(String flag) method

now,

public class Test {
    public static void printFlag(String test) {
        System.out.println(test);
    }
}

input: Test.yv66vgAAADQAGgoABQAOCQAPABAKABEAEgcAEwcAFAEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAAlwcmludEZsYWcBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAApTb3VyY2VGaWxlAQAJVGVzdC5qYXZhDAAGAAcHABUMABYAFwcAGAwAGQALAQAEVGVzdAEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4AIQAEAAUAAAAAAAIAAQAGAAcAAQAIAAAAHQABAAEAAAAFKrcAAbEAAAABAAkAAAAGAAEAAAABAAkACgALAAEACAAAACQAAgABAAAACLIAAiq2AAOxAAAAAQAJAAAACgACAAAAAwAHAAQAAQAMAAAAAgAN

image