made input upper case. renamed login to hack and added new login

This commit is contained in:
Josh d'Entremont 2015-06-14 18:05:56 -03:00
parent 84d382cfef
commit b672f086d2
5 changed files with 399 additions and 258 deletions

View file

@ -2,6 +2,7 @@
import fallout_login as login
import fallout_boot as boot
import fallout_locked as locked
import fallout_hack as hack
import sys
hard = False
@ -9,8 +10,11 @@ if len(sys.argv) == 2 and sys.argv[1].lower() == 'hard':
hard = True
if boot.beginBoot(hard):
if login.beginLogin():
pwd = hack.beginLogin()
if pwd != None:
login.beginLogin(hard, 'ADMIN', pwd)
print 'Login successful'
else:
locked.beginLocked()
print 'Login failed'

View file

@ -1,4 +1,7 @@
from fallout_functions import slowWrite
from fallout_functions import INPUT_PAUSE
from fallout_functions import TYPE_DELAY
from fallout_functions import upperInput
import curses
######################## global 'constants' ##############
@ -11,9 +14,6 @@ ENTRY_3 = 'SET HALT RESTART/MAINT'
ENTRY_4 = 'RUN DEBUG/ACCOUNTS.F'
INPUT_PAUSE = 500 # ms
TYPE_DELAY = 25
######################## text strings ####################
@ -35,12 +35,16 @@ MESSAGE_3 = 'Initializing Robco Industries(TM) MF Boot Agent v2.3.0\n' \
def runBoot(scr, hardMode):
"""
Start the boot portion of the terminal
hardMode - boolean indicating whether the user has to enter the ENTRY
constants, or if they are entered automatically
"""
curses.use_default_colors()
scr.erase()
scr.move(0, 0)
curses.echo()
curses.noecho()
scr.scrollok(True)
slowWrite(scr, MESSAGE_1 + '\n\n')
@ -49,7 +53,7 @@ def runBoot(scr, hardMode):
entry = ''
while entry.upper() != ENTRY_1.upper():
slowWrite(scr, '>')
entry = scr.getstr()
entry = upperInput(scr)
else:
# input is entered for them
slowWrite(scr, '>')
@ -62,10 +66,10 @@ def runBoot(scr, hardMode):
entry = ''
while entry.upper() != ENTRY_2.upper():
slowWrite(scr, '>')
entry = scr.getstr()
entry = upperInput(scr)
while entry.upper() != ENTRY_3.upper():
slowWrite(scr, '>')
entry = scr.getstr()
entry = upperInput(scr)
else:
slowWrite(scr, '>')
curses.napms(INPUT_PAUSE)
@ -80,7 +84,7 @@ def runBoot(scr, hardMode):
entry = ''
while entry.upper() != ENTRY_4.upper():
slowWrite(scr, '>')
entry = scr.getstr()
entry = upperInput(scr)
else:
slowWrite(scr, '>')
curses.napms(INPUT_PAUSE)

View file

