This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
RoD's profile picture

Program Security

Started by RoD, 13 May 2014 - 07:38 PM
RoD #1
Posted 13 May 2014 - 09:38 PM
My goal, just like the other advanced programmers is to have a really secure code and hard to hack. For this, i test all my codes as if i was the attacker.
I have done a lot of research and to hack the following program, a password cracker was the only way:

--SERVER

pass = "testpass123"

function listen()
	   rednet.open("right")
	   while true do
			  local event, p1, p2, p3 = os.pullEvent()
			 
			  if event == "rednet_message" then
					 --local id, mess = rednet.receive()
					 if p2 == pass then
						    rednet.send(p1, true)
					 else
						    rednet.send(p1, false)
					 end
			  elseif event == "char" then
					 if p1 == "r" then
						    shell.run( shell.getRunningProgram() )
					 else
					 print( pass )
					 end
			  end
	   end
end
term.clear()
term.setCursorPos(1,1)
print("Running...")
listen()

So, can a hacker get the password apart from using a cracker? Thanks in advance.
Yevano #2
Posted 13 May 2014 - 10:00 PM
So, can a hacker get the password apart from using a cracker? Thanks in advance.

Yes. If some other real client sends the password to the server, the hacker could easily listen for the message which is being sent entirely in plaintext.
RoD #3
Posted 13 May 2014 - 10:11 PM
But a real client will send the password only to the server. Being a hackerPC——server there is no way of the server "leak" the password out of it, isn't it?
gezepi #4
Posted 13 May 2014 - 10:14 PM
Using the Modem API a computer can listen on any channel. If the id of the server computer is already known it would be easy to capture all of the messages. Otherwise you'd have to open a lot of channels at once or cycle through until you got something interesting.
Edited on 13 May 2014 - 08:15 PM
RoD #5
Posted 13 May 2014 - 10:33 PM
That is a flaw in the general rednet programs that people make. Thanks for pointing that out, i may create a sort of protocol or validation system to prevent it.
But if the attacker wants to find a specific password in the server, he will not wait for the client to send his password to the server (he can, with maybe a rednet logger). But anyways that is a huge help in my programs security. Thanks
albrat #6
Posted 14 May 2014 - 11:04 AM
I would say the best way to prevent a random computer from password finding on your server… Would be to list all your client computers in your server program.

eg.

serid = { 12,15,17,19,23,25 }
Then when you get a rednet message you run a little check on the list.

eg.


onlist = false
for chk, #serid, 1 do
  if serid(chk) = p1 then onlist = true break
end

if onlist == false then rednet.send(p1, "not on access list") end

if onlist == true then -- Check if our request is from a pc on our list.
  if p2 == pass then
	rednet.send(p1, true)
  else
	rednet.send(p1, false)
  end
end



I also have a log on the server that records failed attempts to login and the password they tried. (only on failed attempts) it also logs the Id of the computer, so I can ban the id from the server.
theoriginalbit #7
Posted 14 May 2014 - 11:41 AM
is everyone forgetting the disk drive + startup disk combo? if you're storing passwords in plaintext (assuming no block protection) there's ALWAYS a method of getting it…

if you're massively concerned about it here's what I'd do… account modification and addition can only be added locally on the server machine… passwords are hashed and stored on the drive… client gets username and password, requests server for the hashed password matching the supplied username… server responds with either an error (if user doesn't exist) or with the hashed password… client hashes the user's input and compares against the server's response… even this approach has holes in it, however forcing account control to only be on the server means that the only distribution of passwords is in hashed form, something that is far more difficult for an intercepting computer to interpret.

you can try and prevent unauthorised computers from communicating with you until you're blue in the face, but there'll always be a way for them to communicate with you, you're best bet is to just reduce the amount of useful things they can do with the communications. for example in the above scenario I gave you all they can do is poll for passwords given random usernames from the server or send dummy data to make the client reject a login (which having the client go 'oh, okay' and type their password again could mitigate that, depending on how the intercepting program works)
Edited on 14 May 2014 - 09:44 AM
H4X0RZ #8
Posted 14 May 2014 - 02:50 PM
I would say the best way to prevent a random computer from password finding on your server… Would be to list all your client computers in your server program.

eg.

serid = { 12,15,17,19,23,25 }
Then when you get a rednet message you run a little check on the list.

eg.


onlist = false
for chk, #serid, 1 do
  if serid(chk) = p1 then onlist = true break
end

if onlist == false then rednet.send(p1, "not on access list") end

if onlist == true then -- Check if our request is from a pc on our list.
  if p2 == pass then
	rednet.send(p1, true)
  else
	rednet.send(p1, false)
  end
