Boost C++ Libraries: Ticket #12837: Binary serialization: crash that may allow jump to attacker-controlled address https://svn.boost.org/trac10/ticket/12837 <p> Using afl-fuzz on some simple programs that use boost binary and xml serialization, I have found a number of crashes and assertion failures. </p> <p> To test the waters, I am beginning by filing a single bug which may allow a jump to an attacker-controlled address (i.e., the most exploitable-looking crash that has turned up so far). On my test system, it crashes on the instruction shown: </p> <pre class="wiki">=&gt; 0x000000000044849c &lt;+524&gt;: mov (%r12),%rax 0x00000000004484a0 &lt;+528&gt;: mov 0x20(%rbp),%r15d 0x00000000004484a4 &lt;+532&gt;: mov %r12,%rdi 0x00000000004484a7 &lt;+535&gt;: callq *0x10(%rax) </pre><p> Notice that the value loaded at instruction &lt;+524&gt; is used to determine the address to call at instruction &lt;+535&gt;. The value of %<a class="changeset" href="https://svn.boost.org/trac10/changeset/12" title="More things getting included from common. ">r12</a> interpreted as bytes is "\0\0hive\0\0", which makes me strongly suspect that it is data from the input file (part of the 'serialization::archive' signature, masked off). Generally, the whole text of the input file would be considered under the control of the adversary. </p> <p> I ran my tests on Debian Jessie amd64 with gcc version 4.9.2 (Debian 4.9.2-10). The following revisions of modularized boost were used (the tip of each master branch at the time of writing, as described by 'git describe --tags --always): </p> <pre class="wiki">config: boost-1.62.0-57-g1abc59c core: boost-1.61.0-59-gd753d9a move: boost-1.63.0 serialization: boost-1.61.0-57-g62bf8fc </pre><p> The commandline to compile the (non-fuzzing) version of the input test program is: </p> <pre class="wiki">g++-4.9 -std=c++11 -Os -I serialization/include -I core/include -I move/include -I config/include -o pvec_in pvec_in.cc serialization/src/extended_type_info.cpp serialization/src/extended_type_info_typeid.cpp serialization/src/archive_exception.cpp serialization/src/basic_archive.cpp serialization/src/basic_serializer_map.cpp serialization/src/void_cast.cpp serialization/src/singleton.cpp serialization/src/basic_iarchive.cpp serialization/src/binary_iarchive.cpp serialization/src/basic_iserializer.cpp serialization/src/basic_pointer_iserializer.cpp </pre><p> The breaking input file is (base-64 encoded): </p> <pre class="wiki">FgAAAAAAAABzZXJpYWxpemF0aW9uOjphcmNoaXZlDwAECAQIAQAAAAAAAAAAAwAAAAAAAAABAAAA AAEAAAD0/wEAAAAAAAAAAAEAAAACAAEAAAACAAAAAgAAAAAA </pre><p> The source for the test harness program (pvec_in.cc) is </p> <pre class="wiki">#include &lt;fstream&gt; #include &lt;vector&gt; #include &lt;boost/shared_ptr.hpp&gt; #include &lt;boost/archive/binary_iarchive.hpp&gt; #include &lt;boost/serialization/nvp.hpp&gt; #include &lt;boost/serialization/shared_ptr.hpp&gt; #include &lt;boost/serialization/vector.hpp&gt; struct boxed_int { boxed_int() : i(0) {} boxed_int(int i) : i(i) {} int i; template&lt;class Archive&gt; void serialize(Archive &amp;ar, unsigned version) { ar &amp; BOOST_SERIALIZATION_NVP(i); } }; typedef boost::shared_ptr&lt;boxed_int&gt; pi; void go(std::istream &amp;is) { std::vector&lt;pi&gt; vv; try { boost::archive::binary_iarchive ia(is); ia &amp; vv; } catch(std::exception &amp;e) {} } int main(int argc, char **argv) { if(argc &gt; 1) { std::ifstream is(argv[1]); go(is); } else { go(std::cin); } return 0; } </pre><p> The test harness program either takes the input file on stdin or the name of the input file as the first positional argument. </p> <p> I can share details about the fuzzing setup if you like. </p> <p> Thank you for taking the time to consider this issue. </p> <p> --Jeff </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/12837 Trac 1.4.3 Robert Ramey Thu, 04 May 2017 16:25:16 GMT status changed https://svn.boost.org/trac10/ticket/12837#comment:1 https://svn.boost.org/trac10/ticket/12837#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> <p> This is pretty interesting. I'm curious about the fuzz testing setup. But I'm not sure what to do about it without undertaking a huge effort - which I'm not prepared to do. But you're issue is legitimate and I'm going to accept and leave open this issue in case someone wants to take it on. </p> <p> Thanks for your efforts here. I'm sorry I can't be more helpful. </p> <p> Robert Ramey </p> Ticket