Mariusz Bartosik's website

Graphics programming, demoscene and book reviews

BlueHens CTF The Immortal Game write-up

Chess piece king on a chessboard

On November 8, the University of Delaware, in partnership with BSides Delaware, hosted a 36-hour CTF competition. Open to all-levels teams, the event challenged participants across categories like cryptography, reverse engineering and web exploitation. In this write-up, we’ll explore one of the standout challenges from the competition: The Immortal Game. This 500-point forensics challenge saw only three successful solves.

Category: Forensics

Points: 500
Solves: 3 out of 498 teams

Author: riiyak

Challenge:
184.60.121.146:53
make your move.

Initial recon

We begin with the IP address of a DNS server operating on the standard port 53. Using the dig command, we can gather additional information. Our first step is to perform a reverse lookup to find the domain name associated with this IP:

dig @184.60.121.146 -x 184.60.121.146

This command asks the specific DNS server (@184.60.121.146) to return the domain name assigned to the IP. In this case, we get:

146.121.60.184.in-addr.arpa. 604800 IN	PTR	yatznetlab.ctf.

If you omit the @ part, the request will be handled by your network’s DNS, which might return a different result, such as:

146.121.60.184.in-addr.arpa. 43200 IN   PTR     h184-60-121-146.clevwi.dedicated.static.tds.net.

One more thing: If you’re not getting responses, your requests may be blocked by a firewall. In that case, try an online dig tool like diggui.com or digwebinterface.com, which work well for this purpose.

DiG Web Interface
DiG GUI – DiG Web Interface

Discovering the Domain Records

With the domain name in hand, we can query the server for more information:

dig @184.60.121.146 yatznetlab.ctf ANY +multiline

I used the +multiline option for a clearer, formatted view of the certificate.

Note: The ANY query type is deprecated as per RFC8482, which limits the usefulness of ANY queries. See RFC8482 – Saying goodbye to ANY for further disscusion. If you encounter issues, make individual requests for A, CNAME, MX, TXT, CERT, and other record types. Here’s the server’s response:

yatznetlab.ctf.		604800 IN SOA localhost. root.localhost. (
				2          ; serial
				604800     ; refresh (1 week)
				86400      ; retry (1 day)
				2419200    ; expire (4 weeks)
				604800     ; minimum (1 week)
				)
yatznetlab.ctf.		604800 IN NS localhost.
yatznetlab.ctf.		300 IN A 184.60.121.146
yatznetlab.ctf.		604800 IN CERT PKIX 0 0 (
				MIIEODCCAyCgAwIBAgIUcMHAP9GAMSHIbzpJwOBwGc8b
				jq4wDQYJKoZIhvcNAQELBQAwgaYxCzAJBgNVBAYTAlVT
				(...)
				)

Pretty standard reply and, unfortunatelly, there’s no TXT entry with a flag here.

Playing chess with a DNS server

At this point we have to think what this task is all about. The name is The Immortal Game, and the description says “make your move”. If you look up the name in Google, the first result points to online chess platform immortal.game. But the server doesn’t return anything interesting about this domain.

The second one is Wikipedia page for Immortal Game, a classic 1851 chess match between Adolf Anderssen and Lionel Kieseritzky. It is well-known among chess fans for its brilliant strategy and sacrifices. There are annotated moves of this game, and if we have to make our move, we play White and start with pawn to e4.

We send our first query to see the response:

dig @184.60.121.146 e4.yatznetlab.ctf ANY

The server responds with:

e4.yatznetlab.ctf.	300	IN	CNAME	e5.133f595e-bcdb-a407-74d2a95.yatznetlab.ctf.

The CNAME (Canonical Name) record indicates that e4.yatznetlab.ctf is an alias for another domain, e5.133f595e-bcdb-a407-74d2a95.yatznetlab.ctf. The server is responding with the Black move e5.

Checking this domain for clues:

