『 BangMaple's Blog 』

BangMaple's Blog. Nơi sẻ chia kiến thức!

Bảo mật Java Web Application trước lỗ hổng Cross-Site Request Forgery (CSRF)

Security: What is Cross-Site Request Forgery? - Davos Networks ...

Chào các bạn,

Trong bài viết này mình sẽ nói về một lỗ hỏng website tương đối nghiêm trọng và cách phòng chống nó trên ứng dụng Java Web.

Tấn công Cross-Site Request Forgery được thực thi bên trình duyệt web (client-side), nó có thể đánh cắp thông tin của người dùng, thực hiện hành vi không đúng đắn hoặc thực thi những đoạn code không hợp lệ đối với máy chủ back-end (Java Web).

Chỉ cần thông qua một số thủ thuật như là tấn công phi vật lý (social engineering) để có thể chèn một đoạn code nào đó vào máy của nạn nhân để đánh lừa nạn nhân tiếp tay thực thi giúp đoạn code không hợp lệ đó.

Mình sẽ ví dụ bạn thông qua chức năng thay đổi tài khoản và mật khẩu của người dùng bằng ứng dụng Java Web. 

Những đoạn code dưới được code chỉ để demo cho lỗ hỏng CSRF, các bạn có thể tham khảo để phòng tránh

Chúng ta sẽ cùng tạo một Database trong SQL Server và một ứng dụng Java Web quản lý người dùng có chức năng đăng nhập và thay đổi mật khẩu của tài khoản.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
CREATE DATABASE UserManagement
USE UserManagement
CREATE TABLE Users (
	Username varchar(100) NOT NULL PRIMARY KEY,
	Password varchar(100) NOT NULL,
	Role varchar(100) NOT NULL
)

INSERT INTO Users VALUES ('bang','1234','Administrator')
INSERT INTO Users VALUES ('admin','4567', 'Administrator')

Dữ liệu sẽ trông như sau:
Hình 2 - Dữ liệu ở bảng Users trong DB UserManagement sau khi thực hiện câu truy vấn
Vì code khá dài nên mình sẽ đính kèm source code ở dưới bài viết, từ giờ mình chỉ đưa ra những nội dung chính đối với Java Web Application.

Chúng ta đăng nhập ứng dụng Web với tài khoản của admin.
Hình 3 - Đăng nhập với tài khoản admin 
Ta sẽ vào tiếp chức năng thay đổi mật khẩu.
Hình 4 - Thực hiện chức năng thay đổi mật khẩu

Hình 5 - Thao tác thay đổi mật khẩu
Sau khi nhập mật khẩu bất kì, ta nhận được kết quả báo thành công!

Hình 6 - Thay đổi mật khẩu thành công
Dựa vào những kĩ năng tấn công phi vật lý (social engineering), ta có thể thấy được dữ liệu trong form được đẩy qua cho ChangePasswordController với nội dung txtUsername=admin&txtPasswordChange=...&btnAction=Change password now!

Kiểm chứng lại trong cơ sở dữ liệu.
Hình 7 - Dữ liệu trong cơ sở dữ liệu sau khi thay đổi mật khẩu của admin

Ta có thể dễ dàng kết luận địa chỉ đầy đủ sẽ là http://abcxyz.com/DemoCSRF/ChangePasswordController?txtUsername=admin&txtPasswordChange=1234&btnAction=Change password now!

Hãy cùng xem source code mẫu của ChangePasswordController hiện tại nhé!
 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package bangmaple.controllers;

import bangmaple.daos.UsersDAO;
import bangmaple.utils.AntiCSRFToken;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet(name = "ChangePasswordController", urlPatterns = {"/ChangePasswordController"})
public class ChangePasswordController extends HttpServlet {

