SQLI-LABS SERIES PART - 2,3,4,5 In the first part of the series we downloaded the PHP code files and installed them on the backtrack machine or under XAMPP on windows. 第一部分:搭建測試環境 Error based SQL injections:報錯注入 Error Based Sql injection is called so because in this errors are being displaded on the web page, and these errors are used to discover the underlying query. 報錯注入:是由於網頁把錯誤展現出來,而且這些錯誤是用來發現潛在查詢的。 What exactly is SQL injection? 什麼是sql注入 SQL injection is a technique often used to attack databases through a website. SQL injection is a code injection technique that exploits a security vulnerability in a website's software. -- source wikipedia SQL注入是常常被用來經過一個網站來攻擊數據庫的技術。 SQL注入是利用在網站的軟件安全漏洞的代碼注入技術。 - 源維基百科 How does SQL injection happen? Sql注入發生的緣由 Let us take the example of Less-1, the webpage is taking an input through the parameter "ID" and passes it on to the backend database by constructing a query in real time. 打開Less-1,網頁是經過參數「ID」取輸入,並把它送到後端數據庫被實時地構造查詢。 Less-1:第一課 if you open the source of the index.php under Less-1, you would see on line 29:打開Less-1的index.php的第29行 $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; 查詢語句 in here we see that the variable $id is being wrapped around single quotes. 發現id沒有任何過濾; id = ' $id ' , Now when a tester provides a ' or 1=1 then it becomes id = ' ' or 1=1 ' thereby effectively evaluating the complete query as id= empty string or (evaluate one equals one) and escaping the data boundary and getting executed as code. As there is a quote on right side which we either need to handle or comment out remaining part of query. 構造查詢語句 ' or '1'='1 Will work nicely. id = ' ' or '1'='1 ' LIMIT 0,1 ' or 1=1 --+ Will also work. id = ' ' or 1=1 --+ ' commented out ' or 1=1 # will also work. id = ' ' or 1=1 # ' commented out Less-2 line number 31,32 第二課 $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1"; or 1=1 Will work nicely. id = or 1=1 LIMIT 0,1 or 1=1 --+ Will also work. id = or 1=1 --+ or 1=1 # Will also work. id = or 1=1 # SQLI-LABS SERIES PART 6,7 DOUBLE QUERY INJECTIONS OR SUBQUERY INJECTIONS:二次注入或子查詢注入 In the last 5 parts of the series we learnt about some basics about the error based injections and used the UNION statements to dump the database using the web application. Well we could achieve it because the database was interacting with web page and some database fields were visible on the web pages. A basic injection looked like id=-1 union all select 1,2,3 --+ and we were able to see the username name and password field displaying value 2 and 3. 在過去的5個部分的系列,咱們瞭解了有關基於錯誤注入一些基礎知識和使用UNION語句來使用Web應用程序的數據庫。好了,咱們能夠實現它,由於數據庫是使用網頁交互和一些數據庫領域是在網頁上可見的。基本注入看起來ID=-1聯盟的全部選擇1,2,3 - +,咱們可以看到的用戶名名和密碼字段中顯示的值2和3。 In a scenario when the database does not directly display columns on the web page, then the above technique cannot be used. 在當數據庫結果不直接顯示web頁面的狀況下,則上述技術不能被使用。 As we see we just see a generic message "You are in". Therefore in this case, the database is not displaying any files on the page. In this case only way the database is displaying into is through the mysql error. (note: I am interchangeably using the Lesson 5 and 6, only thing different is way to produce error) 正如咱們看到的,咱們只看到一個通用的消息:「You are in」。所以,在這種狀況下,數據庫結果沒有顯示在頁面上。在這種狀況下,惟一的辦法數據庫顯示成是經過MySQL錯誤。(注:我能夠互換使用的第5課和第6課,惟一不一樣的就是這樣產生的偏差) So primary objective in a double query injection is to create a query injection in such a way which is syntactically correct (correct at compile time) but produce an error at run time thereby spitting useful information in the errors. In case of MSSQL server cast errors dumps the info but in case of MYSQL, being flexible returns empty rows. Therefore some genius researchers found a combination of use of aggregate functions, group by clause, and use of random functions to produce errors are run time due to dynamic calculations involved in random function and aggregate function like count. 在二次SQL注入等等主要目的是在這樣一種方式是語法正確(在編譯時是正確的)建立一個查詢,產生注入,但在運行時出現錯誤,從而獲取錯誤的有用信息。若是MSSQL服務器存放錯誤的轉儲信息,但若是是靈活的返回空行(這裏的翻譯有問題,但願大牛指教)。所以,一些天才的研究人員發現,使用聚合函數,group by子句,並利用隨機函數產生錯誤運行時,因爲涉及的隨機函數和聚合函數計算; Less-5 line number 29 第五課 $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; ' or '1'='1 Will work nicely. id = ' ' or '1'='1 ' LIMIT 0,1 ' or 1=1 --+ Will also work. id = ' ' or 1=1 --+ ' commented out ' or 1=1 # will also work. id = ' ' or 1=1 # ' commented out Less-6 line number 28,29 第六課 $id = '"'.$id.'"'; $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1"; " or "1"="1 Will work nicely. id = " " or "1"="1 " LIMIT 0,1 " or 1=1 --+ Will also work. id = " " or 1=1 --+ " commented out " or 1=1 # will also work. id = " " or 1=1 # " commented out SQLI-LABS SERIES PART-8 BLIND INJECTIONS:盲注 Continuing the SQLI-LABS series, we discussed the Error based injections, and discussed Union type injections and double query injections. In today's post we would be discussing Blind injections. Blind injections got this name because during blind injections, you do not get any help from the application. All the errors are suppressed from the end user. 繼續SQLI-LABS系列中,咱們討論了基於注入錯誤,並討論了聯合型注入劑和二次注入。在今天的文章中,咱們將討論盲注。盲注這個名字,由於在盲目進行,你不會從應用程序的任何幫助。全部的錯誤都來自終端用戶抑制。 Therefore complete injection is based on a guess. The tester does not see any error responses to tune his injections. 所以,注入徹底是基於猜想。該測試沒有看到本身注入語句返回的任何錯誤響應。 Blind Injections can be classified mainly into two categories:盲注的分類 Boolean based Blind injections:基於bool的盲注 Time based Blind injections.:基於時間的盲注 Boolean Based:布爾類型的盲注 As per wikipedia "In computer science, the Boolean or logical data type is a data type, having two values (usually denoted true and false), intended to represent the truth values of logic and Boolean algebra. It is named after George Boole, who first defined an algebraic system of logic in the mid 19th century". 按照維基百科「在計算機科學中,布爾邏輯或數據類型的數據類型,有兩個值(一般表示true和false),意在表示邏輯和布爾代數的真值。喬治·布爾,以後它被命名誰第一個定義的邏輯,在19世紀中期的代數系統「。 Well in certain web applications, you can witness that the database does not write any fields on the web page or somehow union injections do not work, and the mysql errors are also not displayed on the page, so technically there is no direct channel through which the database writes on web page. In this case the only option left is to use blind injections. With Blind injections we cannot dump the strings or names directly but need to deduce names character by character. 以及在特定的Web應用程序,你能夠親眼目擊該數據庫不顯示任何事物在網頁上或在某種方式聯合注入不顯示,MySQL的錯誤也不會顯示在頁面上,因此在技術上沒有經過任何直接的渠道把數據庫回顯寫在網頁上。在這種狀況下,剩下的惟一選擇是使用盲注。盲注,咱們不能直接傾倒字符串或名稱,但須要經過角色來演繹角色的名字。 In general when we were dealing with error based injections, we ask the database questions like, dump us the database name, version, table names etc. In case of blind injections, we change the way we ask questions to database and rephrase questions like is the first letter of the database this? and answer comes out as either yes or no or true or false. 通常來講,當咱們處理基於錯誤注入,咱們問這樣的數據庫的問題,咱們轉儲數據庫的名稱,版本,表名等。若是盲注,咱們改變咱們提問到數據庫的方式,另外一種方式的問題,好比是在這個數據庫的第一個字母?並回答出來的是或否或真或假。 Less-8 line number 29 $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; basic injection example: 1' AND '1'='1 -- returns true 1' AND '1'='0 -- returns false Therefore by evaluating the strings character by character we can dump the complete database. 所以由性格評估字符串的字符,咱們能夠轉儲整個數據庫。 SQLI-LABS SERIES PART 9 TIME BASED INJECTIONS:時間注入 In the previous post, we discussed the basics of Blind injections and started to explore Boolean based blind injections. In this blog post we would continue with the Blind injections and discuss TIME based injections. 在前面的文章中,咱們討論了盲注資的基礎知識,並開始探索基於布爾盲注。在這篇博客文章中,咱們將繼續與盲注,並討論基於時間的注射。 In certain web web applications, which are vulnerable but does not disclose errors, nor does the database display any fields on the web pages and neither does it react to physical boolean queries of yes and no meaning we cannot physically differentiate between true and false,in that case, we can use time to distinguish between true and false. This can be achieved by using sleep() function. This function is non cpu intensive and if query is true will wait for some time before returning a response and respond quickly if false. This time difference in page reload gives us the correct characters one by one. 在某些網頁的Web應用程序,它是脆弱的,但沒有透露錯誤,也不在網頁上顯示數據庫任何信息,甚至沒有bool類型的正確判斷,並無任何意義,咱們不能在物理真假區分,在這種狀況下,咱們能夠用時間真假分辨。這能夠經過使用sleep()函數來實現。此功能非CPU密集型的,若是查詢是真的會等待一段時間返回響應以前,若是假的快速響應。在頁面重載這個時間差給了咱們正確的字符一個接一個。 Another way to do time based injections is by use of heavy queries (benchmark queries) which are intensive and consume some CPU cycles if query returns true and are quick if it is false. It is always good to use sleep() function. 另外一種方法作基於時間的注射是使用重查詢(查詢基準),這是密集的,消耗一些CPU週期,若是查詢返回真,很快,若是它是假的。這是一件好事,用sleep()函數。 Less - 9 line number 29 $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; 1'+and+sleep(10)+--+ -- Basic injection to detect sqli 1'+and+if(1=1, sleep(10), null)+--+ -- Returns True ( page load is approx 10 sec) 1'+and+if(1=0, sleep(10), null)+--+ -- Returns False (page load is almost instant) Less-10 line number 28,29 $id = '"'.$id.'"'; $sql="SELECT * FROM users WHERE id=$id LIMIT 0,1"; 1"+and+sleep(10)+--+ -- Basic injection to detect sqli 1"+and+if(1=1, sleep(10), null)+--+ -- Returns True ( page load is approx 10 sec) 1"+and+if(1=0, sleep(10), null)+--+ -- Returns False (page load is almost instant) SQLI-LABS SERIES PART-10 outfile function or dumpfile function:outfile()函數注入 USING THE OUTFILE/DUMPFILE:使用outfile或dunpfile Well if the connection user which is configured to run the queries to the back-end DB has the privileges to write to file system (webroot of server or any other folder under it), then in that case, we can build queries and use the inbuilt function called outfile or dumpfile. example query: select * from table into outfile "path-to-file/filename" 那麼,若是其被配置在鏈接用戶運行查詢後端DB具備特權寫入到文件系統(服務器或根據任何其餘文件夾的根目錄),那麼在這種狀況下,咱們能夠構造查詢,並使用內置的函數調用輸出文件或轉儲文件。 例如查詢:select * from table into outfile "path-to-file/filename" There are two functions which can be used in this case, outfile and dumpfile. With dumpfile, it dumps only one row without any formatting details. This is specially important if you are playing with binary data. The outfile preserves the formatting, carriage returns, etc and dumps multiple rows. 還有,能夠在這種狀況下,輸出文件和轉儲文件可使用兩種功能。與轉儲文件,它轉儲只有一行不帶任何格式的詳細信息。這是特別重要的,若是你在玩的二進制數據。該輸出文件保存格式,回車等,並轉儲多行。 same way we can use mysql to read files from the file system. for that we can use the function called load_file(). By default we cannot execute system commands through mysql, but if mysql is misconfigured, then can lead to upload of User Defined Functions which can lead to a complete compromise of server. 一樣,咱們能夠用mysql從文件系統中讀取文件。爲此,咱們可使用函數調用LOAD_FILE()。默認狀況下,咱們沒法經過執行mysql的系統命令,可是若是MySQL配置不正確,則可能會致使上傳用戶定義函數,可致使服務器的一個完整的妥協。 example injection may look like: 例如 ' union select 1,load_file("/etc/passwd"),3 into dumpfile "/var/www/test.txt" Less -7 Line number 31 $sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1"; 1'))+or+1=1--+ -- Basic injection to detect sqli SQLI-LABS SERIES PART-11 Today we will discuss about the injections in the forms. In the last 11 lessons of the series we discussed injections via the GET request. When I had started to learn this topic, I realized that a lot of stuff was available on internet for the GET based injections but POST injections were rarely discussed. That increased curiosity in me much and this was the point when i started this lab. The forms , lesson 11 to 20 are different implementations similar to GET method. We would cover : 今天咱們將討論有關在形式注射。在本系列的最後11個課程,咱們經過GET請求所討論的注入。當我開始學習這個話題,我意識到,在互聯網上有不少東西是可用於基於GET注入,但POST注入不多討論。在個人好奇增長了不少,這是一點,當我開始這個實驗。11-20是不一樣的實現方式相似於get方法。咱們將覆蓋(將開始討論POST注入) Error based injections:報錯注入 Double Query injections:二次注入 Boolean based Blind injections:布爾盲注 Time based Blind Injections:時間盲注 Injections in update query:執行更新注入 Injections in the Headers:refer頭注入 Injections in cookies:cookie注入 POST BASED INJECTIONS:post注入 In general, nothing changes with the change in injection point. The logic for injection remains the same, the process remains the same. In a general scenario we take up Less-11 and 12 for this. As the page displays a login field. therefore we can build our first sudo query; 在通常狀況下,沒有用在注入點的變化而變化。用於注射的邏輯保持相同,則過程保持相同。在通常狀況下,咱們採起了11和12課這一點。因爲頁面顯示登陸域。所以,咱們能夠創建咱們的第一個sudo的查詢: SELECT * FROM table WHERE username="$uname" and password="$password". The basic steps involved in the testing to exploitation are: 參與測試開發的基本步驟以下: 1.Fuzzing: Try to give random inputs to all points where it is accepted, be creative and send the values which the developer has failed to visualize. Objective is to try to break the underlying query and gain more insite on how the query is formulated by reviewing error. 1,模糊測試:儘可能給隨機輸入到被接受,敢於創新,發送該開發商並無想象中的值的全部點。目的是嘗試打破基礎查詢,並得到關於如何查詢是經過檢查錯誤制定更INSITE。 2.Then try to fix the query by either providing the extra characters to balance off what we injected to break the query or comment off rest of query in such a way that it gets fixed. 2,而後,嘗試經過提供額外的字符,以平衡掉了咱們注入到中斷查詢或以這樣一種方式,它被固定評斷的查詢其他修正該查詢。 3.Once we successfully achieved the above, we effectively get the left side, and right side of the injection and sql statement we inject in between these gets executed on backend. 3.一旦咱們成功地實現了上述狀況,咱們有效地得到左側和右側,咱們投放在這些之間的注入和SQL語句獲取對後端執行。 As discussed in the previous post on error based injections, we used the UNION SELECT to dump the DB because the database layer was interacting with the web page and columns from table were visible on screen. same way we can see that a successful login leads to display of the username and password. 正如在之前的帖子上基於錯誤注入的討論,咱們用UNION SELECT轉儲數據庫,由於數據庫層用網頁和列從表中的互動都顯示在屏幕上。一樣,咱們能夠看到,一個成功的登陸會致使顯示的用戶名和密碼。 This can then be used to dump the database. 這能夠被用來轉儲數據庫。 Less-11 line number 57 @$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1"; ' or '1'='1 Will work nicely if injected in username and password field. username = ' ' or '1'='1 ' AND password = ' ' or '1'='1 ' ' or 1=1 --+ Will also work only in one field. username = ' ' or 1=1 --+ ' commented out ' or 1=1 # will also work only in one field. username = ' ' or 1=1 # ' commented out Less-12 Line 57,58,59 $uname='"'.$uname.'"'; $passwd='"'.$passwd.'"'; @$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1"; ") or ("1")=("1 Will work nicely. username = (" ")or ("1")=("1 ") AND password = (" ")or ("1")=("1 ") ") or 1=1 --+ Will also work. username = (" ")or 1=1 --+ ") commented out ") or 1=1 # will also work. username = (" ") or 1=1 # ") commented out SQLI-LABS SERIES PART 12 In the last part we started to explore the error based sql injections in the POST parameters. We were able to use the UNION statements to dump the database of the test bed. In a situation when the database does not interact with the web page and only was the database displays some info on the web page is through the mysql errors. Then in this case the fastest way to extract the info is through use of type caste errors involving sub queries also referred to as double queries, but MYSQL is very flexible and returns empty rows rather than throwing an error, so infosec guru's figured out some combinations of functions, if combined make sql queries which pass the compile time check but throw run-time errors. With the errors dumps the useful info which is needed. 在最後一部分,咱們開始探索在POST參數基於錯誤的SQL注射。咱們可使用UNION語句來轉儲試驗檯的數據庫。在這種狀況時,該數據庫不與網頁交互,並僅是在數據庫顯示在網頁上的一些信息是經過MySQL的錯誤。那麼在這種狀況下,提取的信息以最快的方式就是經過使用包括子查詢,也被稱爲二次查詢類型種姓的錯誤,但MySQL是很是靈活的,會返回空行,而不是拋出一個錯誤,所以信息安全大師的想通了一些組合的功能,若是它經過了編譯時檢查,但拋出運行時錯誤結合使SQL查詢。隨着錯誤轉儲所須要的有用的信息。 DOUBLE QUERY INJECTIONS:二次注入 As these involve sub query injections, the focus is to use the internal query to dump the info we want and wrap around a query which is syntactically correct, passing the compile time checks and produces error at run time and in process spit the core query as part of error. 因爲這些涉及到的子查詢注入,重點是使用內部查詢轉儲咱們想要的信息,並環繞查詢的語法正確,通過編譯時檢查,並在運行時產生的錯誤,並在過程當中吐出的核心查詢做爲錯誤的部分。 Basic query to cause injections :基於查詢形成的注入 Less-13 line number 57 @$sql="SELECT username, password FROM users WHERE username=('$uname') and password=('$passwd') LIMIT 0,1"; ') or ('1')=('1 Will work nicely if injected in username and password field. username = (' ') or ('1')=('1 ') AND password = (' ') or ('1')=('1 ') ') or 1=1 --+ Will also work only in one field. username = (' ') or 1=1 --+ ' commented out ') or 1=1 # will also work only in one field. username = (' ') or 1=1 # ' commented out Less-14 Line 57,58,59 $uname='"'.$uname.'"'; $passwd='"'.$passwd.'"'; @$sql="SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1"; " or "1"="1 Will work nicely. username = " " or "1"="1 " AND password = " " or "1"= "1 " " or 1=1 --+ Will also work. username = " " or 1=1 --+ " commented out " or 1=1 # will also work. username = " " or 1=1 # " commented out SQLI-LABS SERIES PART 13 INJECTION IN UPDATE QUERY:執行更新注入 In the earlier parts of the series we looked at the GET and POST based injections and dived into details on error based SQL Injections (string type, Integer type), Double Query injections error based, Blind injections (Boolean based and Time based) or use the outfile/dumpfile to . In this part we would look at the injections in the update Query. 在本系列的早期部分,咱們看了一下基於GET和POST注入一頭扎進基於SQL注入的錯誤的詳細信息(字符串型,整型),二次查詢注入基於錯誤,盲目注入(布爾型和基於時間)或使用在輸出文件/轉儲文件,以。在這一部分,咱們將看看在更新查詢的注射。 A general update query looks like 通常更新查詢樣子:UPDATE TABLE SET PARAMETER-1="some value" WHERE PARAMETER-2="some value"; In the general case, a front end for a password update or profile update would have this query working in the backend. During a pentest be extra careful while handling these queries, because one wrong test can update the complete production database with wrong values. 在通常狀況下,對於一個密碼更新或配置文件更新的前端會有這種查詢在後臺工做。在一次測試中要格外當心,而處理這些質疑,由於一個錯誤的測試有更新完整的數據庫錯誤的產生價值。 In the update statement injection, our objective is to extract info and not update the database, therefore we can use the the basics of 在update語句注入,咱們的目標是提取信息,並及時更新數據庫,所以咱們可使用的基本知識: Double query injection Blind injection Dumpfile/outfile to extract the information. Basic query injections Less-17 Line number 97 $update="UPDATE users SET password = '$passwd' WHERE username='$row1'"; SQLI-LABS SERIES PART-15 INJECTION IN THE INSERT QUERY:插入執行注入 INJECTION IN HEADERS:refer頭注入 通常插入查詢樣子:INSERT INTO table (col1,col2, col3) values (val1,val2, val3); "Less-18 - INJECTION IN THE USERAGENT FIELD" "Less-19 - INJECTION IN THE REFER FIELD." For the purpose of fuzzing these input points we need to write a script or use interceptor proxies like Tamper data (add on for Firefox), Burp suite, Fiddler, Zap, or any other tool which allows you to modify the headers on the fly. 對於這些模糊測試輸入點的目的,咱們須要編寫一個腳本或使用攔截器代理類數據防篡改(加上用於Firefox),burpsuit,Fiddler,ZAP,或任何其餘工具,它容許你修改標題。 These sort of injections where the Header fields are being inserted into the database, our focus is to check if the data can be extracted from it is certain way. Well blind is always an option and we can use Boolean or time based injections. The process works but is overall slow. 這些地方的頭字段排序被插入到數據庫中注入的,咱們的重點是,以檢查是否能夠數據形式提取它。固然盲目始終是一個選項,咱們可使用布爾或基於時間的注射。該過程的工做,但整體緩慢。 In cases where MySQL errors are displayed by the application, this can be used to dump the values efficiently and with much lesser number of queries as compared to Blind based. The logic of Double query injections is used to dump the info. 在其中顯示由應用MySQL的錯誤的狀況下,這能夠被用來有效地和以比盲基於查詢的小得多的數目傾倒的值。二次查詢注射的邏輯是用來轉儲信息。 SQLI-LABS SERIES PART-16 SQL Injection via COOKIES:cookie注入 As we discussed before in the earlier posts, enumeration is the first and very essential part of every penetration test. Knowing the workflow of application is trivial to its testing. The more one knows about the application, the better and effective it becomes. Secondly, all input parameters should be tested. These do not include just the form fields, but also the other input fields like the referrers, user-agent, cookies. Developers these days take care to sanitize the the form inputs and take extra care for those but forget to pay the same attention to the other inputs. We discussed the injection in update query and injection in the headers in our previous lessons. In this lesson we will discuss the injection via cookies. Technically speaking, it is trivial to understand, how cookies are being generated by application and how the same is used within application. Understanding the cookie generation logic is trivial to the successful testing. In Less-20, we introduce the basics and use a clear text cookie generation logic to explain. There is no difference in how the injection is performed via a cookie or any other form parameter. In Less-20 and 21 we deal with error based injections. Less-21 uses an encoded cookie value and the application logic is used to encode and decode the data and use the result in the queries later on. For Less-21 we observe that the system is using Base64 encoding scheme to send an encoded cookie to the browser. Hence forth we need to encode our injections using Base64 to be consumed nicely by the web application. SQLI-LABS SERIES PART-17 SECOND ORDER INJECTIONS:二次排序注入 What are second order injection? Second order injections can be considered simmilar to the stored XSS. Injection does not directly yeild result but this injection is used at some other places insecurely causing the injection to trigger and yield results. As an Example to understand this imagine an application which allows user to create a user account in the system. Now a malicious user can try to inject SQL keywords in the user creation form which is nicely escaping dangerous characters by use of mysql_real_escape_string() and making it safe for that form. Because mysql_real_escape_string() escapes the dangerous chars, therefore if attacker tries to inject admin' OR 1=1-- in the username field, because of the function, the quotes would be escaped and input would become admin\' or 1=1--. If other values of form are valid, the user account is created with the name admin' OR 1=1-- . Now with the user created, he can login with newly created account and go to the password reset page. As this page is checking for old password , and building up a query behind the scene something like UPDATE users SET passwd="New_Pass" WHERE username="Username" and passwd="oldpassword" Now as the username is being taken from the database, the developer treats this as trusted info. As he is confident that initially there is no SQL Injection on the pages. This blind trust on the data from database is called without any escaping, thereby causing the username to trigger the SQL injection. The query becomes UPDATE users SET passwd="New_Pass" WHERE username =' admin' -- ' AND password=' old password '. Effectively SQLi working and changing the password of Admin user commenting out rest of query which is marked in brown