Cybersecurity News Hub
No Result
View All Result
  • Home
  • Cyber Crime
  • Cyber Security
  • Data Breach
  • Mobile Security
  • Videos
  • Advertise
  • Privacy Policy
  • Contact Us
  • Home
  • Cyber Crime
  • Cyber Security
  • Data Breach
  • Mobile Security
  • Videos
  • Advertise
  • Privacy Policy
  • Contact Us
No Result
View All Result
Cybersecurity News Hub
No Result
View All Result
Home Mobile Security

Flare-On 6 CTF WriteUp (Part 4)

Cyberinchief by Cyberinchief
November 20, 2025
Reading Time: 6 mins read
0
Flare-On 6 CTF WriteUp (Part 4)


RELATED POSTS

Top 5 Mobile App Security Threats Leaders Must Prepare for in 2026

Emerging Technology Management for Modern IT Leaders

Adopting Blueprints in Jamf Tools

This is the fourth part of the FlareOn 6 CTF WriteUp series.

4 – Dnschess

The challenge reads

Some suspicious network traffic led us to this unauthorized chess program running on an Ubuntu desktop. This appears to be the work of cyberspace computer hackers. You’ll need to make the right moves to solve this one. Good luck!

We have three files – ChessUI, ChessAI.so and capture.pcap. The first two are ELF binaries compiled for Linux x64. Running ChessUI on an Ubuntu 18.04 system we are greeted with a Chess game.

Figure 1: A game of chess
Figure 1: A game of chess

Our opponent DeepFLARE is the black side and waits for our move. Let’s make a move. We move the knight from B1 to A3.

Figure 2: Making our move
Figure 2: Making our move

DeepFLARE resigns immediately without making a move. Trying other first moves doesn’t change the outcome. Let’s have a look at the PCAP.

Figure 3: The PCAP
Figure 3: The PCAP

The PCAP in its entirety consists of DNS requests along with their responses. There are DNS A queries for domain names which have the form of --.game-of-thrones.flare-on.com where

Buy JNews
ADVERTISEMENT
  • name is the name of a chess piece
  • pos1 and pos2 are two positions on the chess board

Corresponding to these DNS queries, we have responses as well.

Figure 4: DNS response
Figure 4: DNS response

However, we get a NXDOMAIN response when we try to lookup the names on our system.

$ nslookup rook-c3-c6.game-of-thrones.flare-on.com 1.1.1.1
Server:		1.1.1.1
Address:	1.1.1.1#53

** server can't find rook-c3-c6.game-of-thrones.flare-on.com: NXDOMAIN

Analyzing ChessUI

ChessUI as it’s name suggest must be responsible for the game GUI. Let’s analyze the binary in Ghidra. Make sure that “Fixup Unresolved External Symbols” is unchecked in ELF loading options.

Figure 5: The main function in ChessUI
Figure 5: The main function in ChessUI

The presence of function names starting with gtk implies that the GUI was developed using the GIMP Toolkit framework. The third parameter to g_signal_connect_data takes the address of a callback handler function FUN_00103ab0.

Going through the decompiled code of FUN_00103ab0 we can notice that it loads ChessAI.so and obtains the addresses of symbols getAiName, getAiGreeting and getNextMove as shown in Figure 6.

Figure 6: ChessUI loads ChessAI
Figure 6: ChessUI loads ChessAI

Among the three functions, getNextMove looks interesting. Lets check out its code in ChessAI.so

Analyzing ChessAI.so

Figure 7: Decompiled code of getNextMove
Figure 7: Decompiled code of getNextMove

Near the beginning there is a call to gethostbyname. This function can be used to obtain the IPv4 address of a domain name. Calling this function will result in a DNS query as we saw in the PCAP. gethostbyname returns a hostent structure filled with the requested info.

struct hostent 
{
    char  *h_name;            /* official name of host */
    char **h_aliases;         /* alias list */
    int    h_addrtype;        /* host address type */
    int    h_length;          /* length of address */
    char **h_addr_list;       /* list of addresses */
};

For now, let’s try to hook gethostbyname using the LD_PRELOAD technique. We define our own version of gethostbyname which will simply print its argument.

// Compile using
// gcc -Wall -fPIC -shared -o gethostbyname gethostbyname.c

#include 
#include 
#include 

struct hostent *gethostbyname(char *name)
{
	printf("[+] %s\n", name);
	return NULL;
}
gethostbyname.c

Let us inject the library using LD_PRELOAD and run ChessUI. When we make a move such as B1-A3 we get the following output on the terminal.

$ LD_PRELOAD=./gethostbyname ./ChessUI
[+] knight-b1-a3.game-of-thrones.flare-on.com

Essentially the application makes a DNS request for a name which contains the information about our move. The IP address returned as a response to this request must contain the move DeepFLARE should make.

