2023HWS_RE复现
2023HWS_RE复现
参考wp:https://oacia.cc/hws-2023/
Android
参考这篇文章:https://www.52pojie.cn/thread-1680984-1-1.html
360加固去掉


利用gg修改器+lua脚本去掉360加固后
然后就ok了,但是dex文件直接丢尽jadx会报错


把多余的数据删了就行

然后可以正常看

到so里面看,sm4加密,
enc给出,key,iv通过app里面的字符串猜出


Animals
有很多花指令

手动patch后发现还有一堆
脚本去花
import idc
def clear_junk(ea_start,ea_end):
junk=[0x74, 0x15, 0x75, 0x13, 0x8D, 0x44, 0x24, 0xFC, 0x83, 0xF0,
0x22, 0x3B, 0x04, 0x24, 0x74, 0x0A, 0xE8, 0x1F, 0x00, 0x00,
0x00, 0x74, 0x04]
while ea_start<ea_end:
if idc.get_bytes(ea_start,len(junk))==bytes(junk):
for i in range(len(junk)):
idc.patch_byte(ea_start+i,0x90)
ea_start+=len(junk)
ea_start+=1
ea_start=0x0000000000400800
ea_end=0x00000406E20
clear_junk(ea_start,ea_end)
print("ok")

修改junk里面的机器码,再进行去花
import idc
def clear_junk(ea_start,ea_end):
junk=[0x74, 0x0A, 0x75, 0x08, 0xE8, 0x10, 0x00, 0x00, 0x00, 0xEB,
0x04, 0xE8, 0x48, 0x8D, 0xBD, 0x90, 0xFE, 0xFF, 0xFF]
while ea_start<ea_end:
if idc.get_bytes(ea_start,len(junk))==bytes(junk):
for i in range(len(junk)):
idc.patch_byte(ea_start+i,0x90)
ea_start+=len(junk)
ea_start+=1
ea_start=0x0000000000400800
ea_end=0x00000406E20
clear_junk(ea_start,ea_end)
print("ok")
还有一种,这本质上同一种花

import idc
def clear_junk(ea_start,ea_end):
junk=[0x74, 0x0A, 0x75, 0x08, 0xE8, 0x10, 0x00, 0x00, 0x00, 0xEB,
0x04, 0xE8]
while ea_start<ea_end:
if idc.get_bytes(ea_start,len(junk))==bytes(junk):
for i in range(len(junk)):
idc.patch_byte(ea_start+i,0x90)
ea_start+=len(junk)
ea_start+=1
ea_start=0x0000000000400800
ea_end=0x00000406E20
clear_junk(ea_start,ea_end)
print("ok")
去完差不多这个样子

去不透明谓词

找到汇编

给寄存器赋值为0

这样就去掉了

