-HTML 코드
-문제파일 코드
#!/usr/bin/env python3 from flask import Flask, request, render_template app = Flask(__name__) try: FLAG = open("./flag.txt", "r").read() # flag is here! except: FLAG = "[**FLAG**]" @app.route('/', methods=['GET', 'POST']) def index(): menu_str = '' org = FLAG[10:29] org = int(org) st = ['' for i in range(16)] for i in range (0, 16): res = (org >> (4 * i)) & 0xf if 0 < res < 12: if ~res & 0xf == 0x4: st[16-i-1] = '_' else: st[16-i-1] = str(res) else: st[16-i-1] = format(res, 'x') menu_str = menu_str.join(st) # POST if request.method == "POST": input_str = request.form.get("menu_input", "") if input_str == str(org): return render_template('index.html', menu=menu_str, flag=FLAG) return render_template('index.html', menu=menu_str, flag='try again...') # GET return render_template('index.html', menu=menu_str) if __name__ == '__main__': app.run(host='0.0.0.0', port=8000)
문제 의도 : 문제에서 제시된 태그 → FLAG의 인덱스값 10:29까지의 값이 조건식에 따라 암호화된 값을 해독화하여 input_str 에 POST 요청으로 보내라
여기에서 return 되는값으로 FLAG를 받으려면 if input_str == str(org) 의 조건에 참이여야함
str(org) 값을 알아야함 → org == FLAG[10:29] → FLAG[10:29] 를 알아보자
우선 코드를 분석해보면
-org = FLAG[10:29] : FLAG의 인덱스값 10부터 29까지의 값을 org에 대입연산한다.
-org = int(org) : org의 값을 int형으로 강제형변환한다.
-st = [’’ for i in range(16)] : 빈문자열이 16개 있는 리스트를 만든다.
-res = (org >> (4 * i)) & 0xf : org의 2진수 값을 오른쪽으로 (4 * i) 만큼 비트쉬프트 시킴 그리고 그 값을 0xf 와 AND 연산을 수행한 값이 res 이다.
- 여기에서 org는 비트쉬프트를 시킬때 10진수 → 2진수 로 변환되고 AND 연산을 수행시킬때 0xf 도 2진수로 변환되어 수행됨
-만약 res 값이 0 초과 12 미만 일때 2중 if문으로 들어간다
- 2중 if문 - ~res(NOT연산) & 0xf 의 값이 0x4 일때 st[16-i-1] 의 값은 ‘_’ 이 된다. - 0xf 는 2진수로 ‘1111’ 이다 NOT 연산을 수행한 res가 0x4 가 나오려면 res는 11이여야함 → res의 값이 11이면 ‘_’ 이 - 그렇지 않을 경우 st[16-i-1] 의 값은 str(res) 값이 된다.
-res가 12초과의 값일때는 res의 값이 16진수로 변환되어서 st[16-i-1] 에 대입된다.
이러한 일련의 과정을 거쳐 FLAG가 암호화 되는것이다.
이 암호화 된 결과값을 거꾸로 복호화하는 과정은?
- 암호화 과정이 문제파일에 있으니 거꾸로 조건문을 작성하여서 풀어보았습니다.
DH{e4f547e200276020255784838237d30bfed6b1c6065dbbd7102853bf3dd}
-다른방식으로 풀이
2중 if 문에서 if ~res & 0xf == 0x4 가 나오려면 res의 값은 11 이여야 함
11은 16진수로 b에 해당함
sample flag로 해당 코드를 실행한 결과
가 나오는것을 확인
1번째는 ‘_’ 를 16진수 b로 대치한 결과
2번째는 10진수와 16진수가 합쳐진 menu_str를 10진수화 시켜 출력한 결과
반대로 생각을 해보면 문제의 ‘1_c_3_c_0__ff_3e’ 의 ‘_’ 언더바를 16진수의 b로 대치시킨 결과 ‘1bcb3bcb0bbffb3e’ 를 10진수화 시켜서 풀어보면 ‘2002760202557848382’ 가 나온다.
-HTML 코드
-문제파일 코드
#!/usr/bin/env python3 from flask import Flask, request, render_template app = Flask(__name__) try: FLAG = open("./flag.txt", "r").read() # flag is here! except: FLAG = "[**FLAG**]" @app.route('/', methods=['GET', 'POST']) def index(): menu_str = '' org = FLAG[10:29] org = int(org) st = ['' for i in range(16)] for i in range (0, 16): res = (org >> (4 * i)) & 0xf if 0 < res < 12: if ~res & 0xf == 0x4: st[16-i-1] = '_' else: st[16-i-1] = str(res) else: st[16-i-1] = format(res, 'x') menu_str = menu_str.join(st) # POST if request.method == "POST": input_str = request.form.get("menu_input", "") if input_str == str(org): return render_template('index.html', menu=menu_str, flag=FLAG) return render_template('index.html', menu=menu_str, flag='try again...') # GET return render_template('index.html', menu=menu_str) if __name__ == '__main__': app.run(host='0.0.0.0', port=8000)
문제 의도 : 문제에서 제시된 태그 → FLAG의 인덱스값 10:29까지의 값이 조건식에 따라 암호화된 값을 해독화하여 input_str 에 POST 요청으로 보내라
여기에서 return 되는값으로 FLAG를 받으려면 if input_str == str(org) 의 조건에 참이여야함
str(org) 값을 알아야함 → org == FLAG[10:29] → FLAG[10:29] 를 알아보자
우선 코드를 분석해보면
-org = FLAG[10:29] : FLAG의 인덱스값 10부터 29까지의 값을 org에 대입연산한다.
-org = int(org) : org의 값을 int형으로 강제형변환한다.
-st = [’’ for i in range(16)] : 빈문자열이 16개 있는 리스트를 만든다.
-res = (org >> (4 * i)) & 0xf : org의 2진수 값을 오른쪽으로 (4 * i) 만큼 비트쉬프트 시킴 그리고 그 값을 0xf 와 AND 연산을 수행한 값이 res 이다.
- 여기에서 org는 비트쉬프트를 시킬때 10진수 → 2진수 로 변환되고 AND 연산을 수행시킬때 0xf 도 2진수로 변환되어 수행됨
-만약 res 값이 0 초과 12 미만 일때 2중 if문으로 들어간다
- 2중 if문 - ~res(NOT연산) & 0xf 의 값이 0x4 일때 st[16-i-1] 의 값은 ‘_’ 이 된다. - 0xf 는 2진수로 ‘1111’ 이다 NOT 연산을 수행한 res가 0x4 가 나오려면 res는 11이여야함 → res의 값이 11이면 ‘_’ 이 - 그렇지 않을 경우 st[16-i-1] 의 값은 str(res) 값이 된다.
-res가 12초과의 값일때는 res의 값이 16진수로 변환되어서 st[16-i-1] 에 대입된다.
이러한 일련의 과정을 거쳐 FLAG가 암호화 되는것이다.
이 암호화 된 결과값을 거꾸로 복호화하는 과정은?
- 암호화 과정이 문제파일에 있으니 거꾸로 조건문을 작성하여서 풀어보았습니다.
DH{e4f547e200276020255784838237d30bfed6b1c6065dbbd7102853bf3dd}
-다른방식으로 풀이
2중 if 문에서 if ~res & 0xf == 0x4 가 나오려면 res의 값은 11 이여야 함
11은 16진수로 b에 해당함
sample flag로 해당 코드를 실행한 결과
가 나오는것을 확인
1번째는 ‘_’ 를 16진수 b로 대치한 결과
2번째는 10진수와 16진수가 합쳐진 menu_str를 10진수화 시켜 출력한 결과
반대로 생각을 해보면 문제의 ‘1_c_3_c_0__ff_3e’ 의 ‘_’ 언더바를 16진수의 b로 대치시킨 결과 ‘1bcb3bcb0bbffb3e’ 를 10진수화 시켜서 풀어보면 ‘2002760202557848382’ 가 나온다.