Command Injection 요약

실습 기간 : 2017.05.05 ~ 2017.05.07
실습 환경 : kali linux, FTZ

Content

  1. Command Injection 기법이란?
    1.1. Command Injection 정의
    1.2. SetUID, SetGID, Sticky Bit
    1.3. Code Injection

  2. Command Injection 관련 취약 함수
    2.1. System()
    2.2. exec 계열 함수
    2.3. fork()

  3. Command Injection 실습
    3.1. FTZ level 3

Command Injection 기법이란?

1.1 Command Injection 정의

1.2 SetUID, SetGID, Sticky Bit

    chmod 1755 stickybit.txt     // -rwxr-xr-t
    chmod 2755 setgid.txt        // -rwxr-sr-x
    chmod 4755 setuid.txt        // -rwsr-xr-x
              [ ex - 권한 설정 ]

1.3 Code Injection

­     ` ` : back quote ( back tick )
­     $( ) : dollar
­     ex) command1 `command2` : 2의 실행 결과를 1의 인자로 넘김

     command1; command2; command3 ...
     => 터미널에서 다수의 명령어를 각각 실행
     command1 && command2 && command3 ...
     => 다수의 명령어를 실행, 앞선 명령어가 성공적으로 실행되어야 다음 명령어
        실행 가능
     command1 || command2 || command3 ...
     => 다수의 명령어 중 하나라도 성공하면 다음 명령어 수행 X
            [ ex - code injection ( ;, &&, || ) ]

Command Injection 관련 취약 함수 분석

2.1. System()

     #include <stdlib.h>
     int system(const char *string)
        [ ex - system 함수 원형 ]
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    void main( char* argc, char** argv ) {
            char cmd[60] = "/bin/ls ";
            strcat(cmd, argv[1]);
            system(cmd);
    }
    [ ex - soruce code – command_injection.c ]

    ­ - SetUID 설정 chmod 4755 command_injection.c
    ­ - 검증 되지 않은 입력( Untrusted Input )

2.2. exec 계열 함수

    #include <unistd.h>
    int execv  ( const char *path, char *const argv[]);
    int execve ( const char *path, char *const argv[], char *const envp);
    int execlp ( const char *file, const char *arg0, ... , const char *argn, (char *)0);
    int execvp ( const char *file, char *const argv[]);
    int execl  ( const char *path, const char *arg0, ... , const char *argn, (char *)0);
    int execle ( const char path, const char *arg0, ... , const char *argn, (char *)0,
                 char *const envp[]);
                        [ ex - exec 계열 함수 원형 ]
    #include <unistd.h>
    int main() {  
         execl("/bin/sh", "/bin/sh", NULL);
    }
             [ ex - execl 함수 ]
    #include <unistd.h>
    #include <string.h>
    int main(int argc, char **argv)  {
         char *env[]={"MYHOME=seoul", "MYTEST=1234", (char *)0};
         execle("/bin/sh", "sh", NULL, env);
         perror();
    }
                [ ex - execle 함수 ]

2.3. fork()

    #include <sys/types.h>
    #include <unistd.h>
    pid_t fork(void)
    [ ex – fork 함수 원형 ]

2.4. 기타 언어의 함수들

취약한 함수 구분

Command Injection 실습

3.1. FTZ level 3