@ -4,6 +4,16 @@ import sys
LETTER_PAUSE = 5
INPUT_PAUSE = 500 # ms
TYPE_DELAY = 30
HIDDEN_MASK = '*'
NEWLINE = 10
DELETE = 127
def slowWrite(window, text, pause = LETTER_PAUSE):
"""
wrapper for curses.addstr() which writes the text slowely
@ -12,3 +22,40 @@ def slowWrite(window, text, pause = LETTER_PAUSE):
window.addstr(text[i])
window.refresh()
curses.napms(pause)
def upperInput(window, hidden = False, can_newline = True):
"""
Reads user input until enter key is pressed. Echoes the input in upper case
hidden - if true the output will be masked
can_newline - if true the input is followed by a newline and the screen is
scrolled if necessary
"""
inchar = 0
instr = ''
while inchar != NEWLINE:
inchar = window.getch()
# convert lower case to upper
if inchar > 96 and inchar < 123:
inchar -= 32
# deal with backspace
if inchar == DELETE:
if len(instr) > 0:
instr = instr[:-1]
cur = window.getyx()
window.move(cur[0], cur[1] - 1)
window.clrtobot()
else:
continue
elif inchar > 255:
continue
# output the character
elif inchar != NEWLINE:
instr += chr(inchar)
if hidden:
window.addch(HIDDEN_MASK)
else:
window.addch(inchar)
elif can_newline:
window.addch(NEWLINE)
return instr

272
fallout_hack.py Normal file
View file

@ -0,0 +1,272 @@
import curses
import random
import os
from fallout_functions import slowWrite
from fallout_functions import upperInput
################## text strings ######################
HEADER_TEXT = 'ROBCO INDUSTRIES (TM) TERMLINK PROTOCOL'
################## global "constants" ################
# number of characters for hex digits and spaces
CONST_CHARS = 16
# position of the attempt squares
SQUARE_X = 19
SQUARE_Y = 3
LOGIN_ATTEMPTS = 4
HEADER_LINES = 5
# amount of time to pause after correct password input
LOGIN_PAUSE = 3000
# starting number for hex generation
START_HEX = 0xf650
# list of possible symbols for password hiding
SYMBOLS = '!@#$%^*()_-+={}[]|\\:;\'",<>./?'
################## functions #########################
def generateHex(n):
"""
generates n numbers starting at START_HEX and increasing by 12 each time
"""
num = START_HEX
list = []
for i in xrange(n):
list.append(num)
num += 12
return list
def getSymbols(n):
"""
return n random symbols
"""
count = len(SYMBOLS)
result = ""
for i in xrange(n):
result += SYMBOLS[random.randint(0, count - 1)]
return result
def getPasswords():
"""
Returns an array of strings to be used as the password and the decoys
"""
groups = []
# script file / password file location
__location__ = os.path.realpath(os.path.join(os.getcwd(),
os.path.dirname(__file__)))
# read from passwords.txt
with open(os.path.join(__location__, "passwords.txt")) as pwfile:
for line in pwfile:
if not line.strip():
groups.append([])
elif len(groups) > 0:
groups[len(groups) - 1].append(line[:-1])
passwords = groups[random.randint(0, len(groups) - 1)]
random.shuffle(passwords)
return passwords
def getFiller(length, passwords):
"""
Return a string of symbols with potential passwords mixed in
length - the length of the string to create
passwords - an array of passwords to hide in the symbols
"""
filler = getSymbols(length)
# add the passwords to the symbols
pwdLen = len(passwords[0])
pwdCount = len(passwords)
i = 0
for pwd in passwords:
# skip a distance based on total size to cover then place a password
maxSkip = length / pwdCount - pwdLen
i += random.randint(maxSkip - 2, maxSkip)
filler = filler[:i] + pwd + filler[i + pwdLen:]
i += pwdLen
return filler
def initScreen(scr):
"""
Fill the screen to prepare for password entry
scr - curses window returned from curses.initscr()
"""
size = scr.getmaxyx()
height = size[0]
width = size[1]
fillerHeight = height - HEADER_LINES
hexes = generateHex(fillerHeight * 2)
hexCol1 = hexes[:fillerHeight]
hexCol2 = hexes[fillerHeight:]
# generate the symbols and passwords
fillerLength = width / 2 * fillerHeight
passwords = getPasswords()
filler = getFiller(fillerLength, passwords)
fillerCol1 = filler[:len(filler) / 2]
fillerCol2 = filler[len(filler) / 2:]
# each column of symbols and passwords should be 1/4 of the screen
fillerWidth = width / 4
# print the header stuff
slowWrite(scr, HEADER_TEXT)
slowWrite(scr, '\nENTER PASSWORD NOW\n\n')
slowWrite(scr, str(LOGIN_ATTEMPTS) + ' ATTEMPT(S) LEFT: ')
for i in xrange(LOGIN_ATTEMPTS):
scr.addch(curses.ACS_BLOCK)
slowWrite(scr, ' ')
slowWrite(scr, '\n\n')
# print the hex and filler
for i in xrange(fillerHeight):
slowWrite(scr, "0x%X %s" % (hexCol1[i], fillerCol1[i * fillerWidth: (i + 1) * fillerWidth]), 1)
if i < fillerHeight - 1:
scr.addstr('\n')
for i in xrange(fillerHeight):
scr.move(HEADER_LINES + i, CONST_CHARS / 2 + fillerWidth)
slowWrite(scr, '0x%X %s' % (hexCol2[i], fillerCol2[i * fillerWidth: (i + 1) * fillerWidth]), 1)
scr.refresh()
return passwords
def moveInput(scr, inputPad):
"""
moves the input pad to display all text then a blank line then the cursor
"""
size = scr.getmaxyx()
height = size[0]
width = size[1]
inputPad.addstr('\n>')
# cursor position relative to inputPad
cursorPos = inputPad.getyx()
inputPad.refresh(0, 0,
height - cursorPos[0] - 1,
width / 2 + CONST_CHARS,
height - 1,
width - 1)
def userInput(scr, passwords):
"""
let the user attempt to crack the password
scr - curses window returned from curses.initscr()
passwords - array of passwords hidden in the symbols
"""
size = scr.getmaxyx()
height = size[0]
width = size[1]
# set up a pad for user input
inputPad = curses.newpad(height, width / 2 + CONST_CHARS)
attempts = LOGIN_ATTEMPTS
# randomly pick a password from the list
pwd = passwords[random.randint(0, len(passwords) - 1)]
curses.noecho()
while attempts > 0:
# move the curser to the correct spot for typing
scr.move(height - 1, width / 2 + CONST_CHARS + 1)
# scroll user input up as the user tries passwords
moveInput(scr, inputPad)
guess = upperInput(scr, False, False)
cursorPos = inputPad.getyx()
# write under the last line of text
inputPad.move(cursorPos[0] - 1, cursorPos[1] - 1)
inputPad.addstr('>' + guess.upper() + '\n')
# user got password right
if guess.upper() == pwd.upper():
inputPad.addstr('>Exact match!\n')
inputPad.addstr('>Please wait\n')
inputPad.addstr('>while system\n')
inputPad.addstr('>is accessed.\n')
moveInput(scr, inputPad)
curses.napms(LOGIN_PAUSE)
return pwd
# wrong password
else:
pwdLen = len(pwd)
matched = 0
try:
for i in xrange(pwdLen):
if pwd[i].upper() == guess[i].upper():
matched += 1
except IndexError:
pass # user did not enter enough letters
inputPad.addstr('>Entry denied\n')
inputPad.addstr('>' + str(matched) + '/' + str(pwdLen) +
' correct.\n')
attempts -= 1
# show remaining attempts
scr.move(SQUARE_Y, 0)
scr.addstr(str(attempts))
scr.move(SQUARE_Y, SQUARE_X)
for i in xrange(LOGIN_ATTEMPTS):
if i < attempts:
scr.addch(curses.ACS_BLOCK)
else:
scr.addstr(' ')
scr.addstr(' ')
# Out of attempts
return None
def runLogin(scr):
"""
Start the login portion of the terminal
Returns the password if the user correctly guesses it
"""
curses.use_default_colors()
size = scr.getmaxyx()
width = size[1]
height = size[0]
random.seed()
# set screen to initial position
scr.erase()
scr.move(0, 0)
passwords = initScreen(scr)
return userInput(scr, passwords)
def beginLogin():
"""
Initialize curses and start the login process
Returns the password if the user correctly guesses it
"""
return curses.wrapper(runLogin)

View file

@ -1,270 +1,84 @@
import curses
import random
import os
from fallout_functions import slowWrite
from fallout_functions import INPUT_PAUSE
from fallout_functions import TYPE_DELAY
from fallout_functions import upperInput
from fallout_functions import HIDDEN_MASK
################## text strings ######################
HEADER_TEXT = 'ROBCO INDUSTRIES (TM) TERMLINK PROTOCOL'
HEADER_TEXT = 'WELCOME TO ROBCO INDUSTRIES (TM) TERMLINK'
PASSWORD_PROMPT = 'ENTER PASSWORD NOW'
PASSWORD_ERROR = 'INCORRECT PASSWORD, PLEASE TRY AGAIN'
################## global "constants" ################
# number of characters for hex digits and spaces
CONST_CHARS = 16
# position of the attempt squares
SQUARE_X = 19
SQUARE_Y = 3
LOGIN_ATTEMPTS = 4
HEADER_LINES = 5
# amount of time to pause after correct password input
LOGIN_PAUSE = 3000
# starting number for hex generation
START_HEX = 0xf650
# list of possible symbols for password hiding
SYMBOLS = '!@#$%^*()_-+={}[]|\\:;\'",<>./?'
ENTRY = 'LOGON '
################## functions #########################
def generateHex(n):
def runLogin(scr, hardMode, username, password):
"""
generates n numbers starting at START_HEX and increasing by 12 each time
"""
num = START_HEX
list = []
for i in xrange(n):
list.append(num)
num += 12
return list
Start the login process
def getSymbols(n):
"""
return n random symbols
"""
count = len(SYMBOLS)
result = ""
for i in xrange(n):
result += SYMBOLS[random.randint(0, count - 1)]
return result
def getPasswords():
"""
Returns an array of strings to be used as the password and the decoys
"""
groups = []
# script file / password file location
__location__ = os.path.realpath(os.path.join(os.getcwd(),
os.path.dirname(__file__)))
# read from passwords.txt
with open(os.path.join(__location__, "passwords.txt")) as pwfile:
for line in pwfile:
if not line.strip():
groups.append([])
elif len(groups) > 0:
groups[len(groups) - 1].append(line[:-1])
passwords = groups[random.randint(0, len(groups) - 1)]
random.shuffle(passwords)
return passwords
def getFiller(length, passwords):
"""
Return a string of symbols with potential passwords mixed in
length - the length of the string to create
passwords - an array of passwords to hide in the symbols
"""
filler = getSymbols(length)
# add the passwords to the symbols
pwdLen = len(passwords[0])
pwdCount = len(passwords)
i = 0
for pwd in passwords:
# skip a distance based on total size to cover then place a password
maxSkip = length / pwdCount - pwdLen
i += random.randint(maxSkip - 2, maxSkip)
filler = filler[:i] + pwd + filler[i + pwdLen:]
i += pwdLen
return filler
def initScreen(scr):
"""
Fill the screen to prepare for password entry
scr - curses window returned from curses.initscr()
"""
size = scr.getmaxyx()
height = size[0]
width = size[1]
fillerHeight = height - HEADER_LINES
hexes = generateHex(fillerHeight * 2)
hexCol1 = hexes[:fillerHeight]
hexCol2 = hexes[fillerHeight:]
# generate the symbols and passwords
fillerLength = width / 2 * fillerHeight
passwords = getPasswords()
filler = getFiller(fillerLength, passwords)
fillerCol1 = filler[:len(filler) / 2]
fillerCol2 = filler[len(filler) / 2:]
# each column of symbols and passwords should be 1/4 of the screen
fillerWidth = width / 4
# print the header stuff
slowWrite(scr, HEADER_TEXT)
slowWrite(scr, '\nENTER PASSWORD NOW\n\n')
slowWrite(scr, str(LOGIN_ATTEMPTS) + ' ATTEMPT(S) LEFT: ')
for i in xrange(LOGIN_ATTEMPTS):
scr.addch(curses.ACS_BLOCK)
slowWrite(scr, ' ')
slowWrite(scr, '\n\n')
# print the hex and filler
for i in xrange(fillerHeight):
slowWrite(scr, "0x%X %s" % (hexCol1[i], fillerCol1[i * fillerWidth: (i + 1) * fillerWidth]), 1)
if i < fillerHeight - 1:
scr.addstr('\n')
for i in xrange(fillerHeight):
scr.move(HEADER_LINES + i, CONST_CHARS / 2 + fillerWidth)
slowWrite(scr, '0x%X %s' % (hexCol2[i], fillerCol2[i * fillerWidth: (i + 1) * fillerWidth]), 1)
scr.refresh()
return passwords
def moveInput(scr, inputPad):
"""
moves the input pad to display all text then a blank line then the cursor
"""
size = scr.getmaxyx()
height = size[0]
width = size[1]
inputPad.addstr('\n>')
# cursor position relative to inputPad
cursorPos = inputPad.getyx()
inputPad.refresh(0, 0,
height - cursorPos[0] - 1,
width / 2 + CONST_CHARS,
height - 1,
width - 1)
def userInput(scr, passwords):
"""
let the user attempt to crack the password
scr - curses window returned from curses.initscr()
passwords - array of passwords hidden in the symbols
"""
size = scr.getmaxyx()
height = size[0]
width = size[1]
# set up a pad for user input
inputPad = curses.newpad(height, width / 2 + CONST_CHARS)
attempts = LOGIN_ATTEMPTS
# randomly pick a password from the list
pwd = passwords[random.randint(0, len(passwords) - 1)]
curses.echo()
while attempts > 0:
# move the curser to the correct spot for typing
scr.move(height - 1, width / 2 + CONST_CHARS + 1)
# scroll user input up as the user tries passwords
moveInput(scr, inputPad)
guess = scr.getstr()
cursorPos = inputPad.getyx()
# write under the last line of text
inputPad.move(cursorPos[0] - 1, cursorPos[1] - 1)
inputPad.addstr('>' + guess.upper() + '\n')
# user got password right
if guess.upper() == pwd.upper():
inputPad.addstr('>Exact match!\n')
inputPad.addstr('>Please wait\n')
inputPad.addstr('>while system\n')
inputPad.addstr('>is accessed.\n')
moveInput(scr, inputPad)
curses.napms(LOGIN_PAUSE)
return True
# wrong password
else:
pwdLen = len(pwd)
matched = 0
try:
for i in xrange(pwdLen):
if pwd[i].upper() == guess[i].upper():
matched += 1
except IndexError:
pass # user did not enter enough letters
inputPad.addstr('>Entry denied\n')
inputPad.addstr('>' + str(matched) + '/' + str(pwdLen) +
' correct.\n')
attempts -= 1
# show remaining attempts
scr.move(SQUARE_Y, 0)
scr.addstr(str(attempts))
scr.move(SQUARE_Y, SQUARE_X)
for i in xrange(LOGIN_ATTEMPTS):
if i < attempts:
scr.addch(curses.ACS_BLOCK)
else:
scr.addstr(' ')
scr.addstr(' ')
# Out of attempts
return False
def runLogin(scr):
"""
Start the login portion of the terminal
hardMode - boolean indicating whether the user has to enter the username
and password or if they are entered automatically
username - the username to log in
password - the password to log in
Returns true if hardMode == false or if the user entered the correct string
"""
curses.use_default_colors()
size = scr.getmaxyx()
width = size[1]
height = size[0]
random.seed()
# set screen to initial position
scr.erase()
scr.move(0, 0)
passwords = initScreen(scr)
return userInput(scr, passwords)
curses.noecho()
scr.scrollok(True)
slowWrite(scr, HEADER_TEXT + '\n\n')
if hardMode:
# use must enter the correct text to proceed
entry = ''
while entry.upper() != ENTRY.upper() + username.upper():
slowWrite(scr, '> ')
entry = upperInput(scr)
else:
# input is entered for them
slowWrite(scr, '> ')
curses.napms(INPUT_PAUSE)
slowWrite(scr, ENTRY + username.upper() + '\n', TYPE_DELAY)
slowWrite(scr, '\n' + PASSWORD_PROMPT + '\n\n')
if hardMode:
# use must enter the correct text to proceed
entry = ''
while entry.upper() != password.upper():
if entry:
slowWrite(scr, PASSWORD_ERROR + '\n\n')
slowWrite(scr, '> ')
entry = upperInput(scr, True)
else:
# input is entered for them
slowWrite(scr, '> ')
curses.napms(INPUT_PAUSE)
password_stars = HIDDEN_MASK * len(password)
slowWrite(scr, password_stars + '\n', TYPE_DELAY)
curses.napms(500)
def beginLogin():
def beginLogin(hardMode, username, password):
"""
Initialize curses and start the login process
Returns true if the user correctly guesses the password
hardMode - boolean indicating whether the user has to enter the username
and password or if they are entered automatically
username - the username to log in
password - the password to log in
Returns true if hardMode == false or if the user entered the correct string
"""
return curses.wrapper(runLogin)
res = curses.wrapper(runLogin, hardMode, username, password)
return res