source

MySQL에서 실제로 SQL 주입을 일으킬 수 있는 문자는 무엇입니까?

ittop 2023. 9. 24. 13:08
반응형

MySQL에서 실제로 SQL 주입을 일으킬 수 있는 문자는 무엇입니까?

응용 프로그램에서 sql 주입을 방지하기 위해 준비된 문 또는 적절한 대체/포맷 규칙을 사용해야 한다는 것을 우리는 모두 알고 있습니다.

그러나 MySQL의 캐릭터 리터럴 목록을 살펴보니 다음과 같은 캐릭터가 포함되어 있습니다.

  • \0ASCII NUL)0x00.).
  • \' 하나 나()'.).
  • \"표()".).
  • \b백스페이스 캐릭터.
  • \n새 줄(라인피드) 문자입니다.
  • \r캐리지 리턴 문자입니다.
  • \t탭 문자.
  • \ZASCII 26(+).CtrlZ표 뒤에 있는 참고 사항을 참조하십시오.
  • \\시()\.).
  • \% A %성격.
  • \_ A _성격.

, 은.%그리고._ 않는 다. 그리고 그 동안.' 표),\) 및 )"를 이스케이프하지 할 수 수도 있습니다 (double quote) SQL다를의합니다. 다른 문자를 이스케이프하지 않으면 SQL 주입 취약성이 직접적으로 발생할 수 있습니까?그러한 악용의 실제 사례를 가지고 있는 사람이 있습니까?

다음과 같이 쿼리를 구축하고 있다고 가정해 보겠습니다.

SELECT * FROM users WHERE username='$user'

에 ?$user하지 못한 \b 스),\0(NUL),\n 선 줄),\r 드),\t 탭)탭\Z이 쿼리에 임의 SQL을 주입할 수 있는 (+)?CtrlZ

2020년부터 의무부록:

캐릭터를 다루는 것은 비효율적이고 쓸모없는 것으로 증명되었습니다.

당신은 준비된 진술을 사용해야 하며 탈출, "위험한 인물" 또는 그 어떤 사업도 잊어버려야 합니다.

매개 변수화된 쿼리를 사용하는 것은 아래의 원래 답변에서 제공되는 이유 때문에 SQL 주입으로부터 보호할 수 있는 유일한 적절한 방법으로 여겨집니다.

실제로 mysql에서 SQL 주입을 일으킬 수 있는 문자는 무엇입니까?

그런 캐릭터가 없습니다.

SQL 주입의 원인은 "문자"가 아닙니다.하지만 부적절한 포맷.상황에 따라 어떤 캐릭터든 "위험"하거나 전혀 무해할 수 있습니다.보호 기능을 일부 하위 집합으로 제한하는 것은 실제로 SQL 주입을 조만간 초래할 위험한 망상입니다.

당신의 질문에 당신을 혼란에 빠뜨린 두 가지 잘못된 진술이 있습니다.

  1. 우리 모두는 우리가 ...을 사용해야 한다는 것을 알고 있습니다.응용 프로그램에서 sql 주입을 방지하기 위한 적절한 교체 규칙.

