Hacking (CTF)/Web

[Dreamhack/드림핵] command-injection-1

gapsoo 2023. 11. 20. 18:26

https://dreamhack.io/wargame/challenges/44

 

command-injection-1

특정 Host에 ping 패킷을 보내는 서비스입니다. Command Injection을 통해 플래그를 획득하세요. 플래그는 flag.py에 있습니다. Reference Introduction of Webhacking

dreamhack.io

 

 


[1] 문제 분석

 

# 문제 웹 페이지 분석

 

 

첫 화면이다.

 

 

 

상단에 'Home' 옆에 'Ping'을 누르면 이동하는 페이지이다.

네모 칸에 IP 주소를 입력할 수 있게 되어있는 것 같았고, "Ping!" 버튼을 눌러 결과를 확인할 수 있는 것 같았다.

 

 

⚙️ /ping.html

 

<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/css/bootstrap-theme.min.css">
    <link rel="stylesheet" href="/static/css/non-responsive.css">
    <title>ping | Dreamhack Ping Tester</title>
    
  

  </head>
<body>

    <!-- Fixed navbar -->
    <nav class="navbar navbar-default navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
	<a class="navbar-brand" href="/">Home</a>
        </div>
        <div id="navbar">
          <ul class="nav navbar-nav">
            <li><a href="/ping">Ping</a></li>
          </ul>

        </div><!--/.nav-collapse -->
      </div>
    </nav>

    <div class="container">
      
<h1>Let's ping your host</h1><br/>
<form method="POST">
  <div class="row">
    <div class="col-md-6 form-group">
      <label for="Host">Host</label>
      <input type="text" class="form-control" id="Host" placeholder="8.8.8.8" name="host" pattern="[A-Za-z0-9.]{5,20}" required>
    </div>
  </div>

  <button type="submit" class="btn btn-default">Ping!</button>
</form>

    </div> <!-- /container -->

    <!-- Bootstrap core JavaScript -->
    <script src="/static/js/jquery.min.js"></script>
    <script src="/static/js/bootstrap.min.js"></script> 
</body>
</html>

 

이 페이지의 소스 코드이다.

 

폼 부분을 위주로 분석해봤을 때,

 

1. 서버로 전송될 때 "host"라는 이름을 사용하여 전송한다.

2. 알파벳 대소문자, 숫자, 그리고 점(.)이 5부터 20개까지 허용된다.

3. required 속성은 이 필드가 비어있으면 제출이 불가능하도록 만든다.

 

이 정도 내용을 알 수 있었다.

 

 

 

"8.8.8.8"을 적어서 핑 테스트를 해본 결과 화면이다.

실제 ping 명령과 동일한 기능을 수행하고, 그 결과를 출력하는 것을 알 수 있다.

 

 

 

이 페이지의 소스 코드를 보았는데 별 건 없었다.

.

.

.

 

이제 다운로드한 문제 파일을 분석해보도록 하겠다.

 

 

# 다운로드한 문제 파일 분석

 

 

⚙️ app.py

 

#!/usr/bin/env python3
import subprocess

from flask import Flask, request, render_template, redirect

from flag import FLAG

APP = Flask(__name__)


@APP.route('/')
def index():
    return render_template('index.html')


@APP.route('/ping', methods=['GET', 'POST'])
def ping():
    if request.method == 'POST':
        host = request.form.get('host')
        cmd = f'ping -c 3 "{host}"'
        try:
            output = subprocess.check_output(['/bin/sh', '-c', cmd], timeout=5)
            return render_template('ping_result.html', data=output.decode('utf-8'))
        except subprocess.TimeoutExpired:
            return render_template('ping_result.html', data='Timeout !')
        except subprocess.CalledProcessError:
            return render_template('ping_result.html', data=f'an error occurred while executing the command. -> {cmd}')

    return render_template('ping.html')


if __name__ == '__main__':
    APP.run(host='0.0.0.0', port=8000)

 

이 app.py에서 주목할만한 부분은,

 

 

 

이 부분인데, 이 코드를 통해 {host} 부분에 내가 입력한 값이 들어간다는 것을 알 수 있었다.

 

 

 


⭐ ⭐  [2] 공격 ⭐ ⭐ 

 

 

command injection 공격은 주로 "메타 문자"를 이용하여 발생이 된다.

 

그러나 /ping.html의 pattern="[A-Za-z0-9.]{5,20}"부분을 보면,

알파벳 대문자, 소문자, 0-9까지의 숫자 이외의 문자는 필터링이 됨을 알 수 있다.

 

즉, 메타 문자를 사용할 수 없는 것이다.

 

 

 

개발자 도구를 열어서 필터링 기능을 만드는 네모 박스 부분을 지운 다음 명령어를 입력해보았다.

 

 

 

{host} 부분에 내가 입력한 텍스트가 들어가는 것을 참고하여 8.8.8.8";ls" 를 입력하고 제출한 결과이다.

 

이렇게 되면, cmd = f'ping -c 3 "8.8.8.8";ls"' 을 입력한 것이 된다.

 

현재 디렉토리에 flag.py가 존재하는 것과, 필터링을 해주는 코드를 지우면 공격이 된다는 점을 이용해 cat 명령어로 flag.py 파일을 읽어올 것이다.

 

 

 

(핑은 아무거나 입력해도 상관없다.)

 

cat 명령어로 flag.py의 내용인 플래그 값을 출력할 수 있었다.

 

 

 

문제 풀이 완료!


 

[3] 참고

 

https://hobbylists.tistory.com/entry/%EB%93%9C%EB%A6%BC%ED%95%B5DreamHack-%EC%BB%A4%EB%A7%A8%EB%93%9C-%EC%9D%B8%EC%A0%9D%EC%85%98-1-Command-Injection-1%ED%92%80%EC%9D%B4

 

드림핵(DreamHack) - 커맨드 인젝션 -1, Command Injection-1(풀이)

해당 문제는 드림핵의 커맨드 인젝션-1번 문제입니다. command injection-1 Command injection 말 그대로 명령어 삽입 공격인 것 같은데 이 문제에서 해당 기법을 처음 접해봤습니다. SQL Injection 처럼 명령

hobbylists.tistory.com