# Aspire CTF 2021: Crypto `Unless otherwise specified flags shall be submitted using the format: Aspire{"flag"}.` ![](https://i.imgur.com/eCgQwvJ.png) I've never played Aspire CTF before. I got to know of it when i read Trevor Saudi's writeup on `Linux Skills and Networking`. This first experience was quite good. I didn't have a team, so i decided to make my own and play solo, which was quite exciting. Most of the challenges i'd say were easy because of readily available materials on the internet especially from `Cryptopal’s challenges` writeups. The scoreboard at the time i was doing this writeup: ![](https://i.imgur.com/wW0O3T5.png) ### **First Challenge: Primer - Hex** ``` Obtain the flag from the following hex data. 51584e7761584a6c653046795a534235623355675953426b5a585a766447566c4947396d4948526f5a53426d6157356c49474679644342765a6942696158527a494746755a4342696558526c637a3939 ``` We're given hex encoded text. The simplest way of decoding this is using `xxd` to reverse the data. ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/hex_COMPLETE] └─$ echo "51584e7761584a6c653046795a534235623355675953426b5a585a766447566c4947396d4948526f5a53426d6157356c49474679644342765a6942696158527a494746755a4342696558526c637a3939" | xxd -r -p QXNwaXJle0FyZSB5b3UgYSBkZXZvdGVlIG9mIHRoZSBmaW5lIGFydCBvZiBiaXRzIGFuZCBieXRlcz99 ``` Looks like we get a base64 encoded string. Decoding it... ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/hex_COMPLETE] └─$ echo -n "QXNwaXJle0FyZSB5b3UgYSBkZXZvdGVlIG9mIHRoZSBmaW5lIGFydCBvZiBiaXRzIGFuZCBieXRlcz99" | base64 -d Aspire{Are you a devotee of the fine art of bits and bytes?} ``` Got the flag. Nice and easy! You can also use `cyberchef` which will automatically decode it from hex then decode the base64. ![](https://i.imgur.com/Pot75xh.png) We can use a simple get flag script. **Bash** ```bash= #!/usr/bin/env bash # @author: mug3njutsu echo "51584e7761584a6c653046795a534235623355675953426b5a585a766447566c4947396d4948526f5a53426d6157356c49474679644342765a6942696158527a494746755a4342696558526c637a3939" | xxd -r -p | base64 -d ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/hex_COMPLETE] └─$ ./ape.sh Aspire{Are you a devotee of the fine art of bits and bytes?} ``` **Python** ```python= #!/usr/bin/env python3 # @author: mug3njutsu from binascii import unhexlify from base64 import b64decode char = "51584e7761584a6c653046795a534235623355675953426b5a585a766447566c4947396d4948526f5a53426d6157356c49474679644342765a6942696158527a494746755a4342696558526c637a3939" string = unhexlify(char) flag = b64decode(string).decode() print(flag) ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/hex_COMPLETE] └─$ python3 ape.py Aspire{Are you a devotee of the fine art of bits and bytes?} ``` ### **Second Challenge: Primer - ON/OFF** ``` 01000001 01110011 01110000 01101001 01110010 01100101 01111011 01010100 01101000 01100101 01110010 01100101 00100000 01100001 01110010 01100101 00100000 00110001 00110000 00100000 01110100 01111001 01110000 01100101 01110011 00100000 01101111 01100110 00100000 01110000 01100101 01101111 01110000 01101100 01100101 00101110 00101110 00101110 01111101 ``` Binary indeed. Like before, you can use cyberchef to automatically decode the binary. ![](https://i.imgur.com/YDTvTnw.png) Scripting is fun, so i made a script in python that does the job. I can share a script in Python2 and one in Python3. **Python2** ```python= #!/usr/bin/env python # @author: mug3njutsu contents = "01000001 01110011 01110000 01101001 01110010 01100101 01111011 01010100 01101000 01100101 01110010 01100101 00100000 01100001 01110010 01100101 00100000 00110001 00110000 00100000 01110100 01111001 01110000 01100101 01110011 00100000 01101111 01100110 00100000 01110000 01100101 01101111 01110000 01101100 01100101 00101110 00101110 00101110 01111101" flag = contents.replace(" ", "") print(hex(int(flag, 2))[2:-1].decode('hex')) ``` **Python3** ```python= #!/usr/bin/env python3 # @author: mug3njutsu binary = "01000001 01110011 01110000 01101001 01110010 01100101 01111011 01010100 01101000 01100101 01110010 01100101 00100000 01100001 01110010 01100101 00100000 00110001 00110000 00100000 01110100 01111001 01110000 01100101 01110011 00100000 01101111 01100110 00100000 01110000 01100101 01101111 01110000 01101100 01100101 00101110 00101110 00101110 01111101".split() flag = [int(a, 2) for a in binary] print("".join(map(chr, flag))) ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/primer-on-off_COMPLETE] └─$ python3 ape.py Aspire{There are 10 types of people...} ``` ### **Third Challenge: Primer - Touch** ``` ⠁⠎⠏⠊⠗⠑{⠁⠞⠀⠽⠕⠥⠗⠀⠋⠊⠝⠛⠑⠗⠞⠊⠏⠎} ``` That is braille. And with some quick research, i found an online braille decoder. <a href="https://www.dcode.fr/braille-alphabet">Braille Translator</a> ![](https://i.imgur.com/pdPuMkH.png) There's the flag! It's literally that simple. Decided to do some geeky stuff and came up with a python script that decodes the braille to text. ```python= #!/usr/bin/env python3 # @author: mug3njutsu #BRAILLE_ENCODE_DICT = {" ":" ", "!":"⠮", '"':"⠐", "#":"⠼", "$":"⠫", "%":"⠩", "&":"⠯", "'":"⠄", "(":"⠷", ")":"⠾", "*":"⠡", "+":"⠬", ",":"⠠", "-":"⠤", ".":"⠨", "/":"⠌", "((0":"⠴", "1":"⠂", "2":"⠆", "3":"⠒", "4":"⠲", "5":"⠢", "6":"⠖", "7":"⠶", "8":"⠦", "9":"⠔", ":":"⠱", ";":"⠰", "<":"⠣", "=":"⠿", ">":"⠜", "?":"⠹", "@":"⠈", "A":"⠁", "B":"⠃", "C":"⠉", "D":"⠙", "E":"⠑", "F":"⠋", "G":"⠛", "H":"⠓", "I":"⠊", "J":"⠚", "K":"⠅", "L":"⠇", "M":"⠍", "N":"⠝", "O":"⠕", "P":"⠏", "Q":"⠟", "R":"⠗", "S":"⠎", "T":"⠞", "U":"⠥", "V":"⠧", "W":"⠺", "X":"⠭", "Y":"⠽", "Z":"⠵", "[":"⠪", "]":"⠻", "^":"⠘", "_":"⠸", "{":"{", "}":"}"} BRAILLE_DECODE_DICT = {"⠀":"⠀", "!":"⠮", '"':"⠐", "#":"⠼", "$":"⠫", "%":"⠩", "&":"⠯", "'":"⠄", "(":"⠷", ")":"⠾", "*":"⠡", "+":"⠬", ",":"⠠", "-":"⠤", ".":"⠨", "/":"⠌", "0":"⠴", "1":"⠂", "2":"⠆", "3":"⠒", "4":"⠲", "5":"⠢", "6":"⠖", "7":"⠶", "8":"⠦", "9":"⠔", ":":"⠱", ";":"⠰", "<":"⠣", "=":"⠿", ">":"⠜", "?":"⠹", "@":"⠈", "A":"⠁", "B":"⠃", "C":"⠉", "D":"⠙", "E":"⠑", "F":"⠋", "G":"⠛", "H":"⠓", "I":"⠊", "J":"⠚", "K":"⠅", "L":"⠇", "M":"⠍", "N":"⠝", "O":"⠕", "P":"⠏", "Q":"⠟", "R":"⠗", "S":"⠎", "T":"⠞", "U":"⠥", "V":"⠧", "W":"⠺", "X":"⠭", "Y":"⠽", "Z":"⠵", "[":"⠪", "]":"⠻", "^":"⠘", "_":"⠸", "{":"{", "}":"}"} def decode(instring): out = "" chunks, chunk_size = len(instring), 1 for i in range(0, chunks, chunk_size): for key, value in BRAILLE_DECODE_DICT.items(): if value == instring[i:i+chunk_size]: out += key continue return out """ def encode(instring): out = "" for s in instring: out += BRAILLE_ENCODE_DICT[s] return out """ if __name__ == "__main__": braille = "⠁⠎⠏⠊⠗⠑{⠁⠞⠀⠽⠕⠥⠗⠀⠋⠊⠝⠛⠑⠗⠞⠊⠏⠎}" decoder_result = decode(braille) print(decoder_result) ``` I was testing out it's ability to decode and encode text, that's why i never got rid of the comments. Might prove useful later. ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/primer-touch_COMPLETE] └─$ python3 ape.py ASPIRE{AT⠀YOUR⠀FINGERTIPS} ``` ### **Fourth Challenge: Primer - XOR: OTP** ``` 0000000000000011453d08004320493e00432204075800 Key: Aspire{A One Time Pad!} ``` Found an online resource to very easily decipher this with the key. <a href="https://www.dcode.fr/xor-cipher">XOR Decoder</a> ![](https://i.imgur.com/Tl5VQrp.png) Simple. Made a script in python to decipher this as well. ```python= #!/usr/bin/env python # @author: mug3njutsu from binascii import unhexlify enc = "0000000000000011453d08004320493e00432204075800" key = "Aspire{A One Time Pad!}" def solve(): unhexed = unhexlify(enc) flag = "" for a in range(len(unhexed)): flag += chr(ord(unhexed[a]) ^ ord(key[a % len(key)])) print(flag) def main(): solve() if __name__ == "__main__": main() ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/primer-xor-otp_COMPLETE] └─$ python ape.py Aspire{Perfect Secrecy} ``` ### **Fifth Challenge: Primer - XOR: A Solitary Byte** ``` Decrypt the following: 0032312833243a0e2f24612e2761352924617374773c Key: A ``` Similar challenge to the previous one. You could use the online decoder. Used the same python script as the previous challenge, just changed the cipher text and the key. ```python= #!/usr/bin/env python # @author: mug3njutsu from binascii import unhexlify enc = "0032312833243a0e2f24612e2761352924617374773c" key = "A" def solve(): unhexed = unhexlify(enc) flag = "" for a in range(len(unhexed)): flag += chr(ord(unhexed[a]) ^ ord(key[a % len(key)])) print(flag) def main(): solve() if __name__ == "__main__": main() ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/primer-xor-solitary-byte_COMPLETE] └─$ python ape.py Aspire{One of the 256} ``` ### **Sixth Challenge: Primer - Blocks** ``` Decrypt the following AES-128 ciphertext using ECB mode. 30975fd3aecf32625ef239b7fcbae845b00c265cc29bc04df3619985bb56af9f KEY: "HACK THE PLANET!" ``` Found an awesome resource. <a href="https://www.devglan.com/online-tools/aes-encryption-decryption">AES Encryption and Decryption Online Tool</a> ![](https://i.imgur.com/FdXlr8X.png) I also made a script for this in python. ```python #!/usr/bin/env python3 # @author: mug3njutsu from Crypto.Cipher import AES from binascii import unhexlify key = b'{KEY}' decipher = AES.new(key, AES.MODE_ECB) ciphertext = unhexlify("{STRING}") msg = decipher.decrypt(ciphertext) print(msg.decode()) ``` ### **Seventh Challenge: Primer - XOR: Repeater** ``` The following hex encoded key has been encrypted using a repeating key. Decode it. 0020202020203a74132827362473392772312936703a26372436243a7e6508743d6925202d3f70223c2a363d70253b2e2473242137652f263d2b3737613e31272f KEY: ASPIRE ``` Yes. I used the same python script for the previous XOR challenges, just changed the ciphertext and the key. ```python= #!/usr/bin/env python # @author: mug3njutsu from binascii import unhexlify enc = "0020202020203a74132827362473392772312936703a26372436243a7e6508743d6925202d3f70223c2a363d70253b2e2473242137652f263d2b3737613e31272f" key = "ASPIRE" def solve(): unhexed = unhexlify(enc) flag = "" for a in range(len(unhexed)): flag += chr(ord(unhexed[a]) ^ ord(key[a % len(key)])) print(flag) def main(): solve() if __name__ == "__main__": main() ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/primer-xor-repeater_COMPLETE] └─$ python ape.py Aspire{'Cause in the streets, I'm well known like the number man} ``` ### **Eighth Challenge: Matthew 22:21** ``` vasbezngvba vf gur erfbyhgvba bs hapregnvagl - Nfcver{Pynhqr Funaaba} ``` Seems to be rotated text. I really enjoy such challenges. This is most likely ROT13, but just to be sure, I used `caesar` to loop through the 26 rotations which ideally does this. ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/matthew_COMPLETE] └─$ for i in {1..13}; do echo -n "rot$i: "; echo "Nfcver{Pynhqr Funaaba}" | caesar $i; done rot1: Ogdwfs{Qzoirs Gvobbcb} rot2: Phexgt{Rapjst Hwpccdc} rot3: Qifyhu{Sbqktu Ixqdded} rot4: Rjgziv{Tcrluv Jyreefe} rot5: Skhajw{Udsmvw Kzsffgf} rot6: Tlibkx{Vetnwx Latgghg} rot7: Umjcly{Wfuoxy Mbuhhih} rot8: Vnkdmz{Xgvpyz Ncviiji} rot9: Wolena{Yhwqza Odwjjkj} rot10: Xpmfob{Zixrab Pexkklk} rot11: Yqngpc{Ajysbc Qfyllml} rot12: Zrohqd{Bkztcd Rgzmmnm} rot13: Aspire{Claude Shannon} ``` Incase you don't have `caesar`, you can install it using `sudo apt install bsdgames`. You could also use this resource: <a href="https://rot13.com/">rot13</a> ![](https://i.imgur.com/rtBBa3Z.png) Here's a simple get flag script. ```bash= #!/usr/bin/env bash # @author: mug3njutsu for i in {1..26}; do echo "vasbezngvba vf gur erfbyhgvba bs hapregnvagl - Nfcver{Pynhqr Funaaba}" | caesar $i; done | grep -oE "Aspire{.*?}" ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/matthew_COMPLETE] └─$ ./ape.sh Aspire{Claude Shannon} ``` ### **Ninth Challenge: Tele** ``` Find the message Flag format: Aspire{message} ``` You can access the file here: <a href="https://ciphercode.dev/files/a5d2d6be4f2b70d655c7475a7ba19893/tele.jpg?token=eyJ1c2VyX2lkIjoyOTksInRlYW1faWQiOjIwMiwiZmlsZV9pZCI6MjR9.YHdcQQ.3FBYfnYwWbRx8O5jOp-ozABHveY">Challenge</a> You're given a jpg file. And the first thing i did was to run `exiftool`. ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/tele_COMPLETE] └─$ exiftool tele.jpg ExifTool Version Number : 12.16 File Name : tele.jpg Directory : . File Size : 29 KiB File Modification Date/Time : 2021:04:07 12:16:49+03:00 File Access Date/Time : 2021:04:24 12:33:34+03:00 File Inode Change Date/Time : 2021:04:07 12:17:03+03:00 File Permissions : rw-r--r-- File Type : JPEG File Type Extension : jpg MIME Type : image/jpeg XMP Toolkit : Image::ExifTool 11.88 Aspire : .- / -.. --- - / .... . .-. . / .- -. -.. / .- / -.. .- ... .... / - .... . .-. . Image Width : 470 Image Height : 251 Encoding Process : Progressive DCT, Huffman coding Bits Per Sample : 8 Color Components : 3 Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2) Image Size : 470x251 Megapixels : 0.118 ``` We get and interesting comment called Aspire and what looks to be a morsecode. <a href="https://morsecode.world/international/translator.html">Morse Code Translator</a> This is an awesome online resource to decode the morsecode. ![](https://i.imgur.com/wpxthi1.png) ![](https://i.imgur.com/NifM5Ay.gif) Made a python script to decode the morse to text. ```python= #!/usr/bin/env python3 # @author: mug3njutsu import subprocess MORSE_CODE_DICT = { 'A':'.-', 'B':'-...', 'C':'-.-.', 'D':'-..', 'E':'.', 'F':'..-.', 'G':'--.', 'H':'....', 'I':'..', 'J':'.---', 'K':'-.-', 'L':'.-..', 'M':'--', 'N':'-.', 'O':'---', 'P':'.--.', 'Q':'--.-', 'R':'.-.', 'S':'...', 'T':'-', 'U':'..-', 'V':'...-', 'W':'.--', 'X':'-..-', 'Y':'-.--', 'Z':'--..', '1':'.----', '2':'..---', '3':'...--', '4':'....-', '5':'.....', '6':'-....', '7':'--...', '8':'---..', '9':'----.', '0':'-----', ', ':'--..--', '.':'.-.-.-', '?':'..--..', '/':'-..-.', '-':'-....-', '(':'-.--.', ')':'-.--.-', ' ':'/'} def decrypt(message): message += ' ' decipher = '' citext = '' for letter in message: if (letter != ' '): i = 0 citext += letter else: i += 1 if i == 2 : decipher += ' ' else: decipher += list(MORSE_CODE_DICT.keys())[list(MORSE_CODE_DICT.values()).index(citext)] citext = '' return decipher def main(): message = subprocess.check_output(['exiftool tele.jpg | cut -d ":" -f 2 | head -n 13 | tail -n 1'], shell=True).decode().strip() result = decrypt(message) print('Aspire{' + result + '}') if __name__ == '__main__': main() ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/tele_COMPLETE] └─$ python3 ape.py Aspire{A DOT HERE AND A DASH THERE} ``` ### **Tenth Challenge: Wavy** ``` Find the message. Flag format: Aspire{message} ``` You can access the file here: <a href="https://ciphercode.dev/files/0c9e18dbb0e0acc65c2568b580b36133/wavy.wav?token=eyJ1c2VyX2lkIjoyOTksInRlYW1faWQiOjIwMiwiZmlsZV9pZCI6MjN9.YHg-9w.9ia-xczjZPrpUVoN0fjea72S3Fg">Challenge</a> We are given a wav file and when you play it, you hear an unusual sequence of pauses or sort. So, the first thing that came up was, it might be playing a morse code. So, i googled `audio morse decoder`. Came across an interesting website, <a href="https://morsecode.world/international/decoder/audio-decoder-adaptive.html">Morse Code Adaptive Audio Decoder</a>. Uploaded the audio file, and waited for it to decode letter by letter and ended up with something this: `EI O M E T I M E S I T I S T H E P E O P L E N O O N E C A N I M A G I N E A N Y T H I N G O F W H O B O T H E T H I N G S N O O N E C A N I M A G I N E` ![](https://i.imgur.com/1144suW.png) The first word `EIOMETIMES` should actually be `SOMETIMES`. Another bug is `WHO BO THE` should be `WHO DO THE`. Abit of a guessing game there. And then you had to change the casing to small and then space the words to get the actual flag. `Aspire{sometimes it is the people no one can imagine anything of who do the things no one can imagine}`. Wanted to come up with a script for this one, but, no luck with that. ### **Eleventh Challenge: Cover Image** ``` Find what is hidden. My cool friend will help you pass. ``` You can access the file here: <a href="https://ciphercode.dev/files/23e48b8b3bee2aadc707292b52cfa33f/scorpion.jpg?token=eyJ1c2VyX2lkIjoyOTksInRlYW1faWQiOjIwMiwiZmlsZV9pZCI6Mjh9.YHhBJA.OcsRDWYWVax368i9_Tw-rmINwg8">Challenge</a> You're given a jpg file. Running `exiftool`, `binwalk` doesn't get anything interesting. So, i decided to try out `stegseek`. And just incase you don't know what tool that is, you can check it out here <a href="https://github.com/RickdeJager/stegseek">Stegseek</a>. It's super reliable because it's insanely fast. Quick analysis. | password | Line | Stegseek | StegCracker | StegBrute | | -------- | ---- | -------- | ----------- | --------- | |"cassandra" | 1 000 | 0.05s | 3.1s | 0.7s | | "kupal" | 10 000 | 0.05s | 14.4s | 7.1s | | "sagar" | 100 000 | 0.09s | 2m23.0s | 1m21.9s | | "budakid1" | 1 000 000 | 0.73s | [p] 23m50.0s | 13m45.7s | That is incredible. If you'd like to install it, you can run: ``` wget https://github.com/RickdeJager/stegseek/releases/download/v0.5/stegseek_0.5-1.deb sudo dpkg -i ./stegseek_0.5-1.deb ``` And you're done. Running this... ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/cover-image_COMPLETE] └─$ stegseek scorpion.jpg /usr/share/wordlists/rockyou.txt -xf subzero.jpg StegSeek version 0.5 Progress: 13.87% (19408343 bytes) [i] --> Found passphrase: "subzero" [i] Original filename: "subzero.jpg" [i] Extracting to "subzero.jpg" ``` The extracted JPEG file has the flag. ![](https://i.imgur.com/G9GEfTn.jpg) I made a script for this one. It will run the entire process, that is, cracking the jpg file using stegseek, then it'll use `pytesseract` which is an OCR module for python. And this is supposed to read text from the jpg file we extracted. However, i had a problem getting it to read the text from that file, so what i did was i took a screenshot of the thin section where the flag was and base64 encoded that screenshot into the script. Because hey, i wanted to make a script that automates that, opens the flag.jpg, and then takes a screenshot of that thin section and then saves it to a file and reads that with `pytesseract`. The thing is, i ended up making a GUI that takes screenshots..ahahahaha. ![](https://i.imgur.com/JYqD2jr.gif) ```python= #!/usr/bin/env python3 # @author: mug3njutsu from os import system from PIL import Image from pytesseract import pytesseract system("stegseek scorpion.jpg /usr/share/wordlists/rockyou.txt -xf subzero.jpg") data = "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" file = system(f'echo {data} | base64 -d > newflag.png') img = Image.open('newflag.png').convert("RGB") text = pytesseract.image_to_string(img) print(text[:-1].replace(" ", "").strip()) ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/cover-image_COMPLETE] └─$ python3 ape.py StegSeek version 0.5 Progress: 15.52% (21719961 bytes) [i] --> Found passphrase: "subzero" [i] Original filename: "subzero.jpg" [i] Extracting to "subzero.jpg" Aspire{Chill} ``` Smooth. ### **Twelfth Challenge: One way** ``` Break the following hash: 49418d084567b5d3e3067ae735965961 Flag format: Aspire{????} ``` I really liked this one xD. Sat on it for like 3 hours and blooded it. Figuring it out was so relieving reason being, i was wondering how a 200-point challenge could be that difficult. So, the thing that threw people off the boat was they thought that the string in between the flag was md5 encoded. Yes, md5. The challenge name tells you it's md5 encoded because on the wikipedia about MD5, you'll see this `Historically, MD5 has been used to store a one-way hash of a password, often with key stretching.` Ideally, the entire flag was encoded which was pretty cool. Whoever made this challenge, you're brilliant lol. I used `sed` at first to append parts of the flag to rockyou and then used john to crack the hash. ``` sed -i 's/^/Aspire{/g' rockyou.txt sed -i 's/$/}/g' rockyou.txt ``` The first command will append `Aspire{` to the beginning of each line. Then the second will append `}` to the end of each line. At this point we'll have a passlist with flags. ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/one-way_COMPLETE] └─$ sed -i 's/^/Aspire{/g' rockyou.txt; cat rockyou.txt | head -n 1 Aspire{123456 ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/one-way_COMPLETE] └─$ sed -i 's/$/}/g' rockyou.txt; cat rockyou.txt| head -n 1 Aspire{123456} ``` Sweeeet! Now let's crack the hash using john the ripper.. And for some reason, if you run john without specifying that the hash is md5, it won't work. That's why i said the challenge name was just right. ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/one-way_COMPLETE] └─$ john -w=rockyou.txt --format=Raw-MD5 hash Using default input encoding: UTF-8 Loaded 1 password hash (Raw-MD5 [MD5 256/256 AVX2 8x3]) Warning: no OpenMP support for this hash type, consider --fork=4 Press 'q' or Ctrl-C to abort, almost any other key for status Aspire{Nice} (?) 1g 0:00:00:01 DONE (2021-04-25 19:24) 0.6849g/s 7384Kp/s 7384Kc/s 7384KC/s Aspire{Nick1222}..Aspire{Niamh010} Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably Session completed ``` And we get the flag. I also made a ruby script that just hammers that and it will guess the string that's inbetween the flag. ```ruby= #!/usr/bin/env ruby # @author: mug3njutsu require 'digest/md5' $my_hash = "49418d084567b5d3e3067ae735965961" def attempt(guess) if Digest::MD5.hexdigest("Aspire{#{guess}}") == $my_hash then puts "Flag: Aspire{#{guess}}" exit end end #A capital letter and three small letters. for a in "A".."Z" for b in "a".."z" for c in "a".."z" for d in "a".."z" permutes = [a, b, c, d].permutation.map &:join for guess in permutes attempt(guess) end end end end puts "a=" + a end ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/one-way_COMPLETE] └─$ ruby ape.rb a=A a=B a=C a=D a=E a=F a=G a=H a=I a=J a=K a=L a=M Flag: Aspire{Nice} ``` ### **Thirteenth Challenge: Alan's Hash** ``` What is Alan's password? Flag format: Aspire{password} ``` You can access the file here: <a href="https://ciphercode.dev/files/c233133c9584ed80fbb130c246cf1f06/enigma.png?token=eyJ1c2VyX2lkIjoyOTksInRlYW1faWQiOjIwMiwiZmlsZV9pZCI6Mjd9.YHhJqw.euz7aZDLGQIUQKF20K2kPqqbZlI">Challenge</a> You're given a QR code and my first thought was, it must have some hidden data. I then googled `qr code decoder` and found this <a href="https://zxing.org/w/decode.jspx">ZXing Decoder Online</a> ![](https://i.imgur.com/EJcDk7t.png) Got this with a pastebin link which is interesting. Heading there, got this hash: `Alan:500:aad3b435b51404eeaad3b435b51404ee:8bf2a1dffe406c86434ac82c841328ed:::` And, the challenge asks for Alan's password, so, took the second part of the hash and went to <a href="https://hashes.com/en/decrypt/hash">Hashes</a> ![](https://i.imgur.com/OItMNv6.png) And that gives us `turing4ever` which is Alan's password. ### **Fourteenth Challenge: Breaker - Single byte XOR** ``` The following hex encoded string has been XOR'd against a single character. Find the key and decrypt the message. 15342c7b2d32382f3429227b32287b3632353e777b28333e7b2f3a282f3e287b28347b282c3e3e2f5108333eb9dbc2287b36227b2f29342b33227b2c323d3e777b28333e7c287b38343632353c7b2c322f337b363e510c3e7c37377b333a2d3e7b3a7b393a39227b2c33347b282f2e2f2f3e29287b293e2b3e3a2f3e3f3722510c3e7c37377b353a363e7b3332367b3332282f342922777b333e7c37377b293e2b3e3a2f7b3a3d2f3e297b363e51133eb9dbc2287b36227b373e3c3a3822777b2834357b343d7b36227b333a293f7b2c342930511d2e2f2e293e7b343d7b36227b2b3a282f777b333eb9dbc237377b3e232b373a32357b2c33347b127b393e51093a35307b363e7b3a3634353c282f7b2f333e7b3c293e3a2f28777b3e322f333e297b6a777b697b34297b6851123d7b127b3a3235b9dbc22f7b352e36393e297b34353e7b2f333e357b127b3d3a32373e3f7b22342e7b2d32382f342922511a3235b9dbc22f7b32357b322f7b3d34297b2f333e7b3d3a363e777b2f333a2f7b3f323e287b2c322f3332357b2c3e3e3028511a3235b9dbc22f7b32357b322f7b3d34297b2f333e7b3634353e22777b383a35b9dbc22f7b2f3a303e7b322f7b2c333e357b22342e7b373e3a2d3e51127b2c3a35353a7b393e7b293e363e36393e293e3f7b3734353c7b3a3d2f3e297b22342e7b3c29323e2d3e511734353c7b3a3d2f3e297b12b9dbc2367b3c34353e777b3734353c7b3a3d2f3e297b127b39293e3a2f333e51127b373e3a2d3e7b3a37377b127b3a36777b32357b2f333e7b333a353f287b343d7b3332282f342922510f333a2f7c287b36227b373a282f7b2c3237377b2f3e282f3236343522510f3332287b32287b362e38337b3634293e7b2f333a357b3a7b2834353c777b322fb9dbc2287b3a7b393a39227b2833342c3e295112b9dbc22d3e7b393e3e357b2c3a322f32353c7b3d34297b2f3332287b33342e29777b3332282f342922777b22342e7c293e7b342e2928 Flag format: Aspire{first line of the message} ``` This challenge, unlike the previous ones, you have to find the key and then decrypt the cipher and that's why it's called `Breaker`. At the beginning of this blog i mentioned a cool resource from `Cryptopal's Challenges` writeups where i used their scripts wisely and was able to solve these Breaker challenges. ![](https://i.imgur.com/BS4NfMu.png) Got the solution for this one here: <a href="https://laconicwolf.com/2018/05/29/cryptopals-challenge-3-single-byte-xor-cipher-in-python/">Cryptopals challenge 3: Single-byte XOR cipher in Python</a> Here's my final script. ```python= #!/usr/bin/env python3 # @author: mug3njutsu def get_english_score(input_bytes): """Compares each input byte to a character frequency chart and returns the score of a message based on the relative frequency the characters occur in the English language """ # From https://en.wikipedia.org/wiki/Letter_frequency # with the exception of ' ', which I estimated. character_frequencies = { 'a': .08167, 'b': .01492, 'c': .02782, 'd': .04253, 'e': .12702, 'f': .02228, 'g': .02015, 'h': .06094, 'i': .06094, 'j': .00153, 'k': .00772, 'l': .04025, 'm': .02406, 'n': .06749, 'o': .07507, 'p': .01929, 'q': .00095, 'r': .05987, 's': .06327, 't': .09056, 'u': .02758, 'v': .00978, 'w': .02360, 'x': .00150, 'y': .01974, 'z': .00074, ' ': .13000 } return sum([character_frequencies.get(chr(byte), 0) for byte in input_bytes.lower()]) def single_char_xor(input_bytes, char_value): """Returns the result of each byte being XOR'd with a single value. """ output_bytes = b'' for byte in input_bytes: output_bytes += bytes([byte ^ char_value]) return output_bytes def main(): hexstring = '15342c7b2d32382f3429227b32287b3632353e777b28333e7b2f3a282f3e287b28347b282c3e3e2f5108333eb9dbc2287b36227b2f29342b33227b2c323d3e777b28333e7c287b38343632353c7b2c322f337b363e510c3e7c37377b333a2d3e7b3a7b393a39227b2c33347b282f2e2f2f3e29287b293e2b3e3a2f3e3f3722510c3e7c37377b353a363e7b3332367b3332282f342922777b333e7c37377b293e2b3e3a2f7b3a3d2f3e297b363e51133eb9dbc2287b36227b373e3c3a3822777b2834357b343d7b36227b333a293f7b2c342930511d2e2f2e293e7b343d7b36227b2b3a282f777b333eb9dbc237377b3e232b373a32357b2c33347b127b393e51093a35307b363e7b3a3634353c282f7b2f333e7b3c293e3a2f28777b3e322f333e297b6a777b697b34297b6851123d7b127b3a3235b9dbc22f7b352e36393e297b34353e7b2f333e357b127b3d3a32373e3f7b22342e7b2d32382f342922511a3235b9dbc22f7b32357b322f7b3d34297b2f333e7b3d3a363e777b2f333a2f7b3f323e287b2c322f3332357b2c3e3e3028511a3235b9dbc22f7b32357b322f7b3d34297b2f333e7b3634353e22777b383a35b9dbc22f7b2f3a303e7b322f7b2c333e357b22342e7b373e3a2d3e51127b2c3a35353a7b393e7b293e363e36393e293e3f7b3734353c7b3a3d2f3e297b22342e7b3c29323e2d3e511734353c7b3a3d2f3e297b12b9dbc2367b3c34353e777b3734353c7b3a3d2f3e297b127b39293e3a2f333e51127b373e3a2d3e7b3a37377b127b3a36777b32357b2f333e7b333a353f287b343d7b3332282f342922510f333a2f7c287b36227b373a282f7b2c3237377b2f3e282f3236343522510f3332287b32287b362e38337b3634293e7b2f333a357b3a7b2834353c777b322fb9dbc2287b3a7b393a39227b2833342c3e295112b9dbc22d3e7b393e3e357b2c3a322f32353c7b3d34297b2f3332287b33342e29777b3332282f342922777b22342e7c293e7b342e2928' ciphertext = bytes.fromhex(hexstring) potential_messages = [] for key_value in range(256): message = single_char_xor(ciphertext, key_value) score = get_english_score(message) data = { 'message': message.decode("latin-1"), 'score': score, 'key': key_value } potential_messages.append(data) best_score = sorted(potential_messages, key=lambda x: x['score'], reverse=True)[0] for item in best_score: print("{}: {}".format(item.title(), best_score[item])) if __name__ == '__main__': main() ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/breaker-single-byte-xor_COMPLETE] └─$ python3 ape.py Message: Now victory is mine, she tastes so sweet Sheâs my trophy wife, she's coming with me We'll have a baby who stutters repeatedly We'll name him history, he'll repeat after me Heâs my legacy, son of my hard work Future of my past, heâll explain who I be Rank me amongst the greats, either 1, 2 or 3 If I ainât number one then I failed you victory Ainât in it for the fame, that dies within weeks Ainât in it for the money, canât take it when you leave I wanna be remembered long after you grieve Long after Iâm gone, long after I breathe I leave all I am, in the hands of history That's my last will testimony This is much more than a song, itâs a baby shower Iâve been waiting for this hour, history, you're ours Score: 50.97693000000017 Key: 91 ``` That was easy. Changed a few things here and there but, it's the same script. ### **Fifteenth Challenge: Breaker - Single byte XOR in a haystack** ``` One of the 94-character strings in the attached file has been encrypted by single-character XOR. Find it and decrypt it. Flag format: Aspire{decrypted message} ``` You can access the file here: <a href="https://ciphercode.dev/files/d800aa3386ae49daa91729a0d63f5a44/single_xor.txt?token=eyJ1c2VyX2lkIjoyOTksInRlYW1faWQiOjIwMiwiZmlsZV9pZCI6MjV9.YHhQ1Q.HUh8x8lozAUXcPWQvKZ9ENKtUMs">Challenge</a> Got the solution here: <a href="https://laconicwolf.com/2018/06/05/cryptopals-challenge-4-detect-single-character-xor-encryption/">Cryptopals challenge 4: Detect single-character XOR encryption</a> And my final sript: ```python= #!/usr/bin/env python3 # @author: mug3njutsu def get_english_score(input_bytes): """Compares each input byte to a character frequency chart and returns the score of a message based on the relative frequency the characters occur in the English language. """ # From https://en.wikipedia.org/wiki/Letter_frequency # with the exception of ' ', which I estimated. character_frequencies = { 'a': .08167, 'b': .01492, 'c': .02782, 'd': .04253, 'e': .12702, 'f': .02228, 'g': .02015, 'h': .06094, 'i': .06094, 'j': .00153, 'k': .00772, 'l': .04025, 'm': .02406, 'n': .06749, 'o': .07507, 'p': .01929, 'q': .00095, 'r': .05987, 's': .06327, 't': .09056, 'u': .02758, 'v': .00978, 'w': .02360, 'x': .00150, 'y': .01974, 'z': .00074, ' ': .13000 } return sum([character_frequencies.get(chr(byte), 0) for byte in input_bytes.lower()]) def single_char_xor(input_bytes, char_value): """Returns the result of each byte being XOR'd with a single value. """ output_bytes = b'' for byte in input_bytes: output_bytes += bytes([byte ^ char_value]) return output_bytes def bruteforce_single_char_xor(ciphertext): """Performs a singlechar xor for each possible value(0,255), and assigns a score based on character frequency. Returns the result with the highest score. """ potential_messages = [] for key_value in range(256): message = single_char_xor(ciphertext, key_value) score = get_english_score(message) data = { 'message': message.decode("latin-1"), 'score': score, 'key': key_value } potential_messages.append(data) return sorted(potential_messages, key=lambda x: x['score'], reverse=True)[0] def main(): ciphers = open('single_xor.txt').read().splitlines() potential_plaintext = [] for hexstring in ciphers: ciphertext = bytes.fromhex(hexstring) potential_plaintext.append(bruteforce_single_char_xor(ciphertext)) best_score = sorted(potential_plaintext, key=lambda x: x['score'], reverse=True)[0] for item in best_score: print("{}: {}".format(item.title(), best_score[item])) if __name__ == '__main__': main() ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/breaker-single-byte-xor-in-a-haystack_COMPLETE] └─$ python3 ape.py Message: They said they need proof like a vestless chest Score: 3.7722199999999995 Key: 92 ``` Nice and easy. ### **Sixteenth Challenge: Breaker - Repeating XOR** ``` The hex encoded data in the file attached has been XOR'ed using a repeating key XOR. Find the key and decrypt the message. The key length is between 2 and 20 bytes. Flag format: Aspire{key} Hint: Hamming Distance ``` Got the solution here: <a href="https://cedricvanrompay.gitlab.io/cryptopals/challenges/01-to-08.html">01-to-08</a> For this one, even if you had the resource available to you and you didn't know how to debug the code, it wouldn't have been easy. My final script: ```python= #!/usr/bin/env python3 # @author: mug3njutsu from binascii import unhexlify def bxor(a, b): "bitwise XOR of bytestrings" return bytes([ x^y for (x,y) in zip(a, b)]) def hamming_distance(a, b): return sum(bin(byte).count('1') for byte in bxor(a,b)) with open("repeat_breaker.txt") as file: ciphertext = unhexlify(file.read()) def score_vigenere_key_size(candidate_key_size, ciphertext): # as suggested in the instructions, # we take samples bigger than just one time the candidate key size slice_size = 2*candidate_key_size # the number of samples we can make # given the ciphertext length nb_measurements = len(ciphertext) // slice_size - 1 # the "score" will represent how likely it is # that the current candidate key size is the good one # (the lower the score the *more* likely) score = 0 for i in range(nb_measurements): s = slice_size k = candidate_key_size # in python, "slices" objects are what you put in square brackets # to access elements in lists and other iterable objects. # see https://docs.python.org/3/library/functions.html#slice # here we build the slices separately # just to have a cleaner, easier to read code slice_1 = slice(i*s, i*s + k) slice_2 = slice(i*s + k, i*s + 2*k) score += hamming_distance(ciphertext[slice_1], ciphertext[slice_2]) # normalization: do not forget this # or there will be a strong biais towards long key sizes # and your code will not detect key size properly score /= candidate_key_size # some more normalization, # to make sure each candidate is evaluated in the same way score /= nb_measurements return score def find_vigenere_key_length(ciphertext, min_length=2, max_length=30): # maybe this code is a bit over-sophisticated # it just outputs the key size for wich # the score at the "score_vigenere_key_size" function is the *lowest* key = lambda x: score_vigenere_key_size(x,ciphertext) return min(range(min_length, max_length), key=key) def attack_single_byte_xor(ciphertext): # a variable to keep track of the best candidate so far best = None for i in range(2**8): # for every possible key # converting the key from a number to a byte candidate_key = i.to_bytes(1, byteorder='big') keystream = candidate_key*len(ciphertext) candidate_message = bxor(ciphertext, keystream) ascii_text_chars = list(range(97, 122)) + [32] nb_letters = sum([ x in ascii_text_chars for x in candidate_message]) # if the obtained message has more letters than any other candidate before if best == None or nb_letters > best['nb_letters']: # store the current key and message as our best candidate so far best = {"message": candidate_message, 'nb_letters': nb_letters, 'key': candidate_key} return best def attack_repeating_key_xor(ciphertext): keysize = find_vigenere_key_length(ciphertext) # we break encryption for each character of the key key = bytes() message_parts = list() for i in range(keysize): # the "i::keysize" slice accesses elements in an array # starting at index 'i' and using a step of 'keysize' # this gives us a block of "single-character XOR" (see figure above) part = attack_single_byte_xor(bytes(ciphertext[i::keysize])) key += part["key"] message_parts.append(part["message"]) # then we rebuild the original message # by putting bytes back in the proper order # TODO again code may be over-sophisticated and not very readable here message = bytes() for i in range(max(map(len, message_parts))): message += bytes([part[i] for part in message_parts if len(part)>=i+1]) return {'message':message, 'key':key} result = attack_repeating_key_xor(ciphertext) print("key:",result["key"].decode(),'\n') print('message:\n') print(result["message"].decode()) ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/breaker-repeating-xor_COMPLETE] └─$ python3 ape.py key: LyricalLyricalLyrical message: I ain’t scanning networks for practice Checking ports. I am scanning for access Enumeratin’ services. Better apply your patches I’ll search sploits. exploitDB knows what the hack is Yo, you need fortify heavily I see your database services and version 1 SMB You know what this nerd gon’ do, payloads I’mma turn on you That quad 4 make you sad forever, that’s ETERNALBLUE Dumpin’ hashes when I’m loading up that mimikatz Creds to my boy John, see how many he can crack Smash and I grab on that lateral path Ain’t movin’ blunts when I say that I’m passin the hash Not a script kiddie. They ain’t the level I’m on I’m a snake charmer, watch me dance around some Python And generate shellcode for services I find on, ya network Pop a shell, I get right on No anti-virus seen. Well, I guess you never heard of those I’m on that Willy Wonka, got the golden ticket, Kerberos You actively blind, I’m tappin’ ya lines, homey. All ya unsecure traffic is mine Why ya boss browsing porno in the work day? No good, he ‘bout a catch a virus in the worst way He’s staring at a lot of chicks, but all that I’m gettin’ out of it That site he’s peepin’ is mining Monero with some Javascript And I bet he won’t like that. I’m just tryna get paid to be a white hat Open my report, I’mma write that and Show the impact of an attacker and Put ‘em on the right track I’ll advise you invest. A HIDS or a NIDS, or a fly IPS Firewall ports, and deny that egress Or I’ll deliver a payload right to ya chest ``` Another thing is, the flag format needs a key and we got `LyricalLyricalLyrical`. That doesn't work and this spiked my adrenaline for a moment. The actually idea was that the key was one of those words since it's just a repeat of the word `Lyrical`. ### **Seventeenth Challenge: Attack of the Oracle** ``` The Aspire Cryptographic System accepts your input and encrypts it as follows: AES-128-ECB(your string || flag) For instance if your input is "123", the system will encrypt is as follows: AES-128-ECB(123flag). The encryption key used remains the same every time. Server: 149.248.56.250 Port: 45912 Decrypt the flag! ``` I didn't understand the attack method for this as much. Found a good resource though: <a href="https://godiego.tech/posts/AES-128-padding-attack/">AES 128 Padding Attack - CSACTF Crypto: Flag server</a> Tried to modify the script but, i wasn't able to succeed. I then reached out to a friend of mine called Lucas and asked him to help me out because i was burning out, 8, almost 9 hours in and wasn't close to the solution. He was able to come up with this script: ```python= #!/usr/bin/env python3 # @author: Lucas import socket import string sk = socket.socket() sk.connect(('149.248.56.250', 45912)) sk.recv(2048) known_text = "" blocksize = 16 size = blocksize - 1 tmp = "" def brute(search, pad, index): for c in string.printable: print('\b%s' %c, end='', flush=True) payload = pad + known_text + tmp + c sk.send(b"encrypt " + payload.encode()) data = b'' while not b'\r\n' in data: data += sk.recv(1024) data = data[3:].decode().rstrip().split()[0] block = data[index * 2 * blocksize : index * 2 * blocksize + 2 * blocksize] if block == search: print(" ", end=''); return c index = 0 while (1): pad = "Z" * size sk.send(b"encrypt " + pad.encode()) data = b'' while not b'\r\n' in data: data += sk.recv(1024) data = data[3:].decode().rstrip().split()[0] if (size == blocksize): data = data[blocksize * 2:] block = data[index * 2 * blocksize : index * 2 * blocksize + 2 * blocksize] tmp += brute(block, pad if size != blocksize else "", index) if len(tmp) == blocksize: known_text += tmp if tmp[-1] == '}': print() print("FLAG:", known_text) break tmp = "" index += 1 size = size - 1 if size > 1 else blocksize if (len(known_text) == len(data) / 2): break ``` ``` ┌──(mug3njutsu㉿Lenovo-Ideapad)-[~/ctf/aspire ctf/attack-oracle_COMPLETE] └─$ python3 ape.py Aspire{You-Got-The-Gift,-But-It-Looks-Like-You're-Waiting-For-Something.} ``` Those are all the crypto challenges. It was too much fun. Hope you learnt something. <a href="https://www.buymeacoffee.com/mug3njutsu"><img class="bounce" src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=vsalguero&button_colour=BD5FFF&font_colour=ffffff&font_family=Cookie&outline_colour=000000&coffee_colour=FFDD00"></a> <style> /*Bounce*/ @keyframes bounce { 0%, 5%, 15%, 25% { -webkit-transform: translateY(0); transform: translateY(0); } 10% { -webkit-transform: translateY(-20px); transform: translateY(-20px); } 20% { -webkit-transform: translateY(-10px); transform: translateY(-10px); } } .bounce{ animation: bounce 5s infinite; } </style> <style> .twitter a { font-family: "Roboto", "Noto Sans", "Open Sans", "sans-serif"; display: inline-flex; color: #fff; border-radius: 5px; background: #1b95e0; padding: .4em .8em; text-decoration: none; font-weight: bold; text-align: left; position: absolute; bottom:138px; left:300px; } </style> <div class="twitter" style="height: 35px; width: 300px;"><a target="_blank" rel="noopener noreferrer" href="https://twitter.com/mug3njutsu"> <svg height="20px" width="20px" style="margin-right: 5px; fill: #fff;" viewBox="0 0 512 512" preserveAspectRatio="none"> <path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z" /></a></div> <style> body[style], body[style*="background-color: white;"] { background-color: #1e1e1e !important; } body { color: #abb2bf; } .ui-view-area, .markdown-body, .ui-content { background: #1e1e1e; color: #abb2bf; } h1, h2, h3, h4, h5, h6, p { color: #ddd; } /* form */ .form-control { background: #333; color: #fff; border-color: #8e8e8e; } .form-control::placeholder, .form-control::-webkit-input-placeholder, .form-control:-moz-placeholder, .form-control::-moz-placeholder, .form-control:-ms-input-placeholder { color: #eee; } /*--------------- navbar ---------------*/ .header { background-color: #0e0e0e; border-color: #0e0e0e; } .navbar { background-color: #0e0e0e; border-color: #0e0e0e; } .navbar a { color: #eee !important; } .navbar .btn-group label { background-color: #0e0e0e; color: #eee; border-color: #555; } .navbar .btn-group label.btn-default:focus, .navbar .btn-group label.btn-default:hover { background-color: #2a2a2a; color: #eee; border-color: #555; } .navbar .btn-group label.active { background-color: #555; color: #eee; border-color: #555; } .navbar .btn-group label.active:focus, .navbar .btn-group label.active:hover { background-color: #555; color: #eee; border-color: #555; } .navbar-default .btn-link:focus, .navbar-default .btn-link:hover { color: #eee; } .navbar-default .navbar-nav>.open>a, .navbar-default .navbar-nav>.open>a:focus, .navbar-default .navbar-nav>.open>a:hover { background-color: #555; } .dropdown-header { color: #eee; } .dropdown-menu { background-color: #222; border: 1px solid #555; border-top: none; } .dropdown-menu>li>a { color: #eee; } .dropdown-menu>li>a:focus, .dropdown-menu>li>a:hover { background-color: #555555; color: #eee; } .dropdown-menu .divider { background-color: #555; } .header .open .dropdown-menu { background-color: #202020; } .ui-share-menu .ui-share-copy, .ui-share-menu .ui-share-preview { border-color: #6d6d6d !important; background-color: #333 !important; color: #FFF !important; } .ui-share-menu .ui-share-copy:hover, .ui-share-menu .ui-share-copy:focus, .ui-share-menu .ui-share-preview:hover, .ui-share-menu .ui-share-preview:focus { background-color: #737373 !important; color: #FFF !important; } .permission-dropdown .ui-more-settings, .permission-dropdown .sidenav-trigger { color: #7bf; } .public-published-toggle .unpublish:hover { background-color: #286090; } .menuitem-dropdown .menuitem-dropdown-trigger { border-color: #8e8e8e; } .menuitem-dropdown .menuitem-dropdown-trigger:hover, .menuitem-dropdown .menuitem-dropdown-trigger:focus { background-color: #3e4045; } .navbar .announcement-popover { background: #4F4F4F; } .navbar .announcement-popover .announcement-popover-header { background: #2e2e2e; border-bottom: 1px solid #2e2e2e; } .navbar .announcement-popover .announcement-popover-body { background: #4F4F4F; color: #eee; } .navbar .announcement-popover .announcement-popover-footer { background: #4F4F4F; } .navbar .announcement-area .caption.inverse { color: #eee; } .label-warning { background-color: #ffc107; color: #212529; } /*--------------- history / recent ---------------*/ .list.row-layout li .item { border-color: #696c7d; } .list.row-layout li:nth-last-of-type(1) .item { border-bottom: none; } .list li .item { background: #1c1c1c; color: #fff; } .list li:hover .item, .list li:focus .item { background: #404040; } .list li .item h4 { color: #fff; } .list li p { color: #ccc; } .list li p i { font-style: normal; } .list li .item .content .tags span { background: #555; } .list li .item.wide .content .title a, .list li .item.wide .content .title a:focus, .list li .item.wide .content .title a:hover { color: #ddd; } .ui-item { color: #fff; opacity: 0.7; } .ui-item:hover, .ui-item:focus { opacity: 1; color: #fff; } .list li .item.wide hr { border-color: #6d6d6d; } .overview-widget-group .btn, .multi-select-dropdown-menu .ui-dropdown-label, .multi-select-dropdown-menu .dropdown-options, .form-control { border-color: #8e8e8e; } .multi-select-dropdown-menu .dropdown-options .ui-option:hover { background-color: #4d4d4d; color: #eee; } #overview-control-form #overview-keyword-input-container .select2-container { background-color: #3e4045 !important; } #overview-control-form #overview-keyword-input-container .select2-container .select2-choices { background-color: #3e4045; } .search { background-color: #3e4045; color: #eee; } .btn.btn-gray { background: #1b1b1b; } .btn.btn-gray:hover { background: #4d4d4d; color: #eee; } .search::placeholder, .search::-webkit-input-placeholder, .search:-moz-placeholder, .search::-moz-placeholder, .search:-ms-input-placeholder { color: #eee; } .btn.btn-gray { border-color: #6d6d6d; background: #333; color: #eee; } .select2-default { color: #eee !important; } .select2-results .select2- ed { background: #4d4d4d; color: #eee; } .select2-container-multi .select2-choices { background: #3e4045; } .select2-container-multi .select2-choices .select2-search-choice { background: #131313; color: #eee; border-color: #555; box-shadow: none; } .btn-default, .btn-default:focus { color: #eee; background-color: #2e2e2e; border-color: #6a6a6a; } .btn-default.active.focus, .btn-default.active:focus, .btn-default.active:hover, .btn-default:active.focus, .btn-default:active:focus, .btn-default:active:hover, .open>.dropdown-toggle.btn-default.focus, .open>.dropdown-toggle.btn-default:focus, .open>.dropdown-toggle.btn-default:hover { background: #737373; } .btn-default:hover { color: #fff; background-color: #7d7d7d; border-color: #6a6a6a; } .overview-widget-group .btn.active { background-color: #6a6a6a; color: #eee; } .overview-widget-group .btn:hover { background-color: #7d7d7d; color: #eee; border-color: #636363; } .overview-widget-group .slider.round { border-color: #ccc; } .overview-widget-group .slider.round:before { border-color: #ccc; } .overview-widget-group input:checked+.slider { background-color: #ccc; } .ui-category-description-icon a { color: #eee; } .item .ui-history-pin.active { color: #f00; } .ui-history-close { color: #eee; opacity: 0.5; } .pagination>li>a, .pagination>li>span { color: #eee; background-color: #2e2e2e; border-color: #6a6a6a; } .pagination>li>a:hover { color: #fff; background-color: #7d7d7d; border-color: #6a6a6a; } .pagination>.disabled>a, .pagination>.disabled>a:focus, .pagination>.disabled>a:hover, .pagination>.disabled>span, .pagination>.disabled>span:focus, .pagination>.disabled>span:hover { color: #eee; background-color: #2e2e2e; border-color: #6a6a6a; } .pagination.dark>li>a, .pagination.dark>li>span { color: #aaa; } /*--------------- new overview ---------------*/ .overview-component .list li .item { background: #1c1c1c; color: #fff; } .overview-component .list li:hover .item, .overview-component .list li:focus .item { background: #404040; } .overview-component .list li p { color: #ccc; } .overview-component .list li .item { color: #888888; } .overview-component .ui-overview-pin { opacity: 1; } /*--------------- settings ---------------*/ .section .form-horizontal .form-group .btn-default { font-size: 16px; border-color: #6d6d6d; background-color: #333; color: #FFF; } .section .form-horizontal .form-group .btn-default:hover, .section .form-horizontal .form-group .btn-default:focus { background-color: #737373; color: #FFF; } .section .form-horizontal .form-control:focus { border-color: #bbb; } /*--------------- share view ---------------*/ #notificationLabel, .ui-infobar .btn.ui-edit { color: #eee; border-color: #6a6a6a; } .ui-infobar__user-info li { color: #bbb; } footer { background: #101010; color: #bbb; border-top: 1px solid #454545; } footer a { color: #bbb; } /*--------------- doc view ---------------*/ .markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6, #doc>h1 { color: #ddd; border-color: #777 !important; } .markdown-body hr { background-color: #7e7e7e; } .h1 .small, .h1 small, .h2 .small, .h2 small, .h3 .small, .h3 small, .h4 .small, .h4 small, .h5 .small, .h5 small, .h6 .small, .h6 small, h1 .small, h1 small, h2 .small, h2 small, h3 .small, h3 small, h4 .small, h4 small, h5 .small, h5 small, h6 .small, h6 small { color: #ddd; } .markdown-body p { color: #ddd; } .markdown-body a { color: #7bf; } .markdown-body a code { color: #7bf !important; } .markdown-body ul li, .markdown-body ol li { color: #ddd; } .markdown-body blockquote { color: #ddd; border-left-color: #777; font-size: 16px; } .markdown-body code, code { color: #dfdfdf !important; background-color: #424a55; } .markdown-body code { padding: 1px 2px; } .markdown-body pre { background-color: #1e1e1e; border: 1px solid #555 !important; color: #dfdfdf; } .markdown-body details { margin-bottom: 16px; } blockquote .small, blockquote footer, blockquote small { color: #bbb; } .mark, mark { background-color: rgba(255, 255, 0, 0.32) !important; color: #ddd; margin: .1em; padding: .1em .2em; } /* Todo list */ .task-list-item-checkbox { margin: 0.18em 0 0.2em -1.3em !important; } .task-list-item input[type=checkbox] { -webkit-appearance: none; -moz-appearance: none; appearance: none; position: relative; top: -1px; margin: 0 1rem 0 0; cursor: pointer; } .task-list-item input[type=checkbox]::before { -webkit-transition: all 0.1s ease-in-out; -moz-transition: all 0.1s ease-in-out; transition: all 0.1s ease-in-out; content: ""; position: absolute; left: 0; z-index: 1; width: 16px; height: 16px; border: 2px solid #F44336; } .task-list-item input[type=checkbox]:checked::before { -webkit-transform: rotate(-48deg); -moz-transform: rotate(-48deg); -ms-transform: rotate(-48deg); -o-transform: rotate(-48deg); transform: rotate(-48deg); height: 9px; border-color: #00E676; border-top-style: none; border-right-style: none; } .task-list-item input[type=checkbox]::after { content: ""; position: absolute; top: -0.125rem; left: 0; width: 16px; height: 16px; background: #333; cursor: pointer; } /* table */ .markdown-body table tr { background-color: #1e1e1e; border-color: #626262; } .markdown-body table tr:last-child { border-bottom: 1px solid #626262; } .markdown-body table tr:nth-child(2n) { background-color: #333; } .markdown-body table tr th { color: #64B5F6; } .markdown-body table th, .markdown-body table td { border: none; border-color: #626262; } .markdown-body table tr td { color: #ddd; } .markdown-body table tr th:first-child, .markdown-body table tr td:first-child { border-left: 1px solid #626262; } .markdown-body table tr th:last-child, .markdown-body table tr td:last-child { border-right: 1px solid #626262; } .markdown-body pre.flow-chart, .markdown-body pre.sequence-diagram, .markdown-body pre.graphviz, .markdown-body pre.mermaid, .markdown-body pre.abc { background-color: #fff !important; } /* alert */ .alert-danger h1, .alert-danger h2, .alert-danger h3, .alert-danger h4, .alert-danger h5, .alert-danger h6, .alert-danger p, .alert-danger mark, .alert-danger ul li, .alert-danger ol li { color: #721c24; } .alert-danger hr { background-color: #721c24; } .alert-warning h1, .alert-warning h2, .alert-warning h3, .alert-warning h4, .alert-warning h5, .alert-warning h6, .alert-warning p, .alert-warning mark, .alert-warning ul li, .alert-warning ol li { color: #856404; } .alert-warning hr { background-color: #856404; } .alert-success h1, .alert-success h2, .alert-success h3, .alert-success h4, .alert-success h5, .alert-success h6, .alert-success p, .alert-success mark, .alert-success ul li, .alert-success ol li { color: #155724; } .alert-success hr { background-color: #155724; } .alert-info h1, .alert-info h2, .alert-info h3, .alert-info h4, .alert-info h5, .alert-info h6, .alert-info p, .alert-info mark, .alert-info ul li, .alert-info ol li { color: #004085; } .alert-info hr { background-color: #004085; } .alert a { color: #002752; font-weight: 700; } .alert h1:first-child, .alert h2:first-child, .alert h3:first-child, .alert h4:first-child, .alert h5:first-child, .alert h6:first-child { margin-top: 0; } .markdown-body .alert>p { margin-top: 0px; margin-bottom: 10px; } .markdown-body .alert>ul, .markdown-body .alert>ol { margin-bottom: 16px; } .markdown-body .alert>*:last-child { margin-bottom: 0; } .alert-warning { background-color: #fff3cd; border-color: #ffeeba; } .alert-danger mark { background-color: #ffb7b7 !important; } .alert-warning mark { background-color: #ffe966 !important; } .alert-success mark { background-color: #b9e990 !important; } .alert-info mark { background-color: #b1d6ff !important; } /* scroll bar */ .ui-edit-area .ui-resizable-handle.ui-resizable-e { background-color: #303030; border: 1px solid #303030; box-shadow: none; } /* info bar */ .ui-infobar { color: #999; } /* permission */ .permission-popover-btn-group .btn.focus, .permission-popover-btn-group .btn:active, .permission-popover-btn-group .btn:focus, .permission-popover-btn-group .btn.active { background-color: #6a6a6a !important; color: #eee !important; border-color: #555 !important; } .permission-popover-btn-group .btn:hover, .permission-popover-btn-group .btn.active:hover { background-color: #7d7d7d !important; color: #eee !important; border-color: #636363 !important; } .ui-delete-note:hover, .ui-delete-note:focus, .ui-delete-note:active { background-color: #dc3545 !important; } .ui-invitee-invite { border-color: #8e8e8e !important; } .ui-invitee-invite:hover, .ui-invitee-invite:focus { background-color: #737373; color: #eee !important; } .ui-no-invitee-label { color: #ccc !important; } .select2-container { background: #202020; } .select2-container-multi .select2-choices .select2-search-field input { color: #eee; } .select2-container-multi .select2-choices .select2-search-field input.select2-active { color: #000; } .select2-drop { background: #202020; color: #eee; } .select2-results .select2-no-results, .select2-results .select2-searching, .select2-results .select2-ajax-error, .select2-results .select2-selection-limit { background: #202020; } /* table of contents block*/ .ui-toc-dropdown { width: 42vw; max-height: 90vh; overflow: auto; text-align: inherit; } /* table of contents text*/ .ui-toc-dropdown .nav>li>a { font-size: 14px; font-weight: bold; color: #ddd; } /* table of contents text: active*/ .ui-toc-dropdown .nav>.active:focus>a, .ui-toc-dropdown .nav>.active:hover>a, .ui-toc-dropdown .nav>.active>a { color: #7bf; border-left-color: #7bf; } /* table of contents text: focus, hover*/ .ui-toc-dropdown .nav>li>a:focus, .ui-toc-dropdown .nav>li>a:hover { color: #7bf; border-left-color: #7bf; } /* drop down floating table of contents */ .ui-toc-dropdown.dropdown-menu { background: #333; } .toc-menu a { color: #ddd; } .toc-menu a:focus, .toc-menu a:hover { color: #7bf; } /*--------------- editor ---------------*/ .cm-m-markdown { color: #ddd; } .cm-s-one-dark .cm-header, .cm-m-xml.cm-attribute { color: #ffa653; } .cm-m-markdown.cm-variable-3 { color: #ff7e7e; } .cm-s-one-dark .cm-string, .cm-s-one-dark .cm-variable-2, .cm-s-one-dark .cm-m-markdown.cm-url{ color: #7bf; } .cm-s-one-dark .cm-m-markdown.cm-link { color: #b0ee83; } .cm-s-one-dark .CodeMirror-linenumber { color: #666; } .cm-strong { color: #f4511e; } .cm-s-one-dark .cm-comment { color: #a9a9a9; } .cm-matchhighlight { color: #ffea00; } .cm-positive { color: #11bf64; } .cm-negative { color: #ff3e3e; } .dropdown-menu.CodeMirror-other-cursor { border: 2px solid #4d4d4d; background-color: #202020; } .dropdown-menu.CodeMirror-other-cursor li a { color: #ececec; } /*--------------- book mode ---------------*/ .topbar { background: #1e1e1e; } .btn.focus, .btn:focus, .btn:hover { color: #fff; background-color: #333; } .summary { background: #1e1e1e; } .summary, .toolbar { background: #1e1e1e !important; border-color: #4d4d4d !important; } .toolbar i { color: #fff; } .summary h1, .summary h2, .summary h3 .summary hr { color: #ddd; border-color: #777 !important; } .summary .nav>li>a { color: #7bf; } .summary .nav-pills>li.active>a, .summary .nav-pills>li.active>a:focus, .summary .nav-pills>li.active>a:hover { color: #ff9100; } .ui-summary-search { font-size: 16px; border: 1px solid #6D6D6D; background-color: #333; color: #FFF; } .summary h1, .summary h2, .summary h3, .summary h4, .summary h5, .summary h6 { border-color: #454545; } /* fix body background color to dark */ div[class$=container-mask] { background: #1e1e1e; z-index: 1; display: block; } /* notification */ .dropdown.ui-notification .ui-notification-label, .dropdown.ui-invitee .ui-invitee-label { color: #eee; border-color: #6a6a6a; } .ui-notification .dropdown-menu { border-top: 1px solid #555; } /*--------------- help ---------------*/ .modal-header { background-color: #2a2a2a; } .panel-default { border-color: #6d6d6d; } .panel-default>.panel-heading { background-color: #2a2a2a; color: #eee; border-color: #6d6d6d; } .panel-body { background: #2e2e2e; } .panel-body a { color: #7bf; } .table>tbody>tr>td, .table>tbody>tr>th, .table>tfoot>tr>td, .table>tfoot>tr>th, .table>thead>tr>td, .table>thead>tr>th { border-color: #6d6d6d; } /*--------------- comment ---------------*/ .ui-comment-container .ui-comment-header { background-color: #2a2a2a; color: #eee; border-color: #6d6d6d; } .ui-comment-container { background-color: #2e2e2e; border-color: #6d6d6d; } .ui-comment-container .ui-comments-container .ui-comment .comment-author { color: #eee; } .ui-comment-container .ui-comments-container .ui-comment .timestamp { color: #aaa; } .ui-comment-container .ui-comments-container .ui-comment .comment-content { color: #eee; } .ui-comment-container .ui-comments-container .ui-comment .comment-menu { color: #eee; } .ui-comment-container .ui-comments-container .ui-comment .comment-menu .comment-dropdown-menu { background: #222; color: #eee; border-color: #555; } .ui-comment-container .ui-comments-container .ui-comment .comment-menu .comment-dropdown-menu>div:hover { background-color: #555555; color: #eee; } .ui-comment-container .ui-comments-container .ui-comment .comment-menu:hover, .ui-comment-container .ui-comments-container .ui-comment .comment-menu:active, .ui-comment-container .ui-comments-container .ui-comment .comment-menu.active { background-color: #737373; color: #eee; } .ui-comment-container .ui-comment-input-container { background-color: #3c3c3c; } .ui-comment-container textarea { background-color: #3e4045; color: #eee; border: 1px solid #6d6d6d; } .ui-comment-container textarea::placeholder, .ui-comment-container textarea::-webkit-input-placeholder, .ui-comment-container textarea:-moz-placeholder, .ui-comment-container textarea::-moz-placeholder, .ui-comment-container textarea:-ms-input-placeholder { color: #eee; } @keyframes highlight { 0% { background-color: #3c3c3c; } 30% { background-color: #3c3c3c; } 100% { background-color: transparent; } } /*--------------- template ---------------*/ .template-content .modal-header { background: #2a2a2a; } .template-content .close { color: #fff; } .template-content .modal-title { color: #eee; } .template-content .ui-templates-container { border-color: #6d6d6d; } .ui-templates-container .ui-create-template-btn { background: #446fab; color: #fff; } .ui-template-list-filter .ui-template-list-filter-label, .ui-template-list-filter .ui-template-list-filter-label:hover { color: #eee; } .ui-template-list .list-group-item.active { background: #4d4d4d; } .ui-template-list .list-group-item.active:focus { background: #4d4d4d !important; } .list-group-item.active, .list-group-item.active:focus, .list-group-item.active:hover { color: #eee; } .ui-template-list .list-group-item .list-group-item-heading { color: #eee; } .ui-template-list .list-group-item.active .list-group-item-heading { color: #eee; } .ui-template-list .list-group-item:hover { background: #4d4d4d !important; } .ui-template-item-menu { color: #eee !important; } .ui-template-list .list-group-item { color: #fff; } .ui-template-list .list-group-item .dropdown-container.open { background-color: #2a2a2a; } .ui-template-list .list-group-item .dropdown-container:hover { background-color: #2a2a2a !important; } .template-menu .more-template { border-color: #6d6d6d; } .template-menu .more-template:hover { color: #eee; border-color: #6d6d6d; } /*--------------- code mirror ---------------*/ .modal-content { background: #1f2226; } .modal-header { border-bottom: 1px solid #46484f; } .modal-footer { border-top: 1px solid #46484f; } a.list-group-item { background: #1f2226; color: #ddd; border: 1px solid #46484f; } a.list-group-item .list-group-item-heading { color: #ddd; } a.list-group-item:focus, a.list-group-item:hover { background: #434651; color: #ddd; } button.close { color: #ddd; opacity: .5; } .close:focus, .close:hover { color: #fff; opacity: .8; } .CodeMirror { background: #1f2226; } .CodeMirror-gutters { background: #1f2226; border-right: 1px solid rgba(204, 217, 255, 0.1); } .cm-s-default .cm-comment { color: #888; } .cm-s-default .cm-quote { color: #ddd; } .cm-s-default .cm-header { color: #ffa653; } .cm-s-default .cm-link { color: #b0ee83; } .cm-s-default .cm-string, .cm-s-default .cm-variable-2 { color: #7bf; } .cm-s-default .cm-def { color: #c678dd; } .cm-s-default .cm-number, .cm-s-default .cm-attribute, .cm-s-default .cm-qualifier, .cm-s-default .cm-plus, .cm-s-default .cm-atom { color: #eda35e; } .cm-s-default .cm-property, .cm-s-default .cm-variable, .cm-s-default .cm-variable-3, .cm-s-default .cm-operator, .cm-s-default .cm-bracket { color: #f76e79; } .cm-s-default .cm-keyword, .cm-s-default .cm-builtin, .cm-s-default .cm-tag { color: #98c379; } .modal-title { color: #ccc; } .modal-body { color: #ccc !important; } div[contenteditable]:empty:not(:focus):before { color: #aaa; } .CodeMirror pre { color: #ddd; } .CodeMirror pre span[style^="background-color: rgb(221, 251, 230)"] { background-color: #288c27 !important; } .CodeMirror pre span[style^="background-color: rgb(249, 215, 220)"] { background-color: #a52721 !important; } /*------- code highlight: Visual Stutdio Code theme for highlight.js -------*/ .hljs { background: #1E1E1E; color: #DCDCDC; } .hljs-keyword, .hljs-literal, .hljs-symbol, .hljs-name { color: #569CD6; } .hljs-link { color: #569CD6; text-decoration: underline; } .hljs-built_in, .hljs-type { color: #4EC9B0; } .hljs-number, .hljs-class { color: #B8D7A3; } .hljs-string, .hljs-meta-string { color: #D69D85; } .hljs-regexp, .hljs-template-tag { color: #d16969; } .hljs-title { color: #dcdcaa; } .hljs-subst, .hljs-function, .hljs-formula { color: #DCDCDC; } .hljs-comment, .hljs-quote { color: #57A64A; } .hljs-doctag { color: #608B4E; } .hljs-meta, .hljs-meta-keyword, .hljs-tag { color: #9B9B9B; } .hljs-variable, .hljs-template-variable { color: #BD63C5; } .hljs-params, .hljs-attr, .hljs-attribute, .hljs-builtin-name { color: #9CDCFE; } .hljs-section { color: gold; } .hljs-emphasis { font-style: italic; } .hljs-strong { font-weight: bold; } /* .hljs-code { font-family:'Monospace'; } */ .hljs-bullet, .hljs-selector-tag, .hljs-selector-id, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo { color: #D7BA7D; } .hljs-addition { background-color: #155a36; color: #dfdfdf; display: inline-block; width: 100%; } .hljs-deletion { background-color: #872e2e; color: #dfdfdf; display: inline-block; width: 100%; } /*---------- code highlight: Visual Stutdio Code theme for Prism.js ----------*/ code[class*="language-"], pre[class*="language-"] { color: #DCDCDC; } :not(pre)>code[class*="language-"], pre[class*="language-"] { background: #1E1E1E; } .token.comment, .token.block-comment, .token.prolog, .token.cdata { color: #57A64A; } .token.doctype, .token.punctuation { color: #9B9B9B; } .token.tag, .token.entity { color: #569CD6; } .token.attr-name, .token.namespace, .token.deleted, .token.property, .token.builtin { color: #9CDCFE; } .token.function, .token.function-name { color: #dcdcaa; } .token.boolean, .token.keyword, .token.important { color: #569CD6; } .token.number { color: #B8D7A3; } .token.class-name, .token.constant { color: #4EC9B0; } .token.symbol { color: #f8c555; } .token.rule { color: #c586c0; } .token.selector { color: #D7BA7D; } .token.atrule { color: #cc99cd; } .token.string, .token.attr-value { color: #D69D85; } .token.char { color: #7ec699; } .token.variable { color: #BD63C5; } .token.regex { color: #d16969; } .token.operator { color: #DCDCDC; background: transparent; } .token.url { color: #67cdcc; } .token.important, .token.bold { font-weight: bold; } .token.italic { font-style: italic; } .token.entity { cursor: help; } .token.inserted { color: green; } /*---------- code highlight: dark theme for Gist ----------*/ .gist .gist-file { border: 1px solid #555; } .gist .gist-data { background-color: #1e1e1e; border-bottom: 1px solid #555; } .gist .gist-meta { background-color: #424a55; color: #eee; } .gist .gist-meta a { color: #eee; } .gist .highlight { color: #eee; background-color: #1e1e1e; } .gist .blob-num { color: #afafaf; } .gist .blob-code-inner { color: #dfdfdf; } .pl-mb { color: #fff !important; } .pl-c { color: #57A64A !important; } /* comment */ .pl-ent { color: #569CD6 !important; } /* entity */ .pl-e { color: #9CDCFE !important; } .pl-en { color: #4EC9B0 !important; } /* entity attribute */ .pl-smi { color: #9CDCFE !important; } .pl-k { color: #569cd6 !important; } .pl-c1, .pl-s .pl-v { color: #4EC9B0 !important; } .pl-pds, .pl-s, .pl-s .pl-pse .pl-s1, .pl-sr, .pl-sr .pl-cce, .pl-sr .pl-sra, .pl-sr .pl-sre, .pl-s .pl-s1 { color: #D69D85 !important; } .pl-s .pl-s1 .pl-pse { color: #c5dbff !important; } /* strings */ .diff-table .pl-c, .diff-table .pl-ent, .diff-table .pl-e, .diff-table .pl-en, .diff-table .pl-pds, .diff-table .pl-s, .diff-table .pl-s .pl-s1, .diff-table .pl-s .pl-pse .pl-s1, .diff-table .pl-sr, .diff-table .pl-sr .pl-cce, .diff-table .pl-sr .pl-sra, .diff-table .pl-sr .pl-sre, .diff-table .pl-k, .diff-table .pl-smi, .diff-table .pl-c1, .diff-table .pl-v { color: #eee !important; } </style>