1 2 3 4
| "Host": "teslamotorsclub.com", "Connection": "keep-alive", "Pragma": "no-cache", "Cache-Control": "no-cache",
|
chrome 元素断点
当元素发生变化时,断住
fiddler 导出 curl
fiddler 抓包 tls
原型链
原型链继承
1 2 3 4 5
| function Student() { }
cxs.propotype = new Student()
|
箭头函数
1 2 3 4 5 6 7 8 9 10 11 12 13
| fn => x * x
function (x) { return x * x }
obj = { name: "cxs", fun: () => { console.log(this.name) } }
|
严格模式
this
非严格模式下,默认指向 window,其他默认指向最后调用的函数
1 2 3 4 5 6 7
| var name = "cxs"; function cxs(){ console.log(this.name) }; obj = {name: "123", cxs} cxs() obj.cxs()
|
延迟函数 setTimeout
1 2 3
| setTimeout(() => { console.log("这是第三条消息"); }, 0);
|
一些 built-in函数
用法参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
- unscape 十六进制解码
- Function 构造函数
1
| const sum = new Function('a', 'b', 'return a + b');
|
- eval
- Array
- Object
- Date
- RegExp
unshift()
添加到数组的开头
- splice 和 slice,前者会改变数据
- Uint8Array、ArrayBuffer、Int32Array、Int16Array
1 2 3 4 5 6
| const uint8Array = new Uint8Array([72, 101, 108, 108, 111]);
const decoder = new TextDecoder();
const decodedString = decoder.decode(uint8Array);
|
- setTimeout 和 setInterval,到期执行 和 定时执行
- 移位运算
- 自执行函数嵌套:
function (a, b){}(fn1, fn2)
无限debugger的三种方式
debugger
eval("debugger")
Function("debugger").call()["action"]
格式化检测
1 2 3 4 5 6 7 8
| a = function cxs(params) { } a.toString() >>> 'function cxs(params) {\n \n}' a = function cxs(params) {} a.toString() >>> 'function cxs(params) {}'
|
小程序
反编译
https://github.com/r3x5ur/unveilr(已删库)
用法:先用UnpackMiniApp解密,再运行命令 unveilr.exe 4h43h4j3h43.wxapkg
动态调试
【6-1】小程序逆向基本工具的使用
多包反编译
【6-4】小程序逆向多包反编译与前面加密处理
对小程序的逐个包进行解密,然后直接反编译文件夹,注意wxapkg的文件名保持一致即可
wx.login code 的调用获取
例如:0a14390w33UZS130DT3w30Gne324390U
https://developers.weixin.qq.com/minigame/dev/api/open-api/login/wx.login.html
httpx隐藏ssl指纹
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import ssl import httpx import random
ORIGIN_CIPHERS = ( 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:' 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES' )
class SSLFactory: def __init__(self): self.ciphers = ORIGIN_CIPHERS.split(":")
def __call__(self): random.shuffle(self.ciphers) ciphers = ":".join(self.ciphers) ciphers = ciphers + ":!aNULL:!eNULL:!MD5" context = ssl.create_default_context() context.set_ciphers(ciphers) return context
sslgen = SSLFactory()
client = httpx.Client(headers=headers, timeout=15, proxies=proxy, verify=sslgen()) response = client.get(url=url) client.close()
async with httpx.AsyncClient(headers=headers, proxies=proxies, verify=sslgen()) as client: response = client.get(url=url)
|
requests隐藏ssl指纹
效果很差,不如curl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import requests from requests.adapters import HTTPAdapter from requests.packages.urllib3.util.ssl_ import create_urllib3_context
ORIGIN_CIPHERS = ('ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:' 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES')
class DESAdapter(HTTPAdapter): def __init__(self, *args, **kwargs): """ A TransportAdapter that re-enables 3DES support in Requests. """ CIPHERS = ORIGIN_CIPHERS.split(':') random.shuffle(CIPHERS) CIPHERS = ':'.join(CIPHERS) self.CIPHERS = CIPHERS + ':!aNULL:!eNULL:!MD5' super().__init__(*args, **kwargs)
def init_poolmanager(self, *args, **kwargs): context = create_urllib3_context(ciphers=self.CIPHERS) kwargs['ssl_context'] = context return super(DESAdapter, self).init_poolmanager(*args, **kwargs)
def proxy_manager_for(self, *args, **kwargs): context = create_urllib3_context(ciphers=self.CIPHERS) kwargs['ssl_context'] = context return super(DESAdapter, self).proxy_manager_for(*args, **kwargs)
session = requests.Session() session.mount("https://so.m.jd.com", DESAdapter())
|
curl_cffi 的使用
原作者:https://zhuanlan.zhihu.com/p/601474166
1
| from curl_cffi import requests
|
express搭建http服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const express = require('express') const app = express()
app.post('/a_bogus', function (req, res) { req.on('data', function (data) { obj = JSON.parse(data); console.log(obj.url); try { res.send(getab(obj.url, obj.ua, obj.data)) } catch (e) { console.log(e) } }) });
app.listen(8911, () => { console.log("开启服务,端口8911", new Date().toString().replace(/\+0800.*/, '')) })
|
随机返回古诗
1 2 3 4 5 6 7 8 9 10 11 12 13
| def jinrishici(): poem_api = "https://v2.jinrishici.com/one.json" params = { "client": "browser-sdk/1.2", "X-User-Token": "SPw7uQvsfkhrtJte9ljEock8hiuq+W/o", } poem_json = requests.get(poem_api, params=params).json() desc = poem_json["data"]["content"] title = poem_json["data"]["origin"]["title"] content = poem_json["data"]["origin"]["content"] author = poem_json["data"]["origin"]["author"] translate = poem_json["data"]["origin"]["translate"] return desc, author, title
|
JS Hook 脚本
参考:https://www.cnblogs.com/ikdl/p/15352809.html
1 2 3 4 5 6 7 8 9
| (function () { var org = window.XMLHttpRequest.prototype.setRequestHeader; window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) { if (key == 'Authorization') { debugger; } return org.apply(this, arguments); }; })();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| (function () { 'use strict'; var cookieTemp = ''; Object.defineProperty(document, 'cookie', { set: function (val) { if (val.indexOf('otherid') != -1) { debugger; } console.log('Hook捕获到cookie设置->', val); cookieTemp = val; return val; }, get: function () { return cookieTemp; }, }); })();
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| (function () { 'use strict'; var org = document.cookie.__lookupSetter__('cookie'); document.__defineSetter__('cookie', function (cookie) { if (cookie.indexOf('__dfp') != -1) { debugger; } org = cookie; }); document.__defineGetter__('cookie', function () { return org; }); })();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| (function() { var parse = JSON.parse; JSON.parse = function(params) { console.log("Hook JSON.parse ——> ", params); debugger; return parse(params); } })();
(function() { var stringify = JSON.stringify; JSON.stringify = function(params) { console.log("Hook JSON.stringify ——> ", params); debugger; return stringify(params); } })();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| (function() { window.__cr_eval = window.eval; var myeval = function(src) { console.log(src); console.log("=============== eval end ==============="); debugger; return window.__cr_eval(src); } var _myeval = myeval.bind(null); _myeval.toString = window.__cr_eval.toString; Object.defineProperty(window, 'eval', { value: _myeval }); })();
eval_bk = eval eval = function (val){ debugger; return eval_bk(val) } eval.toString = function () { return "function eval() { [native code] }" }
|
Fiddler 内存漫游
编程猫插件:
1 2
| 链接: https://pan.baidu.com/s/1N8UVyHSF3qUqsNJa7w3PsQ?pwd=pdgy 提取码: pdgy 复制这段内容后打开百度网盘手机App,操作更方便哦
|
fiddler 命令行
?sometext
搜索特定文本
@cxs.com
域名定位
=301
=post
定位状态码,method
js逆向:浏览器内存漫游安装与使用 - 爬虫之家
安装:fiddler安装编程猫插件就行
用法:
1
| hook.search("f9ad7f8a78df78df7a97d8f8dfaer68er")
|
webpack
用来加载各种函数和模块的方法
入门:http://pychong.com/article/23.html
实战:http://pychong.com/article/24.html
Smail 日志&修改
1 2
| # 加上 log,印出 "we are here" const-string v1, "we are here"
|
查看日志
1 2 3 4 5
| adb logcat -c
adb logcat --pid=`adb shell pidof -s com.cymetrics.demo`
|
函数返回false
1 2 3
| # 在開頭新增底下這兩行,永遠回傳 false const/4 v0, 0x0 return v0
|
Android 抓包
https://blog.huli.tw/2023/04/27/android-apk-decompile-intro-3/
Frida 技巧
无需 root
Android App 逆向入門之四:使用 Frida 進行動態分析 - Huli’s blog
脚本注入方式:先 patch app,然後在 terminal 輸入:
1
| frida -U Gadget -l script.js
|
接著 terminal 上面多了一行 log,內容就是 MainActivity onCreate
,而手機上出現 app crash 的訊息,這是正常的。
overload 传参
建议再每次覆盖原函数之前,都加上 overload()
1
| MainActivity.onCreate.overload().implementation = function() {}
|
其他操作:
- 打印 stack trace
- hook Reflect 反射
- hook 字符串
- hook 加解密
- SSL Pinning
zenTracer日志追踪
https://github.com/hluwa/ZenTracer
安卓主动调用方案
Xposed + Sekiro
安卓逆向 | 主动调用方案之sekiro + xposed
自由职业注意事项:
- 每天要做什么你必须非常清楚,而且还有对应的时间表
- 收入=你提供的价值+对应受众的人数
- 你没有很紧迫的资金压力
- 你一天有工作中10个小时以上的准备
- 一定要让自己的能力跑到头部领域,这样你才被关注的资本
- 每次保持学习,和职业技能的精进,明白核心竞争力并不断去优化它