The returned value from gethostbyname is a pointer to a hostent structure.

Figure 8: Checks on the returned hostent structure
Figure 8: Checks on the returned hostent structure

h_addr_list is a double pointer to the octets in the IP address. There are a few checks done on the octet. If the returned IP address is of the form W.X.Y.Z then W must be 127, the last bit of Z must be zero (even). uParm is a counter starting from 0 which increases by 1 for each turn. Y & 0xf i.e. the last 4 bits must equal to this counter value.

If all of the conditions satisfy, it xors some data from DAT_00102020 with Y – the second octet, with the result stored to DAT_00104060. The data at 102020 looks to be array of encrypted bytes.

Figure 9: An array of encrypted bytes
Figure 9: An array of encrypted bytes

The following is the list of IP addresses obtained from the DNS responses which have the first octet equal to 127 and the last octet even.

127.53.176.56
127.159.162.42
127.230.231.104
127.141.14.174
127.34.217.88
127.108.24.10
127.25.74.92
127.99.253.122
127.200.76.108
127.182.147.24
127.49.59.14
127.217.37.102
127.89.38.84
127.215.177.38
127.252.212.90

This can be further be sorted in ascending order according to the value of octet[2] & 0xf

>>> ip_list = ['127.53.176.56', '127.159.162.42', '127.230.231.104', '127.141.14.174', '127.34.217.88', '127.108.24.10', '127.25.74.92',  '127.99.253.122', '127.200.76.108', '127.182.147.24', '127.49.59.14', '127.217.37.102', '127.89.38.84', '127.215.177.38', '127.252.212.90']

>>> ip_list.sort(key=lambda x:int(x.split('.')[2]) & 0xf)

>>> ip_list
['127.53.176.56', '127.215.177.38', '127.159.162.42', '127.182.147.24', '127.252.212.90', '127.217.37.102', '127.89.38.84', '127.230.231.104', '127.108.24.10', '127.34.217.88', '127.25.74.92', '127.49.59.14', '127.200.76.108', '127.99.253.122', '127.141.14.174']

This is the order of DNS responses the game expects to receive. Note that the legality of our move is not checked client-side within the game. So its possible that we make any move as long as the DNS response is correct.

However, for completeness let’s make our moves in proper order too. Corresponding to the sorted list of IP addresses we have this list of DNS requests which indicate the move we should make.

╔═════╦═════════════════╦═══════════════════════════════════════════╗
║ No. ║        IP       ║                Domain Name                ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  1  ║ 127.53.176.56   ║ pawn-d2-d4.game-of-thrones.flare-on.com   ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  2  ║ 127.215.177.38  ║ pawn-c2-c4.game-of-thrones.flare-on.com   ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  3  ║ 127.159.162.42  ║ knight-b1-c3.game-of-thrones.flare-on.com ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  4  ║ 127.182.147.24  ║ pawn-e2-e4.game-of-thrones.flare-on.com   ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  5  ║ 127.252.212.90  ║ knight-g1-f3.game-of-thrones.flare-on.com ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  6  ║ 127.217.37.102  ║ bishop-c1-f4.game-of-thrones.flare-on.com ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  7  ║ 127.89.38.84    ║ bishop-f1-e2.game-of-thrones.flare-on.com ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  8  ║ 127.230.231.104 ║ bishop-e2-f3.game-of-thrones.flare-on.com ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  9  ║ 127.108.24.10   ║ bishop-f4-g3.game-of-thrones.flare-on.com ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  10 ║ 127.34.217.88   ║ pawn-e4-e5.game-of-thrones.flare-on.com   ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  11 ║ 127.25.74.92    ║ bishop-f3-c6.game-of-thrones.flare-on.com ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  12 ║ 127.49.59.14    ║ bishop-c6-a8.game-of-thrones.flare-on.com ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  13 ║ 127.200.76.108  ║ pawn-e5-e6.game-of-thrones.flare-on.com   ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  14 ║ 127.99.253.122  ║ queen-d1-h5.game-of-thrones.flare-on.com  ║
╠═════╬═════════════════╬═══════════════════════════════════════════╣
║  15 ║ 127.141.14.174  ║ queen-h5-f7.game-of-thrones.flare-on.com  ║
╚═════╩═════════════════╩═══════════════════════════════════════════╝

For example, our first move will be to move the pawn from d2 to d4. Now all that is left is to modify gethostbyname.c  such that it also returns the response in the correct order.

#include 
#include 
#include 

unsigned char ip_list[16][4] = {
{127,53,176,56}, {127,215,177,38}, {127,159,162,42}, {127,182,147,24}, {127,252,212,90}, {127,217,37,102}, {127,89,38,84}, {127,230,231,104}, {127,108,24,10}, {127,34,217,88}, {127,25,74,92}, {127,49,59,14}, {127,200,76,108}, {127,99,253,122}, {127,141,14,174}};