source code

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    int main(int argc, char **argv){
        char cmd[100];
        if( argc!=2 ){
            printf( "Auto Digger Version 0.9\n" );
            printf( "Usage : %s host\n", argv[0] );
            exit(0);
        }
        strcpy( cmd, "dig @" );
        strcat( cmd, argv[1] );
        strcat( cmd, " version.bind chaos txt");
        system( cmd );
    }
    ```

    분석
    ```
    # 공격 대상 파일 찾기
         1. 파일명
              find / -name autodig 2> /dev/null
              / 경로를 기준으로 이름이 autodig인 파일을 탐색,
              2> (오류메세지)를 /dev/null 로 보내어 오류메세지 안보이게 함
         2. 파일 권한
              find / -perm +6000 -user level4 2> /dev/null
    # 공격 대상 파일의 기능 분석
    # 리버싱을 통한 의사 코드 복원
    0x08048430 <main+0>:    push   %ebp
    0x08048431 <main+1>:    mov    %esp,%ebp
         - 스택 구성
         - ebp 주소를 저장하고 현재의 esp를 ebp에 저장
    0x08048433 <main+3>:    sub    $0x78,%esp
         - 변수 선언 공간 확보
    0x08048436 <main+6>:    and    $0xfffffff0,%esp
    0x08048439 <main+9>:    mov    $0x0,%eax
    0x0804843e <main+14>:   sub    %eax,%esp
    0x08048440 <main+16>:   cmpl   $0x2,0x8(%ebp)
    0x08048444 <main+20>:   je     0x8048475 <main+69>
         - 조건문 EBP+8의 위치에 값이 0x2인지 비교
         - 참일 경우 0x8048475 <main+69>로 이동
    인자값이 2가 아닐 경우 수행
    0x08048446 <main+22>:   sub    $0xc,%esp
    0x08048449 <main+25>:   push   $0x8048588
    0x0804844e <main+30>:   call   0x8048340 <printf>
    0x08048453 <main+35>:   add    $0x10,%esp
    0x08048456 <main+38>:   sub    $0x8,%esp
    0x08048459 <main+41>:   mov    0xc(%ebp),%eax
    0x0804845c <main+44>:   pushl  (%eax)
    0x0804845e <main+46>:   push   $0x80485a1
    0x08048463 <main+51>:   call   0x8048340 <printf>
    0x08048468 <main+56>:   add    $0x10,%esp
    0x0804846b <main+59>:   sub    $0xc,%esp
    0x0804846e <main+62>:   push   $0x0
    0x08048470 <main+64>:   call   0x8048360 <exit>
    인자값이 2일경우 수행 구문
    0x08048475 <main+69>:   sub    $0x8,%esp
    0x08048478 <main+72>:   push   $0x80485b2
         - 0x80485b2 <_IO_stdin_used+46>:    " dig @"
    0x0804847d <main+77>:   lea    0xffffff88(%ebp),%eax
    0x08048480 <main+80>:   push   %eax
    0x08048481 <main+81>:   call   0x8048370 <strcpy>
         - strcpy의 인자로 스택에 push된 %eax, dig @ 사용
    0x08048486 <main+86>:   add    $0x10,%esp
    0x08048489 <main+89>:   sub    $0x8,%esp
    0x0804848c <main+92>:   mov    0xc(%ebp),%eax
    0x0804848f <main+95>:   add    $0x4,%eax
    0x08048492 <main+98>:   pushl  (%eax)
         - 입력받은 아이피 주소
    0x08048494 <main+100>:  lea    0xffffff88(%ebp),%eax
    0x08048497 <main+103>:  push   %eax
    0x08048498 <main+104>:  call   0x8048330 <strcat>
         - dig @ 와 아이피 주소 문자열 합침
    0x0804849d <main+109>:  add    $0x10,%esp
    0x080484a0 <main+112>:  sub    $0x8,%esp
    0x080484a3 <main+115>:  push   $0x80485b8
         - 0x80485b8 <_IO_stdin_used+52>:   " version.bind chaos txt"
    0x080484a8 <main+120>:  lea    0xffffff88(%ebp),%eax
    0x080484ab <main+123>:  push   %eax
    0x080484ac <main+124>:  call   0x8048330 <strcat>
         - push 된 두인자의 문자열 합침
    0x080484b1 <main+129>:  add    $0x10,%esp
    0x080484b4 <main+132>:  sub    $0x8,%esp
    0x080484b7 <main+135>:  push   $0xbbc
    0x080484bc <main+140>:  push   $0xbbc
         - 3004
    0x080484c1 <main+145>:  call   0x8048350 <setreuid>
         - setreuid : 현재 프로세스의 유효한 사용자 ID 설정
         - 인자 : ruid, euid
    0x080484c6 <main+150>:  add    $0x10,%esp
    0x080484c9 <main+153>:  sub    $0xc,%esp
    0x080484cc <main+156>:  lea    0xffffff88(%ebp),%eax
    0x080484cf <main+159>:  push   %eax
    0x080484d0 <main+160>:  call   0x8048310 <system>
         - 시스템 함수 실행
    0x080484d5 <main+165>:  add    $0x10,%esp
    0x080484d8 <main+168>:  leave
    0x080484d9 <main+169>:  ret
    0x080484da <main+170>:  nop
    0x080484db <main+171>:  nop

공격

참고문헌

[1] 문제풀이로 배우는 시스템 해킹 테크닉, 여동기 저, 위키북스

[2] Command Injection
https://bpsecblog.wordpress.com/2016/10/05/command_injection_02/

[3] Command Injection 정의
https://www.owasp.org/index.php/Command_Injection