LoginSignup
1
1

More than 1 year has passed since last update.

picoCTF Practice Writeup 2

Last updated at Posted at 2021-04-11

picoCTF Practice Writeup 2
picoGym Practice Challenges page=2 の12問を勉強した記録

このページの難問は,
352 solves の tunn3l v1s10n (壊れたbmpの修復)
450 solves の Easy Peasy (pythonの問題)
469 solves の ARMssembly 0 (ARM 64bit のアセンブリ)

あと,Cookiesを力業に頼らず,bashでループ処理をして,curlできるようになった。

keygenme-py

Category: Reverse Engineering
Description:
keygenme-trial.py
Hints:
(None)

keygenme-trial.py
#============================================================================#
#============================ARCANE CALCULATOR===============================#
#============================================================================#

import hashlib
from cryptography.fernet import Fernet
import base64



# GLOBALS --v
arcane_loop_trial = True
jump_into_full = False
full_version_code = ""

username_trial = "GOUGH"
bUsername_trial = b"GOUGH"

key_part_static1_trial = "picoCTF{1n_7h3_|<3y_of_"
key_part_dynamic1_trial = "xxxxxxxx"
key_part_static2_trial = "}"
key_full_template_trial = key_part_static1_trial + key_part_dynamic1_trial + key_part_static2_trial

star_db_trial = {
  "Alpha Centauri": 4.38,
  "Barnard's Star": 5.95,
  "Luhman 16": 6.57,
  "WISE 0855-0714": 7.17,
  "Wolf 359": 7.78,
  "Lalande 21185": 8.29,
  "UV Ceti": 8.58,
  "Sirius": 8.59,
  "Ross 154": 9.69,
  "Yin Sector CL-Y d127": 9.86,
  "Duamta": 9.88,
  "Ross 248": 10.37,
  "WISE 1506+7027": 10.52,
  "Epsilon Eridani": 10.52,
  "Lacaille 9352": 10.69,
  "Ross 128": 10.94,
  "EZ Aquarii": 11.10,
  "61 Cygni": 11.37,
  "Procyon": 11.41,
  "Struve 2398": 11.64,
  "Groombridge 34": 11.73,
  "Epsilon Indi": 11.80,
  "SPF-LF 1": 11.82,
  "Tau Ceti": 11.94,
  "YZ Ceti": 12.07,
  "WISE 0350-5658": 12.09,
  "Luyten's Star": 12.39,
  "Teegarden's Star": 12.43,
  "Kapteyn's Star": 12.76,
  "Talta": 12.83,
  "Lacaille 8760": 12.88
}


def intro_trial():
    print("\n===============================================\n\
Welcome to the Arcane Calculator, " + username_trial + "!\n")    
    print("This is the trial version of Arcane Calculator.")
    print("The full version may be purchased in person near\n\
the galactic center of the Milky Way galaxy. \n\
Available while supplies last!\n\
=====================================================\n\n")


def menu_trial():
    print("___Arcane Calculator___\n\n\
Menu:\n\
(a) Estimate Astral Projection Mana Burn\n\
(b) [LOCKED] Estimate Astral Slingshot Approach Vector\n\
(c) Enter License Key\n\
(d) Exit Arcane Calculator")

    choice = input("What would you like to do, "+ username_trial +" (a/b/c/d)? ")

    if not validate_choice(choice):
        print("\n\nInvalid choice!\n\n")
        return

    if choice == "a":
        estimate_burn()
    elif choice == "b":
        locked_estimate_vector()
    elif choice == "c":
        enter_license()
    elif choice == "d":
        global arcane_loop_trial
        arcane_loop_trial = False
        print("Bye!")
    else:
        print("That choice is not valid. Please enter a single, valid \
lowercase letter choice (a/b/c/d).")


def validate_choice(menu_choice):
    if menu_choice == "a" or \
       menu_choice == "b" or \
       menu_choice == "c" or \
       menu_choice == "d":
        return True
    else:
        return False


def estimate_burn():
  print("\n\nSOL is detected as your nearest star.")
  target_system = input("To which system do you want to travel? ")

  if target_system in star_db_trial:
      ly = star_db_trial[target_system]
      mana_cost_low = ly**2
      mana_cost_high = ly**3
      print("\n"+ target_system +" will cost between "+ str(mana_cost_low) \
+" and "+ str(mana_cost_high) +" stone(s) to project to\n\n")
  else:
      # TODO : could add option to list known stars
      print("\nStar not found.\n\n")


