SECCON Beginners CTF 2020 Writeup

12460 단어 CTF

풀린 문제





소개



제목대로 SECCON Beginners CTF 2020에 참가했습니다. 결과는 참패였던 것입니다만, 일단 풀린 것을 공유합니다.

Welcome



튜토리얼이므로 할애합니다.

R&B



우선 file명령으로 텍스트 파일인 것을 알았습니다.
그래서 프로그램을 보면,
from os import getenv


FLAG = getenv("FLAG")
FORMAT = getenv("FORMAT")


def rot13(s):
    # snipped


def base64(s):
    # snipped


for t in FORMAT:
    if t == "R":
        FLAG = "R" + rot13(FLAG)
    if t == "B":
        FLAG = "B" + base64(FLAG)

print(FLAG)


우선 rot13, base64 란 무엇입니까? 라는 초보적인 것을 알지 못했기 때문에 검색하면 파이썬으로 디코딩할 수 있다는 것.
그래서 다음 프로그램을 작성했습니다.
def rot13Reverse(arg):
    import codecs
    return codecs.decode(arg, 'rot13')

def base64Reverse(arg):
    import base64
    return str(base64.b64decode(bytes(arg, 'utf-8')))

s = "___" #テキストファイルの中身

while(True):
    print(s)
    if(s[0] == 'R'):
        s = rot13Reverse(s[1:])
    elif(s[0] == 'B'):
        s = base64Reverse(s[1:])
    else:
        break

print(s)

아시다시피 이것을 잘 움직이지 않았습니다. base64Reverse는 byte 배열을 반환합니다.
그러니까 콘솔에 나온 것을 오로지 copipe하고 어떻게든 대답에 도착했습니다.

emoemoencode



귀여운

조금 고민, 바이너리 에디터에서 열면,


F09F???? 라고 하는 줄이 4회씩 반복하고 있는 것을 깨달은 나는, 디코드하면 ctf4b로부터 시작될 것이라고 가정해 이하와 같은 프로그램을 썼습니다.
import java.util.List;

public class Main{
    public static void main(String[] args){
        List<Integer> list = List.of(0xF09F8DA3,0xF09F8DB4,0xF09F8DA6,0xF09F8CB4,
            0xF09F8DA2,0xF09F8DBB,0xF09F8DB3,0xF09F8DB4,0xF09F8DA5,0xF09F8DA7,
            0xF09F8DA1,0xF09F8DAE,0xF09F8CB0,0xF09F8DA7,0xF09F8DB2,0xF09F8DA1,
            0xF09F8DB0,0xF09F8DA8,0xF09F8DB9,0xF09F8D9F,0xF09F8DA2,0xF09F8DB9,
            0xF09F8D9F,0xF09F8DA5,0xF09F8DAD,0xF09F8CB0,0xF09F8CB0,0xF09F8CB0,
            0xF09F8CB0,0xF09F8CB0,0xF09F8CB0,0xF09F8DAA,0xF09F8DA9,0xF09F8DBD);

            list.stream().map(
                i -> {
                    if(i > 0xF09F8D60){
                        return i-0xF09F8D60;
                    }else{
                        return i-0xF09F8C80;
                    }
                }).forEach(i->System.out.print((char)i.shortValue()));
    }
}

머리가 나쁘다
처음 if로 분기하지 않으면 문자 깨짐이 심했기 때문에 ctf4b를 참고하여 처음이 그렇게 되도록 분기를 만들었습니다.

결과는
CTF4B[STEGAN0GRAPHY?BY?EM000000JI]

그리고는 에스퍼로 알파벳을 소문자로 해, 「[」를 「{」로 해, 「?」를 「_」로 하면(자) 통과했습니다.
상정해가 아니겠지만.

Spy



Beginner 문제를 나중에 한 개라도 열심히 다니려고 노력하고 있는 것이 이것입니다.

서버측 프로그램의 중요한 부분:
        if not exists:
            return render_template("index.html", message="Login failed, try again.", sec="{:.7f}".format(time.perf_counter()-t))

        # auth.calc_password_hash(salt, password) adds salt and performs stretching so many times.
        # You know, it's really secure... isn't it? :-)
        hashed_password = auth.calc_password_hash(app.SALT, password)
        if hashed_password != account.password:
            return render_template("index.html", message="Login failed, try again.", sec="{:.7f}".format(time.perf_counter()-t))

처음에는 SQL 인젝션이라든지 강제로 로그인할까라고 생각하고 여러가지 했습니다만, 2개의 render_template가 무엇이 다른가를 구멍이 열릴 정도 응시해 드디어 깨달았습니다.

hash 처리에 시간이 걸리는 것은 계속!

비밀번호를 의도적으로 길게 하여 모든 유저에 대해 총당하고, 로드 시간이 부자연스럽게 긴 것을 선택해 가면 정답했습니다.

로그인하지 않아서 좋았습니까?

끝에



아직도 자신이 공부 부족임을 재차 생각해 왔으므로, 앞으로도 정진해 나가려고 합니다.

운영 여러분 감사합니다.

좋은 웹페이지 즐겨찾기