who is it

Figure 1: The challenge description.

The context is that of a suspected phishing attack from an adversary impersonating Larry Page.

After downloading the .eml file with wget, the content shows the following information supporting the suspicion of it being a scam:

The message shown between line 68 to line 72 promises a reward too-good-to-be-true to the recipient, Francis Manzi. All the he has to do is conveniently open an attachment. (Figure 2)

Figure 2: The email content.

The email was sent from the address with the domain name of lpage@onionmail.org. This immediately raises red flags, as Rocketreach reveals that the real Larry Page might possibly only use email with domains of @google.com, @cs.standford.edu, @yahoo.com and @gmail.com. [1]

On top of this, OnionMail is a mail service related to the Onion Search Engine project, its aim is to provide private, anonymous emails accounts. This is a sign that the true sender of this email might be abusing the service for illicit activities, but also pose a problem for tracking down the adversary.

The Onionmail info site explains that all OnionMail servers are configured as TOR hidden services. TOR is famous as a privacy technology that utilize the concept of onion routing where request must go through an entry node, various proxies and an exit node before reaching the destination. The entry node does not know the IP of the destination, whilst the exit node does not know the IP of the source of the message. [2]

This might be a reason why the hint suggests WHOIS IP lookup instead of WHOIS domain lookup, the IP address in line 29 of the .eml file might help narrow the sender down to an IP range. (Figure 3)

Figure 3: The IP address of the onion email server protecting the attacker.
Figure 4: Results from reverse lookup.

After performing whois on the IP address, WHOIS found a referral in its RIPE database pointing to the IP range of –

The remarks here seem to validate WHOIS findings as it’s stating that IP address within the range are known to be associated with “Spam, hacking or scans” to the point of raising complaints, and that the attacker’s true email may be abuse@contabo.de. (Figure 5).

Figure 5: Zoom in of whois reverse lookup result, showing malicious IP range.

The sender’s full name is Wilhelm Zwalina. (Figure 6)

Figure 6: Zoom in of whois reverse lookup result, showing full name of adversary.

The correct flag is picoCTF{WilhelmZwalina}.


[1] “Larry Page email address & phone number | Google Founder contact information,” RocketReach. https://rocketreach.co/larry-page-email_69657426

[2] “What is OnionMail?,” en.onionmail.info. https://en.onionmail.info/what.html.


Figure 1: The Challenge description
Figure 2: Inspecting the file type and metadata associated with the download.

The file was downloaded with wget then examined with the file command, revealing it to be a JPEG image file (figure 3).

Figure 3: atbash.jpg image from the challenge

On superficial inspection, the picture shows a conversion wheel for a type of cipher, Atbash. It also points to a website, RoyalOrderoftheHolyMackerel.com. Trying to access the website proved to be unsuccessful.

However, some OSINT on its fandom wiki page [1] revealed the order to be a secret society, dedicated to decoding and protecting the secrets of Gravity Falls, a cartoon series. It even made a cameo in the show itself.

Given that a quick OSINT didn’t indicate the flag to be remotely on other sites, the flag could be instead encrypted and embedded into the local image itself through steganography. A renowned tool to extract stego data from images, when the passphrase is unknown is Stegseek. If the user does not specify a custom wordlist, Stegseek will crack the passphrase using a default wordlist located at /usr/share/wordlists/rockyou.txt.

Figure 4: The steganography of the flag being revealed as a cipher.

Stegseek then reveals that the flag is an encrypted string: krxlXGU{zgyzhs_xizxp_vx4zyz61}. (Figure 4)

The flag seems to be encrypted and the clue is in the picture. Some reading from geeksforgeeks [2] reveals Atbash to be a type of substitution cipher with one key. It works by mapping the letters of an alphabetical language to corresponding letters when the alphabet is reversed. As shown in atbash.jpg, A becomes Z, Z becomes A etc.

To avoid reliance on pre-made tools, I have written a python script, atbash_decypher.py to decrypt the flag, revealing the answer to be: picoctf{atbash_crack_ec4aba61}. (Figure 5)

Figure 5: The flag is decrypted with the script.

An alternative option is to use dcode website’s Atbash Cipher option [3]. This was deployed and it reproduced my answer from the encrypted flag, validating its correctness.


