HWS2021 固件安全 Write Up部分题目复现

这个当时我是菜逼,我根本不会做,现在照着wp反复的也就成功复现了三个题目(其他几个没有环境呜呜呜,也记录一下吧)

NodeMCU

binwalk解不开,直接cat bin就出来了

图片[1]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

STM

直接binwalk,解不开,尝试丢入ida进行分析

参考文章:https://www.angelic47.com/archives/97/

ida打开后直接看字符,只找到一个hello world

图片[2]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

跟一下代码

图片[3]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

v0=sub_800314()这个函数有点可疑,跟一下

图片[4]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

看一眼v1的数值,跟进byte

图片[5]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

算法就是v1元数据,v3^0x1E+3后给v0,最后char转换

尝试写个代码拼接

v1 = [0x7D, 0x77, 0x40, 0x7A, 0x66, 0x30, 0x2A, 0x2F, 0x28, 0x40, 0x7E, 0x30, 0x33, 0x34, 0x2C, 0x2E, 0x2B, 0x28, 0x34, 0x30, 0x30, 0x7C, 0x41, 0x34, 0x28, 0x33, 0x7E, 0x30, 0x7E, 0x2F, 0x31, 0x2A, 0x41, 0x7F, 0x2F, 0x28, 0x2E, 0x64]

flag_list = []
for i in range(len(v1)):
    flag = chr((v1[i] ^ 0x1E) + 3)
    flag_list.append(flag)
print("".join(flag_list))
图片[6]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

EASYBIOS

一个readme.txt,读一下

图片[7]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

看样子需要用qemu来启动,这就来

图片[8]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇
图片[9]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

启动后是一个shell系统,让我们输入getflag,内容,按照正常思路来讲,应该就需要re了,既然是固件日常binwalk跑一波

图片[10]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

分离成功,丢入ida进行分析

图片[11]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

然而并未识别成正确的pe文件,,看来分离方式有问题,丢入winhex进行手动提取

图片[12]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

寻找关键字,根据binwalk上下段进行判断具体pe位置

图片[13]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇
dd if=easybios of=112233 skip=3186244 count=2322919 bs=1

直接dd指令分割

图片[14]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

丢入ida进行分析

图片[15]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇

跟进wrong,发现他判断输入类型是否为小写,做数据转换,这里changehex跟进汇编

图片[16]-HWS2021 固件安全 Write Up部分题目复现-魔法少女雪殇
__int64 v0; // rdi
  __int64 i; // rcx
  __int64 v2; // rcx
  int v3; // edx
  int v4; // er8
  int v5; // er11
  __int64 v6; // rcx
  int v7; // er10
  int v8; // er11
  int v9; // ebx
  __int64 v10; // r9
  int v11; // edx
  __int64 result; // rax
  int v13[514]; // [rsp+0h] [rbp-808h]

  for ( i = 0i64; i != 256; ++i )
  {
    v13[i] = i;
    v13[i + 256] = (unsigned __int8)aOvmfAndEasyBio[(int)i % 18];
  }
  v2 = 0i64;
  v3 = 0;
  do
  {
    v4 = v13[v2];
    v3 = (v13[v2 + 256] + v4 + v3) % 256;
    v5 = v13[v3];
    v13[v3] = v4;
    v13[v2++] = v5;
  }
  while ( v2 != 256 );
  v6 = 0i64;
  v7 = 0;
  LOBYTE(v8) = 0;
  do
  {
    v8 = (unsigned __int8)(v8 + 1);
    v9 = v13[v8];
    v10 = (v9 + v7) % 256;
    v11 = v13[v10];
    v13[v10] = v9;
    v7 = (v9 + v7) % 256;
    v13[v8] = v11;
    result = (unsigned int)v13[(v11 + v13[v10]) % 256];
    *(_BYTE *)(v0 + v6++) ^= result;
  }
  while ( v6 != 16 );
  return result;

可以看见v0从rdi进行跟进的,这里直接写脚本即可

def print_bytes_hex(data):
    lin = ['%0x' % i for i in data]
    print("".join(lin))

magic = 'OVMF_And_Easy_Bios'
demo = [0x46, 0x77, 0x74, 0xb0, 0x27, 0x8e, 0x8f, 0x5b, 0xe9, 0xd8, 0x46, 0x9c, 0x72, 0xe7, 0x2f, 0x5e]
v13 = [0]*514
for i in range(256):
    v13[i] = i
    v13[i+256] = ord(magic[i%18])


v2 = 0
v3 = 0
new_list = []
while v2!=256:
    v4 = v13[v2]
    v3 = (v13[v2 + 256] + v4 + v3) % 256
    v5 = v13[v3]
    v13[v3] = v4
    v13[v2] = v5
    v2+=1

v6 = 0
v7 = 0
v8 = 0

while v6 != 16:
    v8 = v8 + 1
    v9 = v13[v8]
    v10 = (v9 + v7) % 256
    v11 = v13[v10]
    v13[v10] = v9
    v7 = (v9 + v7) % 256
    v13[v8] = v11
    result = v13[(v11 + v13[v10]) % 256]
    new_list.append(result)
    #(v0 + v6) ^= result
    v6 += 1
#print len(demo)
#print len(new_list)
flag_list = []
for i in range(16):
    flag_list.append(new_list[i]^demo[i])
    print(hex(new_list[i]^demo[i]))

print_bytes_hex(flag_list)

参考文章:2021HWS冬令营线上赛固件安全-WriteUp (qq.com)

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情