struct hostent 
{
    char  *h_name;            /* official name of host */
    char **h_aliases;         /* alias list */
    int    h_addrtype;        /* host address type */
    int    h_length;          /* length of address */
    char **h_addr_list;       /* list of addresses */
}_hostent;

int idx = 0;

void* addr_list[] = {NULL, NULL};

struct hostent *gethostbyname(char *name)
{
	addr_list[0] = &ip_list[idx++];
	_hostent.h_addr_list = addr_list; 
	return &_hostent;
}

We can compile and LD_PRELOAD it the same way.

$ gcc -Wall -fPIC -shared -o gethostbyname gethostbyname.c
$ LD_PRELOAD=./gethostbyname ./ChessUI

Winning the game

Let’s play the game executing the moves in the order specified in the table.

Figure 10: The Endgame
Figure 10: The Endgame

Playing out all 15 moves we win and reach the stage as shown in Figure 15. The flag is also printed.

FLAG: [email protected]



Source link

Tags: CTFFlareOnPartWriteUp
ShareTweetPin
Cyberinchief

Cyberinchief

Related Posts

Top 5 Mobile App Security Threats Leaders Must Prepare for in 2026
Mobile Security

Top 5 Mobile App Security Threats Leaders Must Prepare for in 2026

January 21, 2026
Emerging Technology Management for Modern IT Leaders
Mobile Security

Emerging Technology Management for Modern IT Leaders

December 8, 2025
Adopting Blueprints in Jamf Tools
Mobile Security

Adopting Blueprints in Jamf Tools

December 8, 2025
Jamf Safe Internet + On-Device Phishing AI
Mobile Security

Jamf Safe Internet + On-Device Phishing AI

December 7, 2025
Act on Jamf Protect Alerts
Mobile Security

Act on Jamf Protect Alerts

December 7, 2025
Terraform + GitLab CI/CD for Jamf
Mobile Security

Terraform + GitLab CI/CD for Jamf

December 6, 2025
Next Post
Identity Security in the Face of AI Scams

Identity Security in the Face of AI Scams

जब Cyber Crime Officer को ही आया, Cyber ठगों का फ़ोन | Subhranshu | Kaithal | Podcast | Haryana

जब Cyber Crime Officer को ही आया, Cyber ठगों का फ़ोन | Subhranshu | Kaithal | Podcast | Haryana

Recommended Stories

जारी है DIGITAL ARREST का खेल। TRANSNATIONAL ORGANIZED CYBER CRIME। MAMTA CHOPRA | CYBER ALERT

जारी है DIGITAL ARREST का खेल। TRANSNATIONAL ORGANIZED CYBER CRIME। MAMTA CHOPRA | CYBER ALERT

October 23, 2025
5 ways to strengthen your firewall and endpoint’s defenses against ransomware – Sophos News

5 ways to strengthen your firewall and endpoint’s defenses against ransomware – Sophos News

November 12, 2025
Harvard CS50’s Intro to Cybersecurity – Full University Course

Harvard CS50’s Intro to Cybersecurity – Full University Course

November 5, 2025

Popular Stories

  • Allianz Life – 1,115,061 breached accounts

    Allianz Life – 1,115,061 breached accounts

    0 shares
    Share 0 Tweet 0
  • Prosper – 17,605,276 breached accounts

    0 shares
    Share 0 Tweet 0
  • साइबर अपराध | Illegal Payment Gateway & Rented Bank Accounts | MAMTA CHOPRA

    0 shares
    Share 0 Tweet 0
  • Miljödata – 870,108 breached accounts

    0 shares
    Share 0 Tweet 0
  • Snowflake Data Breach Explained: Lessons and Protection Strategies

    0 shares
    Share 0 Tweet 0

Search

No Result
View All Result

Recent Posts

  • Top 5 Mobile App Security Threats Leaders Must Prepare for in 2026
  • Microsoft On Women In Cybersecurity At Black Hat Europe 2025 In London
  • Polisi kembali ungkap sindikat Cyber Crime kejahatan Internasional – iNews Malam 09/03

Categories

  • Cyber Crime
  • Cyber Security
  • Data Breach
  • Mobile Security
  • Videos

Newsletter

© 2025 All rights reserved by cyberinchief.com

No Result
View All Result
  • Home
  • Cyber Crime
  • Cyber Security
  • Data Breach
  • Mobile Security
  • Videos
  • Advertise
  • Privacy Policy
  • Contact Us

© 2025 All rights reserved by cyberinchief.com

Newsletter Signup

Subscribe to our weekly newsletter below and never miss the latest News.

Enter your email address

Thanks, I’m not interested