Logo Zephyrnet

Sản phẩm khác của Apache: Các lỗi nghiêm trọng trong máy chủ web 'httpd', hãy vá ngay!

Ngày:

Chọn một người ngẫu nhiên, ngay bây giờ vào cuối tháng 2021 năm XNUMX và hỏi họ hai câu hỏi sau:

Q1. Bạn đã nghe nói về Apache chưa?
Q2. Nếu vậy, bạn có thể đặt tên cho một sản phẩm Apache không?

Chúng tôi sẵn sàng đánh cuộc rằng bạn sẽ nhận được một trong hai câu trả lời:

A1. Không. A2. (Không áp dụng.)
A1. Vâng. A2. Nhật ký4j.

Tuy nhiên, hai tuần trước, chúng tôi cho rằng rất ít người đã nghe nói đến log4j, và thậm chí trong số những người am hiểu đó, rất ít người đặc biệt quan tâm đến nó.

Cho đến khi một nhóm lỗi có khả năng gây thảm họa được phát hiện dưới lỗi thương hiệu Log4Shell, thư viện lập trình Log4j chỉ đơn thuần là một trong nhiều thành phần được hàng nghìn, thậm chí có thể là hàng trăm nghìn ứng dụng và tiện ích Java sử dụng.

Log4j chỉ là “một phần của chuỗi cung ứng” và nó đã được tích hợp vào nhiều máy chủ phụ trợ và dịch vụ dựa trên đám mây hơn bất kỳ ai thực sự nhận ra cho đến nay.

Nhiều sysdamin, nhân viên CNTT và nhóm an ninh mạng đã dành hai tuần qua diệt trừ bệnh dịch có lập trình này khỏi sự tàn phá của họ. (Vâng, đó là một từ có thật. Nó được phát âm là lĩnh vực, nhưng cách viết cổ xưa tránh ám chỉ mạng Windows.)

Đừng quên “Apache khác”

Tua lại thời kỳ tiền Log4j gần đây và chúng tôi khuyên bạn nên nhận được một cặp câu trả lời khác, cụ thể là:

A1. Vâng. A2. Apache là một máy chủ web phải không? (Trên thực tế, đó là nền tảng phần mềm tạo nên máy chủ web, cùng với nhiều thứ khác.)
A1. Vâng. A2. Apache tạo ra httpd, có lẽ vẫn là máy chủ web phổ biến nhất thế giới.

Với hơn 3000 tệp với tổng số gần một triệu dòng mã nguồn, Apache httpd là một máy chủ lớn và có khả năng, với vô số sự kết hợp của các mô-đun và tùy chọn khiến nó vừa mạnh mẽ vừa nguy hiểm.

May mắn thay, nguồn mở httpd Sản phẩm nhận được sự quan tâm liên tục từ các nhà phát triển, nhận được các bản cập nhật thường xuyên mang đến các tính năng mới cùng với các bản vá bảo mật quan trọng.

Vì vậy, trong sự phấn khích về Apache Log4j, đừng quên điều đó:

  • Bạn gần như chắc chắn có Apache httpd trong mạng của bạn ở đâu đó. Giống như Log4j, httpd có thói quen âm thầm tham gia vào các dự án phần mềm, chẳng hạn như một phần của dịch vụ nội bộ hoạt động tốt đến mức hiếm khi thu hút sự chú ý đến chính nó hoặc như một thành phần được xây dựng một cách kín đáo vào sản phẩm hoặc dịch vụ mà bạn bán không chủ yếu được coi là "chứa một máy chủ web".
  • Apache vừa xuất bản một httpd bản cập nhật sửa hai lỗi bảo mật được đánh số CVE. Những lỗi này có thể không xuất hiện trong cấu hình của bạn vì chúng là một phần của các mô-đun thời gian chạy tùy chọn mà bạn có thể không thực sự sử dụng. Nhưng nếu bạn đang sử dụng các mô-đun này, dù bạn có nhận ra hay không, bạn vẫn có thể gặp nguy cơ xảy ra sự cố máy chủ, rò rỉ dữ liệu hoặc thậm chí là thực thi mã từ xa.