[1] “The Royal Order of the Holy Mackerel,” The Royal Order of the Holy Mackerel Wiki. https://royalorderoftheholymackerel.fandom.com/wiki/The_Royal_Order_of_the_Holy_Mackerel (accessed Mar. 31, 2023).

[2] “Implementing Atbash Cipher,” GeeksforGeeks, Jun. 11, 2017. https://www.geeksforgeeks.org/implementing-atbash-cipher/

[3] “Atbash Cipher – Backwards/Reverse Alphabet – Online Decoder/Translator,” www.dcode.fr. https://www.dcode.fr/atbash-cipher

Two Sums

Figure 1: Challenge description revealed after launching instance.

The challenge (figure 1) wants 2 integers that satisfy the expression of:

n1 > n1 + n2  OR  n2 > n1 + n2

The condition being that they must both be positive. The 2 hints also offer very important details, namely that integer overflow is involved and that this is not a mathematical problem (figure 2).

Figure 2: Zoom in of the challenge’s 2 hints.

This would make sense in that neither n1 or n2 would be positive mathematically.

n1 + n2 < n1
n2 < n1 - n1
n2 <0

n1 + n2 < n2
n1 < n2 - n2
n1 < 0

The challenge also reveals that flag.c, a C script runs when a user logs into the remote server. The script takes 2 numbers from the user as input. The addIntOvf function is first declared such that if both the input numbers are positive but their sums are negative or vice versa, it returns the value of -1. Later on in the main function if calling addIntOvf returns -1, the flag is printed out (figure 3).

Figure 3: The overflow checking and main function of the C script running on remote server to take user input.

Integer Overflow

In the C language, integers can be unsigned or signed. Unsigned integers are always positive, but for signed integers the most significant bit to the left is assigned to denote it as a positive or negative number. If that bit is 1, the integer is positive, if that bit is 0, the integer is negative.

X86, the most popular computing architecture on most server devices can either be 32 bits or 64 bits. In the case of 32 bits OS, up to 32 bits can be used to represent a C integer. If it’s signed, 1 out of 31 bit is used to denote it as positive or negative. As computers use binary number system of either 1 or 0, this means that the maximum combination this signed integer could represent would be:

2 ^ 31 = 2147483647

As the signed integer can be negative or positive, the range of denary numbers represented by this integer is therefore -2,147,483,647 to +2,147,483,647.

The same logic apply to 64 bits OS where 64 bits represent an integer. 1 out of 64 bit is used to denote it as positive or negative, whilst 63 bits represents the value. Hence the maximum combination is

2 ^ 63 = 9223372036854775808 

Thus a signed integer on 64 bit OS can cover the denary range of -9,223,372,036,854,775,808 to +9,223,372,036,854,775,808.

When the range is exceeded, integer overflow occurs because the designated storage has run out, this changes the value of the most significant bit and as a result the value becomes negative. For example, on a 32-bit system, 1 added to 2,147,483,647 would not give 2,147,483,648 but rather -2,147,483,648.

This means if n1 and n2 are integers large enough to exceed the storage limit when added together, the expressions can be satisfied.


The server is likely of an x86 computing architecture. It’s unknown if it’s 32-bits or 64-bits. Thus, it’s worth trying to exceed the maximum positive denary number that can be represented on a 32-bit system first. If that does not work, the maximum for 64-bits can be tried.

For this purpose, I choose the following:

  • let n1 = 2147483647 (the maximum positive signed integer that 32 bits can represent)
  • let n2 = 2 (a randomly picked positive number that will push the sum over the limit)
Figure 4: The message displayed if the values for n1 & n2 causes overflow.

The flag is then revealed because the values for n1 and n2 caused integer overflow.


Figure 1: Challenge description

The hints for this challenge suggests that an Open Redirection exploit is present in the input fields of the website shown below (figure 2).

Figure 2: Web portal interface

Mitre’s database lists Open Redirect as CWE-601 and confirms a lack of input validation as a cause, where a malicious input could lead to the browser navigating to an URL of the adversary’s choosing, leading to more severe follow ups such as phishing and download of malware.

As the inputs of username and password then submitting them generates a HTTP POST request to send data to the server and update its information, a relevant tool here to use would be Burp Suite. Portswigger’s official documentation[1] contains description on how to analyze for redirections. The idea being to use Burp’s Proxy interceptor to capture the HTTP POST request then send it to the Repeater.


