2014-07-19 5 views
3

다음 쿼리는 tbl_user 테이블의 모든 암호를 반환하지만이 문제가 발생한 이유를 이해할 수 없습니다.'admin'의 의미 OR 1 = '-

SELECT password FROM tbl_users WHERE name = 'admin' OR 1=1 -- ' 

나 쿼리의이 부분을 이해하는 데 도움이 바랍니다 : '관리자'OR 1 = 1 - '

당신이 (, 웹 사이트, 책 등)과 같은 다른 위협을 소개 할 수 있습니까?

+3

이되도록

SELECT password FROM tbl_users 

고전적인 SQL 인젝션. 이름이'admin' * OR * 인 사용자를 리턴합니다. 1 = 1입니다 (1은 실제로 모든 레코드가 일치하므로 1).'--'는 주석으로 본 후에 eveyrthing을 확인합니다. – PeeHaa

+0

아무것도하지 않으므로 1 = 1을 제거 할 수 있습니다. – Gadgetster

+0

@Gadgetster 무엇을 의미합니까? – PeeHaa

답변

6

이것은 고전적인 SQL 인젝션입니다. SQLfiddle이 예에서

, 5 사용자가 테이블에 추가되고있다 : 나는 그것을 설명하면서

이 바이올린을 참조하십시오. 그런 다음 쿼리가 실행됩니다. 예상 결과는 admin 사용자에 대해서만 암호 값을 반환하는 것입니다.

그러나 진실한 진술 인 1=1을 추가하면 모든 암호가 반환됩니다.

시각화하는 데 도움이되는 또 다른 방법은 모든 것이 평가되는 방식을 볼 수 있도록 괄호를 추가하는 것입니다.

SELECT pass FROM users WHERE (user_name = 'admin')    OR (1=1) -- ' 
           ^Pulls only the admin user  ^Pulls everything because 1=1 

그래서 우리는 사용자 이름이 admin입니다 테이블에서 암호를 선택합니다. 또한 1 = 1 인 테이블에서 암호를 가져 오는 중입니다. 이는 항상 사실입니다. 각 행은 true로 평가되므로 모든 암호가 반환됩니다.

마지막 -- '은 나머지 검색어를 주석 처리하는 데 사용됩니다.

SELECT pass from users WHERE user_name = 'admin' or (1=1) -- 'and permission='superadmin' 

일반적으로는합니다 (1=1가 주입되지 않은 경우), 당신은 관리자 및 최고 관리자 권한의 사용자 _ 이름을 가진 사용자의 암호를 풀 것입니다. 당신은 이제 그것을 주석 처리했으며 실행되지 않습니다. 이것이 전체 암호 테이블을 반환하는 방법입니다.

+0

논리적 인 부분뿐만 아니라이 작업을 충분히 수행했다고 생각합니다.하지만이 익스플로잇이 쿼리의 의도를 어떻게 바꾸고 어떻게 확장 할 수 있는지 생각해보십시오. – VMai

-2

나는 대신 'OR'은

'OR'수단을 찾고 'AND'하는 생각 (이름 = '관리자'OR 1 = 1) 참이어야하는 조건 중 하나,이에 경우, 그것은 '관리'에 동일한 이름을 가진 모든 것을 반환, 또는 1과 동일한 1에

이 대신 사용해보십시오 있습니다

SELECT password FROM tbl_users WHERE name = 'admin' AND 1=1 
+4

쿼리는 실제로 원래 작성자가 의도 한 것이 아니며 모든 상황에서 행을 반환하기 위해 널리 사용되는 크래킹 구문이며 SQL 주입 취약점을 이용합니다. 그 맥락에서 'OR'형식은 크래커가 원하는 것입니다. – halfer

+0

오, 오, 죄송합니다.이 물건을 처음 접했고, 제가 아는 작은 것을 도왔습니다. 말해 주셔서 감사합니다. – Duane

+0

걱정할 필요가 없습니다. '1 = 1'_preceded_ 나머지 'WHERE' 절 - 여러 개의 선택적인 영구 조항이있는 경우 쿼리 빌더 라이브러리에서 많이 사용됩니다. 이것은 새로운 구문을 단순화하기 때문입니다. 모든 새로운 절은'AND (clause)'형식입니다. – halfer

4

논리적 OR의 결과는 다음과 같습니다 :

a  | b  | a OR b 
----------------------- 
false | false | false 
false | true | true 
true | false | true 
true | true | true 

