Hi,

Our First API

ctfchallenges.ritsec.club:3000 ctfchallenges.ritsec.club:4000

Hint: You don't need the Bearer keyword!

Author: sandw1ch

-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBquzMGkZlJmZm4pYppxeDmsGd 8+9mOh5S9O7W7Gu5VByfl7i3JdCfGxRJdHscg6l321PeTXsXGZ7goHd4Xjv/FtKQ DyoaKql4Kl692KKKN/9xA6tKdOYQbZvPqyRXUVOGdyZ12qFBOQzI7ox22YL3ul/3 nyiDR+p+JKbdVU6AWQIDAQAB -----END PUBLIC KEY-----

import jwt e={ "name": "abc", "type": "admin", "iat": 1573986641 } f=open('signing.pem','rb') s=f.read() f.close() print jwt.encode(e,s,algorithm='HS256')

Hop By Hop

ctfchallenges.ritsec.club:81

Hint: I thought I would forward this hint to you.

Author: Chaim Sanders

URGGGGG

One of our operatives sent us this packet capture but we aren't quite sure what to make of it, what can you find?

Author: DataFrogman

tshark -r URGGGGGG.pcapng -T fields -e usb.capdata > data.txt

codes={ "01": "[MOD_LCTRL]", "02": "[MOD_LSHIFT]", "04": "[MOD_LALT]", "08": "[MOD_LMETA]", "10": "[MOD_RCTRL]", "20": "[MOD_RSHIFT]", "40": "[MOD_RALT]", "80": "[MOD_RMETA]", "00": "[NONE]", "01": "[ERR_OVF]", "04": "aA", "05": "bB", "06": "cC", "07": "dD", "08": "eE", "09": "fF", "0a": "gG", "0b": "hH", "0c": "iI", "0d": "jJ", "0e": "kK", "0f": "lL", "10": "mM", "11": "nN", "12": "oO", "13": "pP", "14": "qQ", "15": "rR", "16": "sS", "17": "tT", "18": "uU", "19": "vV", "1a": "wW", "1b": "xX", "1c": "yY", "1d": "zZ", "1e": "1!", "1f": "2@", "20": "3#", "21": "4$", "22": "5%", "23": "6^", "24": "7&", "25": "8*", "26": "9(", "27": "0)", "28": "[ENTER]", "29": "[ESC]", "2a": "[BACKSPACE]", "2b": "[TAB]", "2c": " ", "2d": "-_", "2e": "=+", "2f": "[{", "30": "]}", "31": "\\|", "32": "[HASHTILDE]", "33": ";:", "34": "'\"", "35": "[GRAVE]", "36": ",<", "37": ".>", "38": "/?", "39": "[CAPSLOCK]", "3a": "[F1]", "3b": "[F2]", "3c": "[F3]", "3d": "[F4]", "3e": "[F5]", "3f": "[F6]", "40": "[F7]", "41": "[F8]", "42": "[F9]", "43": "[F10]", "44": "[F11]", "45": "[F12]", "46": "[SYSRQ]", "47": "[SCROLLLOCK]", "48": "[PAUSE]", "49": "[INSERT]", "4a": "[HOME]", "4b": "[PAGEUP]", "4c": "[DELETE]", "4d": "[END]", "4e": "[PAGEDOWN]", "4f": "[RIGHT]", "50": "[LEFT]", "51": "[DOWN]", "52": "[UP]", "53": "[NUMLOCK]", "54": "[KPSLASH]", "55": "[KPASTERISK]", "56": "[KPMINUS]", "57": "[KPPLUS]", "58": "[KPENTER]", "59": "[KP1]", "5a": "[KP2]", "5b": "[KP3]", "5c": "[KP4]", "5d": "[KP5]", "5e": "[KP6]", "5f": "[KP7]", "60": "[KP8]", "61": "[KP9]", "62": "[KP0]", "63": "[KPDOT]", "64": "[102ND]", "65": "[COMPOSE]", "66": "[POWER]", "67": "[KPEQUAL]", "68": "[F13]", "69": "[F14]", "6a": "[F15]", "6b": "[F16]", "6c": "[F17]", "6d": "[F18]", "6e": "[F19]", "6f": "[F20]", "70": "[F21]", "71": "[F22]", "72": "[F23]", "73": "[F24]", "74": "[OPEN]", "75": "[HELP]", "76": "[PROPS]", "77": "[FRONT]", "78": "[STOP]", "79": "[AGAIN]", "7a": "[UNDO]", "7b": "[CUT]", "7c": "[COPY]", "7d": "[PASTE]", "7e": "[FIND]", "7f": "[MUTE]", "80": "[VOLUMEUP]", "81": "[VOLUMEDOWN]", "85": "[KPCOMMA]", "87": "[RO]", "88": "[KATAKANAHIRAGANA]", "89": "[YEN]", "8a": "[HENKAN]", "8b": "[MUHENKAN]", "8c": "[KPJPCOMMA]", "90": "[HANGEUL]", "91": "[HANJA]", "92": "[KATAKANA]", "93": "[HIRAGANA]", "94": "[ZENKAKUHANKAKU]", "b6": "[KPLEFTPAREN]", "b7": "[KPRIGHTPAREN]", "e0": "[LEFTCTRL]", "e1": "[LEFTSHIFT]", "e2": "[LEFTALT]", "e3": "[LEFTMETA]", "e4": "[RIGHTCTRL]", "e5": "[RIGHTSHIFT]", "e6": "[RIGHTALT]", "e7": "[RIGHTMETA]", "e8": "[MEDIA_PLAYPAUSE]", "e9": "[MEDIA_STOPCD]", "ea": "[MEDIA_PREVIOUSSONG]", "eb": "[MEDIA_NEXTSONG]", "ec": "[MEDIA_EJECTCD]", "ed": "[MEDIA_VOLUMEUP]", "ee": "[MEDIA_VOLUMEDOWN]", "ef": "[MEDIA_MUTE]", "f0": "[MEDIA_WWW]", "f1": "[MEDIA_BACK]", "f2": "[MEDIA_FORWARD]", "f3": "[MEDIA_STOP]", "f4": "[MEDIA_FIND]", "f5": "[MEDIA_SCROLLUP]", "f6": "[MEDIA_SCROLLDOWN]", "f7": "[MEDIA_EDIT]", "f8": "[MEDIA_SLEEP]", "f9": "[MEDIA_COFFEE]", "fa": "[MEDIA_REFRESH]", "fb": "[MEDIA_CALC]" } f=open('data.txt') s=[] for i in f: k=i[6:8] if k=='00': continue if codes[k][0]=='[' and codes[k][-1]==']': s.append(codes[k]) else: if i[0:2]=='02': s.append(codes[k][1]) elif i[0:2]=='01': s.append('[CTR]'+codes[k][0]) else: s.append(codes[k][0]) if len(s)>1 and s[-1]==s[-2]: s=s[:-1] f.close() print ''.join(s)

