Skip to main content

[bash] shellshock - từ gốc đến ngọn

Shellshock là gì?
shellshock là tên của lỗi bảo mật của phần mềm bash mới được phát hiện (tháng 9/2014) và hiện đang gây một cơn sốc trên Internet. Nó không phải sốc theo kiểu "cộng đồng mạng phát cuồng", hay "cộng đồng mạng bị sốc", mà là kiểu sốc "cộng đồng mạng" cơ bản là không tham gia vào :D

Shellshock có nguy hiểm không?
Cực kỳ nguy hiểm! cực kỳ là đến mức nào? Hãy google với từ khoá "shellshock dangerous" để tìm ra câu trả lời cho chính mình.
Nói thẳng ra thì người dùng Windows không bị ảnh hưởng (trực tiếp), còn ai không biết thì chẳng thấy nguy hiểm gì. Giống như dịch Ebola, ai biết nó gây chết người trong vài ngày thì thấy sợ, ai không biết nó là cái gì thì làm sao mà thấy nó nguy hiểm?!!!

Lỗi này có từ năm 1993 1989 [Thanks Le Manh Cuong] và đến nay đã 25 năm từ khi nó ra đời, nhưng đến giờ mới được phát hiện. Hãy tưởng tượng trong 25 năm ấy, hacker có thể dễ dàng vào máy tính của bạn với quyền root (tức muốn làm gì thì làm),  chẳng phải login hay ssh gì hết, và không để lại dấu vết của một cuộc xâm nhập :3

Bài viết này phân tích câu lệnh dùng để tìm ra xem phiên bản bash đang dùng có bị dính lỗi bảo mật shellshock hay không.

Câu lệnh sau giúp thực hiện điều đó (theo link wikipedia ở cuối bài):
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Nếu sau khi gõ enter mà thấy hiện ra
vulnerable
this is a test
Tức là phiên bản bash bạn đang dùng có dính lỗi bảo mật này.

Để hiểu rõ chuyện gì đã xảy ra, ta sẽ từ từ phân tích câu thần chú vừng ơi mở ra đầy thần bí này. Lần lượt dạo qua một vài khái niệm của bash để có thể hiểu câu lệnh quá xúc tích trên:

1. function 
Có hai cách định nghĩa function trong bash, trích cú pháp từ man 1 bash:

       name () compound-command [redirection]
       function name [()] compound-command [redirection]

Cách 1 ngắn gọn hơn, là dùng: tên_function () body
Cách 2 dài dòng hơn, dùng từ khóa "function": function tên_function body

Ví dụ sau định nghĩa function lần lượt theo 2 cách tương ứng trên:
hvn@archhvn: ~ () $ pika() { echo pikachu; }
hvn@archhvn: ~ () $ pika
pikachu
hvn@archhvn: ~ () $ function chipu { echo chukapi; }
hvn@archhvn: ~ () $ chipu
chukapi
Trong câu thần chú, phần định nghĩa function là:
() { :;}
Nó định nghĩa function theo cách 1, nhưng không đưa ra tên function.

2. semi-colon (dấu ;)
để viết nhiều câu lệnh trên cùng 1 dòng.

Có thể thấy 2 cách viết sau là tương đương:
hvn@archhvn: ~ () $ meomeo() {
> echo meomeomeo
> }
hvn@archhvn: ~ () $ meomeo
meomeomeo

hvn@archhvn: ~ () $ meomeo() { echo gaugaugau; }
hvn@archhvn: ~ () $ meomeo
gaugaugau
Và hoàn toàn có thể chạy một câu lệnh khác sau khi định nghĩa 1 function:
hvn@archhvn: ~ () $ fml() { echo FML; }; echo sau func
sau func
hvn@archhvn: ~ () $ fml
FML
3. env
đọc kỹ lại câu thần chú:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test" 
nó tuân theo cú pháp của câu lệnh env:
hvn@archhvn: ~ () $ env --help
Usage: env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]
ở đây, set cho NAME x bằng VALUE string '() { :;}; echo vulnerable'