The website URL link is opened with the Burp Suite browser. The intercept is then turned on. Per instruction, the username of “test” and password of “test!” were entered into the webpage.

When submitted, the browser navigates to the following site.

Figure 3: Interface of redirected site.

The login submission’s HTTP POST request was captured by Burp’s Proxy Interceptor during this. The first interesting finding is that there was a HTTP 302 found status code (figure 4), suggesting that a redirection has taken place.

The second interesting finding is that the beginning part of the flag has already been revealed in the response to the POST request. The last line of the HTTP 302 response contains an anchor element indicating the URL of the website it is redirecting the browser to. In the URL, the id contains the base64 encoded string “cGljb0NURntwcm94aWVzX2Fs” (figure 4) which Burp helpfully decoded as “picoCTF{proxies_al”

Figure 4: The HTTP POST request intercepted and its response, without following redirections.

This request was then sent to the Repeater field, which had the “Follow redirections” option changed from ‘Never’ to the “On-site” option (figure 5) as in this particular instance both sites are from the domain of picoCTF.net.

Figure 5: Turning the follow redirection on in Burp’s Repeater.

After this, clicking ‘Send’ button resubmitted the POST request, the response now contained new data (figure 6). Namely a snippet of HTML showing the Javascript function, setTimeout() [2], which calls the window.location object after a defined time gap, 2 seconds in this case. In Javascript, the window.location redirect to a new specified URL [3].

Figure 6: The HTTP POST request intercepted and its response, after following redirections.

That the redirect URL in the updated HTTP response (figure 6) contains the the base64 encoded id string of “bF90aGVfd2F5X2EwZmUwNzRmfQ==” which Burp Suite decoded as “l_the_way_a0fe074f}”

The full flag is therefore the 2 parts combined which turns out to be:



[1] “Repeater settings,” portswigger.net. https://portswigger.net/burp/documentation/desktop/settings/tools/repeater#redirects (accessed Mar. 31, 2023).

[2] “Window setTimeout() Method,” W3schools.com, 2019. https://www.w3schools.com/jsref/met_win_settimeout.asp

[3] “JavaScript Window Location,” W3schools.com, 2019. https://www.w3schools.com/Js/js_window_location.asp


Figure 1: The challenge description.

The challenge involves decompiling an apk file. Its hints suggests to use either mobsf or jadx tool (figure 1). The skills involved here, namely decompiling APK to Java is new to me as up till this challenge, as C is the low level language I’m more familiar with.

GeeksforGeeksexplains that in order to run a java code, it is first compiled into bytecode and class files similar to C, however it has the extra step involving a Java Virtual Machine to generate the machine code for execution of the program. This lends to Java’s strength in portability across operating systems. [1]

However, ARM based Android devices have limited battery life, memory and processing capacity compared to desktops. These requirements means special compilers and VMs need to be used for compilation and execution of Java in Android systems, namely DEX and Dalvik Virtual Machine or DVM. The file extension of the final executable is also .apk instead of .jar [2]

First, let’s inspect the file. It is indeed an APK file for Android OS and its shown to be signed. (Figure 2)

Figure 2: Inspection of file type for timer.apk

The official github repository for Mobile Security Framework, or Mobsf describes the tool as an all-in-one security suite but designed as a web app for use on Android, iOS or Windows systems [3], making it unsuitable in this use-case involving Kali Linux as the Guest OS testing environment. Thus the next step would be to research the process of Java code compilation on Android then use jadx to obtain timer’s source code.


The official Kali Linux describes jadx as a tool for reverse engineering .apk files or output of DEX compiler back to the human readable java source code. It comes in both CLI and GUI options. Jadx does not ship with Kali Linux by default and needs to be installed through the usual apt package manger [4] :

sudo apt install jadx

From jadx CLI’s help page the syntax of usage is:

jadx [options] <input files>

From the help page the GUI option for jadx can be accessed with the command:


timer.apk was subsequently opened in the graphical interface and the flag is shown to be hidden as the version name of the timer app, in the BuildConfig class of the example.timer package. (Figure 3)

Figure 3: The flag revealed in jadx ‘s graphical user interface.


