SQL 주입은 공격자가 해킹되는 소프트웨어나 서비스를 제공할 수 있는 데이터베이스 서버를 대상으로 SQL 명령을 소프트웨어 애플리케이션이나 사이트 인터페이스에 보내는 일반적인 유형의 주입입니다.
SQL 주입 공격은 공격자가 데이터베이스에 대한 무단 액세스 권한을 얻고, 데이터를 검색, 수정 또는 삭제하고 심지어 전체 서버를 손상시킬 수도 있기 때문에 특히 위험합니다. 이러한 유형의 공격은 사용자 입력의 유효성을 적절하게 검증하지 못하는 웹 애플리케이션의 부적절한 코딩을 이용합니다. 공격자는 데이터베이스 서버에서 실행되는 로그인 양식과 같은 입력 필드에 SQL 명령을 삽입하거나 "주입"하여 이 취약점을 악용합니다.
SQL 주입 공격의 심각성은 공격자가 데이터베이스 명령을 조작하여 인증을 우회하고, 중요한 데이터에 액세스하고, 데이터베이스에 대한 관리 작업을 수행할 수 있는 능력을 제공하는 데 사용될 수 있다는 사실에서 비롯됩니다. 경우에 따라 공격자는 SQL 주입을 사용하여 조직 시스템에 대한 지속적인 백도어를 확보하여 데이터 보안에 장기적인 위협을 가할 수 있습니다.
SQL 주입 원인 및 시연
SQL 주입 취약점의 주요 원인은 데이터 상호 작용 중에 데이터가 프런트엔드에서 백엔드로 전달될 때 엄격한 유효성 검사가 부족하기 때문입니다. 이를 통해 입력 데이터를 SQL 문으로 연결하고 SQL 쿼리의 일부로 실행할 수 있습니다. 결과적으로 데이터베이스가 손상되어 데이터 유출, 삭제 또는 전체 서버 액세스 손상으로 이어질 수 있습니다.
Pikachu 훈련 환경의 SQL-Inject 모듈은 이 취약점을 보여줄 수 있습니다. 시스템에 등록된 사용자 이름을 다음 애플리케이션의 입력 필드에 입력하면 시스템은 해당 UID와 이메일을 반환합니다.
이 서비스에 대한 PHP 코드는 다음과 같습니다. 백엔드 코드는 프런트엔드에서 전달된 이름 매개변수에 대해 어떠한 필터링도 수행하지 않습니다. 다음과 같이 이를 데이터베이스 쿼리 문에 직접 연결합니다.
"ID 선택, 사용자 이름='$name'인 회원의 이메일"
이로 인해 SQL 주입 취약점이 발생합니다. 공격자는 name 매개 변수를 통해 악의적인 SQL 문을 삽입하여 서비스가 제공하려는 것 이상의 데이터를 검색하여 시스템의 기밀성을 손상시킬 수 있습니다.
if (isset($_GET['제출']) && $_GET['이름'] != null) {
// 여기서는 처리가 수행되지 않으며 select 문에 직접 연결됩니다.
$이름 = $_GET['이름'];
// 이 변수는 문자열 타입이므로 이스케이프 처리를 고려해야 합니다.
$query = "ID 선택, 사용자 이름='$name'인 구성원의 이메일";
$result = 실행($link, $query);
if (mysqli_num_rows($result) >= 1) {
동안($data = mysqli_fetch_assoc($result)) {
$id = $data['id'];
$email = $data['이메일'];
$html .= "<p class='notice'>귀하의 UID: {$id} <br />귀하의 이메일은 다음과 같습니다: {$email}</p>";
}
} 또 다른 {
$html .= "<p class='notice'>입력한 사용자 이름이 존재하지 않습니다. 다시 입력해 주세요!</p>";
}
}
앞서 언급한 쿼리 서비스를 예로 들면, 악성 SQL 주입 페이로드 테스트 '또는 1=1#'를 입력하면 시스템은 등록된 모든 사용자의 UID와 이메일을 반환합니다. 이는 데이터 유출의 간단한 예입니다. 해커가 SQL 주입 취약점을 인지하면 데이터베이스 추가, 삭제, 수정, 쿼리 등의 작업을 자유롭게 수행할 수 있습니다. 전체 서버에 대한 추가 제어권을 얻기 위해 웹 셸을 삽입할 수도 있습니다.
이 모든 일이 어떻게 일어났습니까? 앞서 언급한 것처럼 백엔드 코드는 필터링을 수행하지 않고 사용자 입력 이름 매개변수를 데이터베이스 쿼리 문에 직접 연결합니다. 따라서 악성 페이로드 테스트 ' 또는 1=1#를 입력하면 백엔드 코드는 다음 쿼리를 생성합니다.
$query = "사용자 이름='test' 또는 1=1#'인 구성원의 ID, 이메일을 선택하세요."
이 문이 데이터베이스에서 실행되면 결과는 명확합니다. 데이터베이스는 1=1 표현식을 항상 true로 평가하여 멤버 테이블의 모든 데이터를 반환합니다.
SQL 주입을 방지하는 방법
SQL 주입을 방지하려면 개발자는 웹 애플리케이션이 사용자 입력을 적절하게 삭제하는지 확인해야 합니다. 여기에는 일반적으로 SQL 명령을 데이터 입력에서 분리하는 준비된 문과 매개변수화된 쿼리를 사용하여 악의적으로 삽입된 SQL 코드의 실행을 방지하는 작업이 포함됩니다. 정기적인 코드 검토 및 보안 테스트도 SQL 주입을 통해 악용될 수 있는 취약점을 식별하고 수정하는 데 도움이 될 수 있습니다.
또한, 강력한 구현 웹 애플리케이션 방화벽(WAF) SQL 주입 공격에 대한 추가 방어 계층을 제공할 수 있습니다. 씨디네트웍스 WAF 악의적인 요청이 데이터베이스 서버에 도달하기 전에 이를 감지하고 차단하는 데 도움이 됩니다. 보안 코딩 방법에 대해 개발자를 교육하고 입력 유효성 검사의 중요성에 대한 인식을 높이는 것도 SQL 주입 공격을 예방하는 데 중요합니다.