Files
Penetration_Testing_POC/books/记一次使用 Xposed RPC 和 BurpGuard 应对金融APP参数签名及加密的详细过程.html
T

627 lines
351 KiB
HTML
Raw Normal View History

<!DOCTYPE html> <html lang=en style><!--
Page saved with SingleFile
url: https://xz.aliyun.com/t/15533
--><meta charset=utf-8>
<title>记一次使用 Xposed RPC 和 BurpGuard 应对金融APP参数签名及加密的详细过程</title>
<meta name=description content=先知社区,先知安全技术社区>
<meta name=viewport content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<style>/*!
* Bootstrap v2.3.1
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}footer{display:block}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}img{height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}input{margin:0}button{-webkit-appearance:button}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" ("attr(href)")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre{border:1px solid #999;page-break-inside:avoid}img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2{orphans:3;widows:3}h2{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333}a{text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}.container{width:940px}.span10{width:780px}.container{margin-right:auto;margin-left:auto}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}p{margin:0 0 10px}strong{font-weight:bold}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h4{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h4{font-size:17.5px}ul{padding:0}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}code,pre{color:#333;-webkit-border-radius:3px;-moz-border-radius:3px}code{color:#d14}pre{display:block;margin:0 0 10px;word-break:break-all;white-space:pre-wrap;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px}pre code{color:inherit}input{font-weight:normal}input{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}input[type="text"]{display:inline-block;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px}input{width:206px}input[type="text"]{background-color:#fff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}input{margin-left:0}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear}.collapse{position:relative;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.btn{text-shadow:0 1px 1px rgba(255,255,255
<style>/*! Editor.md v1.5.0 | editormd.min.css | Open source online markdown editor. | MIT License | By: Pandao | https://github.com/pandao/editor.md | 2015-06-09 *//*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){}@media only screen and (-webkit-min-device-pixel-ratio:3),only screen and (min-device-pixel-ratio:3){}/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 *//*!
* Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
*/@font-face{font-family:FontAwesome;src:/* original URL: https://xz.aliyun.com/static/editor.md/fonts/fontawesome-webfont.woff2?v=4.3.0 */url(data:font/woff2;base64,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
<style>/*!
* Bootstrap Responsive v2.3.1
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}@-ms-viewport{width:device-width}@media (min-width:768px) and (max-width:979px){}@media (max-width:767px){}@media print{}@media (min-width:1200px){.row{margin-left:-30px}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container{width:1170px}.span10{width:970px}input{margin-left:0}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container{width:724px}.span10{width:600px}input{margin-left:0}}@media (max-width:767px){body{padding-right:0px;padding-left:0px}.container{width:auto}.row{margin-left:0}[class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.modal{position:fixed;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.modal{top:10px;right:10px;left:10px}}@media (max-width:979px){body{padding-top:0}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px}.nav-collapse{clear:both}.nav-collapse.collapse{height:0;overflow:hidden}}@media (min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}}</style>
<style>li{line-height:26px}a:hover{text-decoration:none}.post-user-action>span{margin-right:10px;line-height:21px;border:none}.post-user-action .i-seprator{color:rgba(0,0,0,0.1);margin:0 2px}.navbar .brand{padding:0;height:50px;margin-left:0;display:inline-block!important;background-repeat:no-repeat;width:120px;background-size:207px 50px;background-image:/* original URL: https://xz.aliyun.com/static/icon/xianzhi-brand.svg */url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIxLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IuWbvuWxgl8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIKCSB2aWV3Qm94PSIwIDAgODAwLjQgMTMwLjQiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDgwMC40IDEzMC40OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Cgkuc3Qwe2ZpbGw6IzM3M0Q0MTt9Cjwvc3R5bGU+Cjx0aXRsZT7lhYjnn6XmioDmnK/npL7ljLo8L3RpdGxlPgo8Zz4KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMCwxMjEuNCAwLDI3LjMgNTYuMywyNy4zIAkiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iODkuOSw4LjQgODkuOSwxMDIuNSAzMy41LDEwMi41IAkiLz4KPC9nPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTMwLjcsNTguNGMtMi4zLTEuNC00LjctMi45LTcuMi00LjVjNi02LjksMTAuNy0xNi4yLDE0LjEtMjcuOWw4LjMsMS43Yy0wLjcsMS42LTEuNiwzLjktMi44LDYuOQoJYy0wLjcsMi4zLTEuMywzLjktMS43LDQuOGgxNy41VjI0aDguM3YxNS41aDI5LjZWNDdoLTI5LjZ2MTUuMWgzNC43VjcwaC0yNi41djIxLjNjLTAuMiwzLjQsMS42LDUsNS41LDQuOGg3LjIKCWMzLjIsMC4yLDUuMy0xLjMsNi4yLTQuNWMwLjItMS40LDAuNS00LjEsMC43LTguM2MwLDAuNywwLjEtMC4xLDAuMy0yLjRsNy42LDIuOGMtMC4yLDQuMS0wLjcsNy45LTEuNCwxMS40CgljLTEuNiw2LTUuOCw4LjgtMTIuNyw4LjZoLTEwLjdjLTcuNiwwLjItMTEuMi0zLjItMTEtMTAuM1Y3MC4xaC0xNS44djMuMWMwLDE1LjQtOS4xLDI2LjQtMjcuMiwzM2MtMS40LTIuMS0zLTQuNi00LjgtNy42CglDMTM1LjEsOTQsMTQzLDg1LjQsMTQzLDcyLjhWNzBoLTIyLjd2LTcuOWgzOC41VjQ3aC0yMS4zQzEzNS41LDUxLjEsMTMzLjIsNTQuOSwxMzAuNyw1OC40eiIvPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjEzLjIsNTQuNmMtMC41LTAuMi0xLjItMC43LTIuMS0xLjRjLTEuOC0xLjQtMy4yLTIuMy00LjEtMi44YzQuOC04LjksOC4xLTE3LjksMTAtMjYuOGw3LjYsMS40CgljLTAuNSwxLjgtMS4zLDQuNC0yLjQsNy42Yy0wLjIsMS4yLTAuNSwyLTAuNywyLjRoMjQuMXY3LjJoLTEyYzAsOC43LTAuMSwxNC45LTAuMywxOC42aDE0LjFWNjhoLTE0LjhjMCwyLjMtMC4yLDQuNS0wLjcsNi41CgljMS42LDEuNiwzLjgsNCw2LjUsNy4yYzQuNiw0LjgsOCw4LjYsMTAuMywxMS40bC01LjgsNS4yYy0wLjktMS4yLTIuMy0yLjgtNC4xLTQuOGMtMS44LTIuMy00LjgtNS44LTguOS0xMC43CgljLTIuNSw3LjgtOC40LDE1LjUtMTcuNSwyMy4xYy0yLjMtMi44LTQuMS00LjgtNS41LTYuMmMxMS4yLTguOSwxNy4zLTE5LjUsMTguMi0zMS43aC0xNy4ydi03LjJoMTcuNWMwLjItMy45LDAuMy0xMC4xLDAuMy0xOC42CgloLTYuOUMyMTcuMSw0Ni4zLDIxNS4zLDUwLjQsMjEzLjIsNTQuNnogTTI1MS40LDEwMi43VjMxLjloMzUuOHY3MC41aC04LjN2LTcuNmgtMTkuNnY3LjlDMjU5LjMsMTAyLjcsMjUxLjQsMTAyLjcsMjUxLjQsMTAyLjd6CgkgTTI1OS4zLDM5LjR2NDcuOGgxOS42VjM5LjRIMjU5LjN6Ii8+CjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0yOTcuMiw4MS4xYy0wLjItMC45LTAuNi0yLjMtMS00LjFjLTAuNy0xLjgtMS4yLTMuMi0xLjQtNC4xYzkuMi02LjIsMTYuNC0xNC4zLDIxLjctMjQuNGgtMTkuNnYtNi45aDI3LjV2Ny4yCgljLTIuNSw1LjUtNS40LDEwLjQtOC42LDE0Ljh2NDIuM2gtNy42VjcyLjFDMzA1LDc1LjEsMzAxLjQsNzguMSwyOTcuMiw4MS4xeiBNMzExLjcsNDAuNWMtMC4yLTAuNS0wLjYtMS4xLTEtMi4xCgljLTIuOC02LTQuNi05LjctNS41LTExLjRsNi45LTMuMWMwLjcsMS4yLDEuOCwzLjMsMy40LDYuNWMxLjYsMywyLjgsNS4yLDMuNCw2LjVMMzExLjcsNDAuNXogTTMyNi44LDgwLjcKCWMtMS42LTIuMS00LjctNS42LTkuMy0xMC43Yy0wLjItMC4yLTAuNS0wLjUtMC43LTAuN2w0LjgtNC41YzIuMSwxLjgsNC45LDQuNiw4LjYsOC4zYzEuMSwxLjIsMS45LDIsMi40LDIuNEwzMjYuOCw4MC43egoJIE0zMjguNSw1Ni42VjQ5aDE4LjZWMjQuM2g4LjN2MjQuOEgzNzV2Ny42aC0xOS42djM5LjJoMjIuNHY2LjloLTUzdi02LjloMjIuNFY1Ni42SDMyOC41eiIvPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMzg5LjgsMTAxLjRWMjkuMUg0NjJ2Ny42aC02NC4zdjU3LjhoNjUuN3Y2LjlIMzg5Ljh6IE00NTAuMyw5MC40Yy02LjItNi42LTEyLjYtMTMtMTkuMy0xOC45CgljLTYsNS43LTEzLjQsMTIuMy0yMi40LDE5LjZjLTEuNC0xLjYtMy40LTMuOC02LjItNi41YzguMy01LjcsMTUuOC0xMiwyMi43LTE4LjljLTYuOS02LjQtMTMuOC0xMi43LTIwLjYtMTguOWw2LjItNS4yTDQzMSw2MC4yCgljNS41LTYuMiwxMC45LTEyLjgsMTYuMi0yMGw3LjIsNC41Yy01LjcsNy42LTExLjYsMTQuNC0xNy41LDIwLjZjNi45LDYuNywxMy42LDEzLDIwLjMsMTguOUw0NTAuMyw5MC40eiIvPgo8L3N2Zz4K)}.brand-box{position:absolute}.related-section{min-height:42px;padding:5
<style>a{color:#778087}.topic-list p{margin:0 0 0 0}.topic-content{min-height:40px}.collapse form{position:relative;width:300px;float:right}div.search{padding:10px 0}.d1 input{height:20px;padding-left:18px;border:1px solid #ddd;border-radius:15px;outline:none;background:#ffffff;color:#9E9C9C;float:right}.vote{font-weight:normal;margin-left:6px}.topic-list{word-break:break-all;word-wrap:break-word}ul{margin:0 0 10px 0}/*!*border-bottom: solid #eee 1px;*!*/.user-info{padding:5px 0 5px 0}.topic-info a,.topic-info{padding-top:5px}.topic-info a:hover{text-decoration:solid}.reminder{min-height:200px;border:1px #ddd solid;border-radius:3px;line-height:200px;text-align:center}</style>
<style>body{background-color:#eee}img{max-width:100%}form{margin:0!important}a:focus{text-decoration:none}.markdown-body p>code{white-space:normal;word-break:break-all;border:none!important}.box ul,ol{margin-bottom:0px!important}.markdown-body ol{margin:0 0 24px 0!important}.box a:hover{text-decoration:none}.box-container>ul>li{list-style-type:none}#Wrapper .row.box{margin-left:0px}.navbar-inner{border-radius:0px;min-height:40px;padding-right:0px;padding-left:0px;outline:none;margin-bottom:0;list-style:none;z-index:1050;background:#fff;-webkit-box-shadow:0 1px 4px rgba(0,21,41,0.08);box-shadow:0 1px 4px rgba(0,21,41,0.08);line-height:46px;-webkit-transition:background .3s,width .2s;-o-transition:background .3s,width .2s;transition:background .3s,width .2s}.bs-docs-footer{text-align:left;color:#99979c;height:64px;background-color:#FFF;border-top:1px solid rgba(0,0,0,0.22);line-height:64px}.bs-docs-footer .links>a{display:inline-block;padding:0 12px;border-left:1px solid #e8e8e8;color:#8c8c8c;line-height:1}.bs-docs-footer .links>a:first-child{border-left:none}.box-container .user-info{margin-bottom:10px;background:#fff}.content-title{font-size:24px;color:#333;text-decoration:none;line-height:24px;text-shadow:0 1px 0#fff}.markdown-body h1,.markdown-body h2{border-bottom:none}.box-container{padding:20px}.breadcrumb{padding:8px 10px 8px 15px;margin-bottom:10px;border-radius:0;color:#000;background-color:#fff}.breadcrumb>li{text-shadow:none!important;margin:2px 0px}.active{text-shadow:none!important}.breadcrumb .active{color:#555;display:inline-block;text-shadow:none!important}.label{background-color:#f4f4f4;line-height:12px;display:inline-block;padding:4px 4px 4px 4px;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;text-decoration:none;text-shadow:none;font-weight:normal}.topic-info{color:#999!important;font-size:12px!important}.topic-info a{padding:0px;color:#555!important;font-size:12px!important}.topic-info a:hover{color:#4d5256;text-decoration:underline}.topic-info .cell{padding-left:0!important;margin-left:0px;font-size:10px;font-weight:bold}.markdown-body img{max-width:90%!important;text-align:center;margin-left:auto;margin-right:auto;display:block;padding:10px 0px 10px 0px}.topic-info span{margin-left:0px;font-size:10px;color:rgba(0,0,0,0.45)}.btn{display:inline-block;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:20px;background-color:#f4f4f4;color:#444;border-color:#ddd;font-family:"Helvetica Neue For Number",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Helvetica Neue",Helvetica,Arial,sans-serif;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;list-style:none;font-weight:400;text-align:center;cursor:pointer;background-image:none;white-space:nowrap;border-radius:2px;height:32px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.box{font-family:Monospaced Number,Chinese Quote,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.5;color:rgba(0,0,0,0.65);-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:0!important;margin-bottom:20px;padding:0;list-style:none;background:#fff;border-radius:2px;position:relative;-webkit-transition:all .3s;-o-transition:all .3s;transition:all .3s;-moz-box-shadow:0 1px 1px rgba(0,0,0,0.15);-webkit-box-shadow:0 1px 1px rgba(143,168,191,.35);box-shadow:0 1px 1px rgba(143,168,191,.35);border-bottom:1px solid #e2e2e9}.span10{float:left;min-height:1px}#Wrapper .span10{margin-left:0px!important;max-width:960px}@media (min-width:1200px){.container{width:82%!important}}@media screen and (min-width:1500px){#Wrapper.container,.navbar .navbar-inner .container,.bs-docs-footer .container{max-width:1100px!important}#Wrapper .span10{max-width:810px!important}}@media screen and (min-width:980px) and (max-width:1499px){#Wrapper.container,.navbar .navbar-inner .container,.bs-docs-footer .container{max-width:1100px!important}#Wrapper .span10{max-width:74%!important}}@m
<style>/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 */@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-device-pixel-ratio:2){}@media only screen and (-webkit-min-device-pixel-ratio:3),only screen and (min-device-pixel-ratio:3){}/*! prefixes.scss v0.1.0 | Author: Pandao | https://github.com/pandao/prefixes.scss | MIT license | Copyright (c) 2015 *//*!
* Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
*/@font-face{font-family:"FontAwesome";src:/* original URL: https://xz.aliyun.com/static/editor.md/fonts/fontawesome-webfont.woff2?v=4.3.0 */url(data:font/woff2;base64,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
<style>.highlight .k{color:#204a87;font-weight:bold}.highlight .n{color:#000000}.highlight .o{color:#ce5c00;font-weight:bold}.highlight .p{color:#000000;font-weight:bold}.highlight .c1{color:#8f5902;font-style:italic}.highlight .kc{color:#204a87;font-weight:bold}.highlight .kd{color:#204a87;font-weight:bold}.highlight .kn{color:#204a87;font-weight:bold}.highlight .kt{color:#204a87;font-weight:bold}.highlight .s{color:#4e9a06}.highlight .na{color:#c4a000}.highlight .nc{color:#000000}.highlight .nd{color:#5c35cc;font-weight:bold}.highlight .ne{color:#cc0000;font-weight:bold}.highlight .nf{color:#000000}.highlight .nn{color:#000000}.highlight .ow{color:#204a87;font-weight:bold}.highlight .mi{color:#0000cf;font-weight:bold}.highlight .s2{color:#4e9a06}.highlight .se{color:#4e9a06}.highlight .s1{color:#4e9a06}.highlight .bp{color:#3465a4}</style>
<style>@-webkit-keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes a{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@media (max-width:800px){}</style>
<!--[if lte IE 8]>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<![endif]-->
<!--[if !IE]> -->
<style>#waf_nc_block{position:fixed;width:100%;height:100%;top:0;bottom:0;left:0;z-index:99999}</style><style data-id=immersive-translate-input-injected-css>@-webkit-keyframes immersive-translate-loading-animation{from{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@keyframes immersive-translate-loading-animation{from{transform:rotate(0deg)}to{transform:rotate(359deg)}}@keyframes immersiveTranslateShadowRolling{0%{box-shadow:0px 0 rgba(255,255,255,0),0px 0 rgba(255,255,255,0),0px 0 rgba(255,255,255,0),0px 0 rgba(255,255,255,0)}12%{box-shadow:100px 0 var(--loading-color),0px 0 rgba(255,255,255,0),0px 0 rgba(255,255,255,0),0px 0 rgba(255,255,255,0)}25%{box-shadow:110px 0 var(--loading-color),100px 0 var(--loading-color),0px 0 rgba(255,255,255,0),0px 0 rgba(255,255,255,0)}36%{box-shadow:120px 0 var(--loading-color),110px 0 var(--loading-color),100px 0 var(--loading-color),0px 0 rgba(255,255,255,0)}50%{box-shadow:130px 0 var(--loading-color),120px 0 var(--loading-color),110px 0 var(--loading-color),100px 0 var(--loading-color)}62%{box-shadow:200px 0 rgba(255,255,255,0),130px 0 var(--loading-color),120px 0 var(--loading-color),110px 0 var(--loading-color)}75%{box-shadow:200px 0 rgba(255,255,255,0),200px 0 rgba(255,255,255,0),130px 0 var(--loading-color),120px 0 var(--loading-color)}87%{box-shadow:200px 0 rgba(255,255,255,0),200px 0 rgba(255,255,255,0),200px 0 rgba(255,255,255,0),130px 0 var(--loading-color)}100%{box-shadow:200px 0 rgba(255,255,255,0),200px 0 rgba(255,255,255,0),200px 0 rgba(255,255,255,0),200px 0 rgba(255,255,255,0)}}@media screen and (max-width:768px){}@media screen and (max-width:768px){}</style><meta name=referrer content=no-referrer><link rel=icon href="data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAADDUExURUxpcVVVVUNDVT5CTz1BUEBVVT1BUD1BTz5CTz5GT0BDUVVVVT5CTz5BUj1CTz5BT05OYj1CUD5GVUJCUj5CUD5BTz5BT0lJbT5CUEJCVT9DUUBHVT5CUD5CTz9CUD5BTz1BTz5CUEREUz5CUD5BUD5DTz5CUD5BT0BDUT5CTz1CUD5EUUBgYEBDUT5CUT1CTz1BUD5BUD9DUT1CT0REVT5BUENDUT1BUEBGUz1BUD9DT0FBUz1CTz5BTz1CUD1BUD1BT5JdbS4AAABAdFJOUwAJKr76DPbywR1MBuRO5fsNsyEfvdtKB4MbfiTa+FnegYwitbBXfPdYrt0pCEiL9XmsRdgeVhO8KI2KK45a2b/ePQx7AAAAwUlEQVQ4y4XTxw7CQAwE0A2E0BN67733Xv3/X4U0kYgimKxP9vgdfNhVildaBVfmpQGPaPD+7mjAW74g5q8Ewqd4QHy1T+JCm4IdsqswsEUUchhYHxCFhYENkpYw0MCFEZuCJYKuMDB1LzQZsPLehX/BCONEGCiWcWGKghKmlTAwwDA3GbByGArCQA39UBiYLfwX/gD3mdyEgSy6i8nAuIfuLAx00ByFgbaB5hT3VdUDmk8mfc0fa9Y1oKLZKyNo+QEJQV3gLnHrKwAAAABJRU5ErkJggg==" type=image/x-icon data-sf-original-href=https://xz.aliyun.com/static/icon/favicon.ico><style>.sf-hidden{display:none!important}</style><link rel=canonical href=https://xz.aliyun.com/t/15533><meta http-equiv=content-security-policy content="default-src 'none'; font-src 'self' data:; img-src 'self' data:; style-src 'unsafe-inline'; media-src 'self' data:; script-src 'unsafe-inline' data:; object-src 'self' data:; frame-src 'self' data:;"><style>img[src="data:,"],source[src="data:,"]{display:none!important}</style></head>
<body>
<div class="navbar navbar-default">
<div class=navbar-inner>
<div class=container style=text-align:center;position:relative>
<!--[if lte IE 8]>
<span style="display:inline-block;margin:0 auto;color:red;">为了更好的体验,请使用IE10及以上版本</span>
<![endif]-->
<div class=brand-box>
<a class=brand href=https://xz.aliyun.com/tab/1></a>
</div>
<a href="https://account.aliyun.com/login/login.htm?oauth_callback=https%3A%2F%2Fxz.aliyun.com%2Ft%2F15533&amp;from_type=xianzhi" class="pull-right anonymous-user hh_loding sf-hidden">
登录</a>
<div class="nav-collapse collapse">
<div class="search d1 text-right">
<form action=/search>
<input type=text placeholder=搜索 name=keyword value>
</form>
</div>
</div>
</div>
</div>
</div>
<div id=Wrapper class=container>
<div class=row2>
<div class=span10>
<div class="row box content" width="1200px !important" style=width:1200px>
<div class=box-container>
<div class=main-topic>
<div class="clearfix user-info topic-list">
<p><span class=content-title>记一次使用 Xposed RPC 和 BurpGuard 应对金融APP参数签名及加密的详细过程</span>
</p>
<div class=topic-info>
<span class=info-left>
<a href=https://xz.aliyun.com/u/78157>
<span class="username cell"> 1053418361825225</span></a> <span class=i-seprator> / </span>
<span> 2024-09-05 12:51:59</span><span class=i-seprator> / </span>
<span>发表于北京 / </span>
<span>浏览数 49</span>
<span class=content-node>
<span class="label label-default label-node-first">
<a href=https://xz.aliyun.com/tab/1>技术文章</a></span>
<span class="label label-default">
<a href=https://xz.aliyun.com/node/11>技术文章</a></span>
</span>
</span>
<span class="pull-right t-vote cell info-right"><a class="vote vote-up" href=javascript:void(0)>
顶(0)</a>
<a class="vote vote-down" href=javascript:void(0)>
踩(0)</a></span>
</div>
</div>
<hr>
<div id=topic_content class="topic-content markdown-body">
<h1 id=toc-0>前言</h1>
<p>在一次金融渗透测试项目中需要对 APP 进行渗透,发现 APP 对参数进行了签名以及加密,于是便逆向 APP 并通过 Xposed RPC 和 BurpGuard 解决了问题,从中学到了许多,因此记录过程并分享一下思路,代码和图片均做了脱敏处理,同时省略了代码调试的过程。</p>
<p>阅读完本文,你可以学习到:</p>
<ol>
<li>APP 请求逆向思路</li>
<li>如何查阅资料</li>
<li>APP 请求签名和加密的原理</li>
<li>了解白盒 WbSM4</li>
<li>Xposed RPC 的实现思路</li>
<li>BurpGuard 如何使用</li>
</ol>
<p><strong>声明:本文不针对任何 APP,仅对加密及签名技术进行研究,如有侵权,请联系删除。</strong></p>
<h1 id=toc-1>详细过程</h1>
<p>测试环境:mumu 模拟器、<code>Magisk</code>、<code>Lsposed</code></p>
<h2 id=toc-2>初探签名及加密</h2>
<p>APP 的 HTTPS 验证就不阐述了,常规方式均可绕过。</p>
<p>查看请求包,发现了 <code>MsgId</code>、<code>AppSign</code> 以及密文 <code>cTxt</code>:</p>
<p><a id=img0 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124025-f81e40fc-6b40-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124025-f81e40fc-6b40-1.png></a></p>
<p>修改 <code>MsgId</code>,返回 401,很明显做了请求签名:</p>
<p><a id=img1 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124029-fa49aaf6-6b40-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124029-fa49aaf6-6b40-1.png></a></p>
<h2 id=toc-3>加密分析</h2>
<p>这里 APP 采用了爱加密企业版加固,于是使用 <strong>算法助手Plus</strong> + frida 脚本脱壳,使用 <code>Jadx</code> 反编译,搜索关键词,发现没搜到:</p>
<p><a id=img2 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124034-fd974cc2-6b40-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124034-fd974cc2-6b40-1.png></a></p>
<p>随后翻了翻,发现代码都抽空了,到 native 层去了?似乎是没脱完整:</p>
<p><a id=img3 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124037-ff026830-6b40-1.png title><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124037-ff026830-6b40-1.png></a></p>
<p>求助某大佬帮忙脱了个壳,继续搜索关键词,找到两处,看到 ECB,莫非是常见的 <code>AES-ECB</code> 加密(心中窃喜):</p>
<p><a id=img4 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124042-01e88ef8-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124042-01e88ef8-6b41-1.png></a></p>
<p>跟进去:</p>
<p><a id=img5 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124046-04557642-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124046-04557642-6b41-1.png></a></p>
<p>继续跟 <code>encryptECB</code>:</p>
<p><a id=img6 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124050-06b34edc-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124050-06b34edc-6b41-1.png></a></p>
<p>跟进:</p>
<p><a id=img7 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124052-083ebd72-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124052-083ebd72-6b41-1.png></a></p>
<p>最终来到 <code>xxx.WbSM4Util$Companion</code> 类的 <code>encryptDataECB</code> 方法:</p>
<p><a id=img8 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124055-09daad80-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124055-09daad80-6b41-1.png></a></p>
<p>这是对应的解密函数:</p>
<p><a id=img9 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124057-0b4b9ada-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124057-0b4b9ada-6b41-1.png></a></p>
<p>接着看看加密函数中的关键部分 <code>WbSm4().encode()</code>,这个函数传入的就是明文的字节对象和长度,并没有密钥相关,最后做了一层 Base64:</p>
<div class=highlight><pre><span></span><span class=n>String</span> <span class=n>encodeToString</span> <span class=o>=</span> <span class=n>Base64</span><span class=o>.</span><span class=na>encodeToString</span><span class=o>(</span><span class=k>new</span> <span class=n>WbSm4</span><span class=o>().</span><span class=na>encode</span><span class=o>(</span><span class=n>bytes2</span><span class=o>.</span><span class=na>length</span><span class=o>,</span> <span class=n>bytes2</span><span class=o>),</span> <span class=mi>0</span><span class=o>,</span> <span class=n>bytes2</span><span class=o>.</span><span class=na>length</span><span class=o>,</span> <span class=mi>2</span><span class=o>);</span>
</pre></div>
<p>跟进 <code>WbSm4</code> 一探究竟,发现是 native 的:</p>
<p><a id=img10 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124101-0db6a45e-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124101-0db6a45e-6b41-1.png></a></p>
<p>网上搜寻一下看看是什么,似乎是 <code>SM4</code> 国密:</p>
<p><a id=img11 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124105-0fd41ad2-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124105-0fd41ad2-6b41-1.png></a></p>
<p>问一下 <code>GPT</code>,白盒 <code>SM4</code> 是什么,看起来是很难复现的算法,密钥也很难提取,后续可能需要采用 RPC 远程调用 :</p>
<p><a id=img12 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124108-11e422e0-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124108-11e422e0-6b41-1.png></a></p>
<p>根据上面的代码分析简单画一个图:</p>
<p><a id=img13 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124111-1332ddf8-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124111-1332ddf8-6b41-1.png></a></p>
<h2 id=toc-4>签名分析</h2>
<p>接下来看看签名,搜索签名关键词 <code>appsign</code>:</p>
<p><a id=img14 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124114-14f116f0-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124114-14f116f0-6b41-1.png></a></p>
<p>跟进第一个的 <code>WelfareTaskRequestService.APPSIGN</code>,是个常量:</p>
<p><a id=img15 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124118-177d3ca0-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124118-177d3ca0-6b41-1.png></a></p>
<p>搜索常量名,看看哪一处使用了它,这里发现第二个是添加请求头,比较可疑:</p>
<p><a id=img16 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124122-1a054d78-6b41-1.png title><img src=data:, title data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124122-1a054d78-6b41-1.png></a></p>
<p>跟进代码如下:</p>
<div class=highlight><pre><span></span><span class=n>String</span> <span class=n>uuid</span> <span class=o>=</span> <span class=n>UUID</span><span class=o>.</span><span class=na>randomUUID</span><span class=o>().</span><span class=na>toString</span><span class=o>();</span>
<span class=n>Request</span><span class=o>.</span><span class=na>Builder</span> <span class=n>addHeader</span> <span class=o>=</span> <span class=k>new</span> <span class=n>Request</span><span class=o>.</span><span class=na>Builder</span><span class=o>().</span><span class=na>url</span><span class=o>(</span><span class=n>ServiceUrls</span><span class=o>.</span><span class=na>getAccessKeyListUrl</span><span class=o>(</span><span class=n>ServerInfoMgr</span><span class=o>.</span><span class=na>getInstance</span><span class=o>().</span><span class=na>getDefaultServerInfo</span><span class=o>(</span><span class=mi>204</span><span class=o>))).</span><span class=na>addHeader</span><span class=o>(</span><span class=n>RemoteMessageConst</span><span class=o>.</span><span class=na>MSGID</span><span class=o>,</span> <span class=n>uuid</span><span class=o>).</span><span class=na>addHeader</span><span class=o>(</span><span class=s>"deviceId"</span><span class=o>,</span> <span class=n>SysConfigs</span><span class=o>.</span><span class=na>DEVICE_ID</span><span class=o>).</span><span class=na>addHeader</span><span class=o>(</span><span class=s>"agent"</span><span class=o>,</span> <span class=s>"android-"</span> <span class=o>+</span> <span class=n>YBHelper</span><span class=o>.</span><span class=na>getAppVersionName</span><span class=o>()).</span><span class=na>addHeader</span><span class=o>(</span><span class=n>WelfareTaskRequestService</span><span class=o>.</span><span class=na>APPSIGN</span><span class=o>,</span> <span class=n>HeaderUtils</span><span class=o>.</span><span class=na>generateAppSign</span><span class=o>(</span><span class=n>ServiceUrls</span><span class=o>.</span><span class=na>getAccessKeyListUrl</span><span class=o>(</span><span class=n>ServerInfoMgr</span><span class=o>.</span><span class=na>getInstance</span><span class=o>().</span><span class=na>getDefaultServerInfo</span><span class=o>(</span><span class=mi>204</span><span class=o>)),</span> <span class=n>uuid</span><span class=o>,</span> <span class=n>HeaderUtils</span><span class=o>.</span><span class=na>requestBodyToString</span><span class=o>(</span><span class=n>create</span><span class=o>)));</span>
</pre></div>
<p>分析上面代码可知,<code>RemoteMessageConst.MSGID</code> 是个字符串常量,值为"MsgId",而签名是由静态方法 <code>HeaderUtils.generateAppSign(url,uuid.requestBody)</code> 生成的,其中三个参数分别为:完整 URL、UUID、完整请求 Body,可以看出请求 body 与 <code>msgid</code> 和 <code>appsign</code> 强相关,任何一个参数错误都可能导致请求不合法,以下是简单示意图:</p>
<p><a id=img17 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124127-1cbb2bf0-6b41-1.png title><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124127-1cbb2bf0-6b41-1.png></a></p>
<h2 id=toc-5>Xposed RPC 实现</h2>
<p>加密和签名都分析完毕,剩下的就是使用 RPC (远程过程调用)了,也就是注入代码,这里我用的是 <code>Xposed</code> 框架,没有检测,但 <code>frida</code> 有检测,过检测的方式参考下方公众号的文章(理论无脑过爱加密企业版),自己试了下确实可以:</p>
<p><a href=https://mp.weixin.qq.com/s/34c5JVJzSCEfqlPanV1FtA target=_blank>https://mp.weixin.qq.com/s/34c5JVJzSCEfqlPanV1FtA</a></p>
<p>对 <code>Xposed</code> 的 RPC 不太熟悉,网上查阅资料,找到如下文章:</p>
<p><a href=https://www.52pojie.cn/thread-1519322-1-1.html target=_blank>https://www.52pojie.cn/thread-1519322-1-1.html</a></p>
<p>发现使用 <code>NanoHTTPD</code> 在 APP 内部起一个 HTTP 服务器来与外部通信来实现 RPC 比较方便,写一个 demo,代码可以直接运行,会开启一个 50000 端口的 HTTP 服务器,开放 <code>/encrypt</code> 接口用于加密数据和生成签名,<code>/decrypt</code> 接口用于解密数据:</p>
<div class=highlight><pre><span></span><span class=kn>import</span> <span class=nn>com.google.gson.JsonObject</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>fi.iki.elonen.NanoHTTPD</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>java.io.IOException</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>java.util.HashMap</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>java.util.Map</span><span class=o>;</span>
<span class=kd>class</span> <span class=nc>HTTPServer</span> <span class=kd>extends</span> <span class=n>NanoHTTPD</span> <span class=o>{</span>
<span class=kd>public</span> <span class=nf>HTTPServer</span><span class=o>(</span><span class=kt>int</span> <span class=n>port</span><span class=o>)</span> <span class=o>{</span>
<span class=kd>super</span><span class=o>(</span><span class=n>port</span><span class=o>);</span>
<span class=o>}</span>
<span class=nd>@Override</span>
<span class=kd>public</span> <span class=n>Response</span> <span class=nf>serve</span><span class=o>(</span><span class=n>IHTTPSession</span> <span class=n>session</span><span class=o>)</span> <span class=o>{</span>
<span class=n>JsonObject</span> <span class=n>responseJson</span> <span class=o>=</span> <span class=k>new</span> <span class=n>JsonObject</span><span class=o>();</span>
<span class=n>String</span> <span class=n>encryptData</span> <span class=o>=</span> <span class=s>""</span><span class=o>;</span>
<span class=n>String</span> <span class=n>decryptData</span> <span class=o>=</span> <span class=s>""</span><span class=o>;</span>
<span class=n>Map</span><span class=o>&lt;</span><span class=n>String</span><span class=o>,</span> <span class=n>String</span><span class=o>&gt;</span> <span class=n>map</span> <span class=o>=</span> <span class=k>new</span> <span class=n>HashMap</span><span class=o>&lt;&gt;();</span>
<span class=k>try</span> <span class=o>{</span>
<span class=n>session</span><span class=o>.</span><span class=na>parseBody</span><span class=o>(</span><span class=n>map</span><span class=o>);</span>
<span class=o>}</span> <span class=k>catch</span> <span class=o>(</span><span class=n>Exception</span> <span class=n>e</span><span class=o>)</span> <span class=o>{</span>
<span class=k>return</span> <span class=n>newFixedLengthResponse</span><span class=o>(</span><span class=n>Response</span><span class=o>.</span><span class=na>Status</span><span class=o>.</span><span class=na>INTERNAL_ERROR</span><span class=o>,</span> <span class=s>"text/plain"</span><span class=o>,</span> <span class=n>e</span><span class=o>.</span><span class=na>getMessage</span><span class=o>());</span>
<span class=o>}</span>
<span class=k>if</span> <span class=o>(</span><span class=n>session</span><span class=o>.</span><span class=na>getMethod</span><span class=o>()</span> <span class=o>==</span> <span class=n>Method</span><span class=o>.</span><span class=na>POST</span><span class=o>)</span> <span class=o>{</span>
<span class=k>switch</span> <span class=o>(</span><span class=n>session</span><span class=o>.</span><span class=na>getUri</span><span class=o>())</span> <span class=o>{</span>
<span class=k>case</span> <span class=s>"/encrypt"</span><span class=o>:</span>
<span class=n>responseJson</span><span class=o>.</span><span class=na>addProperty</span><span class=o>(</span><span class=s>"encryptData"</span><span class=o>,</span> <span class=n>encryptData</span><span class=o>);</span>
<span class=k>return</span> <span class=n>newFixedLengthResponse</span><span class=o>(</span><span class=n>Response</span><span class=o>.</span><span class=na>Status</span><span class=o>.</span><span class=na>OK</span><span class=o>,</span> <span class=s>"application/json"</span><span class=o>,</span> <span class=n>responseJson</span><span class=o>.</span><span class=na>toString</span><span class=o>());</span>
<span class=k>case</span> <span class=s>"/decrypt"</span><span class=o>:</span>
<span class=n>responseJson</span><span class=o>.</span><span class=na>addProperty</span><span class=o>(</span><span class=s>"decryptData"</span><span class=o>,</span> <span class=n>decryptData</span><span class=o>);</span>
<span class=k>return</span> <span class=n>newFixedLengthResponse</span><span class=o>(</span><span class=n>Response</span><span class=o>.</span><span class=na>Status</span><span class=o>.</span><span class=na>OK</span><span class=o>,</span> <span class=s>"application/json"</span><span class=o>,</span> <span class=n>responseJson</span><span class=o>.</span><span class=na>toString</span><span class=o>());</span>
<span class=k>default</span><span class=o>:</span>
<span class=k>return</span> <span class=n>newFixedLengthResponse</span><span class=o>(</span><span class=n>Response</span><span class=o>.</span><span class=na>Status</span><span class=o>.</span><span class=na>NOT_FOUND</span><span class=o>,</span> <span class=s>"text/plain"</span><span class=o>,</span> <span class=s>"Not Found"</span><span class=o>);</span>
<span class=o>}</span>
<span class=o>}</span> <span class=k>else</span> <span class=o>{</span>
<span class=k>return</span> <span class=n>newFixedLengthResponse</span><span class=o>(</span><span class=n>Response</span><span class=o>.</span><span class=na>Status</span><span class=o>.</span><span class=na>NOT_FOUND</span><span class=o>,</span> <span class=s>"text/plain"</span><span class=o>,</span> <span class=s>"Not Found"</span><span class=o>);</span>
<span class=o>}</span>
<span class=o>}</span>
<span class=o>}</span>
<span class=kd>public</span> <span class=kd>class</span> <span class=nc>Demo</span> <span class=o>{</span>
<span class=kd>public</span> <span class=kd>static</span> <span class=kt>void</span> <span class=nf>main</span><span class=o>(</span><span class=n>String</span><span class=o>[]</span> <span class=n>args</span><span class=o>)</span> <span class=kd>throws</span> <span class=n>IOException</span> <span class=o>{</span>
<span class=n>HTTPServer</span> <span class=n>httpServer</span> <span class=o>=</span> <span class=k>new</span> <span class=n>HTTPServer</span><span class=o>(</span><span class=mi>50000</span><span class=o>);</span>
<span class=n>httpServer</span><span class=o>.</span><span class=na>start</span><span class=o>(</span><span class=n>NanoHTTPD</span><span class=o>.</span><span class=na>SOCKET_READ_TIMEOUT</span><span class=o>,</span> <span class=kc>false</span><span class=o>);</span>
<span class=o>}</span>
<span class=o>}</span>
</pre></div>
<p>Xposed 模块使用的模板:<a href=https://github.com/yinsel/XposedProjectTemplate target=_blank>https://github.com/yinsel/XposedProjectTemplate</a></p>
<p>完整 <code>Xposed</code> 代码实现如下(代码写的有点烂,勿喷):</p>
<div class=highlight><pre><span></span><span class=kn>package</span> <span class=nn>com.example.xposed</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>android.util.Log</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>com.google.gson.JsonObject</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>com.google.gson.JsonParser</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>java.io.IOException</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>java.lang.reflect.Constructor</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>java.lang.reflect.InvocationTargetException</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>java.lang.reflect.Method</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>java.util.HashMap</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>java.util.Map</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>java.util.UUID</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>de.robv.android.xposed.IXposedHookLoadPackage</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>de.robv.android.xposed.callbacks.XC_LoadPackage</span><span class=o>;</span>
<span class=kn>import</span> <span class=nn>fi.iki.elonen.NanoHTTPD</span><span class=o>;</span>
<span class=kd>public</span> <span class=kd>class</span> <span class=nc>Hooker</span> <span class=kd>implements</span> <span class=n>IXposedHookLoadPackage</span> <span class=o>{</span>
<span class=kd>private</span> <span class=n>HTTPServer</span> <span class=n>httpServer</span> <span class=o>=</span> <span class=k>new</span> <span class=n>HTTPServer</span><span class=o>(</span><span class=mi>50000</span><span class=o>);</span>
<span class=nd>@Override</span>
<span class=kd>public</span> <span class=kt>void</span> <span class=nf>handleLoadPackage</span><span class=o>(</span><span class=n>XC_LoadPackage</span><span class=o>.</span><span class=na>LoadPackageParam</span> <span class=n>loadPackageParam</span><span class=o>)</span> <span class=kd>throws</span> <span class=n>Throwable</span> <span class=o>{</span>
<span class=k>try</span> <span class=o>{</span>
<span class=n>Class</span><span class=o>&lt;?&gt;</span> <span class=n>clazz</span> <span class=o>=</span> <span class=n>Class</span><span class=o>.</span><span class=na>forName</span><span class=o>(</span><span class=s>"xxx.WbSM4Util$Companion"</span><span class=o>,</span> <span class=kc>true</span><span class=o>,</span> <span class=n>loadPackageParam</span><span class=o>.</span><span class=na>classLoader</span><span class=o>);</span>
<span class=n>Method</span> <span class=n>methods</span><span class=o>[]</span> <span class=o>=</span> <span class=n>clazz</span><span class=o>.</span><span class=na>getDeclaredMethods</span><span class=o>();</span>
<span class=n>Constructor</span><span class=o>&lt;?&gt;</span> <span class=n>constructor</span> <span class=o>=</span> <span class=n>clazz</span><span class=o>.</span><span class=na>getDeclaredConstructor</span><span class=o>();</span>
<span class=n>constructor</span><span class=o>.</span><span class=na>setAccessible</span><span class=o>(</span><span class=kc>true</span><span class=o>);</span>
<span class=n>Crypto</span> <span class=n>crypto</span> <span class=o>=</span> <span class=k>new</span> <span class=n>Crypto</span><span class=o>();</span>
<span class=n>crypto</span><span class=o>.</span><span class=na>setClassLoader</span><span class=o>(</span><span class=n>loadPackageParam</span><span class=o>.</span><span class=na>classLoader</span><span class=o>);</span>
<span class=n>crypto</span><span class=o>.</span><span class=na>setObject</span><span class=o>(</span><span class=n>constructor</span><span class=o>.</span><span class=na>newInstance</span><span class=o>());</span>
<span class=k>for</span> <span class=o>(</span><span class=kt>int</span> <span class=n>i</span> <span class=o>=</span> <span class=mi>0</span><span class=o>;</span> <span class=n>i</span> <span class=o>&lt;</span> <span class=n>methods</span><span class=o>.</span><span class=na>length</span><span class=o>;</span> <span class=n>i</span><span class=o>++)</span> <span class=o>{</span>
<span class=k>if</span> <span class=o>(</span><span class=n>methods</span><span class=o>[</span><span class=n>i</span><span class=o>].</span><span class=na>getName</span><span class=o>().</span><span class=na>equals</span><span class=o>(</span><span class=s>"decryptDataECB"</span><span class=o>))</span> <span class=o>{</span>
<span class=n>methods</span><span class=o>[</span><span class=n>i</span><span class=o>].</span><span class=na>setAccessible</span><span class=o>(</span><span class=kc>true</span><span class=o>);</span>
<span class=n>crypto</span><span class=o>.</span><span class=na>setDecrypt</span><span class=o>(</span><span class=n>methods</span><span class=o>[</span><span class=n>i</span><span class=o>]);</span>
<span class=o>}</span>
<span class=k>if</span> <span class=o>(</span><span class=n>methods</span><span class=o>[</span><span class=n>i</span><span class=o>].</span><span class=na>getName</span><span class=o>().</span><span class=na>equals</span><span class=o>(</span><span class=s>"encryptDataECB"</span><span class=o>))</span> <span class=o>{</span>
<span class=n>methods</span><span class=o>[</span><span class=n>i</span><span class=o>].</span><span class=na>setAccessible</span><span class=o>(</span><span class=kc>true</span><span class=o>);</span>
<span class=n>crypto</span><span class=o>.</span><span class=na>setEncrypt</span><span class=o>(</span><span class=n>methods</span><span class=o>[</span><span class=n>i</span><span class=o>]);</span>
<span class=o>}</span>
<span class=o>}</span>
<span class=k>if</span> <span class=o>(</span><span class=n>crypto</span><span class=o>.</span><span class=na>getEncrypt</span><span class=o>()</span> <span class=o>!=</span> <span class=kc>null</span> <span class=o>&amp;&amp;</span> <span class=n>crypto</span><span class=o>.</span><span class=na>getDecrypt</span><span class=o>()</span> <span class=o>!=</span> <span class=kc>null</span><span class=o>)</span> <span class=o>{</span>
<span class=k>this</span><span class=o>.</span><span class=na>httpServer</span><span class=o>.</span><span class=na>setCrypto</span><span class=o>(</span><span class=n>crypto</span><span class=o>);</span>
<span class=n>startHttpServer</span><span class=o>();</span>
<span class=o>}</span>
<span class=o>}</span> <span class=k>catch</span> <span class=o>(</span><span class=n>Exception</span> <span class=n>e</span><span class=o>)</span> <span class=o>{</span>
<span class=n>Log</span><span class=o>(</span><span class=n>e</span><span class=o>.</span><span class=na>toString</span><span class=o>());</span>
<span class=o>}</span>
<span class=o>}</span>
<span class=kd>private</span> <span class=kd>static</span> <span class=kt>void</span> <span class=nf>Log</span><span class=o>(</span><span class=n>String</span> <span class=n>msg</span><span class=o>)</span> <span class=o>{</span>
<span class=n>Log</span><span class=o>.</span><span class=na>v</span><span class=o>(</span><span class=s>"Xposed"</span><span class=o>,</span> <span class=n>msg</span><span class=o>);</span>
<span class=o>}</span>
<span class=kd>private</span> <span class=kt>void</span> <span class=nf>startHttpServer</span><span class=o>()</span> <span class=o>{</span>
<span class=k>if</span> <span class=o>(</span><span class=n>httpServer</span> <span class=o>!=</span> <span class=kc>null</span> <span class=o>&amp;&amp;</span> <span class=n>httpServer</span><span class=o>.</span><span class=na>getCrypto</span><span class=o>()</span> <span class=o>!=</span> <span class=kc>null</span><span class=o>)</span> <span class=o>{</span>
<span class=k>new</span> <span class=n>Thread</span><span class=o>(()</span> <span class=o>-&gt;</span> <span class=o>{</span>
<span class=k>try</span> <span class=o>{</span>
<span class=n>httpServer</span><span class=o>.</span><span class=na>start</span><span class=o>(</span><span class=n>NanoHTTPD</span><span class=o>.</span><span class=na>SOCKET_READ_TIMEOUT</span><span class=o>,</span> <span class=kc>false</span><span class=o>);</span>
<span class=n>Log</span><span class=o>(</span><span class=s>"HTTP Server started on port "</span> <span class=o>+</span> <span class=n>httpServer</span><span class=o>.</span><span class=na>getListeningPort</span><span class=o>());</span>
<span class=o>}</span> <span class=k>catch</span> <span class=o>(</span><span class=n>IOException</span> <span class=n>e</span><span class=o>)</span> <span class=o>{</span>
<span class=n>Log</span><span class=o>(</span><span class=s>"Error starting HTTP Server: "</span> <span class=o>+</span> <span class=n>e</span><span class=o>.</span><span class=na>toString</span><span class=o>());</span>
<span class=o>}</span>
<span class=o>}).</span><span class=na>start</span><span class=o>();</span>
<span class=o>}</span>
<span class=o>}</span>
<span class=kd>public</span> <span class=kd>static</span> <span class=kd>class</span> <span class=nc>HTTPServer</span> <span class=kd>extends</span> <span class=n>NanoHTTPD</span> <span class=o>{</span>
<span class=kd>private</span> <span class=n>Crypto</span> <span class=n>crypto</span><span class=o>;</span>
<span class=kd>public</span> <span class=nf>HTTPServer</span><span class=o>(</span><span class=kt>int</span> <span class=n>port</span><span class=o>)</span> <span class=o>{</span>
<span class=kd>super</span><span class=o>(</span><span class=n>port</span><span class=o>);</span>
<span class=o>}</span>
<span class=kd>public</span> <span class=n>Crypto</span> <span class=nf>getCrypto</span><span class=o>()</span> <span class=o>{</span>
<span class=k>return</span> <span class=n>crypto</span><span class=o>;</span>
<span class=o>}</span>
<span class=kd>public</span> <span class=kt>void</span> <span class=nf>setCrypto</span><span class=o>(</span><span class=n>Crypto</span> <span class=n>crypto</span><span class=o>)</span> <span class=o>{</span>
<span class=k>this</span><span class=o>.</span><span class=na>crypto</span> <span class=o>=</span> <span class=n>crypto</span><span class=o>;</span>
<span class=o>}</span>
<span class=nd>@Override</span>
<span class=kd>public</span> <span class=n>Response</span> <span class=nf>serve</span><span class=o>(</span><span class=n>IHTTPSession</span> <span class=n>session</span><span class=o>)</span> <span class=o>{</span>
<span class=n>JsonObject</span> <span class=n>responseJson</span> <span class=o>=</span> <span class=k>new</span> <span class=n>JsonObject</span><span class=o>();</span>
<span class=n>JsonObject</span> <span class=n>body</span> <span class=o>=</span> <span class=k>new</span> <span class=n>JsonObject</span><span class=o>();</span>
<span class=n>Map</span><span class=o>&lt;</span><span class=n>String</span><span class=o>,</span> <span class=n>String</span><span class=o>&gt;</span> <span class=n>map</span> <span class=o>=</span> <span class=k>new</span> <span class=n>HashMap</span><span class=o>&lt;&gt;();</span>
<span class=k>try</span> <span class=o>{</span>
<span class=n>session</span><span class=o>.</span><span class=na>parseBody</span><span class=o>(</span><span class=n>map</span><span class=o>);</span>
<span class=n>String</span> <span class=n>data</span><span class=o>;</span>
<span class=k>if</span> <span class=o>(</span><span class=n>session</span><span class=o>.</span><span class=na>getMethod</span><span class=o>()</span> <span class=o>==</span> <span class=n>Method</span><span class=o>.</span><span class=na>POST</span><span class=o>)</span> <span class=o>{</span>
<span class=n>body</span> <span class=o>=</span> <span class=n>JsonParser</span><span class=o>.</span><span class=na>parseString</span><span class=o>(</span><span class=n>map</span><span class=o>.</span><span class=na>get</span><span class=o>(</span><span class=s>"postData"</span><span class=o>)).</span><span class=na>getAsJsonObject</span><span class=o>();</span>
<span class=k>switch</span> <span class=o>(</span><span class=n>session</span><span class=o>.</span><span class=na>getUri</span><span class=o>())</span> <span class=o>{</span>
<span class=k>case</span> <span class=s>"/encrypt"</span><span class=o>:</span>
<span class=c1>// 从BurpGuard拿到需要加密的数据data以及签名需要的url</span>
<span class=n>data</span> <span class=o>=</span> <span class=n>body</span><span class=o>.</span><span class=na>get</span><span class=o>(</span><span class=s>"data"</span><span class=o>).</span><span class=na>getAsString</span><span class=o>();</span>
<span class=n>String</span> <span class=n>url</span> <span class=o>=</span> <span class=n>body</span><span class=o>.</span><span class=na>get</span><span class=o>(</span><span class=s>"url"</span><span class=o>).</span><span class=na>getAsString</span><span class=o>();</span>
<span class=c1>// 反射获取需要的方法</span>
<span class=n>Class</span><span class=o>&lt;?&gt;</span> <span class=n>headerUtil</span> <span class=o>=</span> <span class=n>Class</span><span class=o>.</span><span class=na>forName</span><span class=o>(</span><span class=s>"xxx.HeaderUtils"</span><span class=o>,</span> <span class=kc>false</span><span class=o>,</span> <span class=n>crypto</span><span class=o>.</span><span class=na>getClassLoader</span><span class=o>());</span>
<span class=n>java</span><span class=o>.</span><span class=na>lang</span><span class=o>.</span><span class=na>reflect</span><span class=o>.</span><span class=na>Method</span> <span class=n>generateAppSign</span> <span class=o>=</span> <span class=n>headerUtil</span><span class=o>.</span><span class=na>getDeclaredMethod</span><span class=o>(</span><span class=s>"generateAppSign"</span><span class=o>,</span> <span class=n>String</span><span class=o>.</span><span class=na>class</span><span class=o>,</span> <span class=n>String</span><span class=o>.</span><span class=na>class</span><span class=o>,</span> <span class=n>String</span><span class=o>.</span><span class=na>class</span><span class=o>);</span>
<span class=n>generateAppSign</span><span class=o>.</span><span class=na>setAccessible</span><span class=o>(</span><span class=kc>true</span><span class=o>);</span>
<span class=c1>// 对数据进行加密</span>
<span class=n>String</span> <span class=n>encryptData</span> <span class=o>=</span> <span class=k>this</span><span class=o>.</span><span class=na>crypto</span><span class=o>.</span><span class=na>getEncrypt</span><span class=o>().</span><span class=na>invoke</span><span class=o>(</span><span class=n>crypto</span><span class=o>.</span><span class=na>getObject</span><span class=o>(),</span> <span class=n>data</span><span class=o>,</span> <span class=kc>false</span><span class=o>).</span><span class=na>toString</span><span class=o>();</span>
<span class=n>JsonObject</span> <span class=n>jsondata</span> <span class=o>=</span> <span class=k>new</span> <span class=n>JsonObject</span><span class=o>();</span>
<span class=n>jsondata</span><span class=o>.</span><span class=na>addProperty</span><span class=o>(</span><span class=s>"cTxt"</span><span class=o>,</span> <span class=n>encryptData</span><span class=o>);</span>
<span class=n>String</span> <span class=n>uuid</span> <span class=o>=</span> <span class=n>UUID</span><span class=o>.</span><span class=na>randomUUID</span><span class=o>().</span><span class=na>toString</span><span class=o>();</span>
<span class=c1>// 获取参数签名 </span>
<span class=n>String</span> <span class=n>appsign</span> <span class=o>=</span> <span class=n>generateAppSign</span><span class=o>.</span><span class=na>invoke</span><span class=o>(</span><span class=kc>null</span><span class=o>,</span> <span class=n>url</span><span class=o>,</span> <span class=n>uuid</span><span class=o>,</span> <span class=n>jsondata</span><span class=o>.</span><span class=na>toString</span><span class=o>()).</span><span class=na>toString</span><span class=o>();</span>
<span class=c1>// 添加签名至响应JSON</span>
<span class=n>responseJson</span><span class=o>.</span><span class=na>addProperty</span><span class=o>(</span><span class=s>"msgid"</span><span class=o>,</span> <span class=n>uuid</span><span class=o>);</span>
<span class=n>responseJson</span><span class=o>.</span><span class=na>addProperty</span><span class=o>(</span><span class=s>"appsign"</span><span class=o>,</span> <span class=n>appsign</span><span class=o>);</span>
<span class=c1>// 添加加密数据</span>
<span class=n>responseJson</span><span class=o>.</span><span class=na>addProperty</span><span class=o>(</span><span class=s>"encryptData"</span><span class=o>,</span> <span class=n>encryptData</span><span class=o>);</span>
<span class=k>return</span> <span class=n>newFixedLengthResponse</span><span class=o>(</span><span class=n>Response</span><span class=o>.</span><span class=na>Status</span><span class=o>.</span><span class=na>OK</span><span class=o>,</span> <span class=s>"application/json"</span><span class=o>,</span> <span class=n>responseJson</span><span class=o>.</span><span class=na>toString</span><span class=o>());</span>
<span class=k>case</span> <span class=s>"/decrypt"</span><span class=o>:</span>
<span class=c1>// 获取需要解密的数据</span>
<span class=n>data</span> <span class=o>=</span> <span class=n>body</span><span class=o>.</span><span class=na>get</span><span class=o>(</span><span class=s>"data"</span><span class=o>).</span><span class=na>getAsString</span><span class=o>();</span>
<span class=c1>// 解密数据</span>
<span class=n>String</span> <span class=n>decryptData</span> <span class=o>=</span> <span class=k>this</span><span class=o>.</span><span class=na>crypto</span><span class=o>.</span><span class=na>getDecrypt</span><span class=o>().</span><span class=na>invoke</span><span class=o>(</span><span class=n>crypto</span><span class=o>.</span><span class=na>getObject</span><span class=o>(),</span> <span class=n>data</span><span class=o>,</span> <span class=kc>false</span><span class=o>).</span><span class=na>toString</span><span class=o>();</span>
<span class=n>responseJson</span><span class=o>.</span><span class=na>addProperty</span><span class=o>(</span><span class=s>"decryptData"</span><span class=o>,</span> <span class=n>decryptData</span><span class=o>);</span>
<span class=k>return</span> <span class=n>newFixedLengthResponse</span><span class=o>(</span><span class=n>Response</span><span class=o>.</span><span class=na>Status</span><span class=o>.</span><span class=na>OK</span><span class=o>,</span> <span class=s>"application/json"</span><span class=o>,</span> <span class=n>responseJson</span><span class=o>.</span><span class=na>toString</span><span class=o>());</span>
<span class=k>default</span><span class=o>:</span>
<span class=k>return</span> <span class=n>newFixedLengthResponse</span><span class=o>(</span><span class=n>Response</span><span class=o>.</span><span class=na>Status</span><span class=o>.</span><span class=na>NOT_FOUND</span><span class=o>,</span> <span class=s>"text/plain"</span><span class=o>,</span> <span class=s>"Not Found"</span><span class=o>);</span>
<span class=o>}</span>
<span class=o>}</span> <span class=k>else</span> <span class=o>{</span>
<span class=k>return</span> <span class=n>newFixedLengthResponse</span><span class=o>(</span><span class=n>Response</span><span class=o>.</span><span class=na>Status</span><span class=o>.</span><span class=na>NOT_FOUND</span><span class=o>,</span> <span class=s>"text/plain"</span><span class=o>,</span> <span class=s>"Not Found"</span><span class=o>);</span>
<span class=o>}</span>
<span class=o>}</span> <span class=k>catch</span> <span class=o>(</span><span class=n>InvocationTargetException</span> <span class=n>e</span><span class=o>)</span> <span class=o>{</span>
<span class=n>Log</span><span class=o>(</span><span class=n>e</span><span class=o>.</span><span class=na>getCause</span><span class=o>().</span><span class=na>fillInStackTrace</span><span class=o>().</span><span class=na>toString</span><span class=o>());</span>
<span class=k>return</span> <span class=n>newFixedLengthResponse</span><span class=o>(</span><span class=n>Response</span><span class=o>.</span><span class=na>Status</span><span class=o>.</span><span class=na>BAD_REQUEST</span><span class=o>,</span> <span class=s>"text/plain"</span><span class=o>,</span> <span class=s>"Invalid JSON data"</span><span class=o>);</span>
<span class=o>}</span> <span class=k>catch</span> <span class=o>(</span><span class=n>Exception</span> <span class=n>e</span><span class=o>)</span> <span class=o>{</span>
<span class=n>Log</span><span class=o>(</span><span class=n>e</span><span class=o>.</span><span class=na>getCause</span><span class=o>().</span><span class=na>fillInStackTrace</span><span class=o>().</span><span class=na>toString</span><span class=o>());</span>
<span class=o>}</span>
<span class=k>return</span> <span class=n>newFixedLengthResponse</span><span class=o>(</span><span class=n>Response</span><span class=o>.</span><span class=na>Status</span><span class=o>.</span><span class=na>INTERNAL_ERROR</span><span class=o>,</span> <span class=s>"text/plain"</span><span class=o>,</span> <span class=s>"Invalid Request"</span><span class=o>);</span>
<span class=o>}</span>
<span class=o>}</span>
<span class=o>}</span>
</pre></div>
<p>连接 ADB 将模拟器端口转发出来:</p>
<pre><code>adb forward tcp:50000 tcp:50000</code></pre>
<p>测试 APP 内部的 HTTP 服务器是否启动,成功启动:</p>
<p><a id=img18 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124139-23f7b320-6b41-1.png title><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124139-23f7b320-6b41-1.png></a></p>
<p>接口测试,这里使用的是 <code>Reqable</code>,测试解密接口:</p>
<p><a id=img19 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124141-25838a66-6b41-1.png title><img src=data:, title data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124141-25838a66-6b41-1.png></a></p>
<p>测试加密接口,获取加密数据和签名,可以看到加密的数据一致:</p>
<p><a id=img20 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124144-275a2304-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124144-275a2304-6b41-1.png></a></p>
<p>尝试替换获取的签名并发送测试,成功:</p>
<p><a id=img21 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124205-33aff23c-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124205-33aff23c-6b41-1.png></a></p>
<h2 id=toc-6>BurpGuard 实现</h2>
<p>BurpGuard 项目地址:<a href=https://github.com/yinsel/BurpGuard target=_blank>https://github.com/yinsel/BurpGuard</a></p>
<p>这里画一个示意图以便分析和理解:</p>
<p><a id=img22 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124208-3554e0ca-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124208-3554e0ca-6b41-1.png></a></p>
<p>完整代码如下:</p>
<p>ClientProxyHandler:</p>
<div class=highlight><pre><span></span><span class=kn>from</span> <span class=nn>mitmproxy</span> <span class=kn>import</span> <span class=n>http</span>
<span class=kn>from</span> <span class=nn>Utils.Crypto</span> <span class=kn>import</span> <span class=o>*</span>
<span class=kn>import</span> <span class=nn>httpx</span>
<span class=kn>from</span> <span class=nn>base64</span> <span class=kn>import</span> <span class=n>b64encode</span><span class=p>,</span><span class=n>b64decode</span>
<span class=kn>from</span> <span class=nn>urllib.parse</span> <span class=kn>import</span> <span class=n>quote</span><span class=p>,</span><span class=n>unquote</span>
<span class=kn>import</span> <span class=nn>json</span>
<span class=kn>import</span> <span class=nn>traceback</span>
<span class=k>class</span> <span class=nc>ClientProxyHandler</span><span class=p>:</span>
<span class=k>def</span> <span class=fm>__init__</span><span class=p>(</span><span class=bp>self</span><span class=p>)</span> <span class=o>-&gt;</span> <span class=bp>None</span><span class=p>:</span>
<span class=bp>self</span><span class=o>.</span><span class=n>client</span> <span class=o>=</span> <span class=n>httpx</span><span class=o>.</span><span class=n>Client</span><span class=p>(</span><span class=n>timeout</span><span class=o>=</span><span class=bp>None</span><span class=p>,</span><span class=n>verify</span><span class=o>=</span><span class=bp>False</span><span class=p>)</span>
<span class=c1># 处理来自客户端的请求,通常在这里对请求进行解密</span>
<span class=k>def</span> <span class=nf>request</span><span class=p>(</span><span class=bp>self</span><span class=p>,</span><span class=n>flow</span><span class=p>:</span> <span class=n>http</span><span class=o>.</span><span class=n>HTTPFlow</span><span class=p>):</span>
<span class=k>try</span><span class=p>:</span>
<span class=n>req</span> <span class=o>=</span> <span class=n>flow</span><span class=o>.</span><span class=n>request</span> <span class=c1># 获取请求对象</span>
<span class=c1># 在这里编写你的代码</span>
<span class=c1># ...</span>
<span class=k>if</span> <span class=n>req</span><span class=o>.</span><span class=n>method</span> <span class=o>==</span> <span class=s2>"POST"</span> <span class=ow>and</span> <span class=s2>"json"</span> <span class=ow>in</span> <span class=n>req</span><span class=o>.</span><span class=n>headers</span><span class=p>[</span><span class=s2>"Content-Type"</span><span class=p>]</span> <span class=ow>and</span> <span class=s2>"</span><span class=se>\"</span><span class=s2>cTxt</span><span class=se>\"</span><span class=s2>"</span> <span class=ow>in</span> <span class=n>req</span><span class=o>.</span><span class=n>text</span><span class=p>:</span>
<span class=n>json_data</span> <span class=o>=</span> <span class=n>req</span><span class=o>.</span><span class=n>json</span><span class=p>()</span>
<span class=n>result</span> <span class=o>=</span> <span class=bp>self</span><span class=o>.</span><span class=n>client</span><span class=o>.</span><span class=n>post</span><span class=p>(</span><span class=s2>"http://127.0.0.1:50000/decrypt"</span><span class=p>,</span> <span class=n>json</span><span class=o>=</span><span class=p>{</span><span class=s2>"data"</span><span class=p>:</span> <span class=n>json_data</span><span class=p>[</span><span class=s2>"cTxt"</span><span class=p>]})</span><span class=o>.</span><span class=n>json</span><span class=p>()</span>
<span class=n>req</span><span class=o>.</span><span class=n>text</span> <span class=o>=</span> <span class=n>result</span><span class=p>[</span><span class=s2>"decryptData"</span><span class=p>]</span>
<span class=c1># 标记数据包需要由BurpProxyHandler来加密</span>
<span class=n>req</span><span class=o>.</span><span class=n>headers</span><span class=p>[</span><span class=s2>"burp"</span><span class=p>]</span> <span class=o>=</span> <span class=s2>"1"</span>
<span class=k>except</span> <span class=ne>Exception</span> <span class=k>as</span> <span class=n>e</span><span class=p>:</span>
<span class=n>traceback</span><span class=o>.</span><span class=n>print_exception</span><span class=p>(</span><span class=n>e</span><span class=p>)</span>
<span class=k>finally</span><span class=p>:</span>
<span class=k>return</span> <span class=n>flow</span>
<span class=c1># 处理返回给客户端的响应,通常在这里对响应进行解密</span>
<span class=k>def</span> <span class=nf>response</span><span class=p>(</span><span class=bp>self</span><span class=p>,</span><span class=n>flow</span><span class=p>:</span> <span class=n>http</span><span class=o>.</span><span class=n>HTTPFlow</span><span class=p>):</span>
<span class=k>try</span><span class=p>:</span>
<span class=n>req</span> <span class=o>=</span> <span class=n>flow</span><span class=o>.</span><span class=n>request</span> <span class=c1># 获取请求对象</span>
<span class=n>rsp</span> <span class=o>=</span> <span class=n>flow</span><span class=o>.</span><span class=n>response</span> <span class=c1># 获取响应对象</span>
<span class=c1># 在这里编写你的代码</span>
<span class=c1># ...</span>
<span class=k>except</span> <span class=ne>Exception</span> <span class=k>as</span> <span class=n>e</span><span class=p>:</span>
<span class=n>traceback</span><span class=o>.</span><span class=n>print_exception</span><span class=p>(</span><span class=n>e</span><span class=p>)</span>
<span class=k>finally</span><span class=p>:</span>
<span class=k>return</span> <span class=n>flow</span>
<span class=n>addons</span> <span class=o>=</span> <span class=p>[</span><span class=n>ClientProxyHandler</span><span class=p>()]</span>
</pre></div>
<p>BurpProxyHandler:</p>
<div class=highlight><pre><span></span><span class=kn>from</span> <span class=nn>mitmproxy</span> <span class=kn>import</span> <span class=n>http</span>
<span class=kn>from</span> <span class=nn>Utils.Crypto</span> <span class=kn>import</span> <span class=o>*</span>
<span class=kn>import</span> <span class=nn>httpx</span>
<span class=kn>from</span> <span class=nn>base64</span> <span class=kn>import</span> <span class=n>b64encode</span><span class=p>,</span><span class=n>b64decode</span>
<span class=kn>from</span> <span class=nn>urllib.parse</span> <span class=kn>import</span> <span class=n>quote</span><span class=p>,</span><span class=n>unquote</span>
<span class=kn>import</span> <span class=nn>json</span>
<span class=kn>import</span> <span class=nn>traceback</span>
<span class=k>class</span> <span class=nc>BurpProxyHandler</span><span class=p>:</span>
<span class=k>def</span> <span class=fm>__init__</span><span class=p>(</span><span class=bp>self</span><span class=p>)</span> <span class=o>-&gt;</span> <span class=bp>None</span><span class=p>:</span>
<span class=bp>self</span><span class=o>.</span><span class=n>client</span> <span class=o>=</span> <span class=n>httpx</span><span class=o>.</span><span class=n>Client</span><span class=p>(</span><span class=n>timeout</span><span class=o>=</span><span class=bp>None</span><span class=p>,</span><span class=n>verify</span><span class=o>=</span><span class=bp>False</span><span class=p>)</span>
<span class=c1># 处理来自Burp的请求,通常在这里对请求进行加密</span>
<span class=k>def</span> <span class=nf>request</span><span class=p>(</span><span class=bp>self</span><span class=p>,</span><span class=n>flow</span><span class=p>:</span> <span class=n>http</span><span class=o>.</span><span class=n>HTTPFlow</span><span class=p>):</span>
<span class=k>try</span><span class=p>:</span>
<span class=n>req</span> <span class=o>=</span> <span class=n>flow</span><span class=o>.</span><span class=n>request</span> <span class=c1># 获取请求对象</span>
<span class=c1># 在这里编写你的代码</span>
<span class=c1># ... </span>
<span class=c1># 判断数据包是否需要加密</span>
<span class=k>if</span> <span class=n>req</span><span class=o>.</span><span class=n>headers</span><span class=o>.</span><span class=n>get</span><span class=p>(</span><span class=s2>"burp"</span><span class=p>):</span>
<span class=n>json_data</span> <span class=o>=</span> <span class=n>req</span><span class=o>.</span><span class=n>json</span><span class=p>()</span>
<span class=n>result</span> <span class=o>=</span> <span class=bp>self</span><span class=o>.</span><span class=n>client</span><span class=o>.</span><span class=n>post</span><span class=p>(</span><span class=s2>"http://127.0.0.1:50000/encrypt"</span><span class=p>,</span> <span class=n>json</span><span class=o>=</span><span class=p>{</span><span class=s2>"data"</span><span class=p>:</span> <span class=n>req</span><span class=o>.</span><span class=n>text</span><span class=p>,</span><span class=s2>"url"</span><span class=p>:</span> <span class=n>req</span><span class=o>.</span><span class=n>url</span><span class=p>})</span><span class=o>.</span><span class=n>json</span><span class=p>()</span>
<span class=c1># 去除json字符串空格</span>
<span class=n>req</span><span class=o>.</span><span class=n>text</span> <span class=o>=</span> <span class=n>json</span><span class=o>.</span><span class=n>dumps</span><span class=p>({</span><span class=s2>"cTxt"</span><span class=p>:</span> <span class=n>result</span><span class=p>[</span><span class=s2>"encryptData"</span><span class=p>]},</span><span class=n>separators</span><span class=o>=</span><span class=p>(</span><span class=s1>','</span><span class=p>,</span> <span class=s1>':'</span><span class=p>))</span>
<span class=n>req</span><span class=o>.</span><span class=n>headers</span><span class=p>[</span><span class=s2>"msgid"</span><span class=p>]</span> <span class=o>=</span> <span class=n>result</span><span class=p>[</span><span class=s2>"msgid"</span><span class=p>]</span>
<span class=n>req</span><span class=o>.</span><span class=n>headers</span><span class=p>[</span><span class=s2>"appsign"</span><span class=p>]</span> <span class=o>=</span> <span class=n>result</span><span class=p>[</span><span class=s2>"appsign"</span><span class=p>]</span>
<span class=k>except</span> <span class=ne>Exception</span> <span class=k>as</span> <span class=n>e</span><span class=p>:</span>
<span class=n>traceback</span><span class=o>.</span><span class=n>print_exception</span><span class=p>(</span><span class=n>e</span><span class=p>)</span>
<span class=k>finally</span><span class=p>:</span>
<span class=k>return</span> <span class=n>flow</span>
<span class=c1># 处理返回给Burp的响应,通常在这里对响应进行解密</span>
<span class=k>def</span> <span class=nf>response</span><span class=p>(</span><span class=bp>self</span><span class=p>,</span><span class=n>flow</span><span class=p>:</span> <span class=n>http</span><span class=o>.</span><span class=n>HTTPFlow</span><span class=p>):</span>
<span class=k>try</span><span class=p>:</span>
<span class=n>req</span> <span class=o>=</span> <span class=n>flow</span><span class=o>.</span><span class=n>request</span> <span class=c1># 获取请求对象</span>
<span class=n>rsp</span> <span class=o>=</span> <span class=n>flow</span><span class=o>.</span><span class=n>response</span> <span class=c1># 获取响应对象</span>
<span class=c1># 在这里编写你的代码</span>
<span class=c1># ...</span>
<span class=k>except</span> <span class=ne>Exception</span> <span class=k>as</span> <span class=n>e</span><span class=p>:</span>
<span class=n>traceback</span><span class=o>.</span><span class=n>print_exception</span><span class=p>(</span><span class=n>e</span><span class=p>)</span>
<span class=k>finally</span><span class=p>:</span>
<span class=k>return</span> <span class=n>flow</span>
<span class=n>addons</span> <span class=o>=</span> <span class=p>[</span><span class=n>BurpProxyHandler</span><span class=p>()]</span>
</pre></div>
<h1 id=toc-7>最终效果</h1>
<p>模拟器安装编写的 <code>Xposed</code> 模块,使用 <code>Lsposed</code> 激活并勾选 APP。</p>
<p>运行 <code>BurpGuard</code>,并配置模拟器代理为 8081,也就是让 APP 首先走 <code>ClientProxyHandler</code>,同时 Burp 配置上游代理为 8082:</p>
<pre><code>python BurpGuard.py</code></pre>
<p><a id=img23 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124215-396862b8-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124215-396862b8-6b41-1.png></a></p>
<p><a id=img24 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124216-3a6bf1d4-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124216-3a6bf1d4-6b41-1.png></a></p>
<p>在模拟器操作 APP,并使用 Burp 拦截,可以看到请求 body 已经解密:</p>
<p><a id=img25 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124219-3c3de10c-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124219-3c3de10c-6b41-1.png></a></p>
<p>发送至重发器,并尝试修改请求 body,这里加了个单引号,请求正常:</p>
<p><a id=img26 href=https://xzfile.aliyuncs.com/media/upload/picture/20240905124223-3e1d3338-6b41-1.png><img src=data:, data-sf-original-src=https://xzfile.aliyuncs.com/media/upload/picture/20240905124223-3e1d3338-6b41-1.png></a></p>
<p>接下来就可以愉快的渗透啦!</p>
</div>
<div class=post-user-action style=margin-top:34px>
<span class="btn btn-default pull-right" id=mark data-action=topic data-pk=15533>
<span id=mark-text>点击收藏 </span><span class=i-seprator> | </span><span id=mark-count>0</span>
</span>
<span class="btn btn-default pull-right" id=follow_topic data-pk=15533>
<span>关注</span><span class=i-seprator> | </span><span id=follow-count>1</span>
</span>
<span class="btn btn-default pull-right">
<span>
<span id=ready_reward data-toggle=modal data-target=#myModal>打赏</span>
</span>
</span>
<div class=clearfix></div>
</div>
<div class=related-section>
<div class=related-box>
<span><a class=pull-left href=https://xz.aliyun.com/t/15532 title="NepCTF 2024(WEB)"><span class=related-label style="padding:3px 4px;margin-right:3px">上一篇:</span>NepCTF 2024(WEB)</a></span>
<span><a class=pull-left href=https://xz.aliyun.com/t/15534 title=初入代码审计之lmxcms代码执行><span class=related-label>下一篇:</span>初入代码审计之lmxcms代码执行</a></span>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id=myModal role=dialog aria-labelledby=myModalLabel aria-hidden=true>
<div class=modal-dialog>
<div class=modal-content>
<div class=modal-header>
<h4 class=modal-title id=myModalLabel style=text-align:center>
积分打赏
</h4>
</div>
<div class=modal-body id=button-value>
<div style=text-align:center>
<div role=group>
<button type=button class="btn btn-secondary m64" style=min-width:64px data-value=type1>
1分
</button>
<button type=button class="btn btn-secondary m64" style=min-width:64px data-value=type2>
2分
</button>
<button type=button class="btn btn-secondary m64" style=min-width:64px data-value=type3>
5分
</button>
</div>
<br>
<div style=margin-top:20px>
<button type=button class="btn btn-secondary m64" style=min-width:64px data-value=type4>
8分
</button>
<button type=button class="btn btn-secondary m64" style=min-width:64px data-value=type5>
10分
</button>
<button type=button class="btn btn-secondary m64" style=min-width:64px data-value=type6>
20分
</button>
</div>
</div>
</div>
<div class=modal-footer id=confirm>
<button type=button class="btn btn-default" data-dismiss=modal>关闭</button>
<button type=button class="btn btn-primary" id=reward_topic data-pk=15533>确定</button>
</div>
</div>
</div>
</div>
<div class="row box">
<ol class=breadcrumb>
<li class=active>0 条回复</li>
</ol>
<div class="box-container post-container">
<ul>
<li style=min-height:50px;line-height:60px;margin-left:15px><strong>动动手指,沙发就是你的了!</strong></li>
</ul>
</div>
</div>
<div class="row box" id=reply-box>
<div class="box-container clearfix">
<div class=reminder>
<a href="https://account.aliyun.com/login/login.htm?oauth_callback=https%3A%2F%2Fxz.aliyun.com%2Ft%2F15533&amp;from_type=xianzhi"><strong>登录</strong></a> 后跟帖
</div>
</div>
</div>
</div>
</div>
</div>
<footer class=bs-docs-footer>
<div class="container text-center">
<div class=links>
<a href=https://xz.aliyun.com/feed target=_blank>RSS</a>
<a href=https://xz.aliyun.com/about target=_blank><span>关于社区</span></a>
<a href=https://xz.aliyun.com/partner target=_blank><span>友情链接</span></a>
<a href=https://xz.aliyun.com/notice>社区小黑板</a>
<a href=https://xz.aliyun.com/connection>联系我们</a>
<a href=https://report.aliyun.com/ target=_blank>举报中心</a>
<a href=https://www.aliyun.com/complaint target=_blank>我要投诉</a>
</div>
</div>
</footer>
<div id=waf_nc_block style=display:none></div><div id=immersive-translate-popup style=all:initial><template shadowrootmode=open><style class=sf-hidden>/*!
* Pico.css v1.5.6 (https://picocss.com)
* Copyright 2019-2022 - Licensed under MIT
*/#mount{--font-family:system-ui,-apple-system,"Segoe UI","Roboto","Ubuntu","Cantarell","Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--line-height:1.5;--font-weight:400;--font-size:16px;--border-radius:0.25rem;--border-width:1px;--outline-width:3px;--spacing:1rem;--typography-spacing-vertical:1.5rem;--block-spacing-vertical:calc(var(--spacing)*2);--block-spacing-horizontal:var(--spacing);--grid-spacing-vertical:0;--grid-spacing-horizontal:var(--spacing);--form-element-spacing-vertical:0.75rem;--form-element-spacing-horizontal:1rem;--nav-element-spacing-vertical:1rem;--nav-element-spacing-horizontal:0.5rem;--nav-link-spacing-vertical:0.5rem;--nav-link-spacing-horizontal:0.5rem;--form-label-font-weight:var(--font-weight);--transition:0.2s ease-in-out;--modal-overlay-backdrop-filter:blur(0.25rem)}@media (min-width:576px){#mount{--font-size:17px}}@media (min-width:768px){#mount{--font-size:18px}}@media (min-width:992px){#mount{--font-size:19px}}@media (min-width:1200px){#mount{--font-size:20px}}@media (min-width:576px){#mount>header,#mount>main,#mount>footer,section{--block-spacing-vertical:calc(var(--spacing)*2.5)}}@media (min-width:768px){#mount>header,#mount>main,#mount>footer,section{--block-spacing-vertical:calc(var(--spacing)*3)}}@media (min-width:992px){#mount>header,#mount>main,#mount>footer,section{--block-spacing-vertical:calc(var(--spacing)*3.5)}}@media (min-width:1200px){#mount>header,#mount>main,#mount>footer,section{--block-spacing-vertical:calc(var(--spacing)*4)}}@media (min-width:576px){article{--block-spacing-horizontal:calc(var(--spacing)*1.25)}}@media (min-width:768px){article{--block-spacing-horizontal:calc(var(--spacing)*1.5)}}@media (min-width:992px){article{--block-spacing-horizontal:calc(var(--spacing)*1.75)}}@media (min-width:1200px){article{--block-spacing-horizontal:calc(var(--spacing)*2)}}dialog>article{--block-spacing-vertical:calc(var(--spacing)*2);--block-spacing-horizontal:var(--spacing)}@media (min-width:576px){dialog>article{--block-spacing-vertical:calc(var(--spacing)*2.5);--block-spacing-horizontal:calc(var(--spacing)*1.25)}}@media (min-width:768px){dialog>article{--block-spacing-vertical:calc(var(--spacing)*3);--block-spacing-horizontal:calc(var(--spacing)*1.5)}}a{--text-decoration:none}a.secondary,a.contrast{--text-decoration:underline}small{--font-size:0.875em}h1,h2,h3,h4,h5,h6{--font-weight:700}h1{--font-size:2rem;--typography-spacing-vertical:3rem}h2{--font-size:1.75rem;--typography-spacing-vertical:2.625rem}h3{--font-size:1.5rem;--typography-spacing-vertical:2.25rem}h4{--font-size:1.25rem;--typography-spacing-vertical:1.874rem}h5{--font-size:1.125rem;--typography-spacing-vertical:1.6875rem}[type="checkbox"],[type="radio"]{--border-width:2px}[type="checkbox"][role="switch"]{--border-width:3px}thead th,thead td,tfoot th,tfoot td{--border-width:3px}:not(thead,tfoot)>*>td{--font-size:0.875em}pre,code,kbd,samp{--font-family:"Menlo","Consolas","Roboto Mono","Ubuntu Monospace","Noto Mono","Oxygen Mono","Liberation Mono",monospace,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}kbd{--font-weight:bolder}[data-theme="light"],#mount:not([data-theme="dark"]){--background-color:#fff;--background-light-green:#F5F7F9;--color:hsl(205deg,20%,32%);--h1-color:hsl(205deg,30%,15%);--h2-color:#24333e;--h3-color:hsl(205deg,25%,23%);--h4-color:#374956;--h5-color:hsl(205deg,20%,32%);--h6-color:#4d606d;--muted-color:hsl(205deg,10%,50%);--muted-border-color:hsl(205deg,20%,94%);--primary:hsl(195deg,85%,41%);--primary-hover:hsl(195deg,90%,32%);--primary-focus:rgba(16,149,193,0.125);--primary-inverse:#fff;--secondary:hsl(205deg,15%,41%);--secondary-hover:hsl(205deg,20%,32%);--secondary-focus:rgba(89,107,120,0.125);--secondary-inverse:#fff;--contrast:hsl(205deg,30%,15%);--contrast-hover:#000;--contrast-focus:rgba(89,107,120,0.125);--contrast-inverse:#fff;--mark-background-color:#fff2ca;--mark-color:#543a26;--ins-color:#388e3c;--del-color:#c62828;--blockquote-border-color:var(--muted-border-color);--blockquote-footer-color:var(--muted-c