피연산자 중 하나가 참이면 OR b의 결과는 참으로 평가됩니다.

1 = 1 evaluates to true 

=>

(any expression) OR 1 = 1 evaluates to true 

=>

name = 'admin' OR 1 = 1 

은 테이블의 모든 행에 대해 true로 평가

결과 :

SELECT password FROM tbl_users WHERE name = 'admin' OR 1=1 -- ' 
으로는 SQL 주석의 시작입니다
-- 

PeeHaa

에 의해 명시된 때문에

은 관리자에 대한뿐만 아니라, 모든 사용자에 대해 암호를 반환합니다.

2

내가 여기에서 겪을 수있는 2 가지 혼란이 있습니다. 첫 번째는 다른 사람들이 언급했듯이 expr1 OR expr2expr1 또는 expr2이 true 일 때 true를 반환합니다. 1=1은 항상 true이므로 테이블의 모든 레코드에 대해 WHERE 문이 true입니다.

두 번째로 혼란스러운 점은 쿼리에서 마지막으로 -- '입니다. --은 PHP에서 //에 해당하는 SQL입니다. 줄의 나머지 부분은 주석이며 무시해야 함을 나타냅니다. 따라서 SQL 인터프리터는 SELECT password FROM tbl_users WHERE name = 'admin' OR 1=1을 읽고 나머지 줄을 무시하므로 그 작은 따옴표로 인해 구문 오류가 발생하지 않습니다.

유일한 보안 위험은 이스케이프 처리되지 않은 사용자 입력을 SQL에 전달하는 경우입니다. 항상 사용자 입력을 mysqli_real_escape_string 또는 이와 동등한 함수로 이스케이프 처리 한 다음 SQL 쿼리에서 사용하십시오.

편집 : 주석에서 지적했듯이 매개 변수가있는 쿼리는 일반적으로 각 입력 요소를 수동으로 이스케이프 처리하는 것보다 나은 방법입니다. PHP의 PDO 확장은이 접근법을 시작하기에 좋은 장소입니다.

+1

IMO, escaping 및 concatenation보다 parameterisation을 사용하는 것이 좋습니다. 후자는 열 이름과 같이 매개 변수화 할 수없는 항목에만 사용해야합니다. – halfer

+1

@halfer 필자는 실수를하는 것이 어렵 기 때문에 parameterisation이 코드 연습으로 이스케이프 + 연결보다 낫다는 것에 동의합니다. 답변에 대한 참조를 편집합니다. –

0

마지막 부분 인 -- '은 주석이므로 MySQL은 상관하지 않습니다. 결과는 항상 동일합니다 - (1) 동일 물론 예를 들어 같은 다른 진정한 표현 2=2 또는 'a'='a' 그것은 여기에있을 수있는 1입니다 때문에 그래서 우리는 더이 쿼리에서

SELECT password FROM tbl_users WHERE name = 'admin' OR 1=1 

을 떠난 1=1 사실입니다.

그래서 쿼리는 다음과 같이 수 : 조건 중 하나에 해당하는 경우는, 전체 표현식이 참 것을 의미 이런 식으로 작동 OR

SELECT password FROM tbl_users WHERE name = 'admin' OR true 

운영자. 표현에서 name = 'admin' OR true 하나의 표현 (사실은 사실이다) 사실 그래서이 모든 표현은 그래서 쿼리 지금 이제 우리는 우리가 WHERE true이 WHERE 부분을 보면

SELECT password FROM tbl_users WHERE true 

true

입니다. 그것은 드 아무 조건이없는 사실상 의미한다, 그래서 우리는에 쿼리를 변경할 수 있습니다 : 당신이 당신의 테이블의 각 레코드에 대해 쿼리 간단한 GET 열 password를 참조로 (아마 모든 사용자에 대해)

+0

죄송합니다. 다음 쿼리가 작동하지 않는 이유를 알려주십시오. 'SELECT name FROM list WHERE name = true - '' – Daniyal

+0

@Daniyal, 문제가 있다면 항상 어떻게되는지 설명하십시오 (오류가 없습니까? 충돌? 등). 이 경우 문자열 열과 부울 상수를 비교할 가능성이 높습니다. – halfer

+0

@halfer MR @ Marrcin, 고마워요, 다음 쿼리가 빈 결과 집합을 반환하는 이유를 도와 주시겠습니까? 'SELECT name FROM list WHERE name = true - '' – Daniyal