Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Do we have a way to make... truly secure scripts?

Charmande Petion
Registered User
Join date: 4 Jan 2006
Posts: 118
08-01-2006 12:20
I have a sphere, and a cube.

The sphere listens on channel -102 for any message, from any key, and repeats whatever message it hears on channel 0.

The cube sends a message on channel -102.

...Let's say I had some complicated scripted objects and I wanted them to be secure, I didn't want other people to be able to mess with the scripts at all, and the objects (they are unlinked, so using llMessageLinked will not work) need to communicate to each other. As far as I can tell, the only thing someone would need to break into my objects would be the channel number, using the sphere I mentioned above.

Also, I may or may not be the owner of the objects, so getting the object owner and owner id will not work here either.

Is there a way to make a truly secure communication script between to objects?
Harris Hare
Second Life Resident
Join date: 5 Nov 2004
Posts: 301
08-01-2006 13:02
This is a simple method for encrypting your messages. A seriously hardcore hacker could probably crack it but it's a good enough to keep the other 99.9% of SL's population from reverse engineering your stuff.

http://secondlife.com/badgeo/wakka.php?wakka=llXorBase64Strings
Charmande Petion
Registered User
Join date: 4 Jan 2006
Posts: 118
08-01-2006 14:48
That is wonderul and just what I needed, if I was the gender you liked I would kiss you. o.o
ed44 Gupte
Explorer (Retired)
Join date: 7 Oct 2005
Posts: 638
08-01-2006 18:53
You've now published your channel number for the benefit of the 0.01 % who might break your product, so pick another channel number anywhere from neg 2 billion to pos 2 billion. And confirm your script permission is no mod ( I think that is the default).
Gaius Goodliffe
Dreamsmith
Join date: 15 Jan 2006
Posts: 116
08-01-2006 22:23
From: ed44 Gupte
You've now published your channel number for the benefit of the 0.01 % who might break your product, so pick another channel number anywhere from neg 2 billion to pos 2 billion. And confirm your script permission is no mod ( I think that is the default).

I wouldn't bother trying too hard to make your channel number secret. It's pretty easy for anyone who truly wants to know it to figure it out. If you want to keep the communications secret, you've got to encrypt the messages.

Anything said with llWhisper/Say/Shout on a fixed channel is effectively public. If you can change channels on the fly, that affords quite a bit of protection, but if you're using a fixed channel number, you might as well publish the info -- you're fooling yourself if you think keeping that number secret is helping you be more secure.
grumble Loudon
A Little bit a lion
Join date: 30 Nov 2005
Posts: 612
08-02-2006 01:00
How can they find the channel number wihtout some sort of scriped scanner?

A scripted scanner would take a long time to scan thrue all he 4 billion possible channels.

also as far as I know the non zero chat and scripts both run on the server and arn't sent to the client.

My money is on the line here as I am using scripts that pay people and comunicate via chat.
Thraxis Epsilon
Registered User
Join date: 31 Aug 2005
Posts: 211
08-02-2006 02:14
If you're using a fixed channel and communicate regularly without encryption... someone can and will most likely find it.


I myself have a system that generates an authentication token every 10 seconds and changes channels every 30 seconds... and this is just for a combat system. If it was something to do with money I'd add in encryption with a key that changed every 30 seconds along with the channel change.
Hank Ramos
Lifetime Scripter
Join date: 15 Nov 2003
Posts: 2,328
08-02-2006 03:42
For the ultimate in security, use a one-time-pad. Basically, use a list of single-use passwords that both systems share. Encrypt each message with that password, and it's impossible to break as long as you never reuse the password again.