def locked_estimate_vector():
    print("\n\nYou must buy the full version of this software to use this \
feature!\n\n")


def enter_license():
    user_key = input("\nEnter your license key: ")
    user_key = user_key.strip()

    global bUsername_trial

    if check_key(user_key, bUsername_trial):
        decrypt_full_version(user_key)
    else:
        print("\nKey is NOT VALID. Check your data entry.\n\n")


def check_key(key, username_trial):

    global key_full_template_trial

    if len(key) != len(key_full_template_trial):
        return False
    else:
        # Check static base key part --v
        i = 0
        for c in key_part_static1_trial:
            if key[i] != c:
                return False

            i += 1

        # TODO : test performance on toolbox container
        # Check dynamic part --v
        if key[i] != hashlib.sha256(username_trial).hexdigest()[4]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[5]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[3]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[6]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[2]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[7]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[1]:
            return False
        else:
            i += 1

        if key[i] != hashlib.sha256(username_trial).hexdigest()[8]:
            return False



        return True


def decrypt_full_version(key_str):

    key_base64 = base64.b64encode(key_str.encode())
    f = Fernet(key_base64)

    try:
        with open("keygenme.py", "w") as fout:
          global full_version
          global full_version_code
          full_version_code = f.decrypt(full_version)
          fout.write(full_version_code.decode())
          global arcane_loop_trial
          arcane_loop_trial = False
          global jump_into_full
          jump_into_full = True
          print("\nFull version written to 'keygenme.py'.\n\n"+ \
                 "Exiting trial version...")
    except FileExistsError:
        sys.stderr.write("Full version of keygenme NOT written to disk, "+ \
                      "ERROR: 'keygenme.py' file already exists.\n\n"+ \
              "ADVICE: If this existing file is not valid, "+ \
              "you may try deleting it and entering the "+ \
              "license key again. Good luck")

def ui_flow():
    intro_trial()
    while arcane_loop_trial:
        menu_trial()