    private static final String ERROR = "error.jsp";
    private static final String SUCCESS = "success.jsp";

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        String url = ERROR;
        try {
            HttpSession session = request.getSession();
            if (request.getParameter("btnAction") == null) {
                request.getRequestDispatcher("changePassword.jsp").forward(request, response);
            } else {
                UsersDAO dao = new UsersDAO();
                if (dao.changePassword(request.getParameter("txtUsername"), request.getParameter("txtPasswordChange"))) {
                    url = SUCCESS;
                }
            }
        } catch (ClassNotFoundException | SQLException e) {
            log("ERROR at ChangePasswordController: " + e.getMessage());
        } finally {
            if (url.equals(SUCCESS)) {
                request.getSession().invalidate();
                response.sendRedirect("success.jsp");
            } else {
                request.getRequestDispatcher(url).forward(request, response);
            }
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
}

Dựa vào một số kĩ năng tấn công phi vật lí (social engineering) hoặc SQL Injection, kẻ xấu có thể thu được (các) account cùng chung bảng trong cơ sở dữ liệu. Ví dụ kẻ xấu đó biết được có tồn tại một tài khoản tên là bang và ta sẽ thực hiện tấn công CSRF bằng cách thay đổi tham số txtUsername để thay đổi mật khẩu của người dùng khác mà không phải của mình.

http://abcxyz.com/DemoCSRF/ChangePasswordController?txtUsername=bang&txtPasswordChange=aaaa&btnAction=Change password now!

Hình 8 - Thay đổi tham số của địa chỉ
Truy cập vào địa chỉ, ta nhận được kết quả như sau:
Hình 9 - Thành công trong việc thay đổi mật khẩu của người dùng khác
Kiểm chứng lại dữ liệu trong cơ sở dữ liệu, ta nhận thấy mật khẩu của người dùng bang đã bị thay đổi.
Hình 10 - Mật khẩu của người dùng bang đã bị thay đổi
Vậy ta sẽ cần phải pháp, đó là tạo một Anti-CSRF Token đưa đến cho từng form nhập và code trong ChangePasswordController sẽ được sửa lại như sau là một ví dụ:

 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package bangmaple.controllers;

import bangmaple.daos.UsersDAO;
import bangmaple.utils.AntiCSRFToken;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 *
 * @author bangmaple
 */
@WebServlet(name = "ChangePasswordController", urlPatterns = {"/ChangePasswordController"})
public class ChangePasswordController extends HttpServlet {

    private static final String ERROR = "error.jsp";
    private static final String SUCCESS = "success.jsp";

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        String url = ERROR;
        try {
            HttpSession session = request.getSession();
              String antiCSRFToken;
            if (request.getParameter("btnAction") == null) {
                    antiCSRFToken = AntiCSRFToken.getToken();
                  session.setAttribute("csrfToken", antiCSRFToken);
                request.getRequestDispatcher("changePassword.jsp").forward(request, response);
            } else {
                 antiCSRFToken = String.valueOf(session.getAttribute("csrfToken"));
                if (antiCSRFToken.equals(request.getParameter("csrfToken"))) {
                UsersDAO dao = new UsersDAO();
                if (dao.changePassword(request.getParameter("txtUsername"), request.getParameter("txtPasswordChange"))) {
                    url = SUCCESS;
                }
                } else {
                  request.setAttribute("ERROR", "Invalid CSRF Token! Well done, hacker!");
                }
            }
        } catch (ClassNotFoundException | SQLException e) {
            log("ERROR at ChangePasswordController: " + e.getMessage());
        } finally {
            if (url.equals(SUCCESS)) {
                request.getSession().invalidate();
                response.sendRedirect("success.jsp");
            } else {
                request.getRequestDispatcher(url).forward(request, response);
            }
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
}


Vậy bạn sẽ thắc mắc là Anti-CSRF Token đào ở đâu ra? Token chúng ta có thể sinh ra bằng hàm tuyến tính ví dụ đơn giản là f[session](x) = x + 1, x>0 nhưng mà không ai làm đơn giản như vậy vì dễ bị đoán mò. Nên là mình sẽ sử dụng sự trợ giúp của java.security.SecureRandom và bộ thư viện chữ và số.

Ta tạo một class mới có tên là AntiCSRFToken có chứa hàm static để cho việc tái sử dụng hàm được dễ dàng hơn.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package bangmaple.utils;

import java.security.SecureRandom;

public class AntiCSRFToken {

