764 lines
61 KiB
HTML
764 lines
61 KiB
HTML
<!DOCTYPE HTML>
|
||
<html lang="en" class="coal" dir="ltr">
|
||
<head>
|
||
<!-- Book generated using mdBook -->
|
||
<meta charset="UTF-8">
|
||
<title>PWN Patch defense skill - Andrew's Blog</title>
|
||
|
||
|
||
<!-- Custom HTML head -->
|
||
|
||
<meta name="description" content="Andrew Ryan's Blog">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<meta name="theme-color" content="#ffffff">
|
||
|
||
<link rel="icon" href="../../favicon.svg">
|
||
<link rel="shortcut icon" href="../../favicon.png">
|
||
<link rel="stylesheet" href="../../css/variables.css">
|
||
<link rel="stylesheet" href="../../css/general.css">
|
||
<link rel="stylesheet" href="../../css/chrome.css">
|
||
|
||
<!-- Fonts -->
|
||
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
|
||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||
|
||
<!-- Highlight.js Stylesheets -->
|
||
<link rel="stylesheet" href="../../highlight.css">
|
||
<link rel="stylesheet" href="../../tomorrow-night.css">
|
||
<link rel="stylesheet" href="../../ayu-highlight.css">
|
||
|
||
<!-- Custom theme stylesheets -->
|
||
<link rel="stylesheet" href="../../src/style/custom.css">
|
||
|
||
<!-- MathJax -->
|
||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||
</head>
|
||
<body class="sidebar-visible no-js">
|
||
<div id="body-container">
|
||
<!-- Provide site root to javascript -->
|
||
<script>
|
||
var path_to_root = "../../";
|
||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "coal" : "coal";
|
||
</script>
|
||
|
||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||
<script>
|
||
try {
|
||
var theme = localStorage.getItem('mdbook-theme');
|
||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||
|
||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||
}
|
||
|
||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||
}
|
||
} catch (e) { }
|
||
</script>
|
||
|
||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||
<script>
|
||
var theme;
|
||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||
var html = document.querySelector('html');
|
||
html.classList.remove('coal')
|
||
html.classList.add(theme);
|
||
var body = document.querySelector('body');
|
||
body.classList.remove('no-js')
|
||
body.classList.add('js');
|
||
</script>
|
||
|
||
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||
|
||
<!-- Hide / unhide sidebar before it is displayed -->
|
||
<script>
|
||
var body = document.querySelector('body');
|
||
var sidebar = null;
|
||
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||
if (document.body.clientWidth >= 1080) {
|
||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||
sidebar = sidebar || 'visible';
|
||
} else {
|
||
sidebar = 'hidden';
|
||
}
|
||
sidebar_toggle.checked = sidebar === 'visible';
|
||
body.classList.remove('sidebar-visible');
|
||
body.classList.add("sidebar-" + sidebar);
|
||
</script>
|
||
|
||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||
<div class="sidebar-scrollbox">
|
||
<ol class="chapter"><li class="chapter-item affix "><a href="../../index.html">Andrew's Blog</a></li><li class="chapter-item "><a href="../../posts/linux/linux.html"><strong aria-hidden="true">1.</strong> linux</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/linux/install_linux.html"><strong aria-hidden="true">1.1.</strong> install linux</a></li><li class="chapter-item "><a href="../../posts/linux/bash_profile.html"><strong aria-hidden="true">1.2.</strong> bash profile</a></li><li class="chapter-item "><a href="../../posts/linux/command_list.html"><strong aria-hidden="true">1.3.</strong> command list</a></li><li class="chapter-item "><a href="../../posts/linux/git_guide.html"><strong aria-hidden="true">1.4.</strong> git guide</a></li><li class="chapter-item "><a href="../../posts/linux/tar.html"><strong aria-hidden="true">1.5.</strong> tar</a></li><li class="chapter-item "><a href="../../posts/linux/run_x86_elf_in_x64_setup.html"><strong aria-hidden="true">1.6.</strong> run x86 elf in x64 setup</a></li></ol></li><li class="chapter-item "><a href="../../posts/mac/mac.html"><strong aria-hidden="true">2.</strong> mac</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/mac/macos_profiles.html"><strong aria-hidden="true">2.1.</strong> macos profiles</a></li></ol></li><li class="chapter-item "><a href="../../posts/swift/swift.html"><strong aria-hidden="true">3.</strong> swift</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/swift/learn_swift.html"><strong aria-hidden="true">3.1.</strong> learn swift basics</a></li><li class="chapter-item "><a href="../../posts/swift/swift_extensions.html"><strong aria-hidden="true">3.2.</strong> Swift extensions</a></li><li class="chapter-item "><a href="../../posts/swift/swiftui_extension.html"><strong aria-hidden="true">3.3.</strong> SwiftUI extensions</a></li><li class="chapter-item "><a href="../../posts/swift/install_swift.html"><strong aria-hidden="true">3.4.</strong> install swift</a></li><li class="chapter-item "><a href="../../posts/swift/task_planner.html"><strong aria-hidden="true">3.5.</strong> implment task panner app with SwiftUI</a></li><li class="chapter-item "><a href="../../posts/swift/swift_cheat_sheet.html"><strong aria-hidden="true">3.6.</strong> Swift Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/swift/yinci_url.html"><strong aria-hidden="true">3.7.</strong> Personal privacy protocol</a></li><li class="chapter-item "><a href="../../posts/swift/swift_regular_exressions.html"><strong aria-hidden="true">3.8.</strong> Swift regular exressions</a></li><li class="chapter-item "><a href="../../posts/ios/how_to_create_beautiful_ios_charts_in_swift.html"><strong aria-hidden="true">3.9.</strong> How to Create Beautiful iOS Charts in鑱絊wift</a></li><li class="chapter-item "><a href="../../posts/swift/swiftui_source_code.html"><strong aria-hidden="true">3.10.</strong> SwiftUI source code</a></li><li class="chapter-item "><a href="../../posts/swift/use_swift_fetch_iciba_api.html"><strong aria-hidden="true">3.11.</strong> use swift fetch iciba API</a></li></ol></li><li class="chapter-item "><a href="../../posts/ios/ios.html"><strong aria-hidden="true">4.</strong> ios</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ios/cocaposd_setup_and_install_for_ios_project.html"><strong aria-hidden="true">4.1.</strong> cocaposd setup and install for ios project</a></li><li class="chapter-item "><a href="../../posts/ios/swiftui_show_gif_image.html"><strong aria-hidden="true">4.2.</strong> SwiftUI show gif image</a></li><li class="chapter-item "><a href="../../posts/ios/implement_task_planner_app.html"><strong aria-hidden="true">4.3.</strong> implement Task planner App</a></li></ol></li><li class="chapter-item "><a href="../../posts/objective_c/objective_c.html"><strong aria-hidden="true">5.</strong> objective_c</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/objective_c/objective_c_cheat_sheet.html"><strong aria-hidden="true">5.1.</strong> Objective-C Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/objective_c/objective_c_for_absolute_beginners_read_note.html"><strong aria-hidden="true">5.2.</strong> Objective-C Note</a></li></ol></li><li class="chapter-item "><a href="../../posts/dart/dart.html"><strong aria-hidden="true">6.</strong> dart</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/dart/flutter.html"><strong aria-hidden="true">6.1.</strong> Flutter Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/dart/dart_cheat_sheet.html"><strong aria-hidden="true">6.2.</strong> Dart Cheat Sheet</a></li><li class="chapter-item "><a href="../../posts/flutter/flutter_dev_test.html"><strong aria-hidden="true">6.3.</strong> Flutter dev test</a></li></ol></li><li class="chapter-item "><a href="../../posts/rust/rust.html"><strong aria-hidden="true">7.</strong> rust</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/rust/offline_use_rust.html"><strong aria-hidden="true">7.1.</strong> Offline use rust</a></li><li class="chapter-item "><a href="../../posts/rust/rust_grammer.html"><strong aria-hidden="true">7.2.</strong> rust grammar</a></li><li class="chapter-item "><a href="../../posts/rust/pase_string_and_decimal_conversion.html"><strong aria-hidden="true">7.3.</strong> pase string and decimal conversion</a></li><li class="chapter-item "><a href="../../posts/rust/parse_types.html"><strong aria-hidden="true">7.4.</strong> rust types</a></li><li class="chapter-item "><a href="../../posts/rust/rust_life_cycle.html"><strong aria-hidden="true">7.5.</strong> Rust life cycle</a></li><li class="chapter-item "><a href="../../posts/rust/rust_generic.html"><strong aria-hidden="true">7.6.</strong> rust generics</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implment_matrix.html"><strong aria-hidden="true">7.7.</strong> Rust implement matrix</a></li><li class="chapter-item "><a href="../../posts/rust/rust_sort.html"><strong aria-hidden="true">7.8.</strong> Rust implement sort algorithms</a></li><li class="chapter-item "><a href="../../posts/rust/implement_aes_encryption.html"><strong aria-hidden="true">7.9.</strong> Rust implement AEC encryption and decryption</a></li><li class="chapter-item "><a href="../../posts/rust/implement_trie_data_structure.html"><strong aria-hidden="true">7.10.</strong> implement trie data structure</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implement_tree.html"><strong aria-hidden="true">7.11.</strong> implement tree data_structure</a></li><li class="chapter-item "><a href="../../posts/rust/list_dir.html"><strong aria-hidden="true">7.12.</strong> list dir</a></li><li class="chapter-item "><a href="../../posts/rust/fast_way_to_implment_object_trait.html"><strong aria-hidden="true">7.13.</strong> fast way to implment object trait</a></li><li class="chapter-item "><a href="../../posts/rust/compress_rust_binary_size.html"><strong aria-hidden="true">7.14.</strong> compress rust binary size</a></li><li class="chapter-item "><a href="../../posts/rust/implment_file_upload_backend.html"><strong aria-hidden="true">7.15.</strong> impliment file upload</a></li><li class="chapter-item "><a href="../../posts/rust/this_is_add_post_cli_implementation_in_rust.html"><strong aria-hidden="true">7.16.</strong> this is add_post cli implementation in rust</a></li><li class="chapter-item "><a href="../../posts/rust/use_rust_implment_a_copyclipbord_cli.html"><strong aria-hidden="true">7.17.</strong> Use rust implment a copyclipbord CLI</a></li><li class="chapter-item "><a href="../../posts/rust/sqlite_database_add_delete_update_show_in_rust.html"><strong aria-hidden="true">7.18.</strong> sqlite database add delete update show in rust</a></li><li class="chapter-item "><a href="../../posts/rust/implementing_tokio_joinhandle_for_wasm.html"><strong aria-hidden="true">7.19.</strong> Implementing tokio JoinHandle for wasm</a></li><li class="chapter-item "><a href="../../posts/rust/rust_implement_a_crate_for_encode_and_decode_brainfuck_and_ook.html"><strong aria-hidden="true">7.20.</strong> rust implement a crate for encode and decode brainfuck and ook</a></li><li class="chapter-item "><a href="../../posts/rust/slint_builtin_elements.html"><strong aria-hidden="true">7.21.</strong> Slint Builtin Elements</a></li><li class="chapter-item "><a href="../../posts/rust/corporate_network_install_rust_on_windows.html"><strong aria-hidden="true">7.22.</strong> Corporate network install Rust on windows</a></li><li class="chapter-item "><a href="../../posts/rust/rust_binary_file_how_to_judge_static_link_or_dynamic_link_in_macos.html"><strong aria-hidden="true">7.23.</strong> rust binary file how to judge static link or dynamic link in Macos</a></li><li class="chapter-item "><a href="../../posts/rust/rust_binary_include_dir_and_get_contents.html"><strong aria-hidden="true">7.24.</strong> rust binary include dir and get contents</a></li><li class="chapter-item "><a href="../../posts/rust/rust_logger_non-block.html"><strong aria-hidden="true">7.25.</strong> rust logger non-block</a></li><li class="chapter-item "><a href="../../posts/rust/rust_connect_sql_server_database.html"><strong aria-hidden="true">7.26.</strong> rust connect sql server database</a></li><li class="chapter-item "><a href="../../posts/rust/rust_websocket_implment.html"><strong aria-hidden="true">7.27.</strong> rust websocket implment</a></li></ol></li><li class="chapter-item "><a href="../../posts/java/java.html"><strong aria-hidden="true">8.</strong> java</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/java/java_grammar.html"><strong aria-hidden="true">8.1.</strong> java grammar and codewar</a></li><li class="chapter-item "><a href="../../posts/java/run_jar.html"><strong aria-hidden="true">8.2.</strong> java run .jar</a></li><li class="chapter-item "><a href="../../posts/java/java_pomxml_add_defaultgoal_to_build.html"><strong aria-hidden="true">8.3.</strong> Java pomxml add defaultGoal to build</a></li><li class="chapter-item "><a href="../../posts/java/java_set_mvn_mirror.html"><strong aria-hidden="true">8.4.</strong> Java set mvn mirror</a></li></ol></li><li class="chapter-item "><a href="../../posts/python/python.html"><strong aria-hidden="true">9.</strong> python</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/python/convert_pesn.html"><strong aria-hidden="true">9.1.</strong> convert pesn</a></li><li class="chapter-item "><a href="../../posts/python/find_remove_dir.html"><strong aria-hidden="true">9.2.</strong> find and remove dir</a></li><li class="chapter-item "><a href="../../posts/python/timing_message.html"><strong aria-hidden="true">9.3.</strong> wechat send message</a></li><li class="chapter-item "><a href="../../posts/python/use_python_openpyxl_package_read_and_edit_excel_files.html"><strong aria-hidden="true">9.4.</strong> Use python openpyxl package read and edit excel files</a></li></ol></li><li class="chapter-item "><a href="../../posts/go/go.html"><strong aria-hidden="true">10.</strong> go</a></li><li class="chapter-item "><a href="../../posts/js/js.html"><strong aria-hidden="true">11.</strong> js</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/js/js_tutorial.html"><strong aria-hidden="true">11.1.</strong> js tutorial</a></li><li class="chapter-item "><a href="../../posts/js/js_tutorial_map.html"><strong aria-hidden="true">11.2.</strong> ja map</a></li><li class="chapter-item "><a href="../../posts/js/js_tutorial_math.html"><strong aria-hidden="true">11.3.</strong> js math</a></li><li class="chapter-item "><a href="../../posts/js/js_tutorial_object.html"><strong aria-hidden="true">11.4.</strong> js object</a></li><li class="chapter-item "><a href="../../posts/js/js_tutorial_set.html"><strong aria-hidden="true">11.5.</strong> js set</a></li><li class="chapter-item "><a href="../../posts/js/single_thread_and_asynchronous.html"><strong aria-hidden="true">11.6.</strong> single thread and asynchronous</a></li><li class="chapter-item "><a href="../../posts/js/this.html"><strong aria-hidden="true">11.7.</strong> js this</a></li><li class="chapter-item "><a href="../../posts/js/js_implment_aes.html"><strong aria-hidden="true">11.8.</strong> js implment aes</a></li><li class="chapter-item "><a href="../../posts/js/getting_started_with_ajax.html"><strong aria-hidden="true">11.9.</strong> getting started with ajax</a></li><li class="chapter-item "><a href="../../posts/js/BinarySearchTree.html"><strong aria-hidden="true">11.10.</strong> binary search tree</a></li><li class="chapter-item "><a href="../../posts/js/goole_zx.html"><strong aria-hidden="true">11.11.</strong> goole zx</a></li><li class="chapter-item "><a href="../../posts/js/es6.html"><strong aria-hidden="true">11.12.</strong> es6</a></li></ol></li><li class="chapter-item "><a href="../../posts/ruby/ruby.html"><strong aria-hidden="true">12.</strong> ruby</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ruby/rails_setup_env.html"><strong aria-hidden="true">12.1.</strong> ruby on rails setup environment</a></li><li class="chapter-item "><a href="../../posts/ruby/learn_ruby.html"><strong aria-hidden="true">12.2.</strong> learn ruby</a></li><li class="chapter-item "><a href="../../posts/ruby/ruby_note.html"><strong aria-hidden="true">12.3.</strong> Ruby Note</a></li><li class="chapter-item "><a href="../../posts/ruby/setup_ruby_for_ctf.html"><strong aria-hidden="true">12.4.</strong> Setup ruby for CTF</a></li></ol></li><li class="chapter-item "><a href="../../posts/react/react.html"><strong aria-hidden="true">13.</strong> react</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/react/react_life_cycle.html"><strong aria-hidden="true">13.1.</strong> react life cycle</a></li><li class="chapter-item "><a href="../../posts/react/react_router.html"><strong aria-hidden="true">13.2.</strong> react router</a></li><li class="chapter-item "><a href="../../posts/react/react_this.html"><strong aria-hidden="true">13.3.</strong> react this</a></li><li class="chapter-item "><a href="../../posts/react/react_interviw.html"><strong aria-hidden="true">13.4.</strong> react interview</a></li><li class="chapter-item "><a href="../../posts/react/important_react_interview.html"><strong aria-hidden="true">13.5.</strong> important react interview</a></li><li class="chapter-item "><a href="../../posts/react/react_quick_reference.html"><strong aria-hidden="true">13.6.</strong> react quick reference</a></li><li class="chapter-item "><a href="../../posts/react/redux_quick_reference.html"><strong aria-hidden="true">13.7.</strong> redux quick reference</a></li></ol></li><li class="chapter-item "><a href="../../posts/vue/vue.html"><strong aria-hidden="true">14.</strong> vue</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/vue/vue_ajax.html"><strong aria-hidden="true">14.1.</strong> vue ajax</a></li></ol></li><li class="chapter-item "><a href="../../posts/angular/angular.html"><strong aria-hidden="true">15.</strong> angular</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/angular/controller_communication.html"><strong aria-hidden="true">15.1.</strong> controller communication</a></li><li class="chapter-item "><a href="../../posts/angular/creating_custom_directives.html"><strong aria-hidden="true">15.2.</strong> creating custom directives</a></li><li class="chapter-item "><a href="../../posts/angular/directive_notes.html"><strong aria-hidden="true">15.3.</strong> directive notes</a></li><li class="chapter-item "><a href="../../posts/angular/directive_communication.html"><strong aria-hidden="true">15.4.</strong> directive communication</a></li><li class="chapter-item "><a href="../../posts/angular/post_params.html"><strong aria-hidden="true">15.5.</strong> post params</a></li><li class="chapter-item "><a href="../../posts/angular/read_json_angular.html"><strong aria-hidden="true">15.6.</strong> read json angular</a></li><li class="chapter-item "><a href="../../posts/angular/same_route_reload.html"><strong aria-hidden="true">15.7.</strong> same route reload</a></li></ol></li><li class="chapter-item "><a href="../../posts/css/css.html"><strong aria-hidden="true">16.</strong> css</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/css/use_css_media.html"><strong aria-hidden="true">16.1.</strong> use css media</a></li></ol></li><li class="chapter-item "><a href="../../posts/php/php.html"><strong aria-hidden="true">17.</strong> php</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/php/for_php_string_implment_some_extemtion_functions.html"><strong aria-hidden="true">17.1.</strong> for php string implment some extemtion functions</a></li><li class="chapter-item "><a href="../../posts/php/php_cheatsheet.html"><strong aria-hidden="true">17.2.</strong> PHP cheatsheet</a></li></ol></li><li class="chapter-item "><a href="../../posts/leetcode/leetcode.html"><strong aria-hidden="true">18.</strong> leetcode</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/leetcode/rust_leetcode.html"><strong aria-hidden="true">18.1.</strong> rust leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_codewar.html"><strong aria-hidden="true">18.2.</strong> rust codewar</a></li><li class="chapter-item "><a href="../../posts/leetcode/swift_codewar.html"><strong aria-hidden="true">18.3.</strong> swift codewar</a></li><li class="chapter-item "><a href="../../posts/leetcode/js_leetcode.html"><strong aria-hidden="true">18.4.</strong> js leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/java_leetcode.html"><strong aria-hidden="true">18.5.</strong> java leetcode</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_huawei.html"><strong aria-hidden="true">18.6.</strong> huawei test</a></li><li class="chapter-item "><a href="../../posts/leetcode/rust_utils.html"><strong aria-hidden="true">18.7.</strong> rust common functions</a></li><li class="chapter-item "><a href="../../posts/leetcode/olympiad_training.html"><strong aria-hidden="true">18.8.</strong> Computer olympiad training</a></li></ol></li><li class="chapter-item expanded "><a href="../../posts/ctf/CTF.html"><strong aria-hidden="true">19.</strong> ctf</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../posts/ctf/CTF_Note.html"><strong aria-hidden="true">19.1.</strong> CTF Note</a></li><li class="chapter-item "><a href="../../posts/ctf/0.1_Web.html"><strong aria-hidden="true">19.2.</strong> Web</a></li><li class="chapter-item "><a href="../../posts/ctf/4.1_Misc.html"><strong aria-hidden="true">19.3.</strong> Misc</a></li><li class="chapter-item "><a href="../../posts/ctf/3.2_PWN_note.html"><strong aria-hidden="true">19.4.</strong> PWN</a></li><li class="chapter-item "><a href="../../posts/ctf/3.1_Crypto.html"><strong aria-hidden="true">19.5.</strong> Crypto</a></li><li class="chapter-item "><a href="../../posts/ctf/3.4_RSA_note.html"><strong aria-hidden="true">19.6.</strong> Rsa attack</a></li><li class="chapter-item "><a href="../../posts/ctf/3.5_Base64.html"><strong aria-hidden="true">19.7.</strong> Base64</a></li><li class="chapter-item "><a href="../../posts/ctf/0.0_SQL Injection Cheatsheet.html"><strong aria-hidden="true">19.8.</strong> SQL Injection Cheatsheet</a></li><li class="chapter-item "><a href="../../posts/ctf/1.1_SQL_injection.html"><strong aria-hidden="true">19.9.</strong> SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.2_SQL_injection_UNION_attacks.html"><strong aria-hidden="true">19.10.</strong> SQL Injection UNION attacks</a></li><li class="chapter-item "><a href="../../posts/ctf/1.3_Blind SQL injection.html"><strong aria-hidden="true">19.11.</strong> Blind SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.4_Code Injection.html"><strong aria-hidden="true">19.12.</strong> Code Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.5_SSRF.html"><strong aria-hidden="true">19.13.</strong> SSRF</a></li><li class="chapter-item "><a href="../../posts/ctf/1.6_OS command injection.html"><strong aria-hidden="true">19.14.</strong> OS command injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.7_Local file inclusion.html"><strong aria-hidden="true">19.15.</strong> Local file inclusion</a></li><li class="chapter-item "><a href="../../posts/ctf/1.8_Remote file inclusion.html"><strong aria-hidden="true">19.16.</strong> Remote file inclusion</a></li><li class="chapter-item "><a href="../../posts/ctf/1.9_CSRFm.html"><strong aria-hidden="true">19.17.</strong> CSRF</a></li><li class="chapter-item "><a href="../../posts/ctf/1.10_NoSQL injection.html"><strong aria-hidden="true">19.18.</strong> NoSQL injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.11_JSON injection.html"><strong aria-hidden="true">19.19.</strong> JSON injection</a></li><li class="chapter-item "><a href="../../posts/ctf/1.12_CTF_Web_SQL_Note.html"><strong aria-hidden="true">19.20.</strong> CTF Web SQL Note</a></li><li class="chapter-item "><a href="../../posts/ctf/2.1_XXE.html"><strong aria-hidden="true">19.21.</strong> XXE</a></li><li class="chapter-item "><a href="../../posts/ctf/2.2_XSS.html"><strong aria-hidden="true">19.22.</strong> XSS</a></li><li class="chapter-item "><a href="../../posts/ctf/2.3_Upload File.html"><strong aria-hidden="true">19.23.</strong> Upload File</a></li><li class="chapter-item "><a href="../../posts/ctf/2.4_serialize_unserialize.html"><strong aria-hidden="true">19.24.</strong> serialize unserialize</a></li><li class="chapter-item "><a href="../../posts/ctf/2.5_Race condition.html"><strong aria-hidden="true">19.25.</strong> Race condition</a></li><li class="chapter-item "><a href="../../posts/ctf/3.2_PWN_note.html"><strong aria-hidden="true">19.26.</strong> PWN_note</a></li><li class="chapter-item "><a href="../../posts/ctf/3.3_pwn HCTF2016 brop.html"><strong aria-hidden="true">19.27.</strong> pwn HCTF2016 brop</a></li><li class="chapter-item expanded "><a href="../../posts/ctf/pwn_patch_defense_skill.html" class="active"><strong aria-hidden="true">19.28.</strong> PWN Patch defense skill</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_stack_overflow.html"><strong aria-hidden="true">19.29.</strong> PWN stack overflow</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_heap_overflow.html"><strong aria-hidden="true">19.30.</strong> PWN heap overflow</a></li><li class="chapter-item "><a href="../../posts/ctf/pwn_format_string_vulnerability.html"><strong aria-hidden="true">19.31.</strong> PWN Format String Vulnerability</a></li><li class="chapter-item "><a href="../../posts/ctf/kali_linux_tutorials.html"><strong aria-hidden="true">19.32.</strong> Kali linux tutorials</a></li><li class="chapter-item "><a href="../../posts/ctf/google_dorks_2023_lists.html"><strong aria-hidden="true">19.33.</strong> Google Dorks 2023 Lists</a></li><li class="chapter-item "><a href="../../posts/ctf/dvwa_writeup.html"><strong aria-hidden="true">19.34.</strong> DVWA WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/bwapp_writeup.html"><strong aria-hidden="true">19.35.</strong> bWAPP WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/sqlilabs_writeup.html"><strong aria-hidden="true">19.36.</strong> sqlilabs WriteUp</a></li><li class="chapter-item "><a href="../../posts/ctf/ctf_train_at_hangzhou.html"><strong aria-hidden="true">19.37.</strong> ctf train at hangzhou</a></li><li class="chapter-item "><a href="../../posts/ctf/ctf_common_mindmap_list.html"><strong aria-hidden="true">19.38.</strong> ctf common mindmap list</a></li><li class="chapter-item "><a href="../../posts/ctf/error_based_sql_injection.html"><strong aria-hidden="true">19.39.</strong> Error Based SQL Injection</a></li><li class="chapter-item "><a href="../../posts/ctf/urlfinder_tutorial.html"><strong aria-hidden="true">19.40.</strong> URLFinder Tutorial</a></li><li class="chapter-item "><a href="../../posts/ctf/observer_ward_tutorial.html"><strong aria-hidden="true">19.41.</strong> observer_ward Tutorial</a></li><li class="chapter-item "><a href="../../posts/ctf/mysql_udf_.html"><strong aria-hidden="true">19.42.</strong> MySQL UDF 提权</a></li><li class="chapter-item "><a href="../../posts/ctf/nuclei__tutorial.html"><strong aria-hidden="true">19.43.</strong> Nuclei Tutorial</a></li><li class="chapter-item "><a href="../../posts/ctf/2024_ctf_solution_thinking.html"><strong aria-hidden="true">19.44.</strong> 2024 ctf solution thinking</a></li><li class="chapter-item "><a href="../../posts/ctf/man_che_si_te_bian_ma.html"><strong aria-hidden="true">19.45.</strong> 曼彻斯特编码</a></li></ol></li></ol>
|
||
</div>
|
||
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||
<div class="sidebar-resize-indicator"></div>
|
||
</div>
|
||
</nav>
|
||
|
||
<!-- Track and set sidebar scroll position -->
|
||
<script>
|
||
var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
|
||
sidebarScrollbox.addEventListener('click', function(e) {
|
||
if (e.target.tagName === 'A') {
|
||
sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
|
||
}
|
||
}, { passive: true });
|
||
var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
|
||
sessionStorage.removeItem('sidebar-scroll');
|
||
if (sidebarScrollTop) {
|
||
// preserve sidebar scroll position when navigating via links within sidebar
|
||
sidebarScrollbox.scrollTop = sidebarScrollTop;
|
||
} else {
|
||
// scroll sidebar to current active section when navigating via "next/previous chapter" buttons
|
||
var activeSection = document.querySelector('#sidebar .active');
|
||
if (activeSection) {
|
||
activeSection.scrollIntoView({ block: 'center' });
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<div id="page-wrapper" class="page-wrapper">
|
||
|
||
<div class="page">
|
||
<div id="menu-bar-hover-placeholder"></div>
|
||
<div id="menu-bar" class="menu-bar sticky">
|
||
<div class="left-buttons">
|
||
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||
<i class="fa fa-bars"></i>
|
||
</label>
|
||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||
<i class="fa fa-paint-brush"></i>
|
||
</button>
|
||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||
</ul>
|
||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||
<i class="fa fa-search"></i>
|
||
</button>
|
||
</div>
|
||
|
||
<h1 class="menu-title">Andrew's Blog</h1>
|
||
|
||
<div class="right-buttons">
|
||
<a href="https://gitlink.org.cn/dnrops/dnrops.gitlink.net.git" title="Git repository" aria-label="Git repository">
|
||
<i id="git-repository-button" class="fa fa-github"></i>
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div id="search-wrapper" class="hidden">
|
||
<form id="searchbar-outer" class="searchbar-outer">
|
||
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||
</form>
|
||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||
<div id="searchresults-header" class="searchresults-header"></div>
|
||
<ul id="searchresults">
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||
<script>
|
||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||
});
|
||
</script>
|
||
|
||
<div id="content" class="content">
|
||
<main>
|
||
<h1 id="pwn-patch-defense-skill"><a class="header" href="#pwn-patch-defense-skill">PWN Patch defense skill</a></h1>
|
||
<h1 id="环境安装"><a class="header" href="#环境安装">环境安装</a></h1>
|
||
<ul>
|
||
<li>keypatch
|
||
<a href="https://github.com/keystone-engine/keypatch">https://github.com/keystone-engine/keypatch</a>
|
||
将keypatch.py复制到 IDA 7.0\plugins<br />
|
||
安装依赖Consolas</li>
|
||
</ul>
|
||
<pre><code class="language-shell">pip install keystone-engine
|
||
pip install six
|
||
</code></pre>
|
||
<p><strong>Edit -> Keypatch -> Patcher</strong>
|
||
选中一行指令patch,可以输入汇编代码 。
|
||
<strong>Edit -> Patch program -> Apply patches to input file</strong>
|
||
将修改保存到一个新的二进制文件(这是ida原本就有的功能)
|
||
<strong>Edit -> Keypatch -> Search</strong>
|
||
可以搜索汇编指令,不能直接搜索16进制,多条指令用 <code>;</code> 分隔</p>
|
||
<ul>
|
||
<li>lief</li>
|
||
</ul>
|
||
<pre><code class="language-shell">#python3
|
||
pip3 install lief
|
||
#python2
|
||
wget https://github.com/lief-project/LIEF/releases/download/0.9.0/lief-0.9.0-py2.7-linux.egg
|
||
cp ./lief-0.9.0-py2.7-linux.egg ~
|
||
pip install lief==0.9.0
|
||
</code></pre>
|
||
<p>API文档:https://lief-project.github.io/doc/latest/api/python/index.html</p>
|
||
<h1 id="patch技巧"><a class="header" href="#patch技巧">patch技巧</a></h1>
|
||
<h2 id="ida直接patch"><a class="header" href="#ida直接patch">IDA直接patch</a></h2>
|
||
<p>这种方式适合于较简单的修改,不能修改文件结构,直接使用**keypatch(快捷键Ctrl+Alt+k)**修改汇编代码,或者在Edit–>Patch program–>Assemble中进行修改:
|
||
<img src="../../img_list/20190411094250.png" alt="img" />](../../img_list/20190411094250.png)
|
||
例如这里存在<code>off-by-null</code>,直接将该指令nop掉即可:
|
||
<img src="../../img_list/20190411094555.png" alt="img" />](../../img_list/20190411094555.png)
|
||
如下图所示:
|
||
<img src="../../img_list/20190411094831.png" alt="img" />](../../img_list/20190411094831.png)
|
||
此时查看反编译的结果可以发现已经没有<code>off-by-null</code>漏洞了,最终还需要将修改的结果保存至文件中:
|
||
Edit–>Patch program–>Apply patches to input file</p>
|
||
<h2 id="使用lief"><a class="header" href="#使用lief">使用LIEF</a></h2>
|
||
<p>项目的地址:
|
||
<a href="https://github.com/lief-project/LIEF">https://github.com/lief-project/LIEF</a></p>
|
||
<h2 id="lief增加段来patch"><a class="header" href="#lief增加段来patch">LIEF增加段来patch</a></h2>
|
||
<p>程序的源代码如下:</p>
|
||
<pre><code class="language-c">#include <stdio.h>
|
||
#include <stdlib.h>
|
||
int main(int argc, char** argv) {
|
||
printf("/bin/sh%d",102);
|
||
puts("let's go\n");
|
||
printf("/bin/sh%d",102);
|
||
puts("let's gogo\n");
|
||
return EXIT_SUCCESS;
|
||
}
|
||
</code></pre>
|
||
<p><strong>目标是修改其中的printf函数为我们自己的函数</strong></p>
|
||
<h3 id="hook程序中的导入函数"><a class="header" href="#hook程序中的导入函数">hook程序中的导入函数</a></h3>
|
||
<h4 id="编写hook函数"><a class="header" href="#编写hook函数">编写hook函数</a></h4>
|
||
<p>首先要先编写我们的hook函数,编写hook函数有几个要求:</p>
|
||
<ul>
|
||
<li>汇编代码必须是位置独立的(也就是要使用-fPIC或-pie / -fPIE标志编译)</li>
|
||
<li>不要使用libc.so等外部库(使用:-nostdlib -nodefaultlibs flags)
|
||
根据上面的限制条件,我们编译hook程序时使用的编译指令如下所示:</li>
|
||
</ul>
|
||
<blockquote>
|
||
<p>gcc -nostdlib -nodefaultlibs -fPIC -Wl,-shared hook.c -o hook
|
||
我们编写的hook函数<code>my_printf</code>如下:</p>
|
||
</blockquote>
|
||
<pre><code class="language-c">void myprintf(char *a,int b){
|
||
//AT&T汇编格式
|
||
asm(
|
||
"mov %rdi,%rsi\n"
|
||
"mov $0,%rdi\n"
|
||
"mov $0x20,%rdx\n"
|
||
"mov $0x1,%rax\n"
|
||
"syscall\n"
|
||
);
|
||
}
|
||
//gcc -nostdlib -nodefaultlibs -fPIC -Wl,-shared hook.c -o hook
|
||
// Intel汇编格式
|
||
// void myprintf(char *a,int b){
|
||
// asm(
|
||
// "mov rsi, rdi;\n"
|
||
// "mov rdi, 0;\n"
|
||
// "mov rdx, 0x20;\n"
|
||
// "mov rax, 0x1;\n"
|
||
// "syscall;\n"
|
||
// );
|
||
// }
|
||
//gcc -masm=intel -nostdlib -nodefaultlibs -fPIC -Wl,-shared hook.c -o hook
|
||
</code></pre>
|
||
<h4 id="将hook函数注入到程序并修改got表"><a class="header" href="#将hook函数注入到程序并修改got表">将hook函数注入到程序并修改got表</a></h4>
|
||
<pre><code class="language-python">import lief
|
||
binary = lief.parse("./vulner")
|
||
hook = lief.parse('./hook')
|
||
# inject hook program to binary
|
||
segment_added = binary.add(hook.segments[0])
|
||
# hook got
|
||
my_printf = hook.get_symbol("myprintf")
|
||
my_printf_addr = segment_added.virtual_address + my_printf.value
|
||
binary.patch_pltgot('printf', my_printf_addr)
|
||
binary.write('vulner.patched')
|
||
</code></pre>
|
||
<p>运行patch后的程序可以发现patch成功:
|
||
<img src="../../img_list/20190411190529.png" alt="img" />](../../img_list/20190411190529.png)</p>
|
||
<h3 id="hook指定地址的函数调用"><a class="header" href="#hook指定地址的函数调用">hook指定地址的函数调用</a></h3>
|
||
<p>使用下面的代码可以完成hook程序中指定地址的call函数调用:</p>
|
||
<pre><code class="language-python">import lief
|
||
from pwn import *
|
||
def patch_call(file,srcaddr,dstaddr,arch = "amd64"):
|
||
print hex(dstaddr)
|
||
length = p32((dstaddr - (srcaddr + 5 )) & 0xffffffff)
|
||
order = '\xe8'+length
|
||
print disasm(order,arch=arch)
|
||
file.patch_address(srcaddr,[ord(i) for i in order])
|
||
binary = lief.parse("./vulner")
|
||
hook = lief.parse('./hook')
|
||
# inject hook program to binary
|
||
segment_added = binary.add(hook.segments[0])
|
||
hook_fun = hook.get_symbol("myprintf")
|
||
dstaddr = segment_added.virtual_address + hook_fun.value
|
||
srcaddr = 0x400584
|
||
patch_call(binary,srcaddr,dstaddr)
|
||
binary.write('vulner.patched')
|
||
</code></pre>
|
||
<h2 id="修改eh_frame段实现patch"><a class="header" href="#修改eh_frame段实现patch">修改.eh_frame段实现patch</a></h2>
|
||
<p><code>eh_frame</code>段在执行的时候对程序的影响不大,所以可以把hook代码添加到该段中,通过修改函数跳转的方式来执行hook代码
|
||
对section的操作参考<a href="https://lief.quarkslab.com/doc/latest/api/python/elf.html#section">官方文档-section部分</a>
|
||
section对象中的content属性就是该section中的内容,所以要对待patch程序的<code>.eh_frame</code>段进行修改,直接将<code>hook</code>程序中的<code>.text</code>段的内容赋值到<code>.eh_frame</code>段的内容即可。赋值完成之后,在通过与前面一致的方法修改函数跳转地址,使其跳转到<code>.eh_frame</code>段来执行我们的hook代码
|
||
具体的代码如下:</p>
|
||
<pre><code class="language-python">import lief
|
||
from pwn import *
|
||
def patch_call(file,srcaddr,dstaddr,arch = "amd64"):
|
||
print hex(dstaddr)
|
||
length = p32((dstaddr - (srcaddr + 5 )) & 0xffffffff)
|
||
order = '\xe8'+length
|
||
print disasm(order,arch=arch)
|
||
file.patch_address(srcaddr,[ord(i) for i in order])
|
||
binary = lief.parse("./vulner")
|
||
hook = lief.parse('./hook')
|
||
# write hook's .text content to binary's .eh_frame content
|
||
sec_ehrame = binary.get_section('.eh_frame')
|
||
print sec_ehrame.content
|
||
sec_text = hook.get_section('.text')
|
||
print sec_text.content
|
||
sec_ehrame.content = sec_text.content
|
||
print binary.get_section('.eh_frame').content
|
||
# hook target call
|
||
dstaddr = sec_ehrame.virtual_address
|
||
srcaddr = 0x400584
|
||
patch_call(binary,srcaddr,dstaddr)
|
||
binary.write('vulner.patched')
|
||
</code></pre>
|
||
<p>直接将hook程序中的<code>.text</code>段的<code>content</code>赋值到binary程序中的<code>.eh_frame</code>段的<code>content</code>段得到的效果如下图所示,内容确实是我们的hook函数:
|
||
<img src="../../img_list/20190411220505.png" alt="img" />](../../img_list/20190411220505.png)
|
||
修改指定的函数调用,使其跳转到我们修改后的<code>.eh_frame</code>段来执行,效果如下图所示:
|
||
<img src="../../img_list/20190411223153.png" alt="img" />](../../img_list/20190411223153.png)</p>
|
||
<h2 id="示例"><a class="header" href="#示例">示例</a></h2>
|
||
<p>容易造成栈溢出的函数</p>
|
||
<pre><code class="language-c">void * memcpy ( void * destination, const void * source, size_t num );
|
||
char * strcpy ( char * destination, const char * source );
|
||
char * strncpy ( char * destination, const char * source, size_t num );
|
||
char * gets(char*str);
|
||
ssize_t read(int fd, void *buf, size_t count);
|
||
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
|
||
char * fgets ( char * str, int num, FILE * stream );
|
||
char * strcat ( char * destination, const char * source );
|
||
scanf(“%20c”, &s);
|
||
</code></pre>
|
||
<h3 id="read-patch"><a class="header" href="#read-patch">read patch</a></h3>
|
||
<p>read造成的栈溢出,直接修改第三个参数,限制输入大小。
|
||
others_babystack中,read存在栈溢出。
|
||
使用keypatch将第三个参数改为0x80即可。
|
||
<strong>Edit -> Patch program -> Apply patches to input file</strong>
|
||
将修改保存到一个新的二进制文件</p>
|
||
<h3 id="gets-patch"><a class="header" href="#gets-patch">gets patch</a></h3>
|
||
<p>ret2text为例,32位程序。
|
||
gets造成栈溢出,程序没有read函数,构造syscall系统调用,<strong>注意32位程序系统调用为<code>int 0x80;</code>,64为程序为<code>syscall ;</code></strong>
|
||
先从<code>call gets</code>跳到eh_frame构造系统调用处的。</p>
|
||
<pre><code class="language-c">void mygets(char *a,int b){
|
||
// 32bits int 0x80; 64bits syscall;
|
||
asm(
|
||
"mov $0x3,%eax\n"
|
||
"mov $0, %ebx\n"
|
||
"mov %eax, %ecx\n"
|
||
"mov $0x20,%edx\n"
|
||
"int $0x80\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
);
|
||
}
|
||
//gcc -Os -nostdlib -nodefaultlibs -fPIC -Wl,-shared hook_gets.c -o hook_gets
|
||
// 64bits
|
||
// void mygets(char *a,int b){
|
||
// // 32bits int 0x80; 64bits syscall;
|
||
// asm(
|
||
// "mov $0x0,%rax\n"
|
||
// "mov %rdi, %rsi\n"
|
||
// "mov $0, %rdi\n"
|
||
// "mov $0x20,%rdx\n"
|
||
// "syscall\n"
|
||
// "nop\n"
|
||
// "nop\n"
|
||
// "nop\n"
|
||
// "nop\n"
|
||
// "nop\n"
|
||
|
||
// );
|
||
// }
|
||
</code></pre>
|
||
<pre><code class="language-python">import lief
|
||
from pwn import *
|
||
def patch_call(file,srcaddr,dstaddr,arch = "i386"):
|
||
print hex(dstaddr)
|
||
length = p32((dstaddr - (srcaddr + 5 )) & 0xffffffff)
|
||
order = '\xe8'+length
|
||
print disasm(order,arch=arch)
|
||
file.patch_address(srcaddr,[ord(i) for i in order])
|
||
binary = lief.parse("./ret2text")
|
||
hook = lief.parse('./hook_gets')
|
||
# write hook's .text content to binary's .eh_frame content
|
||
sec_ehrame = binary.get_section('.eh_frame')
|
||
print sec_ehrame.content
|
||
sec_text = hook.get_section('.text')
|
||
print sec_text.content
|
||
sec_ehrame.content = sec_text.content
|
||
print binary.get_section('.eh_frame').content
|
||
# hook target call
|
||
dstaddr = sec_ehrame.virtual_address
|
||
srcaddr = 0x080486AE
|
||
print("dstaddr ==>", hex(dstaddr))
|
||
patch_call(binary,srcaddr,dstaddr)
|
||
binary.write('ret2text-patched')
|
||
</code></pre>
|
||
<h3 id="堆溢出"><a class="header" href="#堆溢出">堆溢出</a></h3>
|
||
<p>以0ctf_2017_babyheap为例,程序edit功能处,输入大小又用户重新输入,造成任意大小写。</p>
|
||
<pre><code class="language-c">__int64 __fastcall sub_E7F(__int64 a1)
|
||
{
|
||
__int64 result; // rax
|
||
int v2; // [rsp+18h] [rbp-8h]
|
||
int v3; // [rsp+1Ch] [rbp-4h]
|
||
printf("Index: ");
|
||
result = sub_138C();
|
||
v2 = result;
|
||
if ( (int)result >= 0 && (int)result <= 15 )
|
||
{
|
||
result = *(unsigned int *)(24LL * (int)result + a1);
|
||
if ( (_DWORD)result == 1 )
|
||
{
|
||
printf("Size: ");
|
||
result = sub_138C();
|
||
v3 = result;
|
||
if ( (int)result > 0 )
|
||
{
|
||
printf("Content: ");
|
||
return sub_11B2(*(_QWORD *)(24LL * v2 + a1 + 16), v3); //v3为用户输入任意大小
|
||
}
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
</code></pre>
|
||
<p>这个我们把v3参数修改为堆块本身大小即可,根据堆块结构<code>(24LL * v2 + a1 + 8)</code>为堆块的size。
|
||
那么把v3修改为<code>(24LL * v2 + a1 + 8)</code>
|
||
对应汇编代码如下:
|
||
需要修改rsi为<code>(24LL * v2 + a1 + 8)</code> ,即<code>mov rsi, [rax+8]</code></p>
|
||
<pre><code class="language-asm">.text:0000000000000F39 mov rax, [rax+10h]
|
||
.text:0000000000000F3D mov rsi, rcx
|
||
.text:0000000000000F40 mov rdi, rax
|
||
.text:0000000000000F43 call sub_11B2
|
||
.text:0000000000000F48 jmp short locret_F4E
|
||
</code></pre>
|
||
<p><code>mov rsi, [rax+8]</code>占四字节,本身<code> mov rsi, rcx</code>指令占3字节,长度不够,所以跳转到<code>.eh_frame</code>段执行再跳转回来。
|
||
又由于<code>mov rax, [rax+10h]</code>修改了<code>rax</code>的值,所以<code>mov rax, [rax+10h]</code>与<code>mov rsi, [rax+8]</code>调换一下位置
|
||
patch方法:<strong>edit->Patch program->change byte</strong>输入十六进制机器码</p>
|
||
<pre><code class="language-asm">48 8B 70 08 48 8B 40 10 48 89 C7 E9 A3 F9 FF
|
||
</code></pre>
|
||
<p>修改如下:</p>
|
||
<pre><code class="language-asm">.eh_frame:0000000000001590 loc_1590:
|
||
.eh_frame:0000000000001590 48 8B 70 08 mov rsi, [rax+8]
|
||
.eh_frame:0000000000001594 48 8B 40 10 mov rax, [rax+10h]
|
||
.eh_frame:0000000000001598 48 89 C7 mov rdi, rax
|
||
.eh_frame:000000000000159B E9 A3 F9 FF FF jmp loc_F43
|
||
</code></pre>
|
||
<pre><code class="language-asm">.text:0000000000000F39 E9 52 06 00 00 jmp loc_1590
|
||
.text:0000000000000F3E 90 nop
|
||
.text:0000000000000F3F 90 nop
|
||
.text:0000000000000F40 90 nop
|
||
.text:0000000000000F41 90 nop
|
||
.text:0000000000000F42 90 nop
|
||
.text:0000000000000F43
|
||
.text:0000000000000F43 loc_F43: ; CODE XREF: sub_E7F+71C↓j
|
||
.text:0000000000000F43 E8 6A 02 00 00 call sub_11B2
|
||
</code></pre>
|
||
<p>查看伪代码</p>
|
||
<pre><code class="language-c">....
|
||
.....
|
||
if ( (_DWORD)result == 1 )
|
||
{
|
||
printf("Size: ");
|
||
result = sub_138C();
|
||
if ( (int)result > 0 )
|
||
{
|
||
printf("Content: ");
|
||
return sub_11B2(*(_QWORD *)(24LL * v2 + a1 + 16), *(_QWORD *)(24LL * v2 + a1 + 8));
|
||
.....
|
||
....
|
||
</code></pre>
|
||
<h3 id="off-by-nullone-patch"><a class="header" href="#off-by-nullone-patch">off-by-null/one patch</a></h3>
|
||
<p><code>b00ks</code>为例,题目中读取数据的函数会多读入2个字节的数据,程序在调用该函数时都将<code>size</code>减去了<code>1</code>,所以这里仍然会多读入一个字节,导致<code>off-by-null</code>
|
||
<img src="../../img_list/20190413184702.png" alt="img" />](../../img_list/20190413184702.png)
|
||
所以,这里的目标就是在调用该函数之前,把它的第二个参数再次减去<code>1</code>,这样就不存在<code>off-by-null</code>漏洞了,调用该函数的地方有好几个,这里仅对其中的一个进行<code>hook</code>,就选取<code>edit</code>功能中调用该函数的地方进行<code>hook</code>
|
||
待<code>hook</code>的call指令地址为<code>0xF2B</code>
|
||
<img src="../../img_list/20190413185106.png" alt="img" />](../../img_list/20190413185106.png)
|
||
要将第二个参数减一,而第二个参数是存放在<code>rsi</code>寄存器中的,所以只需要将<code>rsi</code>的值减去一,接着直接调用函数<code>read_ndata</code>即可,而我们在<code>hook.c</code>中写hook函数时是不知道增加了<code>segment</code>之后函数<code>read_ndata</code>的地址是多少的,所以这里先采取用<code>5个nop</code>指令来占位置的方法为<code>call</code>指令占位</p>
|
||
<pre><code>int myread(char *ptr,int num){
|
||
asm(
|
||
"sub $0x1,%rsi\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
);
|
||
return 0;
|
||
}
|
||
</code></pre>
|
||
<p>将上述的<code>hook.c</code>进行编译,得到<code>hook</code>文件:</p>
|
||
<blockquote>
|
||
<p>gcc -nostdlib -nodefaultlibs -fPIC -Wl,-shared hook.c -o hook
|
||
接着使用如下脚本将<code>0xF2B</code>处的<code>call</code>指令进行<code>hook</code></p>
|
||
</blockquote>
|
||
<pre><code class="language-python">import lief
|
||
from pwn import *
|
||
def patch_call(file,srcaddr,dstaddr,arch = "amd64"):
|
||
print hex(dstaddr)
|
||
length = p32((dstaddr - (srcaddr + 5 )) & 0xffffffff)
|
||
order = '\xe8'+length
|
||
print disasm(order,arch=arch)
|
||
file.patch_address(srcaddr,[ord(i) for i in order])
|
||
binary = lief.parse("./b00ks")
|
||
hook = lief.parse('./hook')
|
||
print hook.get_section('.text').content
|
||
# inject hook program to binary
|
||
segment_added = binary.add(hook.segments[0])
|
||
hook_fun = hook.get_symbol("myread")
|
||
# hook b00k's call
|
||
dstaddr = segment_added.virtual_address + hook_fun.value
|
||
srcaddr = 0xf2b
|
||
patch_call(binary,srcaddr,dstaddr)
|
||
binary.write('b00ks-patched')
|
||
</code></pre>
|
||
<p>patch之后,把得到的<code>b00ks-patched</code>文件拖到<code>IDA</code>中进行分析,发现并没有将<code>edit</code>功能中的call指令指向我们的hook函数,而且该call指令的地址也由原来的<code>0xf2b</code>变成了<code>0x1f2b</code>
|
||
<img src="../../img_list/20190413190056.png" alt="img" />](../../img_list/20190413190056.png)
|
||
是怎么回事呢?对比一下两个程序的段信息,发现patch之后的程序第一个段的大小增加了<code>0x1000</code>,导致后面的地址都增加了<code>0x1000</code>:
|
||
<img src="../../img_list/20190413190609.png" alt="img" />](../../img_list/20190413190609.png)
|
||
所以在增加了段之后我们需要修改的<code>call</code>指令地址已经不再是<code>0xf2b</code>,而变成了<code>0x1f2b</code>,所以对脚本稍作修改,把脚本中的<code>srcaddr = 0xf2b</code>改成<code>srcaddr = 0x1f2b</code>,再次查看patch的结果:
|
||
<img src="../../img_list/20190413190956.png" alt="img" />](../../img_list/20190413190956.png)
|
||
可以看到该出的函数调用确实指向了我们的hook函数<code>sub_4042d8</code></p>
|
||
<pre><code>LOAD:00000000004042D8 sub_4042D8 proc near ; CODE XREF: sub_1E17+114↑p
|
||
LOAD:00000000004042D8
|
||
LOAD:00000000004042D8 var_C = dword ptr -0Ch
|
||
LOAD:00000000004042D8 var_8 = qword ptr -8
|
||
LOAD:00000000004042D8
|
||
LOAD:00000000004042D8 push rbp
|
||
LOAD:00000000004042D9 mov rbp, rsp
|
||
LOAD:00000000004042DC mov [rbp+var_8], rdi
|
||
LOAD:00000000004042E0 mov [rbp+var_C], esi
|
||
LOAD:00000000004042E3 sub rsi, 1
|
||
LOAD:00000000004042E7 nop
|
||
LOAD:00000000004042E8 nop
|
||
LOAD:00000000004042E9 nop
|
||
LOAD:00000000004042EA nop
|
||
LOAD:00000000004042EB nop
|
||
LOAD:00000000004042EC mov eax, 0
|
||
LOAD:00000000004042F1 pop rbp
|
||
LOAD:00000000004042F2 retn
|
||
LOAD:00000000004042F2 sub_4042D8 endp
|
||
</code></pre>
|
||
<ul>
|
||
<li>继续完善
|
||
经过上面的操作,我们已经能够将<code>call</code>劫持到我们的hook函数来执行了,还差的就是把hook函数中<code>占位的nop指令</code>修改成<code>call read_ndata</code>函数,所以接下来将对其进行修改
|
||
观察上面patch后的结果,可以知道<code>nop</code>指令的起始地址为<code>0x4042E7</code>,我们要调用的函数<code>read_ndata</code>地址则变成了<code>0x19f5</code>
|
||
<img src="../../img_list/20190413191719.png" alt="img" />](../../img_list/20190413191719.png)
|
||
所以直接如下设置<code>patch_call</code>的参数就能实现最终的patch:</li>
|
||
</ul>
|
||
<pre><code>dstaddr = 0x19f5
|
||
srcaddr = 0x4042e7
|
||
</code></pre>
|
||
<p>完整的脚本如下:</p>
|
||
<pre><code class="language-python">import lief
|
||
from pwn import *
|
||
def patch_call(file,srcaddr,dstaddr,arch = "amd64"):
|
||
print hex(dstaddr)
|
||
length = p32((dstaddr - (srcaddr + 5 )) & 0xffffffff)
|
||
order = '\xe8'+length
|
||
print disasm(order,arch=arch)
|
||
file.patch_address(srcaddr,[ord(i) for i in order])
|
||
binary = lief.parse("./b00ks")
|
||
hook = lief.parse('./hook')
|
||
print hook.get_section('.text').content
|
||
# inject hook program to binary
|
||
segment_added = binary.add(hook.segments[0])
|
||
hook_fun = hook.get_symbol("myread")
|
||
# hook b00k's call
|
||
dstaddr = segment_added.virtual_address + hook_fun.value
|
||
srcaddr = 0x1f2b
|
||
patch_call(binary,srcaddr,dstaddr)
|
||
dstaddr = 0x19f5
|
||
srcaddr = 0x4042e7
|
||
patch_call(binary,srcaddr,dstaddr)
|
||
binary.write('b00ks-patched')
|
||
</code></pre>
|
||
<p>patch的效果如下所示:
|
||
<img src="../../img_list/20190413192115.png" alt="img" />](../../img_list/20190413192115.png)</p>
|
||
<pre><code>LOAD:00000000004042D8 ; Attributes: bp-based frame
|
||
LOAD:00000000004042D8
|
||
LOAD:00000000004042D8 sub_4042D8 proc near ; CODE XREF: sub_1E17+114↑p
|
||
LOAD:00000000004042D8
|
||
LOAD:00000000004042D8 var_C = dword ptr -0Ch
|
||
LOAD:00000000004042D8 var_8 = qword ptr -8
|
||
LOAD:00000000004042D8
|
||
LOAD:00000000004042D8 push rbp
|
||
LOAD:00000000004042D9 mov rbp, rsp
|
||
LOAD:00000000004042DC mov [rbp+var_8], rdi
|
||
LOAD:00000000004042E0 mov [rbp+var_C], esi
|
||
LOAD:00000000004042E3 sub rsi, 1
|
||
LOAD:00000000004042E7 call sub_19F5
|
||
LOAD:00000000004042EC mov eax, 0
|
||
LOAD:00000000004042F1 pop rbp
|
||
LOAD:00000000004042F2 retn
|
||
LOAD:00000000004042F2 sub_4042D8 endp
|
||
__int64 __fastcall sub_4042D8(__int64 a1, __int64 a2)
|
||
{
|
||
sub_19F5(a1, a2 - 1);
|
||
return 0LL;
|
||
}
|
||
</code></pre>
|
||
<ul>
|
||
<li>通过.eh_frame段实现patch
|
||
前面介绍的方法是通过在程序中增加一个段的方式来实现patch的,经过这种方法patch后虽然正常的执行都没有问题,但是程序的第一个段的大小增加了0x1000,这导致了程序中各个函数的地址也都增加了0x1000,对程序的改动较大,这里可以通过往<code>.eh_frame</code>段写入hook代码,然后跳转到这里执行的方式
|
||
过程和前面介绍的差不多,这里直接贴patch成功的脚本了</li>
|
||
</ul>
|
||
<pre><code class="language-python">import lief
|
||
from pwn import *
|
||
def patch_call(file,srcaddr,dstaddr,arch = "amd64"):
|
||
print hex(dstaddr)
|
||
length = p32((dstaddr - (srcaddr + 5 )) & 0xffffffff)
|
||
order = '\xe8'+length
|
||
print disasm(order,arch=arch)
|
||
file.patch_address(srcaddr,[ord(i) for i in order])
|
||
binary = lief.parse("./b00ks")
|
||
hook = lief.parse('./hook')
|
||
# write hook's .text content to binary's .eh_frame content
|
||
sec_ehrame = binary.get_section('.eh_frame')
|
||
# print sec_ehrame.content
|
||
sec_text = hook.get_section('.text')
|
||
sec_ehrame.content = sec_text.content
|
||
# hook target call
|
||
dstaddr = sec_ehrame.virtual_address
|
||
srcaddr = binary.get_section('.text').virtual_address+(0xf2b-0x8e0)
|
||
print 'srcaddr:'+hex(srcaddr)
|
||
print 'dstaddr:'+hex(dstaddr)
|
||
patch_call(binary,srcaddr,dstaddr)
|
||
# modify nop to call
|
||
dstaddr = binary.get_section('.text').virtual_address+(0x9f5-0x8e0)
|
||
srcaddr = sec_ehrame.virtual_address+0xf
|
||
patch_call(binary,srcaddr,dstaddr)
|
||
binary.write('b00ks-patched-frame')
|
||
</code></pre>
|
||
<p>patch的效果如下:
|
||
<img src="../../img_list/20190413210506.png" alt="img" />](../../img_list/20190413210506.png)
|
||
<strong>可以看到这种方式对程序的影响确实很小,在hook的代码很少的情况下,可以首选这种方法</strong></p>
|
||
<h3 id="整数溢出"><a class="header" href="#整数溢出">整数溢出</a></h3>
|
||
<p>有符号跳转改为无符号。</p>
|
||
<pre><code>无符号跳转:
|
||
JA ;无符号大于则跳转
|
||
JNA ;无符号不大于则跳转
|
||
JAE ;无符号大于等于则跳转 同JNB
|
||
JNAE ;无符号不大于等于则跳转 同JB
|
||
JB ;无符号小于则跳转
|
||
JNB ;无符号不小于则跳转
|
||
JBE ;无符号小于等于则跳转 同JNA
|
||
JNBE ;无符号不小于等于则跳转 同JA
|
||
有符号跳转:
|
||
JG ;有符号大于则跳转
|
||
JNG ;有符号不大于则跳转
|
||
JGE ;有符号大于等于则跳转 同JNL
|
||
JNGE ;有符号不大于等于则跳转 同JL
|
||
JL ;有符号小于则跳转
|
||
JNL ;有符号不小于则跳转
|
||
JLE ;有符号小于等于则跳转 同JNG
|
||
JNLE ;有符号不小于等于则跳转 同JG
|
||
</code></pre>
|
||
<h3 id="格式化字符串"><a class="header" href="#格式化字符串">格式化字符串</a></h3>
|
||
<p>程序里有puts的话把call printf改成call puts
|
||
增加代码,添加合适的参数,将printf(xxx)改为printf(“%s”,xxxxx)
|
||
增加代码,把printf改成write,没有write可以通过系统调用的形式。
|
||
<strong>容易造成格式化字符串漏洞的函数</strong>:</p>
|
||
<pre><code>int printf ( const char * format, ... );
|
||
int fprintf ( FILE * stream, const char * format, ... );
|
||
int sprintf ( char * str, const char * format, ... );
|
||
</code></pre>
|
||
<h3 id="命令执行"><a class="header" href="#命令执行">命令执行</a></h3>
|
||
<p>把命令执行函数nop掉
|
||
<strong>容易造成命令执行的函数</strong>:</p>
|
||
<pre><code>FILE *popen(const char *command, const char *type);
|
||
int system(const char *command);
|
||
int execve(const char *pathname, char *const argv[], char *const envp[]);
|
||
int execl(const char *path, const char *arg, ...);
|
||
int execlp(const char *file, const char *arg, ...);
|
||
int execle(const char *path, const char *arg, char * const envp[]);
|
||
int execv(const char *path, char *const argv[]);
|
||
int execvp(const char *file, char *const argv[]);
|
||
int execvpe(const char *file, char *const argv[], char *const envp[]);
|
||
int execveat(int dirfd, const char *pathname, char *const argv[], char *const envp[], int flags);
|
||
</code></pre>
|
||
<h3 id="不太优雅的方法"><a class="header" href="#不太优雅的方法"><del>不太优雅的方法</del></a></h3>
|
||
<p><strong>check脚本的时候有可能会检测</strong>
|
||
把free的plt表改成ret~~
|
||
<del>nop 掉 malloc</del>
|
||
<del>nop 掉 free</del>
|
||
<del>打乱got表</del>
|
||
增加代码,在读的字节中过滤一些特殊的字符</p>
|
||
|
||
</main>
|
||
|
||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||
<!-- Mobile navigation buttons -->
|
||
<a rel="prev" href="../../posts/ctf/3.3_pwn HCTF2016 brop.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||
<i class="fa fa-angle-left"></i>
|
||
</a>
|
||
|
||
<a rel="next prefetch" href="../../posts/ctf/pwn_stack_overflow.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||
<i class="fa fa-angle-right"></i>
|
||
</a>
|
||
|
||
<div style="clear: both"></div>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
|
||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||
<a rel="prev" href="../../posts/ctf/3.3_pwn HCTF2016 brop.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||
<i class="fa fa-angle-left"></i>
|
||
</a>
|
||
|
||
<a rel="next prefetch" href="../../posts/ctf/pwn_stack_overflow.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||
<i class="fa fa-angle-right"></i>
|
||
</a>
|
||
</nav>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<script>
|
||
window.playground_line_numbers = true;
|
||
</script>
|
||
|
||
<script>
|
||
window.playground_copyable = true;
|
||
</script>
|
||
|
||
<script src="../../ace.js"></script>
|
||
<script src="../../editor.js"></script>
|
||
<script src="../../mode-rust.js"></script>
|
||
<script src="../../theme-dawn.js"></script>
|
||
<script src="../../theme-tomorrow_night.js"></script>
|
||
|
||
<script src="../../elasticlunr.min.js"></script>
|
||
<script src="../../mark.min.js"></script>
|
||
<script src="../../searcher.js"></script>
|
||
|
||
<script src="../../clipboard.min.js"></script>
|
||
<script src="../../highlight.js"></script>
|
||
<script src="../../book.js"></script>
|
||
|
||
<!-- Custom JS scripts -->
|
||
<script src="../../src/js/custom.js"></script>
|
||
|
||
|
||
</div>
|
||
</body>
|
||
</html>
|