2014-09-30 4 views
1

이것이 올바른 곳인지 물어보십시오. 제한된 (사용자 지정) 셸에서 벗어날 수 있습니까?

이 입력은 그래서 같이 특정 명령을 생각한 나는, 표준 입력 입력을 받아 필터링하는 쉘을 쓰기 말

  • LS
  • 업데이트 (자식 클론) (바이너리 디렉토리 및 하위 디렉토리 목록의 내용)
  • 빌드
  • 정지 (systemctl의 STO (this.service에게 단지를 시작 systemctl)
  • 시험 (이동 테스트)
  • 시작 (빌드로 이동)
  • 이 (실행 페이지의 this.service 만) 바이너리 존재가 실행 얼마나 많은 GOMAXPROCS 함께?)
  • 사용 (메모리, CPU 사용량)
  • gensvc()
  • 종료 .service 파일을 생성 (쉘을두고/로그 아웃)

작동, 당신이 그것을 추측, 나는 사용자에게 매우 제한된 유지 관리 액세스를 ssh를 통해 제공하려고합니다.

내가 \0 조심 해요 말

sh 또는 유사하거나 어떤 식 으로든에/빈 /을 실행중인 쉘을 중지하고 실행하기 위해 어떤 방법이 있나요 (I 어쨌든 bufio.Scanner를 사용하여 이동에 쓰기 것) 이 껍질 주위에있어?

사용자는 git을 통해 베어 레포로 물건을 밀어 넣어야합니다.이 저장소는 파일 시스템에 특정 디렉토리로 복제 된 다음 빌드가 호출되고 바이너리가 systemd .service 파일로 실행됩니다. 이전에 생성되었습니다.

논리적으로 생각하면 사용자가 받아 들일 수있는 특정 문자열을 쓸 수만 있다면 아무런 방법이 없습니다. 하지만 어쩌면 당신은 하나의 ctrl + z 요법을 알 수 있습니다.) 또는 뭐든간에.

유일한 공격 대상은 입력 문자열 또는 오히려 바이트입니다. 물론 사용자는 자신의 셸을 빌드하거나 특정 명령을 실행하는 프로그램을 실행할 수 있지만 범위를 벗어납니다 (systemd를 사용하여 기능을 제거하고 장치 액세스를 제한하고 데이터베이스 서버, 개인 tmp 및 모든 장치에 대한 연결을 금지합니다. , namespace and subnamespace it)

유일한 문제는 git pushing이지만 git only mode argv에서이를 해결하고 ~/.ssh/authorized_keys에 추가 할 수 있다고 확신합니다. lish gitmode과 같은 것이고 git 또는 그와 비슷한 것으로 시작하는 경우 stdin 명령을 실행하십시오.

예 : 특정 명령을 허용하는 경우

https://gist.github.com/dalu/ce2ef43a2ef5c390a819

+0

'vim'과 같은 편집기를 사용하지 마십시오. 일단 그들은'vim '을 사용하고 나면, 그들은 쉘에 도달 할 수 있고, 그런 다음에 그들이 좋아하는 곳으로 갈 수 있습니다. 편집은 언급하지 않으므로 괜찮을 수도 있습니다. 특히 빌드 및 테스트 명령에 의해 실행될 수있는 것에주의하십시오. –

+0

@JonathanLeffler'vim'은'vim -Z'로 시작하면 안전해야합니다. – fuz

+0

@FUZxxl : 흥미 롭습니다. 예,'vim -Z'는 몇 가지 옵션을 줄이는 것 같습니다. 오리지널 'vi'도 포함되지 않았습니다. 최소한 편집자가 허용하는 사항에 대해 매우 신중해야합니다. –

답변

3

, 당신의 "쉘"명령을 읽고 그것을 분석하고 내가 오해 않는 한, 당신은 괜찮을 다음을 실행합니다.

이동 "메모리"는 실행할 수 없습니다. 어쨌든 어셈블리로 불쾌한 해킹을하지 않아도되므로 쉘 주입에 대해 걱정할 필요가 없습니다.이 라인을 따라

뭔가 안전합니다 :

func getAction() (name string, args []string) { 
    // read stdin to get the command of the user 
} 

func doAction() { 
    for { 
     action, args := getAction() 
     switch action { 
      case "update": //let's assume the full command is: update https://repo/path.git 
       if len(args) != 1 { 
        //error 
       } 
       out, err := exec.Command("/usr/bin/git", "clone", "--recursive", args[0]).CombinedOutput() 
       // do stuff with out and err 
     } 
    } 
} 
3

당신이 쉘을 직접 구현하고 직접 exec()를 통해 명령을 실행하거나 내부를 구현하는 경우, 안전한 제한된 쉘을 생산하기 위해 확실히 가능하다. 명령 행을 실제 쉘로 전달하기 전에 표면적으로 명령 행을 점검하고 있다면 예상하지 못했던 경우가있을 것입니다.

내가 말했듯이, 당신이 열거 한 test 명령에 대해 조금 걱정이됩니다. 사용자가 업로드하는 Go 패키지의 테스트 스위트를 실행하기위한 것인가? 그렇다면 공격자 인 경우 제한된 셸을 악용하려고 시도조차하지 않을 것입니다. 원하는 작업을 수행하는 테스트로 패키지를 업로드하기 만하면됩니다. build/start에 대해서도 마찬가지입니다.

+0

예, git push, 복제, 빌드, 테스트, 생성 서비스, 실행 서비스. tcp outbound 및 tcp를 제외한 모든 환경을 로컬 데이터베이스 노드에 완전히 격리시켜야합니다. 프로그램이 실행될 때 나는 아무것도 마운트 할 수 없다는 것을 확신시켜야하며, 쓰기는 미리 정의 된 디렉토리 (파일 업로드의 경우)에서만 발생합니다. 비공개 tmp./dev 노드에 대한 기본 액세스 외에는 금지되어 있습니다. 이는 누군가가 http를 통해 사용할 수있는 셸을 운영하더라도 관리 권한 상승으로 어떤 것도 실행할 수 없어야합니다. 나는 어느 대답을 고를 지 모른다. 나는 그것을 열어두고, 둘다 좋다. –

1

펜 테스 티잉 팀이 검토했습니다.

모든 유형의 샌드 박스를 분리 할 때 사람들은 매우 창의적입니다. 사용자의 의견을 받아 들일 수없는 경우에만 구내에서 안전하다고 생각할 수 있습니다 (그러나 명령은 입력입니다). 종이 보안 가정은 소프트웨어를 평가하는 데 약한 것으로 간주됩니다. 그것들은 논문의 알고리즘에 대한 '버그 없음'가정과 유사합니다 : 구현하자 마자 99 %의 버그가 발생합니다.

관련 문제