CTF Writeups - CTFSHOW HappyNewYear2022 web7
Challenge Solving
Source File
1 |
|
1 |
|
Unserialization Analyzing
Got phpinfo by accessing /?phpinfo
:
Because session.serialize_handler
was set to php
and its default value is php_serialize
, we can unserialize any object we want. And session.upload_progress.enabled
was set to On
and we have value of session.upload_progress.name
, only we need to do is adding our payload at upload filename then our object will be unserialized.
POP Chain Building
Here is the POP clain: Happy->__destruct() ==> _New_->__get() ==> _New_->__toString() ==> Year->show()
1 |
|
I create a Happy
object called $happy1
as starting object, its __destruct
method will be called during unserialization. This method access happy
attribute of $happy1->happy
, then I create a _New_
object called $new1
and Happy->happy
was set to it, $new1->__get
magic method will be called because _New_
class does not have happy
attribute. $new1->__get
will connect $new1->daniu
with some string
, which will convert $new1->daniu
into string
if its type is not string. Then I create another _New_
object called new2
and $new1->daniu
was set to it, $new2->__toString
will be called when calling $new1->__get
method converting $new2
into string
. $new2->__toString
will setup a specific attribute of $new2->daniu
with specific value, and convert $new2->daniu
, then I create a Year
object called year1
and $new2->daniu
was set to it, set $new2->robot
and $new2->notrobot
to zodiac
and /etc/passwd
so that the $year1->zodiac
will be set to /etc/passwd
, then $year1->__toString
will be called and $year1->show
show the file content of /etc/passwd
. I didn’t use Year
class directly because Year->__wakeup
method will reset $year1->zodiac
, so I have to use $new2->toString
to setup $year1->zodiac
dynamically.
Exploit
Now we have the payload to unserialize, so we can read any file. Let’s catch requests in burp and insert our payload.
1 | <form action="http://276c305a-1877-4365-bab1-45cd8da4be3b.challenge.ctf.show/index.php" method="POST" |
Reading /etc/passwd
file successfully, but the flag is not at /flag
. Here is a hint from ctfshow:
This hint tells us the flag is in other process, follow the hint I start to scan the process through /proc/pid/cmdline
. Then I found a python process has pid 114
.
1 | from flask import * |
This python script open the flag file without close, then remove the file. I test actions like this through an local script, and I found removed file can still access from script at /proc/pid/fd/3
. Then read this file through http://127.0.0.1:5000/download/?filename=/proc/pid/fd/3
.
Summarize
This time I used some tricks I learned from hackthebox. This is positive feedback for me to spend more time on hackthebox next. Maybe it’s not a bad idea Hah?
And the ctfshow lottery drew me and gave me a one-month bilibili membership as a prize, thanks.