Điều gì đã được sửa chữa?

Hai lỗ hổng được đánh số CVE được liệt kê trong Nhật ký thay đổi của riêng Apache như sau:

  • CVE-2021-44790: Có thể tràn bộ đệm khi phân tích nội dung nhiều phần trong mod_lua của Máy chủ HTTP Apache 2.4.51
  • CVE-2021-44224: Có thể hủy đăng ký NULL hoặc SSRF trong cấu hình proxy chuyển tiếp trong Máy chủ HTTP Apache 2.4.51 trở về trước.

Tin tốt về lỗi đầu tiên là Chính Apache đã cảnh báo rằng mod_lua phần mở rộng máy chủ (cho phép bạn điều chỉnh hành vi của httpd sử dụng tập lệnh Lua thay vì phải viết mô-đun bằng C):

…nắm giữ rất nhiều quyền lực httpd, vừa là điểm mạnh vừa là nguy cơ bảo mật tiềm ẩn. Bạn không nên sử dụng mô-đun này trên máy chủ được chia sẻ với những người dùng mà bạn không tin tưởng vì nó có thể bị lạm dụng để thay đổi hoạt động nội bộ của httpd.

Tuy nhiên, như Log4j đã dạy chúng ta, các lỗi có khả năng bị khai thác ngay cả trên các máy chủ không công cộng cũng có thể gây rắc rối nếu những lỗi đó có thể được kích hoạt bởi dữ liệu người dùng không đáng tin cậy được truyền qua các máy chủ kết nối internet khác ở biên mạng của bạn.

Và CVE-2021-44790 không liên quan đến việc đưa bất kỳ tập lệnh Lua bổ trợ không đáng tin cậy nào vào cấu hình.

Thay vào đó, nó chỉ đơn giản là đánh lừa “bộ tiền xử lý” chuẩn bị nội dung người dùng không đáng tin cậy để chuyển đến các tập lệnh Lua đáng tin cậy, do đó, cuộc tấn công không phụ thuộc vào lỗi hoặc sai sót trong bất kỳ tập lệnh bổ sung nào mà bạn có thể đã tự viết.

Chia tin nhắn nhiều phần

Nói một cách đơn giản, lỗi CVE-2021-44790 tồn tại trong mã giải mã các thông báo nhiều phần, thường gặp trong các biểu mẫu tải lên trên web, thường trông giống như sau:

Loại nội dung: nhiều phần/biểu mẫu dữ liệu; ranh giới=VILC2R2IHFHLZZ --VILC2R2IHFHLZZ Bố trí nội dung: dữ liệu biểu mẫu; name="name" <--blank dòng biểu thị sự bắt đầu của mục dữ liệu đầu tiên Paul Ducklin --VILC2R2IHFHLZZ <--double-dash-plus-boundary biểu thị sự kết thúc Content-Disposition: form-data; name="phone" <--dòng trống biểu thị sự bắt đầu của mục dữ liệu thứ hai 555-555-5555 --VILC2R2IHFHLZZ-- <-double-dash-plus-boundary biểu thị sự kết thúc

Về mặt kỹ thuật, mỗi thành phần gồm nhiều phần bao gồm dữ liệu sau khi ở cuối mỗi dòng trống hoàn toàn (xem ở trên) và trước mỗi đường ranh giới, bao gồm hai dấu gạch ngang (dấu gạch ngang), theo sau là văn bản đánh dấu ranh giới duy nhất.

(Trong trường hợp bạn thắc mắc, dấu gạch ngang kép bổ sung ở cuối dòng cuối cùng ở trên báo hiệu mục cuối cùng trong danh sách.)

Một dòng trống trong dữ liệu thô xuất hiện dưới dạng hai dòng liên tiếp CRLF (chuyển dòng cộng với dòng cấp dữ liệu) hoặc mã ASCII (13,10,13,10), được biểu thị bằng C bằng chuỗi văn bản "rnrn".

