webhacking/etc

wargame.kr php? c?

qkqhxla1 2014. 10. 4. 14:20

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!=&& $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