Showing posts with label security. Show all posts
Showing posts with label security. Show all posts

Feb 27, 2017

Log (CRLF) Injection with SLF4J

At my job we have a CIO installed policy of remediating issues found by a static analysis tool and what it finds are most targeted at finding security issues. Currently this tool is Veracode, and I don't recommend it, it misses more problems than it finds, and what it finds, including this issue, are often false positives. Our most common issue, is CRLF (Carriage Return Line Feed) or other log injection, which we have mitigated in a custom log appender (which Veracode doesn't recognize).

So in order to educate people, I've made a sample app to demo what you can do, here's the code, if you're familiar with SLF4J it should be pretty obvious. We're logging the arguments in various ways passed to the program (note: there's a README.md on how to build it in repo)

When you run the code, it has 2 outputs, one with default SLF4J settings, and the other with Spring Boot's default SLF4J settings. If you run this application with hello as an argument you'd get the following output, there's no injection here, this is obviously what the developer intends for it to do.


15:06:16.266 [main] INFO com.xenoterracide.log_injection_example.Application - STARTING
15:06:16.271 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: hello
15:06:16.273 [main] DEBUG com.xenoterracide.log_injection_example.Application - running 'hello'
15:06:16.276 [main] ERROR com.xenoterracide.log_injection_example.Application - 
java.lang.IllegalArgumentException: [hello]
 at com.xenoterracide.log_injection_example.Application$Runner.run(Application.java:31)
 at com.xenoterracide.log_injection_example.Application.main(Application.java:19)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:498)
 at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
 at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.1.RELEASE)

2017-02-22 15:06:17.138  INFO 41153 --- [           main] c.x.log_injection_example.Application    : Starting Application v1.0-SNAPSHOT on Calebs-MacBook-Pro.local with PID 41153 (/Users/calebcushing/IdeaProjects/loginjectionexample/target/log-injection-example-1.0-SNAPSHOT.jar started by calebcushing in /Users/calebcushing/IdeaProjects/loginjectionexample)
2017-02-22 15:06:17.139  INFO 41153 --- [           main] c.x.log_injection_example.Application    : No active profile set, falling back to default profiles: default
2017-02-22 15:06:17.208  INFO 41153 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@41906a77: startup date [Wed Feb 22 15:06:17 CST 2017]; root of context hierarchy
2017-02-22 15:06:17.848  INFO 41153 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2017-02-22 15:06:17.861  INFO 41153 --- [           main] c.x.log_injection_example.Application    : running with args: hello
2017-02-22 15:06:17.864 ERROR 41153 --- [           main] c.x.log_injection_example.Application    : 

java.lang.IllegalArgumentException: [hello]
 at com.xenoterracide.log_injection_example.Application$Runner.run(Application.java:31) ~[classes!/:1.0-SNAPSHOT]
 at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at com.xenoterracide.log_injection_example.Application.main(Application.java:20) [classes!/:1.0-SNAPSHOT]
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_112]
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_112]
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_112]
 at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112]
 at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
 at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]

2017-02-22 15:06:17.868  INFO 41153 --- [           main] c.x.log_injection_example.Application    : Started Application in 1.422 seconds (JVM running for 1.839)
2017-02-22 15:06:17.869  INFO 41153 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@41906a77: startup date [Wed Feb 22 15:06:17 CST 2017]; root of context hierarchy
2017-02-22 15:06:17.870  INFO 41153 --- [       Thread-2] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

One thing to notice here is that Spring Boot doesn't log debug by default, so no help there.

Ok, so now let's see what happens if I inject a log by inputing. The newline, after the quote, below is very important.


java -jar target/log-injection-example-1.0-SNAPSHOT.jar "
11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar"

that will generate this output

11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar"
15:13:31.162 [main] INFO com.xenoterracide.log_injection_example.Application - STARTING
15:13:31.167 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: 
11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar
15:13:31.168 [main] DEBUG com.xenoterracide.log_injection_example.Application - running '
11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar'
15:13:31.170 [main] ERROR com.xenoterracide.log_injection_example.Application - 
java.lang.IllegalArgumentException: [
11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar]
 at com.xenoterracide.log_injection_example.Application$Runner.run(Application.java:31)
 at com.xenoterracide.log_injection_example.Application.main(Application.java:19)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:498)
 at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
 at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.1.RELEASE)

2017-02-22 15:13:31.782  INFO 41187 --- [           main] c.x.log_injection_example.Application    : Starting Application v1.0-SNAPSHOT on Calebs-MacBook-Pro.local with PID 41187 (/Users/calebcushing/IdeaProjects/loginjectionexample/target/log-injection-example-1.0-SNAPSHOT.jar started by calebcushing in /Users/calebcushing/IdeaProjects/loginjectionexample)
2017-02-22 15:13:31.783  INFO 41187 --- [           main] c.x.log_injection_example.Application    : No active profile set, falling back to default profiles: default
2017-02-22 15:13:31.863  INFO 41187 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@41906a77: startup date [Wed Feb 22 15:13:31 CST 2017]; root of context hierarchy
2017-02-22 15:13:32.504  INFO 41187 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2017-02-22 15:13:32.516  INFO 41187 --- [           main] c.x.log_injection_example.Application    : running with args: 
11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar
2017-02-22 15:13:32.520 ERROR 41187 --- [           main] c.x.log_injection_example.Application    : 

