2012-03-27 2 views
3

몇 년 전, 나는 C에서 어려운 길을 Format String Attacks에 대해 배웠다. 지금, 나는 최근에이 같은 일부 PHP 코드를 보았다 : 나는 %s%s%s... 같은 문자열로 $_GET['format'] 세트와 같이 실행이 시도PHP sprintf가 유해한 것으로 간주 되나요?

<?php 
echo sprintf($_GET['format'], $_GET['value1'], $_GET['value2']); 

,하지만 PHP는 PHP Warning: sprintf(): Too few arguments in file.php on line 2로 존재한다. 형식 문자열 공격을 수행 할 수 있습니까?

+0

글쎄, $ _GET [ 'format']에있는 % s의 개수가 인수의 개수와 일치해야합니다. 그렇지 않으면 인수 오류가 너무 적습니다. –

답변

2

PHP의 sprintf은 (는) %n과 같이 실제로 위험한 변환을 지원하지 않으므로 전통적인 의미는 아닙니다. 사용자가 제어 할 수있는 형식 문자열은 여전히 ​​제한된 혼란을 야기 할 수 있습니다 (고려할 때 %99999999s).하지만 최악의 경우 메모리와 시간을 소비 할 수 있다고 생각합니다.

0

상위 수준 언어는 프로그래머를 맹목적으로 신뢰하는 대신 전달 된 인수의 수를 확인하는 경향이 있습니다. 다른 공격 경로를 찾아야합니다.

-1

PHP sprintf() 취약점이 있는지는 잘 모르겠지만 예제 코드는 일을하지 않는 방법의 대표적인 예입니다.

내가 아는 한, sprintf는 문자열을 잠그는 데 도움이됩니다.

$sql = sprintf(
    "insert into table (myname, myvalue) values ('%s', '%s')", 
    mysql_real_escape_string($_GET['name']), 
    intval($_GET['value']) 
); 

의 사촌을 빌려 sprintf를이다 사용하기 더 유용한 이유는, vsprintf 지속적으로 재사용 :

// takes variable number of parameters 
function sanitize() { 
    $args = func_get_args(); 
    $sql = array_shift($args); 
    foreach($args as $k => $v) $args[$k] = mysql_escape_string($v); 
    $safe_sql = vsprintf($sql, $args); 
    return($safe_sql); 
} 
예를 들어, 내가의 sprintf()를 사용하는 유용한 이유를 생각 하는데요 것입니다

그것으로, 당신은 안전하게 쿼리에서 매개 변수를 분리하고이 살균 것으로 가정 할 수 있습니다

$t = mysql_query(sanitize(
    "insert into mytable (myname, myvalue) values ('%s', '%s')", 
    $_GET['name'], 
    $_GET['value'] 
)); 
+0

이것은'sprintf'와는 아무런 관련이 없으며, PDO 이외의 것을 사용하여 MySQL 쿼리에 대한 사용자 입력을 준비하는 것으로 보입니다. –

+0

sprintf()를 eval()처럼 사용해서는 안된다는 점을 지적했습니다. – pp19dd

1

는 또한 정수 오버 플로우를 발견했다. 그 결과는 다음과 같습니다 :

<?php 
echo sprintf('%2147483646$s', "foo"); # Warning: Too few arguments 
echo sprintf('%2147483647$s', "foo"); # Warning: Argument number must be greater than zero 

나는 이것을 PHP Bug #61531으로 제출했습니다. 악용 될 수 있는지 확실하지 않습니다.

관련 문제