My ATM network system used such an encryption mechanism to keep communications secure, and I know that initially Gigas/Second Server (being that I was a co-founder) did as well.
Kage Seraph
I Dig Giant Mecha
Join date: 3 Nov 2004
Posts: 513
08-02-2006 07:16
How does the system handle updating new passwords? Eventually any inworld list will run out. XMLRPC to an external server?
_____________________
Thraxis Epsilon
Registered User
Join date: 31 Aug 2005
Posts: 211
08-02-2006 10:28
Use a Psuedo-Random Number Generator. There is a good example of one on the lslWiki
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
08-02-2006 11:02
Don't forget, there are two parts to secure authentication, and you may only need one. The first part is preventing others from seeing what you're saying, and the second part is being able to trust that a message is coming from who you think it's coming from. Often in LSL, the latter is really the only thing that matters. If you can ensure that your objects will only listen to each other, does it matter if the information they're sharing can be heard by a third party?

There's a simple way to ensure the latter (which is called authentication). First of all, if messages are only going between two objects you own, then you can use llGetOwnerKey() on the key passed as an argument to the listen() event to determine that the script sending the message is owned by you. This is not perfectly secure, in the case that someone manages to get you to run another script that eavesdrops and tries to inject its own messages.

To get more secure authentication, you need both of your scripts to share some password in common. Set it as a global variable. You don't want to send it with every message, because we're assuming that anyone can still eavesdrop on what you send. Instead, a script needs to demonstrate that it knows the password without actually sending it along.

One way to do this is the llMD5String function. This computes a (theoretically) one-way hash on the input, which can be used to "sign" a message. With every message you send, run llMD5String() on the message with the password stuck at the end. The other end will also run llMD5String() on the message it receives with the password it knows about stuck on the end, and if it gets a result that matches yours, it knows that you had the password when you sent the message.

The only problem is that any eavesdropper can get a message that you send, plus the MD5 "signature", and just send that same message again. This can be a security vulnerability in some cases. To mitigate that, you should instead MD5 a string like this: "<my object key>|<password>|<message>". The other end will do the same to check the authenticity of the message. Since (as far as I know), it's impossible in SL to spoof the source of a message that's received in a listen() event, this is much more secure.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
08-02-2006 12:44
If you only want to authenticate (not encrypt), it may be possible for the two objects to establish a trusted relationship once, and then simply only accept messages from each other.

1.) If one object rezzes another this can be done pretty securely (and pretty quickly): the rezzer gets the key of the created object in the 'object_rez' event, so it knows who to trust, and it can send a random number to the rezzed object for the start parameter which it then also sends to the rezzed object on a chat channel. Once the trusted relationship is established it is fixed. This is pretty secure if the whole exchange is done in a timely manner and/or if the rezzed object stops listening after a certain number (in the extreme case, one) of bad authentication attempts are sent its way.

2.) Another good way to establish a trusted relationship is similar to a strategy already mentioned, but is done once instead of for each message: the applicant takes the key of the target, adds a random pad, and encrypts the whole thing using a private key (which can be stored in no-modify scripts, or in a notecard if the object itself is no-modify). This is sent to the target, which then decrypts the message and knows to trust the applicant when the decrypted key matches its own. This relies on a good encryption method, so you may want to use something like ''llModPow()' with a well-generated RSA key (though you are limited to very small key in this system). It is less secure, but you could also use a one-time pad that is calculated from the time or is also sent in clear text. Then you need only a one-way (hash) method rather than both encryption and decryption.

3.) If neither object knows to trust the other from the start, you may have to do a two-way handshake, each direction of which might look like the proceedure in #2. This depends a lot on your application.

Once the trust is established there is no further need of authentication because you get the key of the speaking object directly from the system.

Note that most of the methods that come up here are likely to be rather slow in LSL; they will likely take at least 1-2 seconds if they do any kind of encyption or hashing. So if you are doing anything time-critical it is much better to rely on the two objects simply having the same owner or something. How much security do you REALLY need here?
grumble Loudon
A Little bit a lion
Join date: 30 Nov 2005
Posts: 612
08-02-2006 18:47
I want to converting over to use the following so I can better deal with deeded objects.
But getting the key list is tricky.

CODE

list m_AcceptNames = ["my name","Group name","altName"];
list m_AcceptKeys = [NULL_KEY,NULL_KEY,NULL_KEY];

