巅峰极客 决赛 re wp
misc
开端:strangeTempreture
根据提示 温度传感器有异常数据
看到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
得到base64
得到flag
1-3:babyProtocol
题目说控制流量 只用看udp即可
可以看到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
发现其中一个是
一眼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也没跑起来
直看到左边
点开一看 Encrypt有内容 Decrypt没内容 稳了
然后开始几个小时的不知道干嘛的找enc和key时间
想了半天想起来&31好像是rc5
先尝试化简一下加密逻辑
确实是RC5
然后找enc和key
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
然后流量包里面标明寄存器是UINT16 两个字节 然后按小端序即可
t8D93lmX