Nmap 을 이용한 SQL 인젝션 취약점 공격

Beginner

소개

이 랩에서는 공격자가 데이터베이스와 상호 작용하는 웹 애플리케이션의 취약점을 악용하는 기술인 SQL 인젝션 (SQL injection) 에 대해 배우게 됩니다. SQL 인젝션 공격은 무단으로 민감한 데이터에 접근하고, 데이터를 조작하며, 심지어 시스템 전체를 손상시킬 수 있습니다.

이 랩의 목표는 취약한 웹 애플리케이션의 취약점을 악용하여 SQL 인젝션에 대한 실질적인 경험을 쌓는 것입니다. 잠재적인 SQL 인젝션 취약점을 식별하고, 악성 SQL 쿼리를 작성하며, 데이터베이스에서 민감한 정보를 추출하는 방법을 배우게 됩니다. 또한, SQL 인젝션 공격을 완화하기 위한 방어 메커니즘과 모범 사례에 대해서도 배우게 됩니다.

랩 환경 설정

이 단계에서는 취약한 웹 애플리케이션과 데이터베이스 서버를 포함하는 랩 환경을 설정합니다.

  1. 터미널을 열고 /home/labex/project 디렉토리로 이동합니다.

    cd /home/labex/project
  2. project 디렉토리에는 app.pysetup_db.py 두 개의 파이썬 파일이 있습니다. app.py 파일에는 취약한 웹 애플리케이션의 소스 코드가 포함되어 있으며, setup_db.py 파일에는 데이터베이스를 설정하는 코드가 포함되어 있습니다.

  3. setup_db.py 스크립트를 실행하여 데이터베이스를 생성하고 샘플 데이터를 채웁니다.

    python3 setup_db.py
  4. 웹 애플리케이션 서버를 시작합니다.

    python3 app.py

서버가 http://localhost:5000에서 실행 중임을 나타내는 메시지가 표시되어야 합니다.

SQL 인젝션 취약점 식별

이 단계에서는 웹 애플리케이션에서 잠재적인 SQL 인젝션 취약점을 식별하는 방법을 배우게 됩니다.

  1. 웹 브라우저를 열고 http://localhost:5000으로 이동합니다.
    Web application homepage
  2. 검색 상자와 같이 사용자 데이터가 서버로 전송되는 입력 필드를 찾습니다.
  3. 입력 필드에 특수 문자 또는 SQL 키워드 (예: ', ", --, ;) 를 입력하고 애플리케이션의 동작을 관찰합니다.
  4. 애플리케이션이 오류 메시지를 표시하거나 예상치 못한 방식으로 동작하는 경우, 잠재적인 SQL 인젝션 취약점을 나타낼 수 있습니다.
    Search box input test
    검색 상자에 작은 따옴표 (') 를 입력하고 "Search" 버튼을 클릭하면 애플리케이션은 오류 메시지 없이 No results found만 표시합니다. 이러한 동작은 애플리케이션이 SQL 인젝션에 취약할 수 있음을 시사합니다.

SQL 인젝션 취약점 악용

이 단계에서는 식별된 SQL 인젝션 취약점을 악용하여 데이터베이스에서 민감한 정보를 추출하는 방법을 배우게 됩니다.

  1. 이전 단계에서 식별된 취약한 입력 필드 또는 매개변수를 찾습니다.

  2. 입력 필드 또는 매개변수에 다양한 SQL 인젝션 페이로드 (payload) 를 삽입해 봅니다.

  3. SQL 인젝션 페이로드를 사용하여 데이터베이스에서 민감한 정보를 추출해 봅니다. 예를 들어, 다음 페이로드를 사용하여 데이터베이스에서 데이터를 추출할 수 있습니다.

    ' UNION SELECT username, password FROM users --

    위의 페이로드는 데이터베이스의 users 테이블에서 사용자 이름과 비밀번호를 검색하는 데 사용할 수 있습니다.

  4. 애플리케이션의 응답을 관찰하고 표시되는 민감한 정보나 데이터베이스 구조 또는 내용에 대한 정보를 드러낼 수 있는 오류가 있는지 확인합니다.

SQL 인젝션 취약점 완화

이 단계에서는 SQL 인젝션 취약점을 완화하기 위한 방어 메커니즘과 모범 사례에 대해 배우게 됩니다.

  1. 취약한 웹 애플리케이션의 소스 코드를 검토하고 사용자 입력이 적절한 sanitization(위생 처리) 없이 데이터베이스 쿼리에 사용되는 영역을 식별합니다.

  2. 다음과 같은 입력 유효성 검사 및 sanitization 기술을 구현합니다.

    • 매개변수화된 쿼리 또는 prepared statement (준비된 구문)
    • 입력 유효성 검사 및 sanitization (예: 특수 문자 제거 또는 이스케이프 처리)
    • 데이터베이스 계정에 대한 최소 권한 원칙
  3. 사용자 입력을 사용하여 데이터베이스 쿼리를 실행할 때 매개변수화된 쿼리 또는 prepared statement 를 사용하도록 애플리케이션 코드를 업데이트합니다.
    app.py 파일을 다음과 같이 수정합니다.

    sql_query = "SELECT username, password FROM users WHERE username LIKE '%{}%' OR '{}'".format(query, query)
    cur.execute(sql_query)

    다음으로:

    sql_query = "SELECT username, password FROM users WHERE username LIKE ?"
    cur.execute(sql_query, ('%' + query + '%',))

    그리고 results = cur.fetchall()logging.info(f"Search query: {query}") 라인 아래로 이동합니다.

    logging.info(f"Search query: {query}")
    
    results = cur.fetchall()
  4. 위의 변경 사항을 적용한 후 파일을 저장하고 웹 애플리케이션 서버를 다시 시작합니다.

    ctrl+c를 사용하여 서버를 중지한 다음 다음 명령을 사용하여 다시 시작합니다.

    python3 app.py
  5. 업데이트된 애플리케이션을 테스트하여 SQL 인젝션 공격이 더 이상 불가능한지 확인합니다.

요약

이 랩에서는 공격자가 데이터베이스와 상호 작용하는 웹 애플리케이션의 취약점을 악용하는 데 사용하는 기술인 SQL 인젝션에 대해 배웠습니다. 취약한 웹 애플리케이션과 데이터베이스 서버를 설정하고, 잠재적인 SQL 인젝션 취약점을 식별했으며, 이를 악용하여 데이터베이스에서 민감한 정보를 추출했습니다. 또한 입력 유효성 검사, sanitization(위생 처리), 매개변수화된 쿼리 또는 prepared statement (준비된 구문) 사용과 같은 SQL 인젝션 공격을 완화하기 위한 방어 메커니즘과 모범 사례에 대해 배웠습니다.

이러한 실습 경험을 통해 SQL 인젝션 공격과 웹 애플리케이션에서 이를 방지하는 방법에 대한 더 깊은 이해를 얻었습니다. 또한 안전한 코딩 방식의 중요성과 데이터베이스와 상호 작용할 때 사용자 입력을 적절하게 sanitization 하지 못할 경우 발생할 수 있는 잠재적 결과에 대해서도 배웠습니다.