# Encrypted blob of full version
full_version = \
b"""
gAAAAABgT_nv39GmDRYkPhrc2hba8UHCHnSTHqdFxXNdemW0svN2hYYw-6n56ErD3NrQYQlNL0sfdsGTmvWKxh5gVRGeCv5kNq-l6PpL0Fzzjo1x_E2Jjbw_xWKIwbvd7BRXFQZKnhs2ehcSEacqES4gsVMOExHUetxFtmYiHLMB0_kqueeT8zf_vcXAPzbiYA0hvD_QSAXzPiKwM2IsGpGzIS5O4_ODq6-knKszeQFstWKFNH_-jNAylCTWSQpPrWqJxCWhSINPhOZ9-PkBsy8lpqmksa6ZBCMvej4W9YFldupRHNoHUHzt8xScEvcsTzIgNmvzOsCBSf5GJGHbLw4yVjsNWmbKRKiE_6BrRMHZW01hcYbfNa1TdJ1MLUX64e_tpDDjMfKvlXZ1qMx4GDwR2lFza9_fm98zoaV-ccgQ1qiSf3wDU1KuKxd9e9TbUAn2TTJfVH9d6IU8emK3QWcn8XRFcMRzVMvlBuNnCVrZmHCYZUzRmwneo15FS-giH63hPzfvjuRfzwp1sFa3wqo5YTJHWejsU0suORvViiDuIpDozmlXTLKLhKj51NkI6QqqDXhMcWkHwKy9V1LN2Furmz_rPbahbNAxnTAWpjF0VELQAvyNHdVy0yxBIbbOJq1oMvHiDJo2adecADc8hMRb4RZJoLqokXxtKLulywhagQjX9METL9bw1YTP9orWXAMwKhTdDbEUdnHViEq8MHo5DcnVvH0yPlnc9Zn2s3_UOfswnhz5vKm0ZbDc5aX0sFTNiMJVjjCrMhQ6HYp5yf_ybd9Tcx_u6xLtwUZBERZWt931n4hQN8n4C_XmDsMehuoSuFmi2NpAuDhX2rcEQK86Ito0KYp-8n2RmbOjzcjo5V5aqHXujmEfX8GYIUWEUKXVcFouF5rZtxtNz3Wsm_j4tqL4Tom27YE5eK7LQSi5B-AsmSF5JGTam2mWeykOGyE-3pHZmNxxkRfdRjxM0uFV13yjQSLFgNIkZ--8n0uAoTb62c7ZFxoFItMNrWasd5zMvp9Nqq70se2KOUieV6VbPJdSL0Sf1uGDmbRFdMmopDm-AuS-7-MLBGiOPmwXtse_9yXjUggeuo3UU4bxyQxCgwh17Ul1ZgxGeopcU7s7Sjm3rqxwlaJWTPRzeF5AXxtZHgyyZjwQ3EB9xYeoMCFh6gsF06bcwnK1Esgar7IYR3JBUfBH6KnWiTyhx_dLkUdomAPMPY0cRoreYsXmFKkEWhYg-TCdifL0nRT8BTEhVyUwFTvqn4PJknTn8NXelYu8co3n8_PoxsOnTrbdNXBJP9vD8Qp2oMi0ZsyCIeekwuX7MCcK4oFVpLGwOrhJdQhJWVqxQdt0ULS-ROB08eOglsXifnVrDl0hi2B0EYcWxxGs-CzsXJPSBvqKWti9XdU5oIhuUH2d7jnAx0pM9tTKqNiL5sfL2mhakMI8XGcljZw2KI0ldgaOW_UvAgh8N3FgKUR4qh_iJ0raoQaaJJFbFneKRoDNT3QsywP_qj6avStEbMGnhN3iBOoc7S3VrN8853X5fow2yDUJaexAKjpYGphE7K4e1g3fHWYjvgnJ-AoXfqALOwDLzaLRjVHSsgF1TQl39XgiAgEzJL-7w_zBn_Hxl5BfYtqe4vxf4PVMZGvof0jXMpM4W-AQ8IW-41LbNgNbPnRuTLubiJCV7MWYu8J7wO0ADSqgv0aXK60IOl0NphAzflWRvjytyT1CljFa0wcsBZvTyyks_ZOoa2__iAj3VlQjcrQynzrxoT5NASs_k51IYPr913nkfOT29oekedYMcxaHzlICLXmjlVHctJfATgYue7xc1BotMDO0Uj5q-wfcg03dq1cZmJ_qhe3AqWrZt3RraYVcvTT2B9Nu2KHBTyjQvCsQMXyFjlqasFZ4jSuNcqybxS3ocP4z-5oGV43zsVjr6YAZyjQiUoLJN6i6h39G5YfH4SStpbTcj7WXWj9WNqxcrF_swHNeIkOPByEa34TIXyJvEOGefZOw7h-F-hxCGuho7LOwabIopS6IykeSLMw1Ra4COmYN-VamVHVUGo50AVEXcmcnHL9NmXP_812Y_sSFdNPo-jglCzjv3KS5jajY1tReYKC9ehz5phUgReaVkiawSc5Tm5BZ42dfJuYZeTwnknsgTWiyGt3Ov6PddqD_40Ye6oHMLO0VjjT_Ul8GWh8hhmxcWxbN8H6dYwLJD0_-YbXvFpRQSi8IQ7BKjY0ZrZm1_tYO87Gg5YcUJznce53ltjXtGCgNIqywt3FDyJ709hOATCIHWf_u-Jfmc7QcIuSss7Rjh68ZgQoQu0Ybjt0Y5bEGEymuyYbgvdUwW8xTksnpl9Jju4x8hMORUQtkyxD0SBG1j7OEsDCK4axMjWxBj4D0liLOSwUuCWr5COJ0Bf_SlydQmufol1HzVIwxTSUG2m7gXEO6cv6gvBIzK0DdcUMjEzXNnqa8davVM0tFvXfuQcgjz8C7tj4-fu4UvikQyAvO5PdSIhClyl06fAyuUmmJgKvyyuoX3plOaMqq5rJbCzXl8OV1anQzSscXIR2Ur_ePhX5IoZNe2XifzLkgVk-lc-Z0gj5Q4WRuo2IYxOcJG-woHvml0oHDY-hQU-gNflauD38YQcfpwdXV0WgcQseWgKNlXfEuldWVktYXn8JNvqVUTOXrNJBEGB9RDyQqp9IubjhQqOJh31eunKYq6oTx4PgjSii0QOKaLKkonBsYtAbb3cUwSoCvek719cI2tp33XWYq2UqQ8J74PtRNzG061_RR_TxHKyWBll-6ii9dgFPki104UzjFkFXkYPzButkzcvcXIDAWD2RNBK6-bshYKS2xr5XxJXgr3QBTWdjrm-p6EwlbFd4DGDR7ran7b38NRkrFD0ignYiKc68xlAPGg9E084LBVXCVlRas8YvYReJH_sl6ZR7faNme2F-qYFzbcvD3jmp5fX0nzvyJuTGWa51qh7siaVBxHETZ_rzoqTh-tr91b_aHPFdcQMfe1Pd-GBQiy9e5N41GQ4MCpvzs87kV5spprXd_DOKnkjeC5bJDFUoIdMk5r-UO2boRH0tHONCbUOzw7HOgFcJUA13yjtvGGbfPPMHvhFMtMDMRw8gacd-5WHaLeh05yBy4UjT_9flAGAqYMWbvrhkAbwEYPJ0abxp1weANOcYZ-gMHm7kn9kF_eTpzKXxWsViR0AekfepQICVZI1eJzLjV2w6qWq7yDA2ALUxFW10GuEqhP9DI_OVVg6AILHPgokj0pcVA9zUizVTWaGnB1Te8_Zlw5Ik-MwNFPJHYLAug14JI4iYeY0zVsgvkpPJmg_dJD4U7Lr4PBwANvyz5NmGZiITqslCAwUDRMK10u3o2ZmSMn-MuBje_9NRYvh8SRvtbWCB46Yj1YMSJvaqci0MaJK8FdPeDPJ84uSK3eWzq75X96k9nVPnHPnlLkcls3480mlq_81V9MTWlLcvgqhEU4FxE7lGjSF9orw7HCK_9lx2rXwuFAaovFweQw2bu7Nr7pH1X82y0XQCI7aeP687QHdONEoIkWikG5Oub8kEGTBq1D4yeRLocq8dPSoRUAPOb6g-QVAOlu3fiJBGIikubJUWSdQ97pbLgxhnpCrRYS3uFZVo-4f5lnwBNEHrR7DuVc13M-rkUXO-oeqrz6Txmr-xAjYtWrg7IsMr-UPihTJC0Gsmm1FAlXtVOmuKYjwOV7DG4aPzE1MjDAHMWidls3ECcueaLdUV-oY6Hw3WwOK_Nnj10sPmWSFSuMPeOBwPEL2M-1tCkbOvilqccCAelhS87qU_fDUKzD68TV1tJIoXEKW4sdwAVGxguEv1BAm4G7LhrH08McB5n3ja5I_3IqkeYdyHaxAXJ-O2thg==
"""



