Comments (11)
Hi @reyesmfabian
Could you please confirm this is the bypass that you tried: https://codeshare.frida.re/@enovella/anti-frida-bypass/ ? This one should not be capable of bypassing freeRASP's hook detection.
Thank you in advance,
Talsec Team
from free-rasp-flutter.
Could you please confirm this is the bypass that you tried: https://codeshare.frida.re/@enovella/anti-frida-bypass/ ? This one should not be capable of bypassing freeRASP's hook detection.
Thank you in advance,
Talsec Team
Yes, that one.
I follow this steps:
- Make a release APK of the App with freeRasp integration.
- Install the APK in the rooted device and check the threats recognition. (It works)
- Launch the Apk with Frida bypass to test the threats recognition. (Fail, the app don't recognize threats).
from free-rasp-flutter.
We tested the referenced script and it is definitely not able to bypass freeRASP's hook detection.
The possible culprit on your side may be caused by not refreshing the state of the widget once you receive the callback. Such a problem is explained in this issue: #13 (comment) . Hope this helps!
Thank you for using the freeRASP. Let us know if you need anything,
Talsec Team
Our test
We tested the script against the latest freeRASP.
- no script: Hook is properly detected
- with script: Hook is properly detected
$ frida -U --codeshare enovella/anti-frida-bypass -f com.talsec.demo --no-pause
from free-rasp-flutter.
Hi @talsec-app
I'm testing the solution as follows:
main.dart file:
List<Threat> _threats = [];
@override
void initState() {
super.initState();
initSecurityState();
}
Future<void> initSecurityState() async {
TalsecConfig _config.........
TalsecCallback _callback = TalsecCallback(
// For Android
androidCallback: AndroidCallback(
onRootDetected: () => _updateThreats(Threat.RootDetected).......
TalsecApp app = TalsecApp(
config: _config,
callback: _callback,
);
app.start();
}
_updateThreats(Threat threat) {
if (!_threats.contains(threat)) _threats.add(threat);
setState(() {});
securityServiceController.add(_threats);
}
security_stream.dart
StreamController<List<Threat>> securityServiceController =
new StreamController.broadcast();
login_page.dart
@override
initState() {
securityServiceController.stream.listen((threats) {
if (threats.length != 0) {
Navigator.pushReplacementNamed(context, 'testPage');
}
});
super.initState();
}
The thing is, with the normal start, the App reads the threats and goes to PageTest, everything is fine.
But, if I start the script with this
$ frida -U --codeshare enovella/anti-frida-bypass -f com.myapp.id
The application does not read the threats and works as normally.
Maybe i have something wrong that i can't see
from free-rasp-flutter.
Hello @reyesmfabian ,
We have tried your code mixed with the freeRASP example code (https://pub.dev/packages/freerasp/example). Check below. It still works for us as expected. Please try the code below and let us know if it helps you.
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:freerasp/talsec_app.dart';
import 'package:freerasp/utils/hash_converter.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({final Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
/// ThreatTypes to hold current state (Android)
final ThreatType _root = ThreatType("Root");
final ThreatType _emulator = ThreatType("Emulator");
final ThreatType _tamper = ThreatType("Tamper");
final ThreatType _hook = ThreatType("Hook");
final ThreatType _deviceBinding = ThreatType("Device binding");
final ThreatType _untrustedSource =
ThreatType("Untrusted source of installation");
/// ThreatTypes to hold current state (iOS)
final ThreatType _signature = ThreatType("Signature");
final ThreatType _jailbreak = ThreatType("Jailbreak");
final ThreatType _runtimeManipulation = ThreatType("Runtime Manipulation");
final ThreatType _simulator = ThreatType("Simulator");
final ThreatType _deviceChange = ThreatType("Device change");
final ThreatType _deviceId = ThreatType("Device ID");
final ThreatType _unofficialStore = ThreatType("Unofficial Store");
final ThreatType _passcode = ThreatType("Passcode");
final ThreatType _missingSecureEnclave = ThreatType("Missing secure enclave");
/// ThreatTypes to hold current state (common)
final ThreatType _debugger = ThreatType("Debugger");
/// Getter to determine which states we care about
List<Widget> get overview {
if (Platform.isAndroid) {
return [
Text(_root.state),
Text(_debugger.state),
Text(_emulator.state),
Text(_tamper.state),
Text(_hook.state),
Text(_deviceBinding.state),
Text(_untrustedSource.state),
];
}
return [
Text(_signature.state),
Text(_jailbreak.state),
Text(_debugger.state),
Text(_runtimeManipulation.state),
Text(_passcode.state),
Text(_simulator.state),
Text(_missingSecureEnclave.state),
Text(_deviceChange.state),
Text(_deviceId.state),
Text(_unofficialStore.state)
];
}
/// Override initState of the "highest" widget in order to start freeRASP
/// as soon as possible.
@override
void initState() {
super.initState();
initSecurityState();
}
List<String> _threats = [];
_updateThreats(String threat) {
if (!_threats.contains(threat)) _threats.add(threat);
setState(() {});
securityServiceController.add(_threats);
}
StreamController<List<String>> securityServiceController =
new StreamController.broadcast();
Future<void> initSecurityState() async {
/// Provide TalsecConfig your expected data and then use them in TalsecApp
final TalsecConfig config = TalsecConfig(
// For Android
...
);
/// Callbacks thrown by library
final TalsecCallback callback = TalsecCallback(
/// For Android
androidCallback: AndroidCallback(
onRootDetected: () => _updateState(_root),
onEmulatorDetected: () => _updateState(_emulator),
onHookDetected: () {
_updateThreats("Hook");
},
onTamperDetected: () => _updateState(_tamper),
onDeviceBindingDetected: () => _updateState(_deviceBinding),
onUntrustedInstallationDetected: () => _updateState(_untrustedSource),
),
/// For iOS
iosCallback: IOSCallback(
onSignatureDetected: () => _updateState(_signature),
onRuntimeManipulationDetected: () => _updateState(_runtimeManipulation),
onJailbreakDetected: () => _updateState(_jailbreak),
onPasscodeDetected: () => _updateState(_passcode),
onSimulatorDetected: () => _updateState(_simulator),
onMissingSecureEnclaveDetected: () =>
_updateState(_missingSecureEnclave),
onDeviceChangeDetected: () => _updateState(_deviceChange),
onDeviceIdDetected: () => _updateState(_deviceId),
onUnofficialStoreDetected: () => _updateState(_unofficialStore),
),
/// Debugger is common for both platforms
onDebuggerDetected: () => _updateState(_debugger),
);
final TalsecApp app = TalsecApp(
config: config,
callback: callback,
);
/// Turn on freeRASP
app.start();
securityServiceController.stream.listen((threats) {
if (threats.length != 0) {
print("Broadcast received");
}
});
if (!mounted) return;
}
void _updateState(final ThreatType type) {
setState(() {
// ignore: parameter_assignments
type.threatFound();
});
}
@override
Widget build(final BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: overview,
),
),
),
);
}
}
class ThreatType {
final String _text;
bool _isSecure = true;
ThreatType(this._text);
void threatFound() => _isSecure = false;
String get state => '$_text: ${_isSecure ? "Secured" : "Detected"}\n';
}
from free-rasp-flutter.
Hello @reyesmfabian , We have tried your code mixed with the freeRASP example code (https://pub.dev/packages/freerasp/example). Check below. It still works for us as expected. Please try the code below and let us know if it helps you.
Hi,
This is my main.dart file:
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_translate/flutter_translate.dart';
import 'package:freerasp/talsec_app.dart';
import 'package:provider/provider.dart';
import 'package:my_project/pages/test_page.dart';
import 'package:my_project/provider/provider.dart';
import 'package:my_project/provider/socketService.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
var delegate = await LocalizationDelegate.create(
fallbackLocale: 'en_US', supportedLocales: ['en_US', 'es']);
runApp(LocalizedApp(delegate, MyApp()));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final GlobalKey<NavigatorState> navigatorKey =
new GlobalKey<NavigatorState>();
/// ThreatTypes to hold current state (Android)
final ThreatType _root = ThreatType("Root");
final ThreatType _emulator = ThreatType("Emulator");
final ThreatType _tamper = ThreatType("Tamper");
final ThreatType _hook = ThreatType("Hook");
final ThreatType _deviceBinding = ThreatType("Device binding");
final ThreatType _untrustedSource =
ThreatType("Untrusted source of installation");
/// ThreatTypes to hold current state (iOS)
final ThreatType _signature = ThreatType("Signature");
final ThreatType _jailbreak = ThreatType("Jailbreak");
final ThreatType _runtimeManipulation = ThreatType("Runtime Manipulation");
final ThreatType _simulator = ThreatType("Simulator");
final ThreatType _deviceChange = ThreatType("Device change");
final ThreatType _deviceId = ThreatType("Device ID");
final ThreatType _unofficialStore = ThreatType("Unofficial Store");
final ThreatType _passcode = ThreatType("Passcode");
final ThreatType _missingSecureEnclave = ThreatType("Missing secure enclave");
/// ThreatTypes to hold current state (common)
final ThreatType _debugger = ThreatType("Debugger");
/// Getter to determine which states we care about
List<Widget> get overview {
if (Platform.isAndroid) {
return [
Text(_root.state),
Text(_debugger.state),
Text(_emulator.state),
Text(_tamper.state),
Text(_hook.state),
Text(_deviceBinding.state),
Text(_untrustedSource.state),
];
}
return [
Text(_signature.state),
Text(_jailbreak.state),
Text(_debugger.state),
Text(_runtimeManipulation.state),
Text(_passcode.state),
Text(_simulator.state),
Text(_missingSecureEnclave.state),
Text(_deviceChange.state),
Text(_deviceId.state),
Text(_unofficialStore.state)
];
}
@override
void dispose() {
securityServiceController.close();
super.dispose();
}
@override
void initState() {
super.initState();
initSecurityState();
}
Future<void> initSecurityState() async {
TalsecConfig _config = TalsecConfig(
// For Android
androidConfig: AndroidConfig(
expectedPackageName: 'com.my_identifier',
expectedSigningCertificateHash:
'cert_hash',
supportedAlternativeStores: [],
),
// For iOS
iosConfig: IOSconfig(
appBundleId: 'com.my_identifier',
appTeamId: 'my_team',
),
// Common email for Alerts and Reports
watcherMail: 'email',
);
// Talsec callback handler
TalsecCallback _callback = TalsecCallback(
/// For Android
androidCallback: AndroidCallback(
onRootDetected: () => _updateThreats('root', _root),
onEmulatorDetected: () => _updateThreats('emulator', _emulator),
onHookDetected: () {
_updateThreats("Hook", _hook);
},
onTamperDetected: () => _updateThreats('tamper', _tamper),
onDeviceBindingDetected: () =>
_updateThreats('device_binding', _deviceBinding),
onUntrustedInstallationDetected: () =>
_updateThreats('_untrustedSource', _untrustedSource),
),
/// For iOS
iosCallback: IOSCallback(
onSignatureDetected: () => _updateThreats('_signature', _signature),
onRuntimeManipulationDetected: () =>
_updateThreats('_runtimeManipulation', _runtimeManipulation),
onJailbreakDetected: () => _updateThreats('_jailbreak', _jailbreak),
onPasscodeDetected: () => _updateThreats('_passcode', _passcode),
onSimulatorDetected: () => _updateThreats('_simulator', _simulator),
onMissingSecureEnclaveDetected: () =>
_updateThreats('_missingSecureEnclave', _missingSecureEnclave),
onDeviceChangeDetected: () =>
_updateThreats('_deviceChange', _deviceChange),
onDeviceIdDetected: () => _updateThreats('_deviceId', _deviceId),
onUnofficialStoreDetected: () =>
_updateThreats('_unofficialStore', _unofficialStore),
),
/// Debugger is common for both platforms
onDebuggerDetected: () => _updateThreats('_debugger', _debugger),
);
TalsecApp app = TalsecApp(
config: _config,
callback: _callback,
);
securityServiceController.stream.listen((threats) {
if (threats.length != 0) {
print("Broadcast received");
}
});
if (!mounted) return;
app.start();
}
List<String> _threats = [];
_updateThreats(String threat, ThreatType type) {
if (!_threats.contains(threat)) _threats.add(threat);
setState(() {
type.threatFound();
});
securityServiceController.add(_threats);
}
@override
Widget build(BuildContext context) {
var localizationDelegate = LocalizedApp.of(context).delegate;
final ThemeData theme = ThemeData();
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => new SocketService()),
ChangeNotifierProvider(create: (_) => new UsuarioActivo())
],
child: LocalizationProvider(
state: LocalizationProvider.of(context).state,
child: MaterialApp(
navigatorKey: navigatorKey,
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
DefaultCupertinoLocalizations.delegate
],
supportedLocales: localizationDelegate.supportedLocales,
locale: localizationDelegate.currentLocale,
debugShowCheckedModeBanner: false,
title: 'App Name',
initialRoute: 'testPage',
routes: {
'testPage': (_) => TestSecurityPage(),
},
theme: theme.copyWith(
textTheme: theme.textTheme.apply(fontFamily: 'Nunito'),
colorScheme: theme.colorScheme.copyWith(
secondary: Colors.red[900], primary: Colors.blue[900]))),
),
);
}
}
class ThreatType {
final String _text;
bool _isSecure = true;
ThreatType(this._text);
void threatFound() => _isSecure = false;
String get state => '$_text: ${_isSecure ? "Secured" : "Detected"}\n';
}
StreamController<List<String>> securityServiceController =
new StreamController.broadcast();
test_page.dart file
import 'package:flutter/material.dart';
import '../main.dart';
class TestSecurityPage extends StatefulWidget {
const TestSecurityPage({Key key}) : super(key: key);
@override
State<TestSecurityPage> createState() => _TestSecurityPageState();
}
class _TestSecurityPageState extends State<TestSecurityPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: StreamBuilder<List<String>>(
stream: securityServiceController.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, i) {
return ListTile(
title: Text(snapshot.data[i].toString()),
);
});
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('No Threats Detected'),
],
);
}
}),
));
}
}
this is the behavior.
flutter run --release
https://www.youtube.com/shorts/goULuQPXh4Q
now, with the same release version installed and execute with frida:
frida -U --codeshare enovella/anti-frida-bypass -f com.my_identifier
https://www.youtube.com/shorts/EjuVBWLilCE
from free-rasp-flutter.
Thank you for your testing & videos. We will inspect this issue more and get back to you by the end of the following week.
from free-rasp-flutter.
We couldn't reproduce the issue. The anti-frida-bypass script is not able to mitigate Frida detection.
flutter run --release
The app is hooked with latest Frida v16.0.2. UI works. The button is tapped to increase the number in AppBar in the second half of the recording. The detection works as expected, and the hook callback is successfully received after some slight delay:
frida -U --codeshare enovella/anti-frida-bypass -f com.example.app
https://youtube.com/shorts/bJ5FDxlt0Dk?feature=share
The anti-frida-bypass outputs many errors:
from free-rasp-flutter.
We couldn't reproduce the issue. The anti-frida-bypass script is not able to mitigate Frida detection.
flutter run --release
The app is hooked with latest Frida v16.0.2. UI works. The button is tapped to increase the number in AppBar in the second half of the recording. The detection works as expected, and the hook callback is successfully received after some slight delay:
frida -U --codeshare enovella/anti-frida-bypass -f com.example.app
Do you think that my approach with a stream controller is the problem?
Do you think it is possible to access that repo to test it in my own environment?
from free-rasp-flutter.
$ frida -U --codeshare enovella/anti-frida-bypass -f com.myapp.id
There is a problem with frida detection.
I am trying the CyberTribe application downloaded from the official store as suggested by Sergiy.
look: https://www.youtube.com/watch?v=KsgCfpakFkI&ab_channel=R-Tech
I didn't modify the apk, I just downloaded it and tested it.
from free-rasp-flutter.
Conclusion
We are closing this issue as we were unable to reproduce this behavior. This may be important in the future, but we can't do anything about it currently. If someone encounters this issue in the future, let us know, and it can be further inspected.
Thank you so much for your assistance,
Talsec Team
from free-rasp-flutter.
Related Issues (20)
- [Flutter project] APK file increased by 40% with FreeRASP package HOT 6
- Frida and App Integrity detection not working as expected HOT 6
- Android build fails since March 4th, 14 o'clock HOT 3
- bug: Typecast error (int to String) in debug mode HOT 4
- bug: PlatformException - dlopen failed: library "libsecurity.so" not found HOT 5
- Device Id Issue HOT 5
- Feature: get currentThreatStatus / await freeRasp.checksComplete.future HOT 2
- Freerasp causes error with SharedPreferences at start and application does not run in production HOT 6
- How to know proper value for `AndroidConfig.supportedStores`? HOT 3
- How the 100k limitation for free tier is calculated? HOT 2
- The package is susceptible to smali changes. HOT 6
- Free-RASP-Flutter Security Delay Issue HOT 8
- When the app is minimized and resumed before the checks, they do not occur. HOT 5
- only Xcode 13 required to be able to build the application. HOT 4
- Crash on iOS device with 6.2.0 HOT 6
- onAppIntegrity after releasing playstore HOT 8
- Emulator Detection / Root detection on Android emulator HOT 3
- Which callback? HOT 3
- Android app not compilable with AGP >= 8.0.0 HOT 2
- Android Google Play Automatic integrity protection support HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from free-rasp-flutter.