e-Jornadas 2020 CTF Writeup

skyepodium·2020년 10월 15일
2

포르투칼 대회이고, 난 ㅈ밥이어서 몇개 밖에 못풀었지만, 공부를 위해서 작성합니다.

1. A Mirror would be useful

1) 유형
OSINT(open source intelligence) - 공개된 출처에서 얻은 정보

2) 문제
What is the number on the back of this shirt?

(maximum of 5 attempts)

Flag format: flag{number}


처음 보는 문제유형이다. 셔츠 앞면 사진만 주고 뒷면에 적힌 번호를 적으라는 문제다.

구글 이미지 검색을 사용했다.

페헤르 미클로시라는 헝가리 축구선수의 유니폼이었고 포르투칼 리그 - FC 포르투에서 활동하셨다.

정답: flag{29}

2. Rotate away

1) 유형
Crypto

2) 문제
Rotate every damn day of the year

rxms{xqfedafmfqftueftuzs}

Flag format: flag{string}


ROT13 느낌이 너무나도 강하게 온다.

ROT14 이었다.
https://gchq.github.io/CyberChef/

정답: flag{letsrotatethisthing}

3. Time to Coding

1) 유형
Crypto

2) 문제
Take a look at the python code file, and find the secret message in the file data.enc.

Flag format: flag{string}


파일 2개를 준다.

  • data.enc
BBlZPqpYhG8\kJLhh_Jh=:}W<WKXTSZX
  • encrypt.py
import base64


def encrypt(data): 
    encrypted=""
    key=0x2F
    pre_enc=""
    for x in data:
        tmp = ord(x) 
        tmp = tmp ^ key
        pre_enc+=chr(tmp)

    pre_enc=base64.b64encode(pre_enc)
    encrypted_data="" 
    for x in range(0, len(pre_enc)):   
        tmp = pre_enc[ len(pre_enc) - 1 -x ]    
        encrypted_data+= chr(ord(tmp) + 5 )
           
    return encrypted_data

encrypt.py를 보고 data.enc 결과가 나올수 있도록 거꾸로 해독한다.

다른건 크게 어려운건 없고, XOR 연산에 대해서
a ^ b = c 일때 c ^ b = a가 성립한다.

원리는 봤는데 기억이 잘 안나고, abc는 c바 이렇게 외웠다.

# 해독 코드
data = "BBlZPqpYhG8\kJLhh_Jh=:}W<WKXTSZX"

def decrypt(value):
    # 1. 인덱스 - 5 해줘서 값 원복하기
    first = ""
    for i in range(0, len(data)):
        first += chr(ord(data[i]) - 5)

    # 2. 문자열 뒤집기
    second = first[::-1]

    # 3. base64 디코딩
    third = base64.b64decode(second)

    # 4. XOR 역연산
    fourth = ""
    for i in third:
        fourth += chr(i ^ 0x2F)
    print(fourth)

decrypt(data)

정답: flag{Th1S_is_N0t_safe}

4. Registration Code

1) 유형
WEB

2) 문제
https://summer2020.ctf.cert.rcts.pt/webhack-100.php


들어가 보면 다음 페이지가 나온다.

자바스크립트 코드가 난독화 되어있다. 보통 이런문제 beautifier 사용하는데, 코드를 붙여놓아서 원복이 잘 안되었다.

첫줄을 분리하고 원복하면 다음과 같다.

var _0x2ea6=['regcode','replace','charCodeAt','value','101109114','welcomeregcode','getDay','getFullYear','The inserted code is not valid...'];

(function(_0x1f25e3, _0x2ea6d0) {
    var _0x4341d1 = function(_0x4620e6) {
        while (--_0x4620e6) {
            _0x1f25e3['push'](_0x1f25e3['shift']());
        }
    };
    _0x4341d1(++_0x2ea6d0);
}(_0x2ea6, 0xcc));

var _0x4341 = function(_0x1f25e3, _0x2ea6d0) {
    _0x1f25e3 = _0x1f25e3 - 0x0;
    var _0x4341d1 = _0x2ea6[_0x1f25e3];
    return _0x4341d1;
};

function check_regcode() {
    var _0x61267e = _0x4341,
        _0x4620e6 = document['getElementById'](_0x61267e('0x3'))[_0x61267e('0x6')],
        _0x153262 = new Date(),
        _0x2af850 = String(_0x153262[_0x61267e('0x0')]()) + String(_0x153262[_0x61267e('0x1')]()),
        _0x120b13 = _0x61267e('0x8'),
        _0x312f57 = String(_0x120b13['charCodeAt'](0x1)) + String(_0x120b13[_0x61267e('0x5')](0x5)) + String(_0x120b13[_0x61267e('0x5')](0x7)) + _0x2af850;
        _0x4620e6 == _0x61267e('0x7') + _0x2af850 + 'ABCDFGH' ? location[_0x61267e('0x4')]('/webhack-100.php?reg=' + _0x312f57 + 'ABCDFGH') : alert(_0x61267e('0x2'));
}

