kangsecu's B1og

[wargame.kr] php? c? 문제풀이 본문

Web Hacking/wargame.kr

[wargame.kr] php? c? 문제풀이

Kangsecu 2018. 2. 17. 04:23

[wargame.kr]에 있는 php? c? 문제를 풀어보도록 하겠습니다. 문제에 들어가면 아래와 같이 32bit 어플리케이션에 정수형을 아냐고 물어봅니다.

Start를 누르고 문제를 확인해보면 아래와 같이 D1과 D2를 입력하는 폼이 보이고 그 밑에 소스가 보입니다.

그럼 코드를 확인하도록 하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?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";}
?>
<style>
 table {background-color:#000; color:#fff;}
 td {background-color:#444;}
</style>
<hr />
 <center>
  <form method='post'>
  <table>
  <tr><td>D1:</td><td><input type='text' id="firstf" style="width:75px;" maxlength="9" name='d1'></td></tr>
  <tr><td>D2:</td><td><input type='text' style="width:75px;" name='d2'></td></tr>
  <tr><td colspan="2" style="text-align:center;"><input type='submit' value='try'></td></tr>
  </table>
  </form>
 <div><a href='?view-source'>get source</a></div>
 </center>
 <script>
  document.getElementById("firstf").focus();
 </script>
cs

코드를 분석해보면, D1와 D2를 모두 POST로 받아서 각각 input1과 input2에 저장을 합니다.  그 후, /tmp/p7를 실행시키는데, D1값을 argv로 받습니다. 코드를 보면 실행되는 값이 1이 아니고 result와 D2값이 같을경우 flag를 줍니다. 그럼 이제 다음 힌트인 p7.c를 보도록 하겠습니다. 밑에 코드가 p7.c의 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#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);
}
cs

이렇게 C언어 코드가 있습니다. 이 역시 코드를 분석해보면 argv[1]을 int형으로 변환 후, 값이 0보다 작을경우 1을 출력하는 nono함수로 이동하고, int형 변수 i값을 5를 증가시킨후, i가 4보다 크면 다시 nono를 호출하고, 5보다 작으면 i의 값을 출력하는 코드입니다. 

Exploit Vector

그런데 코드를 보니 이상합니다. i의 값을 5를 증가시킨 후 4보다 크면 1을 출력하고 5보다 작으면 i의 값을 출력합니다. 그래서 생각을 하다 보니 문제에서 자료형에 대하여 물어본 것이 생각이 났습니다. 그리고 다시 생각을 해보니 int형의 최댓값을 입력을 해서 BOF를 일으키면 문제가 해결될 것이라고 생각하였습니다. 

Exploit

vim을 이용하여 c코드를 직접 컴파일 했습니다.

이렇게 컴파일을 한 후, int형의 최댓값인 2147483643 를 인자로 전달해주니 BOF가 성공하였습니다. 

이제 입력값인 2147483643를 D1에 입력하고 출력값인 -2147483648을 D2에 입력해줍니다. 

 그런데 폼에 입력칸이 제한되어 있어서 값이 다 들어가지 않으므로 개발자 도구에서 코드를 수정해줍니다.

이제 값을 전송해주면 문제가 해결됩니다.

php? c? Clear!