ablglaolgalfkihikfhwhjd;s[ENTER]jofs[ENTER]alehwaih)($439(YTY$495[F1]afughw8o[BACKSPACE][ENTER][DELETE][ENTER][BACKSPACE] [ENTER][BACKSPACE][ENTER][DELETE] [BACKSPACE]RITSEC[ESC]{wH0_s@[ESC][UP][LEFT][DOWN][LEFT][UP][LEFT][CTR]xx[DOWN][RIGHT][CTR]vvd_n[UP][RIGHT][LEFT][CTR]c[DOWN][CTR]vtw0rk1nG_wAs[ENTER]jojlgajkgajkselfdje[UP]_tH3_oNlY_pAck3t_TyP3}[DOWN][ENTER]auakg;ekajildhkljaskdgafsfekjkjfcvhihelshiheueuhdhoa

Welcome to my blog!Here is my write-up for some very cool challenges in RITSEC CTF 2019 that I solved last weekend. Hope you enjoy it!Go to ctfchallenges.ritsec.club:4000, you can see what we need to do to get the flag.We should get a token at ctfchallenges.ritsec.club:3000/auth, then use it to authenticated with the /api/admin endpoint. Oh, I guess it's a JWT challenge!If you are unfamiliar with exploiting JWT, you shoud visit here first.First, let's get the token.After that, I use jwt.io to decode it's data. Wow, it uses the RS256 algorithm. Maybe you know what is our next step? Yeah, we only need to find the public key and then sign our modified data with that key and the HS256 algorithm.Take a look at ctfchallenges.ritsec.club:3000/robots.txt, we can see the file signing.pem, which is certainly the publickey that the server used to sign the token.Now, it's very simple. Here is my Python script to generate a new valid token with the type is admin.Let's use the admin's token to access the /api/admin endpoint and get the flag. It'sIf you often read infosec news, you could realize the challenge's name. It's " Abusing HTTP hop-by-hop request headers ". The article was shared many times on Twitter, Reddit,...Look at the challenge's site, it has an admin panel. On this page, a message is showed that only the admin's computer can access it. Furthermore, the request's IP is also shown and it's actually the load balancer's IP (or the first proxy), 10.0.0.37, not our IP.As you know, the load balancer adds its IP before sending the request to the web server by adding the header X-Forwarded-For . So, what happens if we specify that header from our computer?Even when the header X-Forwarded-For contains the IP 127.0.0.1, we still can't access the admin page. At that time, I think maybe the admin's computer is in the local network with the web server so its requests don't need to have X-Forwarded-For. Let's use the header Connection to force the proxy strips off X-Forwarded-For before forwarding requests to the web server.The flag needs to be surrounded by RITSEC{}. Here it is:Do you think it's much simpler than the challenge's point looks like?Open the pcap file , you can see that all packets are USB packets.Look at the captured data, it's in the format of 8 bytes with the first byte is 00, 01 or 02, the second byte is 00 and the other bytes seems to be random. It indicates that this is keyboard traffic . Let's extract the capture data by tshark To convert the captured data to the symbol of pressed keys, I wrote a simple Python script like that:After running the script above, all pressed keys are revealed:What makes this challenge different from other USB forensics challenge is the existence of Ctr+C, Ctr+X, and Ctr+V. However, you can easily guess what are copied and pasted by looking at the flag's style. Yeah, it's leet So the flag is:If you have any questions, please don't hesitate to ask me on Twitter or leave a comment.Thank you for reading!