# Enter main loop
ui_flow()

if jump_into_full:
    exec(full_version_code)

Solution:
コードが長いので心が折れそうになるが,じっくり解析すると,チェックルーチンのif文の直前にデバッグ用のprint()文を入れたら答えが出ることがわかる。

def check_key(key, username_trial):

    global key_full_template_trial

    #solver start -----
    print(key_full_template_trial)
    print("xxxxxxxx is ...")
    print(hashlib.sha256(username_trial).hexdigest()[4])
    print(hashlib.sha256(username_trial).hexdigest()[5])
    print(hashlib.sha256(username_trial).hexdigest()[3])
    print(hashlib.sha256(username_trial).hexdigest()[6])
    print(hashlib.sha256(username_trial).hexdigest()[2])
    print(hashlib.sha256(username_trial).hexdigest()[7])
    print(hashlib.sha256(username_trial).hexdigest()[1])
    print(hashlib.sha256(username_trial).hexdigest()[8])
    #solver end -----

    if len(key) != len(key_full_template_trial):

実行結果
image.png

Matryoshka doll

Category: Forensics
Description:
Matryoshka dolls are a set of wooden dolls of decreasing size placed one inside another. What's the final one? Image: this
Hints:
1. Wait, you can hide files inside files? But how do you find them?
2. Make sure to submit the flag as picoCTF{XXXXX}
image.png

Solution:
拡張子はjpgだが中身はpngにzipがくっついてる
ddでzipを取り出す

dd if=dolls.jpg ibs=1 skip=272492 of=dolls.zip

zipを解凍
image.png
少し小さくなった。

