HacktheBox CTF coding problem

2021. 4. 24. 12:460x07 CTF/[스스로 푼 것]

728x90

문제 명 AlienCamp 

문제 컨셉은 이모지에 대응되는 값들이 유동적으로 변하는 서버에서 나누기를 제외한 사칙연산을 랜덤하게 추출하여 계산하는 문제이다.
처음에 헤맸는데 그 이유는 곱셈이 연산 우선순위가 되어야하는것을 깜박하고 있었기 때문.

 

#-*-coding:utf-8-*-
import emoji
import sys
from pwn import *

# Algorithm
# '1' -> Setting the Emogi's value
# '2' -> Based on the '1' result value -> Calc

################  Emoji  #######################
# \xf0\x9f\x8c\x9e : sun_with_face
# \xf0\x9f\x8d\xa8 : ice_cream
# \xe2\x9d\x8c : cross_mark
# \xf0\x9f\x8d\xaa : cookie
# \xf0\x9f\x94\xa5 : fire
# \xe2\x9b\x94 : no_entry
# \xf0\x9f\x8d\xa7 : shaved_ice
# \xf0\x9f\x91\xba : goblin
# \xf0\x9f\x91\xbe : alien_monster
# \xf0\x9f\xa6\x84 : unicorn
################         #######################

emoji_world= [] 
emoji_set = ['🌞','🍨','❌','🍪','🔥','⛔','🍧','👺','👾','🦄']
emojii_dict = []


emoji_unicode = ['\xf0\x9f\x8c\x9e','\xf0\x9f\x8d\xa8','\xe2\x9d\x8c','\xf0\x9f\x8d\xaa','\xf0\x9f\x94\xa5','\xe2\x9b\x94','\xf0\x9f\x8d\xa7','\xf0\x9f\x91\xba','\xf0\x9f\x91\xbe','\xf0\x9f\xa6\x84']



flag_round=1
data = ""

def tokenize(expStr):
    print("TOKENIZE")
    #expStr = list(expStr)
    pat = re.compile(r'(?:(?<=[^\d\.])(?=\d)|(?=[^\d\.]))', re.MULTILINE)
    for i in expStr:
        print(i)
    #return [x for x in re.sub(pat, ' ', expStr).split(' ') if x]
    print("END")
    return expStr

def parse_expr(expStr):
    tokens = tokenize(expStr)
    print("tokens = {} / {} ".format(type(tokens),tokens))
    op = dict(zip('*+-', (10, 9, 9))) # initialization (priority)
    output = []
    stack = []
    for item in tokens:
        if item not in op:
            output.append(item)
        else:
            while stack != [] and \
                    op[stack[-1]] >= op[item]:
                output.append(stack.pop())
            stack.append(item)

    while stack:
        output.append(stack.pop())
    print(output)
    return output


def calc_expr(tokens):
    operations = {
            '*': lambda x, y: y * x,
            '+': lambda x, y: y + x,
            '-': lambda x, y: y - x
            }

    stack = []

    for item in tokens:
        if item not in operations:
            stack.append(int(item))
        else:
            x = stack.pop()
            y = stack.pop()
            stack.append(operations[item](x, y))
    return stack[-1]




def process(expStr):
    #print(calc_expr(parse_expr(expStr)))
    return calc_expr(parse_expr(expStr))

print("EMOJI WORLD")
for abstract in emoji_set:
    print(emoji.demojize(abstract))

ADDR ="138.68.152.10"
PORT = 30974
p = remote(ADDR,PORT)

def parse_emoji():
    global emoji_world, emoji_dict
    p.sendline('1')
    p.recvuntil('help:\n\n')
    data = p.recvline(200)
    emoji_world = str(data).split("->")
    emoji_dict =    [
                    int(emoji_world[1][1:3]),
                    int(emoji_world[2][1:3]),
                    int(emoji_world[3][1:3]),
                    int(emoji_world[4][1:3]),
                    int(emoji_world[5][1:3]),
                    int(emoji_world[6][1:3]),
                    int(emoji_world[7][1:3]),
                    int(emoji_world[8][1:3]),
                    int(emoji_world[9][1:3]),
                    int(emoji_world[10][1:3])
                    ]

    return emoji_world, emoji_dict # emoji_dict is number 


def formula():
    p.sendline('2')
    msg = "Question {}:\n\n".format(flag_round)
    p.recvuntil(msg)
    print(msg)
    data = p.recvuntil("= ?")

    #data = str(data).split(" ")[20:]
    data = str(data).split(" ")
    print(data)
    #sys.exit(0)
    return data


def getValue(data,length):
    calc = []
    print("array len = {}".format(length))
    for i in range(0,length-3):
        if(i%2!=0):
            calc.append(data[i])
        for j in range(0, len(emoji_unicode)):
            if(data[i] == emoji_unicode[j]):
                tmp = emoji_dict[j]
                calc.append(str(tmp))
                break
    return calc

def solve():
    global flag_round
    
    emoji_world, emoji_dict = parse_emoji()

    data = formula()

    
    calc = getValue(data,len(data))
 
    i = 0
    j = 0

    #tmp = ["10","+","10","*","100"]
    print("calc result {}".format(str(calc)))
    
    answer = process(calc)
    print("{}/answer = {}".format(flag_round,answer))
    p.sendline(str(answer)) # only permitted 1 round
    print(p.recvline())

    ##### New Round #####
    for i in range(2,501):
        flag_round += 1

        msg = "Question {}:\n\n".format(flag_round)
        print("{} round".format(flag_round))
    
        p.recvuntil(msg)
    
        data =p.recvuntil("= ?\n").split(" ")

        print(data)
        print(type(data))

        calc = getValue(data,len(data))
        answer = process(calc)
        p.sendline(str(answer))
        print(p.recvline())
    print(p.recvline())

    #print(type(tmp))

#for i in range(0,501):

if __name__ == '__main__':
    #for i in range(0,3):
    solve()

'0x07 CTF > [스스로 푼 것]' 카테고리의 다른 글

zer0pts 2021 - not beginners rev  (0) 2021.03.12
AeroCTF2021 Dummyper  (0) 2021.03.02
[REV] COMPEST - CreeptiCity  (0) 2020.09.12
HexionCTF XOR - Crypto  (0) 2020.04.18
ISITDTU CTF Reversing inter  (0) 2018.08.03