본문 바로가기

CTF/SWING CTF 2023

[Rev] Simple VM

simplevm.py
0.00MB

def lets_go(flag, code):
    registers = [0] * 0x100
    flag = [ord(x) for x in list(flag)]
    pc = 0

    while True:
        if pc == len(code):
            break
    
        cur = code[pc].split('.')
        pc += 1
    
        if cur[0] == 'A':
            dest = int(cur[1])
            src = int(cur[2])
            registers[dest] += registers[src]
        
        elif cur[0] == 'B':
            dest = int(cur[1])
            src = int(cur[2])
            registers[dest] ^= registers[src]
    
        elif cur[0] == 'C':
            dest = int(cur[1])
            src = int(cur[2])
            registers[dest] *= registers[src]   
    
        elif cur[0] == 'D':
            dest = int(cur[1])
            value = int(cur[2])
            registers[dest] = value
    
        elif cur[0] == 'E':
            dest = int(cur[1])
            src = int(cur[2])
            if registers[dest] != flag[src]:
                pc = int(cur[3])
    
        elif cur[0] == 'F':
            print(cur[1])
        
        elif cur[0] == 'H':
            break
            
if __name__ == '__main__':
    flag = input('Your flag : ')
    program = [
        'D.0.104', 'E.0.0.104', 'D.0.115', 'E.0.1.104', 'D.0.112', 'E.0.2.104', 'D.0.97', 'E.0.3.104',
        'D.0.99', 'E.0.4.104', 'D.0.101', 'E.0.5.104', 'D.0.123', 'E.0.6.104', 
        'D.1.65', 'D.2.40', 'A.1.2', 'E.1.7.104', 'D.1.31', 'D.2.84', 'A.1.2', 'E.1.8.104',
        'D.1.38', 'D.2.57', 'A.1.2', 'E.1.9.104', 'D.1.35', 'D.2.81', 'A.1.2', 'E.1.10.104',
        'D.1.66', 'D.2.38', 'A.1.2', 'E.1.11.104', 'D.1.30', 'D.2.75', 'A.1.2', 'E.1.12.104',
        'D.1.44', 'D.2.71', 'A.1.2', 'E.1.13.104', 'D.1.70', 'D.2.25', 'A.1.2', 'E.1.14.104',
        'D.1.61', 'D.2.60', 'A.1.2', 'E.1.15.104', 'D.1.65', 'D.2.46', 'A.1.2', 'E.1.16.104',
        'D.6.56', 'D.7.77', 'B.6.7', 'E.6.17.104', 'D.6.56', 'D.7.74', 'B.6.7', 'E.6.18.104',
        'D.6.38', 'D.7.121', 'B.6.7', 'E.6.19.104', 'D.6.32', 'D.7.70', 'B.6.7', 'E.6.20.104',
        'D.6.42', 'D.7.67', 'B.6.7', 'E.6.21.104', 'D.6.31', 'D.7.109', 'B.6.7', 'E.6.22.104',
        'D.6.32', 'D.7.83', 'B.6.7', 'E.6.23.104', 'D.6.36', 'D.7.80', 'B.6.7', 'E.6.24.104',
        'D.6.47', 'D.7.112', 'B.6.7', 'E.6.25.104', 'D.6.45', 'D.7.91', 'B.6.7', 'E.6.26.104',
        'D.6.50', 'D.7.95', 'B.6.7', 'E.6.27.104', 'D.6.54', 'D.7.75', 'B.6.7', 'E.6.28.104',  
        'F.Correct!!!', 'H', 'F.Wrong!!!'
    ]
    lets_go(flag, program)

실행하면~

 

if registers[dest] != flag[src]:
                pc = int(cur[3])

 

위의 부분 지우든 안 지우든 출력되는 것은 같다.

 

아, 값을 넣었을 때는 변하는 바가 있다.

 

위 코드가 vm 역할을 하기 때문에... 첫 코드의 'D.0.104'를 넣으면 아래와 같이 기능한다. 

 

elif cur[0] == 'D':
            dest = int(cur[1])  <- 0
            value = int(cur[2])  <- 104
            registers[dest] = value registers[0] = 104

E에 넣으면 아래처럼.

 elif cur[0] == 'E':
            dest = int(cur[1])  <- 0
            src = int(cur[2])  <- 0
            if registers[dest] != flag[src]:  registers[0] != flag[0]
                pc = int(cur[3])  <- 104

 

