def attack(url, tag, sid, mark): extension = "&sid=" + sid + "&mark=" + mark # parameter url is the attack url you construct parsedURL = urlparse.urlparse(url) # open a connection to the server httpconn = httplib.HTTPConnection(parsedURL.hostname, parsedURL.port) h = md5(state=tag.decode("hex"), count=512) h.update(extension) for i in range(8, 21): sid2 = sid + urllib.quote(padding((len(sid) + 4 + i) * 8)) + extension query = parsedURL.path + "?tag=" + h.hexdigest() + "&sid=" + sid2 # issue server-API request httpconn.request("GET", query) # httpresp is response object containing a status value and possible message httpresp = httpconn.getresponse() # valid request will result in httpresp.status value 200 # print httpresp.status httpresp.status # in the case of a valid request, print the server's message # print httpresp.read() httpresp.read() # return the url that made the attack successful return (query)
def M(params): '''returns true/false whether Mallory sends the correct tag and params to the server''' # Mallory does not know the key # but she knows one specific tag, the one resulting from md5("secret" + "show me the grade") tag = "9f4bb32ac843d6db979ababa2949cb52" new_tag = md5(state=tag.decode("hex"), count=512) new_tag.update(padding(2 * 8)) new_tag.update(" and change it to 100") return B(new_tag, params)
def forgeIllegalPayload(message, token, extension): ''' In this function, you are not allowed to: - call the function createToken - use the secret key However, you might know the length of the secret key (6) ''' h = md5(state=token.decode('hex'), count=512) h.update(extension) return h.hexdigest(), message + urllib.quote( padding((11 + len(message)) * 8)) + extension
def forgeIllegalPayload(message, token, extension): ''' In this function, you are not allowed to: - call the function createToken - use the secret key However, you might know the length of the secret key (6) ''' keyLen = 6 h = md5(state=token.decode("hex"), count=512) h.update(extension) message2 = message + padding((len(message) + keyLen) * 8) + extension return h.hexdigest(), message2
def createToken(message): return md5(KEY + message).hexdigest()
def verifyToken(message, token): return (token == md5(KEY + message).hexdigest())
#url = "https://mathlab.utsc.utoronto.ca/courses/cscd27f16/assignment/01/server/?tag=a9ebd4ad4e6f2478a25c638fee58f9f0&utorid=fengxia9" #mark = "100" from md5p import md5, padding # get the string before the tag(hash) which is "http://mathlab.../server/ url_str = url.split('?')[0] # get the hash code from url which is "a9ebd4ad...f0" hash_code = url.split('=')[1].split('&')[0] # get the part with format "&utorid=..." utorid_code = '&' + url.split('&')[1] # get the student's utorid utorid = utorid_code[1:].split('=')[1] # get from d27 hash length-extension attack slides # https://mathlab.utsc.utoronto.ca/courses/cscd27f16/handout/hash-extension.html m = md5(state=hash_code.decode("hex"), count=512) newmark = "&mark=" + mark + "&utorid=" + utorid m.update(newmark) # loop keylength in range(8, 17) for i in range(8, 17): length = (len(utorid_code) + i) * 8 pad = padding(length) # form the new url url = url_str + "?tag=" + m.hexdigest() + utorid_code + urllib.quote( pad) + newmark # parameter url is the attack url you construct parsedURL = urlparse.urlparse(url) # open a connection to the server
def A(params): '''returns true/false whether Alice sends the correct params and tag to the server''' key = "secret" tag = md5(key + params).hexdigest() return B(tag, params)
def B(tag, params): '''returns true/false whether the tag is valid given the params''' key = "secret" return md5(key + params).hexdigest() == tag
# Take command line arguments into variables url = sys.argv[1] mark = sys.argv[2] # ADD CODE HERE # Parsed the url into myParsed myParsed = urlparse.urlparse(url) # Obtained the query from myParsed and put them into dictionary # with title as the key {"tag": "..", "stnum": "##########", etc} query = myParsed.query queryDict = dict(s.split("=") for s in query.split("&")) #Update the hash with the marked query and new tag h = md5(state=queryDict["tag"].decode("hex"), count=512) markQuery = "&mark=" + str(mark) h.update(markQuery) # Store URL Params starting from the first '&' in a variable URL_params = query[query.find("&"):] # Compute the hash of new tag, marks and ith padding on each iteration for i in range(8, 16+1): url = myParsed.scheme + "://" + myParsed.netloc + \ myParsed.path + "?tag=" + str(h.hexdigest()) + URL_params + \ urllib.quote(padding((len(URL_params) + i)* 8)) + markQuery # parameter url is the attack url you construct parsedURL = urlparse.urlparse(url)
print(A("show me the grade")) # this returns true because Alice is able to compute the correct tag given these params print(A("show me the grade and change it to 100")) # this returns true because Mallory knows the correct tag given these params print(M("show me the grade")) # this returns false because Mallory does not know the correct tag given these params print(M("show me the grade and change it to 100")) # and your job is to make it otherwise without modfying A or B but M only print("----------------------------------") k = "secret" m = "show me the grade" m2 = "show me the grade and change it to 100" a = md5(k + m) b = md5(k + m2) print "1---> " + a.hexdigest() print "2---> " + b.hexdigest() h = md5(state="9f4bb32ac843d6db979ababa2949cb52".decode("hex"), count=512) print h.hexdigest() x = " and change it to 100" h.update(x) print h.hexdigest() print md5((k + m + padding(len(k + m) * 8)) + x).hexdigest() print("----------------------------------") def compute_magic_number(md5str): A = struct.unpack("I", md5str[0:8].decode('hex'))[0]
import httplib, urlparse, urllib, sys from md5p import md5, padding, md5_compress url = sys.argv[1] mark = sys.argv[2] tag = url[url.find("=") + 1:url.rfind("&")] URL_param = url[url.find("&") + 1:] msg = "&mark=" + str(mark) # loop to try key length for i in range(7, 17): l = i + len(URL_param) new_tag = md5(state=tag.decode("hex"), count=512) new_tag.state = md5_compress(new_tag.state, msg + padding(l + len(padding(l * 8)) + len(msg)) + msg) url = url[:url.find("=") + 1] + new_tag.hexdigest() + msg # parameter url is the attack url you construct parsedURL = urlparse.urlparse(url) # open a connection to the server httpconn = httplib.HTTPSConnection(parsedURL.hostname) # issue server-API request httpconn.request("GET", parsedURL.path + "?" + parsedURL.query) # httpresp is response object containing a status value and possible message httpresp = httpconn.getresponse()
mark_value = sys.argv[2] # parameter url is the attack url you construct parsedURL = urlparse.urlparse(url) params = parsedURL.query.split('&') # retrieve the actual hased value : e.g. stnum=991234567&asn=1 query = params[1] +"&" + params[2] # open a connection to the server httpconn = httplib.HTTPSConnection(parsedURL.hostname) # get the hash value tag = params[0][4:] # get the new hash value by setting internal state to the previous hash value h = md5(state=tag.decode("hex"), count=512) mark = "&mark=" + mark_value h.update(mark) new_tag = h.hexdigest() # loop through all possible key lengths from 8 to 16 for key_len in range(8, 17): # expected length of paddings to fill 512 bits # (by subtracting the length of existing key and previous query from 512) length = 512 - len(query)*8 - key_len*8 update_query = "tag=" + str(new_tag) + "&" + query + urllib.quote(padding(length)) + mark # issue server-API request httpconn.request("GET", parsedURL.path + "?" + update_query)