Wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.
이번 포스트에서는 php? c? 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.
이번에는 생각보다 간단한 문제입니다.
문제를 풀어보도록 하겠습니다.
| 문제 이해 |
문제는 다음과 같습니다.
문제를 보니 interger 타입에 대해 묻고 있습니다.
INT는 32bit로 되어 있으며, unsigned와 signed에 따라 값의 범위가 달라지게 됩니다.
먼저 문제로 들어가 소스를 살펴보았습니다.
<?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>
위의 코드는 나름 정리해서 보여지게 한 것입니다.
위의 코드에서는 일단 두 개의 입력 값을 post로 받습니다.
input1 값은 p7이라는 C 프로그램의 인자값으로 주어지고,
input2 값은 p7의 값의 결과값과 비교하는 값입니다.
여기서 나름 힌트라고 할 수 있는 것이 14번 라인입니다.
여기서 ./p7.c를 컴파일하여 사용한다는 것입니다.
즉, 현재 디렉토리에 p7.c라는 파일이 있다는 것입니다.
http://wargame.kr:8080/php_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); }
위의 소스도 나름 보기 좋게 정리한 것입니다.
여기서 우리가 입력한 인자값(문자열 값)이 atoi함수를 통해 int로 변경되어 입력됩니다.
그리고 그 값이 각 if문을 통과할 때 정상적인 종료가 이루어집니다.
여기서는 int overflow를 이용하여야 합니다.
| 문제 풀이 |
먼저 int overflow를 하기 전에 어떻게 integer overflow가 가능한지 알아보도록 합시다.
|
integer overflow |
integer 값은 unsigned일 때 -2147483648 ~ 2147483647 의 범위를 가지고 있습니다.
여기서 가장 큰 양수 값을 넣었을 때 위와 같은 비트 형태를 가지게 됩니다.
이때 만약 +1을 하게 되면 다음과 같이 값이 변하게 됩니다.
위의 값은 계산기이기 때문에 양수로 보이게 되지만, C의 unsigned int의 경우 다음과 같이 음수로 변하게 됩니다.
이러한 원리를 이용하여 integer overflow를 수행할 수 있습니다.
|
문제 풀이 |
integer overflow 원리를 이용하여 다음과 같은 값을 넘겨주게 되면, 모든 if 값을 패스합니다.
'WARGAMES > wargame.kr' 카테고리의 다른 글
[Wargame.kr] Level 18 - pyc_decompile (0) | 2019.05.16 |
---|---|
[Wargame.kr] Level 17 - SimpleBoard (0) | 2019.05.16 |
[Wargame.kr] Level 16 - web_chatting (0) | 2019.05.16 |
[Wargame.kr] Level 15 - easy_crackme(IDA) (0) | 2019.05.15 |
[Wargame.kr] Level 13 - img recovery (2) | 2019.05.01 |
[Wargame.kr] Level 12 - type_confusion (0) | 2019.04.30 |
[Wargame.kr] Level 11 - tmitter (0) | 2019.04.30 |
[Wargame.kr] Level 10 - md5_compare (0) | 2019.04.10 |