listen(integer channel, string name, key id, string message){
//name is the name of the object and not the owner name
//id is the id of the object and not the owner id

key OwnerKey = llGetOwnerKey(id); // may not work every time based on sim boundrys

list l_OwnerKey;
l_OwnerKey += OwnerKey;
if (llListFindList(m_AcceptKeys, l_OwnerKey) == -1) { // not found

string OwnerName = llKey2Name(OwnerKey); //only works if owner is in sim
if (OwnerName != "") { //is in sim
list l_OwnerName;
l_OwnerName += OwnerName;
integer Ptr = llListFindList(m_AcceptNames, l_OwnerName);
if (Ptr != -1) { //name in list
list newList = llListReplaceList(m_AcceptKeys,l_OwnerKey ,Ptr,Ptr);
m_AcceptKeys = newList;
//use message
}else{
llInstantMessage(llGetOwner(), "message from "+ OwnerName + ": " + message);
}; //found
}else{
llInstantMessage(llGetOwner(), "message from Object "+ name + ": " + message);
};//Key2name Worked

}else{ //ok

//use message
};

}//listen




The other problem is that I have to rember to uncheck "Share with group" after I deed it to the group to prevent group members from reading the script.

I am also going to use a large "one time pad" to encript what channel the script is moving to next.

I send a lot of messages and can't encript the actual messages, I just need to prevent someone injecting a "Pay" message. Having it check the owner will allow it to keep out most people and having it change channel every hour or so will prevent someone from giving me a bad object.
Gaius Goodliffe
Dreamsmith
Join date: 15 Jan 2006
Posts: 116
08-02-2006 18:57
From: grumble Loudon
How can they find the channel number wihtout some sort of scriped scanner?

Did I say they wouldn't use a scanner? That's certainly how I've always done it.

From: someone
A scripted scanner would take a long time to scan thrue all he 4 billion possible channels.

Not really. Well, long is a relative term. I certainly wouldn't want to sit in front of my computer watching it scan the whole time. That's the sort of thing where I'd want to start it before I go to bed one night and collect the result the next day after work. But that's about as long as it would take.

If I had some helpers, we could do it in a few hours, tops.
grumble Loudon
A Little bit a lion
Join date: 30 Nov 2005
Posts: 612
Wiki?
08-02-2006 19:42
Is there a Wiki page describing overall script security or should I start one?

I see lots of pages describing commands, but no overall page describing security or a "how to"
Alexander Daguerre
Junior Birdman
Join date: 9 Jun 2004
Posts: 32
08-02-2006 23:57
From: Gaius Goodliffe
If I had some helpers, we could do it in a few hours, tops.
If you can check one channel per second, you can pass through all 4 billion channels in 136 years. If the channel you are looking for is only active, say, once every 10 seconds, then to be sure of a channel not being the one you need to listen for at least that long before moving on to the next one. So, 1300 years for a single script checking a single channel at a time. Half this time on average, because that's how these things work.

Even allowing for scripts being able to listen on multiple channels at the same time, you need an awful lot of helpers (multiple scripts, essentially) to pull this kind of thing off. "A few hours, tops" seems like an exaggeration. To bring the completion time down to 24 hours, for example, (average of 12 hours) you'd need to be able to evaluate 49710 channels per second. If channels are only active once every 10 seconds you'd need to be listening to 497103 channels at the same time. That's about 8000 scripts each listening to 64 channels in some theoretical world with infinitely fast simulators. In the real world, you won't be able to cancel and re-establish 50K listens every second anyway.

Security by obscurity is never perfect. But, if you choose a channel in a genuinely random way rather than picking one that just seems random to you, you get something that is at least authentically obscure, and that helps a lot. If you can decrease the frequency of communication on a given channel, you also make the work factor for a sniffer increase proportionally, so you can make it arbitrarily hard for them.

This is all without talking about crypto or channel hopping at all. All I'm saying is that if people are communicating infrequently on a genuinely random channel they are secure against basic sniffing attacks from all but insanely well funded adversaries. If your threat model doesn't include a sim full of hostile scripts running flat out for days, you may feel that just communicating in the clear once in a while on a randomly chosen channel is acceptably secure.
Alexander Daguerre
Junior Birdman
Join date: 9 Jun 2004
Posts: 32
Randomness
08-03-2006 00:11
I should have said something about how to choose genuinely random channels. Don't just pull numbers out of thin air, that just gives you something that is what statisticians call "haphazard", which is practically worthless in crypto contexts.

