Bài Giảng Theo Sách PreOSCP – Và Khóa Học Online Hacking Với Kali Linux 2025

Bash Scripting

1. Giới thiệu về Bash Scripting

Bash (GNU Bourne-Again Shell) là một công cụ tạo kịch bản và môi trường làm việc mạnh mẽ, đặc biệt hữu ích cho các chuyên gia bảo mật để tự động hóa và hợp lý hóa các tác vụ Linux. “Một chuyên gia bảo mật thành thạo tận dụng khéo léo kịch bản Bash để hợp lý hóa và tự động hóa nhiều tác vụ và thủ tục Linux.” Một Bash script là một tệp văn bản thuần túy chứa một chuỗi các lệnh được thực thi.

  • Cấu trúc cơ bản: Các tập lệnh thường có phần mở rộng .sh (tùy chọn), bắt đầu bằng #!/bin/bash (shebang), và phải có quyền thực thi.
  • Shebang (#! /bin/bash): Chỉ định trình thông dịch Bash để chạy tập lệnh.
  • Nhận xét (#): Dùng để thêm ghi chú, bỏ qua bởi trình thông dịch.
  • Lệnh echo: Dùng để in chuỗi ra thiết bị đầu cuối.
  1. Thực thi script:Cấp quyền thực thi: chmod +x ten_script.sh
  2. Chạy script: ./ten_script.sh (ký hiệu ./ chỉ ra script nằm trong thư mục hiện tại).

2. Biến (Variables)

Biến là nơi lưu trữ dữ liệu tạm thời.

  • Khai báo và gán giá trị: ten_bien=gia_tri (không có khoảng trắng xung quanh dấu =).
  • Ví dụ: first_name=Good
  • Tham chiếu biến: Sử dụng ký tự $ trước tên biến (ví dụ: echo $first_name). Bash sẽ “mở rộng” biến thành giá trị của nó trước khi thực thi lệnh.
  • Phân biệt chữ hoa/thường: Bash phân biệt chữ hoa/thường đối với tên biến.
  • Gán giá trị phức tạp:Dấu nháy đơn (‘): Diễn giải mọi ký tự theo nghĩa đen, không mở rộng biến. Ví dụ: greeting=’Hello World’
  • Dấu nháy kép (“): Diễn giải mọi ký tự theo nghĩa đen trừ $ (mở rộng biến), ` và \. Ví dụ: greeting2=”New $greeting” sẽ mở rộng $greeting.
  • Thay thế lệnh (Command Substitution): Gán đầu ra của một lệnh hoặc chương trình vào một biến.
  • Cú pháp hiện đại: bien=$(lenh) (khuyến khích sử dụng). Ví dụ: user=$(whoami)
  • Cú pháp thay thế (backtick): bien=lenh(cũ hơn, không khuyến khích). Ví dụ: `user2=`whoami
  • Lưu ý: Thay thế lệnh xảy ra trong một subshell (shell con), các thay đổi biến trong subshell không ảnh hưởng đến biến trong quá trình chính. Cờ -x trong shebang (#!/bin/bash -x) có thể dùng để gỡ lỗi và quan sát các lệnh được thực thi trong subshell.

3. Đối số (Arguments)

Các script Bash có thể chấp nhận đối số dòng lệnh.

  • Biến đặc biệt cho đối số:$0: Tên của script Bash.
  • $1 – $9: Các đối số từ thứ nhất đến thứ chín.
  • $#: Số lượng đối số được truyền vào script.
  • $@: Tất cả các đối số được truyền vào script.
  • Ví dụ:#!/bin/bash
  • echo “The first two arguments are $1 and $2”
  • Khi chạy ./arg.sh hello there, đầu ra sẽ là The first two arguments are hello and there.

4. Đọc đầu vào người dùng (Reading User Input)

Sử dụng lệnh read để tương tác thu thập đầu vào từ người dùng khi script đang chạy.

  • Cú pháp cơ bản: read bienVí dụ:
  • read answer
  • echo “Your answer was $answer”
  • Tùy chọn hữu ích:-p ‘Lời nhắc: ‘: Chỉ định lời nhắc hiển thị cho người dùng.
  • -s: Đọc đầu vào một cách im lặng (lý tưởng cho mật khẩu).
  • Ví dụ: read -p ‘Username: ‘ username và read -sp ‘Password: ‘ password

5. Câu lệnh điều kiện (If, Else, Elif)

Cho phép thực hiện các hành động khác nhau dựa trên các điều kiện khác nhau.

  • Cú pháp if:if [ <một số kiểm tra> ]
  • then
  • <thực hiện một hành động>
  • fi
  • Dấu ngoặc vuông [ và ] là tham chiếu đến lệnh test. Khoảng trắng xung quanh dấu ngoặc vuông và các toán tử là bắt buộc.
  • Toán tử test phổ biến:!EXPRESSION: Biểu thức là sai.
  • -n STRING: Chiều dài STRING lớn hơn 0.
  • -z STRING: Chiều dài STRING bằng 0 (rỗng).
  • STRING1 != STRING2: STRING1 không bằng STRING2.
  • STRING1 = STRING2: STRING1 bằng STRING2.
  • INTEGER1 -eq INTEGER2: INTEGER1 bằng INTEGER2.
  • INTEGER1 -ne INTEGER2: INTEGER1 không bằng INTEGER2.
  • INTEGER1 -gt INTEGER2: INTEGER1 lớn hơn INTEGER2.
  • INTEGER1 -lt INTEGER2: INTEGER1 nhỏ hơn INTEGER2.
  • INTEGER1 -ge INTEGER2: INTEGER1 lớn hơn hoặc bằng INTEGER2.
  • INTEGER1 -le INTEGER2: INTEGER1 nhỏ hơn hoặc bằng INTEGER2.
  • -d FILE: FILE tồn tại và là thư mục.
  • -e FILE: FILE tồn tại.
  • -r FILE: FILE tồn tại và có quyền đọc.
  • -s FILE: FILE tồn tại và không trống.
  • -w FILE: FILE tồn tại và có quyền ghi.
  • -x FILE: FILE tồn tại và có quyền thực thi.
  • Cú pháp else:if [ <một số kiểm tra> ]
  • then
  • <thực hiện hành động A>
  • else
  • <thực hiện hành động B>
  • fi
  • Cú pháp elif: (viết tắt của “else if”, thêm các nhánh điều kiện bổ sung)
  • if [ <một số kiểm tra 1> ]
  • then
  • <thực hiện hành động A>
  • elif [ <một số kiểm tra 2> ]
  • then
  • <thực hiện hành động B>
  • else
  • <thực hiện hành động C>
  • fi

6. Thao tác Logic Boolean (Boolean Logical Operations)

Toán tử AND (&&) và OR (||) được sử dụng trong danh sách lệnh hoặc trong biểu thức điều kiện.

  • Trong danh sách lệnh:&& (AND): Chỉ thực thi lệnh thứ hai nếu lệnh thứ nhất thành công (trả về 0/True).
  • Ví dụ: grep $user2 /etc/passwd && echo “$user2 found!”
  • || (OR): Chỉ thực thi lệnh thứ hai nếu lệnh thứ nhất thất bại (trả về khác 0/False).
  • Ví dụ: grep $user2 /etc/passwd || echo “$user2 not found !”
  • Trong biểu thức điều kiện (ví dụ if):&& (AND): Kết hợp hai điều kiện; toàn bộ điều kiện là đúng nếu cả hai đều đúng.
  • Ví dụ: if [ $USER == ‘kali’ ] && [ $HOSTNAME == ‘kali’ ]
  • || (OR): Kết hợp hai điều kiện; toàn bộ điều kiện là đúng nếu ít nhất một trong số chúng đúng.
  • Ví dụ: if [ $USER == ‘kali’ ] || [ $HOSTNAME == ‘pwn’ ]

7. Vòng lặp (Loops)

Thực hiện các tác vụ lặp đi lặp lại cho đến khi đáp ứng một số tiêu chí nhất định.

  • Vòng lặp for: Thực hiện một tập hợp lệnh cho mỗi mục trong một danh sách.
  • Cú pháp chung:for var-name in <list>
  • do
  • <action to perform>
  • done
  • seq command: Tạo một chuỗi số. Ví dụ: for ip in $(seq 1 10); do echo 10.11.1.$ip; done
  • Brace expansion: Sử dụng các phạm vi số hoặc ký tự. Ví dụ: for i in {1..10}; do echo 10.11.1.$i;done
  • Vòng lặp while: Thực thi mã trong khi một biểu thức là đúng.
  • Cú pháp chung:while [ <một số kiểm tra> ]
  • do
  • <perform an action>
  • done
  • Tăng biến: Cấu trúc dấu ngoặc kép ((counter++)) thực hiện mở rộng số học.

8. Hàm (Functions)

Một hàm là một “script trong script”, hữu ích khi cần thực thi cùng một đoạn mã nhiều lần.

  1. Hai định dạng khai báo:function function_name {
  2. commands…
  3. }
  4. function_name () {
  5. commands…
  6. }
  • Cả hai đều có chức năng tương đương.
  • Gọi hàm: Đơn giản gọi function_name.
  • Chấp nhận đối số: Các đối số được truyền vào hàm có thể được truy cập bằng $1, $2, v.v., giống như script chính. Dấu ngoặc đơn trong định nghĩa hàm (ví dụ: pass_arg()) chỉ mang tính trang trí trong Bash.
  • Quan trọng: Định nghĩa hàm phải xuất hiện trong script trước khi nó được gọi.
  • Trả về giá trị:Các hàm Bash không “trả về” một giá trị tùy ý theo nghĩa truyền thống.
  • Có thể trả về trạng thái thoát (0 cho thành công, khác 0 cho thất bại) bằng lệnh return. Giá trị này có thể được truy cập từ biến toàn cục $?.
  • Có thể gán một biến toàn cục bên trong hàm hoặc sử dụng thay thế lệnh để mô phỏng trả về giá trị.

9. Phạm vi biến (Variable Scope)

Là ngữ cảnh mà một biến có ý nghĩa.

  • Biến toàn cục (Global Variable): Mặc định, có thể truy cập trong toàn bộ script.
  • Biến cục bộ (Local Variable): Chỉ có thể nhìn thấy trong hàm, khối mã hoặc subshell nơi nó được định nghĩa.
  • Sử dụng từ khóa local để khai báo biến cục bộ: local name=”Joe”
  • “Overlay” một biến toàn cục bằng cách tạo biến cục bộ có cùng tên; biến toàn cục không bị ảnh hưởng bên ngoài hàm.
  • Thay đổi biến toàn cục bên trong hàm mà không khai báo local sẽ ảnh hưởng đến giá trị toàn cục của nó.

10. Ví dụ thực tế

Các ví dụ minh họa cách kết hợp các khái niệm Bash để tự động hóa các tác vụ phức tạp:

  • Ví dụ 1: Trích xuất tên miền phụ và địa chỉ IP:Sử dụng wget để tải trang web.
  • Kết hợp grep, awk, cut để lọc và trích xuất dữ liệu từ tệp HTML.
  • Sử dụng biểu thức chính quy (grep -o ‘[^/]*\.megacorpone\.com’) để trích xuất tên miền phụ hiệu quả hơn.
  • Dùng vòng lặp for và lệnh host để tìm địa chỉ IP tương ứng.
  • Sử dụng cut và sort -u để tinh chỉnh đầu ra IP.
  • Ví dụ 2: Tự động tải xuống các bản khai thác từ Exploit-DB:Sử dụng searchsploit với các tùy chọn -w (trả về URL) và -t (tìm kiếm tiêu đề) để tìm kiếm khai thác.
  • Lọc kết quả bằng grep http và cut để lấy URL.
  • Sử dụng sed ‘s/exploits/raw/’ để chuyển đổi URL khai thác thành URL tải xuống tệp thô.
  • Sử dụng vòng lặp for và wget -q –no-check-certificate để tải xuống các tệp khai thác.
  • Ví dụ 3: Quét mạng con để tìm máy chủ web và chụp ảnh màn hình:Sử dụng mkdir và cd để tạo và vào thư mục tạm thời.
  • Sử dụng nmap -A -p80 –open 10.11.1.0/24 -oG nmap-scan_10.11.1.1-254 để quét mạng con tìm cổng 80 đang mở và lưu kết quả.
  • Lọc kết quả nmap bằng grep 80 | grep -v “Nmap” | awk ‘{print $2}’ để lấy danh sách các địa chỉ IP.
  • Sử dụng vòng lặp for và cutycapt –url=$ip –out=$ip.png để chụp ảnh màn hình các trang web.
  • Tạo script Bash để tạo một tệp HTML đơn giản (pngtohtml.sh) để xem tất cả các ảnh chụp màn hình một cách dễ dàng trong trình duyệt.

11. Kết luận

Bash scripting là một kỹ năng thiết yếu cho các chuyên gia bảo mật. Việc học cách sử dụng Bash một cách hiệu quả giúp tự động hóa nhanh chóng một lượng lớn các tác vụ, đặc biệt trong các quy trình đánh giá bảo mật. “GNU Bourne-Again Shell (Bash) là một công cụ tạo kịch bản và môi trường làm việc mạnh mẽ.”

Bình luận về bài viết này

Thịnh hành