CẢNH BÁO KHÔNG CHẠM VÀO CHẠY NÀY TRÊN MÁY SẢN XUẤT. CHỈ KHÔNG.
Cảnh báo: Để thử bất kỳ "quả bom" nào, hãy đảm bảo ulimit -u
đang sử dụng. Đọc dưới đây [a] .
Chúng ta hãy xác định một hàm để có được PID và ngày (thời gian):
bize:~$ d(){ printf '%7s %07d %s\n' "$1" "$BASHPID" "$(date +'%H:%M:%S')"; }
Một bomb
chức năng đơn giản, không có vấn đề cho người dùng mới (tự bảo vệ mình: đọc [a] ):
bize:~$ bomb() { d START; echo "yes"; sleep 1; d END; } >&2
Khi chức năng đó được gọi để được thực thi hoạt động như sau:
bize:~$ bomb
START 0002786 23:07:34
yes
END 0002786 23:07:35
bize:~$
Lệnh date
được thực thi, sau đó một chữ "có" được in, ngủ trong 1 giây, sau đó là lệnh đóng date
và cuối cùng, hàm thoát ra in một dấu nhắc lệnh mới. Không có gì lạ mắt.
| ống
Khi chúng ta gọi hàm như thế này:
bize:~$ bomb | bomb
START 0003365 23:11:34
yes
START 0003366 23:11:34
yes
END 0003365 23:11:35
END 0003366 23:11:35
bize:~$
Hai lệnh được bắt đầu tại một số thời điểm, hai kết thúc 1 giây sau đó và sau đó nhắc nhở trả về.
Đó là lý do cho đường ống |
, để bắt đầu hai quá trình song song.
& lý lịch
Nếu chúng ta thay đổi cuộc gọi thêm một kết thúc &
:
bize:~$ bomb | bomb &
[1] 3380
bize:~$
START 0003379 23:14:14
yes
START 0003380 23:14:14
yes
END 0003379 23:14:15
END 0003380 23:14:15
Dấu nhắc trả về ngay lập tức (tất cả các hành động được gửi đến nền) và hai lệnh được thực hiện như trước. Vui lòng lưu ý giá trị của "số công việc" [1]
được in trước PID của quy trình 3380
. Sau đó, cùng một số sẽ được in để chỉ ra rằng đường ống đã kết thúc:
[1]+ Done bomb | bomb
Đó là tác dụng của &
.
Đó là lý do của &
: để có được các quy trình bắt đầu nhanh hơn.
Tên đơn giản
Chúng ta có thể tạo một hàm gọi đơn giản là b
để thực thi hai lệnh. Gõ ba dòng:
bize:~$ b(){
> bomb | bomb
> }
Và thực hiện như:
bize:~$ b
START 0003563 23:21:10
yes
START 0003564 23:21:10
yes
END 0003564 23:21:11
END 0003563 23:21:11
Lưu ý rằng chúng tôi không sử dụng ;
trong định nghĩa b
(dòng mới được sử dụng để phân tách các yếu tố). Tuy nhiên, đối với một định nghĩa trên một dòng, thông thường sử dụng ;
, như thế này:
bize:~$ b(){ bomb | bomb ; }
Hầu hết các không gian cũng không bắt buộc, chúng ta có thể viết tương đương (nhưng ít rõ ràng hơn):
bize:~$ b(){ bomb|bomb;}
Chúng ta cũng có thể sử dụng a &
để tách }
(và gửi hai quá trình xuống nền).
Bom.
Nếu chúng ta thực hiện chức năng cắn đuôi của nó (bằng cách gọi chính nó), chúng ta sẽ nhận được "quả bom ngã ba":
bize:~$ b(){ b|b;} ### May look better as b(){ b | b ; } but does the same.
Và để làm cho nó gọi nhiều chức năng nhanh hơn, hãy gửi đường ống đến nền.
bize:~$ b(){ b|b&} ### Usually written as b(){ b|b& }
Nếu chúng ta nối thêm cuộc gọi đầu tiên vào chức năng sau khi có yêu cầu ;
và thay đổi tên thành :
chúng ta sẽ nhận được:
bize:~$ :(){ :|:&};:
Thường được viết là :(){ :|:& }; :
Hoặc, được viết theo một cách vui vẻ, với một số tên khác (một người tuyết):
☃(){ ☃|☃&};☃
Các ulimit (mà bạn nên đặt trước khi chạy này) sẽ khiến cho dấu nhắc trở lại khá nhanh sau khi có nhiều lỗi (nhấn enter khi danh sách lỗi dừng để nhận lời nhắc).
Lý do của việc này được gọi là "bom ngã ba" là vì cách mà lớp vỏ khởi động lớp vỏ phụ là bằng cách sử dụng lớp vỏ đang chạy và sau đó gọi exec () đến quy trình rẽ nhánh bằng lệnh để chạy.
Một đường ống sẽ "rẽ nhánh" hai quá trình mới. Làm điều đó đến vô cùng gây ra một quả bom.
Hoặc một con thỏ như được gọi ban đầu vì nó sinh sản rất nhanh.
Thời gian:
:(){ (:) | (:) }; time :
Chấm dứt
thực 0m45.627s
:(){ : | :; }; time :
Chấm dứt
thực 0m15.283s
:(){ : | :& }; time :
thực 0m00.002 s
Vẫn đang chạy
Ví dụ của bạn:
:(){ (:) | (:) }; :
Trong đó lần đóng thứ hai )
phân tách }
là phiên bản phức tạp hơn :(){ :|:;};:
. Mỗi lệnh trong một ống được gọi bên trong một vỏ con. Đó là tác dụng của ()
.
:(){ : | :& }; :
Là phiên bản nhanh hơn, được viết không có khoảng trắng: :(){(:)|:&};:
(13 ký tự).
:(){ : | : }; :
### hoạt động trong zsh nhưng không phải trong bash.
Có lỗi cú pháp (trong bash), cần có một metacharacter trước khi đóng }
,
như sau:
:(){ : | :; }; :
[a]
Tạo người dùng sạch mới (Tôi sẽ gọi cho tôibize
). Đăng nhập vào người dùng mới này trong bảng điều khiểnsudo -i -u bize
hoặc:
$ su - bize
Password:
bize:~$
Kiểm tra và sau đó thay đổi max user processes
giới hạn:
bize:~$ ulimit -a ### List all limits (I show only `-u`)
max user processes (-u) 63931
bize:~$ ulimit -u 10 ### Low
bize:~$ ulimit -a
max user processes (-u) 1000
Chỉ sử dụng 10 hoạt động như là một người dùng mới đơn độc : bize
. Nó giúp dễ dàng hơn để gọi killall -u bize
và loại bỏ hệ thống loại bỏ hầu hết (không phải tất cả) bom. Xin đừng hỏi cái nào vẫn hoạt động, tôi sẽ không nói. Nhưng vẫn: khá thấp nhưng về mặt an toàn, hãy thích ứng với hệ thống của bạn .
Điều này sẽ đảm bảo rằng "quả bom ngã ba" sẽ không làm sập hệ thống của bạn .
Đọc thêm:
:(){ : | :; }; :