If you want a genuinely random channel number to use for your Second Life communications, fire up a command prompt on your Mac or Linux machine and say something like this:
CODE
dd if=/dev/random bs=1 count=4 | od -x

The result might look like this:
CODE
4+0 records in
4+0 records out
4 bytes transferred in 0.000040 secs (99864 bytes/sec)
0000000 18b6 e548
0000004

That would translate into the following declaration:
CODE
integer gSekritChannel = 0x18b6e548;

Those who don't have the benefit of a Mac or Linux box should find a trusted friend who has one.

Or, take advantage of the soon-to-be-announced Alexander Daguerre Random Numbers service! Only 1L per random bit! Act now before supplies are exhausted! ;)
nand Nerd
Flexi Fanatic
Join date: 4 Oct 2005
Posts: 427
08-03-2006 05:31
From: Alexander Daguerre
Or, take advantage of the soon-to-be-announced Alexander Daguerre Random Numbers service! Only 1L per random bit! Act now before supplies are exhausted! ;)


CODE

Error! Random bits out of stock. Starting 2-for-1 sale on numerical sequence bits.
0x0000
0x0001
_____________________
www.nandnerd.info
http://ordinalmalaprop.com/forum - Ordinal Malaprop's Scripting Forum
Gaius Goodliffe
Dreamsmith
Join date: 15 Jan 2006
Posts: 116
08-03-2006 07:19
From: Alexander Daguerre
Even allowing for scripts being able to listen on multiple channels at the same time, you need an awful lot of helpers (multiple scripts, essentially) to pull this kind of thing off.

Yup.

From: someone
"A few hours, tops" seems like an exaggeration.

Nope.

From: someone
To bring the completion time down to 24 hours, for example, (average of 12 hours) you'd need to be able to evaluate 49710 channels per second.

Precisely.

From: someone
If channels are only active once every 10 seconds you'd need to be listening to 497103 channels at the same time. That's about 8000 scripts each listening to 64 channels in some theoretical world with infinitely fast simulators. In the real world, you won't be able to cancel and re-establish 50K listens every second anyway.

That would be where you're wrong.
Alexander Daguerre
Junior Birdman
Join date: 9 Jun 2004
Posts: 32
08-03-2006 07:33
From: Gaius Goodliffe
That would be where you're wrong.

Which part of the paragraph you quoted is incorrect?
grumble Loudon
A Little bit a lion
Join date: 30 Nov 2005
Posts: 612
08-03-2006 17:03
I'm going to create a wiki page and capture all the thoughts on the subject.

Edit
http://secondlife.com/badgeo/wakka.php?wakka=ScriptSecurity

You can use llFrand to create random numbers
Bitzer Balderdash
Dazed and Confused
Join date: 21 Dec 2005
Posts: 246
08-04-2006 01:28
From: grumble Loudon
You can use llFrand to create random numbers


Actually, I strongly suspect that you can use llFrand to create pseudo random numbers....

Sorry to be picky, but this is a thread about security and in that context, there is a significant difference.

But I'm still waiting to hear how you can scan four billion channels in a couple of hours....
Thanto Usitnov
Lord Byron wannabe
Join date: 4 Aug 2006
Posts: 68
defeating scanning...
08-04-2006 22:20
Assuming scanning even works, there's a way to defeat it anyway. The Germans knew this in WWII. Coded messages were split into parts, each of which were broadcast over different frequencies, which changed depending on the code key used for that message. Now, I'm guessing that the messages talked about here are going to be rather short, so seperating individual messages over multiple channels seems impractical to me (not to mention the fact that the receiver would have to change channels faster than the sender in order to receive the whole thing). Instead, each message could individually be sent on a different (psuedorandom) channel. This could be accomplished easily by sending the next channel number in every message, where that number would be presumably encryption with the rest of the message, possibly with a second key. Presumably, hashing the little bit of extra text shouldn't take too long, and changing channels would be done after the message has been sent, so that shouldn't add to communication time if messages aren't sent too frequently. All in all, it should be rather quick.

