Japanese version: https://hackmd.io/s/rk-iwwpo4
CSS injection and XSS.
FLAG is in admin's cookie.
Injecting evil css containing attribute-selector, we can steal nonce
attribute of script
tag.
With a nonce, we can inject XSS code and bypass CSP restriction, because the nonce used multiple times.
Exploit is below:
Then, report URL of this code.
Admin's browser will execute an evil code and send FLAG to our server.
SHA-1 collision (SHAttered).
Earn much balance to get the FLAG.
Transferring balance to oneself causes unexpected doubling of balance, but this request is prohibited.
Database retains SHA-1 hashed value of username as an user's ID, but /api/transfer
compares username to check whether the receiver is same as the sender or not.
Therefore, a pair of different usernames which have same SHA-1 hash value breaks this application.
We can easily generate such pair of usernames using SHAttered PDF.
Such like this:
Now, we can double our balance again and again, and obtain a FLAG.
XS-Searching.
Use XSS Auditor to know admin's secret information.
We can inject arbitrary HTML codes into profile page, but any script will be blocked by CSP.
If we report suspicious user, then admin checks that user's page.
We can embed IFRAME into that page, so we can make admin's browser jump to any URL.
The profile page also have answer for secret question … as a JavaScript code!
In this page, the header X-XSS-Protection: 1; mode=block
is sent. So XSS Auditor is working as block mode.
XSS Auditor inhibits loading this page with query such like ?onchange="grapes.checked=false;"
.
This behavior is undesirable, because it may be a risk of information leaks.
Then, we made an evil page, which contains two IFRAMEs.
IFRAME loads self-profile page with query, ?onchange="grapes.checked=true;"
and ?onchange="grapes.checked=false;"
.
Measuring loading time of two frames, we are able to know which frame is blocked –- in other words, this is which checkbox is checked.
Exploit script:
With that information, we can view admin's secret message (FLAG).
Fortunately, we know a very similar problem: hxpCTF2017 flea.
When we decide the lower bits of , xor constraints and multiply constraints must be satisfied in the lower bits.
We hold this constraints and manage DFS to decide bits of from LSB to MSB, one bit by one bit.
The below program will be end in a few minute.
TSGCTF{Absolutely, X should be 'S' in 'OPQRX'.}
Chinese Reminder Theorem on (Eisenstein Integer).
In this problem, we know add/sub/mul/div/mod operations for Eisenstein Integer, so we use them to reconstruct flag.
Because of my misunderstanding or bugs, some of calculation results go wrong. So we fix them by hand(take one of from six units, then multiply it).
Using Error Level Analysis of Forensically, generated a slightly readable image.
Then, guessed hard.
We got a git local repository.
Viewing the commits, we detected the commit that contains flag
file.
So, we checkout this commit.
Change main.cr
for output flag
.
Execute.
git gc
was extecuted, so we viewed .git/packed-refs
.
Checkout 1c80e25f
.
After that, the same as Obliterated File.
We got a ttf file.
As stated, we tried typing some flags.
Typing TSGCTF{flag}
, it is displayed as TSGCTF{flag} is incorrect
if flag
is incorrect.
We opened it by FontForge.
glyph346
is displayed as } is correct
.
glyph347
is displayed as } is incorrect
.
Viewing Element > Font Info > Lookups
, many ligatures are configured.
We've only to get what string is displayed as is correct
from this configurations.
We used fonttools.
Search glyph00346
which is displayed as } is correct
.
In a certain string, }
shows glyph00346
.
We focused on <Lookup index="51">
, and searched "51"
.
Next, search glyph00140
.
In a certain string, e
shows glyph00140
.
After that, index="130"
→glyph00219
(n
)→…
So we got TSGCTF{ligature_state_machine}
.
Try typing the flag.
Decoded input
with the following script.
The result was below.
Formatted the result, guessing.
With the given Dockerfile
, built the problem
image and started a container on it.
In the container, removed /dev/urandom
and /dev/random
and recreated /dev/random
with the following commands.
Following the decoding result, built a modified OpenSSL binary. However, re-modified get_time_stamp()
in crypto/rand/rand_unix.c
like that:
Reading OpenSSL source codes, understood there were 3 factors randomizing the key.pem
generation, which were /dev/random
, the generating time and the generating process's ID.
The decoding result tells correct /dev/random
and the correct generating time, but the correct PID remained unknown.
Therefore, copied encrypted
into the container, and then did a blute-force attack with the following commands.
Finally, found the flag.