[1] “Compilation and Execution of a Java Program,” GeeksforGeeks, Apr. 16, 2018. https://www.geeksforgeeks.org/compilation-execution-java-program/

[2] “Difference Between JVM and DVM,” GeeksforGeeks, Dec. 27, 2020. https://www.geeksforgeeks.org/difference-between-jvm-and-dvm/

[3] “Mobile Security Framework (MobSF),” Mobile Security Framework (MobSF). https://mobsf.github.io/Mobile-Security-Framework-MobSF/

[4] “jadx | Kali Linux Tools,” Kali Linux. https://www.kali.org/tools/jadx/.


Figure 1: The challenge description and hints.

XXE attack research

A hint suggests that the /etc/passwd of the insecure website’s back-end can be accessed through a XML external entity injection, or XXE attack. (Figure 1)

As of 2021, XXE remains one of the OWASP’s top 10 critical web application risks, changing to the category of 2021:A05-security misconfiguration risk from the A04 category in 2017. [1]

Based on readings from w3school, eXtensible Markup Language or XML is a markup language much like HTML, except its purpose is to carry data from the browser to the server instead of displaying them. In XML, a storage unit of data is called an entity, much like a variable in a programming language. [2]

According to OWASP, the XXE attack vector is a malicious XML document sent to the victim web app’s server by the attacker. Inside the XML document there is one or more external entity references with URI specifying the resource being targeted e.g. /etc/passwd and the attacker’s address. If the web app uses a poorly configured XML parser, it will process the external entity’s URI, retrieve the specified resource then send it to the attacker. [3]

Attack surface deduction

Figure 2: The challenge website’s interface.

The web portal of the challenge presents no user input options other than a few ‘Details’ button that when clicked will presumably send HTTP POST requests to the server in order to display the ‘Special Info::::’ messages as responses. (Figure 2)

A relevant tool for this context is Burp Suite, a set of tools developed by Portswigger for penetration testing of web applications. [4]

The approach would be to click the ‘Details’ button, intercept the HTTP POST request with burpsuite, and check for any XML information being sent. If there are XML fields, external entities can be written before re-sending the POST request. Alternatively, the mention of SOAP protocol in the challenge’s name might indicate that clients can’t directly submit XML information, unless XIndicate mechanism is used.

Attack procedure

The URL of the website was entered into Burp Suite’s chromium browser. The ‘Intercept’ option in the ‘Proxy’ tab was turned on.

Figure 3: Turning on Burp Suite Proxy’s intercept option.

Clicking the ‘Details’ button on the web portal creates the following HTTP POST request which was intercepted by Burp Suite.

There is evidently a section of XML in the HTTP POST request, starting from line 13 (Figure 4), therefore the next step is to inject an external entity with the URI specifying the path to /etc/passwd.

Figure 4: Intercepted HTTP POST request with XML field.

To do this, one line containing the external entity needs to be added, then said entity must be called in the ID tag. Let’s give it the unique name of cleoptrata.

The following line is added below line 13. (Figure 5)

<!DOCTYPE injection [ <!ENTITY cleoptrata SYSTEM "file:///etc/passwd"> ]>

Where ‘injection’ is the name of root element, it can be anything e.g. foo, example etc. The name of the entity is cleoptrata and the SYSTEM specifies the entity as an external entity. These are followed by the path to the passwd file.

Note that in the ID tags, cleoptrata is called with:

Figure 5: Altered HTTP POST request with the external entity embedded.

To re-send this HTTP POST request back to the server, use ‘Send to Repeater’ then ‘send’ in Burp Suite. This then resulted in the server leaking the contents of the passwd file, revealing the flag. (Figure 6)

Figure 6: HTTP response produced after XXE.


In an educational environment such as the Computer Science website here, this attack is devastating in that attackers can find the username of past logins. The attacker could then try to obtain the shadow file for the passwords.

The results of this challenge also reveals information like Gnats Bug-Reporting System being a component of the web application’s network, which is valuable to an attacker’s Reconnaissance for subsequent attacks.


[1] OWASP, “OWASP Top Ten,” Owasp.org, 2021. https://owasp.org/www-project-top-ten/

[2] w3schools, “XML Introduction,” W3schools.com, 2015. https://www.w3schools.com/xml/xml_whatis.asp