按照这个方法开始去
代码审计
完全去掉不透明谓词和花指令
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rdi
size_t v4; // rax
size_t v5; // rax
size_t v6; // rax
size_t v7; // rax
size_t v8; // rax
size_t v9; // rax
unsigned int v10; // eax
const char *v12; // [rsp+68h] [rbp-2C8h]
const char *v13; // [rsp+80h] [rbp-2B0h]
const char *v14; // [rsp+98h] [rbp-298h]
const char *v15; // [rsp+B0h] [rbp-280h]
const char *v16; // [rsp+C8h] [rbp-268h]
char *src; // [rsp+E0h] [rbp-250h]
int j; // [rsp+144h] [rbp-1ECh]
char v19[88]; // [rsp+148h] [rbp-1E8h] BYREF
char v20[24]; // [rsp+1A0h] [rbp-190h] BYREF
int v21; // [rsp+1B8h] [rbp-178h] BYREF
int i; // [rsp+1BCh] [rbp-174h]
char v23[256]; // [rsp+1C0h] [rbp-170h] BYREF
char *s; // [rsp+2C0h] [rbp-70h] BYREF
char *v25; // [rsp+2C8h] [rbp-68h]
char *v26; // [rsp+2D0h] [rbp-60h]
char *v27; // [rsp+2D8h] [rbp-58h]
char *v28; // [rsp+2E0h] [rbp-50h]
char *v29; // [rsp+2E8h] [rbp-48h]
pthread_t newthread[2]; // [rsp+2F0h] [rbp-40h] BYREF
int v31; // [rsp+300h] [rbp-30h]
int v32; // [rsp+304h] [rbp-2Ch]
v32 = 0;
v31 = argc;
newthread[1] = (pthread_t)argv;
sub_405FF0(argc, argv, envp);
memset(&s, 0, 0x30uLL);
s = (_BYTE *)("0. cat" + 3);
v25 = (_BYTE *)("1. dog" + 3);
v26 = (_BYTE *)("2. fox" + 3);
v27 = (_BYTE *)("3. panda" + 3);
v28 = (_BYTE *)("4. dragon" + 3);
v29 = (_BYTE *)("5. monkey" + 3);
memset(v23, 0, sizeof(v23));
for ( i = 0; i < 9; ++i )
{
v21 = 0;
puts("Welcome Animal shop");
sub_400900();
v3 = "%d";
printf("Please input my favorite animal: ");
__isoc99_scanf("%d", &v21);
switch ( v21 )
{
case 0:
src = s;
v4 = strlen(s);
strncat(v23, src, v4);
break;
case 1:
v16 = v25;
v5 = strlen(v25);
strncat("%d", v16, v5);
break;
case 2:
v15 = v26;
v6 = strlen(v26);
strncat(v23, v15, v6);
break;
case 3:
v14 = v27;
v7 = strlen(v27);
strncat("%d", v14, v7);
break;
case 4:
v13 = v28;
v8 = strlen(v28);
strncat(v23, v13, v8);
break;
case 5:
LOBYTE(v3) = 0;
v12 = v29;
v9 = strlen(v29);
strncat(v3, v12, v9);
break;
default:
puts("Input Err.");
exit(0);
}
}
pthread_create(newthread, 0LL, start_routine, 0LL);
pthread_join(newthread[0], 0LL);
puts("done.");
sub_4009A0(v19);
v10 = strlen(v23);
sub_400B30(v19, v23, v10);
sub_4059A0(v19, v20);
for ( j = 0; j < 16; ++j )
{
if ( byte_608090[j] != v20[j] )
{
puts("Wrong.");
exit(0);
}
}
puts("Win! , flag is flag{md5(input)}");
return 0;
}

