c의 오버플로우 관련 문제.
<?php
if (isset($_GET['view-source'])) {
show_source(__FILE__);
exit();
}
require("../lib.php"); // include for auth_code function.
if(isset($_POST['d1']) && isset($_POST['d2'])){
$input1=(int)$_POST['d1'];
$input2=(int)$_POST['d2'];
if(!is_file("/tmp/p7")){exec("gcc -o /tmp/p7 ./p7.c");}
$result=exec("/tmp/p7 ".$input1);
if($result!=1 && $result==$input2){echo auth_code("php? c?");}else{echo "try again!";}
}else{echo ":p";}
?>
d1과 d2를 post로 받은 후 p7.c파일을 컴파일해서 /tmp/p7로 만든 후 d1을 인자로 줘서 프로그래밍 실행
후 결과가 1이 아니면서 d2와 나온 결과가 같으면 키값 출력. 우선 뭔지 알려면 컴파일하게 되는
p7.c소스코드를 봐야된다. p7.c를 주소창에 입력해보면 소스코드가 나온다.
#include <stdio.h> #include <stdlib.h> void nono(); int main(int argc,char **argv){ int i; if(argc!=2){nono();} i=atoi(argv[1]); if(i<0){nono();} i=i+5; if(i>4){nono();} if(i<5){printf("%d",i);} return 0; } void nono(){ printf("%d",1); exit(1); }
인자를 받아서 인자 하나가 안들어오면 nono()로 종료, 들어오면 그걸 atoi함수로 숫자로 변환 후
i가 0미만이면 nono(), i +=5;로 i에 5를 더한후 i가 4보다 크면 nono(). 그리고 i가 5 미만이면 출력.
그런데 논리적으로 생각해보면 i가 0 미만이면 안되니 최소 0인데, 여기에 5를 더하면 최소 5가 되어
4보다 클수밖에 없다. 그런데 이건 c언어 코드이고... c언어에는 오버플로우가 있다. int형의 최대값에
5를 더하면 -가 되어 i가 0미만도 아니면서, 5를 더했을시 4보다 크지도 않고, -이므로 5보다 작으니
값을 출력하게 된다. 이 출력된 값을 위 코드에서 $result=exec("/tmp/p7 ".$input1); 여기에 저장을
하게 되고, 이 값과 두번째 입력한 값이 같으면 되니. d1에는 5를 더하면 오버플로우 될수 있는
int형의 최대값을 넣어주고, d2에는 d1+5의 값(오버플로우된값) 을 넣어주면 된다.
int형의 최대값은 2147483647이고, 5를 더해보면 -2147483644 가 나온다.
d1,d2에 값을 넣어보면 제대로 답이 나온다.
'webhacking > etc' 카테고리의 다른 글
wargame.kr type_confusion (0) | 2014.10.30 |
---|---|
wargame.kr login_with_crypto_but (0) | 2014.10.29 |
wargame.kr strcmp (0) | 2014.10.02 |
wargame.kr wtf_code (0) | 2014.09.28 |
codeshell.kr admin_pass (2) | 2014.09.24 |