Loading

巅峰极客 决赛 re wp

misc

开端:strangeTempreture

根据提示 温度传感器有异常数据

image-20220824180931796

看到modbus中的reg0 绝大多数都是0或者27 但也有很大的数 猜测这就是温度

导出流量包到json

先正则匹配拿

with open("1.json","r",encoding="utf-8") as f:
    a=f.read()
a=a.split("\n")
d=[]
for x in a:
    if "Register 0 (UINT16):" in x:
        print(x)

再手敲对应的异常的数

d=[23149,30824,23091,29493,20018,19053,23127,18807,19833,12653,22868,22122,19543,18024,20077,22900,22871,20856,23123,12341,22906,22123,19834,26730,20090,20784,20311,22073]
for x in d:
    print(hex(x)[2:].zfill(4),end="")

得到

5a6d78685a3373354e324a6d5a5749774d79316d5954566a4c5746684e6d5974595751785a533035597a566b4d7a686a4e7a51304f575639

image-20220824181134781

得到base64

image-20220824181145569

得到flag

1-3:babyProtocol

题目说控制流量 只用看udp即可

image-20220824181341760

可以看到data中有两个字节一直在变 其中一个都是可见字符

先把所有udp导出到json

再尝试提取这两个字节

import re

with open("udp.json","r",encoding="utf-8") as f:
    a=f.read()
a=a.split("\n")
e=[]
for x in a:
    if "data.data" in x:
        e.append(x.split(":"))
        print(x)
for i in range(len(e[0])):
    d1=[x[i] for x in e]
    f=""
    for x in d1:
        f+=x
    print(f)

提取出之后hex转ascii

发现其中一个是

image-20220824181521527

一眼flag 但是顺序什么的不对 猜测另一个字节是字符顺序

a="0101030b080c11151a1e2718050305060a0c141719191b1c1e271804030405060708090d0e0a090e0f0f140e16191c27270102030405060708090a0b0c0d0e0f101112131415161728191a1b1c1d1e1f202122232425262718251d060401021024091006222426200202050b11261c04080d0a081a20"
b="6666616462393830653835647b617b363439353963632d643835646761677b363862333264343364383835643363643535666c61677b3638623334643932643861383434353033397d63652d6436383139643233363264356432363667666c6136336136323664396c6c7b6438646467623234626539"
c='00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",80",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",80",00",00",00",00",00",00",00",00",00",00",80",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",80",00",00",80",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",00",'.replace('"','').replace(",","")
eddd_a="ffadb980e85d{a{64959cc-d85dgag{68b32d43d885d3cd55flag{68b34d92d8a8445039}ce-d6819d2362d5d266gfla63a626d9ll{d8ddgb24be9"
tem=[0]*1000
a=re.findall(".{2}",a)
c=re.findall(".{2}",c)
for index in range(len(a)):
    x=int(a[index],16)
    tem[x]=eddd_a[index]
    print(str(x).zfill(2),eddd_a[index],c[index])
print(tem)

得到flag{68b34d92d8a8445039dce-d6819d2362d5}

但是不对 这时候返回去看 其实还有一个字节 (最后一个)有变化 只有80和00两种

尝试将80的字符删掉

即flag{68b34d92d88445039dced6819d2362d5}

re

easy_mb

go arm 跑不起来 qemu也没跑起来

直看到左边

image-20220824182054035

点开一看 Encrypt有内容 Decrypt没内容 稳了

然后开始几个小时的不知道干嘛的找enc和key时间

想了半天想起来&31好像是rc5

先尝试化简一下加密逻辑

image-20220824182215152

确实是RC5

然后找enc和key

image-20220824182332612

client里面看到一个指针调用 上面是New 猜测这个就调用的Encrypt

右键 set call type改一下

根据rc5的特点和byte_145A30长8字节 这个就是enc

最顶上调用了一个byte_146DD0 长16字节 这个是原始密钥

然后偷脚本改脚本

