해킹&보안/웹해킹

[웹 해킹 : 나타스(Natas 워게임] Level 8 -> 9(웹 해킹 / 보안)

yamaeking 2025. 4. 6. 11:12

Natas wargame Level 8 -> 9 로그인 정보와 URL 은 아래와 같다.

 

OverTheWire

We're hackers, and we are good-looking. We are the 1%. <!-- Please read and accept the Rules! --> Username: natas1 URL: http://natas1.natas.labs.overthewire.org

overthewire.org

 

 

 

1. 문제 풀이

 > Natas URL로 접속하면 아래 화면이 나온다

 

> 냅다 View sourcecode 로 코드를 살펴보도록 하자.

<html>
<head>
<!-- This stuff in the header has nothing to do with the level -->
<link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
<link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
<script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
<script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
<script src=http://natas.labs.overthewire.org/js/wechall-data.js></script><script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
<script>var wechallinfo = { "level": "natas9", "pass": "<censored>" };</script></head>
<body>
<h1>natas9</h1>
<div id="content">
<form>
Find words containing: <input name=needle><input type=submit name=submit value=Search><br><br>
</form>


Output:
<pre>
<?
$key = "";

if(array_key_exists("needle", $_REQUEST)) {
    $key = $_REQUEST["needle"];
}

if($key != "") {
    passthru("grep -i $key dictionary.txt");
}
?>
</pre>

<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>

 

 

> 이 문제의 핵심은 위 코드라고 볼 수 있는데, 내가 전달해 준 key 값이 ""이 아닌 경우에 위와 같이 리눅스 명령어를 실행한다. 그러면 저기다가 명령어를 삽입하면 비밀번호를 갖고 올 수 있을 것 같은데, 이는 전형적인 Command Injection (명령어 삽입) 문제라고 한다. 

anything; cat /etc/natas_webpass/natas10 를 넣고 search를 해보도록 하자. 그러면 아래와 같이 비밀번호를 얻을 수 있다.

 

 

이것에 대해 부연설명을 하자면, 리눅스에서 ; 를 넣으면 이를 기준으로 명령어를 구분한다.

 

grep -i $key dictionary.txt 가 원래 코드인데, 여기서 anything; cat /etc/natas_webpass/natas10 을 넣게 되면 grep -i anything; 으로 명령어를 하나 처리하게 되고, 그다음에 cat /etc/natas_webpass/natas10 dictionary.txt 명령어를 실행하게 된다라는 것이다. 아래를 참고하면 좋을 것 같다.

[ grep -i anything ] ; [ cat /etc/natas_webpass/natas10 dictionary.txt ]
        ↑ 명령1       ↑ 쉘 명령어 구분자     ↑ 명령2 (두 파일 내용 출력)

 

 

참고로 이와 같은 Command Injection 을 방어하기 위한 방법으로는 아래의 것들이 있다고 한다.

 

 1. 입력값 필터링 (화이트리스트 방식)

$needle = $_GET["needle"];
if (!preg_match('/^[a-zA-Z0-9]+$/', $needle)) {
    die("Invalid input");
}

 

→ 영문자나 숫자만 허용해서, ;, |, & 같은 쉘 제어문자 차단

 


 2. escapeshellarg() 사용

$needle = $_GET["needle"];
$cmd = "grep -i " . escapeshellarg($needle) . " dictionary.txt";
passthru($cmd);

PHP에서 인자값을 안전하게 만들 때 꼭 써야 하는 함수

 

 

🔧 3. 쉘 명령 자체를 사용하지 않는 게 최고

// 위험
passthru("grep -i $input dictionary.txt");

// 안전: PHP 코드로 직접 검색 처리
foreach (file("dictionary.txt") as $line) {
    if (stripos($line, $input) !== false) {
        echo $line;
    }
}

→ 아예 grep 명령을 PHP 코드로 대체하면, 인젝션 걱정 자체가 사라짐

 

 

2. 요약

☞ Command Injection 을 통해 비밀번호 GET!