내가 해독한 내용

var _0x2ea6=['regcode','replace','charCodeAt','value','101109114','welcomeregcode','getDay','getFullYear','The inserted code is not valid...'];

(function(_0x1f25e3, _0x2ea6d0) {
    var _0x4341d1 = function(_0x4620e6) {
        while (--_0x4620e6) {
            _0x1f25e3['push'](_0x1f25e3['shift']());
        }
    };
    _0x4341d1(++_0x2ea6d0);
}(_0x2ea6, 0xcc));

var _0x4341 = function(_0x1f25e3, _0x2ea6d0) {
    _0x1f25e3 = _0x1f25e3 - 0x0;
    var _0x4341d1 = _0x2ea6[_0x1f25e3];
    return _0x4341d1;
};

// 1. 함수 대입, 함수는 두개의 인자를 받지만, 두번째 인자는 사용하지 않으니까 신경쓰지 말자 
var _0x61267e = _0x4341
console.log(_0x61267e)

// 2. 내가 입력해야하는값, 모르니까 빈 문자열로 둔다.
var _0x4620e6 = ""
console.log(_0x4620e6)

// 3. New Date() 현재값
var _0x153262 = new Date()
console.log(_0x153262)

// 4. 문자열 합성, 그 의미를 알아야할 필요는 없어보인다.
var _0x2af850 = String(_0x153262[_0x61267e('0x0')]()) + String(_0x153262[_0x61267e('0x1')]())
console.log(_0x2af850)

// 5. 함수에 인자 1개 넣고 반환값 확인
var _0x120b13 = _0x61267e('0x8')
console.log(_0x120b13)

// 6. 문자열 합성, 의미는 신경쓰지 말자
var _0x312f57 = String(_0x120b13['charCodeAt'](0x1)) + String(_0x120b13[_0x61267e('0x5')](0x5)) + String(_0x120b13[_0x61267e('0x5')](0x7)) + _0x2af850;
console.log(_0x312f57)

// 7. 삼항 연산자 검사식, 내가 입력해야하는값을 찾자
console.log('내가 최종적으로 입력해야하는값: ', _0x61267e('0x7') + _0x2af850 + 'ABCDFGH')

obfuscating 은 난독화라는 의미다.

정답: flag{d3obfuscatingJS}

5. Count the Cups

1) 유형
스테가노그라피

2) 문제
All of them.

(maximum of 10 attempts)

Flag format: flag{number}


컵의 개수를 세라는 문제다.
사진 한장을 주는데 진짜 1개 적으면 ㅈ된다.

헥스 에디터, binwalk 와 같은 툴로는 찾아내기 힘들고, 임베디드된 파일이어서 steghide라는 프로그램을 사용했다.

1) install steghide

steghide download does not support mac os
(I used bootcamp.)

2) download photo

3) using steghide

most cases has a passphrase(encrypte key) but in this case passphrase is null, just press enter
(+ Simple Steganography this problem need a passphrase)

  • find info
> steghide info filename
  • extract embeded file
> steghide extract -sf filename

4) using hexditor

FF D8 FF E0 is a sinature of JPEG file
(common file signatures)

  • change the filename extension txt -> jpeg

5) calculation

ultra low resolution

1 + 26 + 36 + 2 +7 + 7

answer: flag{79}

6. Not so strong covert channel

1) 유형: 네트워크

2) 문제
Find the flag in the attached pcap. It's easier than you may think.


별로 안어렵단다. 이것을 위해 와이어샤크 처음 써봤다.

follo tcp stream 으로 추적하고, 우측 하단 Stream을 1로 바꿨다.

정답: flag{long_live_lalaland}

7. Cooperation is key

1) 유형
네트워크

2) 문제
Find the flag in the attached pcap.


와이어샤크로 열어보면 굉장히 의심스러운 부분이 있다. http 프로토콜로 사진을 받았네

까보면 그렇구나 레알 받았구나

raw로 타입을 바꾼다. PNG 파일의 시그니처 코드는 1) 시작 - 89 50 4e 47 2) 끝 60 82

다음과 같이 헥스 에디터에 붙여주고 저장한다.

정답: flag{red_is_cooler}

profile
callmeskye

3개의 댓글

comment-user-thumbnail
2020년 10월 16일

what is Count the Cups continue? please

1개의 답글