이 진술은 틀렸습니다.교체가 아니라 포맷입니다.그 차이는 꼭 필요합니다.교체만으로는 주입으로부터 보호되지 않는 반면 포맷은 보호됩니다.쿼리의 모든 구별되는 부분에는 다른 형식이 필요하므로 다른 부분에는 쓸모가 없습니다.예를 들어 주사 보호에 필수적인 또 다른 캐릭터가 있습니다. 바로 백틱(')입니다.그런데 스트링 리터럴과는 상관이 없기 때문에 나열하지 않으셨군요.

  1. 주입을 방지하기 위해서는 '(단일 따옴표), \(백슬래시), "(더블 따옴표)를 모두 빼야 합니다.

그것은 대단히 잘못된 진술입니다.탈출한다고 해서 주사를 막을 수는 없습니다.문자열을 포맷하려면 이 문자들을 빼내야 하며 주입과는 전혀 관계가 없습니다.올바른 형식의 쿼리 부분이 취약한 것은 사실이지만 말입니다.그러나 사실은 - 단지 그것을 위해 동적 쿼리 부분을 포맷해야 하고, 어떤 주입 때문에가 아니라 구문 규칙을 따르도록 해야 한다는 것입니다.그리고 당신은 부작용으로 당신의 질의를 이해할 수 없게 될 것입니다.

왜 마지막 진술을 했는지 알겠군요

왜 이 모든 다른 문자들이 mysql_real_escape_string을 통해 빠져나올 수 있을 정도로 취약한지, 그것은 나에게 즉각적으로 명백하지 않기 때문입니다.

잘못 입력되었습니다.
문자열 형식 규칙은 "취약성"이 아니라 이러한 문자를 필요로 합니다.어떤 것들은 단지 편리함 때문에, 어떤 것들은 가독성 때문에, 어떤 것들은 구분자를 벗어나는 명백한 이유 때문에 탈출합니다.그게 전부입니다.

댓글에서 최근에 질문한 내용에 답변하기

PHP의 mysql_real_escape_string에서도 이 문헌들을 인용하지 않기 때문에 이에 대한 답을 정말 원합니다.

비록 을 염두에 있지만: 인 PHP mysql_real_escape_string()어떤 무서운 주사를 맞든 강력하게 연결되어 있지만, 실제로는 그렇지 않습니다."위험한" 캐릭터는 없습니다.단 한 개도 없는.특별한 의미를 가진 서비스 캐릭터들이 있습니다.그들은 상황에 따라 탈출해야 합니다.

따라서 이 함수에 의해 탈출된 문자와 "위험"이 무엇이든 간에 연관성이 없습니다.네가 생각하기 시작하는 순간mysql_real_escape_string()그의 목적은 "dangerous" 캐릭터를 피하는 것인데, 당신은 정말로 자신을 위험에 빠뜨리고 있습니다.이 기능을 사용하여 문자열을 탈출하는 동안(그리고 무조건 사용) - 자신이 안전하다고 생각할 수 있습니다(물론 다른 모든 리터럴도 각각의 서식 규칙을 사용하여 서식을 지정하는 것을 잊지 않는다면).

"%"자가 LIKE 절에 추가 결과 이상의 결과를 가져올 수 있는지 알고 싶습니다.

아니요.

mysql_real_escape_string() 매뉴얼의 아래 행을 고려하면 다음과 같습니다.

MySQL에서는 백슬래시와 쿼리에서 문자열을 따옴표로 묶는 데 사용되는 따옴표 문자만 빼내면 됩니다. mysql_real_escape_string()은 로그 파일에서 읽기 쉽도록 다른 문자를 따옴표로 묶습니다.

MySQL에서 SQL 주입은 이러한 특수 문자만으로 수행할 수 없습니다.\b \0 \n \r \t \Z.

그러나 String Literals 매뉴얼에는 다음과 같이 명시되어 있지만 지정된 이유(또는 지정되지 않은 이유)는 SQL 주입과 관련이 없습니다.

BLOB 열과 같은 문자열 열에 이진 데이터를 삽입하려면 이스케이프 시퀀스로 특정 문자를 나타내야 합니다.문자열을 따옴표로 묶는 데 사용되는 백슬래시("\") 및 따옴표 문자는 제외해야 합니다.특정 클라이언트 환경에서는 NUL 또는 Control+Z를 벗어날 필요가 있을 수도 있습니다.mysql 클라이언트는 NUL 문자가 포함된 따옴표가 붙은 문자열을 이스케이프하지 않으면 잘라내고, 이스케이프하지 않으면 Windows의 END-OF-FILE에 대해 Control+Z를 취할 수 있습니다.

게다가, 단순한 테스트에서, 위의 나열된 특별한 문자들이 탈출하거나 그렇지 않은 날씨에 상관없이, MySQL은 같은 결과들을 산출했습니다.즉, MySQL은 신경도 쓰지 않았습니다.

$query_sql = "SELECT * FROM `user` WHERE user = '$user'";

위의 쿼리는 아래에 나와 있는 것처럼 위에 나열된 문자의 탈출되지 않은 버전과 탈출되지 않은 버전에 대해서도 비슷하게 작동했습니다.

$user = chr(8);     // Back Space
$user = chr(0);     // Null char
$user = chr(13);    // Carriage Return
$user = chr(9);     // Horizontal Tab
$user = chr(26);    // Substitute
$user = chr(92) .chr(8);    // Escaped Back Space
$user = chr(92) .chr(0);    // Escaped Null char
$user = chr(92) .chr(13);   // Escaped Carriage Return
$user = chr(92) .chr(9);    // Escaped Horizontal Tab
$user = chr(92) .chr(26);   // Escaped Substitute

간이 테스트에 사용된 테스트 테이블 및 데이터:

-- Table Structure

CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user` varchar(10) CHARACTER SET utf8 NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

-- Table Data

INSERT INTO `user` ( `user` ) VALUES
( char( '8' ) ),
( char( '0' ) ),
( char( '10' ) ),
( char( '13' ) ),
( char( '9' ) ),
( char( '26' ) );

언급URL : https://stackoverflow.com/questions/14370670/which-characters-are-actually-capable-of-causing-sql-injection-in-mysql

반응형