오라클에서 작은 따옴표를 사용하지 않고 문자열에서 벗어나 SQL을 주입하는 방법이 있습니까?


12

Oracle 기반 응용 프로그램을 테스트하고 있으며 다음 코드를 찾았습니다.

쿼리 = "선택 직원의 이름 WHERE id = '"+ PKID + "';"

즉, 쿼리 문자열에는 URL에서 직접 얻은 PKID 값 주위에 따옴표가 포함됩니다.

분명히, 이것은 응용 프로그램이 CA SiteMinder 뒤에 있다는 점을 제외하고는 고전적인 SQL 주입입니다. (단일 인용 부호가있는 URL이 응용 프로그램으로 전달되는 것을 차단합니다.)

작은 따옴표를 사용하지 않고 문자열에서 벗어나 SQL을 주입하는 방법이 있습니까?

편집 : 죄송합니다. 더 명확 해야 했습니다. 어떻게 작성 해야하는지 이해 하지만 사람들에게 악용 가능한 문제임을 설득해야합니다. 현재 작은 따옴표를 차단하는 siteminder 뒤에 있기 때문에 우선 순위가 낮은 수정 사항이 될 것입니다.


1
바인드 변수를 사용해 보셨습니까?
JHFB

@JHFB가 말한 것. 바인딩 변수는 표준 관행입니다.
Philᵀᴹ

답변:


9

예, 매개 변수에 따옴표를 제공하지 않고 SQL 주입 공격을 수행 할 수 있습니다.

이를 수행하는 방법은 숫자 및 / 또는 날짜를 처리하는 방법과 관련이 있습니다. 세션 레벨에서 날짜 또는 숫자 형식을 지정할 수 있습니다. 이것을 조작하면 어떤 캐릭터로도 주입 할 수 있습니다.

영국과 미국에서는 기본적으로 쉼표를 사용하여 천 단위 구분 기호를 숫자로 표시하고 소수점을 완전히 정지합니다. 다음을 실행하여 이러한 기본값을 변경할 수 있습니다.

alter session set nls_numeric_characters = 'PZ';

즉, "P"는 이제 소수점이고 "Z"는 천 단위 구분 기호입니다. 그래서:

0P01

숫자는 0.01입니다. 그러나 함수 P01을 작성하면 숫자 변환 전에 오브젝트 참조가 선택됩니다. 이를 통해 다음과 같이 데이터베이스에서 기능을 실행할 수 있습니다.

기본 "ID로 가져 오기"기능을 작성하십시오.

create procedure get_obj ( i in number ) as
begin
  execute immediate 'select object_name from all_objects where object_id = ' || i;
end;
/

또한 원하지 않는 일을하는 함수 P01을 작성하십시오 (이 경우 테이블을 작성하지만 아이디어를 얻습니다).

create function p01 return number as
  pragma autonomous_transaction;
begin
  execute immediate 'create table t (x integer)';
  return 1;
end;
/

그리고 우리는 가야합니다 :

alter session set nls_numeric_characters = 'PZ';

SELECT * FROM t;

SQL Error: ORA-00942: table or view does not exist

exec get_obj(p01);

anonymous block completed

SELECT * FROM t;

no rows selected

어디에도 따옴표는 없지만 "숨겨진"기능 P01을 실행하고 테이블을 만들었습니다 t!

실제로는 어려울 수 있지만 (내부 지식 / 도움이 필요할 수 있음) 인용 부호없이 SQL을 삽입 할 수 있음을 보여줍니다. (가) 변경하면 nls_date_format비슷한 일을 할 수 있습니다.

숫자에 대한 원래의 발견은 David Litchfield가했으며 여기에서 그의 논문을 읽을 수 있습니다 . 날짜를 활용하는 방법에 대한 Tom Kyte의 토론은 여기서 확인할 수 있습니다 .


4

사용중인 데이터 유형을 오버로드하여 해당 명령문이 실패 할 수 있습니다. 그런 다음에 오는 것이 잠재적으로 실행될 수 있습니다.

어쩌면 유니 코드 바이트 배열로 보내면 트릭을 수행하고 해당 명령문에서 다른 명령문으로 가져올 수 있습니다.

구멍이 열려 있으면 남용됩니다. 성 "O'Brian"을 가진 사람들이 고객이 될 수 없기 때문에 작은 따옴표로 모든 문자열을 차단하는 것은 좋은 생각이 아닙니다.


나는 당신이 "전체"가 아니라 "구멍"을 의미한다고 생각합니다.
ypercubeᵀᴹ

1

바인드 변수를 사용해보십시오. 숫자로 선언하면 SQL 삽입이 손상되는 것을 막을 수 있습니다.

추가 : 쿼리 계획이 재사용을 위해 컴파일되고 저장되기 때문에 바인드 변수는 성능과 확장 성을 향상시킵니다. 당신의 주장에 덧붙일 다른 것. :)


1
그는 주사 를 막는 방법이 아니라 그것을 남용 하는 방법에 대해 묻고 있습니다.
Jeff

1
@jeff OP는 또한 이런 종류의 코드를 사용하지 않는 이유를 묻습니다. 바인드 변수를 사용하지 않으면 성능이 저하되므로 항상 사용 하는 것이 좋습니다 .
Vincent Malgrat

@Vincent Malgrat : "바인드 변수를 사용하지 않으면 성능이 저하됩니다"가 잘못되었습니다. 바인드 변수를 사용하면 명령문의 재 컴파일을 피할 수 있습니다. 또한 바인드 변수를 사용하지 않으면 공유 풀에 많은 유사한 문이 넘칠 수 있습니다. 그럼에도 불구하고 리터럴 값 대신 바인드 변수를 사용하는 경우 옵티마이 저는 계획을 빌드하기위한 정보가 적습니다. 바인드 변수 값 (또는 리터럴 값)에 따라 다른 계획을 선택해야하는 상황이 있습니다.
miracle173

@ miracle173 물론 있지만 기본 키 조회를위한, 예외가있을 것 OP에 의해 주어진, 결코 =)
빈센트 말그라
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.