java.lang.IllegalArgumentException: [
11:45:21.873 [main] INFO com.xenoterracide.log_injection_example.Application - running with args: bar]
 at com.xenoterracide.log_injection_example.Application$Runner.run(Application.java:31) ~[classes!/:1.0-SNAPSHOT]
 at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.1.RELEASE.jar!/:1.5.1.RELEASE]
 at com.xenoterracide.log_injection_example.Application.main(Application.java:20) [classes!/:1.0-SNAPSHOT]
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_112]
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_112]
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_112]
 at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112]
 at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
 at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]
 at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) [log-injection-example-1.0-SNAPSHOT.jar:1.0-SNAPSHOT]

2017-02-22 15:13:32.524  INFO 41187 --- [           main] c.x.log_injection_example.Application    : Started Application in 1.168 seconds (JVM running for 1.594)
2017-02-22 15:13:32.525  INFO 41187 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@41906a77: startup date [Wed Feb 22 15:13:31 CST 2017]; root of context hierarchy
2017-02-22 15:13:32.526  INFO 41187 --- [       Thread-2] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

You can see that in the default SLF4J output we've created a convincing message, It looks like we have empty string argument, and a second log statement. If you look at the debug message though, it has an unbalanced quote, which will tip your hat to the idea that something strange has happened. This debug statement is not run in our "production" spring boot. However if you look at the spring boot output the formatting is significantly different. Also this may seem obvious in this contrived example, but would you really notice it if you were reading thousands of lines of logs?

Log injection gets dangerous in a few scenario's. The first would be if you're using a log analysis tool, it might not pick up the second log line as a fraud, and instead treat it as a real log and the former log as only having an empty string. If they get the log format wrong (like with boot) then the analysis tool might not match the pattern and throw it out.

The next danger in log injection is XSS (or other types of injection). Take Docker Cloud (I don't know if it is or isn't vulnerable) it allows you to view your containers logs in a web browser, now imagine I put javascript code that pushes a malicious pdf (or something) to your computer "onload". When the system administrator goes in to view these logs this pdf might download and then be opened in a vulnerable viewer. Now you have an admin with a trojan horse on his computer. To be said other types of injection come in if you're saving logs to a database in an unsafe way, or for some reason passing them to a parser that might interpret the content (like regex injection).

P.S. the blogger preview of this is seriously misformated, looks like it may be time for me to migrate to another platform, if it is sorry about that.

Sep 20, 2014

Celebrity nude scandal, on security, an analogy

Though I won't say they aren't victims of a crime... What the victims did is fundamentally the equivalent of using skeleton keys in the modern day. What apple did or rather didn't do, is prevent that. Apple could have used a tool like cracklib, and said at the time of password creation, this is too short, this is not random enough, we are refusing to allow you to put this skeleton key lock on your front door. So while I think that the perp should be prosecuted to the full extend of the law, it should be like a Breaking & Entering where the door was left unlocked. Apple should be sued for not requiring secure passwords. Imagine if your lock company installed them wrong, and because of that you got broken into, they didn't do their job correctly. Would people just stand for that? No, I don't think so. Somehow physical locks are seen as easier to understand, and all this computer mumbo jumbo is hard, event though I suspect most people can't tell you why a deadbolt is a better lock. People should realize Skeleton keys are no longer secure, even if they look cool, and are easy to use, it's better to use a password manager (http://lastpass.com is what I use) with a randomly generated password for all other sites (I'd say 16 characters, though I think 12 is the current suggested). Fundamentally this setup is a deadbolt with a different key required for each door, but one keychain. You can also do multifactor, which is like a key with a chip in it that will refuse to start your car if it's the wrong chip, so making a physical copy of the key (password) isn't enough.

Nov 3, 2010

Making Secure Recoverable Passwords ( part 3 )

If you haven't read Part 1 please do so.

Although the criticism of Part 2 should be taken with a grain of XKCD Salt, and even the primary plaintiff admitted that it would take him 2 months to crack the final salted sha512. Usually your attacker shouldn't have your shadow file, and having stored them as anything less is just plain not secure. I will acknowledge it has some merit.

Doing a base64 transformation on hex only digits is a bad, idea, and does not have nearly enough possible combinations. Nothing is going to be more secure than random, but random isn't really recoverable, if you lose it. That's why I do some kind of transformation.

I believe that somewhere someone suggested that it would be better to convert from the binary digest into base64 as it would be more random than from hex. I believe this is accurate, but the method suggested was in Perl, which is kind of messy, and more importantly hard to remember. So I asked, on unix.stackexchange.com, how I could do this on the command line. Here's the answer I decided to accept:

echo -n `date` | openssl dgst -binary -sha512 | base64