dd if=2_c.jpg ibs=1 skip=187707 of=2.zip
dd if=3_c.jpg ibs=1 skip=123606 of=3.zip
dd if=4_c.jpg ibs=1 skip=79578 of=4.zip

繰り返すと最後にflag.txtが出てきた。

crackme-py

Category: Reverse Engineering
Description:
crackme.py
Hints:
(None)

crackme.py
# Hiding this really important number in an obscure piece of code is brilliant!
# AND it's encrypted!
# We want our biggest client to know his information is safe with us.
bezos_cc_secret = "A:4@r%uL`M-^M0c0AbcM-MFE0cdhb52g2N"

# Reference alphabet
alphabet = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"+ \
            "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"



def decode_secret(secret):
    """ROT47 decode

    NOTE: encode and decode are the same operation in the ROT cipher family.
    """

    # Encryption key
    rotate_const = 47

    # Storage for decoded secret
    decoded = ""

    # decode loop
    for c in secret:
        index = alphabet.find(c)
        original_index = (index + rotate_const) % len(alphabet)
        decoded = decoded + alphabet[original_index]

    print(decoded)



def choose_greatest():
    """Echo the largest of the two numbers given by the user to the program

    Warning: this function was written quickly and needs proper error handling
    """

    user_value_1 = input("What's your first number? ")
    user_value_2 = input("What's your second number? ")
    greatest_value = user_value_1 # need a value to return if 1 & 2 are equal

    if user_value_1 > user_value_2:
        greatest_value = user_value_1
    elif user_value_1 < user_value_2:
        greatest_value = user_value_2

    print( "The number with largest positive magnitude is "
        + str(greatest_value) )



choose_greatest()

Solution:
ソースを見ると呼ばれていない関数 decode_secret(secret) がある。
末尾を変更

# choose_greatest()
decode_secret(bezos_cc_secret)

実行

>python crackme_solv.py
picoCTF{1|\/|_4_p34|\|ut_4593da8a}

Magikarp Ground Mission

Category: General Skills
Description:
Do you know how to move between directories and read files in the shell? Start the container, ssh to it, and then ls once connected to begin. Login via ssh as ctf-player with the password, abcba9f7
ssh ctf-player@venus.picoctf.net -p 49915
Hints:
1. Finding a cheatsheet for bash would be really helpful!

Solution:
sshでつなげて簡単な調査をするだけ。
image.png
image.png
image.png
image.png
image.png
image.png

tunn3l v1s10n

良問です。
picoCTF 2021 tunn3l v1s10n Writeup

Easy Peasy

Category: Cryptography
Description:
A one-time pad is unbreakable, but can you manage to recover the flag? (Wrap with picoCTF{}) nc mercury.picoctf.net 20266 otp.py
Hints:
1. Maybe there's a way to make this a 2x pad.

otp.py
#!/usr/bin/python3 -u
import os.path

KEY_FILE = "key"
KEY_LEN = 50000
FLAG_FILE = "flag"


def startup(key_location):
    flag = open(FLAG_FILE).read()
    kf = open(KEY_FILE, "rb").read()

    start = key_location
    stop = key_location + len(flag)

    key = kf[start:stop]
    key_location = stop

    result = list(map(lambda p, k: "{:02x}".format(ord(p) ^ k), flag, key))
    print("This is the encrypted flag!\n{}\n".format("".join(result)))

    return key_location

def encrypt(key_location):
    ui = input("What data would you like to encrypt? ").rstrip()
    if len(ui) == 0 or len(ui) > KEY_LEN:
        return -1

    start = key_location
    stop = key_location + len(ui)

    kf = open(KEY_FILE, "rb").read()

    if stop >= KEY_LEN:
        stop = stop % KEY_LEN
        key = kf[start:] + kf[:stop]
    else:
        key = kf[start:stop]
    key_location = stop

    result = list(map(lambda p, k: "{:02x}".format(ord(p) ^ k), ui, key))

    print("Here ya go!\n{}\n".format("".join(result)))

    return key_location


print("******************Welcome to our OTP implementation!******************")
c = startup(0)
while c >= 0:
    c = encrypt(c)

Solution:
まず nc してみる

$ nc mercury.picoctf.net 20266
******************Welcome to our OTP implementation!******************
This is the encrypted flag!
5b1e564b6e415c0e394e0401384b08553a4e5c597b6d4a5c5a684d50013d6e4b