#include <stdio.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include <iostream>
#include <cstring>
using namespace std;
#define ROTL32(x, c) (((x) << (c)) | ((x) >> (32 - c)))
#define ROTR32(x, c) (((x) >> (c)) | ((x) << (32 - c)))
#define ROTL(x, y) (((x) << (y & (32 - 1))) | ((x) >> (32 - (y & (32 - 1)))))
#define ROTR(x, y) (((x) >> (y & (32 - 1))) | ((x) << (32 - (y & (32 - 1)))))
int w = 32; //字长 32bit 4字节
int r = 12; // 12;//加密轮数12
int b = 16; //主密钥(字节为单位8bit)个数  这里有16个
int t = 26; // 2*r+2=12*2+2=26
int c = 4;  //主密钥个数*8/w = 16*8/32
void generateChildKey(uint8_t *KeyK, uint32_t *ChildKeyS)
{
  // const double e = 2.718281828459;
  // const double Phia = 1.618033988749;

  int PW = 0xB7E15163; // 0xb7e1;
  int QW = 0x9E3779B9; // 0x9e37;//genggai
  int i;
  int u = w / 8; // b/8;
  uint32_t A, B, X, Y;
  uint32_t L[4]; // c=16*8/32
  A = B = X = Y = 0;
  //初始化数组S
  ChildKeyS[0] = PW;
  printf("\n初始子密钥(没有主密钥的参与):\n%.8X ", ChildKeyS[0]);
  for (i = 1; i < t; i++) // t=26
  {
    if (i % 13 == 0)
      printf("\n");
    ChildKeyS[i] = (ChildKeyS[i - 1] + QW);
    printf("%.8X ", ChildKeyS[i]);
  }
  printf("\n");

  //将K数组转换为L数组
  for (i = 0; i < c; i++) //初始化L数组c=8
  {
    L[i] = 0;
  }

  for (i = b - 1; i != -1; i--) // b=16  转换主密钥数组(16个 单位为8bit)为L数组(8个单位为16bit),数组L每一元素长为16bit,数组K每一元素长为8bit
  {
    L[i / u] = (L[i / u] << 8) + KeyK[i];
  }
  printf("\n把主密钥变换为4字节单位:\n");
  for (i = 0; i < c; i++) // 16进制输出gaidong
  {
    printf("%.8X ", L[i]);
  }
  printf("\n\n");

  //产生子密钥,存储在ChildKeyS中
  for (i = 0; i < 3 * t; i++)
  {
    X = ChildKeyS[A] = ROTL(ChildKeyS[A] + X + Y, 3);
    A = (A + 1) % t;
    Y = L[B] = ROTL(L[B] + X + Y, (X + Y));
    B = (B + 1) % c;
  }
  printf("生成的子密钥(初始主密钥参与和初始子密钥也参与):");
  for (i = 0; i < t; i++) // 16进制输出
  {
    if (i % 13 == 0)
      printf("\n");
    printf("0X%.8X, ", ChildKeyS[i]);
  }
  printf("\n\n");
}
/**5、    加密函数
  加密函数
*/
void Encipher(uint32_t *In, uint32_t *Out, uint32_t *S)
{
  uint32_t X, Y; //定义两个16位存储器
  int i, j;
  for (j = 0; j < 2; j += 2)
  {
    X = In[j] + S[0];     // In[j]+S[0];
    Y = In[j + 1] + S[1]; // In[j+1]+S[1];
    for (i = 1; i <= 12; i++)
    {
      X = ROTL((X ^ Y), Y) + S[2 * i];     // X=ROTL((X^Y),Y) + S[2*i];   异或,循环移位,相加 //ROTL(x,y) (((x)<<(y&(w-1))) | ((x)>>(w-(y&(w-1)))))
      Y = ROTL((Y ^ X), X) + S[2 * i + 1]; // Y=ROTL((Y^X),X) + S[2*i+1];
    }
    Out[j] = X;
    Out[j + 1] = Y; //密文
  }
}
void Decipher(uint32_t *In, uint32_t *Out, uint32_t *S)
{
  int i = 0, j;
  uint32_t X, Y;
  for (j = 0; j < 2; j += 2)
  {
    X = In[j];
    Y = In[j + 1];
    for (i = 12; i > 0; i--)
    {
      Y = ROTR(Y - S[2 * i + 1], X) ^ X; // Y = ROTR(Y-S[2*i+1],X)^X;相减,循环移位,异或  //ROTR(x,y) (((x)>>(y&(w-1))) | ((x)<<(w-(y&(w-1)))))
      X = ROTR(X - S[2 * i], Y) ^ Y;     // X = ROTR(X-S[2*i],Y)^Y;
    }
    Out[j] = X - S[0];     // Out[j]=X - S[0];
    Out[j + 1] = Y - S[1]; //明文 Out[j+1]=Y - S[1];
  }
}
int main()
{
  uint8_t inkey[16] = {
      0x2D, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xB3, 0x00, 0x95, 0x2C, 0x49, 0x1E, 0x48, 0x81, 0xFF, 0x48};
  uint32_t key[26] = {0};
  generateChildKey(inkey, key);
  uint32_t v[2] = {0x73189ACE, 0x7C282BAA};
  uint32_t t[3] = {0};
  // decode(v, key);
  Decipher(v, t, key);
  puts((char *)t);
}

得到8t9Dl3Xm

image-20220824183602895

然后流量包里面标明寄存器是UINT16 两个字节 然后按小端序即可

t8D93lmX

posted @ 2022-08-25 12:53  FW_ltlly  阅读(184)  评论(0编辑  收藏  举报