    private static final String DICT = "abcdefghijklmnopqrstuvwxyz"
            + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    private static final int DICT_SIZE = DICT.length();

    public static String getToken() {
        final SecureRandom random = new SecureRandom();
        final StringBuilder sb = new StringBuilder();
        for (int i = 0; i < DICT_SIZE / 2; i++) {
            sb.append(DICT.charAt(random.nextInt(DICT_SIZE)));
        }
        return sb.toString();
    }
}

Ta cũng sửa cho bên view là changePassword.jsp để lúc từ ChangePasswordController trước khi thay đổi thì nó phải trả về thêm một hidden field csrfToken được generate từ nó, gán vào session và sau đó lúc người dùng submit form thay đổi mật khẩu thì dùng hidden field csrfToken đó chứng thực lại với csrfToken bên back-end server ở session (Java Web). 

Nếu người dùng có chứa đúng csrfToken thì mới thực thi hành động thay đổi mật khẩu.
Ở bên trang changePassword.jsp ta thêm một dòng hidden field chứa csrfToken như dòng 15 ở đoạn code dưới.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>Hello ${sessionScope.USER_NAME}!</h1><br/>
        <h2>Change your password!</h2><br/>
        Please input your new password!<br/>
        <form action="ChangePasswordController" method="POST">
            Current username: <input type="text" name="txtUsername" value="${sessionScope.USER_NAME}" readonly="true"/><br/>
            New password: <input type="password" name="txtPasswordChange"/><br/>
            <input type="hidden" name="csrfToken" value="${sessionScope.csrfToken}"/>
            <input type="submit" name="btnAction" value="Change password now!"/>
        </form>
    </body>
</html>

Đăng nhập với tài khoản tên bang và thực hiện chức năng thay đổi mật khẩu, khi Inspect và ta thấy được hidden field csrfToken được generate với một chuỗi số chữ ngẫu nhiên.
Vậy khi chúng ta submit form, nó sẽ được gửi đi dạng http://abcxyz.com/DemoCSRF/ChangePasswordController?txtUsername=bang?txtPasswordChange=...&csrfToken=wSE3fY7Mc2SuAXozqPlqFxNKRjc1drX

Trông khá là rườm rà nhỉ, đương nhiên là để tránh dài dòng và lộ thông tin của csrfToken, ta luôn thực hiện khi gửi request đi phải gửi dưới dạng POST và để mã hoá nội dung của request dạng POST, ta nên thêm lớp TLS (HTTPS) cho nó.
Hình 11 - Form đã được thêm csrfToken
Nếu là người dùng thông thường gửi lệnh thay đổi mật khẩu một cách chính đáng, ta sẽ nhận dược thông báo thay đổi mật khẩu thành công.

Hình 12 - Mật khẩu được thay đổi thành công cho tài khoản bang

Chúng ta sẽ cố gắng tấn công bằng cách thay đổi tài khoản admin không thông qua tài khoản chính chủ.
Hình 13 - Tiếp tục tấn công CSRF

Ta nhận được kết quả trả về thất bại vì Anti-CSRF Token không hợp lệ.
Hình 14 - Cố gắng thay đổi mật khẩu của tài khoản khác thất bại
Vậy ta đã thực hiện áp dụng chức năng vô hiệu hoá được tấn công CSRF.

Từ giờ trở đi, chúng ta nên generate Anti-CSRF Token mọi lúc trước khi thực hiện gửi dữ liệu trong form để tránh bị hack. Để tối ưu nhất, ta nên để thời gian timeout cho session càng ngắn càng tốt!

Để cho việc thử nghiệm dễ dàng, bạn nên sử dụng trình duyệt FireFox hoặc Google Chrome bản cũ để tránh bị lỗi Cross-Origin Read Blocking.

Lỗ hỏng bảo mật CSRF thường được dùng chung với XSS, cho nên bảo mật trước CSRF không phải là bảo mật được tất cả. Bạn nên xem xét bảo mật những thành phần còn lại, validate các nội dung trong headers, review code kĩ là được.

Cảm ơn các bạn đã dành thời gian ra đọc bài viết.
Chúc các bạn học tốt!


------

Quản trị Windows Server cho mọi người - Phần 2


Chào các bạn,

Trong bài viết này mình sẽ tiếp tục đi với series Quản trị Windows Server cho mọi người về phần 2.

Sau khi cài đặt và tinh chỉnh cơ bản hoàn tất với Windows Server 2012 trên máy ảo có tên là SRV1. Hãy cùng tiếp tục đi với những bước tiếp theo.

Chúng ta có tên dễ nhớ, máy tính cũng vậy cho nên để nhận diện được máy tính dễ dàng hơn thì chúng ta hãy đặt một cái tên cho nó nhé!

Trước khi định danh cho máy tính, chúng ta hãy cùng nghiên cứu tổng quát về Windows Server đã nhé!
Như bạn có thể thấy bên dưới là thời hạn sử dụng Windows Server 2012 R2, chúng ta sẽ có 180 ngày sử dụng nó trước khi hết hạn, nếu hết hạn thì bạn có thể dễ dàng kích hoạt lại được nên không cần phải lo lắng về vấn đề này nhé!
Hình 1 - Thông báo thời hạn sử dụng Windows Server
Bạn có thể thấy ở dưới là một số icon của Windows Server, nó cho phép chúng ta truy cập dễ dàng đến các dịch vụ của Windows, bạn sẽ cảm thấy quen thuộc nếu bạn đã từng sử dụng Windows 8-8.1. Chúng ta sẽ không sử dụng âm thanh trong Windows Server nên nếu tắt được âm thanh thì tốt nhất, icon hình Mạng sẽ là nơi chúng ta sử dụng nhiều nhất.
Hình 2 - Các icon của Windows Server
Hình bên dưới sẽ là một số icon của Windows Server, cho phép chúng ta truy cập nhanh chóng ví dụ như là bên trái cùng là icon Windows quen thuộc giúp chúng ta quay về cửa sổ Start.
Icon thứ 2 sẽ là Server Manager, giúp chúng ta quản lý các tài nguyên của Server hiện hành dễ dàng.
Icon thứ 3 sẽ là Windows PowerShell, giúp chúng ta gõ lệnh hoặc lập trình trên đó, cao cấp hơn Windows Command Line mà chúng ta hay sử dụng thường ngày.
Icon thứ 4 thì rất quen thuộc, giúp chúng ta truy cập vào This PC để quản lý tài nguyên của bộ nhớ của từng phân vùng thuộc (các) ổ cứng.

Hình 3 - Các icon taskbar chính của Windows Server
Khi nhấn vào biểu tượng Windows, chúng ta sẽ được dẫn đến Start quen thuộc mà chúng ta đã và đang sử dụng những bản Windows trước đó, cụ thể là Windows 8 - 8.1.
Hình 4 - Start sau khi nhấn icon Windows
Nếu bạn không thích kiểu dáng Start như vậy vì bạn đang sử dụng Windows 7 hoặc 10 thì không cần phải lo, ở màn hình Start đó, hãy gõ "Internet Explorer" thì bạn sẽ được gợi ý IE ngay kết quả đầu tiên, bạn có thể cài đặt các trình duyệt duyệt web khác hoặc là bạn sẽ phải cần tải StartIsBack trên Google Search để có được Start ưng ý nhé.
Hình 5 - Truy cập Internet Explorer
Dưới đây là cửa sổ sau khi bạn cài đặt phần mềm StartIsBack thành công.
Hình 6 - Cửa sổ hiển thị cài đặt StartIsBack thành công
Bạn sẽ có được một Start ưng ý và quen thuộc.
Hình 7 - Start giả lập bởi StartIsBack
Mở icon thứ 2 là Server Manager, bạn sẽ được đưa đến cửa sổ chính của Server Manager và đây là nơi chúng ta sẽ thực hành chủ yếu lên nó.
Hình 8 - Cửa sổ chính của Server Manager
Mở icon thứ 3 là Windows PowerShell, một cửa sổ giao diện dòng lệnh mà chúng ta có thể truy xuất các lệnh giống tương tự với Windows Command Line nhưng cao cấp hơn và màu xanh biển, bạn cũng có thể lập trình script tự động bằng Windows PowerShell.
Hình 9 - Cửa sổ chính của Windows PowerShell
Khi bạn nhấn icon Explorer thì bạn sẽ được đưa đến cửa sổ chính của This PC, tại đây bạn có thể quản lý tệp tin hoặc truy cập vào một số dịch vụ của Windows.
Hình 10 - Cửa sổ chính của This PC
Bạn có thể xem thông tin chi tiết của phân vùng hiện tại thì bạn nhấn chuột phải vào phân vùng đó rồi nhấn Properties để xem chi tiết và thực hiện các thao tác khác.
Hình 11 - Thông tin của phân vùng
Bạn có thể xem chi tiết cấu hình máy và những thứ khác bằng cách nhấn chuột phải vào dòng This PC bên trái và chọn Properties
Hình 12 - Kiểm tra thông tin của máy ảo hiện hành
Một cửa sổ System được hiển thị ra để cho bạn xem chi tiết máy ảo hiện hành.
Proccessor: Tên vi xử lý trên máy thật của bạn
Installed Memory (RAM): Bộ nhớ bạn cấp phát cho máy ảo hiện hành
System Type: Phiên bản hệ điều hành
Hình 13 - Thông tin chi tiết cấu hình máy ảo hiện hành
Bạn có thể chỉnh sửa các thông tin chi tiết của máy ảo bằng cách chọn dòng Advanced system settings.
Hình 14 - Chỉnh sửa chi tiết thông tin máy ảo hiện hành
Để đổi tên của máy ảo hiện hành, bạn chọn qua tab Computer Name và sau đó nhấn nút Change.
Hình 15 - Đổi tên máy ảo hiện hành
Hãy đổi tên thành SRV1 và nhấn OK.
Hình 16 - Đổi tên máy ảo hiện hành
Sau khi đổi tên máy ảo hiện hành thành công, bạn sẽ nhận được thông báo yêu cầu khởi động lại máy tính sau. Nhấn OK 2 lần và sau đó chọn Restart Now để khởi động lại.
Hình 17 - Đổi tên máy ảo hiện hành thành công
Để có thể đổi ngày và giờ, bạn chọn vào chỗ thời gian rồi sau đó chọn dòng Change date and time settings...
Hình 18 - Ngày và giờ hệ thống
Thay đổi đúng múi giờ Việt Nam bằng cách chọn nút Change time zone... sau đó chọn múi giờ UTC +07:00 rồi sau đó nhấn OK để hoàn tất.
Hình 19 - Thay đổi múi giờ hệ thống
Xác nhận giờ hiện hành và múi giờ của hệ thống đã chính xác.
Hình 20 - Xác nhận đổi múi giờ thành công
Máy tính nào cũng có một địa chỉ để truy cập giống như địa chỉ nhà, bây giờ chúng ta gần phải gán địa chỉ nhà phù hợp và dễ nhớ cho nó nhé!

Trong menu bar của VirtualBox, chọn File. Sau đó chọn Host Network Manager. Sau đó nhấn Create rồi nhấn Properties, trong phần Adapter, nhập như sau:
IPv4 Address: 172.16.0.1
IPv4 Network Mask: 255.255.0.0
Còn lại để mặc định.
Hình 21 - Tạo host network
Sau khi tạo xong network thì chúng ta vào Settings của máy ảo hiện hành, sau đó qua tab Network. Chọn tên của network giống như lúc mới tạo trong Host Network Manager.
Hình 22 - Gán card mạng mới vào máy ảo
Sau khi chọn, hãy xác nhận chính xác rồi nhấn OK. Sau đó quay lại màn hình máy ảo.
Chọn icon Server Manager, sau đó chọn Local Server rồi chọn dòng Ethernet IPv4 address assigned by DHCP, IPv6 enabled.
Hình 23 - Cấu hình địa chỉ IPv4
Sau đó nhấn chuột phải vào biểu tượng Ethernet rồi chọn Properties, sau đó một cửa sổ mới hiện rồi chọn dòng Internet Protocol Version 4 (TCP/IPv4) rồi chọn nút Properties.
Hình 24 - Cấu hình địa chỉ IPv4

Trong cửa sổ mới, ta chọn Use the following IP address, sau đó nhập:
IP address: 172.16.0.101
Subnet mask: 255.255.0.0
Default gateway: 172.16.0.1
Sau khi hoàn tất thì hãy nhấn nút OK là xong.
Hình 25 - Cấu hình địa chỉ IPv4
Xác nhận địa chỉ IPv4 bằng cách mở Windows Command Line, sau đó gõ ipconfig
Hình 26 - Xác nhận địa chỉ IPv4
Sau khi hoàn tất, chúng hãy tạo một Snapshot cho máy ảo hiện hành. Mục đích của Snapshot tồn tại trên phần mềm quản lý máy ảo để tránh trường hợp chúng ta gặp sự cố thì có thể quay lại vào thời điểm lúc chúng ta đã tạo backup. 

Đây là một thử thách cho các bạn.
Tạo một snapshot có Snapshot DescriptionSRV1 - Phan 2
Hình 27 - Tạo một snapshot
Hãy xác nhận snapshot vừa tạo trong VirtualBox.
Hình 28 - Xác nhận snapshot đã được tạo

Lưu trạng thái máy ảo hiện hành bằng cách tắt thông thường rồi chọn Save the machine state.
Hình 29 - Lưu trạng thái hiện hành của máy ảo

Phần 2 đến đây là kết thúc. Hẹn các bạn ở phần 3!
Chúc các bạn học tốt!

--------------------------------------------------
Tài liệu tham khảo thêm (nên đọc):

Quản trị Windows Server cho mọi người - Phần 1



Chào các bạn,

Mình có mong muốn làm một series về các bài viết quản trị Windows Server cho mọi người, mục đích của mình muốn hướng đến là làm sao để cho các bạn có cái nhìn tổng quan về các dịch vụ của Windows Server nói chung và cái nhìn riêng là làm được và hiểu được.

Không nói nhiều, mình sẽ bắt tay vào hướng dẫn các bạn làm và sẽ giải thích từng phần.

Trước khi bước vào nội dung chính thì mình cũng mong là các bạn đã từng có kinh nghiệm thao tác và sử dụng Windows thông thường.

Thời gian không có nhiều và thiết bị máy tính cũng vậy, nên chúng ta sẽ thực hành trên máy ảo.
Vậy máy ảo sẽ giúp các bạn tiết kiệm chi phí triển khai phần cứng hơn, bạn không cần phải băn khoăn nếu bạn chưa từng dùng máy ảo bao giờ vì mình sẽ đi từng bước cụ thể nhé!

Đầu tiên bạn sẽ phải cần cài một máy ảo. Có rất nhiều dạng máy ảo hiện nay: Oracle VirtualBox, VMWare Player, VMWare Workstation, Parallels Desktop, ... Các cách cấu hình tương tự nhau, bạn có thể dễ dàng tìm hiểu cách sử dụng máy ảo bạn chọn trên Google Search.

Từ giờ trở đi mình sẽ sử dụng máy ảo Oracle VirtualBox cho việc triển khai Windows Server.
Phiên bản Windows Server 2012 cũng được sử dụng cho series này.

Bạn có thể tải xuống (các) tài nguyên dưới đây:
- Windows Server 2012 R2 64-bit ISO (bản cài đặt):
Hình 1 - Tải xuống Windows Server 2012 R2
- Oracle VirtualBox
Sau khi tải các tài nguyên cần thiết về, hãy thiết lập môi trường để cài đặt Windows Server 2012 nhé! Dưới đây là hình ảnh sau khi cài đặt VirtualBox và khởi động lên hoàn tất.
Hình 2 - Giao diện của VirtualBox
Để bắt đầu tạo môi trường máy ảo, ta chọn New.
Sau đó sẽ có một cửa sổ mới được hiện ra, ta nhập:
Name: SRV1
Machine Folder: Để ở nơi nào bạn có nhiều dung lượng sẽ là nơi chứa máy ảo của bạn
Type: Microsoft Windows
Version: Windows 2012 (64-bit)
Memory Size: 1500MB
Hard disk: Create a existing virtual hard disk file
Hình 3 - Giao diện tạo máy ảo
Sau khi nhập hoàn tất, ta nhấn Create. Một cửa sổ mới bên trong nữa sẽ được hiển thị ra.
Đây là cửa sổ tạo ổ cứng mới giống như lúc bạn gắn thêm ổ cứng vào máy tính thật vậy đó.
File location: Hãy để mặc định chung với thư mục của máy ảo để tránh bị nhầm lẫn
File size: Khuyến cáo 50.00GB
Hard disk file type: Hãy để VDI để có sự tương thích giữa các phần mềm quản lý máy ảo tương thích nhất.
Storage on physical hard disk: Nên để Dynamically allocated để cấp phát vùng bộ nhớ động có nghĩa là bạn dùng bao nhiêu dung lượng trên máy ảo thì bên máy thật mới tốn chừng đó, còn Fixed size thì bạn sẽ tạo sẵn 50GB dung lượng trên ổ cứng của máy thật.
Hình 4 - Tạo ổ cứng cho máy ảo
Sau khi đã xong xuôi hết thì hãy nhấn Create lần nữa nhé.
Hình 5 - Cửa sổ chính của VirtualBox sau khi máy ảo được tạo
Lúc này, chúng ta chưa gắn đĩa ISO để cài nên là chúng ta không khởi động máy bây giờ, chuột phải vào tên máy và chọn Settings.
Hình 6 - Thiết lập máy ảo
Một cửa sổ mới được hiện ra và bạn hãy nhanh chóng chọn tab Storage (Bộ nhớ lưu trữ), bạn sẽ thấy bên trái cửa sổ là danh sách các ổ đĩa lưu trữ được quản lý bởi Controller SATA.
Hình 7 - Thiết lập bộ nhớ lưu trữ
Hãy nhìn bên phải và nhấn hình chiếc đĩa CD và chọn Choose a disk file... để tìm và chọn ra một tệp tin đĩa cài Windows Server 2012 dạng ISO mà bạn đã tải xuống trước đó.
Hình 8 - Chọn đĩa ISO cho ổ đĩa
Sau khi đã chọn, hãy xác nhận bạn đã nhập đúng hay chưa, nếu đúng thì hãy nhấn OK để hoàn tất.
Hình 9 - Xác nhận đã chèn đĩa ISO vào ổ đĩa
Sau khi xong, bạn sẽ thấy dòng SATA Port 1 có thêm chữ là đã thành công, bạn hãy nhấn Start để khởi động máy ảo lên.
Hình 10 - Cửa sổ chính của VirtualBox sau khi import ISO
Bạn sẽ thấy một cửa sổ mới được mở ra và đưa bạn đến trình cài đặt của Windows Server 2012, chọn ngôn ngữ bạn cần, mình khuyến cáo nên để mặc định là tiếng Anh và nhấn Next.
Hình 11 - Màn hình cài đặt chính của Windows Server 2012
Hãy nhấn Install Now để bắt đầu đi vào chi tiết các bước cài đặt Windows Server.
Hình 12 - Cài đặt Windows Server
Hãy chọn phiên bản Datacenter (Server with a GUI) để làm quen với giao diện của nó và cách cấu hình và nhấn Next, sau đó tích vào điều khoản và điều lệ của Microsoft và tiếp tục.
Hình 13 - Chọn phiên bản cài đặt Windows Server
Hãy chọn cách cài đặt là Custom: Install Windows only (advanced).
Hình 14 - Chọn phương thức cài đặt.
Hãy nhấn vào Drive 0 Unallocated Space rồi nhấn New để tạo phân vùng mới với dung lượng cho trước rồi nhấn Apply.
Hình 15 - Tạo phân vừng ổ cứng
Sau khi tạo phân vùng mới, bạn sẽ thấy có 2 phân vùng được tạo ra, phân vùng System Reserved là để dành riêng cho hệ thống, phân vùng này không nên được chỉnh sửa/xoá nếu bạn không biết rõ về nó, nó chứa các thành phần khởi động hệ điều hành và khôi phục.

Chúng ta sẽ chọn Drive 0 Partition 2 để cài đặt Windows Server lên nó và nhấn Next.
Hình 16 - Phân vùng ổ cứng sau khi tạo mới
Windows Server 2012 đang được cài đặt trên máy ảo của bạn, hãy đợi đến khi nó cài đặt xong rồi khởi động lại.
Hình 17 - Cài đặt Windows Server
Sau khi cài đặt hoàn tất và khởi động lại, bạn sẽ được yêu cầu là nhập mật khẩu và bạn chỉ được cho phép nhập mật khẩu tương đối mạnh như là mình dùng mật khẩu BangMaple1 để làm mật khẩu cho tài khoản Administrator sau đó nhấn Finish để hoàn tất.
Hình 18 - Sau khi cài đặt hoàn tất và khởi động lại
Sau khi nhấn Finish, bạn sẽ được đưa về màn hình khoá cũng như mỗi lúc khởi động lại, bạn cần nhấn tổ hợp phím Ctrl + Alt + Delete để có thể đăng nhập vào màn hình Desktop.
Hình 19 - Màn hình khoá của Windows Server 2012
Sau khi mở màn hình khoá, bạn sẽ nhận được yêu cầu đăng nhập vào màn hình Desktop, bạn sẽ phải sử dụng lại mật khẩu lúc bạn tạo trước đó rồi nhấn Enter để hoàn tất việc xác thực.
Hình 20 - Đăng nhập vào Windows Server
Sau khi đăng nhập thành công, bạn sẽ được chuyển sang giao diện Windows chính như những Windows thông thường của bạn.
Hình 21 - Cửa sổ giao diện chính của Windows Server
Vậy là bạn đã hoàn tất phần 1 của Quản trị Windows Server cho mọi người rồi đó.

Mình sẽ có thử thách nho nhỏ là hãy cài đặt VirtualBox Guest Addition Tool CD lên Windows Server, sau khi cài đặt xong để biết bạn đã hoàn thành hay chưa thì icon mới sẽ được hiển thị trên thanh taskbar là hoàn tất!
Hình 22 - Sau khi cài đặt Guest Addition Image thành công
Chúc các bạn học tốt!
-------------------------------------------
Tài liệu tham khảo thêm nên đọc: