PHP: ejemplo de inyección de SQL

안녕하세요, 저는 알리 칸테 대학교 (University of Alicante)의 컴퓨터 과학 교수 인 Sergio Luján Mora입니다 그리고이 비디오에서는 "웹 개발 소개"과정의 일부입니다

SQL 주입의 두 가지 예를 보여 드리겠습니다 시작하기 전에 내가 할 수있는 웹 사이트 몇 가지를 알려드립니다 저와 제 일에 대한 더 많은 정보와 저에게 연락 할 수있는 두 가지 방법을 찾으십시오 내 이메일 sergiolujan@ua

es와 트위터 계정 @sergiolujanmora를 통해 이 비디오에서는 SQL 주입이 무엇인지 설명하지 않겠습니다 그래서, 만약 당신이 모르는 SQL 주입이란 무엇입니까? 예 : Wikipedia에있는 기사 또한 문서에있는 SQL 삽입에 대한 기사를 확인할 수도 있습니다 PHP 관계자 어쨌든, SQL 삽입은 단순히 삽입으로 정의 될 수있다

응용 프로그램의 프로그래밍 된 SQL 코드 내 침입 SQL 코드 SQL 인젝션에 대한 간단한 두 가지 예제와 자신을 보호 할 수있는 최선의 방법을 살펴 보겠습니다 이 유형의 공격 분명히, SQL 인젝션의 예제를 수행하기 위해서 우리는 공격을 수행 할 데이터 내가 사용할 데이터베이스는 기본 데이터베이스입니다 매우 간단한 데이터, 목록이있는 사용자라는 단일 테이블로 구성됩니다

사용자 수 이 경우 나는 "Sergio", "Manolo" 와 "다니엘" 내가 사용하는 "users-backup"이라는 테이블도 있습니다 내가 공격 테스트를 수행하고 사용자가 복사 한 테이블에서 데이터를 삭제할 때 사용자로부터 데이터를 다시 쉽게 백업 할 수 있습니다 두 가지 유형의 공격을 표시하기 위해 두 개의 웹 페이지를 만들었습니다 처음에는 사용자가 이름을 통해 검색 할 수있는 양식, 필드 여기서 우리가 사용자 테이블에 가지고있는 이름

예를 들어 "Sergio"를 검색하는 경우 "SELECT * FROM Users"를 수행하면됩니다 이름은 Sergio이며 사용자 Sergio의 모든 데이터를 검색합니다 그러나, 우리는 존재하지 않는 사용자를 찾습니다 예를 들어, Mariano는 쿼리를 작성하기 때문에 결과가 표시되지 않습니다 이 애플리케이션의 소스 코드를 보자

코드는 매우 간단합니다 한편으로는 폼이 표시되는 HTML 페이지가 있습니다 name 값과 함께 name 속성을 전달하는 단일 텍스트 필드로 구성됩니다 및 보내기 단추 폼은이 데이터를 "formulario

php"라는 PHP 페이지로 보냅니다 "Formulariophp"는 단순히 데이터베이스에 연결하고, 데이터베이스, 사용자가 삽입 된 SELECT 인 SQL 문을 마운트하십시오 이름 필드에 입력하고 SQL 문을 실행합니다 한 번 실행하면 이 while 루프의 결과

공격이란 무엇입니까? 우리는 형식으로 돌아가서 공격을 수행 할 것입니다 그 공격은 단순히이 입력 값을 입력하는 것으로 구성되며 전송할 때 모든 사용자의 데이터 어떻게 가능합니까? 여기에 실행 된 SQL 문에 설명이 나와 있습니다 항목을 입력 할 때 '또는'1 '='1이 SQL 문과 연결되고 첫 번째 조건 이름이 남아 있습니다 빈 것과 같습니다 빈 문자열 인 이름은 없습니다 그러나 우리는 이 논리 표현식은 항상 참입니다

따라서 이것이 항상 사실이므로이 SELECT는 조건없이 SELECT가됩니다 즉, 모든 사용자와 여기를 꺼냅니다 우리는 아마 모든 사용자의 전체 목록을 볼 수 있습니다 이 하나 예를 들어 다음과 같은 형식을 건너 뛰기 때문에 공격 유형을 사용할 수도 있습니다 로그인, 웹 응용 프로그램의 식별

