picoCTF Practice Writeup 2

picoCTF Practice Writeup 2
[picoGym Practice Challenges page=2](https://play.picoctf.org/practice?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)

```python: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()文を入れたら答えが出ることがわかる。

```python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/6a508a9d-1e80-64aa-425a-76d2797f98e5.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/d009a340-2913-9ee9-a95d-af400ebc33d5.png)

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

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

zipを解凍
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/70852128-7d9a-d937-8299-4f7b6aa212f9.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)

```python: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) がある。
末尾を変更

```python
# 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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/1f0388bf-28e9-3712-0225-58fa9d7981f8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/b82483b1-5791-72f6-147e-eb8966dbd648.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/ed270fe1-db26-5f42-aa10-e587fa7a97be.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/9dc02b61-603d-3c81-87a7-317dfd865a7c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/81b68152-5d2c-4399-eb83-751c59d61ad9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/4887b773-bcc5-e669-7898-b5dbd8ef7724.png)




# tunn3l v1s10n
良問です。
[picoCTF 2021 tunn3l v1s10n Writeup](https://qiita.com/housu_jp/items/bb0d41be153e7ee2b148)



# 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.

```python: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が暗号化され，さらに任意の文字を暗号化してくれる

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

```python: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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/c3b7f90a-a712-794a-79d9-ddd972c31e77.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

```armasm: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のアセンブラで説明

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

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

https://www.mztn.org/dragon/arm6408cond.html

https://vanya.jp.net/os/x86call/#section-5



# 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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/ce8bef31-b89a-e90f-27fb-259270caac9d.png)



Solution:
aaaを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/34a9b2a5-5f4a-c569-3fcb-a5dd5cc390c0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/929c65d3-3df3-bc17-3882-fd7d92f78da7.png)
Burp Suiteでは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/bb2291a7-8b6f-c152-657e-9efa33ffb150.png)

テキストボックスに薄く見えている snickerdoodle を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/0e6e8af0-e69b-a41d-7772-8d0bdeeef915.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/5cccf0ce-11e3-3e01-eece-9c71d2483136.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/697db185-5382-b15f-df94-fc187d890e09.png)
おしいみたい。
Burpは？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/36b3c087-21e1-7505-73cf-a6cbbf22d4cc.png)
snickerdoodle name=0

今度は，burp で intersept して name=1 を送ってみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/bcf124bc-e5c4-319b-a577-fa0c5bb79cac.png)
name=1 は　chocolate chip cookies

name=2は
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/b9b3a05c-1df9-06f1-b910-44a9be13fe95.png)
oatmeal raisin cookies

中略
name=18
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/778fc2a3-e2f8-7320-80ac-9b472702a13c.png)

力業に頼らない方法

```bash
$ 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...でエラーになっている

https://qiita.com/takayukioda/items/edf371b3566bea64d046

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

```bash
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>
```

クッキーの名前は

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

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

```bash
$ 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>
```

なんか進捗が出た

https://qiita.com/takayukioda/items/edf371b3566bea64d046

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

```bash
$ 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>
```

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

https://qiita.com/ytyng/items/d7afe80ef9da7aa8b721

```bash
$ 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.

```java: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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/9e2a7f75-88e3-778f-a2e7-781a5ba988c2.png)

Solution:
ページのソース
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/48e69612-c7e2-dd83-0007-4c2529c6bb37.png)

CSS
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/4ec9b9ed-9697-71e8-f308-4d224af65f9f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/edb312af-f3e9-716d-c59c-e13440aa0f0c.png)

js
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/160b7e30-e45c-db7d-fd37-519990fbabfe.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/ade05a85-6a68-9db1-db55-c8097e0cc100.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:

https://www.k-cube.co.jp/wakaba/server/ascii_code.html




# Glory of the Garden
Description:
This garden contains more than it seems.
Hints:
What is a hex editor?

Solution:
表層解析
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/4bbe8f42-bfa1-2bce-1ef2-c57cf9659152.png)