Remember you should slightly modify the result in a way that you can remember in your head to make it random, and probably use something in place of the "date" command, since it's not reproduce-able.

Again: this is not meant to be as secure as random passwords, just secure enough compared to non random alternatives.

Jul 23, 2010

Making secure recoverable Passwords (Part 2)

This has been prompted by Dave Jacoby's post on generating passwords and the fact that I've learned a new trick since my my first article in 2008; which you should read first (it's a prereq).

Some might point out that using a hex digest limits the characters that will be generated too much, do this then.

echo -n "date" | sum | base64

So let's say you have to change your password every month. Pick a day, let's say the second Tuesday of the month. Since your memory sucks write this down "Pipes on second Tuesday @ 5:08!". Sounds like an event reminder right? Here's your actual password algorithm for this month. First you want to has the 'second Tuesday of the month'.

echo -n "2010/07/12" | sha1sum | base64

which outputs

NTFhMTY4NmJkNWQyZmIzNWJlZTlmYmQxYzEwN2FjNGE1MjUyYjI1OCAgLQo=

So what was the rest of that reminder for? Now you're going to make it as good as random, take the first 8 characters 'NTFhMTY4' and insert a pipe '|' at the 5th character, resulting in 'NTFh|MTY4'. Now you have a 'good as random, but recoverable' 9 character password.

Given if you work with really clever people they might be able to figure it out if they know you use this kind of process. But I'm sure having read this article and my previous one you'll come up with something even better, but just as reproducible.

UPDATE:

I do not believe that anyone can seriously prove (after having read both articles) that you could crack this with anything less than a brute force attack. Because I've suggested inserting 1 or more characters into the final outcome, chances are those are anything in the 94 printable characters of ASCII. Yes you might limit the end possibilities but after seeing passwords that most people have... this makes you a hard enough target that no one is going to bother. Basically all assumptions that using this is bad revolves around someone knowing exactly what you do (so in reality it's probably only bad for me).

I should also note that my personal system encrypts passwords with a salted sha512 and I'm having trouble find a password cracking tool that can even try to brute force that.

UPDATE:

oh and just in case you forgot... no one is trying to brute force your password. Remeber this XKCD

Jan 19, 2010

PostgreSQL initial setup (authentication) Part 2

I ran into so problems and lack of information with my last post on this topic. Firstly my syntax for local all all to local all all ident devel
doesn't seem to work in my current setup. It's possible that it has something to do with the configuration of the Debian/Ubuntu server I was basing that against, and now my targets are Arch Linux and Slackware.

So our goal here will be to provide an alternate user that can log in as postgres via ident. why would you want to do this? maybe you're tired of su - to the postgres unix user after logging in as your administrative user (root?).

First we need to open our pg_ident.conf and add the following line.

admin root postgres

So as I said in the last post on this: "admin" is an arbitrary identifier, root is the system user, and postgres is the database user. Now let's go ahead and make sure the postgres system user can still login.

admin postgres postgres

ok that's all we need to do in the pg_ident.conf. Go ahead and open pg_hba.conf and add this line above the default 3 lines in the file.

local all postgres ident map=admin

as a breakdown: local is for socket connections, all means all databases, ident means it's checking for local users, and map=admin says look at the users in the admin identifier in pg_ident.conf.

Now you should be able to run psql dname postgres as root. You will not be able to use the db postgres user as any system user not in the admin map.

Nov 16, 2009

Bypassing disabled accounts with KDM

So the most common way of disabling an account in a unix system is changing the users shell in /etc/passwd to /bin/false or /sbin/nologin. However, I've discovered on Arch Linux that if I do this only shell login's are disabled, I was still able to log the user in with gui via kdm. I also tried using usermod --expiredate 1. this was not effective either however. the only way I found to lock the account from kdm login was to do a passwd -l accountname, which only locks password authentication. This means key and token authentication should still work. My real concern is that if the user was set to login without a password that it would still be bypass-able. My personal opinion is that I shouldn't have to do more than 1 thing to disable a user account in a 100% effective manner. Currently Arch Linux (and maybe more) fails at this. I'll post a fix later as I investigate further.

Bugs I filed are at kde and Arch Linux

EDIT: expire date worked... just not immediately, very odd.

EDIT: Here's a proper /etc/pam.d/kde

#%PAM-1.0
auth        required    pam_nologin.so
auth        required    pam_unix.so nullok
auth        required    pam_shells.so
auth required pam_tally.so onerr=succeedfile=/var/log/faillog
account     required    pam_access.so
account     required    pam_time.so
account     required    pam_unix.so
password    required    pam_unix.so
session     required    pam_unix.so
session     required    pam_env.so
session     required    pam_limits.so

Oct 3, 2009

Port forwarding in OpenWRT

