ingen-lab / Ruth

Project Ruth - an Open Source Mesh Avatar by Shin Ingen
56 stars 38 forks source link

Fred's Encryption Scripts #36

Open SundanceHaiku opened 5 years ago

SundanceHaiku commented 5 years ago

I have spent the last couple of weeks working with Fred Beckhusen’s encryption scripts, and I have run across a problem. The problem, however, is not Fred’s. It’s a bug in the underlying OpenSimulator code.

(Fred's Google Plus posting explaining the scripts is found here: https://plus.google.com/+FredBeckhusen/posts/1yuHxzjLayq. The scripts themselves are found in GitHub in the following directory: Ruth\LSLScripts\HUD\Ruth\Fred Beckhusen).

Let me first briefly mention why Fred’s work is important. (I am planning to supplement this with a “white paper” similar to the one I put together on communication, but that’s going to take a while to complete.)

Fred’s scripts are in response to the ease in which dishonest people can rip off textures from Ruth. The security holes that we are dealing with are both in the Skin Applier and the Ruth body. It involves easily attainable texture UUID’s.

In-world textures are never perfectly safe, but mesh developers, using the tools available to them, have created one or more approaches to make it difficult to obtain UUID’s. While not perfect, developers have been able to provide a reasonable level security which has become something of a quasi standard accepted by creators.

Currently, Ruth is not meeting this standard. Anyone with a modicum of knowledge of LSL can extract UUID's, enhance them in a graphics program, and bring them back in-world with a different UUID.

Let me move to Fred's code . . .

Fred’s use of XTEA Encryption is nicely written and well thought out. I did find one small oversight. There is one line which needs to be removed. It's line 77 found in the r2HUD_sa_trigger.lsl script and reads as follows:

llSay(r2chan,message);  

The llSay command found on line 77 has already been executed on line 209 in the XTEA Encyption script (XTEA.lsl). That line reads as follows:

llSay((integer) channel, xtea_encrypt_string(message)); 

In other words, the message is being sent to the body receiver twice. Line 77 actually creates an interesting situation if you are debugging the scripts. The scripts use llMessageLinked to communicate with the XTEA script. Because llMessageLinked can have up to a delay of .5 seconds, line 77 ends up sending the message before it is encrypted – which, of course, we don’t want. Rather we want to send an encrypted message. Fred may have been using the line for testing and accidentally left it in. It is an easy fix. Removing the line solves the problem.

But the main problem is the llBase64ToString function. It is used on line 159 in the XTEA script and is the last step in decryption process. Here’s the line:

 return llBase64ToString(result);

Unfortunately, the llBase64ToString function is not performing correctly and adds as many as 30 or more unprintable characters to the tail end of the returned variable. The number of unprintable characters varies depending on the message. Because of this malfunction, the receiving routine in the body (r2_body_receiver.lsl), is unable to process the UUID and nothing happens.

It's a bug in Open Sim, but not in Second Life.

I've tried all sorts of options and work-arounds to try fix this. The first fix that naturally comes to mind is to use the following code:

message = llStringTrim(message, STRING_TRIM);  

But this function won't remove unprintable characters. The other possibility is llDeleteSubString, but you need to know the exact length of message. And here another problem arises: llStringLength is inaccurate when unprintable characters are involved. Let me repeat that because it totally threw me: llStringLength doesn't give you the correct length when unprintable characters are part of the string.

The length of the string is a pretty important number to know if one is trying to devise a work-around. I tried all sorts of options over a period of several days to find a way around the bug. I was finally able to trim off the unprintable characters by using llDeleteSubString, but I could only do it by using trial and error and could not find a programmatic way of doing it.

This is clearly a bug because it works in Second Life and doesn’t work in OpenSim. Here’s what the Second Life LSL Wiki says about llBase64ToString function: "If the conversion creates any unprintable characters, they are converted to spaces." If spaces are tacked on the end, then llStringTrim would be an easy solution, but that’s not happening.

Anyone have any ideas on how to deal with this?

mdickson commented 5 years ago

Really awesome catch and yes, it's going to be impossible to fix since there are so many different versions and flavors of OpenSim floating around.

I did secure appliers for IW and used a different encryption mechanism that was supplied there. I can have a look but your analysis seems sound and I agree its going to be really hard to fix.

Outworldz commented 5 years ago

It's supposed to be extra bits, not bytes. "If extra bits are needed to complete the last base64 symbol, those extra bits will be zero."

SundanceHaiku commented 5 years ago

Fred suggested using the llGetSubstring function. Yes! That will work because we do know the length of a UUID is 36 characters. It's just a matter of pulling out the first 36 characters. That results in the removal of the unprintable characters causing the problem.