Việc phân tích cú pháp này được xử lý rất thô sơ bằng mã mà chúng tôi đã đơn giản hóa như thế này:

for (start = findnext(start,boundarytext); start != NULL; start = end) { crlf = findnext(start,"rnrn"); if (!crlf) break; end = findnext(crlf,boundarytext); len = end - crlf - 8; buff = memalloc(len+1); memcpy(buff,crlf+4,len); [. . .]
}

Đừng lo lắng nếu bạn không biết C – mã này không thể xuyên thủng và được ghi chép kém ngay cả khi bạn biết. (Bản gốc phức tạp hơn và khó theo dõi hơn; chúng tôi đã lược bỏ nó về những điều cơ bản ở đây.)

Nói một cách lỏng lẻo, nó tìm kiếm một đôi-CRLF chuỗi, biểu thị dòng trống tiếp theo.

Từ đó, nó tìm thấy lần xuất hiện tiếp theo của văn bản đánh dấu ranh giới (VILC2R2IHFHLZZ trong ví dụ của chúng tôi ở trên).

Sau đó, nó giả định rằng dữ liệu cần trích xuất bao gồm mọi thứ nằm giữa hai điểm đánh dấu đó, được biểu thị bằng địa chỉ bộ nhớ (con trỏ trong thuật ngữ C) crlfend, trừ 8 byte.

Mã này không nỗ lực giải thích ý nghĩa của “trừ 8” trong mã, cũng như “cộng 4” ở hai dòng sau đó, mặc dù đó là một phỏng đoán ngay lập tức tốt rằng crlf+4 có thể bỏ qua 4 byte tạo nên dữ liệu trong CRLFCRLF chính chuỗi đó. (Dòng trống là dấu phân cách và không phải là một phần dữ liệu sẽ được sử dụng.)

Đây là nơi mà số 8 xuất phát:

  • 4 byte được đưa lên bởi CRLFCRLF các ký tự ở đầu, không phải là một phần của dữ liệu.
  • 2 byte của CRLF ở cuối dòng dữ liệu cuối cùng, không được bao gồm.
  • 2 byte được sử dụng bởi dấu gạch ngang (--) biểu thị điểm bắt đầu của đường ranh giới, không được bao gồm.

Như bạn có thể thấy, mã phân bổ đủ bộ nhớ cho dữ liệu giữa điểm bắt đầu chính xác của dòng sau CRLFCRLF dấu phân cách và điểm cuối chính xác của dòng trước điểm đánh dấu ranh giới…

…cộng thêm 1 byte (len+1) để đảm bảo NUL ký tự (một byte 0) ở cuối bộ đệm để đóng vai trò là dấu kết thúc mà chuỗi văn bản yêu cầu trong C.

Mã sau đó sử dụng memcpy() để sao chép dữ liệu liên quan từ tin nhắn đến vào bộ nhớ đệm mới, trong đó dữ liệu sẽ được hiển thị dưới dạng tập lệnh Lua sắp chạy.

Nếu không có 8 byte thì sao?

Có lẽ bạn đã tìm ra vấn đề: Nếu không còn 8 byte cần xóa thì sao? Điều gì sẽ xảy ra nếu CRLF ở cuối dòng dữ liệu cuối cùng, hoặc -- ở đầu dòng tiếp theo, không có ở đó sao?

Điều gì sẽ xảy ra nếu không có 8 byte hoàn toàn giữa CRLFCRLF và văn bản ranh giới?

Lỗi này sẽ rõ ràng hơn nhiều nếu mã được xây dựng hoặc nhận xét rõ ràng hơn và gần như chắc chắn sẽ tránh được nếu CRLF-- dấu phân cách giữa dòng trống và văn bản ranh giới đã được lập trình viên xác minh rõ ràng. và được kiểm tra một cách rõ ràng.

Lỗi này đã được vá bằng cách thêm một kiểm tra để đảm bảo rằng phép tính kích thước bộ đệm cuối cùng không quá nhỏ, bằng cách thêm một dòng trước nỗ lực phân bổ bộ nhớ:

 if (end - crlf <= 8) break;

