Description: How about we take you on an adventure on exploring certificate signing requests. Take a look at this CSR file here.
Difficulty: Medium
Author: Sunday Jacob Nwanyim
Summary
This challenge introduces the concepts of PEM certificates, certificate signing requests (CSR), and Base64 encoding. The goal is to explore how certificate data is stored and how to inspect whatβs inside a CSR file.
Analysis
We are provided with a file named readmycert.csr:
$ file readmycert.csrreadmycert.csr: PEM certificate requestFrom this, we can see that it is a PEM certificate request.
What is PEM certificate?
A PEM (Privacy Enhanced Mail) certificate is a text-based file format that stores cryptographic data such as digital certificates, certificate signing requests, or private keys. It is commonly used by web servers like Apache and is easy to identify because it contains Base64-encoded text wrapped between headers like:
-----BEGIN CERTIFICATE----------END CERTIFICATE-----Key characteristics of a PEM certificate file:
- Text-based format: PEM files are human-readable text files, though the content itself is encoded in Base64.
- Content: They can contain various security data, including public keys, private keys, and certificate requests.
- Headers and footers: The start and end of the data within a PEM file are marked by clear text labels, such as
-----BEGIN CERTIFICATE-----and-----END CERTIFICATE-----. - File extensions: While the .pem extension is common, PEM-formatted data can also be found in other file extensions like .crt, .cer, .csr, or .key.
- Container format: A single PEM file can sometimes contain multiple certificates and/or keys bundled together.
Since PEM stores Base64-encoded data, letβs briefly look at Base64 encoding.
What is Base64 encoding?
Base64 is a binary-to-text encoding scheme used to represent arbitrary binary data (like certificates, keys, or files) using only readable ASCII characters. This makes it safe for transmission through systems that may not handle raw binary properly.
How it works
- The binary data is split into 6-bit groups.
- Each 6-bit value (0β63) maps to a character in the Base64 index table:
AβZβ 0β25aβzβ 26β510β9β 52β61+β 62/β 63
- If the final chunk is incomplete, padding
(=)is added so the output length is always a multiple of 4.
Manual Encoding (The Concept)
Letβs manually encode the word Hi into Base64 to see the algorithm in action.
- Convert to ASCII Decimal: First, find the ASCII values for each character.
H= 72i= 105
- Convert to Binary: Convert the decimal values to 8-bit binary.
72=01001000105=01101001- Combined binary stream:
01001000 01101001(16 bits)
- Split into 6-bit chunks: Split the 16-bit stream into 6-bit groups.
010010-> Decimal 18000110-> Decimal 61001-> We only have 4 bits. We need to pad with two zeros to make a 6-bit chunk.100100-> Decimal 36- We had 16 bits, which is not divisible by 6. We will need to handle padding later.
- Map to Base64 Table: Convert each 6-bit number using the Base64 index table.
- 18 ->
S - 6 ->
G - 36 ->
k
- Apply Padding: The original data was 2 bytes (16 bits). We ended up with three 6-bit chunks (18 bits), but the last one was padded. Since we had 2 bytes, which is
2 mod 3, we add one=padding character.
- So,
Hiin Base64 isSGk=.
Command-Line
In practice, we use CLI tools instead of manual conversion. On Linux, macOS, or WSL, you can decode Base64 like this:
$ echo "SGk=" | base64 --decodeHiChallenge
The content of the file is:
-----BEGIN CERTIFICATE REQUEST-----MIICpzCCAY8CAQAwPDEmMCQGA1UEAwwdcGljb0NURntyZWFkX215Y2VydF8zYWE4MDA5MH0xEjAQBgNVBCkMCWN0ZlBsYXllcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN1PdpW4sKum7AhFubDl86sflki20dWKkZ/iZBYYX/RYqZIWm9vepdfwkeiDdz7KriPzM9tTDuJm1kWv8/3AxHrYwliFHK0lsmUYdOcPfrvlh6SIuZwHvxhrR0DJ0+W5vU+4j9G/hk2+JLMURh8WZadwBhRcfIxk97OXujjvHS9KplMAs5ulcSSQcv77QkIcxVg1OSDVZoEjTr131g+/Jox3T+uFPEvzF9iq03JMU39oqfGaFL02EQTaTl8efLIDkGxrKCc+Jhn4e1mD+9UlUmIn9nsOBCYNrnfq4usAL10ZPMDty2SxyVTl0171trvCA9DF5PRG6eMYirJOmF18oSUCAwEAAaAmMCQGCSqGSIb3DQEJDjEXMBUwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAMa7s/l3mAwJi7LsosPS6/VlZwfTdiJAv+WOKN9T1q2JRHsAGRrW9Gz5p7nSBKJxevRaOMwnXWK0HqmN3y2/lor50jWzqLhM4TnbKsakXnEIo90XgHoy+n0DL0296Lg/xoXrRgrh2o3rtZTc+irqUzTRM7Q1F76LNmgtEXqvbOm6Gx2dASPhVAAfylRBCTyz2dYwg2vMkwt4e5bTvpze/xyTyI8Pydq09YYJe0+a2cHSgcoyGoWXjIK4CUxjBNXAFxSPCcS35JRkBnyGo+KL+XtuK9yCX7xBFkwLybK7Mj4TeGiwDsR/0SwqyWGb7Q2m58ay8RVmpmAIEs21M3236Z4=-----END CERTIFICATE REQUEST-----We can immediately notice the = padding at the end, which confirms that the content is Base64-encoded.
To decode or inspect the certificate request, we can either use the command line or an online tool like CyberChef.
Using the command line:
OpenSSL can parse and display CSR details:
$ openssl req -in readmycert.csr -noout -textThis will show fields such as:
- Subject (CN, OU, etc.)
- Public key information
- Signature algorithm
- CSR attributes
The output includes the following:
Certificate Request: Data: Version: 1 (0x0) Subject: CN=picoCTF{read_mycert_3aa80090}, name=ctfPlayer Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:dd:4f:76:95:b8:b0:ab:a6:ec:08:45:b9:b0:e5: f3:ab:1f:96:48:b6:d1:d5:8a:91:9f:e2:64:16:18: 5f:f4:58:a9:92:16:9b:db:de:a5:d7:f0:91:e8:83: 77:3e:ca:ae:23:f3:33:db:53:0e:e2:66:d6:45:af: f3:fd:c0:c4:7a:d8:c2:58:85:1c:ad:25:b2:65:18: 74:e7:0f:7e:bb:e5:87:a4:88:b9:9c:07:bf:18:6b: 47:40:c9:d3:e5:b9:bd:4f:b8:8f:d1:bf:86:4d:be: 24:b3:14:46:1f:16:65:a7:70:06:14:5c:7c:8c:64: f7:b3:97:ba:38:ef:1d:2f:4a:a6:53:00:b3:9b:a5: 71:24:90:72:fe:fb:42:42:1c:c5:58:35:39:20:d5: 66:81:23:4e:bd:77:d6:0f:bf:26:8c:77:4f:eb:85: 3c:4b:f3:17:d8:aa:d3:72:4c:53:7f:68:a9:f1:9a: 14:bd:36:11:04:da:4e:5f:1e:7c:b2:03:90:6c:6b: 28:27:3e:26:19:f8:7b:59:83:fb:d5:25:52:62:27: f6:7b:0e:04:26:0d:ae:77:ea:e2:eb:00:2f:5d:19: 3c:c0:ed:cb:64:b1:c9:54:e5:d3:5e:f5:b6:bb:c2: 03:d0:c5:e4:f4:46:e9:e3:18:8a:b2:4e:98:5d:7c: a1:25 Exponent: 65537 (0x10001) Attributes: Requested Extensions: X509v3 Extended Key Usage: TLS Web Client Authentication Signature Algorithm: sha256WithRSAEncryption Signature Value: c6:bb:b3:f9:77:98:0c:09:8b:b2:ec:a2:c3:d2:eb:f5:65:67: 07:d3:76:22:40:bf:e5:8e:28:df:53:d6:ad:89:44:7b:00:19: 1a:d6:f4:6c:f9:a7:b9:d2:04:a2:71:7a:f4:5a:38:cc:27:5d: 62:b4:1e:a9:8d:df:2d:bf:96:8a:f9:d2:35:b3:a8:b8:4c:e1: 39:db:2a:c6:a4:5e:71:08:a3:dd:17:80:7a:32:fa:7d:03:2f: 4d:bd:e8:b8:3f:c6:85:eb:46:0a:e1:da:8d:eb:b5:94:dc:fa: 2a:ea:53:34:d1:33:b4:35:17:be:8b:36:68:2d:11:7a:af:6c: e9:ba:1b:1d:9d:01:23:e1:54:00:1f:ca:54:41:09:3c:b3:d9: d6:30:83:6b:cc:93:0b:78:7b:96:d3:be:9c:de:ff:1c:93:c8: 8f:0f:c9:da:b4:f5:86:09:7b:4f:9a:d9:c1:d2:81:ca:32:1a: 85:97:8c:82:b8:09:4c:63:04:d5:c0:17:14:8f:09:c4:b7:e4: 94:64:06:7c:86:a3:e2:8b:f9:7b:6e:2b:dc:82:5f:bc:41:16: 4c:0b:c9:b2:bb:32:3e:13:78:68:b0:0e:c4:7f:d1:2c:2a:c9: 61:9b:ed:0d:a6:e7:c6:b2:f1:15:66:a6:60:08:12:cd:b5:33: 7d:b7:e9:9eAs we can see, the flag is embedded directly inside the Subject CN field:
CN=picoCTF{read_mycert_3aa80090}Using CyberChef
If using CyberChef, the PEM headers must first be removed:
-----BEGIN CERTIFICATE REQUEST----------END CERTIFICATE REQUEST-----Once removed, apply the βFrom Base64β operation to decode the CSR data and inspect the ASN.1 structure. CyberChef will then display the embedded fields, including the flag.
β‘ Raikiriπ Flag pwned!

π‘ TL;DR / Lesson LearnedThis challenge demonstrates:
- How PEM files store cryptographic information in Base64 format.
- How to decode and inspect CSR files using OpenSSL or CyberChef.
- How flags can be hidden in metadata fields like the Subject CN