문제

우리는 현재 건물은 응용 프로그램을 실행하는 다수의 외부 도구입니다.우리는 종종 있을 통과하는 입력한 정보는 우리의 시스템 사용자에 의해 이러한 도구입니다.

물론,이것은 큰 보안 무슨 일이 기다리고 있습니다.

불행하게도,우리가 아직 발견되지 않는 모든 클래스에서.NET Framework 실행하는 명령행 프로그램을 제공하면서 동일한 종류의 경비에 대하여 주입의 공격으로 IDbCommand 개체 위해 하는 데이터베이스가 있습니다.

지금,우리가 사용하는 매우 기본 문자열체는 의심되는 오히려 부족:

protected virtual string Escape(string value)
{
      return value
        .Replace(@"\", @"\\")
        .Replace(@"$", @"\$")
        .Replace(@"""", @"\""")
        .Replace("`", "'")
      ;
}

너희들은 무엇을 막기 위하여 명령 라인에 주입 공격?우리는 계획을 구현하는 regex 는 매우 엄격하고만 있는 아주 작은 부분 집합의 캐릭터를 통해 이었지만,궁금하는 경우가 있었습니다.

일부 사항:

  • 이러한 도구하지 않 Api 우리는 프로그램할 수 있습니다.그들이 한 경우에,우리는 없을 것이 문제입니다.
  • 사용자 선택하지 않는 도구를 실행하는 그들이 입력한 메타 데이터는 도구를 우리가 선택한 사용할(예를 들어,주사하는 메타 데이터와 같은 저작권으로 대상 파일).
도움이 되었습니까?

해결책

당신은 실행되는 프로그램이 직접 또는 통니까?는 경우에 당신은 항상작 외부 프로그램을 제공하여 전체 경로를 실행을 떠나 쉘 방정식에서,당신은 정말 없이 취약하는 모든 종류의 명령 라인에 주입입니다.

편집:DrFloyd,쉘에 대한 책임을 평가하는 것과 같은 백틱.No shell,아무 쉘 평가입니다.분명히,당신은 여전히 주의해야 할 모든 개는 잠재적인 보안 프로그램에서는 당신을 호출하지만 생각하지 않는 이 질문에 대해입니다.

다른 팁

할 때 과정입니다.시작 새로운 프로세스 공급의 매개 변수는 그것의 매개변수를 인수를 대신 건물의 전체 명령 라인에 자신입니다.

시간이 없어에 대한 적절한 테스트,하지만 제가 생각해야하는 데 도움이 그것을 보호하는 일부 수준입니다.

테스트이다.

편집: Ah,누군가가 나를 이길입니다.하지만 여기는 또 다른 점:을 사용하여 시험합니다.InputStream(기억할 수 없는 이름을 정확하)을 공급하는 대신 데이터의 전달을 매개 변수는 가능한 솔루션?다음과 같정 명령어를 읽도록에서 속이는 장치를 공급을 통해 데이터를 입력 스트림을 대신 합니다.

에서는 C++에 Windows, 에,당신은 탈출 그냥\와"필요한 경우,견적 인수 및 ShellExecute 니다.그런 다음 안에 모든 것을 따옴표로 처리해야 합 텍스트입니다.

이것을 설명:


#include <iostream>
#include <string>
#include <windows.h>
#include <cstdlib>
using namespace std;

// Escape and quote string for use as Windows command line argument
string qEscape(const string& s) {
    string result("\"");
    for (string::const_iterator i = s.begin(); i != s.end(); ++i) {
        const char c = *i;
        const string::const_iterator next = i + 1;
        if (c == '"' || (c == '\\' && (next == s.end() || *next == '"'))) {
            result += '\\';
        }
        result += c;
    }
    result += '"';
    return result;
}

int main() {
    // Argument value to pass: c:\program files\test\test.exe
    const string safe_program = qEscape("c:\\program files\\test\\test.exe");
    cout << safe_program << " ";

    // Argument value to pass: You're the "best" around.
    const string safe_arg0 = qEscape("You're the \"best\" around.");

    // Argument value to pass: "Nothing's" gonna ever keep you down.
    const string safe_arg1 = qEscape("\"Nothing's\" gonna ever keep you down.");

    const string safe_args = safe_arg0 + " " + safe_arg1;
    cout << safe_args << "\n\n";

    // c:\program files\test\  to pass.
    const string bs_at_end_example = qEscape("c:\\program files\\test\\");
    cout << bs_at_end_example << "\n\n";

    const int result = reinterpret_cast<int>(ShellExecute(NULL, "open", safe_program.c_str(), safe_args.c_str(), NULL, SW_SHOWNORMAL));
    if (result < 33) {
        cout << "ShellExecute failed with Error code " << result << "\n";
        return EXIT_FAILURE;
    }
}

하지만,어떤 방법을 사용하여 테스트해야 합니다 지옥에 그것을 참조는 그것이 정말로 방출합니다.

을 사용하지 않는 블랙리스트를 예방 주사입니다.이 있는 경우 n 하는 방법에 코드를 삽입,당신은 당신의 생각할 것 n-mm>0.

사용 whitelist 허용되는 매개변수(또는 패턴).그것은 훨씬 더 제한적인 자연에,하지만 그건 자연의 보안을 보장합니다.

경우,당신을 호출할 수 있는 도구를하지 않고 프로그래밍 명령 라인 것,아마도 당신의 최선의 선택입니다.그렇지 않으면,당신은 잠재적으로 실행하는 명령행 도구를 통해 사용자가 절대적으로 액세스 할 수 아무것도를 제외하고(아마도 하나의 디렉토리에 있는 그들은 할 수 없이 어떤 해로)...하지만 끝날 수 있습을 깨고 도구를,무엇에 따라 이 도구는 않습니다.

그냥 참고,내가 결코 없었다 해도 얼굴이 문제이기 때문에,나는 결코 실제로 있었을 호출하려면 명령행에서 도구를 외부에서 직면하는 도구는 필요로부터 입력을 사용합니다.

Hmmm...

그것은 소리처럼 당신의 목록을 가지고 유효한 명령을 사용할 수 있를 실행할 수 있습니다.하지만 당신은 그들을 원하지 않을 실행합니다.

당신이 시도할 수 있습하고 실제 명령줄 확인 파일에 존재하는"안전한"위치 적어도 있습니다.

수도로 문제를 해결하기 위해 더 많은 인터페이스를 제공한 드롭다운 명령하고 매개 변수들을 사용할 수 있습니다..그것은 더 많은 작업에서 당신의 끝나지만,그것은 궁극적으로 사용.

당신은 실행되는 프로그램이 직접 또는 통니까?는 경우에 당신은 항상작 외부 프로그램을 제공하여 전체 경로를 실행을 떠나 쉘 방정식에서,당신은 정말 없이 취약하는 모든 종류의 명령 라인에 주입입니다.

@커트 Hagenlocher 의 백틱은 당신을 죽일 수 있습니다.는 경우 윈도우 시스템은 설치"잘못된",또는 유닉스 시스템을 수 있는 dir&bt;del*&bt;먼저 실행하 del*명령을 사용하여 다음에서 출력의 장소 del*,이 경우에 상관 없기 때문에 아무것도 없을 dir(또는 ls)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top