What data would you like to encrypt? picoCTF{aaa}
Here ya go!
115f3f177b321a0300503d05

What data would you like to encrypt?

flagが暗号化され,さらに任意の文字を暗号化してくれる

ソースコードを読み解いてコメントを付加していく

otp.py
#!/usr/bin/python3 -u
import os.path

KEY_FILE = "key"
KEY_LEN = 50000 #keyのサイズ
FLAG_FILE = "flag"


def startup(key_location):
    flag = open(FLAG_FILE).read()
    kf = open(KEY_FILE, "rb").read()

    start = key_location
    stop = key_location + len(flag) #消費するkeyの長さはflagの長さと同じ

    key = kf[start:stop]
    key_location = stop #keyの先頭を更新

    result = list(map(lambda p, k: "{:02x}".format(ord(p) ^ k), flag, key))
    print("This is the encrypted flag!\n{}\n".format("".join(result)))
    '''
    lambdaが苦手なので,変形してみた
    enc = []
    i = 0
    while i < len(flag):
        enc.append(flag[i] ^ key[i])
        i = i + 1
    print(enc)
    print(''.join(map(chr,enc)))
    '''

    return key_location

def encrypt(key_location):
    ui = input("What data would you like to encrypt? ").rstrip()
    if len(ui) == 0 or len(ui) > KEY_LEN:
        return -1

    start = key_location
    stop = key_location + len(ui) #入力された文字長だけkeyを消費

    kf = open(KEY_FILE, "rb").read()

    if stop >= KEY_LEN: #5000バイトを超えたら一周する
        stop = stop % KEY_LEN
        key = kf[start:] + kf[:stop]
    else:
        key = kf[start:stop]
    key_location = stop

    result = list(map(lambda p, k: "{:02x}".format(ord(p) ^ k), ui, key))

    print("Here ya go!\n{}\n".format("".join(result)))

    return key_location


print("******************Welcome to our OTP implementation!******************")
c = startup(0) #keyの先頭は0バイト目に位置づけ
while c >= 0:
    c = encrypt(c)

整理すると
encrypted flag 5b1e564b6e415c0e394e0401384b08553a4e5c597b6d4a5c5a684d50013d6e4b
flag長 32バイト
key長 5000バイト(keyの開始位置が5000を超えると先頭に戻る)

よって
What data would you like to encrypt?
で4968バイト送信した後,次の
What data would you like to encrypt?
で\x00を32バイト送信するとkeyが丸見えになる(\x00とxorするとkeyが丸見え)

$ python3 -c "print('\x00'*(50000-32)+'\n'+'\x00'*32)" | nc mercury.picoctf.net 20266
(中略)
What data would you like to encrypt? Here ya go!
6227667c5c7865385c7862365c7831625c7839384b5c7864385c7861365e5c78

あとは
5b1e564b6e415c0e394e0401384b08553a4e5c597b6d4a5c5a684d50013d6e4bと
6227667c5c7865385c7862365c7831625c7839384b5c7864385c7861365e5c78を
xorするだけ
image.png

ARMssembly 0

Category: Reverse Engineering
Description:
What integer does this program print with arguments 182476535 and 3742084308? File: chall.S Flag format: picoCTF{XXXXXXXX} -> (hex, lowercase, no 0x, and 32 bits. ex. 5614267 would be picoCTF{0055aabb})
Hints:
Simple compare

chall.S
    .arch armv8-a
    .file   "chall.c"
    .text
    .align  2
    .global func1
    .type   func1, %function
func1:
    sub sp, sp, #16
    str w0, [sp, 12]
    str w1, [sp, 8]
    ldr w1, [sp, 12]
    ldr w0, [sp, 8]
    cmp w1, w0
    bls .L2
    ldr w0, [sp, 12]
    b   .L3
.L2:
    ldr w0, [sp, 8]
.L3:
    add sp, sp, 16
    ret
    .size   func1, .-func1
    .section    .rodata
    .align  3
.LC0:
    .string "Result: %ld\n"
    .text
    .align  2
    .global main
    .type   main, %function
