Password Protection Using a dynamic keyboard
Problem solved. (Except if you have the NSA after you.)
On an online game they implement a similar, but much waeker method to protect your pin.
The Effect:
1. You lock your computer using the ahk code
2. You wake your computer
3. A 4x4 array of buttons pop up (or symbols)
4. The program takes a few milliseconds to scrample the board, putting the numbers in random spots.
5. Four times a second, a random character is selected and moved to a new spot.
For someone to effectively to hack this, a hacker must do one of the following:
1. get in to your system memory, search the whole ram for your password. (Password changing helps hackers here, and AutoHotkey isn't very effecive at hiding values in the memory)
2. take a picture of your screen twice a second, time each mouse click/release and location, store matches and somehow do this without freezing your computer or having a video camera in plain sight.
If someone were to find a way to encrypt each keystroke, they'd be awesome.
Below here Ill post each version leading up to the one described above.
I made a mistke posting eash version, Sorry moderators
You could simplify the code a little, though. Below is a version of your first script, which is easier to use. At first, after the keypad is shown, 16 random pairs of key names are swapped. When the user presses a button, it is stored, and the keys are randomized again.
If you use a CRT monitor, detecting the EM radiation allows the screen content to be reconstructed in real time (with the mouse pointer), even on the other side of a wall. In this case fast changing keys don't help, but finding the one you need to press next is a challenge. Flat panel displays are not known to be vulnerable to this kind of side channel leakage, so only when you have one, trust this key entry. (If you want continuously changing key names, let the loop run infinitely, with Sleep 500 in it, and make the xx: subroutine only store the key: "o = %o%%A_GuiControl%".)
Another little improvement could be to hash the digits as they arrive, and only store the hash value (to be compared to the hash of the password et the end). Occasional memory inspections leak less. However, if an attacker is able to see the memory periodically, he might as well patch the code in memory to accept any password as valid, so we gain not much. To prevent that we need a background code integrity check, memory protection, etc. They can only be done reliably with extra HW. One component of this is the TPM chip found in many new laptops.
SetFormat Integer, HEX ; for hex keypad Loop 16 { i := A_Index - 1 StringReplace j,i,0x Gui Add, Button, % "x" 8+(i&3)*40 " y" 7 + (i>>2)*40 " w30 h30 gxx", %j% } Gui Add, Button, x8 y167 w70 h30, ENTER Gui Add, Button, x88 y167 w70 h30, CLEAR Gui Show, h204 w166, pwd xx: o = %o%%A_GuiControl% ; store selected digit Loop 16 { i := A_Index - 1 Random j, 0, 15 ; random hex digit = keypad key StringReplace i, i, 0x StringReplace j, j, 0x GuiControl,,%i%,x GuiControl,,%j%,%i% ; swap key names i and j GuiControl,,x,%j% } Return ButtonClear: o = Return ButtonEnter: MsgBox %o% ; <-- add here code to process the password GuiEscape: GuiClose: Gui Destroy ExitApp
Im going to put many different types of my code online in one final master version beacuse of simple differences in opinion which I dont want to argue.
http://stokes91.goog....com/autohotkey
Please feel free to post updates to a code to make it smaller, simpler, or better.
Why not? We may all learn something from arguments. Btw, if you like short code, you could save a few more lines. This version handles any number of keys, like the whole alphabet:differences in opinion which I dont want to argue
keys = 0123456789ABCDEFGHIJKLMNOP Loop Parse, keys Gui Add,Button,% "x" 8+Mod(A_Index-1,4)*40 " y" 7+(A_Index-1)//4*40 " h30 w30 gxx",%A_LoopField% Gui Add, Button, x8 w70 h30, ENTER Gui Add, Button, x88 yp wp hp, CLEAR Gui Show,,pwd xx: o = %o%%A_GuiControl% ; store selected key Loop Parse, keys { Random r,1,StrLen(keys) ; random keypad key StringMid r, keys, r, 1 GuiControl,,%A_LoopField%,x GuiControl,,%r%,%A_LoopField% GuiControl,,x,%r% ; swap key names } Return ButtonClear: o = Return ButtonEnter: MsgBox %o% ; <-- add here code to process the password GuiEscape: GuiClose: Gui Destroy ExitApp
heres a text version: (not code)
wait until password dialog opens.
loop until window is closed:
wait for 200milliseconds -for board to scramble
take a screenshot, save to file
wait until mouse click
save coordinates pressed in file
process image and extract key pressed
On the other hand, the attacker can trigger a hotkey at mouse clicks (~LButton), in the keypad window. It is easy to get the screen pixels around the pointer, even the text of the active control, so the password can be directly sniffed. It does not help, if the button texts change constantly.
For improved security we have to hide the keypad window from the attacker. How about giving it a name and class of existing windows, like the Program Manager? (The attacker can still find our keypad, because he can save the ID of the real program manager, and compares this with the ID's of other similarly named windows.) We can do random clicks all over the keypad, so fast that the user is not disturbed, and the password sniffer is overwhelmed with the large number of fake clicks? (The sniffer could distinguish between physical and generated clicks, unless we do it in the device driver level). We need more ideas!
This attack can be programmed in AHK, but needs a little improvement, because you cannot save a screenshot to a file 5 times a second.
Nor can the average user enter numbers. :wink:
Note: I put "wait until mouse click" to stop that from happening.
--
Good ideas abot the naming, yet wouldn't windows have a problem with me naming the window something like "Windows Task Manager"? I might be wrong, but I'm not too excited about going to court at age 14.
--
Oh, maybe I could put in a code that checks for other open programs and tells the user of the potential problem ex:
[inside a msgbox]
Enigma has detected you have 3 open program(s).
Their process names are:
MSWORD.EXE
firefox.exe
PWsniffr.exe
Please terminate theese programs before reloading Enigma.
Once theese are closed, you can add/allow safe programs.
[OK]
Because windows has many processes that are valid, It could be possible to make a hashed safe list, that a user could see and edit from a settings window, sort of like Windows firewall.
But, how would you stop a malicious program from adding itself to the safe list? Aha! I could not modify the settings because it would be stopped by the above dialog! (Unless if it were to use the same name or something)
Another fix! Somehow find how much disk space the exe has or some of its properties. And make sure there is only one file with that name (using a periodic search of the hd) - would be difficult and time consuming, so maybe find a way to get the exact location of a running exe.
so for a hacker to get in they might need to make a file named firefox.exe with a size of 6.84mb and also remove or replace the old one!
a good solution?
--
english version of hypothetical code:
get all names of running proccesses
hash names and check angainst goodexes.txt
(if possible)get locations of running processes
hash full paths and check anginst goodpaths.txt
(again if possible)get file sizes
hash, check if hash is included in a file
if there are files that do not match a hash,
alert user
close program
--
{update}
Thanks Laszlo for the great simplification of my gui, It made it possible for me to put 3 different layouts (10[numeric] 16[hex] 36[alpha numeric]) all into ~40 lines.
Gui- COMPLETE
changing methods- ALMOST
Settings mgr- NOT STARTED
Hacker/Spyware detection- NOT STARTED- more ideas?
This was the reason I suggested to freeze the keypad after a shuffle. Otherwise, when I find the next digit to be entered, it moves, what drives me crazy. And making a screenshot at a mouse click defeats the constant shuffling, so why bother?Nor can the average user enter numbers
There are different ways to proceed. We can try to hide our password entry keypad from a possible sniffer, or we can try to catch it in action. For hiding:
Most of these window titles are not trademarked. E.g. "Program Manager" is safe, like "ahk_class Progman". However, you have a good point with the process name: the sniffer can find the name and size of the executable having opened the keypad window, so it has to be named accordingly. The size of the executable is easy to be adjusted (append some junk).wouldn't windows have a problem with me naming the window something like "Windows Task Manager"?
The location of the executable still blows our cover. It gets complicated:
- Rename the Windows program manager to something else
- Copy the keypad program to the Windows directory, named progman.exe
- Execute it
- Rename the keypad program
- Give the Windows program manager its original name back.
Renaming running programs might not be easy, but we hid our keypad a little better.
Another alternative to think about is to generate a random window name and the filename of the executable of the keypad function, with setting the file creation time to a fake random date in the past. The sniffer will not know, what to look for.
However, if the sniffer monitors disk activities, both of these methods can be broken. Freshly created new files and new windows appearing soon after, tell tale.
Without hardware support all what we can hope for is making life harder for the bad guys.
I am not sure I understand your points about the safe list. Do you want the password entry program to check if a password sniffer is running and scream if an unknown process is found?
Use digital signatures. To be secure, we need a TPM chip on the motherboard (or some other HW).But, how would you stop a malicious program from adding itself to the safe list?
There are many processes running. In my laptop Task Manager reports 77 of them. I have no idea what most of them do. But we can still create a task monitor, and pop up a warning, when an unknown task appears. At this point the user can allow it to run this time only, add to the safe list or terminate it. Writing this is a lot of work. Do you want to give it a try?
If we can control what is executed, we still miss buffer over-runs, when, for example, a too long email subject line overwrites some executable part of an email program. It is on the safe list, but does now really bad things. There are similar other vulnerabilities, like pictures containing code (meant for image rendering, but misused as virus), Word documents containing malicious macros, etc. When they get executed no new process is started (the browser showing the picture or the macro interpreter of Word are already allowed to run). We can find many of these suspicious programs, but it is an arms race: the bad guys constantly figure new ways to smuggle in malicious code to my PC.
I am not sure I understand your points about the safe list. Do you want the password entry program to check if a password sniffer is running and scream if an unknown process is found?
sorry if I was vague but, basically it would do an initial check (first run- after installation) of all processes running and ask the user which ones are safe to be open during password entry, (just in case if Eve's programs are running). Once a list is made of running process properties (static ex. name, location, size, modification?, created?, makers), the list is hashed a bit, and put into a text document.
Any loads after that (during password entry or setting modification) , the code will check the processes again hash and compare to the older hash.
What if Eve's process gained control of Bob's computer? Would it be safe?
Maybe. Eve would need to find a way to let Bob open the code without the her unapproved process apperaring open. Many ways to do this, but the easiest would be as you said in a different direction, change the names and size.
Btw, that might be useful for a moderate hacker. And unbreakable to a new hacker who doesnt know the limits of non-hardware upgraded computers. (They might not know how it [their software] is found.)
Preliminary Code:
gosub,GetProcessInfo msgbox,%allnames% return GetProcessInfo: allnames= DllCall( "advapi32.dll\LookupPrivilegeValueA", "uint", 0, "str", "SeDebugPrivilege", "int64*", luid_SeDebugPrivilege ) Process, Exist pid_this := ErrorLevel DllCall( "OpenProcess", "uint", 0x400, "int", false, "uint", pid_this ) DllCall( "advapi32.dll\OpenProcessToken", "uint", hp_this, "uint", 0x20, "uint*", ht_this ) VarSetCapacity( token_info, 4+( 8+4 ), 0 ) EncodeInteger( 1, 4, &token_info, 0 ) EncodeInteger( luid_SeDebugPrivilege, 8, &token_info, 4 ) EncodeInteger( 2, 4, &token_info, 12 ) DllCall( "advapi32.dll\AdjustTokenPrivileges", "uint", ht_this, "int", false, "uint", &token_info, "uint", 0, "uint", 0, "uint", 0 ) if A_OSVersion in WIN_95,WIN_98,WIN_ME { MsgBox, This Windows version (%A_OSVersion%) is not supported. } pid_list_size := 4*1000 VarSetCapacity( pid_list, pid_list_size ) status := DllCall( "psapi.dll\EnumProcesses", "uint", &pid_list, "uint", pid_list_size, "uint*", pid_list_actual ) ;if ( ErrorLevel or !status ) ; return total := pid_list_actual//4 r_pid_list= address := &pid_list loop, %total% { p_pid := ( *( address )+( *( address+1 ) << 8 )+( *( address+2 ) << 16 )+( *( address+3 ) << 24 ) ) h_process := DllCall( "OpenProcess", "uint", 0x10|0x400, "int", false, "uint", p_pid ) name_size = 255 VarSetCapacity( name, name_size ) result := DllCall( "psapi.dll\GetModuleFileNameExA", "uint", h_process, "uint", 0, "str", name, "uint", name_size ) DllCall( "CloseHandle", h_process ) if name != allnames=%allnames%`n%name% address += 4 } DllCall( "CloseHandle", "uint", ht_this ) DllCall( "CloseHandle", "uint", hp_this ) return EncodeInteger( p_value, p_size, p_address, p_offset ) { loop, %p_size% DllCall( "RtlFillMemory", "uint", p_address+p_offset+A_Index-1, "uint", 1, "uchar", p_value >> ( 8*( A_Index-1 ) ) ) }
Try and see if you can get a program to hide from this program, *yawn* its 2:00 (night) right now, but ill keep trying different methods.
I found this code on this forum somewhere, and I tried simplifiying it, but you might have better luck.
I found this problem too, so therefore im trying to make sure the processes open are 'clean' and won't pose a threat.And making a screenshot at a mouse click defeats the constant shuffling, so why bother?
EDIT: Oh I see, what you mean, good question. Ill fix that now. (by making the buttons blank during a click\hover and until (maybe) the shuffling is done.) (don't be scared, I'm making it customizable per person/machine so you could choose to not have the numbers hide or shuffle during entry.
(ONE PROBLEM: What if a program is opened by the user or a 'approved' process?)[Make a periodic check after shuffling?]
EDIT:Another true statement Laszlo, (about the macros and coded imgs), but here I'd hope to trust the user into not allowing email clients, browsers, etc. open.
I see. There are difficulties with this, though.an initial check (first run- after installation) of all processes running and ask the user which ones are safe to be open during password entry
- Macro interpreters, like VB, AHK, even MS Office must not be active, because they take text files (scripts), and execute them. The process name does not tell, what code they run. It is too much to ask: "please close all instances of these dangerous processes". It takes minutes, so users will just ignore your request.
- I cannot tell which of the 77 active processes are safe in my laptop. Most users would not be able to select the bad ones.
- Many viruses, worms attach themselves to safe looking processes. If they were already infected when you created the safe list, you might allow them to do harm. This is the typical case: an infection occurs once, and from then on, all your passwords could be sniffed.
- With root-kits or similar tools, malware can be hidden. The user does not know if anything suspicious is running already.
Because of these, I would rely on antivirus programs, instead. They do a pretty good job finding malware. However, a custom made sniffer, distributed in a local area network, will not be detected, so it still makes sense to protect yourself from your colleagues (or the IT guys at your work/school).
This is a good idea, maybe with random shuffled keys shown (the user has to remember the last "real" key names when he clicks, and ignoring the ones on screen). If the sniffer makes a screenshot at a mouse click, it will not see anything useful, and an attack becomes much harder. Accordingly, how about this:making the buttons blank during a click\hover
- The keypad keys are continuously changing at random time intervals.
- The user waits a little, and picks the key with the next password digit (in his mind).
- He starts moving his mouse toward that keypad key. At this moment the script memorizes the current key names, change them on screen (and might keep them changing).
- The user ignores the new key names, knowing that while the mouse is moving the changes are only fake. He clicks on the keypad key he picked before he started to move the mouse.
- The script saves the memorized key name as the next password digit.
If these are combined with randomized process names, the sniffer has to make screenshots very frequently, always while the mouse is stationary. At a mouse click, it uses the last saved key names to discover the password, but the identification of the right window is also complicated (need to use the number of controls, their position, etc). This is a lot of work, and there is a chance that the increased processor load reveals the presence of the password sniffer.
This is not a finished script, it is only for experimenting:
- The mouse should not leave the current window, because its movement outside is not detected.
- If the user leaves the mouse on a button, and clicks again, he gets the last saved key name, not the one shown, unless the mouse moves slightly.
keys = 12345678*90# Loop Parse, keys Gui Add,Button,% "x" 8+Mod(A_Index-1,4)*40 " y" 7+(A_Index-1)//4*40 " h30 w30 gxx",%A_LoopField% Gui Add, Button, x8 w70 h30, ENTER Gui Add, Button, x88 yp wp hp, CLEAR Gui Show,,pwd T1 = 0xFFFFFFFF ; 1st mouse move to be detected OnMessage(0x200,"Mouse") ; react to 0x200 = WM_MOUSEMOVE SetTimer Shuffle, 5000 ; start key shuffling GoSub Shuffle ; shuffle now MouseMove 85,120 ; mouse into GUI window RETURN ; end of autoexecute section Shuffle: ; assign random names to buttons Loop Parse, keys { Random r,1,StrLen(keys) ; random keypad key StringMid r, keys, r, 1 GuiControl,,%A_LoopField%,zz GuiControl,,%r%,%A_LoopField% GuiControl,,zz,%r% ; swap key names } Return Mouse() { ; called at mouse move within GUI Global T0:= T1 + 499 T1 = %A_TickCount% IfLess T1,%T0%, Return ; return if mouse is moving SetTimer Shuffle, OFF Loop % StrLen(keys) ; save keynames GuiControlGet Button%A_Index%,,Button%A_Index% GoSub Shuffle ; shuffle now SetTimer Shuffle, ON ; restart shuffling } xx: GuiControlGet x, Focus ; class of GuiControl (Button1, 2..) x := %x% ; get saved keyname o = %o%%x% ; store selected key Return ButtonClear: o = Return ButtonEnter: MsgBox %o% ; <-- add here code to process the password GuiEscape: GuiClose: Gui Destroy ExitApp