우리가 보게 될 두 번째 예는 더 위험합니다 우리는 전형적인 웹 사이트를 가지고있다 우리는 이메일 수신을 중단하기 위해 가입을 취소 할 수 있습니다 이 우리는 "탈퇴하고 싶으면 여기를 클릭하십시오"라는 링크가있는 페이지를 볼 수 있습니다 매개 변수가 전송되는 방식의 비디오 하단에 표시되는 URL, "correo=sergio@ua

es" Arroba는 % 40으로 나타납니다 이 버튼을 누르면 메일이 수신되는 PHP 페이지가 실행된다 이 매개 변수는 매개 변수로 전달되고이 문을 작성하는 값으로 사용됩니다 이 값과 일치하는 사용자를 효과적으로 삭제하는 SQL

이제 데이터베이스로 이동하여 users 테이블을 참조하면 여기에 사용자가 있습니다 "세르지오"는 지워졌음에 틀림 없다 우리가 그것을 다시 시험 해보면, 우리는 보게 될 것이다 해당 사용자가 얼마나 효과적으로 삭제되었는지 여기에이 예제의 소스 코드가 다시있다

첫 번째 페이지, 페이지 HTML은 매우 간단합니다 단순히 링크, 두 번째 페이지에 대한 하이퍼 링크, 실제로 다운로드를 수행하는 "bajaphp"로 사용자를 삭제하고 사용자의 전자 메일 값과 함께 mail이라는 매개 변수를 전달합니다 우리가 제거하고자하는 나는 우리가 그것을 가지고 있기 때문에 arroba가 40 %로 여기에서 반복한다 그것을 URL을 통해 특수 문자로 전달하도록 인코딩 할 수 있습니다

페이지 "bajaphp" 이전의 것과 매우 비슷하고 매우 간단합니다 데이터를 선택하고 데이터베이스를 선택하고 실행할 SQL 문을 작성하십시오 mail 매개 변수를 사용하여 DELETE를 수행하고 쿼리를 실행합니다 어디있어? 이 코드의 문제점은 무엇입니까? 우리는 웹 사이트로 돌아가서 다음을 수행 할 것입니다

링크 주소를 복사합니다 URL을 입력 한 다음 이전에 작성한 것과 비슷한 것을 추가합니다 모든 사용자를 강제로 지울 수 있습니다 특히, 나는 아포스트로피를 추가 할 것이다 텍스트 문자열을 닫으려면 OR '1'= '1

여기서 일어나는이 값은 그것은 그것이 일어나기 때문에 인코딩되어야하므로 직접 입력해야합니다 특수 문자가 포함되어 있습니다 그래서 그것을 복사하고 자바 스크립트 콘솔을 엽니 다 EncodeURIcomponent ()라는 JavaScript 함수를 사용하여 인코딩 할 것입니다 URL을 통해 가고 싶은 값 붙여 넣으면 체인이 생성됩니다

나는 정말로 지나갈거야 나는 그것을 복사하고 그것을 대체합니다 나는 이것을 여기에서 제거한다 이제 사용자 테이블에는 두 명의 사용자가 있으며 사용자는 "Manolo"입니다 및 사용자 "다니엘"

이 명령문을 실행하면 모든 사용자 우리는 그것을 실행하고 "이메일 sergio@uaes가 구독 취소되었습니다"라고 말합니다 그러면 우리는 우리가 연결 한 표현을 갖게됩니다 그리고 어떻게 조건 한편으로는 우편물이이 경우에는 실현되지 않을 것입니다

왜냐하면 이 사용자는 항상 "true"인 표현식을 "OR"하기 전에 이미 삭제했습니다 이제 사용자 테이블로 다시 이동하여 검토를 다시 한 번 해보면 사용자 테이블이 비어 있고 모든 사용자가 삭제되었습니다 우리가 공격했다 의 SQL 주입 우리는 어떻게 이런 종류의 공격으로부터 자신을 보호 할 수 있습니까? 두 가지 방법이 있습니다

첫 번째 방법은 phpini 파일에서 "magic quotes"를 설정하는 것입니다 그러나, 이 첫 번째 양식은 권장하지 않으며 phpini 파일 자체의 주석은 우리에게 알려줍니다 우리는 "magic_quotes"를 찾을 것이고 우리는 이것이 특징이라는 의견을 말할 것이다