0부터 104까지 총 105개의 경우가 있기 때문에 104를 넣으면 마지막에 위치한 'F.Wrong!!!' 에 가게 된다.

그리고 이 명령어는 바로 위의 코드에서 registers[0] != flag[0] 일 때 출력되는 104번째 값이다.

 

if cur[0] == 'A':
            dest = int(cur[1])  <- 1
            src = int(cur[2])  <- 2
            registers[dest] += registers[src]  registers[i] += registers[2]

 

 

코드를 수정해보았다.

 

def lets_go(code):
    registers = [0] * 0x100
    pc = 0

    while True:
        if pc == len(code):
            break
    
        cur = code[pc].split('.')
        pc += 1
    
        if cur[0] == 'A':
            dest = int(cur[1])
            src = int(cur[2])
            registers[dest] += registers[src]
        
        elif cur[0] == 'B':
            dest = int(cur[1])
            src = int(cur[2])
            registers[dest] ^= registers[src]
    
        elif cur[0] == 'C':
            dest = int(cur[1])
            src = int(cur[2])
            registers[dest] *= registers[src]   
    
        elif cur[0] == 'D':
            dest = int(cur[1])
            value = int(cur[2])
            registers[dest] = value
    
        elif cur[0] == 'E':
            dest = int(cur[1])
            src = int(cur[2])
            print(chr(registers[dest]), end="")
    
        elif cur[0] == 'F':
            print(cur[1])
        
        elif cur[0] == 'H':
            break
            
if __name__ == '__main__':
    program = [
        'D.0.104', 'E.0.0.104', 'D.0.115', 'E.0.1.104', 'D.0.112', 'E.0.2.104', 'D.0.97', 'E.0.3.104',
        'D.0.99', 'E.0.4.104', 'D.0.101', 'E.0.5.104', 'D.0.123', 'E.0.6.104', 
        'D.1.65', 'D.2.40', 'A.1.2', 'E.1.7.104', 'D.1.31', 'D.2.84', 'A.1.2', 'E.1.8.104',
        'D.1.38', 'D.2.57', 'A.1.2', 'E.1.9.104', 'D.1.35', 'D.2.81', 'A.1.2', 'E.1.10.104',
        'D.1.66', 'D.2.38', 'A.1.2', 'E.1.11.104', 'D.1.30', 'D.2.75', 'A.1.2', 'E.1.12.104',
        'D.1.44', 'D.2.71', 'A.1.2', 'E.1.13.104', 'D.1.70', 'D.2.25', 'A.1.2', 'E.1.14.104',
        'D.1.61', 'D.2.60', 'A.1.2', 'E.1.15.104', 'D.1.65', 'D.2.46', 'A.1.2', 'E.1.16.104',
        'D.6.56', 'D.7.77', 'B.6.7', 'E.6.17.104', 'D.6.56', 'D.7.74', 'B.6.7', 'E.6.18.104',
        'D.6.38', 'D.7.121', 'B.6.7', 'E.6.19.104', 'D.6.32', 'D.7.70', 'B.6.7', 'E.6.20.104',
        'D.6.42', 'D.7.67', 'B.6.7', 'E.6.21.104', 'D.6.31', 'D.7.109', 'B.6.7', 'E.6.22.104',
        'D.6.32', 'D.7.83', 'B.6.7', 'E.6.23.104', 'D.6.36', 'D.7.80', 'B.6.7', 'E.6.24.104',
        'D.6.47', 'D.7.112', 'B.6.7', 'E.6.25.104', 'D.6.45', 'D.7.91', 'B.6.7', 'E.6.26.104',
        'D.6.50', 'D.7.95', 'B.6.7', 'E.6.27.104', 'D.6.54', 'D.7.75', 'B.6.7', 'E.6.28.104',  
        'F.Correct!!!', 'H', 'F.Wrong!!!'
    ]
    lets_go(program)

 

 

hspace{is_this_your_first_vm}

'CTF > SWING CTF 2023' 카테고리의 다른 글

[Misc] Nogada  (0) 2023.08.05
[Rev] Unsolvable  (0) 2023.08.05
[Rev] README  (0) 2023.08.05
[Rev] Random Defense  (0) 2023.08.05
[Misc] Click  (0) 2023.08.05