Recently in Programming Category

If you need to export a list of accounts from Active Directory into ldif-format files that will preserve attributes, you can try this. It takes a text list of sAMAccountNames (one per line) and writes out an ldif file for each one. You can easily import the same way by changing the arguments on the exec line and removing the export parameters. You'll also need to fix the line breaks.

'v1.1 ' The script will take a text file with usernames (sAMAaccountNames and export them via ldifde to individual files ' named as sAMAccountname.ldf.

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("samaccounts.txt",1)
'On Error Resume Next
Do Until objTextFile.AtEndOfStream
strName = objTextFile.Readline
WScript.Echo "sAMAccountName: " & strName
Set objShell = CreateObject("WScript.Shell")
'you can add/remove attributes from the line below, but be sure to get the quotes right.
Set objScriptExec = objShell.Exec("ldifde -f c:\scripts\export\" & strName & ".ldf -s myDomainController -d ""ou=myOU,ou=Clients,dc=domain,dc=com"" -r ""(sAMAccountName=" & strName & ")"" -l objectclass,dn,c,department,description,displayName,employeeID,extensionAttribute10,extensionAttribute8,extensionAttribute9,givenName,homeDirectory,initials,manager,otherTelephone,physicalDeliveryOfficeName,extension,sn,streetAddress,telephoneNumber,extensionAttribute14,extensionAttribute11,extensionAttribute12,wWWHomePage,sAMAccountName,userPrincipalName,mail,mailnickname,telephoneNumber " )
strResults = objScriptExec.StdOut.ReadAll
WScript.Echo strResults

Loop
set objFile=Nothing

'End

I first noticed a mysterious connection on a netstat:

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 1 mrtg.sampas.net:42321 223-118-92-213.server:49153 SYN_SENT

I also noticed Apache had opened a shell:
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
1 S apache 18005 1 0 76 0 - 1282 - Apr10 ? 00:00:00 sh -i

Soon after, perl became a runaway process, consuming 100% of my CPU time. And I thought /sbin/nologin meant user Apache couldn't just get a shell. I updated zlib from 1.2.2 to 1.2.3 to fix a security hole. up2date -u reports everything is up-to-date. (It did that for my old zlib, too.) I don't see any new holes in my applications, MT and Gallery. I did a Nessus scan with recent updates, and all it showed no holes and one warning. I ran clamscan and it didn't find anything, either. Rkhunter found nothing, and nikto gave me the following output:

+ Server: Apache/2.0.52 (Red Hat) + Allowed HTTP Methods: GET,HEAD,POST,OPTIONS,TRACE + Apache/2.0.52 appears to be outdated (current is at least Apache/2.2.3). Apache 1.3.33 is still maintained and considered secure. + / - TRACE option appears to allow XSS or credential theft. See http://www.cgisecurity.com/whitehat-mirror/WhitePaper_screen.pdf for details (TRACE) + /usage/ - Webalizer may be installed. Versions lower than 2.10-09 vulnerable to Cross Site Scripting (XSS). CA-2000-02. (GET)


So now I'm stuck looking through my apache access logs, because that's the only thing exposed to the outside world.

I did a capture just while open my firewall for a couple of minutes, and I saw it try to log in to an IRC channel. Ouch. I've been pwned. Fortunately, my firewall stops my server from being used for attacks, and I was able to block the port range used by the IRC bot.

Finally, Red Hat released a lot of new patches for PHP, and I set PerlTaintCheck On in /etc/httpd/conf.d/perl.conf, which was the real problem: user Apache had started listening on port 80 using Perl, so I couldn't even restart httpd.

Next time, I need to check the logs closer and post a network capture of the login process.

The Washington Post's David Ignatius postulated about how the National Security Agency's system might work. In doing so, he provided an excellent example of data mining. What the NSA is trying to do is simple and complex at the same time. The data structure is simple, but the sheer volume makes it complex.

The problem may seem hopelessly complex, but if you use common sense, you can see how the NSA has tried to solve it. Suppose you lost your own cellphone and bought a new one, and people really needed to find out that new number. If they could search all calling records, they would soon find a number with the same pattern of traffic as your old one -- calls to your spouse, your kids, your office, your golf buddies. They wouldn't have to listen to the calls themselves to know it was your phone. Simple pattern analysis would be adequate -- so long as they had access to all the records.

The trouble is, simple pattern analysis isn't that simple when you start trying to code it. You would have a giant data cube, and you would have millions of slices to compare with each other. On the other hand, if you have one target number and have a query that pulls all its callees, you could craft another query that searches for those same numbers. You could then score new numbers based on old queries: each query would have a rating of between 0 and 1 with 1 being just like the original number.

If you have voice matching that can confirm a 1, you could design an artifcial neural network that learns as it targets new numbers. Voice matching would require eavesdropping -- but if you got a score of 1, it would be worth the trouble. This way, your neural network could learn what the score is between 0 and 1 that should trigger voice matching.

People (mostly database people) keep asking what I meant by reflexive query in my previous posts. Some thought I was confusing a self-join with a recursive query that would allow my DNS server to answer a DNS query for a domain for which it is not authoritative. What I mean is a query that returns a caller and a callee; and then another query that returns the callee's callees. In a self-join, I can match employers to their managers, since both are in the same table. While the NSA-phone tracking system might use some self-joins, what makes the network part work is getting queries from queries, and jumping from callers to callees. Of course I'd like all the results timestamped, too. Recursive queries are a part of this, and SQL 2005 can do it. If I had a few gigabytes worth of phone data, I'd love to let SQL 2005 loose and see what connections I could see. When I say reflexive, though, I mean that I'm going to use my queries to start other queries, and not just as sub-queries. The recursive part could lead to infinite loops. I wonder if the NSA hit any infinite loops when testing their system. Fortunately, you can specify limits on recursion in SQL 2005.

The scary part of this is what would happen if I had the resources to make it run really fast and tuned it to be as efficient as possible. I could select a target and find all of its connections in a few seconds or a few minutes. The difference between seconds and minutes would make a huge difference. In a system where it takes a couple of seconds to generate results, nobody would notice if I ran a few "unofficial" queries on my friends. If it took a few minutes and precious computer time, then people would notice. Utilitarian ethics.

This begs the question: how much computer time (and tax dollars) does our government use tracking down everyone who calls reporters? Then again, leaking classified information is unethical, but people do it anway. Contextual ethics. Of course, there's also the issue of selective enforcement, but that's a legal issue, not an ethical one.

Thus we're left with utilitarian ethics vs. contextual ethics. Who knew that efficient queries and more processing power could give one type of ethics an advantage over the other?

I do Windows, Unix (Solaris), and Linux (mostly Red Hat). Everyone who's into "open-source" keeps telling me how much more secure it is. I'm a CISSP and I've been installing open-source OSes since I had to know the chipset, IRQ and DMA of the NICs in my box to get networking to work. (The DEC Tulip was my favorite.) When I started working with Solaris 7 and Red Hat 4.x, telnet was enabled by default. I still wonder if telnet was enabled on a Trusted Solaris 7 default install. People who tell me any form of Unix is inherently more secure than any Windows don't seem to be familiar with the Morris worm, the Leshka Sendmail exploit, or BIND vulnerabilities. In fact, just mentioning BIND and sendmail in the same sentence is likely to send your security coordinator into the bunker for the rest of the day. Mind you, I've also seen IIS flaws. Can't we all just get along and implement security best practices on whatever platforms we're using?

Ruby on Rails shows a lot of promise as to helping people get up and running on applications quickly. The tutorials are pretty helpful , but there are a a couple of caveats:

In the configuration wizard, you can also just accept all of the defaults, except that in the security panel you must uncheck the "Modify Security Settings" checkbox (Figure 4). This is because starting with version 4.1.7, MySQL uses a new authentication algorithm that is not compatible with older client software, including the current version of Rails. By unchecking this box, you can access MySQL without a password.

This is not the path to secure computing. MySQL should NOT ship with a blank root password. Tutorials should not encourage the use of blank root passwords.

And they have you set up your server as to leave database.yml publicly available. I see Drupal attacks (xmlrpc.php) every day; it's only a matter of time before I start to see RoR attacks.

It's the developers' job to make it work. It's your job to make it work securely. Today's hackers don't even know C and have never heard of Kernighan and Ritchie; all they need is a script and an Internet connection to take advantage of your vulnerabilities.

Ruby on Rails is the most recently hyped language, so I though about testing it out on my development server. I followed the tutorial available on the RoR website. It went fine until I did a ./scripts/generate command and got lot of syntax errrors:

/usr/lib/ruby/1.8/yaml.rb:133:in `load': syntax error on line 27, col 2: `  host: localhost' (ArgumentError)
 from /usr/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/initializer.rb:459:in `database_configuration'
        from /usr/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/initializer.rb:181:in `initialize_database'
        from /usr/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/initializer.rb:84:in `process'
        from /usr/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/initializer.rb:42:in `run'
        from ../config/../config/environment.rb:13
        from /usr/lib/site_ruby/1.8/rubygems/custom_require.rb:21:in `require'
        from /usr/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:147:in `require'
        from /usr/lib/ruby/gems/1.8/gems/rails-1.1.2/lib/commands/generate.rb:1
        from /usr/lib/site_ruby/1.8/rubygems/custom_require.rb:21:in `require'
        from /usr/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/ 

I started looking around at the folder structure that Ruby installs itself into when you create a new RoR application. Below my main folder, which the tutorial instructed my to create an alias or virtual directory for is the config folder. Inside the config folder is the database.yml file, holding my database information, with accounts and hard-coded passwords. (On my box, it's all localhost only, but still...)

Just to check, I fired up my browser and entered http://myserver/myrailsalias/config/database.yml. All the information popped up. I changed the Apache alias to /mypathtorails/public/ which I didn't see in the tutorial. This seems to be a lot more secure. This doesn't mean RoR is any more or less secure than any other interpreted scripting language for web applications, just that right now, it's easy to install it in a less secure manner.

What's the point? Know what you're installing, where it installs, what permissions it needs, and what context it runs as. And don't put your database.yml someplace where anyone can download it. I know there are websites where I could find it, but I'm not going to try. That doesn't mean someone else isn't writing a bot to find it right now.

Oh, and know how Apache works and httpd.conf works, too. All that is a lot to expect for people looking for a simple programming language.

For a grad school project we need to build a system that bills people by the amount of time they rent a car. Thus, I needed to use the DateDiff function of VB and SQL in Access. I looked it up using Access help and got to the right MSDN page:

Syntax

DateDiff(interval, date1, date2[, firstdayofweek[, firstweekofyear]])

They tell you that interval is a String and link to what a string is. The part they don't say explicitly is that you need to enclose the interval value in quotation marks. "Of course," you say, "It's a string." Is it too much to ask for an example showing it in use with the quotation marks? e.g.

In Microsoft Access:
WHERE (((Rentals.CarOut)=True)) AND ((DateDiff("h",Rentals.DropOffDate,Now())>3));
In Microsoft SQL: (Transact-SQL for SQL 2000/2005)
WHERE (((Rentals.CarOut)=True)) AND ((DateDiff("h",Rentals.DropOffDate,GETDATE())>3));

Where h is the code for hours.

I just wanted to write this down someplace before I forget it. And why must Access and T-SQL be different? Now() doesn't work in T-SQL and GETDATE() doesn't work in Access.

About this Archive

This page is a archive of recent entries in the Programming category.

HDTV is the previous category.

Random is the next category.

Find recent content on the main index or look in the archives to find all content.