这里我用md5加密硬爆没出来,后面看其他师傅wp才知道md5的常数换位置了,由于全是数字限制小,直接开爆了。
我这里用脚本
from itertools import product
from subprocess import Popen, PIPE
# 创建迭代器
char_set = "012345"
char_length = 9
all_combinations = product(char_set, repeat=char_length)
# 遍历组合并发送给进程
for combination in all_combinations:
inp = "".join(combination)
p = Popen('./main', stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
# 发送输入
for i in inp:
p.stdin.write(i.encode()+b'\n')
#print(i.encode())
p.stdin.close()
# 接收输出
res = p.stdout.read()
print(res.decode('utf-8'))
# 检查是否包含flag
if b'flag' in res:
with open('flag.txt', 'w+') as f:
f.write(inp)
print(inp)
break
E
下一个ida插件
https://www.52pojie.cn/thread-1684608-1-1.html,
下一个易语言,把易语言的静态库全提取sign
https://bbs.kanxue.com/thread-263254.htm

利用工具提取后

我这只选择了一个,没想到同目录下的全提取了

然后打开ida的目录的sig\pc

把名称加载在末尾

进ida先用e插件

识别出来一些,然后shift f5 ,

挨个导入
然后搜索字符wrong,定位逻辑

这边可以看到符号全恢复了

进行代码审计,发现我们输入的input分前后2部分进行
先进行转化操作
def en_head(y):
for i in range(len(y)):
y[i]<<=1
y[i]^=0xbf
y[i]>>=1
y[i]&=0xff
print(bytes(y).decode(),end='\n')
#后部分
def en_tail(y):
for i in range(len(y)):
y[i]>>=1
y[i]^=0x81
y[i]<<=1
y[i]&=0xff
print(bytes(y).decode(),end='\n')

这个就是检测数字,如果字符串是数字就进循环
进行调试
三方支持库命令((unsigned int)ecalc_fnUnlNumImportNum, 2, v69, 0, 131082, v67, 0, 0x80000301);
易语言存储结构研究
这里下一个易语言进行研究,主要导入eCalc的文件
导入教程: https://www.jb51.net/article/151735.htm
.版本 2
.支持库 eCalc
.程序集 程序集1
.子程序 _启动子程序, 整数型
.局部变量 局_大数a, 大数
.局部变量 局_大数b, 大数
.局部变量 局_结果, 大数
.局部变量 局_显示, 文本型
局_大数a.导入数字 (287454020)
局_大数b.导入数字 (1432778632)
局_结果 = 局_大数a.加 (局_大数b)
局_显示 = 局_结果.导出文本 ()
标准输出 (, 局_显示)
返回 (0)

静态编译

三方支持库命令((unsigned int)ecalc_fnUnlNumImportNum, 2, v7, 0, 131082, 0x11223344, 0, -2147482879);
这很明显时让v7=0x11223344
此时v7为一个指针

跟进

继续跟进

继续跟进

此时不难看到我们的数据
经过多次探索得到它的数据结构

后面存放的是链表,每4个字节存放高位信息
val=val_head*(10**9)+val
然后用此方法探索乘,减,=

最终完整的算法
flag后半部分算法
for i in range(1,901):
input_tail=input_tail-i*0x70955fc45*i+i*0x34ED1CCB+0xD1558
if input_tail==0:
break
flag上半部分同理可得
for i in range(1,801):
input_tail=input_tail-i*0x70955fc45*i+i*0x34ED1CCB+0xD1558
if input_tail==0:
break
我们exp
import string
x=string.ascii_letters+string.digits
table=[ord(i) for i in x]
def re_num(number):
x=0
for i in range(1,number):
x=x+i*0x70955fc45*i+i*0x34ED1CCB+0xD1558
return x
def re_tail(y):
for i in range(len(y)):
for j in table:
x=j
j<<=1
j^=0x81
j>>=1
j&=0xff
if j==y[i]:
print(chr(x),end='')
def re_head(y):
for i in range(len(y)):
for j in table:
x=j
j<<=1
j^=0xbf
j>>=1
j&=0xff
if j==y[i]:
print(chr(x),end='')
input_head=[ord(i) for i in str(re_num(801))]
input_tail=[ord(i) for i in str(re_num(901))]
re_head(input_head)
re_tail(input_tail)
2023HWS_RE复现的更多相关文章
- C++复现经典游戏——扫雷
国庆小长假,当大家都去看人山人海的时候,我独自一人狂码代码.这两天想要实现的内容是Windows上的一个经典游戏——扫雷.相信90后和一些上班族对此并不陌生.然而,从win8开始,扫雷就不再是Wind ...
- [troubleshoot][archlinux][X] plasma(KDE) 窗口滚动刷新冻结(约延迟10s)(已解决,root cause不明,无法再次复现)
现象: konsole,setting等plasma的系统应用反应缓慢,在滚动条滚动时,尤为明显. 触发条件: 并不是十分明确的系统滚动升级(Syu)后,产生. 现象收集: 可疑的dmesg [ :: ...
- 时空上下文视觉跟踪(STC)算法的解读与代码复现(转)
时空上下文视觉跟踪(STC)算法的解读与代码复现 zouxy09@qq.com http://blog.csdn.net/zouxy09 本博文主要是关注一篇视觉跟踪的论文.这篇论文是Kaihua Z ...
- ShadowBroker释放的NSA工具中Esteemaudit漏洞复现过程
没有时间测试呢,朋友们都成功复现,放上网盘地址:https://github.com/x0rz/EQGRP 近日臭名昭著的方程式组织工具包再次被公开,TheShadowBrokers在steemit. ...
- CVE-2017-8464远程命令执行漏洞(震网漏洞)复现
前言 2017年6月13日,微软官方发布编号为CVE-2017-8464的漏洞公告,官方介绍Windows系统在解析快捷方式时存在远程执行任意代码的高危漏洞,黑客可以通过U盘.网络共享等途径触发漏洞, ...
- Samba远程代码执行漏洞(CVE-2017-7494)本地复现
一.复现环境搭建 搭建Debian和kali两个虚拟机: 攻击机:kali (192.168.217.162): 靶机:debian (192.168.217.150). 二.Debian安装并配置s ...
- Office远程代码执行漏洞CVE-2017-0199复现
在刚刚结束的BlackHat2017黑帽大会上,最佳客户端安全漏洞奖颁给了CVE-2017-0199漏洞,这个漏洞是Office系列办公软件中的一个逻辑漏洞,和常规的内存破坏型漏洞不同,这类漏洞无需复 ...
- Node.js CVE-2017-1484复现(详细步骤)
0x00 前言 早上看Sec-news安全文摘的时候,发现腾讯安全应急响应中心发表了一篇文章,Node.js CVE-2017-14849 漏洞分析(https://security.tencent. ...
- 【S2-052】漏洞复现(CVE-2017-9805)
一.漏洞描述 Struts2 的REST插件,如果带有XStream组件,那么在进行反序列化XML请求时,存在未对数据内容进行有效验证的安全隐患,可能发生远程命令执行. 二.受影响版本 Struts2 ...
- CVE-2017-8464复现 (远程快捷方式漏洞)
我们的攻击机IP是192.168.222.133 目标机IP是192.168.222.132 我们首先生成一个powershell msfvenom -p windows/x64/meterprete ...
随机推荐
- 2022-11-24:小团在地图上放了3个定位装置,想依赖他们进行定位! 地图是一个n*n的棋盘, 有3个定位装置(x1,y1),(x2,y2),(x3,y3),每个值均在[1,n]内。 小团在(a,
2022-11-24:小团在地图上放了3个定位装置,想依赖他们进行定位! 地图是一个n*n的棋盘, 有3个定位装置(x1,y1),(x2,y2),(x3,y3),每个值均在[1,n]内. 小团在(a, ...
- 2021-05-14:给定一个数组arr,想知道arr中哪两个数的异或结果最大。返回最大的异或结果。
2021-05-14:给定一个数组arr,想知道arr中哪两个数的异或结果最大.返回最大的异或结果. 福大大 答案2021-05-14: 前缀树.一个数,用二进制表示,0走左边分支,1走右边分支.准备 ...
- 2021-12-10:64位的浮点数和64位的有符号整数,哪个能表示的数据个数多? A.整型多。 B.浮点型多。 C.与平台有关。 D.一样多。 来自qq群。
2021-12-10:64位的浮点数和64位的有符号整数,哪个能表示的数据个数多? A.整型多. B.浮点型多. C.与平台有关. D.一样多. 来自qq群. 答案2021-12-10: 答案选A. ...
- DevEco Studio 3.1 Release | 动态共享包开发,编译更快,包更小
原文:https://mp.weixin.qq.com/s/qPvHZNZuLccAsviBcXtPWw,点击链接查看更多技术内容. 动态共享包(HSP)开发是DevEco Studio 3.1 ...
- Deferred Components-实现Flutter运行时动态下发Dart代码 | 京东云技术团队
导读 Deferred Components,官方实现的Flutter代码动态下发的方案.本文主要介绍官方方案的实现细节,探索在国内环境下使用Deferred Components,并且实现了最小验证 ...
- web自动化06-键盘操作
键盘操作 1.说明: 1). 模拟键盘上一些按键或者组合键的输入 如:Ctrl+C .Ctrl+V: 2). Selenium中把键盘的按键都封装在Keys类中 2. Keys类 导包:from se ...
- 在树莓派上实现numpy的LSTM长短期记忆神经网络做图像分类,加载pytorch的模型参数,推理mnist手写数字识别
这几天又在玩树莓派,先是搞了个物联网,又在尝试在树莓派上搞一些简单的神经网络,这次搞得是LSTM识别mnist手写数字识别 训练代码在电脑上,cpu就能训练,很快的: import torch imp ...
- Conda 为什么越来越慢?
作者:生信宝典 | 生信宝典公众号原文:https://mp.weixin.qq.com/s/OkOgN4j44MHNt1_noPVpzA Conda 为什么越来越慢? Conda 中包含的软件越来越 ...
- 从兆碱基到 Kb、KB、Bps、bps 之间的区别
由于微信不允许外部链接,你需要点击文章尾部左下角的 "阅读原文",才能访问文中链接. 生物信息很多文章都提到:DNA 序列的 100 万个碱基数据(兆碱基)大致相当于计算机 1 兆 ...
- CSS 图片加载提前占位 padding-top、padding-bottom
今天聊一个图片加载提前占位的一个问题 ,内容比较适合初学者. 起因 在响应式页面当中,图片加载之前是不知道图片高度的,加载成功图片完全撑开.如果不做提前占位会把下面的内容挤下去,页面出现抖动,就像下面 ...