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
'Web Security > Secure Coding' 카테고리의 다른 글
시큐어 코딩 (Open Redirect) (0) | 2021.07.30 |
---|---|
시큐어 코딩 (File upload vulnerability) (0) | 2021.07.30 |
시큐어 코딩 (Cross-Site Scripting) (0) | 2021.07.29 |
시큐어 코딩 (Resource Injection) (0) | 2021.07.29 |
시큐어 코딩 (SQL Injection) (0) | 2021.07.28 |