main:
    stp x29, x30, [sp, -48]!
    add x29, sp, 0
    str x19, [sp, 16]
    str w0, [x29, 44]
    str x1, [x29, 32]
    ldr x0, [x29, 32]
    add x0, x0, 8
    ldr x0, [x0]
    bl  atoi
    mov w19, w0
    ldr x0, [x29, 32]
    add x0, x0, 16
    ldr x0, [x0]
    bl  atoi
    mov w1, w0
    mov w0, w19
    bl  func1
    mov w1, w0
    adrp    x0, .LC0
    add x0, x0, :lo12:.LC0
    bl  printf
    mov w0, 0
    ldr x19, [sp, 16]
    ldp x29, x30, [sp], 48
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0"
    .section    .note.GNU-stack,"",@progbits

Solution:
重要な場所だけ見ていく
"以下のコメントはx86のアセンブラで説明

    ldr w1, [sp, 12]  " mov ecx, [ebp+c]  ecx に 第2引数(ebp+c)を代入
    ldr w0, [sp, 8]   " mov edx, [ebp+8]  edx に 第1引数(ebp+8)を代入
    cmp w1, w0        " cmp ecx, edx      比較
    bls .L2           " jle .L2           第1引数のほうが大きいとき .L2へ
    ldr w0, [sp, 12]  " mov eax, [ebp+c]  JUMPしなかったので第2引数(ebp+c)のほうが大きいので戻り値EAXにセット
    b   .L3           " jmp .L3
.L2:
    ldr w0, [sp, 8]   " mov eax, [ebp+8]
.L3:
    add sp, sp, 16

つまり2つの引数の大きい方を返してる
3742084308 を 16進にしたら正解

Cookies

Category: Web Exploitation
Description:
Who doesn't love cookies? Try to figure out the best one. http://mercury.picoctf.net:27177/
Hints:
(None)
image.png

Solution:
aaaを入力
image.png
image.png
Burp Suiteでは
image.png

テキストボックスに薄く見えている snickerdoodle を入力
image.png
image.png
image.png
おしいみたい。
Burpは?
image.png
snickerdoodle name=0

今度は,burp で intersept して name=1 を送ってみる
image.png
name=1 は chocolate chip cookies

name=2は
image.png
oatmeal raisin cookies

中略
name=18
image.png

力業に頼らない方法

$ curl --cookie "name=0" --data "name=aaa" http://mercury.picoctf.net:27177/search
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>Redirecting...</title>
<h1>Redirecting...</h1>
<p>You should be redirected automatically to target URL: <a href="/">/</a>.  If not click the link.

Redirecting...でエラーになっている

-L オプションをつけ,リダイレクトも追うように

curl --cookie "name=0" --data "name=aaa" -L http://mercury.picoctf.net:27177/search
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Cookies</title>


    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">

    <link href="https://getbootstrap.com/docs/3.3/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>

<body>

    <div class="container">
        <div class="header">
            <nav>
                <ul class="nav nav-pills pull-right">
                    <li role="presentation"><a href="/reset" class="btn btn-link pull-right">Home</a>
                    </li>
                </ul>
            </nav>
            <h3 class="text-muted">Cookies</h3>
        </div>

        <!-- Categories: success (green), info (blue), warning (yellow), danger (red) -->


        <div class="alert alert-success alert-dismissible" role="alert" id="myAlert">
          <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
          <!-- <strong>Title</strong> --> That is a cookie! Not very special though...
            </div>



        <div class="jumbotron">
            <p class="lead"></p>
            <p style="text-align:center; font-size:30px;"><b>I love snickerdoodle cookies!</b></p>
        </div>


        <footer class="footer">
            <p>&copy; PicoCTF</p>
        </footer>

    </div>
    <script>
    $(document).ready(function(){
        $(".close").click(function(){
            $("myAlert").alert("close");
        });
    });
    </script>
</body>

</html>

クッキーの名前は

            <p style="text-align:center; font-size:30px;"><b>I love snickerdoodle cookies!</b></p>

"<b>"をgrepすればいいみたい

$ curl --cookie "name=0" --data "name=aaa" -L http://mercury.picoctf.net:27177/search |
grep "<b>"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   237  100   219  100    18    341     28 --:--:-- --:--:-- --:--:--   369
100  1779  100  1779    0     0   1732      0  0:00:01  0:00:01 --:--:--  1732
            <p style="text-align:center; font-size:30px;"><b>I love snickerdoodle cookies!</b></p>

なんか進捗が出た

-s で進捗が消えるみたい

