[SECCON Beginners CTF 2020] R&B

解説

FLAGをRとBからなる文字列に従って難読化されたものが与えられます.
文字がRの場合は'R'と全体をROT13,つまりA~Zの文字を13個分後ろにずらす(超過した場合にはAに戻って処理を進める)処理をしたものを結合しています.
Bの場合は'B'とBase64でFLAG全体がエンコードされたものを結合しています.

FLAGを難読化する文字列は与えられませんが,幸いにも処理を行った際に先頭に文字が追加されています.
そのため,文字列の先頭を確認 -> 先頭の文字に従いデコードを行えばよさそう.
最終的にFLAGはctf4b{で始まるため,この形になったら終了する

#!/usr/bin/env python3
import base64
​
Encoded_FLAG = 'BQlVrOUllRGxXY2xGNVJuQjRkVFZ5U0VVMGNVZEpiRVpTZVZadmQwOWhTVEIxTkhKTFNWSkdWRUZIUlRGWFUwRklUVlpJTVhGc1NFaDFaVVY1Ukd0Rk1qbDFSM3BuVjFwNGVXVkdWWEZYU0RCTldFZ3dRVmR5VVZOTGNGSjFTMjR6VjBWSE1rMVRXak5KV1hCTGVYZEplR3BzY0VsamJFaGhlV0pGUjFOUFNEQk5Wa1pIVFZaYVVqRm9TbUZqWVhKU2NVaElNM0ZTY25kSU1VWlJUMkZJVWsxV1NESjFhVnBVY0d0R1NIVXhUVEJ4TmsweFYyeEdNVUUxUlRCNVIwa3djVmRNYlVGclJUQXhURVZIVGpWR1ZVOVpja2x4UVZwVVFURkZVblZYYmxOaWFrRktTVlJJWVhsTFJFbFhRVUY0UlZkSk1YRlRiMGcwTlE9PQ=='
​
def _r_rot13(c):
    if 'A' <= c and c <= 'Z':
        return chr((ord(c) - ord('A') - 13) % 26 + ord('A'))
    if 'a' <= c and c <= 'z':
        return chr((ord(c) - ord('a') - 13) % 26 + ord('a'))
    return c
​
def reverse_rot13(s):
    encoded_str = ""
    for c in s:
        encoded_str += _r_rot13(c)
    return encoded_str
​
def base64_decode(s):
    return base64.b64decode(s)
​
def is_flag(s):
    if s[:6] == 'ctf4b{':
        return True
    else :
        return False
​
def solve(s):
    while not(is_flag(s)):
        if s[0] == 'R':
            s = reverse_rot13(s[1:])
        elif s[0] == 'B':
            s = base64_decode(s[1:]).decode('utf-8')
        else:
            break
    print(s)
if __name__ =='__main__':
     solve(Encoded_FLAG)

ctf4b{rot_base_rot_base_rot_base_base}