end



I also have a log on the server that records failed attempts to login and the password they tried. (only on failed attempts) it also logs the Id of the computer, so I can ban the id from the server.
That wouldn't really work, a computer can tell another computer a fake id… If you know the ID of a client, the hacker could tell the server he is using this client and could gain access this way.
RoD #9
Posted 14 May 2014 - 10:04 PM
what freack said is true.. you can use the modem api to change the reply id. About the disk startup combo: i had already tought of that. Thes code that i have is just to add to a program that already has a way of preventing disk boot (not 100% secure, unless you are in a server where there is a block protection plugin ( the house plugin or whaterver it is called ) because the computer will alaways boot from the disk that is hidden and no one could acess it ). Thanks for the server-client explanation.
theoriginalbit #10
Posted 15 May 2014 - 02:59 AM
the computer will always boot from the disk that is hidden.
so I'm assuming you've placed it on the top of the computer then?

Thanks for the server-client explanation.
no problems.
RoD #11
Posted 15 May 2014 - 05:43 PM
the computer will always boot from the disk that is hidden.
so I'm assuming you've placed it on the top of the computer then?

Thanks for the server-client explanation.
no problems.
There is a disk in the disk drive in the back, with a startup file in it that will run what i want it to run.
BTW, i was thinking of encryptions and i came up with this scenarios:

The client gets the password and encrypts it. Sends the encrypted password into the server. The server decrypts it and returns to the client if the loggin was successful or not. Flaw: a hakcer can listen in the server channel, and make his own "client" wich will send the password already encrypted, and the server will think that its a client that is sending a password that was typed in in the client but was actually stolen.

The client gest the password and encrypts it. Sends the encrypted password into then server. The server don't decrypt the password, and compares with the encrypted password in the "database". Flaw: the hacker can do the same as above and send a encrypted message stolen, while listening on the server channel (when i say server channel i mean all possible channels, because the hacker will open every channel he can, until he can't open more), after he sends the encrypted message the server will compare and returns to the hacker if the loggin was successful or not.

So basicaly, even if i want to encrypt the password for security reasons, the security don't change.
flaghacker #12
Posted 15 May 2014 - 06:56 PM
You can give both computers an algorithm to use something variable and the same for every computer (like os.getTime()) and then compare it on the server side. You can even let the server send the (random) algorithm key to the client, that then gets combined with os.getTime(). Much safer than this you're not going to get in computercraft.
Edited on 15 May 2014 - 04:56 PM
Lyqyd #13
Posted 15 May 2014 - 07:48 PM
You'd be better off having the server store the hashed password. The server generates a temporary salt and sends it to the client, then appends it to a copy if the hashed password. It hashes the combined hash + session salt and waits to compare it to the client response. The client hashes the input password, then appends the session salt from the server and hashes the resulting string. The client then sends the final hash to the server for verification. That way, no information that would be useful a second time is transmitted.
RoD #14
Posted 17 May 2014 - 02:52 PM
You can give both computers an algorithm to use something variable and the same for every computer (like os.getTime()) and then compare it on the server side. You can even let the server send the (random) algorithm key to the client, that then gets combined with os.getTime(). Much safer than this you're not going to get in computercraft.
This is actually pretty safe, and by doing:

key = os.time()..os.day()
hash = crypt.encrypt(pass, key)
I can use a key that will work only once. Thanks :D/>

You'd be better off having the server store the hashed password. The server generates a temporary salt and sends it to the client, then appends it to a copy if the hashed password. It hashes the combined hash + session salt and waits to compare it to the client response. The client hashes the input password, then appends the session salt from the server and hashes the resulting string. The client then sends the final hash to the server for verification. That way, no information that would be useful a second time is transmitted.
That is a good way as well, i am trying that in my program. Thanks :)/>
theoriginalbit #15
Posted 17 May 2014 - 03:47 PM
You'd be better off having the server store the hashed password. The server generates a temporary salt and sends it to the client, then appends it to a copy if the hashed password. It hashes the combined hash + session salt and waits to compare it to the client response. The client hashes the input password, then appends the session salt from the server and hashes the resulting string. The client then sends the final hash to the server for verification. That way, no information that would be useful a second time is transmitted.
so that's basically what I suggested, but with the addition of using a salt.
CCGrimHaxor #16
Posted 17 May 2014 - 03:51 PM
What I would suggest is using a security that you only have like 5 or 3 attempts before it blocks you.

But to make it that much more difficult make it count attempts and if he passed the limit and finally gets the correct code you send him that the code is incorrect and block him.
And make it so only an administrator of that pc can remove a person from blocked.
In this case it is 99.9% harder to crack.