R3CTF 2024 WriteUp

R3CTF event.

Format: Jeopardy !

Official URL: https://ctf2024.r3kapig.com/

misc

Welcome

check our discord

https://discord.gg/zU64ekBsgA

it’s hide into #rules

image-20240609161132408

1
R3CTF{welcome_to_R3CTF2024}

Blizzard CN Restarts

Warriors of the night, assemble!

R3ctf.w3x: Warcraft III map file

May i need a Game Map Editor

But im lazy(

use 010 editor to analyze the w3x file

image-20240609162359235

we can see that this is actually an MPQ file

use winMPQ to extract it

image-20240609164316378

then try to find flag mark string

image-20240609164429822

1
r3ctf{Elune_be_with_you}

hideAndSeek

Ben is a superpower who loves playing hide and seek. He can teleport to anywhere to no one can find him, but he seems unaware that his ability only works within a certain range

Rules:

  1. The adorable Ben will only appear within the range of (0, -50, 0) to (128, 50, 128).
  2. Ben will every 10 seconds and reappear in a new location after 10 seconds.
  3. A “newtp” has been added for all players to teleport to any coordinates.

Connect info: 34.81.163.238

version 1.19.2

oh, its my favorite Minecraft chal

When i join the game , a player named Ben confused my thinking(😢

Some cheating means found that an entity will be refreshed in the specified area

I chose to write script with the nodejs library mineflayer, to get the name of the entity

this library was found while i playing Minecraft

 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
const mineflayer = require('mineflayer')
// const { mineflayer: mineflayerViewer } = require('prismarine-viewer')
const bot = mineflayer.createBot({
    host: '34.81.163.238',
    // host: '127.0.0.1',
    // port: 23333, 
    username: 'Abot', 
})

bot.on('death', () => {
    console.log('Bot died. Restarting...')
    bot.respawn()
})
bot.on('login', () => {
    console.log(`Logged in as ${bot.username}`)
    bot.chat('/newtp 64 0 64')
    setInterval(printNearbyEntities, 350)
})
function printNearbyEntities() {
    const entities = Object.values(bot.entities)
    entities.forEach(entity => {
        entityName = getVillagerName(entity)
    })
}

function getVillagerName(entity) {
    const name = entity.metadata[2]?.toString() || 'Unknown'
        if (name != 'Unknown' & name != 'undefined') {
            // return eneity.metadata
            console.log(name)
        }
    }


bot.on('error', (err) => {
    console.log('An error occurred:', err)
})

bot.on('end', (err) => {
    console.log(err)
})

stand on the 64, 0 ,64 to get the metadata in entitys

image-20240609172133307

1
R3CTF{Jus7_play_m0r3_h1de_2nd_seek_w1th_Ben}

h1de@ndSe3k

After hard training, Ben greatly expanded his teleportation range and now he has also learned how become invisible. Surely no one will be able to find him, right?

Rules:

  1. The adorable Ben now appear within the range of (0, -50,0) to (512,50, 512).
  2. The newtp command can only be used within Ben’s appearance range.
  3. Ben will become invisible.

Server:34.81.163.238:23333

its the Revenge of hideAndSee

only need to teleport in the 0-512 range, nothing else needs to be changed.

u don’t have to change the rest of it, or teleport, of course, but it’s much faster if u do it on your own

Of course it’s fine without teleporting, but active teleportation will work much faster

 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
const mineflayer = require('mineflayer')
// const { mineflayer: mineflayerViewer } = require('prismarine-viewer')
const bot = mineflayer.createBot({
    host: '34.81.163.238',
    // host: '127.0.0.1',
    port: 23333, 
    username: 'Abot', 
})

bot.on('death', () => {
    console.log('Bot died. Restarting...')
    bot.respawn()
})
bot.on('login', () => {
    console.log(`Logged in as ${bot.username}`)
    executeTeleportCommands()
    // bot.chat('/newtp 64 0 64')
    setInterval(printNearbyEntities, 350)
})
function printNearbyEntities() {
    const entities = Object.values(bot.entities)
    entities.forEach(entity => {
        entityName = getVillagerName(entity)
    })
}

function getVillagerName(entity) {
    const name = entity.metadata[2]?.toString() || 'Unknown'
        if (name != 'Unknown' & name != 'undefined') {
            // return eneity.metadata
            console.log(name)
        }
    }

    async function executeTeleportCommands() {
        while (1) {
        y = 0
        for (let x = 0; x <= 512; x=x+64) {
                for (let z = 0; z <= 512; z=z+64) {
                    bot.chat(`/newtp ${x} ${y} ${z}`)
                    console.log(`Teleporting to ${x}, ${y}, ${z}`)
                    await new Promise(resolve => setTimeout(resolve, 1000));
                }
            }
        }
    }

bot.on('error', (err) => {
    console.log('An error occurred:', err)
})

bot.on('end', (err) => {
    console.log(err)
})

image-20240609173536795

It takes less than 10 seconds

64 at the most

1
R3CTF{You_2re_rea1ly_g00d_at_wr1ting_minecraft_sc2ip7s}

its easy alright?

Thief

Can you help Cain steal the data for the rec’s model?

Tips: you need to wait 15-20min let instance run!

analysis with ChatGPT

guess the top10 value has some relations of num

try to guess the threshold

1 is invalid

image-20240610035537037

but 0.9 is valid

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from pwn import *
r = remote("ctf2024-entry.r3kapig.com", 30694)

for i in range(500):
    r.recvuntil(b'top_10_pred :')
    data=r.recvline()
    threshold = 0.9
    top_10_pred = eval(data)[0]
    max_prob = max(top_10_pred)
    if max_prob > threshold:
        inp = 1
    else:
        inp = 0
        
    success(f"{i+1} {inp}")
    r.sendlineafter(b'set?',str(inp).encode())
context.log_level = 'debug'
r.interactive()

actually 0.8 is valid

image-20240610035621778

1
R3CTF{CA1N_IikE_ai_AnD_R3C_1f38d2218a12}

File Share(UNDO😢)

I have a file sharing service built with Kubernetes, I thought there were no secrets in it.

nc 47.242.249.168 8888

Do NOT click the create instance button, it doesn’t work

really thx for deploy basic infra help of p4ck3t0 and diff-fusion

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Please input the team token:338:VXhY+fy3ppzlmIpgl0p0hcD+TTq3RSMOCUKPuDvpgiKUFdKiTlMt0mIwEfcA8VcU9PNZOTC91k27sGqcDQ7ACQ==

     _____      _    __
 _ _|___ /  ___| |_ / _|
| '__||_ \ / __| __| |_
| |  ___) | (__| |_|  _|
|_| |____/ \___|\__|_|


Challenge: File Share
Creating Cluster
Waiting for control plane............................................................................................................................
Here is your Kubernetes information:


server_port: https://47.242.249.168:33068
token: eyJhbGciOiJSUzI1NiIsImtpZCI6Im9BaUNjbGZWck1uZXVPa2NWeFhBUmRrREU5eFNYN0lGWUhpWUJnVlZOQTgifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzE3OTU3MDQ2LCJpYXQiOjE3MTc5NTM0NDYsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6ImN0Zi1wbGF5ZXIiLCJ1aWQiOiI5ZGRjZmZjOS1mZjNhLTQxNzYtYTY2Zi1kNzIwMzhmMGM2NjMifX0sIm5iZiI6MTcxNzk1MzQ0Niwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6Y3RmLXBsYXllciJ9.c_6LO_zxZeTUSX0uCOrgy4Oj3_2Fe2Bh-x2cI7ZGKcGU5p1w3zaI934JE1sdqUCF8atc5ghJL33P4J9xVNAfS3t1MW0KJFWIm9EzSqACaLvNASnZEeVnYIrRIFbAxMe-NHDqYs8vsURk1no2IlxX9TiyZ3_FCwX0LVWOJz1-3O2TOXOsRFsYZfmSk2uoW7nqEd0iaa8UzFTtqEbYTgzcPeRHQ6AVeNliZmf125Op1ASQ27uZuJjKpSUgKfJi4EBIYs-FcwuDDHPmTYBBx9vYu1pcdMXFyuiFDJQrqts4-On312O71ABNYMrj5cx_IMXux55a4W0L-v5jW7E2B6vY-w

Leave this open until you solved the challenge, otherwise your cluster will be deleted. This config is only valid for 1 hour.

can use kubectl to connect to the k8s api

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
clusters:
- cluster:
    insecure-skip-tls-verify: true
    server: https://47.242.249.168:33068
  name: my-cluster
contexts:
- context:
    cluster: my-cluster
    namespace: shares
    user: default
  name: my-context
current-context: my-context
kind: Config
preferences: {}
users:
- name: default
  user: 
    token: eyJhbGciOiJSUzI1NiIsImtpZCI6Im9BaUNjbGZWck1uZXVPa2NWeFhBUmRrREU5eFNYN0lGWUhpWUJnVlZOQTgifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzE3OTU3MDQ2LCJpYXQiOjE3MTc5NTM0NDYsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6ImN0Zi1wbGF5ZXIiLCJ1aWQiOiI5ZGRjZmZjOS1mZjNhLTQxNzYtYTY2Zi1kNzIwMzhmMGM2NjMifX0sIm5iZiI6MTcxNzk1MzQ0Niwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6Y3RmLXBsYXllciJ9.c_6LO_zxZeTUSX0uCOrgy4Oj3_2Fe2Bh-x2cI7ZGKcGU5p1w3zaI934JE1sdqUCF8atc5ghJL33P4J9xVNAfS3t1MW0KJFWIm9EzSqACaLvNASnZEeVnYIrRIFbAxMe-NHDqYs8vsURk1no2IlxX9TiyZ3_FCwX0LVWOJz1-3O2TOXOsRFsYZfmSk2uoW7nqEd0iaa8UzFTtqEbYTgzcPeRHQ6AVeNliZmf125Op1ASQ27uZuJjKpSUgKfJi4EBIYs-FcwuDDHPmTYBBx9vYu1pcdMXFyuiFDJQrqts4-On312O71ABNYMrj5cx_IMXux55a4W0L-v5jW7E2B6vY-w

kubeconfig.yaml

1
2
3
4
5
6
7
8
❯ kubectl get ns

NAME              STATUS   AGE
default           Active   9m25s
kube-node-lease   Active   9m25s
kube-public       Active   9m25s
kube-system       Active   9m25s
shares            Active   8m59s

found a custom namespaces shares

the shares ns permission more than another

 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
❯ kubectl auth can-i --list --namespace=shares

Resources                                       Non-Resource URLs                      Resource Names   Verbs
pods.*/exec                                     []                                     []               [create]
selfsubjectreviews.authentication.k8s.io        []                                     []               [create]
selfsubjectaccessreviews.authorization.k8s.io   []                                     []               [create]
selfsubjectrulesreviews.authorization.k8s.io    []                                     []               [create]
namespaces.*                                    []                                     []               [get list watch]
persistentvolumes.*                             []                                     []               [get list watch]
filesharerequests.*                             []                                     []               [get watch list create update delete]
fileshares.*                                    []                                     []               [get watch list]
persistentvolumeclaims.*                        []                                     []               [get watch list]
                                                [/.well-known/openid-configuration/]   []               [get]
                                                [/.well-known/openid-configuration]    []               [get]
                                                [/api/*]                               []               [get]
                                                [/api]                                 []               [get]
                                                [/apis/*]                              []               [get]
                                                [/apis]                                []               [get]
                                                [/healthz]                             []               [get]
                                                [/healthz]                             []               [get]
                                                [/livez]                               []               [get]
                                                [/livez]                               []               [get]
                                                [/openapi/*]                           []               [get]
                                                [/openapi]                             []               [get]
                                                [/openid/v1/jwks/]                     []               [get]
                                                [/openid/v1/jwks]                      []               [get]
                                                [/readyz]                              []               [get]
                                                [/readyz]                              []               [get]
                                                [/version/]                            []               [get]
                                                [/version/]                            []               [get]
                                                [/version]                             []               [get]
                                                [/version]                             []               [get]
pods                                            []                                     []               [get]
❯ kubectl auth can-i --list --namespace=default
Resources                                       Non-Resource URLs                      Resource Names   Verbs
selfsubjectreviews.authentication.k8s.io        []                                     []               [create]
selfsubjectaccessreviews.authorization.k8s.io   []                                     []               [create]
selfsubjectrulesreviews.authorization.k8s.io    []                                     []               [create]
namespaces.*                                    []                                     []               [get list watch]
persistentvolumes.*                             []                                     []               [get list watch]
                                                [/.well-known/openid-configuration/]   []               [get]
                                                [/.well-known/openid-configuration]    []               [get]
                                                [/api/*]                               []               [get]
                                                [/api]                                 []               [get]
                                                [/apis/*]                              []               [get]
                                                [/apis]                                []               [get]
                                                [/healthz]                             []               [get]
                                                [/healthz]                             []               [get]
                                                [/livez]                               []               [get]
                                                [/livez]                               []               [get]
                                                [/openapi/*]                           []               [get]
                                                [/openapi]                             []               [get]
                                                [/openid/v1/jwks/]                     []               [get]
                                                [/openid/v1/jwks]                      []               [get]
                                                [/readyz]                              []               [get]
                                                [/readyz]                              []               [get]
                                                [/version/]                            []               [get]
                                                [/version/]                            []               [get]
                                                [/version]                             []               [get]
                                                [/version]                             []               [get]

can found the flagpv

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
❯ kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
flagpv   1Gi        ROX            Retain           Available                                   27m
❯ kubectl describe pv
Name:            flagpv
Labels:          <none>
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    
Status:          Available
Claim:           
Reclaim Policy:  Retain
Access Modes:    ROX
VolumeMode:      Filesystem
Capacity:        1Gi
Node Affinity:   <none>
Message:         
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /flag
    HostPathType:  

but there’s no way to get the value

fsr is a crd ,but docs is empty

nooo

 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
❯ kubectl explain filesharerequests
GROUP:      ctf.r3kapig.com
KIND:       FileShareRequests
VERSION:    v1

DESCRIPTION:
    <empty>
FIELDS:
  apiVersion    <string>
    APIVersion defines the versioned schema of this representation of an object.
    Servers should convert recognized schemas to the latest internal value, and
    may reject unrecognized values. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

  kind  <string>
    Kind is a string value representing the REST resource this object
    represents. Servers may infer this from the endpoint the client submits
    requests to. Cannot be updated. In CamelCase. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

  metadata      <ObjectMeta>
    Standard object's metadata. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

  spec  <Object>
    <no description>

cannot find the crd filesharerequests usage

and cant get the pods name to exec

GG

Waiting for WP

forensics

TPA 01 Attachment too big, not enough phone traffic

TPA 02 - 📱

Peggy is an employee at a company and, like many others, occasionally uses her personal mobile phone for work-related tasks. Unfortunately, she has become the target of a phishing attack. Your task is to uncover the details of this attack by finding the attacker’s phone number and Peggy’s password.

Submit your findings in the format r3ctf{number_password}. For the phone number, remove any symbols and spaces. For example, if the attacker’s phone number is +1 123-456-7890 and the password Peggy entered is passwd, your flag should be r3ctf{11234567890_passwd}.

analysis the pcapng

password can be found in tcp stream 31

l0v3_aNd_peace

then try to find tel in another file

the tcp stream 34 can found

1
GET /search?q=IT+deptment+SMS

strings + grep to find the location /data/com.android.providers.telephony

image-20240610041309388

open the sqlite file and open the SMS table

we can found the +15555215558 and +15555215556

image-20240610041543147

the true flag is

1
r3ctf{15555215558_l0v3_aNd_peace}
0%