2025 HITCON CTF - writeup
Author : 堇姬 Naup
Note some cool challenge which i meet
Final scoreboard
Pholyglot! - 🍊
1 |
|
Have one sql injection
We can use like this to RCE
1 | <?=`id`;');VACUUM+INTO('y.php |
But it still use three bytes to command injection.
We can use *>a + ls let filename become command and write command to file.
And then using bash execute this file.
The last piece is to put the php webshell together and finally write it into v.php
We can get RCE and execute /read_flag
We use webshell and brute force until math problem answer is 0.
so fun~
PS: hash is md5(orangeXXX.XXX.XXX.XXX)
1 | import requests |
hitcon{PHP-1s-my-b0dy-4nd-SQL-1s-my-bl00d}
simp - misc
1 | #!/usr/local/bin/python3 |
We can import module and set this module’s value of a variable.
Use venv gadget
https://github.com/python/cpython/tree/3.13/Lib/venv
when you import venv.__main__
It will execute, __init__.py
If we overwrite argv, it wil create a/...
This folder have many many file, like bin/, python3.13 or etc.
And it will output some error:
When you trace context, it is sys._base_executable
If we overwrite _base_executable
First it will build a symlink point to sys._base_executable
For example:sys._base_executable = "aaa"/home/ctf/b/bin/aaa --> aaa
So when we set sys._base_executable = /bin/sh
this command can run a/bin/sh -m ensurepip --upgrade --default-pip
This command will call /bin/sh -m ensurepip --upgrade --default-pip
More can read source code about venv
resource
But /bin/sh will get error
Finally, We use /bin/tclsh open one tclsh shell.
But it doesn’t have stdout, so use curl to send flag on my server.
1 | from pwn import * |
hitcon{__import__(“chalenge”).solved=true}
Simple driver and revenge - crypto
We found that cookie is generated by random.randbytes(32) and same does ecdsa signature nonce k
1 | def gen(): |
1 | def sign(self, m): |
We need 78 × 32 bytes (624 × 32 bits) to restore the random state, , but we can obtain at most 50 cookies.
So we can wait 60 seconds, and the cookies will expire.
1 | def __init__(self, user): |
Then we can request the auth_router with the expired cookies, and the server will delete them.
So we can request new 28 cookies.
Use cookie get continuous random numbers, and we can use randcrack predict k
We can use /backup get r,s.
And use hash get z.
We will use r,s,k,z restore d
We can use symlink (link to /flag) and zip.
And use d sign new signature.
When we call /restore and try to read flag.
We can get flag.
1 | import requests |
after all
So fun~