Điều này xác minh rằng độ dài bộ đệm không thể kết thúc bằng số âm, mặc dù chúng tôi vẫn nghĩ rằng việc kiểm tra rõ ràng để tìm bộ kết thúc dữ liệu chính xác, giống như cách có một kiểm tra rõ ràng cho CRLFCRLF, sẽ làm cho mã rõ ràng hơn.

Chúng tôi cũng sẽ chèn một nhận xét hữu ích giới thiệu người đọc đến một trong các RFC trên internet về các tin nhắn nhiều phần, ví dụ: RFC 2045.

Sự cố proxy

Việc xử lý CVE-2021-44224 liên quan đến nhiều thay đổi về mã, rõ ràng nhất là việc chỉnh sửa một tệp chứa đầy mã tiện ích được sử dụng bởi httpd mô-đun proxy.

Thực tế là có hơn 5000 dòng C trong proxy_util.c riêng, đó chỉ là mã hỗ trợ cho một trong nhiều httpd module, là minh chứng cho kích thước tổng thể và độ phức tạp của Máy chủ HTTP Apache.

Mã chúng tôi đang đề cập ở trên đã được thay đổi từ…

url = ap_proxy_de_socketfy(p, url);

…để mã xác minh rằng hàm được gọi thực sự đã tìm thấy chuỗi URL để hoạt động:

url = ap_proxy_de_socketfy(p, url);
if (!url) { return NULL;
}

Trước khi kiểm tra lỗi “nếu không có url” buộc mã phải bỏ cuộc sớm, chương trình sẽ tiếp tục ngay cả khi urlNULLvà cố gắng truy cập bộ nhớ thông qua NULL địa chỉ nhà.

Nhưng đọc từ hoặc viết vào một NULL con trỏ là “không xác định” theo tiêu chuẩn C, có nghĩa là bạn phải cẩn thận không bao giờ làm như vậy.

Thật vậy, trên hầu hết các hệ điều hành hiện đại, giá trị được sử dụng cho NULL, thường là 0, được chọn sao cho mọi nỗ lực truy cập vào NULL Địa chỉ, dù bằng cách đọc hay ghi, sẽ không những không thành công mà còn bị hệ điều hành giữ lại, sau đó hệ điều hành này thường sẽ tắt quá trình vi phạm để ngăn chặn các tác dụng phụ nguy hiểm hoặc ngoài ý muốn.

Phải làm gì?

  • Nếu bạn đang sử dụng Apache httpd bất cứ nơi nào, Cập nhật lên 2.4.52 Càng sớm càng tốt.
  • Nếu bạn không thể vá, kiểm tra xem cấu hình của bạn có gặp rủi ro hay không. Có nhiều bản sửa lỗi ngoài hai CVE này, vì vậy bạn nên vá sớm hơn. Tuy nhiên, bạn có thể quyết định trì hoãn việc vá lỗi cho đến thời điểm thuận tiện hơn nếu bạn không tải tập lệnh Lua hoặc mô-đun proxy.
  • Nếu bạn là một lập trình viên, đừng quên kiểm tra lỗi kỹ lưỡng trong các chương trình của bạn. Nếu có cơ hội phát hiện ra lỗi trước khi khiến chúng trở nên tồi tệ hơn, chẳng hạn như bằng cách xác minh rằng bạn thực sự có đủ bộ nhớ để sử dụng hoặc kiểm tra xem chuỗi bạn đang tìm kiếm có thực sự ở đó hay không, hãy nắm lấy cơ hội đó!
  • Nếu bạn là lập trình viên, giả sử rằng người khác sẽ cần hiểu mã của bạn trong tương lai. Viết những bình luận hữu ích và hữu ích, với lý do ai không nhớ được chuyện đã qua sẽ bị buộc tội lặp lại.

Nguồn: https://nakedsecurity.sophos.com/2021/12/21/apaches-other-product-essential-bugs-in-httpd-web-server-patch-now/

tại chỗ_img

Tin tức mới nhất

tại chỗ_img