PHP에서 완전 금지되는 SQL 인젝션 공격 중 하나
1. 인젝션 공격의 종류
공격 동기에는 여러 가지가 있을 수 있지만 얼핏 보면 더 많은 유형이 존재한다는 것입니다. 이는 매우 사실입니다. 악의적인 사용자가 여러 쿼리를 수행할 수 있는 방법을 발명한 경우입니다. 이에 대해서는 이 기사의 뒷부분에서 자세히 논의하겠습니다.
스크립트가 SELECT 명령을 실행하는 경우 공격자는 아래와 같이 WHERE 절에 '1=1'과 같은 조건을 삽입하여 테이블의 모든 행을 강제로 표시할 수 있습니다( 주입 부분은 굵게 표시됨):
SELECT * FROM wines WHERE 다양성 = 'lagrein' OR 1=1;'
우리가 앞서 논의한 바와 같이, 이는 테이블의 일반적인 구조(일반 기록으로는 볼 수 없는 것)뿐만 아니라 기밀 정보 기록이 포함된 매복 디스플레이를 보여주기 때문에 그 자체로 유용한 정보가 될 수 있습니다.
업데이트된 명령 매복 공격이 더욱 직접적인 위협이 됩니다. SET 절에 다른 속성을 배치함으로써 공격자는 다음 예(주입된 부분이 굵게 표시됨)와 같이 현재 업데이트된 레코드의 모든 필드를 수정할 수 있습니다.
UPDATE wines SET type=' red', 'vintage'='9999' WHERE Variant = 'lagrein'
1=1 등의 상수를 넣어 WHERE 절에 조건을 추가합니다. 이 수정 범위는 다음 예(주입 부분이 굵게 표시됨)와 같이 각 레코드로 확장될 수 있습니다.
UPDATE wines SET type= 'red', 'vintage' ='9999 WHERE 다양성 = 'lagrein' OR 1=1;'
아마도 가장 위험한 명령은 DELETE일 것입니다. 상상하기 어렵지 않습니다. 주입 기술은 이미 본 것과 유사합니다. 다음 예(주입 부분이 굵게 표시됨)와 같이 WHERE 절을 수정하여 영향을 받는 레코드의 범위를 확장합니다.
DELETE FROM wines WHERE 다양성 = 'lagrein' OR 1=1;'
2. 다중 쿼리 삽입
다중 쿼리 삽입은 잠재력을 증가시킵니다. 쿼리에 여러 개의 손상 명령이 포함되도록 허용하면 공격자가 손상을 입힐 수 있습니다. MySQL 데이터베이스를 사용할 때 공격자는 쿼리에 예상치 못한 종결자를 삽입하여 이를 쉽게 달성할 수 있습니다. 삽입된 따옴표(단일 또는 이중)는 끝에 예상되는 변수를 표시한 다음 세미콜론을 적용하여 지시문을 종료합니다. 이제 종료된 원래 명령 뒤에 추가 공격 명령을 추가할 수 있습니다. 궁극적인 피해를 주는 쿼리는 다음과 같습니다.
SELECT * FROM wines WHERE 다양성 = 'lagrein';
GRANT ALL ON *.* TO 'BadGuy@%' IDENTIFIED BY 'gotcha'; >
이 주입은 새로운 사용자 BadGuy를 생성하고 그 중 네트워크 권한(모든 테이블에 대한 모든 권한)을 부여합니다. 이 간단한에는 '불운한' 비밀번호가 추가됩니다. SELECT 문. 프로세스 사용자의 권한을 엄격하게 제한하기 위해 이전 기사의 조언을 따랐다면 웹 서버 데몬에는 취소한 GRANT 권한이 더 이상 없기 때문에 이 방법은 작동하지 않습니다. 그러나 이론적으로 이러한 공격은 BadGuy에게 데이터베이스에 대한 통제권을 자유롭게 부여할 수 있습니다.
이러한 다중 쿼리가 MySQL 서버에서 처리되는지 여부에 대한 결론은 고유하지 않습니다. 이 중 일부는 MySQL의 다른 버전으로 인해 발생할 수 있지만 대부분은 여러 쿼리가 존재하는 방식으로 인해 발생합니다. MySQL의 모니터링 프로그램은 이러한 쿼리를 완벽하게 허용합니다. 일반적으로 사용되는 MySQL GUI-phpMyAdmin은 최종 쿼리 이전의 모든 이전 내용을 복사하고 이 작업만 수행합니다.
그러나 주입 컨텍스트에서 대부분의 다중 쿼리는 PHP의 mysql 확장으로 처리됩니다. 다행스럽게도 기본적으로 쿼리에서 여러 명령을 실행할 수 없습니다. 두 명령(예: 위에 표시된 주입)을 실행하려고 하면 오류가 발생하지 않으며 출력 정보도 없습니다. 이 경우, PHP는 기본 동작을 "단계적으로" 구현하지만 대부분의 간단한 주입 공격으로부터 사용자를 보호합니다.
PHP5의 새로운 mysqli 확장(http://php.net/mysqli 참조)은 mysql과 마찬가지로 본질적으로 다중 쿼리를 지원하지 않지만 mysqli_multi_query() 함수를 제공하여 구현을 지원합니다. 다중 쿼리 - 정말로 그렇게 하고 싶다면.
그러나 PHP5에 번들로 제공되는 내장형 SQL 데이터베이스 엔진인 SQLite(http://sqlite.org/ 및 http://php.net/sqlite 참조)의 상황은 더욱 심각해 주목을 받고 있습니다. 응용 프로그램의 용이성으로 인해 많은 수의 사용자가 있습니다. 어떤 경우에는 데이터베이스가 일괄 쿼리, 특히 일괄 INSERT 문 처리를 매우 효율적으로 최적화할 수 있기 때문에 SQLite는 기본적으로 이러한 다중 명령 쿼리를 허용합니다. 그러나 쿼리 결과가 스크립트에서 사용되는 경우(예: SELECT 문을 사용하여 레코드를 검색하는 경우) sqlite_query() 함수는 여러 쿼리 실행을 허용하지 않습니다.
3. INVISION Power BOARD SQL 인젝션 취약점
Invision Power Board는 잘 알려진 포럼 시스템입니다. 2005년 5월 6일 로그인 코드에서 SQL 주입 취약점이 발견되었습니다. 발명자는 GulfTech Security Research의 James Bercegay입니다.
이 로그인 쿼리는 다음과 같습니다.
$DB->query('SELECT * FROM ibf_members WHERE id=$mid AND Password='$pid'');
Where , 회원 ID 변수 $mid 및 비밀번호 ID 변수 $pid는 다음 두 줄의 코드를 사용하여 my_cookie() 함수에서 검색됩니다.
$mid = intval($std->my_getcookie('member_id ')) ;
$pid = $std->my_getcookie('pass_hash');
여기서 my_cookie() 함수는 다음 명령문을 사용하여 쿠키에서 요청된 변수를 검색합니다.
return urldecode($ _COOKIE[$ibforums->vars['cookie_id'].$name]);
【참고】이 쿠키에서 반환된 값은 기본적으로 처리되지 않습니다. $mid는 쿼리에 적용되기 전에 정수로 강제 변환되지만 $pid는 변경되지 않습니다. 따라서 앞서 설명한 주입 유형의 공격에 취약합니다.
따라서 my_cookie() 함수를 다음과 같이 수정하면 이 취약점이 노출됩니다.
if ( ! in_array( $name, array('topicsread', 'forum_read', 'collapseprefs) ') ) )
{
return $this->
clean_value(urldecode($_COOKIE[$ibforums->vars['cookie_id'].$name])) ;
}
else
{
return urldecode($_COOKIE[$ibforums->vars['cookie_id'].$name]);
}
이러한 수정 후 전역 clean_value() 함수를 '통과'한 후 주요 변수가 반환되고 다른 변수는 확인되지 않습니다.
이제 SQL 인젝션이 무엇인지, 인젝션 원리와 이 인젝션의 취약점에 대해 전반적으로 이해했으니, 이를 효과적으로 방지하는 방법을 살펴보겠습니다. 다행스럽게도 PHP는 풍부한 리소스를 제공하므로 권장 기술을 사용하여 신중하고 철저하게 구축된 애플리케이션이 기본적으로 스크립트에서 SQL 삽입 가능성을 제거할 것이라는 확신을 가지고 예측할 수 있습니다. 이는 사용자를 '청산'함으로써 달성됩니다. 손상이 발생하기 전에 데이터를 보호하십시오.
4. 쿼리의 모든 값을 정의하세요
쿼리의 모든 값을 정의하는 것이 좋습니다. 문자열 값은 일반적으로 '큰따옴표가 아닌 작은따옴표'를 사용할 것으로 예상되는 콘텐츠뿐만 아니라 가장 먼저 영향을 받습니다. 한편으로, PHP가 문자열 내에서 변수를 교환할 수 있도록 큰따옴표를 사용하면 쿼리 입력이 더 쉬워지고, 이는 (물론 아주 적은 양이지만) 향후 PHP의 필요성도 줄여줍니다. 코드 분석 작업.
다음으로, 이 문제를 설명하기 위해 처음에 사용한 비주입 쿼리를 사용하겠습니다.
SELECT * FROM wines WHERE Variant = 'lagrein'
또는 PHP 문에서 표현됨 as:
$query = 'SELECT * FROM wines WHEREvariety = '$variety'';
기술적으로 말하면 숫자 값에 따옴표를 적용할 필요가 없습니다. 그러나 와인과 같은 필드의 값 주위에 따옴표를 사용해도 괜찮고 사용자가 양식에 null 값을 입력하면 다음과 같은 내용이 표시됩니다. 쿼리:
SELECT * FROM wines WHERE vintage =
물론 이 쿼리는 구문상 유효하지 않지만 다음 구문은 유효합니다.
SELECT * FROM wines WHERE vintage = ''
두 번째 쿼리는 (아마도) 다음을 반환합니다. 아무것도 없지만 적어도 오류 메시지는 반환되지 않습니다.
5. 사용자가 제출한 값의 종류를 확인
앞선 논의를 보면 지금까지의 SQL 인젝션의 중요한 유래를 알 수 있다. 예상치 못한 양식 가져오기가 종종 중단됩니다. 그러나 사용자에게 양식을 통해 특정 값을 제출할 수 있는 기회를 제공할 때 어떤 입력을 얻고 싶은지 잘 알고 있어야 합니다. 이렇게 하면 사용자 입력의 유효성을 더 쉽게 확인할 수 있습니다. 이전 기사에서 이러한 검증 헤더에 대해 이미 논의했으므로 여기서는 그때 논의한 핵심 사항만 간략하게 요약하겠습니다. 숫자를 보고 있는 경우 다음 기술 중 하나를 사용하여 실제로 숫자 유형을 얻고 있는지 확인할 수 있습니다.
is_int() 함수(또는 is_integer() 또는 is_long()) 사용 .
· gettype() 함수를 적용합니다.
· intval() 함수를 적용합니다.
· settype() 함수를 적용합니다.
사용자 입력 길이를 확인하려면 strlen() 함수를 사용하면 됩니다. 원하는 시간이나 날짜가 유효한지 확인하려면 strtotime() 함수를 사용하면 됩니다. 사용자의 가져오기에 세미콜론 문자가 포함되지 않도록 보장하는 것이 거의 확실합니다(구두점이 합법적으로 포함될 수 없는 경우). 아래와 같이 strpos() 함수를 사용하면 쉽게 이를 달성할 수 있습니다.
if( strpos( $variety, ';' ) )exit ( '$variety는variety에 대한 유효하지 않은 값입니다. !' );
앞서 언급했듯이 사용자 입력 기대치를 주의 깊게 분석하면 많은 문제가 있는지 쉽게 감지할 수 있습니다.
6. 검색어에서 의심스러운 문자 필터링
이전 기사에서 위험한 문자가 포함된 제목을 필터링하는 방법에 대해 설명했지만 여기서는 이 제목을 간략하게 과장하고 요약해 보겠습니다. 다시:
· 애플리케이션 개발에서 제한되는 Magic_quotes_gpc 명령이나 '비하인드 파트너'-addslashes() 함수를 사용하지 마십시오. 또한 이 함수는 추가 단계의 적용을 요청합니다. Stripslashes() 함수의 적용.
· 이에 비해 mysql_real_escape_string() 함수가 더 많이 사용되지만, 나름의 단점도 있습니다.
위 내용은 PHP에서 SQL 인젝션 공격 전면 금지 2부입니다. 자세한 내용은 PHP 중국어 홈페이지(m.sbmmt.com)를 참고해주세요!