So you need the outside world to have access to some box's on your internal network. first you should use Static DHCP to tell static the IP's of the computer you're routing to. Then you of course need to know the inbound from the outside world and the port on the computer you are forwarding too. For this example we'll forward WAN (Wide Area Network (or (probably) the Internet)) port 8080 to a local dev box running Apache on httpd (we assume you know how to set apache up and make sure it's working on the LAN(Local Area Network)).

edit /etc/config/firewall. note: /etc/firewall.user is for manual iptables commands and is basically a shell script. I only recommend this if /etc/config/firewall doesn't do what you want (like multiport).
config redirect
        option src              wan
        option src_dport        8080
        option dest             lan
        option dest_ip          192.168.1.3
        option dest_port        80
        option proto            tcp


So options src and dest merely define the too and from interfaces (to be honest I'm not sure they actually do anything. as I'm not seeing any changes to what's in iptables). src_dport is what external port you want to listen on. dest_port is what you want it to go to. dest_ip is what ip you want it to go to and proto is the protocol it listens on (yes you have to specify separately for udp if what you're forwarding uses both tcp and udp).

After you've edited and saved the file to fit your case run /etc/init.d/firewall restart and it should work

IMPORTANT: there's a bug in 7.x and pre 8.09.2 with 2.4-bcrm kernels and netfilter code... it 'causes port drift. if the bug is affecting you. (it did me) reboot the system. you will be able to see it with a -j LOG iptables rule. the output was thus for me
IN=eth0.1 OUT=br-lan SRC=66.98.131.131 DST=192.168.1.3 LEN=44 TOS=0x00 PREC=0x20 TTL=47 ID=63450 DF PROTO=TCP SPT=54402 DPT=82 WINDOW=5840 RES=0x00 SYN URGP=0
as you can see the destination port(DPT) is 82 instead of 80 like it's supposed to be. 8.09.2 should be out in a few weeks it's currently at rc2.

Sep 22, 2009

Quick sha1sum with Crypto++

I've been working on Korama. I was originally planning on hashing each music file and using the sha1 for the track primary key. However, after benchmarking an actual implementation. I've decided that it's too slow, 20 minutes for 3k+ tracks, also my program was about 5 minutes slower than find ... -exec sha1sum not sure on the reason why. However, since I had problems figuring out how to do it I figure I'll post a basic sha1sum program that I made with the help of people on the Crypto++ Mailing List.

Include's are mangled due to blogger filtering

#include < cryptopp/sha.h >
#include < cryptopp/hex.h >
#include < cryptopp/files.h >
#include < string >
#include < iostream >

using namespace std;

int main(int argc, char *argv[])
{
char *file = argv[1];
string result;
CryptoPP::SHA1 hash;

CryptoPP::FileSource( ( file ),true,
new CryptoPP::HashFilter(
hash, new CryptoPP::HexEncoder(
new CryptoPP::StringSink(result), false)
)
);
cout << result << endl;
return 0;
}


it can be built with.

g++ sha1.cpp -lcryptopp -o sha1sum

and tested with

./sha1sum filename
It's not meant to be a exactly compatible implementation of sha1sum. it doesn't output the filename, it isn't capable of handling more than one file argument, and if no argument is provided it crashes. I know I haven't actually explained how the crypo++ code works, but I hope just posting this here will help someone in the future.

Sep 5, 2009

FSDaily security fail (see image)




Hint, Hint! FSDaily don't access your db with the root account. and definitely make sure that, that error page doesn't show that to users.

Aug 24, 2009

PostgreSQL initial setup (authentication)

If you followed my last initial setup post on creating users and are running a default install of postgres you currently should be able to access the database on your cli. However, many distributions do not install postgres in a default manner. A great many distributions make the default authentication for sockets ident sameuser. This is technically much more secure than trust which is the default. However, you may find yourself locked out of your database on the local cli if you make the database name different. I personally was confused about this after first encountering this setting.

So, we don't want trust but we want to use a db username other than our shell login, most likely because we have more than one database. There are several options but I personally think ident is a good one. However, since we don't want to use the same shell login name we have to modify pg_ident.conf and pg_hba.conf, locations vary by distribution.

In pg_ident.conf you have to create a line with the following formatting.

# MAPNAME IDENT-USERNAME PG-USERNAME

I think it's mostly straightforward. In case it isn't, MAPNAME is an arbitrary identifier, sameuser is actually the mapname in ident sameuser A quick example from mine would be

devel xenoterracide webdevwhere my unix username is xenoterracide but I created the database user webdev. If you wanted you could add another devel mapname with another user or the same unix account different db account, or even a different unix account same db account, etc.

After you add all the various mappings you need to add or change the ident in pg_hba.conf. You can only have one method per type/database/user/address combination. so in pg_hba.conf you want to change

local all all to local all all ident devel

If you want postgres to ask for a password use md5 instead of ident further information can be found at http://www.postgresql.org/docs/current/interactive/auth-methods.html.

if you have any problems you might want to see part 2.

Aug 23, 2009

Adding a new group to an open shell without logging in and out

Most Unix users believe it's impossible to add a group that was recently added to your user account without logging in and logging out. If you're running X and need to give your gui new permissions (like dolphin/konqueoror) this may be true, for the most part. I don't know how to change it for those processes. However, if you need to change it for a shell prompt it's easy. You merely execute the command newgrp in an open shell prompt and that prompt will now be loaded with the new group. I believe it also changes the default group that shell is running as. So if you run newgrp http; touch test.txt your file will be created with the group http instead of whatever your default is. You can change your group back to the default by using the sg command.

Aug 22, 2009

More Security = Better. Wrong!

So I just had a discussion on #ubuntu-server on freenode about why my not having a password to connect to postgresql via a socket (read local cli) is insecure. So I asked them, how exactly is it that someone is going to get this access? The answer "there are bad people on the Internet". I'm sure many people right now are agreeing with them and thinking I'm crazy. Let's discuss my setup though shall we.

Postgres: I'm using Ident, and not just sameuser ident. no I had to set a custom rule in the pg_ident.conf file for this user to access because the systemuser != the db user. so just typing psql at the command line should you get access still won't get you into the db. you have to know which user/database to connect to. But that's not that hard right? in fact it's trivial.In addition you have to be a certain systemuser, only one works.

User Access: There is only one user account on the system that can be logged into (it's not root or a generic name). Only 2 people have the credentials to get shell access. One is my host, who happens to have physical and kvm access. The other is me who has ssh access.

SSH: I have ssh on a high port with no password authentication, or root, allowed.

So in order to passwordlessly access the database you would have to ssh into the system from a remote location or find an exploitable bug in apache (the only other service listening, or the kernel) that allows you to switch to my non apache user (meaning root access).

In addition, this system user had rw access to the entire website which includes a file containing the password to the database in plain text. So let's say I created a .pgpass file or variables? what exactly is it that would keep anyone who has access to this account from gaining access to the database? in fact wouldn't it just make it easier, since pgpass has a known location and contains all connection info including the username/dbname string?

But why do I need passwordless access anyways? I wrote a script that dumps the db every hour to a git repo and then pushes that to a remote.

Could I secure it further? yeah I could. I could make the script run as a user who can't log in at all and then put a pgpass in that users account. I'd have to properly ACL the webroot to give the correct write and read access. But is all this really necessary? maybe and I might do it, but at this point it's not nearly as important as it was for me to get backups up and running, because regardless of all the security I implement, if I have no backup and someone finds that loophole in one of the pieces of software and uses it, I might just be screwed. At least now I can restore the site if it gets attacked.

P.S. I was having a problem with my backup not being run by cron, never did figure out why.

May 16, 2009

iptables browsing samba shares

NOTE: this assumes that you've read my previous post on basic iptables setup on the desktop

So I just spent the longest time trying to determine what ports I needed to browse and use samba shares. The sad answer is it's just one.


iptables -A INPUT -p udp --sport 137 -j ACCEPT


the catch with all the information I found with google was that most of it was for samba servers. I didn't want that. I just want to be able to browse my roommates network shares, and download from them. None of the information google provided suggested I need to allow the source port on the other end.

May 6, 2009

Jeff Atwood fails at password security

This was originally written for a class assignment and as that has not been modified (much) for the web.

Jeff Atwood's password was compromised, the following includes a summary of how it happened, and how better security policies could have avoided it. This was written for Advanced Report Writing at Baker College.

Summary of Article

On May 3, 2009, Jeff Atwood reports that his Stack Overflow password was compromised an that he received an email explaining the details. The following is an excerpt of that email, that was posted in his blog post.

How? Well, there were two pieces of the puzzle, the password and the openid provider. I had a possible password; today your blog post revealed the openid provider. I logged in, freaked out that it actually worked, then logged out. The only reason I had the password is because your password is totally inadequate for someone running a site like StackOverflow. I don't want to go into any more detail than that, but man - dictionary password! -A friend of the site (Atwood, 2009)


Jeff confirmed that the authentication logs for Stack Overflow did include a valid login from an unrecognized IP address. Although Jeff defends that his password was not a dictionary password. He also states that this particular OpenID account is for low security transactions online, and not particularly valuable. He digresses that because this account is a Stack Overflow moderation account, with special privileges, that he should have used a more secure login.

Jeff goes on to explain, the various ways which the account could have been compromised. The first method he describes is the "educated guess". An educated guess basically uses what you know about someone to guess there password. The second is "Brute force dictionary attack". Jeff describes this as an attack vulnerable to non-rate limited logins where the password is a word out of the dictionary. The third method described is "interception". This method is basically where the password was captured at some point between the user and its destination, this could be kelogger, packet sniffing, and/or simple lack of encryption. The final method was "Impersonation" where a site pretends to be a different site, and prompts you for credentials, this is also known as phishing.

Jeff presents that none of these methods were used to compromise his account.

I guess I can tell you, so you don't fall into this trap again. There's a site I help out with that doesn't salt their passwords. They're MD5 encrypted, but if you've got a dictionary password, it's very easy to use a reverse-MD5 site to get the original. I was able to figure out you were a user on the site some time back, and realized I could do this, if only I knew your openid provider... (Atwood, 2009)



Jeff then re-iterates that he is to blame, and this is a problem with programmers at large. He then suggests that programmers should get out of the business of storing credentials, if they don't want to take responsibility for it.


Evaluation of the Article


Jeff Atwood, is a fairly famous full time blogger entrepreneur, software developer and blogger, and often seen as an authority in the community. He is self admittedly not an expert and these articles truly show this. Jeff's articles will undoubtedly lead many programmers to be confused and ignorant about the types of attacks possible and the type of attack that actually took place. One good thing does come from these articles however. It increases developer awareness (and hopefully user) awareness of just how easy it is to compromise a password and how inadequate there own authentication systems may be.


Jeff seems to not understand the basics of all the attacks he's described so I will elaborate on what they really are.


1. Educated Guess: Jeff mostly has this right, however, in the article he calls this in with social engineering. It is in no way shape or form social engineering. Social Engineering generally requires convincing someone to give you information. An educated guess requires that you use information you already have to break the password. In a sense this was used to gain the login name, although it was not a guess, it was known. I once used an educated guess to break into the account of someone based on there age, gender, race, and password hint, none of which I had to gain any additional information on. note: my cracking of this account was 100% legal as it was authorized by the computer owner.

2. Brute Force: This is combined with 'dictionary attack' and although the two are often combined they are separate attacks. A brute force attack is simply generating account credentials (username password typically) with an automated computer program and sending them to the system you are attacking until it lets you in, until you are permanently blocked, or until you give up. A brute force attack is 100% successful unless somehow stopped as it will eventually try all combinations. The exception to this is when the password could be changed to a password already tried during the attack. This only works on a live system however, if the attacker manages to gain a copy of the password db they can attack at their leisure and may instead get a stale password. It can mostly be prevented by locking users out after a certain number of failed attempts.

3. Dictionary Attack: A Dictionary attack, although it does reference words from an actual dictionary, such as Webster's, it is not limited to just those words or even words. Dictionary attacks consist of lists of words which may come from any language, including fictional ones like Star Trek's Klingon, slang, names and pop culture references. Because of modern security standards they will often append, and prepend numbers to the words, and even change case around. Dictionary attacks may also include coded words such as 1337 also know as leet or l337 or l33t, etc. 1337 is a substitution cipher popularized online which substitutes letters for numbers that slightly resemble letters. A dictionary attack is usually run before a brute force as it is much faster, and has a high probability of success compared to time used. It can be mostly prevented by forcing users passwords to be compared against known dictionaries (such as cracklib) and making sure their password isn't in them, and forcing them to pick something else if it is.

4. Interception: Interception is another name for "the Man in the Middle" attack, which is
what it more commonly goes by. Jeff seems to be under the assumption that "Man in the Middle" requires the attacker to get the credentials verbatim. "Man in the Middle" basically means getting the data after the user enters it and before it reaches it's destination, this include keyloggers, screen scrapers, and packet sniffers. it may include other methods I'm forgetting. "Man in the Middle" is easily prevented by user strong 'stream encryption' in which all data sent between the client and the host is encrypted, SSL is commonly used for this on websites, note the 'lock' icon, in your browser. This is different from hash encryption which is how the password is (should be) stored as it encrypts all data being transferred including the username and password hash.

5. Impersonation: Or Phishing is a form of social engineering in which you pretend to be something you aren't and attempt to get people to give you sensitive data such as account credentials. It is most commonly done by creating a website which closely resembles the site for which you are trying to get credentials for, and then sending out emails to try to get people to log in.

6. Social Engineering: Social Engineering is simply misrepresenting yourself to get information. It can go as far as full blown fraud, or as simply as talking a person into giving me what they may not even believe is sensitive data. One could for example talk to someone, get there name, mention that they knew a woman who married a man with that last name and ask for a mother maiden name, pretending like they knew her. A mothers maiden name is a highly common question to prove identity in account verification and password resets online. People have also dressed up and walked into nuclear power plants with clipboards making themselves look like they belonged there, and were never stopped. An IT guy asking for your password may also be social engineering, as you think you should trust him. Social Engineering may be used to get account credentials or to formulate an educated guess.

7. Rainbow Tables: Rainbow Tables are databases of all possible straight password hashes up to a certain number of characters, and there corresponding passwords, these hashes may or may not be included with a dictionary attack, they typically include the full contents of a brute force. The largest Rainbow tables includes all possible combinations up to 8 characters for md5 hashes. These make reversing a hash from a password instant and easy. It still requires the attacker get the hash in the first place, this is usually done by "man in the middle", SQL Injection, or compromising the database server. This can generally be avoided by salt-ing the hash making it more difficult for the attacker to get the original password.

Jeff's Password was lost due to a combination of attacks. Firstly was public information, his 'user' credentials (OpenID) were publicly available (this isn't actually an attack), the second was "Man in the Middle", as obviously no one published the hash, so it had to be gotten somehow enroute (unless the db was cracked). The third was "Rainbow Tables" which allowed the attacker to reverse the hash into a real password. I don't believe that Atwood truly understands the attack vector's, and I don't think that people should read these articles for learning purposes. It is good though that he accepts some responsibility for lack of proper security practices on a sensitive account.

In my opinion this is what's wrong with programmers, they think they know better and instead of learning how to do it correctly and all the things that could go wrong, they just go ahead and do.

Atwood, J. (2009). I Just Logged In As You. Retrieved
May 6 2009, from Coding Horror
Web site: www.codinghorror.com/blog/archives/001262.html


Atwood, J. (2009). I Just Logged In As You: How it happened. Retrieved
May 6 2009, from Coding Horror
Web site: www.codinghorror.com/blog/archives/001263.html

EDIT: Sincerest apologies for originally spelling Atwood as Attwood and spreading misinformation about about his profession. Thanks to Stu for pointing this out. For some reason I thought those were both true, and did not check them, since I've been reading Coding Horror for at least a year.

@Grade I'll post it next week when I get it

@Spelling errors, I had reinstalled my system the morning of writing and apparently had forgotten to configure it. They should be corrected now.

@Assignment the assignment was not an essay but the evaluation of an article, and its content. It didn't require me to cite any sources for why I agree or disagree with the article.

Jul 5, 2008

The real problem with windows is not windows

(note: this was originally intended as a reply to Why Is So Hard for Windows Users to Understand That Linux Is Not Windows, but it got so long I felt it should be it's own post. I'm not sure the title is good, but it's close enough)

(note: I use the term users in this blog to mean people who use computers that do not, develop, administrate, repair, or are other wise considered power users, and professional computer users.)

I don't hate windows anymore, like Dan Craciun says they just aren't the same thing. I switched to linux years ago, I see that it isn't perfect anymore, but I still like it better than windows.

If you told me that I had to ignore the constant rebooting on windows and the lack of gaming on linux. I would suggest that I can make either system as stable, and equal in terms of usefulness on the desktop. Sure it might take me a few more hours to secure windows, get drivers installed, and install security tools, and the software I like. But in the end they'd be close to the same, in usability and long term stability for me and normal users.

The truth? the problem with windows isn't entirely windows... it's users. I could teach a user 99% of what they need to know to maintain their computer and keep it running smooth in an hour, but they wouldn't listen, they'd continue to use IE to browse promiscuously, not keep their antivirus, antispyware that I installed up to date.

If you were to change everyone running windows xp to ubuntu (I don't like ubuntu btw) today, I predict in 6 months to a year ubuntu users would have as many problems as windows users today? why? they wouldn't update there systems... they'd disable their firewalls, they would browse to all sorts of bad sites that contain the new linux malware.

How do I know this? I've put 'users' on linux, specifically opensuse, which has a nice little update checker... I show them how to use that after resolving the problems of codecs, and drivers and whatever else install problems they might have. In a week that icon is red, and will stay that way indefinitely because they never ever run updates.

So the real problem is users not treating there computers like cars, and ignoring the fact that they need proper maintenance and there are just some things you shouldn't do with them. True linux is easier for me to fix, mostly due to the lack of a registry, but the problem is not make and model, but lack of maintenance (and yes some makes and models are easier to maintain). If you don't ever get an oil change or add to your oil your engine will burn up a lot faster than it would if you had take care of it.

The one thing that M$ does that causes me to still hate them, because it affects me, is IE. If I had one thing I wanted from microsoft it would be a browser with the standards compliance on par with the likes of Mozilla Firefox (they don't have to achieve opera, or webkit) and without their own proprietary syntax, they have to do it the same way as everyone else (e.g. no active X calls instead of XMLHttpRequest..) But even if IE8 managed to be this browser, it wouldn't help anytime soon... why? because users don't update their software.

May 22, 2008

Debian and OpenSSL blunder - goodbye debian?

I'm sure you've read about Debian's OpenSSL blunder. If not here's a recap on Linux.com.

I'm just wondering... is it possible that the pain will be so great for admins that the great stable debian will be discontinued from production server use? I would (but I don't use debian based systems for anything but livecds), seriously this is a hugely idiotic mistake the pain of which is only beginning. This may in fact be the biggest security blunder I have ever heard of in open source.

Apr 27, 2008

Making secure recoverable passwords

For the basic you need a calculator with a decimal to hex function. Your OS should have one built in (scientific mode), many calculator's do to. For advanced you'll need special hashing software, suggestions for it can be found below.















Windows HashCalc
Macintosh MacHash
Linux/(*nix) Gnu Coreutils


Now that we have the software we need. You'll need an 8 digit (minimum) number that you won't forget. Guess what numbers fit the bill perfectly. Dates. All date's can be expressed in 8 digits, but they require a year. The date we'll use (for example) is Linux's Birthday. August 25, 1991 (I recommend something more personal like your anniversary or birthday).

So we are going to write down the date we picked for the password (note we aren't done yet).

something like

Linux BDay

Date's can be formatted in several ways, Just make sure to remember the numeric format you use. For our example we'll use the ISO 8601 standard. Which leaves our example date in format, YYYYMMDD, looking like 19910825.

So let's make a note of the format (to throw people off use a diff format say DDMMYYYY).

Linux Bday ISO

whatever you do make sure YOU understand your note, but that it isn't easily understandable by OTHERS.

alright... now we're going to take our number and make it hex. So open your calculator enter 19910825, then use the convert to hex function and you should have this 12FD0A9 (if you aren't using our example you may have a different 'number', or it may not be displayed exactly like this, display's vary between calculators). This is your first basic password. you can use it as is, or you can make it a bit more secure by using one of the hexadecimal notations. example: 0x12FD0A9. You can add a word or funny characters to either side of it to make it stronger too, just make sure to note anything you add to it.

Due to a Rainbow Table database you should make sure your password is at least 8 characters but I would recommend no less than 9.

But your hex number is less than 9 and what do the programs you listed have to do with this?

good point... let's make something a bit more crypto and less predictable.

Take the same date and plug it in to your hash creator, I'm going to use an md5sum for my first example.

if you put 19910825 into md5sum you get 6f9822851dfc6c1045c6fef827e5d729 (for you nix people enter the number like this 'echo -n "19910825" | md5sum'
on the cli otherwise you might end up with newline issues because different operating systems use different newlines).

so lets say you need an 12 character password you could just use the first 12 characters of your hash, example: 6f9822851dfc if you need an 8, example: 6f982285 ,etc etc.

if a stupid 'cracker' or black hat hacker get his hands on your actual password he might think he hasn't decrypted it fully because it'll look like a hash or memory error. want to throw people off even more just remember you aren't using the first 8 but the first 8 after the first 2 example 9822851d.

Or use a different has like sha1 or sha512.

Ultimately you could make your note to yourself like this

Sha1LinuxBDayISO to a non IT person this will look like a random password as is.

Also the cryptographic hashes take words too. So you could do your name. Caleb into an md5sum is

9ced73b8525de1db8e232ad575baa9dd

but it's different if I use caleb.

2f0154d7db348840676529dd72f1c034

if you always enter them the same you will always get the same result back. I guarantee after a couple days typing your new password you won't need to have it written down. If you work at a place that requires things like monthly changes.. just put the date you changed it on in to create the hash. Just make sure no one knows but the number/word(s) you used and the hash you used or they will be able to duplicate your password. Of course you're smart and you added somthing to it right? like a symbol (!@#$%^*{}|:"<>?[]\;',./) will all work find if the auth methods allow it.

have fun never having a hard time creating passwords again.

Apr 18, 2008

rss/atom bulk

I've noticed recently that some of the feeds I've subscribed to are including a lot of stuff I don't care about, I'm wondering if it would be possible to have a bayesian filter for rss/atom like I do for email.

Apr 12, 2008

Would you steal a buck? How about a can of soda?

Would you steal a buck? How about a can of soda?

An interesting article questioning why people make predictably irrational decisions.

Apr 8, 2008

iptables for the average desktop user

The Best guide for learning the basics of iptables is here
Linux 2.4 Stateful firewall design for the most part it continues to apply to the 2.6 kernel. The only things that won't apply to your linux system will be: emerge if you aren't on gentoo, and the kernel options which have changed since 2.4 and even a couple of times during 2.6.

I'm not going to cover those here. If you need help building your kernel or installing iptables I suggest that you consult with either the iptables home page or even better your distribution. Chances are it is already installed, and may even be configured.

First Let's see if we have any rules.

The following commands require root access, and can be run in a root shell, with sudo, or in a shell script by root

iptables -L -v

your output should look something like this if you have no rules

Chain INPUT (policy ACCEPT 211 packets, 27413 bytes)
pkts bytes target prot opt in out source destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 312 packets, 211K bytes)
pkts bytes target prot opt in out source destination


If it looks different no worries it just means that your distro has already installed rules.

If so make sure BEFORE CONTINUING to flush them. FIRST check to make sure your policies are set to accept (you can see that in caps above) if they are anything else run


iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT


now that your policies are clean you should flush the rules

iptables -F #flush all rules
iptables -X #delete all chains


all right now hopefully you are at a clean state. If you have ever used iptables for nat you may not be, but that is beyond the scope of this article.

Now we need to create rules, since this is for normal deskop users you shouldn't have any services listening, also you shoudn't be routing anything.

to disable routing with iptables (I'm ignoring the kernel setting for this)


iptables -P FORWARD DROP

# set all forwarded packets to go bye bye if they reach the end of the chain

the output chain is good on accept for the normal user, only a masochist would want to write rules for it. You generally should trust your outbound traffic.

Now to secure input

iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -P INPUT DROP

#this rule drops all packets with a bad state
#accept any packets that have something to do with ones we've sent on outbound
#accept any packets coming or going on localhost (this can be very important
# set all packets not matching these rules to drop

Various linux distro's may require you to do something special to save these rules so that they survive a reboot. consult your distributions community.

If you have rules that you want to keep but also want to use mine I suggest putting mine first, you should do the -A rules in reverse but use a -I for insert.

When dealing with iptables always take care when applying iptables -P DROP. You can be locked out of the machine or the internet if you apply this without the appropriate rules in place.

That's it. your desktop should be secure from an attacker that you aren't allowing in. There are of course other things that you can do to make it even more secure but those are beyond the scope of this tutorial.