diff options
| author | Kali Kaneko <kali@futeisha.org> | 2015-06-08 16:46:12 -0400 | 
|---|---|---|
| committer | Kali Kaneko <kali@futeisha.org> | 2015-06-08 16:46:12 -0400 | 
| commit | b91ea5f9974471c8f596a42eb5023c693a9da450 (patch) | |
| tree | 04d71c67be68d8d069fdf3b355e71b7a1f8e7813 /docs/NOTES-python-gnupg-3.1-audit.org | |
| parent | 3488c8fa0078576ab35e463c33fe8e3e47e34e61 (diff) | |
| parent | a5d46a4e38985be540b9127ddcd3d8e21bbecb9a (diff) | |
Merge tag 'upstream/2.0.2'
Upstream version 2.0.2
Diffstat (limited to 'docs/NOTES-python-gnupg-3.1-audit.org')
| -rw-r--r-- | docs/NOTES-python-gnupg-3.1-audit.org | 232 | 
1 files changed, 0 insertions, 232 deletions
| diff --git a/docs/NOTES-python-gnupg-3.1-audit.org b/docs/NOTES-python-gnupg-3.1-audit.org deleted file mode 100644 index b80fb39..0000000 --- a/docs/NOTES-python-gnupg-3.1-audit.org +++ /dev/null @@ -1,232 +0,0 @@ -#+TITLE:     python-gnupg audit -#+AUTHOR:    isis -#+EMAIL:     isis@leap.se -#+DATE:      2013-02-01 Fri -#+DESCRIPTION: -#+KEYWORDS: -#+LANGUAGE:  en -#+OPTIONS:   H:3 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t -#+OPTIONS:   TeX:t LaTeX:t skip:nil d:nil todo:t pri:nil tags:not-in-toc -#+INFOJS_OPT: view:nil toc:2 ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js -#+EXPORT_SELECT_TAGS: export -#+EXPORT_EXCLUDE_TAGS: noexport -#+LINK_UP:    -#+LINK_HOME:  -#+XSLT: - -[2013-02-01 Fri] - -* gnugp.__main__() -** comments -L58 NullHandler?? see self._write_passphrase -L61 there nifty check for p3k -** def _copy_data(instream, outstream)                              :cleanup: -   copies data from one stream to another, 1024 bytes at a time. -*** L79:                                                          :bad_logic: -    instream is apparently a file descriptor, but is not checked nor -    encased in a try/except block. - -*** L78:                                               :hanging_fd:bad_logic: -    while True: loop, should be  -    : with open(instream) as instrm: -*** L88:                                             :bad_exception_handling: -    : except:  -    should catch an IOError, or whatever specific error is raised for broken -    pipes. -** def _threaded_copy_data(instream, outstream): -*** L99: -    this just wraps self._copy_data in a thread -** def _write_passphrase(stream, passphrase, encoding):        :vuln:cleanup: -*** L110:                                         :writes_passphrase_to_disk: -    logger writes passphrase into debug log. this should be patched. -* class Verify(object) -  basic parsing class, no errors found -* class ImportResult(object) -  basic parsing class, no errors found -* class ListKeys(list): -  basic parsing class, no errors found -* class Crypt(Verify): -  basic parsing class, no errors found -** def __init__(self, gpg)                                          :cleanup: -*** L338                                                       :mro_conflict: - -    #+BEGIN_SRC python -    Verify.__init__(self,gpg) -    #+END_SRC - -    should be changed to: - -    #+BEGIN_SRC python -    super(Verify, self).__init__(gpg) -    #+END_SRC -* class GenKey(object) -  basic parsing class, no errors found -* class DeleteResult(object) -  basic parsing class, no errors found -* class Sign(object) -  basic parsing class, no errors found -* class GPG(object)                                             :exploitable: -*** L474:                                                           :cleanup: -    : cls.__doc__  -    should go directly underneath class signature -** def __init__(self, gpgbinary='gpg', gnupghome=None, verbose=False, use_agent=False, keyring=None) :bug: -*** L494-495:                                                    :type_error: -     -    #+BEGIN_SRC python -    if gnupghome and not os.path.isdir(self.gnupghome): -        os.makedirs(self.gnupghome,0x1C0) -    #+END_SRC - -    #+BEGIN_EXAMPLE -    In [20]: os.makedirs? -    Type:       function -    String Form:<function makedirs at 0x7f8ddeb6cc08> -    File:       /usr/lib/python2.7/os.py -    Definition: os.makedirs(name, mode=511) -    Docstring: -    makedirs(path [, mode=0777]) -    Super-mkdir; create a leaf directory and all intermediate ones. -    Works like mkdir, except that any intermediate path segment (not -    just the rightmost) will be created if it does not exist.  This is -    recursive. -     -    setting mode=0x1c0 is equivalent to mode=hex(0700), which -    may cause bugs on some systems, see -    http://ubuntuforums.org/showthread.php?t=2044879 -     -    this could be do to the complete lack of input validation in -    os.makedirs, and it's calling of the os.mkdir() built-in, which -    may vary depending on the python compilation: -    #+END_EXAMPLE - -    #+BEGIN_SRC python -    Source: -    def makedirs(name, mode=0777): -        """makedirs(path [, mode=0777]) -         -        Super-mkdir; create a leaf directory and all intermediate ones. -        Works like mkdir, except that any intermediate path segment (not -        just the rightmost) will be created if it does not exist.  This is -        recursive. -        """ -        head, tail = path.split(name) -        if not tail: -            head, tail = path.split(head) -        if head and tail and not path.exists(head): -            try: -                makedirs(head, mode) -            except OSError, e: -                # be happy if someone already created the path -                if e.errno != errno.EEXIST: -                    raise -            if tail == curdir:           # xxx/newdir/. exists if xxx/newdir exists -                return -        mkdir(name, mode) -    #+END_SRC - -** def _open_subprocess(self, args, passphrase=False)                  :vuln: -*** L515:                                            :unvalidated_user_input: -    : cmd.extend(args) -     -    cmd is a list of strings, eventually joined with cmd=' '.join(cmd), and -    the args are unvalidated in this function. Then this concatenation of args -    is fed directly into subprocess.Popen(cmd, shell=True, stdin=PIPE, -    stdout=PIPE, stderr=PIPE). THIS SHOULD BE PATCHED. - -** def _collect_output(self, process, result, writer=None, stdin=None) -   sends stdout to self._read_data() and stderr to self._read_response() - -** def _handle_io(self, args, file, result, passphrase=None, binary=False) :vuln:cleanup: -*** L601:                         :unvalidated_user_input:type_check_in_call: -    : p = self._open_subprocess(args, passphrase is not None) -     -    you shouldn't assign or type check in a function call - -** def sign(self, message, **kwargs)                                :cleanup: -*** L617-619:                                                    :hanging_fd: -   calls self._make_binary_stream(), which leaves the file descriptor for -   the encoded message to be encrypted hanging between scopes. - -** def sign_file(self, file, keyid=None, passphrase=None, clearsign=True, detach=False, binary=False) :cleanup: -*** L632-635:                                                     :bad_logic: -    #+BEGIN_SRC python -    if detach: -        args.append("--detach-sign") -    elif clearsign: -        args.append("--clearsign") -    #+END_SRC - -    the logic here allows that if a user erroneously specifies both options, -    rather than doing what the system gnupg would do (that is, do --clearsign, -    and ignore the --attach-sign), python-gnupg would ignore both. - -*** L626-641: -    input 'args' into self._open_subprocess() is defined as static strings. -     -** def verify(self, data):                                          :cleanup: -*** L668-670:                                                    :hanging_fd: -    same hanging file descriptor problem as in self.sign() - -** def verify_file(self, file, data_filename=None)             :vuln:cleanup: -*** L683:                                                        :hanging_fd: -    more potentially hanging file descriptors... -*** L684:                                                        :hanging_fd: -    oh look, another hanging file descriptor. imagine that. -*** L690:                                            :unvalidated_user_input: -    : args.append('"%s"' % data_filename) -    well, there's the exploit. see included POC script. - -** def import_keys(self, key_data)                                     :vuln: -*** L749:                                            :unvalidated_user_input: -    this function could potentially allow an attacker with a GPG exploit to -    use it, because it passes key generation parameter directly into the -    internal packet parsers of GPG. however, without a GPG exploit for one of -    the GPG packet parsers (for explanation of GPG packets look into pgpdump), -    this function alone is not exploitable.     - -** def recieve_keys(self, keyserver, *keyids)                          :vuln: -*** L770:                                            :unvalidated_user_input: -    : args.extend(keyids) - -** def export_keys(self, keyids, secret=False)                         :vuln: -*** L795-796:                                        :unvalidated_user_input: -    args problem again. exploitable though parameter ``keyids``. - -** def list_keys(self, secret=False) -*** L827: -    args is static string. - -** def gen_key(self, input)                                         :cleanup: -*** L864: -    args, passed to self._handle_io(), which in turn passes args directly to -    Popen(), is set to a static string. this function is halfway okay, though -    it really could be more careful with the ``input`` parameter. - -** def gen_key_input(self, **kwargs)                                   :vuln: -*** L981-983:                                        :unvalidated_user_input: -    this function could potentially allow an attacker with a GPG exploit to -    use it, because it passes key generation parameter directly into the -    internal packet parsers of GPG. however, without a GPG exploit for one of -    the GPG packet parsers (for explanation of GPG packets look into pgpdump), -    this function alone is not exploitable. - -** def encrypt_file(self, file, recipiencts, sign=None, ...)           :vuln: -*** L939:                                            :unvalidated_user_input: -    several of the inputs to this function are unvalidated, turned into -    strings, and passed to Popen(). exploitable. - -** def encrypt(self, data, recipients, **kwargs):                      :vuln: -*** L997:                                            :unvalidated_user_input: -    exploitable, passes kwargs to self.encrypt_file() - -** def decrypt(self, message **kwargs):                                :vuln: -*** L1003:                                           :unvalidated_user_input: -    kwargs are passed to self.decrypt_file(), unvalidated, making this -    function also exploitable - -** def decrypt_file(self, file, always_trust=False, passphrase=None, output=None) :vuln: -*** L1013:                                           :unvalidated_user_input: -    unvalidated user input: this function is also exploitable - -* POC -#+INCLUDE: "../python-gnupg-0.3.1/python-gnupg-exploit.py" python | 