$ curl --cookie "name=0" --data "name=aaa" -s -L http://mercury.picoctf.net:27177/search
 | grep "<b>"
            <p style="text-align:center; font-size:30px;"><b>I love snickerdoodle cookies!</b></p>

イイ感じ。あとは回すだけ

$ for i in {0..99} ; do
>     echo -n $i
>     echo -n " "
>     curl --cookie "name=$i" --data "name=aaa" -s -L http://mercury.picoctf.net:27177/search | grep "<b>" | awk -F "<b>" '{print $2}'
> done
0 I love snickerdoodle cookies!</b></p>
1 I love chocolate chip cookies!</b></p>
2 I love oatmeal raisin cookies!</b></p>
3 I love gingersnap cookies!</b></p>
4 I love shortbread cookies!</b></p>
5 I love peanut butter cookies!</b></p>
6 I love whoopie pie cookies!</b></p>
7 I love sugar cookies!</b></p>
8 I love molasses cookies!</b></p>
9 I love kiss cookies!</b></p>
10 I love biscotti cookies!</b></p>
11 I love butter cookies!</b></p>
12 I love spritz cookies!</b></p>
13 I love snowball cookies!</b></p>
14 I love drop cookies!</b></p>
15 I love thumbprint cookies!</b></p>
16 I love pinwheel cookies!</b></p>
17 I love wafer cookies!</b></p>
18 Flag</b>: <code>picoCTF{3v3ry1_l0v3s_c00k135_064663be}</code></p>
19 I love macaroon cookies!</b></p>
20 I love fortune cookies!</b></p>
21 I love crinkle cookies!</b></p>
22 I love icebox cookies!</b></p>
23 I love gingerbread cookies!</b></p>
24 I love tassie cookies!</b></p>
25 I love lebkuchen cookies!</b></p>
26 I love macaron cookies!</b></p>
27 I love black and white cookies!</b></p>
28 I love white chocolate macadamia cookies!</b></p>
29^C

vault-door-training

Category: Reverse Engineering
Description:
Your mission is to enter Dr. Evil's laboratory and retrieve the blueprints for his Doomsday Project. The laboratory is protected by a series of locked vault doors. Each door is controlled by a computer and requires a password to open. Unfortunately, our undercover agents have not been able to obtain the secret passwords for the vault doors, but one of our junior agents obtained the source code for each vault's computer! You will need to read the source code for each level to figure out what the password is for that vault door. As a warmup, we have created a replica vault in our training facility. The source code for the training vault is here: VaultDoorTraining.java
Hints:
1. The password is revealed in the program's source code.

VaultDoorTraining.java
import java.util.*;

class VaultDoorTraining {
    public static void main(String args[]) {
        VaultDoorTraining vaultDoor = new VaultDoorTraining();
        Scanner scanner = new Scanner(System.in); 
        System.out.print("Enter vault password: ");
        String userInput = scanner.next();
    String input = userInput.substring("picoCTF{".length(),userInput.length()-1);
    if (vaultDoor.checkPassword(input)) {
        System.out.println("Access granted.");
    } else {
        System.out.println("Access denied!");
    }
   }

    // The password is below. Is it safe to put the password in the source code?
    // What if somebody stole our source code? Then they would know what our
    // password is. Hmm... I will think of some ways to improve the security
    // on the other doors.
    //
    // -Minion #9567
    public boolean checkPassword(String password) {
        return password.equals("w4rm1ng_Up_w1tH_jAv4_3808d338b46");
    }
}

Solution:
表層解析

Insp3ct0r

Category: Web Exploitation
Description:
Kishor Balan tipped us off that the following code may need inspection: https://jupiter.challenges.picoctf.org/problem/9670/ (link) or http://jupiter.challenges.picoctf.org:9670
Hints:
1. How do you inspect web code on a browser?
2. There's 3 parts
image.png

Solution:
ページのソース
image.png

CSS
image.png
image.png

js
image.png
image.png

Lets Warm Up

Category: General Skills
Description:
If I told you a word started with 0x70 in hexadecimal, what would it start with in ASCII?
Hints:
1. Submit your answer in our flag format. For example, if your answer was 'hello', you would submit 'picoCTF{hello}' as the flag.

Solution:

Glory of the Garden

Description:
This garden contains more than it seems.
Hints:
What is a hex editor?

Solution:
表層解析
image.png

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1