APT研究系统安全 [2021]阴谋论: windows XP中可能带有NSA后门? **这篇文章消息不确定是否属实,仅仅是本人的一个小的想法与思考,请勿当真** 在审计windows XP代码的时候,在数字签名校验部分,PkcsPublicEncrypt、RSAPublicEncrypt这两个函数长这样: RSAPublicEncrypt: ![](https://key08.com/usr/uploads/2021/09/2609714416.png) PkcsPublicEncrypt: ![](https://key08.com/usr/uploads/2021/09/393499675.png) 按道理说,他们应该走标准的Pkcs、RSA加密算法,然而并不,在XP源码下,他们走到了一个叫做BSafeEncPublic的算法中: ![](https://key08.com/usr/uploads/2021/09/3065156119.png) ~~这个BSafeEncPublic源码是不公开的,是一个lib文件~~(有误,不是这个lib文件,但是目前也不知道是哪来的) ![](https://key08.com/usr/uploads/2021/09/1530459164.png) 百思不得其解,在查阅wiki后,发现这个算法挺有意思的: ![](https://key08.com/usr/uploads/2021/09/3832960814.png) > 从 2004 年到 2013 年,BSAFE 中默认的加密安全伪随机数生成器(CSPRNG) 是Dual_EC_DRBG,它包含一个据称来自NSA 的后门,以及一个有偏见且缓慢的 CSPRNG。[4]自 2005 年规范发布后不久,密码学社区就意识到 Dual_EC_DRBG 是一个非常糟糕的 CSPRNG,到 2007 年,很明显 CSPRNG 似乎被设计为包含 NSA 的隐藏后门,只能使用美国国家安全局通过密钥。[5] 2007 年,Bruce Schneier将后门描述为“太明显了,无法欺骗任何人使用它”。[5]后门在斯诺登泄密事件中得到证实在 2013 年,有人暗示 NSA 在 2004 年向 RSA Security 支付了 1000 万美元以默认使用 Dual_EC_DRBG,[3]尽管 RSA Security在 2004 年否认他们知道后门 不过时间有点对不上就是了,按照wiki说的bsafe默认设置为Dual_EC_DRBG的时间是2004年开始,但是微软的bsafe lib是2003年的,那么是真是假只能看微软的那个lib里面用的是啥随机生成算法了 更新: win7 ci.dll里面也有 ![](https://key08.com/usr/uploads/2021/09/1380179034.png) 不知道是故意隐藏代码不给看还是怎么滴,他的数字签名算法都是这玩意 哪怕是win7那时候已经说淘汰bsafe这个算法了还在用,**要么是名字正好重复了**,要么是故意使坏 阅读全文 2021-09-20 huoji 1 条评论
系统安全二进制安全C/C++汇编一线开发 [2021]漫游微软屎山 win32kfull.sys (一) ssdt和shadow ssdt 微软的win32kfull.sys这玩意绝对是,微软整个操作系统上漏洞最多的驱动之一,因为他的代码是从win3.1一路贴屎山贴过来的,在如今windows 20h2最新系统上,你任然可以看到某些莫名其妙的函数 ![](https://key08.com/usr/uploads/2021/09/322474017.png) lszzz zzz qqqqzzzqx等奇怪的看起来就像是屎山的代码 过去二十年,微软这玩意一直是漏洞报告的重头戏,各种本地提权、rce层出不穷,其恶劣程度堪比rpc和wmi.因此我准备单独开一系列介绍这个win32kfull.sys(本人也在持续逆向他中) ## ssdt和shadow ssdt 总所周知,x64后大部分常规API进内核的方式是syscall,当有syscall指令后,cpu会把rip指向amd64_lstar这个寄存器里面的地址,操作系统则把这个寄存器改成自己的进内核的函数,微软windows下这个r3和内核交互的函数名字叫做 kisystemcall64 而操作系统的大部分跟R3交互的API 都是一套叫做SSDT的机制控制的,并且如果是涉及到图形的api 则是放在shadow ssdt也就是sssdt,为什么要这样放,因为内核实在是没办法塞下win3.1的垃圾屎山代码.也没办法重构,所以干脆分开 阅读全文 2021-09-04 huoji 0 条评论
C/C++游戏安全一线开发 [2021]TEA加密 在游戏项目中,一般需要对资源或数据进行加密保护,最简单高效的加密算法就是采用位与或之类的,但是比较容易被人分析出来。 TEA加密算法不但比较简单,而且有很强的抗差分分析能力,加密速度也比较快。可以根据项目需求设置加密轮数来增加加密强度。 1.加密核心函数 阅读全文 2021-08-21 huoji 0 条评论
python系统安全工具软件汇编一线开发 [2021]余弦定理检测文件相似度 & 病毒样本基因检测 本余弦定理有如下应用场景: 1.相似度计算 2.信息推送 在网络安全领域,主要就是样本基因检测,或者叫做样本相似度计算,他的公式长这样: ![](https://key08.com/usr/uploads/2021/08/2243488000.png) 请注意,之所以叫做余弦定理,是因为,他就是求一个三角形的角,并且在N维这个定理也成立 ![](https://key08.com/usr/uploads/2021/08/3451125394.png) 样本相似度检测,以两个风灵月影为例,属于同一个家族: ![](https://key08.com/usr/uploads/2021/08/947620823.png) # 编码 通过pefile库,读入文件,然后逐个比对字节码,参数A为字节码相同的,参数B为字节码不同的: ```cpp def get_peinfo_by_cos(pSource,pTarget): source = pefile.PE(pSource) target = pefile.PE(pTarget) source_map,source_sizeof_code,source_base_of_code = get_pe_info(source) target_map,target_sizeof_code,target_base_of_code = get_pe_info(target) a1_dict = {} a2_dict = {} for iter in range(source_sizeof_code): v1 = iter + source_base_of_code v2 = iter + source_base_of_code + 1 if source_map[v1:v2] in a1_dict.keys(): a1_dict[source_map[v1:v2]] = a1_dict[source_map[v1:v2]] + 1 else: a1_dict[source_map[v1:v2]] = 0 for iter in range(target_sizeof_code): v1 = iter + target_base_of_code v2 = iter + target_base_of_code + 1 if target_map[v1:v2] in a2_dict.keys(): a2_dict[target_map[v1:v2]] = a2_dict[target_map[v1:v2]] + 1 else: a2_dict[target_map[v1:v2]] = 0 str1_vector=[] str2_vector=[] for key in a1_dict: str1_count = a1_dict[key] str1_vector.append(str1_count) for key in a2_dict: str2_count = a2_dict[key] str2_vector.append(str2_count) str1_map = map(lambda x: x*x,str1_vector) str2_map = map(lambda x: x*x,str2_vector) str1_mod = reduce(lambda x, y: x+y, str1_map) str2_mod = reduce(lambda x, y: x+y, str2_map) str1_mod = math.sqrt(str1_mod) str2_mod = math.sqrt(str2_mod) vector_multi = reduce(lambda x, y: x + y, map(lambda x, y: x * y, str1_vector, str2_vector)) # 计算余弦值 cos = float(vector_multi)/(str1_mod*str2_mod) return cos ``` 其中,两个是相似的,两个是不相似的,两个是恶意样本家族 来试试: ![](https://key08.com/usr/uploads/2021/08/1402924204.png) 简单粗暴,并且有效. 完整代码: 阅读全文 2021-08-19 huoji 1 条评论
系统安全C/C++汇编 [2021]Windows PatchGuard KiErrata671Present 在一次偶然中我发现了KiErrata671Present,它这个看起来长这样: ![](https://key08.com/usr/uploads/2021/08/1055346649.png) 人畜无害 但是看调用: ![](https://key08.com/usr/uploads/2021/08/1257889702.png) 第一眼看不出什么 让我们慢慢解释一下: ![](https://key08.com/usr/uploads/2021/08/1678044808.png) 请注意,ida反汇编的代码是没有try和catch的,在汇编里面,你可以看得到如下的代码: ![](https://key08.com/usr/uploads/2021/08/1437456579.png) 通俗的解释一下 1.去掉页面保护 2.给KiErrata671Present + 0x2的位置写0xC3 让其从1返回为0 3.执行KiErrata671Present 4.恢复页面保护 这样做会有什么效果: 一些hypervisor中的EPT/NPT hook技术会让页面读写执行分离实现无痕hook,如果在有EPT/NPT HOOK的情况下并且这个函数正好与某些保护页面在同一页的情况下,第2步(给KiErrata671Present + 0x2的位置写0xC3 让其从1返回为0)不会被写入执行页面,导致执行结果依然是1,从而让其检测到hypervisor,不过这也只是猜测,因为目前有几个不确定: 1. 这个是1809的东西,为什么目前没有1809的ept hook出错的报告 2. 这个东西是如何调用的,会在哪调用,哪些页面会有这个东西,目前来说并不知道 阅读全文 2021-08-18 huoji 5 条评论
python一线开发 [2021]从0开始的tensorflow2.0 (三) LSTM 假设给出如下需求: 我给你几个行为 A B C D E F 要求知道A B C D E 推测出F 这种使用场景就能使用LSTM,关于LSTM本文就不废话了,因为网上介绍一大堆了,直接上干货: 首先我们需要将数据 A B C D E F 转为编号:0 1 2 3 4 6 其次,对其进行扁平归一化,并且划分训练和测试数据: ```cpp train_path = './result_list.csv' data_frame = pd.read_csv(train_path) data_frame['activity'] = data_frame['activity'].astype('float32') scaler = StandardScaler() data_frame['activity'] = scaler.fit_transform( data_frame['activity'].values.reshape(-1, 1), scaler.fit(data_frame['activity'].values.reshape(-1, 1))) train_size = int(len(data_frame['activity']) * 0.75) trainlist = data_frame['activity'][:train_size] testlist = data_frame['activity'][train_size:] ``` 读出来应该是: 0 1 2 3 4 5 .... 然后构造滑块,成0 1 2 3 4(X), 5(Y)的样子: ```cpp look_back = 64 trainX, trainY = create_dataset(trainlist, look_back, None) testX, testY = create_dataset(testlist, look_back, train_size) ``` 注意网上的create_dataset代码都过时了,大部分你直接抄就会报错,用我的就行: ```cpp def create_dataset(dataset, look_back, start_index): dataX, dataY = [], [] for i in range(len(dataset)-look_back-1): a = dataset[i:(i+look_back)] dataX.append(a) if start_index != None: dataY.append(dataset[start_index + i + look_back]) else: dataY.append(dataset[i + look_back]) return np.array(dataX), np.array(dataY) ``` 记得要reshap一下: ```cpp trainX = trainX.reshape(trainX.shape[0], trainX.shape[1], 1) testX = testX.reshape(testX.shape[0], testX.shape[1], 1) ``` 之后直接训练即可: ```cpp model = keras.Sequential() model.add(keras.layers.LSTM(128, input_shape=(look_back, 1), return_sequences=True)) model.add(keras.layers.LSTM(256)) model.add(keras.layers.Dense(1)) model.compile(optimizer=keras.optimizers.Adam(), loss='mae', metrics=['MeanSquaredError']) model.fit(trainX, trainY, epochs=26, batch_size=128) model.save('./model_lstm.h5') ``` 测试: ![](https://key08.com/usr/uploads/2021/08/1454514772.png) 阅读全文 2021-08-14 huoji 0 条评论