rồi chạy COMMAND bash với các arg: -c "echo this is a test"

Lệnh env làm gì?
$ whatis env
env (1)              - run a program in a modified environment
nó chạy một chương trình trong một môi trường đã bị thay đổi. Nói cách khác, env export các variable vào "environment" của câu lệnh theo sau nó.
hvn@archhvn: ~ () $ unset var1 #unset trước đảm bảo var1 không được gán giá trị nào.
# Câu lệnh sau không export var1=5 vào môi trường của câu lệnh bash -c 'echo var1 la $var1", vì vậy nó không in ra gì cả cho giá trị var1:
hvn@archhvn: ~ () $ var1=5; bash -c 'echo var1 la so $var1'
var1 la so
# dưới đây là 3 cách để export var1=5 sang environment của câu lệnh theo sau nó.
hvn@archhvn: ~ () $ env var1=5; bash -c 'echo var1 la so $var1'
var1 la so 5
hvn@archhvn: ~ () $ var1=5 bash -c 'echo var1 la so $var1'
var1 la so 5 # chú ý ở trên không có dấu ;
hvn@archhvn: ~ () $ bash -c 'echo var1 la so $var1'
var1 la so
hvn@archhvn: ~ () $ export var1=5; bash -c 'echo var1 la so $var1'
var1 la so 5
hvn@archhvn: ~ () $ env | grep var1
var1=5
hvn@archhvn: ~ () $ bash -c 'echo var1 la so $var1'
var1 la so 5 
# đừng ngạc nhiên, vì export đã set biến var1 thành biến environment của bash shell hiện tại nên nó sẽ được kế thừa bởi mọi sub-process của process này (nói dễ hiểu là mọi câu lệnh chạy từ shell này). Để hủy tác dụng của nó, dùng ``unset var1``.

Như vậy, ta hòan toàn có thể sửa câu thần chú cho ngắn lại một chút (bỏ env):
$ x='() { :;}; echo vulnerable' bash -c "echo this is a test"
vulnerable
this is a test
Ta có thể định nghĩa một function không có tên, gán nó cho một biến rồi export sang environment của câu lệnh bash:
hvn@archhvn: ~ () $ anon_func='() { echo familug; }'
hvn@archhvn: ~ () $ echo $anon_func # nó chỉ là một string!
() { echo familug; }
hvn@archhvn: ~ () $ anon_func='() { echo familug; }' bash -c 'anon_func'
familug # khi export sang env của câu lệnh bash, nó là một function.

4. noop (no-op)
Trong bash, dấu : là operand (toán tử) no-operate. Tức nó không làm gì cả.

Tổng hợp:

hvn@archhvn: ~ () $ bash --version | grep bash
GNU bash, version 4.3.8(1)-release (x86_64-unknown-linux-gnu)
hvn@archhvn: ~ () $ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
vulnerable
this is a test

Câu lệnh trên export biến x với giá trị là string '() { :;}; echo vulnerable' vào môi trường của câu lệnh bash tiếp theo.
Khi export, nó export biến x nhưng đồng thời cũng chạy câu lệnh sau phần string định nghĩa function.

Đến đây, bạn đã hiểu đọc code của hacker viết mệt mỏi như thế nào :-s

Làm sao để tấn công? và tại sao nó lại nguy hiểm?

Vì rất nhiều phần mềm trên UNIX-like OSes có sử dụng bash, và bash thì lại  được cài trên hầu hết các UNIX-like servers.

