Password on code - what's the best way to obfuscate it?

Dear fellows /.

I’ve been in the need to crate applications which require to make use of
another program which requires authentication. As everyone who has
tried to solve this problem with a script lang (no compiled, what would
be the best term /?), a security concern comes in play.

Where in hell should I put the password /?

Last day I got caught in a philosophical journey thinking about it.
…A password needs a password to be “decrypted”…you can create as many
layers of passwords to obfuscate the previous one , but you will ever
need a password to decrypt all the underlying passwords.

I did not take this subject in the school (:

Some one could share its experiences with ruby to attack this security
issue?
Would be wonderful too if some of you could share your philosophical
thoughts about.

!!! Enjoy its Friday !!!

-r.
rm -rf /usr/bin/rm

On Friday 11 September 2009 08:15:01 am Rodrigo B. wrote:

I’ve been in the need to crate applications which require to make use of
another program which requires authentication. As everyone who has
tried to solve this problem with a script lang (no compiled, what would
be the best term /?), a security concern comes in play.

Where in hell should I put the password /?

Probably the same place you’d put it in a complied language. Consider:

int main() {
char * a = “one two three”;
a = “four five six”;
return 0;
}

Compile that, even strip the result, then run strings on it. I get this:

/lib64/ld-linux-x86-64.so.2
gmon_start
libc.so.6
__libc_start_main
GLIBC_2.2.5
fff.
fffff.
-#
l$ L
t$(L
|$0H
one two three
four five six

If you were “hiding” passwords in C/C++ source, I hope that makes the
point
clearly that they aren’t “hidden” at all. Indeed, it’s the same problem
of any
DRM scheme – if you’re giving your program to a user, and the program
has a
password or key embedded in it, the user can get that key.

To answer your question properly, I have to ask: Who are you trying to
hide
this password from?

If you’re actually going to distribute it to end-users who you don’t
want to
have the key, read the above until it sinks in – you’re not going to
be
able to obfuscate it to where a user can’t figure it out. If this is a
problem,
you’ll have to get more specific – it’s possible there’s a way to make
it more
secure, but it’s not going to involve obfuscation.

If it’s something else, it really depends what you’re doing. For
example, if
your users have that password, but you just don’t want it stored in
plain
text, you might look at interfacing with whatever their local “keychain”
might
be – in OS X, this is Keychain. On Linux, this could be KWallet, or it
could
be gnome-keyring. On Windows, there’s something built in that encrypts
things
using, I believe, the user’s login password.

If this is a web service, and you just don’t want that password in the
repository – understandable, as you might share that code with others
at some
point – separate it out, put it in a config file, make sure that config
file
isn’t in version control and isn’t world-readable, but is somewhere the
app
can get at. For example, if it’s your MySQL password, you could just put
it in
~/.my.cnf and parse that – or, what I used to do, parse that in a
deploy
script, and use it to generate database.yml for Rails.

Oh, and completely unrelated, but your sig:

rm -rf /usr/bin/rm

That’s better written as:

rm -f which rm

And it works just fine. Indeed, if you run “rm -rf /”, it has no
problems
deleting every file on the system, including rm itself and the shell.
This is
because in Unix, a file isn’t removed until its last reference is gone
– that
means all filenames (each file can have multiple names, they’re called
hardlinks), and all open handles (any program that has the file actually
open
for reading/writing).

The ‘rm’ command just removes a link (name) – this usually results in a
file
being deleted, but if a program has it open, the file will still exist
until
the program closes it.

So, rm can rm itself (removing the link), so it looks like rm has been
deleted. Then, when rm exits, the last link to rm is gone, and the
kernel
cleans up the file.

And yes, I did play with this – installed a minimal Linux in a vm, and
did
“rm -rf /” as root, just to see if it would work. It did – I think the
only
things left were mountpoints.

David M. wrote:

On Friday 11 September 2009 08:15:01 am Rodrigo B. wrote:

I’ve been in the need to crate applications which require to make use of
another program which requires authentication. As everyone who has
tried to solve this problem with a script lang (no compiled, what would
be the best term /?), a security concern comes in play.

Where in hell should I put the password /?

Probably the same place you’d put it in a complied language. Consider:

int main() {
char * a = “one two three”;
a = “four five six”;
return 0;
}

Compile that, even strip the result, then run strings on it. I get this:

  1. What does “even strip the result” mean?

  2. What does “run strings on it” mean?

On Sep 12, 2009, at 01:08, 7stud – wrote:

  1. What does “even strip the result” mean?

‘strip’ is a tool for removing all symbols from an object file or
executable. It means that if you try to debug the code you get no
meaningful breakpoints, function names, variable names, etc. On the
other hand, it doesn’t remove any string constants that are used.

  1. What does “run strings on it” mean?

‘strings’ is another tool used to see “strings” in a binary file. It
basically looks through the entire file and when it encounters 4 bytes
in a row that are ASCII characters, it assumes it’s a string and
prints it out. This means it finds a lot of junk that isn’t really a
true string, but it also finds any actual string in the file that’s at
least 4 chars long.

http://unixhelp.ed.ac.uk/CGI/man-cgi?strings
http://unixhelp.ed.ac.uk/CGI/man-cgi?strip

Ben

Thanks for clearing that up, I should’ve been more specific…

On Saturday 12 September 2009 12:15:53 am Ben G. wrote:

On Sep 12, 2009, at 01:08, 7stud – wrote:

  1. What does “even strip the result” mean?

‘strip’ is a tool for removing all symbols from an object file or
executable. It means that if you try to debug the code you get no
meaningful breakpoints, function names, variable names, etc. On the
other hand, it doesn’t remove any string constants that are used.

Right. Basically, it removes so-called “debugging symbols”, returning a
binary
that is smaller, more optimized in theory, but harder to debug. Ubuntu,
at
least, seems to ship stripped binaries, with the debugging symbols
elsewhere.

But the resultant binary is functionally identical. In order for the
program
to run, it needs to have a string somewhere.

  1. What does “run strings on it” mean?

‘strings’ is another tool used to see “strings” in a binary file. It
basically looks through the entire file and when it encounters 4 bytes
in a row that are ASCII characters, it assumes it’s a string and
prints it out. This means it finds a lot of junk that isn’t really a
true string, but it also finds any actual string in the file that’s at
least 4 chars long.

Interesting. I assumed it actually analyzed the binary, somehow…

Of course, you can easily see how one might fool ‘strings’ – something
as
simple as xor’ing the string constant would probably make it seem to be
unprintable characters. But the same thing is going to apply to a
scripted
language – the only difference is that it’s harder for most people to
disassemble a binary and reverse engineer what’s going on, than simply
read
through source code.

I should point out, again, that if the intent is to store a password
inside
your program, such that people with a copy of the program can’t get the
password, this presents roughly the same reverse-engineering difficulty
as DRM,
which is known to be ineffective.

The reason I asked for more details was, maybe we could help rethink the
design, to provide real security, not just obfuscation.

To take a really simple example, suppose I wanted to distribute a
program
which tied into some Amazon S3 storage that I control. I could try to
stick my
Amazon credentials into the program, but then anyone could find them and
delete
everyone’s stuff.

The right solution isn’t to hide them better, it’s to never send those
credentials in the first place. Instead, I can set up a server which
holds my
AWS credentials. The client then pings that server with an S3 request,
the
server signs the request, then S3 knows it’s approved – and the server
can be
smart enough not to let the client delete anything it’s not supposed to.

But to know how to do this right, I’d still have to know what he’s
actually
trying to do.

On Sep 11, 2009, at 10:08 PM, 7stud – wrote:

  1. What does “run strings on it” mean?

Dump anything that seems like strings in otherwise binary data.

$ which strings
/usr/bin/strings
$ strings /usr/bin/strings|head
Usage: %s [-] [-a] [-o] [-t format] [-number] [-n number] [[-arch
<arch_flag>] …] [–] [file …]
%.*s
__text
__TEXT
-arch
missing argument(s) to %s option
unknown architecture specification flag: %s %s
missing argument to %s option
invalid decimal number in option: %s %s
invalid argument to option: %s %s
[…]

Rodrigo B. wrote:

I’ve been in the need to crate applications which require to make use of
another program which requires authentication. As everyone who has
tried to solve this problem with a script lang (no compiled, what would
be the best term /?), a security concern comes in play.

Where in hell should I put the password /?

Option 1: put the password in a config file, and use filesystem
permissions to ensure it is readable to the application but not to
anyone else.

Of course, don’t put the config file with the live password in your
source repository. You can keep a file with dummy passwords in source,
say
config/database.yml.sample

Then when the software is deployed, you do
cp config/database.yml.sample config/database.yml
chmod 400 config/database.yml
vi config/database.yml

(or the equivalent from your automated deployment process) to insert the
real password(s).

Option 2: GPG-encrypt your config file. When the application starts up,
make it prompt the user for the passphrase to decrypt the config. This
is most easily done by piping the config in on stdin, because gpg itself
will prompt for the necessary passphrase.

startup script

gpg --homedir /path/to/config --decrypt /path/to/config.yml.asc | ruby
myapp.rb

application

secret_data = YAML.load($stdin.read)

This is very secure if your passphrase is random enough, but has the
downside that if your machine reboots, it will have to wait for a
passphrase before the application can start.

BTW, I was assuming that your application user doesn’t have
administrative access to the system where the application is hosted.

If they do, all bets are off. For example:

  • They can take a copy of your script, and modify it to add “STDERR.puts
    password” at the appropriate point

  • They can load their own version of Net::HTTP which prints out the
    passwords it is using

  • Unless you’re using HTTPS or digest authentication, they can use
    tcpdump/wireshark to look at the HTTP transaction on the wire, and
    easily see the Authorization: header which contains the cleartext
    username and password

But if you don’t care about those possibilities (*), then you may as
well use any sort of trivial password hiding, such as setting the top
bit in each byte.

[ruby 1.8 example]

passwd
=> “\364\357\360\256\363\345\343\362\345\364”

passwd.size.times { |i| passwd[i] = passwd[i] ^ 0x80 }
=> 10

passwd
=> “top.secret”

[ruby 1.9 example]

passwd = “\364\357\360\256\363\345\343\362\345\364”
=> “\xF4\xEF\xF0\xAE\xF3\xE5\xE3\xF2\xE5\xF4”

passwd.size.times { |i| passwd[i] = (passwd[i].ord ^ 0x80).chr }
ArgumentError: invalid byte sequence in UTF-8
from (irb):2:in ord' from (irb):2:inblock in irb_binding’
from (irb):2:in times' from (irb):2 from /usr/local/bin/irb19:12:in

passwd.force_encoding(“BINARY”)
=> “\xF4\xEF\xF0\xAE\xF3\xE5\xE3\xF2\xE5\xF4”

passwd.size.times { |i| passwd[i] = (passwd[i].ord ^ 0x80).chr(“BINARY”) }
=> 10

passwd
=> “top.secret”

You can both hide and unhide passwords with the same code.

Regards,

Brian.

(*) This is making the (IMO risky) assessment that your users are too
dumb to use these techniques to recover the password, and yet not so
dumb that you’d be happy leaving the password in clear text.

There are lots of similar approaches, for example embedding a client SSL
certificate in your application, and using certificate authentication at
the server. This assumes your adversary is so dumb that they don’t know
how to take the private key and certificate from the app and use it
themselves.

-------- Original-Nachricht --------

Datum: Mon, 14 Sep 2009 17:44:31 +0900
Von: Brian C. [email protected]
An: [email protected]
Betreff: Re: Password on code - what's the best way to obfuscate it?

Rodrigo B. wrote:

I’ve been in the need to crate applications which require to make use of
another program which requires authentication. As everyone who has
tried to solve this problem with a script lang (no compiled, what would
be the best term /?), a security concern comes in play.

Where in hell should I put the password /?

Dear Rodrigo,

you can use a variant of a secret sharing scheme. In such a scheme, a
secret (password) is split up in n parts, and there is a number k<=n of
partial secrets needed to retrieve it.
The fact that a secret is split enables you to distribute less than
the k information bits to any user and keep the remaining secret parts
and the application to recombine it at a safe place (somewhere the user
cannot read from - I assume this is possible for you as you say that you
want to interface another program - which I assume you’ll run on a web
server or the like).

In the safe place, you’d have to write some code to combine the password
from the k bits necessary to retrieve it.
Thus, when the user enters his info, the information transferred is not
sufficient to intercept or rebuild the correct password and the combined
one is wrong.

There’s a descriptions of Shamir’s secret sharing scheme with a
simplified
example and links to some (non-Ruby) code (the web interface didn’t work
for me) here:

If you’d have to give away the entire application on a user’s computer,
I second the previous respondents’ pessimism - just like everything else
they wrote.

Best regards,

Axel