PicoCTF General Skills PW Crack Level4 - python
I'm working on the PW Crack Level4 in the PicoCTF General Skills section. I'm very new to python and CTF's in general. The challenge is to find the right pw from the included list of 100 possibles. I could have, by now, simply entered each one, lol, but that's not the point I think. So I am trying to modify the code to iterate through the list of pw's and pass each one to the part of the code that checks it.
That's where I'm stuck. The for loop seems to run through the list without passing each pw to the part of the code that should check it... I feel like the answer is on the tip of my tongue. But I'm too new to see it.
Here's my code
import hashlib
### THIS FUNCTION WILL NOT HELP YOU FIND THE FLAG --LT ########################
def str_xor(secret, key):
#extend key to secret length
new_key = key
i = 0
while len(new_key) < len(secret):
new_key = new_key + key[i]
i = (i + 1) % len(key)
return "".join([chr(ord(secret_c) ^ ord(new_key_c)) for (secret_c,new_key_c) in zip(secret,new_key)])
###############################################################################
flag_enc = open('level4.flag.txt.enc', 'rb').read()
correct_pw_hash = open('level4.hash.bin', 'rb').read()
def hash_pw(pw_str):
pw_bytes = bytearray()
pw_bytes.extend(pw_str.encode())
m = hashlib.md5()
m.update(pw_bytes)
return m.digest()
pos_pw_list = ["6288", "6152", "4c7a", "b722", "9a6e", "6717", "4389", "1a28", "37ac", "de4f", "eb28", "351b", "3d58", "948b", "231b", "973a", "a087", "384a", "6d3c", "9065", "725c", "fd60", "4d4f", "6a60", "7213", "93e6", "8c54", "537d", "a1da", "c718", "9de8", "ebe3", "f1c5", "a0bf", "ccab", "4938", "8f97", "3327", "8029", "41f2", "a04f", "c7f9", "b453", "90a5", "25dc", "26b0", "cb42", "de89", "2451", "1dd3", "7f2c", "8919", "f3a9", "b88f", "eaa8", "776a", "6236", "98f5", "492b", "507d", "18e8", "cfb5", "76fd", "6017", "30de", "bbae", "354e", "4013", "3153", "e9cc", "cba9", "25ea", "c06c", "a166", "faf1", "2264", "2179", "cf30", "4b47", "3446", "b213", "88a3", "6253", "db88", "c38c", "a48c", "3e4f", "7208", "9dcb", "fc77", "e2cf", "8552", "f6f8", "7079", "42ef", "391e", "8a6d", "2154", "d964", "49ec"]
def level_4_pw_check():
for x in pos_pw_list: # for loop to iterate through the pos_pw_list
user_pw = input(x)
# print(user_pw) # printing user_pw just to make sure the loop is working - it is
user_pw_hash = hash_pw(user_pw)
if( user_pw_hash == correct_pw_hash ):
print("Welcome back... your flag, user:")
decryption = str_xor(flag_enc.decode(), user_pw)
print(decryption)
return
print("That password is incorrect")
level_4_pw_check()
# The strings below are 100 possibilities for the correct password.
# (Only 1 is correct)
pos_pw_list = ["6288", "6152", "4c7a", "b722", "9a6e", "6717", "4389", "1a28", "37ac", "de4f", "eb28", "351b", "3d58", "948b", "231b", "973a", "a087", "384a", "6d3c", "9065", "725c", "fd60", "4d4f", "6a60", "7213", "93e6", "8c54", "537d", "a1da", "c718", "9de8", "ebe3", "f1c5", "a0bf", "ccab", "4938", "8f97", "3327", "8029", "41f2", "a04f", "c7f9", "b453", "90a5", "25dc", "26b0", "cb42", "de89", "2451", "1dd3", "7f2c", "8919", "f3a9", "b88f", "eaa8", "776a", "6236", "98f5", "492b", "507d", "18e8", "cfb5", "76fd", "6017", "30de", "bbae", "354e", "4013", "3153", "e9cc", "cba9", "25ea", "c06c", "a166", "faf1", "2264", "2179", "cf30", "4b47", "3446", "b213", "88a3", "6253", "db88", "c38c", "a48c", "3e4f", "7208", "9dcb", "fc77", "e2cf", "8552", "f6f8", "7079", "42ef", "391e", "8a6d", "2154", "d964", "49ec"]
I'm not too experienced myself, but I think I know what you're doing wrong. I'll try to give you a small tip that will probably help you solve the problem without giving you the answer full out.
I think where you're going wrong is that you're still asking for input. Since you're comparing a list of possible passwords to the actual possible password, you don't need to ask for input anywhere in your code.
I hope this helps you out!
SO I stumbled upon the answer.... it appears to be a indent error (sorry, I don't fully grasp python). But once I properly indented my modified code I got the answer!
def level_4_pw_check():
for x in pos_pw_list: # for loop to iterate through the pos_pw_list
user_pw = x
user_pw_hash = hash_pw(user_pw)
print(user_pw) # printing user_pw just to make sure the loop is working - it is
if( user_pw_hash == correct_pw_hash ):
print("Welcome back... your flag, user:")
decryption = str_xor(flag_enc.decode(), user_pw)
#decryption = xor(flag_enc.decode(), user_pw)
print(decryption)
return
print("That password is incorrect")
Related
Creating nested dictionaries using for and if loops
I am working on creating nested dictionaries. Can someone please help? for key,values in hostwise.iteritems(): values.sort(key=lambda x: x.execution_time) for plugin in values: plugin_wise = {} if plugin.name not in plugin_wise.keys(): plugin_wise[plugin.name] = {} if plugin.status == 'Submitplugin': plugin_wise[plugin.name]['Submitplugin'] = plugin.execution_time elif plugin.status == 'Pluginsucceeded': plugin_wise[plugin.name]['Pluginsucceeded'] = plugin.execution_time else: if plugin.status == 'Submitplugin': plugin_wise.update({plugin.name: {'Submitplugin': plugin.execution_time}}) #plugin_wise[plugin.name]['Submitplugin'] = plugin.execution_time elif plugin.status == 'Pluginsucceeded': plugin_wise.update({plugin.name: {'Pluginsucceeded': plugin.execution_time}}) #plugin_wise[plugin.name]['Pluginsucceeded'] = plugin.execution_time {‘UpgradeOptional’: {‘Pluginsucceeded’: ‘2020-06-06T12:00:09’}} {‘UpgradeOptional’: {‘Submitplugin’: ‘2020-06-06T12:00:03’}} For example. the above output is not what I am expecting...I want the way below. Any ideas please? {‘UpgradeOptional’: {‘Pluginsucceeded’: ‘2020-06-06T12:00:09’,‘Submitplugin’: ‘2020-06-06T12:00:03’}}
Try this. plugin_wise[plugin.name].update({'Submitplugin': plugin.execution_time}) plugin_wise[plugin.name].update({'Pluginsucceeded': plugin.execution_time})
I think the part that you have commented out should work.
How do I consolidate my code to have one variable that changes for each input?
I'm building a program that will take the skillsets of different candidates for a given job, and check to see if they have the required skills. I have figured out how to make this work, but I don't know how to do it without writing "candidate1", "candidate2" etc. Is there a more efficient way to do this?: list_of_qualities = ['Experience in Cold Calling', 'Experience in Door to Door Sales', 'Experience in Account Management','Experience in Warm Leads','Experience in Presenting', 'Experience in Negotiation',\'Experience in Leadership', 'Experience in Closing'] cold_calling = list_of_qualities[0] door_to_door = list_of_qualities[1] account_management = list_of_qualities[2] warm_leads = list_of_qualities[3] presenting = list_of_qualities[4] negotiation = list_of_qualities[5] leadership = list_of_qualities[6] closing = list_of_qualities[7] required_qualities = [cold_calling, presenting, account_management, leadership, closing] candidate1 = [cold_calling, presenting, account_management, leadership, closing, door_to_door] candidate2 = [cold_calling, warm_leads, account_management, leadership] candidate3 = [cold_calling, account_management] matched_qualities1 = [] matched_qualities2 = [] matched_qualities3 = [] lacking_qualities1 = [] lacking_qualities2 = [] lacking_qualities3 = [] print("To view and apply for your job, candidates must have the following skillset:") print(required_qualities) print(" ") print("The candidates have the following matching skills:") Candidate 1 for i in candidate1: if i in required_qualities: matched_qualities1.append(i) print("Candidate 1:", matched_qualities1) for i in required_qualities: if i not in candidate1: lacking_qualities1.append(i) Check if candidate 1 has all skills or not if len(lacking_qualities1) == 0: print(" This candidate has all of the required skills") else: print(" lacking:", lacking_qualities1)
There are several options. You can have a list of lists, or a dataframe. An array is also an option, but not really appropriate. Some other things to simplify your code: You can do cold_calling,door_to_door,account_management,warm_leads,presenting,negotiation, leadership,closing = list_of_qualities Also, you can replace your for-loop with lacking_qualities1=[quality in required_qualities if not quality in candidate1] If you create a list of candidates, you can do lacking_qualities_list_of_list=[ [quality in required_qualities if not quality in candidate] for candidate in list_of_candidates]
Is there a way to programmatically combine Korean unicode into one?
Using a Korean Input Method Editor (IME), it's possible to type 버리 + 어 and it will automatically become 버려. Is there a way to programmatically do that in Python? >>> x, y = '버리', '어' >>> z = '버려' >>> ord(z[-1]) 47140 >>> ord(x[-1]), ord(y) (47532, 50612) Is there a way to compute that 47532 + 50612 -> 47140? Here's some more examples: 가보 + 아 -> 가봐 끝나 + ㄹ -> 끝날
I'm a Korean. First, if you type 버리 + 어, it becomes 버리어 not 버려. 버려 is an abbreviation of 버리어 and it's not automatically generated. Also 가보아 cannot becomes 가봐 automatically during typing by the same reason. Second, by contrast, 끝나 + ㄹ becomes 끝날 because 나 has no jongseong(종성). Note that one character of Hangul is made of choseong(초성), jungseong(중성), and jongseong. choseong and jongseong are a consonant, jungseong is a vowel. See more at Wikipedia. So only when there's no jongseong during typing (like 끝나), there's a chance that it can have jongseong(ㄹ). If you want to make 버리 + 어 to 버려, you should implement some Korean language grammar like, especially for this case, abbreviation of jungseong. For example ㅣ + ㅓ = ㅕ, ㅗ + ㅏ = ㅘ as you provided. 한글 맞춤법 chapter 4. section 5 (I can't find English pages right now) defines abbreviation like this. It's possible, but not so easy job especially for non-Koreans. Next, if what you want is just to make 끝나 + ㄹ to 끝날, it can be a relatively easy job since there're libraries which can handle composition and decomposition of choseong, jungseong, jongseong. In case of Python, I found hgtk. You can try like this (nonpractical code): # hgtk methods take one character at a time cjj1 = hgtk.letter.decompose('나') # ('ㄴ', 'ㅏ', '') cjj2 = hgtk.letter.decompose('ㄹ') # ('ㄹ', '', '') if cjj1[2]) == '' and cjj2[1]) == '': cjj = (cjj1[0], cjj1[1], cjj2[0]) cjj2 = None Still, without proper knowledge of Hangul, it will be very hard to get it done.
You could use your own Translation table. The drawback is you have to input all pairs manual or you have a file to get it from. For instance: # Sample Korean chars to map k = [[('버리', '어'), ('버려')], [('가보', '아'), ('가봐')], [('끝나', 'ㄹ'), ('끝날')]] class Korean(object): def __init__(self): self.map = {} for m in k: key = m[0][0] + m[0][1] self.map[hash(key)] = m[1] def __getitem__(self, item): return self.map[hash(item)] def translate(self, s): return [ self.map[hash(token)] for token in s] if __name__ == '__main__': k_map = Korean() k_chars = [ m[0][0] + m[0][1] for m in k] print('Input: %s' % k_chars) print('Output: %s' % k_map.translate(k_chars)) one_char_3 = k[0][0][0] + k[0][0][1] print('%s = %s' % (one_char_3, k_map[ one_char_3 ]) ) Input: ['버리어', '가보아', '끝나ㄹ'] Output: ['버려', '가봐', '끝날'] 버리어 = 버려 Tested with Python:3.4.2
Python and string accents
I am making a web scraper. I access google search, I get the link of the web page and then I get the contents of the <title> tag. The problem is that, for example, the string "P\xe1gina N\xe3o Encontrada!" should be "Página Não Encontrada!". I tried do decode to latin-1 and then encode to utf-8 and it did not work. r2 = requests.get(item_str) texto_pagina = r2.text soup_item = BeautifulSoup(texto_pagina,"html.parser") empresa = soup_item.find_all("title") print(empresa_str.decode('latin1').encode('utf8')) Can you help me, please? Thanks !
You can change the retrieved text variable to something like: string = u'P\xe1gina N\xe3o Encontrada!'.encode('utf-8') After printing string it seemed to work just fine for me. Edit Instead of adding .encode('utf8'), have you tried just using empresa_str.decode('latin1')? As in: string = empresa_str.decode('latin_1')
Not the most elegant solution, but worked for me : def remove_all(substr, str): index = 0 length = len(substr) while string.find(str, substr) != -1: index = string.find(str, substr) str = str[0:index] + str[index+length:] return str def latin1_to_ascii (unicrap): xlate={ 'xc3cb3':'o' , 'xc3xa7':'c','xc3xb5':'o', 'xc3xa3':'a', 'xc3xa9':'e', 'xc0':'A', 'xc1':'A', 'xc2':'A', 'xc3':'A', 'xc4':'A', 'xc5':'A', 'xc6':'Ae', 'xc7':'C', 'xc8':'E', 'xc9':'E', 'xca':'E', 'xcb':'E', 'xcc':'I', 'xcd':'I', 'xce':'I', 'xcf':'I', 'xd0':'Th', 'xd1':'N', 'xd2':'O', 'xd3':'O', 'xd4':'O', 'xd5':'O', 'xd6':'O', 'xd8':'O', 'xd9':'U', 'xda':'U', 'xdb':'U', 'xdc':'U', 'xdd':'Y', 'xde':'th', 'xdf':'ss', 'xe0':'a', 'xe1':'a', 'xe2':'a', 'xe3':'a', 'xe4':'a', 'xe5':'a', 'xe6':'ae', 'xe7':'c', 'xe8':'e', 'xe9':'e', 'xea':'e', 'xeb':'e', 'xec':'i', 'xed':'i', 'xee':'i', 'xef':'i', 'xf0':'th', 'xf1':'n', 'xf2':'o', 'xf3':'o', 'xf4':'o', 'xf5':'o', 'xf6':'o', 'xf8':'o', 'xf9':'u', 'xfa':'u', 'xfb':'u', 'xfc':'u', 'xfd':'y', 'xfe':'th', 'xff':'y', 'xa1':'!', 'xa2':'{cent}', 'xa3':'{pound}', 'xa4':'{currency}', 'xa5':'{yen}', 'xa6':'|', 'xa7':'{section}', 'xa8':'{umlaut}', 'xa9':'{C}', 'xaa':'{^a}', 'xab':'<<', 'xac':'{not}', 'xad':'-', 'xae':'{R}', 'xaf':'_', 'xb0':'{degrees}', 'xb1':'{+/-}', 'xb2':'{^2}', 'xb3':'{^3}', 'xb4':'', 'xb5':'{micro}', 'xb6':'{paragraph}', 'xb7':'*', 'xb8':'{cedilla}', 'xb9':'{^1}', 'xba':'{^o}', 'xbb':'>>', 'xbc':'{1/4}', 'xbd':'{1/2}', 'xbe':'{3/4}', 'xbf':'?', 'xd7':'*', 'xf7':'/' } unicrap = remove_all ('\\', unicrap) unicrap = remove_all('&', unicrap) unicrap = remove_all('u2013', unicrap) r = unicrap for item,valor in xlate.items(): #print item, unicrap.find(item) r = r.replace(item,valor) return r
Cipher program losing accuracy
I have a program in python that takes two strings. One is the plain text string, another is the cipher key. what it does is go over each of the characters and xors the bits with the cipher characters. But when going back and forth a few of the letter do not seem to change properly. Here is the code: //turns int into bin string length 8 def bitString(n): bin_string = bin(n)[2:] bin_string = ("0" * (8 - len(bin_string))) + bin_string return bin_string //xors the bits def bitXOR(b0, b1): nb = "" for x in range(min(len(b0), len(b1))): nb += "0" if b0[x] == b1[x] else "1" return nb //takes 2 chars, turns them into bin strings, xors them, then returns the new char def cypherChar(c0, c1): return chr(int(bitXOR(bitString(ord(c0)), bitString(ord(c1))), 2)) //takes s0 (the plaintext) and encrypts it using the cipher key (s1) def cypherString(s0, s1): ns = "" for x in range(len(s0)): ns += cypherChar(s0[x], s1[x%len(s1)]) return ns For example sometimes in a long string the word 'test' will cipher back into 'eest', and stuff like that I have checked over the code a dozen times and I can't figure out whats causing some of the characters to change. Is it possible some characters just behave strangely? EDIT: example: This is a test Due to the fact that in the last test Some symbols: !##$%^&*() were not changed properly I am retesting END using the cipher key : 'cypher key' translates back to : This is a test Due to toe aact that in the last sest Some symbols: !##$%^&*() were not changed properly I am retestiig END
Sorry it its a little messy, I put it together real quick from binascii import hexlify, unhexlify from sys import version_info def bit_string(string): if version_info >= (3, 0): return bin(int.from_bytes(string.encode(), 'big')) else: return bin(int(hexlify(string), 16)) def bitXOR_encrypt(plain_text, key): encrypted_list = [] for j in range(2, len(plain_text)): encrypted_list.append(int(plain_text[j]) ^ int(key[j])) #Assume the key and string are the same length return encrypted_list def decrypt(cipher_text, key): decrypted_list = [] for j in range(2, len(cipher_text)): #or xrange decrypted_list.append(int(cipher_text[j]) ^ int(key[j])) #Again assumes key is the same length as the string decrypted_list = [str(i) for i in decrypted_list] add_binary = "0b" + "".join(decrypted_list) decrypted_string = int(add_binary, 2) if version_info >= (3, 0): message = decrypted_string.to_bytes((decrypted_string.bit_length() + 7) // 8, 'big').decode() else: message = unhexlify('%x' % decrypted_string) return message def main(): plain_text = "Hello" plain_text_to_bits = bit_string(plain_text) key_to_bits = bit_string("candy") #Encrypt cipher_text = bitXOR_encrypt(plain_text_to_bits, key_to_bits) #make Strings cipher_text_string = "".join([str(i) for i in cipher_text]) key_string = "".join([str(i) for i in key_to_bits]) #Decrypt decrypted_string = decrypt("0B"+cipher_text_string, key_string) print("plain text: %s" % plain_text) print("plain text to bits: % s" % plain_text_to_bits) print("key string in bits: %s" % key_string) print("Ciphered Message: %s" %cipher_text_string) print("Decrypted String: %s" % decrypted_string) main() for more details or example code you can visit my repository either on github https://github.com/marcsantiago/one_time_pad_encryption Also, I know that in this example the key is the same length as the string. If you want to use a string that is smaller than the string try wrapping it like in a vigenere cipher (http://en.wikipedia.org/wiki/Vigenère_cipher)
I think you are overcomplicating things: def charxor(s1, s2): return chr(ord(s1) ^ ord(s2)) def wordxor(w1, w2): return ''.join(charxor(w1[i], w2[i]) for i in range(min(len(w1), len(w2)))) word = 'test' key = 'what' cyphered = wordxor(word, key) uncyphered = wordxor(cyphered, key) print(repr(cyphered)) print(uncyphered) You get '\x03\r\x12\x00' test There is a fairly good explanation of Python's bit arithmetic in How do you get the logical xor of two variables in Python?
I could find nothing wrong with the results of your functions when testing with your input data and key. To demonstrate, you could try this test code which should not fail: import random def random_string(n): return ''.join(chr(random.getrandbits(8)) for _ in range(n)) for i in range(1000): plaintext = random_string(500) key = random_string(random.randrange(1,100)) ciphertext = cypherString(plaintext, key) assert cypherString(ciphertext, key) == plaintext If you can provide a definitive sample of plain text, key, and cipher text that fails, I can look further.