본문 바로가기

Web Security/Secure Coding

시큐어 코딩 (Command Injection)

Command Injection 이란? 

 적절한 검증 절차를 수행하지 않은 사용자 입력 값이 운영체제 명령어의 일부 또는 전부로 구성되어 실행되는 경우, 의도하지 않은 시스템 명령어가 실행되어 부적절하게 권한이 변경되거나 시스템 동작 및 운영에 악영향을 미치는 공격. 일반적으로 명령어 라인의 인수나 스트림 입력 등 외부 입력을 사용하여 시스템 명령어를 생성하는 프로그램에서 적절한 처리를 해주지 않으면, 공격자가 원하는 명령어 실행이 가능하게 된다. 

Command Injection 공격 원리

 1. 공격자가 입력 값에 ';', "||", "&&" 등을 포함시켜 공격자가 원하는 명령어를 삽입

 2. 웹 서버에서 공격자가 요청한 명령이 실행

 

Command Injection 공격을 당했을 경우, 공격자가 웹 서버에 백도어를 심거나 다른 명령들을 실행할 수 있게 된다. 공격자의 입장이 되어 공격을 시도한다고 가정하면, [일반적인 입력]; [실행하고자 하는 명령] 을 입력한다. 이 후, 일반적인 입력으로 인한 명령이 실행된 후 실행하고자 하는 명령 또한 실행이 된다. 

 

시큐어 코딩 보안 가이드에 나와있는 JAVA 코드를 예시로 알아보자. 

 

[안전하지 않은 코드] 

`````
    props.load(in); 
    String version = props.getProperty("dir_type");
    String cmd = new String("cmd.exe /K \"rmanDB.bat \""); 
    Runtime.getRuntime().exec(cmd + "c:\\prog_cmd\\" + version); // 취약한 코드 
`````

위 코드를 보면, 외부의 입력에 대해 어떠한 필터링 과정도 거치지 않고 실행되고 있는 것을 알 수 있다. 이러한 경우, version 부분에 "1.1; cat /etc/passwd" 와 같은 입력 값을 주고, 해당 명령이 실행된 결과를 웹 사이트에서 보여준다면 "cat /etc/passwd" 해당 명령의 결과를 웹에서 볼 수 있게 된다. 즉, 이러한 공격 뿐만 아니라 공격자가 백도어를 심게 되면 서버가 장악 당할 수도 있기 때문에 매우 위험하다. 그렇기에, 필터링이 필요하다. 아래 예제 코드를 통해 알아보자. 

`````
    props.load(in); 
    String version = {"1.0", "1.1"}; 
    int versionSelection = Integer.pareseInt(props.getProperty("version")); 
    String cmd = new String("cmd.exe /K \"rmanDB.bat \""); 
    String vs = ""; 
    
    //Secure Coding
    if(versionSelection == 0) { 
        vs = version[0];
    }else if (versionSelection == 1) { 
        vs = version[1];
    }else{
        vs = version[1];
    }
    Runtime.getRuntime().exec(cmd + "c:\\prog_cmd\\" + vs); // 취약한 코드 
`````

위 코드는 외부 입력에 따라 적절한 인자값을 선택하도록 하여, 외부의 부적절한 입력이 명령어로 사용될 가능성을 배제시켰다. 이와 같이, 특정 경우를 지정해준다면 Command Injection 에 의한 공격을 막을 수 있다. 

 

참고 문헌

[1] 시큐어 코딩 보안 가이드 https://www.kisa.or.kr/public/laws/laws3_View.jsp?mode=view