The problems I see with this is that in the case of an object that has to communicate with multiple objects, it would have to listen to multiple channels simultaneously. Of course, the Germans figured out how to do it without real computers some 60 years ago, so I'm sure it can be done now. It would be interesting to see this kind of encryption implemented in SL, if as nothing more than a curiosity.
Delerium Hannibal
Registered User
Join date: 30 Apr 2004
Posts: 28
08-06-2006 02:34
I could be missing the point here, but with all this talk about encrypting, changing channels, etc... a more secure method I THINK would be to eliminate channels altogether and just send e-mails between the objects. Thus no listening in.

Why has this not been mentioned before, or did you guys just get off on a tangent about real world security? You would still have to establish some sort of initial secure key exchange, but once that is done the outside world can pretty much be shut out completely. This could be done even without using chat channels through the method described earlier.

Pass a random int across an object rez call, have the rezzed object take that random number, have the parent e-mail the same random number with it's own key to the child through the object rez event (getting the childs key from there), thus securing communication between the two objects. at that point, the parent automatically has the childs key and only listens to that key, and the child verifies that it's listening to the right parent through the random number confirmation.
Alexander Daguerre
Junior Birdman
Join date: 9 Jun 2004
Posts: 32
08-06-2006 04:03
From: Delerium Hannibal
I could be missing the point here, but with all this talk about encrypting, changing channels, etc... a more secure method I THINK would be to eliminate channels altogether and just send e-mails between the objects. Thus no listening in.
That's true, if you can use inter-prim e-mail it is as far as we know secure against eavesdropping and traffic analysis. That's not the only consideration, though, so amongst the reasons people don't just use e-mail for everything are: the 20-second delay imposed on any script that uses it, requirement to poll for new e-mail, unsuitability for broadcast to multiple recipients, greater resource usage of e-mail over chat and the authentication issue you mention. It's not the perfect primitive by a long shot.

From: Delerium Hannibal
Why has this not been mentioned before, or did you guys just get off on a tangent about real world security?
The original poster's question was about chat, so that's what has been under discussion. I'm not sure what you mean by "real world security" being a tangent, though. The same principles apply everywhere, SL just has some slightly different constraints (regarding cleartext e-mail as secure in any sense would be a pretty dodgy assumption outside Second Life, for example, while on the other side of the balance there isn't much real support for crypto operations in LSL).

From: Delerium Hannibal
You would still have to establish some sort of initial secure key exchange, but once that is done the outside world can pretty much be shut out completely.
A lot of things come down to key management. If you're in a position where you can do key distribution simply then everything else gets a lot easier. For example, if you can agree a secret key between two objects then you can do encrypted chat, and a lot of the attraction of e-mail for real traffic disappears because you don't care if someone is listening to your chat.

From: Delerium Hannibal
Pass a random int across an object rez call, have the rezzed object take that random number, have the parent e-mail the same random number with it's own key to the child through the object rez event (getting the childs key from there), thus securing communication between the two objects. at that point, the parent automatically has the childs key and only listens to that key, and the child verifies that it's listening to the right parent through the random number confirmation.
That sounds like a pretty good authentication protocol if you're lucky enough to be in the situation where one object rezzes another. Your scheme as described ptotects you against malicious traffic being injected into chat (which is indeed sometimes what you're worried about), but you could extend it to give you encryption to protect against eavesdropping as well; it all depends on what you're protecting against. For example, the rezzing prim can easily pass key material across to the rezzed prim in that e-mail.

Using an initial expensive e-mail exchange to set up parameters for later less-expensive chat is pretty similar to the way things like SSL work: expensive public-key operations setting up the conditions for later communications encrypted with less expensive block ciphers.

If you're not in the situation where one object rezzes another, secure key exchange is a lot harder.
1 2