[3] “XML External Entity (XXE) Processing | OWASP,” owasp.org. https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing

[4] portswigger, “What is XXE (XML external entity) injection? Tutorial & Examples | Web Security Academy,” portswigger.net. https://portswigger.net/web-security/xxe


Figure 1: The challenge description

The challenge starts with a SSH connection to a remote server through port 51999. The syntax to do this on Kali Virtual Machine is:

ssh -p <port number> <username>@<website URL>
Figure 2: Remote log in with SSH.
Figure 3: Inspection of file type.

In the home directory, there is a bash shell script called ‘useless.’ The challenge description hints that this script should be inspected prior to running, running before looking the script leads to the message: “Read the code first”

The script’s first line indicates that the program requires 3 input arguments from the user, it then directs the inputs into a series of elif statements for carrying out either addition, multiplication, substitution and division.

Figure 4: The bash script.

The code here suggests that the flag is not going to be revealed by running this script and trying to break it using user inputs it was not designed for. The first argument has to be either the options of add, sum, sub, div or mul and the next 2 inputs must be numerical. If anything less than 3 input is given, the message to read the code appears. If the 3 inputs do not satisfy requirements e.g. an integer instead of add, sum, sub, div or mul for $1 argument, or strings instead of 2 numbers for $2 and $3 argument, the script will simply display “Read the manual.”

Hence the next step is to read the manual.

Figure 5: Manual page for the shell script.

The manual then reveals the flag as picoCTF{us3l3ss_ch4ll3ng3_3xpl0it3d_1155}.


Figure 1: The challenge description.

The instance shows the information for connecting to the remote server via SSH. No additional clues other than the description was given.

The syntax for connecting to SSH server through a given port is:

ssh -p <port> <username>@<website URL>
Figure 2: Remote login with SSH.

The tool that automates tasks to run at set intervals in linux is usually cron. The crontab file is at /var/spool/cron/crontabs. Trying to access this file gave me a warning as I lack user privilege as a picoCTF player to see the crontab file.

However, upon surfing through some of the directories, I have found an interesting hack in the form of a custom directory, named “challenge” in the root of the file system.

Figure 3: The mysterious repository.

The /challenge directory contains a file named ‘metadata.json’ that holds the flag as its content.

Figure 4: The flag hidden inside the json.


Figure 1: The challenge description.

The hints given are:

  • The malware utilizes Crypto-currency abuse databases.
  • The message displays the hash: 1Mz7153HMuxXTuR2R1t78mGSdzaAtNbBWX
  • The challenge involves Googling and OSINT.

A googling of the hash leads to the bleepingcomputer’s website explaining that the hash is the bitcoin wallet address used by the adversary behind the infamous NotPetya ransomware. [1]

This led me to go to Fortinet that explains the difference between Petya and NotPetya. [2]

This is where I would question the answer flag in this exercise. Fortinet clearly suggests that the 1Mz7153HMuxXTuR2R1t78mGSdzaAtNbBWX string is in NotPetya’s message, not Petya’s message.

Figure 2: The message hash string of NotPetya. Credit to fortinet’s figure 8.

However the answer flag is picoCTF{Petya}. I would assume that this is because NotPetya technically is a sub-strain of Petya.


[1] “NotPetya Group Moves All Their Bitcoin, Posts Proposition on the Dark Web,” BleepingComputer. https://www.bleepingcomputer.com/news/security/notpetya-group-moves-all-their-bitcoin-posts-proposition-on-the-dark-web/

[2] R. Alvarez, “Key Differences Between Petya and NotPetya,” Fortinet Blog, Jul. 09, 2017. https://www.fortinet.com/blog/threat-research/key-differences-between-petya-and-notpetya

Rules 2023

Figure 1: The challenge description.

The hint suggests that Ctrl – F will not work. This suggests that the flag is either not a string object, or be exposed to client-side interface but only available in the developer tools section of the browser.

The following is the webpage listing the rules for 2023’s PicoCTF Challenge.

Figure 2: The section of the website holding the flag.

As predicted, the flag is an image object sneakily added to a paragraph. Whilst this can’t be located with the search shortcut, it can be found using Ctrl – F in the HTML section within developer tools on Chromium.

The alt attribute is the text that displays when image fails to load and in this case that’s the flag.