01 Introduction Ubus is the inter-process communication mechanism in OpenWRT, which simplifies the implementation of inter-process communication. The foundation of ubus is the UNIX Socket, which is a local socket that is more efficient and reliable compared to traditional network communication sockets.
1.1 Model Architecture
UNIX Socket adopts a C/S model architecture, divided into server and client:1. The server establishes a socket and binds it to a local socket file, responsible for listening to client connections2. The client establishes one or more socket connections to the server3. The client and server send messages to each other4. The client and server process the received messages accordinglyUbus also follows the above process, Ubusd implements the server, while other processes (such as procd, netifd, ubus) implement the client. Communication between clients needs to be forwarded through the server.02 Interaction Methods
2.1 Ubus CLI
The command line Ubus tool interacts with Ubusd (with all currently registered), returning responses in a more user-friendly JSON format when using parameter calls.View currently running services (as shown in Figure 1-1 Current Running Services)
$ ubus |
Figure 1-1 Current Running ServicesFind specific service parameters and methods (as shown in Figure 1-2 Find Specific Service)
$ ubus -v list system |
Figure 1-2 Find Specific ServiceView specific parameters of a specific service (as shown in Figure 1-3 View Specific Parameters)
$ ubus call network.interface.lan status |
Figure 1-3 View Specific Parameters of ServiceService parameter transmission (as shown in Figure 1-4 Service Parameter Transmission)
$ ubus call network.interface.lan status ‘{“name”:”eth0″}’ |
Figure 1-4 Service Parameter Transmission
2.2 HTTP Access
OpenWRT’s uhttpd has a built-in uhttpd-mod-ubus plugin that runs HTTP protocol calls to ubus functionality. When accessing /ubus, it first checks whether the visitor has permission. The implementation of ACL in OpenWRT mainly relies on rpcd, and the acl files need to be configured in /usr/share/rpcd/acl.The following is an example of ACL definition, which only allows access to certain specific ubus modules, rather than unrestricted access to everything luci-mod-system.json
{ “luci-mod-system-config”: { “description”: “Grant access to system configuration”, “read”: { “ubus”: { “luci”: [ “getInitList”, “getLEDs”, “getTimezones”, “getUSBDevices” ], “system”: [ “info” ] }, “uci”: [ “luci”, “system” ] }, “write”: { “ubus”: { “luci”: [ “setInitAction”, “setLocaltime”, “setPassword” ] }, “uci”: [ “luci”, “system” ] } }, “luci-mod-system-ssh”: { “description”: “Grant access to SSH configuration”, “read”: { “file”: { “/etc/dropbear/authorized_keys”: [ “read” ] }, “ubus”: { “file”: [ “read” ] }, “uci”: [ “dropbear” ] }, “write”: { “file”: { “/etc/dropbear/authorized_keys”: [ “write” ] }, “ubus”: { “file”: [ “write” ], “luci”: [ “setInitAction”, “setLocaltime” ] }, “uci”: [ “dropbear” ] } }, …………. “luci-mod-system-reboot”: { “description”: “Allow rebooting the device”, “write”: { “file”: { “/sbin/reboot”: [ “exec” ] }, “ubus”: { “file”: [ “exec” ], “system”: [ “reboot” ] } } } } |
Note:rpcd also requires pre-validation for handling interface requests, and the login file is configured as /etc/config/rpcd
config rpcd option socket /var/run/ubus/ubus.sock option timeout 30 config login option username ‘root’ option password ‘$p$root’ list read ‘*’ list write ‘ |
Login request (to obtain rpc_session)
$ curl -d ‘{“jsonrpc”: “2.0”, “id”: 1, “method”: “call”, “params”: [ “00000000000000000000000000000000”, “session”, “login”, {“username”: “root”, “password”: “secret” }]}’ http://your.server.ip/ubus { “jsonrpc”:”2.0″, “id”:1,”result”: [0, { “ubus_rpc_session”:”c1ed6c7b025d0caca723a816fa61b668″, “timeout”:300, “expires”:299, “acls”: { “access-group”: { “superuser”:[“read”,”write”], “unauthenticated”:[“read”] }, “ubus”: { “*”:[“*”], “session”:[“access”,”login”]}, “uci”:{“*”:[“read”,”write”]} }, “data”:{“username”:”root”}} |
03 Session Management Obtaining ubus_rpc_session allows you to call functions (as shown in Figure 2-1 Obtaining rpc session)Figure 2-1 Obtaining rpc sessionRequest header packet format
{ “jsonrpc”: “2.0”, “id”: <unique-id-to-identify-request>, “method”: “call”, “params”: [ <ubus_rpc_session>, <ubus_object>,//system <ubus_method>, //board { <ubus_arguments> } ]} |
Response error codes for data packets
enum ubus_msg_status { UBUS_STATUS_OK,/* 0 */ UBUS_STATUS_INVALID_COMMAND,/* 1 */ UBUS_STATUS_INVALID_ARGUMENT,/* 2 */ UBUS_STATUS_METHOD_NOT_FOUND,/* 3 */ UBUS_STATUS_NOT_FOUND,/* 4 */ UBUS_STATUS_NO_DATA,/* 5 */ UBUS_STATUS_PERMISSION_DENIED,/* 6 */ UBUS_STATUS_TIMEOUT,/* 7 */ UBUS_STATUS_NOT_SUPPORTED,/* 8 */ UBUS_STATUS_UNKNOWN_ERROR,/* 9 */ UBUS_STATUS_CONNECTION_FAILED,/* 10 */ __UBUS_STATUS_LAST};{“jsonrpc”:”2.0″,”id”:1,”result”:[6]}`That is a valid jsonrpc response, 6 is the ubus code for UBUS_STATUS_PERMISSION_DENIED |
04 Exploiting Potential Vulnerabilities Request MethodsFile
-
1. read
-
2. list
-
3. write
UCI
-
1. set
-
2. get
-
3. show
-
4.1 File Directory Disclosure
4.2 Arbitrary File Read
Permission settings cause arbitrary file read failures.05 References https://openwrt.org/zh/docs/techref/ubus