dig @184.60.121.146 133f595e-bcdb-a407-74d2a95.yatznetlab.ctf ANY

We receive a TXT entry:

133f595e-bcdb-a407-74d2a95.yatznetlab.ctf. 300 IN TXT "cJr7g<g45}?vj{_w*ut6Ge}"

After analyzing this string in many ways as various ciphers, I was unable to convert it to a proper flag in udctf{} format.

We must continue following the chess game’s moves. According to the game’s record, Anderssen proposes his pawn in exchange for faster development, f4. This is called the King’s Gambit.

The Immortal Game 3

We query the next move:

dig @184.60.121.146 f4.133f595e-bcdb-a407-74d2a95.yatznetlab.ctf ANY

The server’s response shows the gambit is accepted with exf4:

f4.133f595e-bcdb-a407-74d2a95.yatznetlab.ctf. 300 IN CNAME exf4.07cb4fe8-459c-8d80-2b21535.yatznetlab.ctf.
The Immortal Game 4

Is there something in TXT record for us?

dig @184.60.121.146 07cb4fe8-459c-8d80-2b21535.yatznetlab.ctf ANY

Yes, another cryptic string:

07cb4fe8-459c-8d80-2b21535.yatznetlab.ctf. 300 IN TXT "h4dJsB>zR-6wph_a`RCf$CC"

You have to repeat these steps using 23 moves from the Immortal Game and collect all TXT entries.

The Immortal Game – complete match, courtesy of chess.com

Try harder

After check-mating opponent’s king with Be7# move:

dig @184.60.121.146 Be7#.6f159061-42f5-9124-8c46dfb.yatznetlab.ctf ANY

the server doesn’t really want to give up and sends us a classic “try harder” instead of the flag:

Be7#.6f159061-42f5-9124-8c46dfb.yatznetlab.ctf.	300 IN CNAME tryharder.f0c89234-46de-8f0d-8efdfb4.yatznetlab.ctf.

Apparently this in not the end, so let’s analyze what we have. Each query gave us one string:

cJr7g<g45}?vj{_w*ut6Ge}
h4dJsB>zR-6wph_a`RCf$CC
e}<NqRWq-WBm^3b.$c3zw#,
c72a$%t,uc@hkQxrX4gSc>'
k9PxK?.f7&U%$Ydu'6,&d*c
_Q~d@Q=,W{Q>ch5eU$Cqmxb
ck7F$9cW4h>4V/##ed5fn.a
e@5nA!xY8mWx5fa_{s>k4QP
r#CaRDCQy<S$Aa@_.?&n}pV
tgJ~#m%%GUc}m}BRQy6w&@A
_&axv2jMR3HK!FZ=5{}-h8#
r4}eU6<#Y_HpBh4*b%&sGxP
eN.7F>V{Ng-Rst2wRHHD^qg
c=s4JmagD*q<r?rv5QFBps@
o@S%D=UD=FD=_-wQm#BrHa-
r@6F<7-3FYU@XW1FvqE9E@1
dPs>E-<=#jm$91k8-_!`-UV
_c@?x}-nV-xjk@gb*T_2N?y
@z-a2e_UW@BasPjju,&@-k-
rX6-y3XV~FDYTn`,Q-{s-H~
ora7f}q6UuV8m^h}~QWgYp.
o7Kq@vq@T!r#hnjaQkGTdw#
tsmy5%vy~}?,y7>bK7g#Qmd

This isn’t base64 encoded string, decoding from standard ciphers with various parameters also doesn’t reveal anything meaningful. However, there’s a hint: reading the first letter of each string yields: check_cert_record_@root. As this is our only remaining unanalyzed artefact, it might be worth investigating further.

After saving it to a file and decoding from base64 as ctf.cer:

openssl x509 -noout -text -in ctf.cer
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            70:c1:c0:3f:d1:80:31:21:c8:6f:3a:49:c0:e0:70:19:cf:1b:8e:ae
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = DC, L = Newark, O = University of Delaware, OU = Computer Sciences, CN = dns.yatznetlab.ctf, emailAddress = [email protected]
        Validity
            Not Before: Jun 23 03:00:15 2024 GMT
            Not After : Apr 13 03:00:15 2027 GMT
        Subject: C = US, ST = DC, L = Newark, O = University of Delaware, OU = Computer Sciences, CN = dns.yatznetlab.ctf, emailAddress = [email protected]
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:dc:ad:00:27:6c:22:e1:75:3d:ce:b0:c8:fd:d9:
                    f1:6b:d1:04:a9:16:f7:bf:36:dd:fb:b8:86:81:59:
		    (...)
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:1803180708100206200917102304170314180710042210
            X509v3 Subject Key Identifier:
                70:BF:8D:43:E2:EE:F7:BD:E7:B3:44:8B:31:83:7E:57:74:96:03:21
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        7a:fe:6c:88:2e:fb:06:57:e5:55:3d:62:c4:71:12:c0:d3:66:
        7d:bc:14:2f:1c:38:83:b5:01:f7:35:77:fe:32:23:4c:98:f1:
	(...)

Notice a strange Subject Alternative Name: 1803180708100206200917102304170314180710042210. It doesn’t look like a typical hex byte string, but it has 46 digits, twice the number of chess moves and random strings.

If you extract every n’th letter from each string:

18 cJr7g<g45}?vj{_w*ut6Ge}
03 h4dJsB>zR-6wph_a`RCf$CC
18 e}<NqRWq-WBm^3b.$c3zw#,
07 c72a$%t,uc@hkQxrX4gSc>'
08 k9PxK?.f7&U%$Ydu'6,&d*c
10 _Q~d@Q=,W{Q>ch5eU$Cqmxb
02 ck7F$9cW4h>4V/##ed5fn.a
06 e@5nA!xY8mWx5fa_{s>k4QP
20 r#CaRDCQy<S$Aa@_.?&n}pV
09 tgJ~#m%%GUc}m}BRQy6w&@A
17 _&axv2jMR3HK!FZ=5{}-h8#
10 r4}eU6<#Y_HpBh4*b%&sGxP
23 eN.7F>V{Ng-Rst2wRHHD^qg
04 c=s4JmagD*q<r?rv5QFBps@
17 o@S%D=UD=FD=_-wQm#BrHa-
03 r@6F<7-3FYU@XW1FvqE9E@1
14 dPs>E-<=#jm$91k8-_!`-UV
18 _c@?x}-nV-xjk@gb*T_2N?y
07 @z-a2e_UW@BasPjju,&@-k-
10 rX6-y3XV~FDYTn`,Q-{s-H~
04 ora7f}q6UuV8m^h}~QWgYp.
22 o7Kq@vq@T!r#hnjaQkGTdw#
10 tsmy5%vy~}?,y7>bK7g#Qmd

You get the final flag: udctf{k!nG5_g4m61T_F7w}

Summary

This challenge was pretty hardcore – not quite a full chess match with the server, but still demanding in time and complexity. I would like to thank Professor Andrew Novocin aka ProfNinja and the BlueHens CTF team for not telling me “try harder” in a moment of confusion with this task.

While this particular challenge was tricky, most of the BlueHens CTF challenges were accesible and we managed to secure 5th place out of 498 teams. I’m looking forward to the next edition of this CTF!

Avatar

Written by Mariusz Bartosik

I'm a software engineer passionate about 3D graphics programming and the demoscene. I'm also an educator and enthusiast of e-learning. I enjoy reading books. In my free time, I secretly work in my lab on the ultimate waffles with whipped cream recipe.

Comments

Leave a Reply

Required fields are marked *. Your email address will not be published. You can use Gravatar to personalize your avatar.

Allowed HTML tags: <blockquote> <a href=""> <strong> <em> <pre> . Use [code lang="cpp"] and [/code] for highlighted code.