위험 할 수있는 몇몇 특성을 도주하는 것을 허용하는 그러나 우리는 말한다 이 기능은 100 % 안전하지 않으며 PHP 53에서는 권장되지 않으며 PHP 6에서 제거, 삭제됩니다 따라서 이 속성을 신뢰하십시오 "On"으로 설정하면 데이터 항목이 이스케이프됩니다 그들은 인코딩 될 것이고이 예제에서 우리가 가진 문제는 일어나지 않을 것입니다

그러나 나는 반복한다 이 매개 변수를 신뢰하는 것은 좋은 해결책이 아닙니다 또한 많은 경우 우리는 phpini 파일에 접근 할 수없고 변경할 수 없습니다 두 번째 옵션은 MySQL 함수 "mysql_real_escape_string ()"을 사용하는 것입니다

"Mysql_real_escape_string ()"은 문자열의 특수 문자를 이스케이프합니다 문자열로, SQL 문에 사용됩니다 그리고 조금 더 자세히 설명하면 다음과 같습니다 MySQL 라이브러리 접두사 모음의 "mysql_real_escape_string ()"함수를 호출하십시오 뒤에 오는 특성에 반전 해, 안으로 위험 할 수있는 특성에 SQL 문

특히 여기서 우리는 내가 아 포스 트로피 특성을 발견했습니다 내 SQL 주입 공격에 사용 그렇다면이 함수로 코드에서 무엇을해야합니까? 코드에서 사용자 입력을 SQL 문에 직접 전달해서는 안되며, 그러나 우리는 다음과 비슷한 것을해야합니다 나는 예를 들면 티켓을 집어 들었다 변수 "name"에 "mysql_real_escape_string"을 수행하고 사용자 입력을 전달합니다

그리고 지금 예 SQL 문에 "name"변수를 사용할 수 있습니다 그러나 여기에 직접적으로 있지는 않습니다 사용자의 입력 내용은 위험하지만 위험한 문자는 탈출했다 다른 예에서는 같은 방식으로 행동해야합니다

나는 입구에 갈 것이다 사용자, 여기에 변수 "mail"과 "mail"을 넣을 것입니다 다시 깨끗한 사용자 입력이 될 것입니다 그리고 우리는 이미 그것을했을 것입니다 이 비디오를 끝내기 전에 또 다른 SQL 주입 공격을 보여 드리겠습니다

이것을 위해 저는이 연재 만화를 만들 것입니다 나는 그것을 번역했다 번역은 다음과 같다 여보세요,이 분은 당신 아들의 학교입니다 우리는 컴퓨터에 몇 가지 문제가 있습니다

오, 이런 뭔가 망가 뜨 렸니? 어떤 의미에서는 그렇습니다 그들은 정말로 그들의 아들 로버트라고 불렀다); DROP TABLE 학생; -? 오, 그래 리틀 바비 테이블 (Little Bobby Tables)

우리는 올해 학생들의 기록을 모두 잃었습니다 나는 그것이 있기를 바란다 행복한 그리고 데이터베이스의 항목을 정리하는 법을 배우기를 바랍니다 여기 무슨 일이 있었던거야? 어떤 유형의 SQL 주입 공격이 발생 했습니까? 우리는 여기서 사용자의 입구에서 공격을 봅니다 양식에 이름을 묻는 경우 사용자가 "Robert"와 같은 것을 작성했으며, SQL 쿼리를 닫고 파트를 추가했습니다

다른 SQL 쿼리의 경우 (이 경우 "DROP TABLE") 따라서 한 번의 상담만으로 SQL은 두 부분으로 실행되었습니다 여기에서 누락 된 첫 번째 부분은 올바른 부분입니다 두 번째는이 학생이 여기서 한 주사입니다 이것은 MySQL에서 원칙적으로 그것은 불가능합니다, 왜? 일반적으로 SQL 쿼리를 실행하는 데 사용되는 mysql_query () 함수 MySQL을 사용하면 여러 쿼리, 즉 하나의 문자열에서 누락 될 수 있습니다 매개 변수로 둘 이상의 쿼리를 입력 할 수 없습니다

따라서 이러한 유형의 공격은 원칙적으로 MySQL을 통해 API를 통해 가능하지 않습니다 mysql_query () 함수가 보호되어 있기 때문에 PHP에서 사용 가능한 MySQL 표준 이러한 유형의 공격을 피하기 위해 이 비디오는 "웹 개발 소개"과정의 일부입니다 ideswebes 주소에서 구할 수 있습니다 주의 해 주셔서 대단히 감사합니다