Một ví dụ tấn công điển hình ở đây với kịch bản là hacker đã chiếm được DHCP server, và sử dụng lỗi shellshock để tấn công các máy client.
Bạn sẽ làm gì nếu toàn quyền chiếm được một DHCP server? có thể bạn nghĩ ra nhiều cách, nhưng chẳng có cách nào kinh khủng bằng việc chiếm được quyền root của các máy client. Tức nắm toàn quyền điều khiển hệ điều hành *NIX của người dùng, muốn lấy password, muốn cài backdoor, virus... chỉ là chuyện vặt :3
https://www.trustedsec.com/september-2014/shellshock-dhcp-rce-proof-concept/

Giải thích ngắn:
Do dhclient (client của DHCP) chạy dhcp hook scripts ( thường tìm thấy ở /etc/dhclient-enter-hooks) với quyền root. Khi một DHCP client request xin cấp một IP, nó sẽ nhận được variable gửi xuống từ DHCP server rồi chạy (bash) hook script với variable đó, nếu đó là một bash variable sử dụng lỗi nói trên, phía DHCP client sẽ chạy câu lệnh sau phần định nghĩa function với quyền root ... và BOOM!

Với lỗi nãy, hacker có thể khai thác các service có sử dụng bash variable nhận được từ phía user để chiếm quyền root trên server tương ứng. Tham khảo các cách tấn công đã được thực hiện ở đây:

http://www.fireeye.com/blog/uncategorized/2014/09/shellshock-in-the-wild.html

Làm sao để fix lỗi này?
upgrade bash trên máy/server của bạn đến version mới nhất, hầu hết các OS đều đã đưa ra bản fix cho lỗi này.

Tham khảo:
http://en.wikipedia.org/wiki/Shellshock_%28software_bug%29

patch http://thread.gmane.org/gmane.comp.shells.bash.bugs/22190

man 1 bash
SHELL BUILTIN COMMANDS

       : [arguments]
              No effect; the command does nothing beyond expanding arguments and performing any specified redirections.  A zero exit code is returned.

http://unix.stackexchange.com/questions/157381/when-was-the-shellshock-cve-2014-6271-7169-bug-introduced-and-what-is-the-pat/157495#157495

Comments

  1. Lỗi này có từ tháng 5/8/1989, khi Brian Fox triển khai tính năng export function cho bash, và được release 1 tháng sau đó, 1/9/1989.

    Tham khảo: http://www.oldlinux.org/Linux.old/bin/old/bash-1.05/ChangeLog

    ReplyDelete
    Replies
    1. cám ơn bạn, mình đã sửa lại bài viết và trả lại cho lịch sử những gì của nó :D

      Delete

Post a Comment

Popular posts from this blog

Tài liệu và hướng dẫn học Python

Để tiết kiệm thời gian, tốt nhất là đi học PyMI Updated: 130617 Sau đây là các tài liệu khuyên dùng: Vì nhiều lý do, nên học python2.7 tại thời điểm hiện tại (giờ là tháng 6/2013 - muốn biết tại sao thì tự tìm hiểu) python 3.5+ (giờ là tháng 2/2017) Chuẩn bị: 1. biết bật tắt máy 2. biết cài python 3. tập gõ 10 ngón - gõ 2 ngón hay 1 ngón cũng không sao, nhưng 10 ngón là cách dễ nhất để gõ nhanh nhất. Tài liệu - Nên dùng tài liệu tại trang chủ của Python làm chính, tham khảo thêm các tài liệu khác tại http://www.familug.org/2016/12/free-ebook.html Căn bản, mới học 1.1 Python PyMI.vn https://pymi.vn/tutorial/ 1.2. Python offical tutorial kết hợp làm bài tập trên HackerRank  (đề bài bằng tiếng Anh, nhưng Google translate 1 lúc cũng ra vì có nhiều ví dụ mẫu đi kèm). Học viên của Pymi.vn có rất nhiều học viên đã tự học với Learn Python the hard way nhưng chưa thấy ai thành công cả. Hai link dưới nên đọc sau khi đã nắm được những phần cơ bản của ngôn ngữ pytho...

The PyMiers

New FAMILUG