Search
Search titles only
By:
Search titles only
By:
Log in
Register
Search
Search titles only
By:
Search titles only
By:
Menu
Install the app
Install
Forums
New posts
All threads
Latest threads
New posts
Trending threads
Trending
Search forums
What's new
New posts
New ads
New profile posts
Latest activity
Free Ads
Latest reviews
Search ads
Members
Current visitors
New profile posts
Search profile posts
Contact us
Latest ads
එක පැකේජ් එකයි මාසෙටම Unlimited Internet. තාමත් DATA CARD දාන්න සල්ලි වියදම් කරනවද? අඩුම මිලට අපෙන්.
sayuru bandara
Updated:
Tuesday at 12:30 PM
Ad icon
ඉන්ටර්නෙට් එකෙන් හරියටම සල්ලි හොයන්න සහ Success වෙන්න කැමතිද? 🚀 (E-Money & Success Stories)
siri sumana
Updated:
Saturday at 11:44 PM
Gemini AI PRO 18 months Offer
Hawaka
Updated:
May 27, 2026
Ad icon
koko account
DasunEranga
Updated:
May 27, 2026
Ad icon
koko account
DasunEranga
Updated:
May 27, 2026
Electronics
Vehicles
Property
Search
Reply to thread
Forums
General
ElaKiri Talk!
SQL Injection for SQL Databases.!
Get the App
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an
alternative browser
.
Message
<blockquote data-quote="Core" data-source="post: 8977251" data-attributes="member: 263471"><p><strong>Finding the table name</strong></p><p></p><p> 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 <strong>subselect</strong>. </p><p> A standalone query of </p><p> SELECT COUNT(*) FROM <em>tabname</em> 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: </p><p> SELECT email, passwd, login_id, full_name FROM <em>table</em> WHERE <strong>email</strong> = 'x' AND 1=(SELECT COUNT(*) FROM <em>tabname</em>); --'; 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 <strong>members</strong> was a valid table in the database. But is it the table used in <strong>this</strong> query? For that we need yet another test using <strong>table</strong>.<strong>field</strong> notation: it only works for tables that are actually part of this query, not merely that the table exists. </p><p> 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. </p><p> <strong>Finding some users</strong></p><p></p><p> At this point we have a partial idea of the structure of the <strong>members</strong> 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. </p><p> 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. </p><p> The idea is to submit a query that uses the <strong>LIKE</strong> 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. <strong>Warning</strong>: 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. </p><p> We can do the query on email name or full name (or presumably other information), each time putting in the <strong>%</strong> wildcards that <strong>LIKE</strong> supports: </p><p> 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 <strong>LIKE</strong> clause narrowly. </p><p> Ultimately, we may only need one valid email address to leverage our way in. </p><p> <strong>Brute-force password guessing</strong></p><p></p><p> 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. </p><p> 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, <strong>bob@example.com</strong> and try multiple passwords. </p><p> 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. </p><p> 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. </p><p> <strong>The database isn't readonly</strong></p><p></p><p> So far, we have done nothing but <strong>query</strong> the database, and even though a <strong>SELECT</strong> is readonly, that doesn't mean that <strong>SQL</strong> 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. </p><p> The most drastic example is: </p><p> SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x'; DROP TABLE members; --'; -- Boom! The first part provides a dummy email address -- <strong>'x'</strong> -- 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 <strong>members</strong> table, which really doesn't seem too sporting. </p><p> This shows that not only can we run separate SQL commands, but we can also modify the database. This is promising. </p><p> <strong>Adding a new member</strong></p><p></p><p> Given that we know the partial structure of the <strong>members</strong> 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. </p><p> 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: </p><p> 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: </p><p> </p><ol> <li data-xf-list-type="ol">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).</li> <li data-xf-list-type="ol">The web application user might not have <strong>INSERT</strong> permission on the <strong>members</strong> table.</li> <li data-xf-list-type="ol">There are undoubtedly other fields in the <strong>members</strong> table, and some may <em>require</em> initial values, causing the <strong>INSERT</strong> to fail.</li> <li data-xf-list-type="ol">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.</li> <li data-xf-list-type="ol">A valid "member" might require not only a record in the <strong>members</strong> table, but associated information in other tables (say, "accessrights"), so adding to one table alone might not be sufficient.</li> </ol><p> 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. </p><p> 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. </p><p> We ended up going down a different road. </p><p> <strong>Mail me a password</strong></p><p></p><p> We then realized that though we are not able to add a new record to the <strong>members</strong> database, we can <strong>modify</strong> an existing one, and this proved to be the approach that gained us entry. </p><p> From a previous step, we knew that <strong>bob@example.com</strong> had an account on the system, and we used our SQL injection to update his database record with <strong>our</strong> email address: </p><p> 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 <strong>UPDATE</strong> wouldn't have registered with the application, so it executed quietly. </p><p> We then used the regular "I lost my password" link - with the updated email address - and a minute later received this email: </p><p> From: <a href="mailto:system@example.com">system@example.com</a> To: <a href="mailto:steve@unixwiz.net">steve@unixwiz.net</a> Subject: Intranet login This email is in response to your request for your Intranet log in information. Your User ID is: bob Your password is: hello 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 <strong>INSERT</strong> approach. </p><p> 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. </p><p> 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. </p><p></p><p></p><p></p><p>Finding the table name</p><p></p><p>The application's built-in query a</p></blockquote><p></p>
[QUOTE="Core, post: 8977251, member: 263471"] [B]Finding the table name[/B] 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 [B]subselect[/B]. A standalone query of SELECT COUNT(*) FROM [I]tabname[/I] 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 [I]table[/I] WHERE [B]email[/B] = 'x' AND 1=(SELECT COUNT(*) FROM [I]tabname[/I]); --'; 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 [B]members[/B] was a valid table in the database. But is it the table used in [B]this[/B] query? For that we need yet another test using [B]table[/B].[B]field[/B] 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. [B]Finding some users[/B] At this point we have a partial idea of the structure of the [B]members[/B] 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 [B]LIKE[/B] 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. [B]Warning[/B]: 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 [B]%[/B] wildcards that [B]LIKE[/B] 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 [B]LIKE[/B] clause narrowly. Ultimately, we may only need one valid email address to leverage our way in. [B]Brute-force password guessing[/B] 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, [B]bob@example.com[/B] 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. [B]The database isn't readonly[/B] So far, we have done nothing but [B]query[/B] the database, and even though a [B]SELECT[/B] is readonly, that doesn't mean that [B]SQL[/B] 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 -- [B]'x'[/B] -- 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 [B]members[/B] 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. [B]Adding a new member[/B] Given that we know the partial structure of the [B]members[/B] 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: [LIST=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). [*]The web application user might not have [B]INSERT[/B] permission on the [B]members[/B] table. [*]There are undoubtedly other fields in the [B]members[/B] table, and some may [I]require[/I] initial values, causing the [B]INSERT[/B] to fail. [*]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. [*]A valid "member" might require not only a record in the [B]members[/B] table, but associated information in other tables (say, "accessrights"), so adding to one table alone might not be sufficient. [/LIST] 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. [B]Mail me a password[/B] We then realized that though we are not able to add a new record to the [B]members[/B] database, we can [B]modify[/B] an existing one, and this proved to be the approach that gained us entry. From a previous step, we knew that [B]bob@example.com[/B] had an account on the system, and we used our SQL injection to update his database record with [B]our[/B] 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 [B]UPDATE[/B] 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: From: [email]system@example.com[/email] To: [email]steve@unixwiz.net[/email] Subject: Intranet login This email is in response to your request for your Intranet log in information. Your User ID is: bob Your password is: hello 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 [B]INSERT[/B] 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. Finding the table name The application's built-in query a [/QUOTE]
Insert quotes…
Verification
Hath warak paha keeyada? (hatha wadikireema paha)
Post reply
Top
Bottom