测试文件:https://adworld.xctf.org.cn/media/task/attachments/17574fc423474b93a0e6e6a6e583e003.zip

我们直接将Linux当前日期设置为2012-12-21,运行文件就能得到flag,不过还是要分析一下。

1.准备

获取信息

  • 64位文件

2.IDA打开

主函数main

signed __int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
size_t v3; // rbx
size_t v4; // rax
unsigned __int64 v6; // rax
unsigned __int64 v7; // rax
unsigned __int64 v8; // rsi
char *v9; // rdi
time_t timer; // [rsp+18h] [rbp-128h]
char v11[]; // [rsp+20h] [rbp-120h]
char src; // [rsp+40h] [rbp-100h]
char s; // [rsp+60h] [rbp-E0h]
unsigned __int64 v14; // [rsp+C8h] [rbp-78h]
char v15; // [rsp+D4h] [rbp-6Ch]
char v16; // [rsp+DDh] [rbp-63h]
char v17; // [rsp+E6h] [rbp-5Ah]
char v18; // [rsp+EFh] [rbp-51h]
char *v19; // [rsp+F8h] [rbp-48h]
char *v20; // [rsp+100h] [rbp-40h]
char *v21; // [rsp+108h] [rbp-38h]
char *dest; // [rsp+110h] [rbp-30h]
int *v23; // [rsp+118h] [rbp-28h]
size_t v24; // [rsp+120h] [rbp-20h]
struct tm *tp; // [rsp+128h] [rbp-18h] strcpy(v11, ".fluxfingers.net");
timer = time(0LL);
tp = localtime(&timer);
strftime(&s, 99uLL, "%Y-%m-%d", tp); // 将现在的日期放入s
v24 = strlen(&s); // v24=99
sub_B5A(&s, v24); // 将日期s进行MD5加密
v23 = &dword_2030B8; // v23为加密后的日期的一部分
snprintf(
&v18,
9uLL,
"%02x%02x%02x%02x",
(unsigned __int8)dword_2030B8,
BYTE1(dword_2030B8),
BYTE2(dword_2030B8),
HIBYTE(dword_2030B8));
v23 = &dword_2030C0;
snprintf(
&v17,
9uLL,
"%02x%02x%02x%02x",
(unsigned __int8)dword_2030C0,
BYTE1(dword_2030C0),
BYTE2(dword_2030C0),
HIBYTE(dword_2030C0));
v23 = &dword_2030B4;
snprintf(
&v16,
9uLL,
"%02x%02x%02x%02x",
(unsigned __int8)dword_2030B4,
BYTE1(dword_2030B4),
BYTE2(dword_2030B4),
HIBYTE(dword_2030B4));
v23 = &dword_2030BC;
snprintf(
&v15,
9uLL,
"%02x%02x%02x%02x",
(unsigned __int8)dword_2030BC,
BYTE1(dword_2030BC),
BYTE2(dword_2030BC),
HIBYTE(dword_2030BC));
snprintf(&src, 33uLL, "%s%s%s%s", &v18, &v17, &v16, &v15);// src为加密后的日期
v3 = strlen(&src); // v3=33
v4 = strlen(v11); // v4=16
dest = (char *)malloc(v3 + v4 + );
if ( !dest )
return 1LL;
*dest = ;
strcat(dest, &src);
strcat(dest, v11); // dest为MD5(s)+".fluxfingers.net"
v21 = sub_18A4(dest);
if ( !v21 )
return 1LL;
v6 = strlen(v21);
v20 = sub_15E0((__int64)v21, v6, &v14); // base64解密
v7 = strlen(v21);
v19 = sub_15E0((__int64)v21, v7, &v14);
if ( !v20 )
return 1LL;
v8 = v14;
v9 = v20;
sub_1858((__int64)v20, v14, (__int64)v19); // 异或0x25
((void (__fastcall *)(char *, unsigned __int64))v19)(v9, v8);
return 0LL;
}

3.代码分析

3.1 MD5加密

首先,程序将获取到的时间进行了MD5码加密

  for ( i =  * a2 + ; i %  != ; ++i )
;
v2 = i;
i /= ;
dest = calloc(v2 / + , 1uLL);
memcpy(dest, a1, a2); // 将a1中的值存入dest中
*((_BYTE *)dest + a2) = -;
*(_DWORD *)((char *)dest + i) = * a2;
for ( j = ; j < i; j += )
{
v132 = (char *)dest + j;
v140 = dword_2030B8;
v139 = dword_2030C0;
v138 = dword_2030B4;
v137 = dword_2030BC;
for ( k = ; k <= 0x3F; ++k ) // MD5码加密
{
if ( k > 0xF )
{
if ( k > 0x1F )
{
if ( k > 0x2F )
{
v135 = v138 ^ (v139 | ~v137);
v134 = * (_BYTE)k & 0xF;
}
else
{
v135 = v137 ^ v138 ^ v139;
v134 = ( * (_BYTE)k + ) & 0xF;
}
}
else
{
v135 = v139 & v137 | v138 & ~v137;
v134 = ( * (_BYTE)k + ) & 0xF;
}
}
else
{
v135 = v138 & v139 | v137 & ~v139;
v134 =
k;
}

v131 = v137;
v137 = v138;
v138 = v139;
v139 += __ROL4__(*(_DWORD *)&v132[ * v134] + *(&v3 + k) + v135 + v140, *(&v67 + k));
v140 = v131;
}
dword_2030B8 += v140;
dword_2030C0 += v139;
dword_2030B4 += v138;
dword_2030BC += v137;
}
free(dest);
}

3.2 连接字符串

将加密后的时间与“.fluxfingers.net”结合

  snprintf(&src, 33uLL, "%s%s%s%s", &v18, &v17, &v16, &v15);// src为加密后的日期
v3 = strlen(&src); // v3=33
v4 = strlen(v11); // v4=16
dest = (char *)malloc(v3 + v4 + );
if ( !dest )
return 1LL;
*dest = ;
strcat(dest, &src);
strcat(dest, v11); // dest为MD5(s)+".fluxfingers.net"

3.3 传递处理

将得到的字符串传入  v21 = sub_18A4(dest);处理

char *__fastcall sub_18A4(const char *a1)
{
char *v2; // rax
ns_rr v3; // [rsp+10h] [rbp-24A0h]
ns_msg v4; // [rsp+430h] [rbp-2080h]
char s; // [rsp+480h] [rbp-2030h]
u_char v6; // [rsp+1480h] [rbp-1030h]
char *dest; // [rsp+2488h] [rbp-28h]
size_t n; // [rsp+2490h] [rbp-20h]
char *v9; // [rsp+2498h] [rbp-18h]
char *src; // [rsp+24A0h] [rbp-10h]
int v11; // [rsp+24ACh] [rbp-4h] v11 = __res_query(a1, , , &v6, ); // 字符串作为查询域名传入,返回消息的长度
if ( v11 < )
return 0LL;
ns_initparse(&v6, v11, &v4); // 获得控制句柄
v11 = v4._counts[];
ns_parserr(&v4, ns_s_an, , &v3); // 解析具体区域获取记录类型数据
ns_sprintrr(&v4, &v3, 0LL, 0LL, &s, 0x1000uLL);// 将字段转换为演示文稿格式
v2 = strchr(&s, );
src = v2 + ;
if ( v2 == (char *)-1LL )
return 0LL;
v9 = strchr(src, );
if ( !v9 )
return 0LL;
n = v9 - src;
dest = (char *)malloc(v9 - src + );
strncpy(dest, src, n);
dest[n] = ;
return dest;
}

3.4 base64解密

再对得到的字符串进行base64解密

  v6 = strlen(v21);
v20 = sub_15E0((__int64)v21, v6, &v14); // base64解密
v7 = strlen(v21);
v19 = sub_15E0((__int64)v21, v7, &v14);
char *__fastcall sub_15E0(__int64 a1, unsigned __int64 a2, _QWORD *a3)
{
char *v4; // rax
char *v5; // rax
char *v6; // rax
_QWORD *v7; // [rsp+8h] [rbp-158h]
char v8; // [rsp+28h] [rbp-138h]
unsigned __int8 v9; // [rsp+29h] [rbp-137h]
unsigned __int8 v10; // [rsp+2Ah] [rbp-136h]
char v11; // [rsp+2Bh] [rbp-135h]
char v12[]; // [rsp+2Ch] [rbp-134h]
char v13; // [rsp+2Eh] [rbp-132h]
char v14; // [rsp+2Fh] [rbp-131h]
char s[]; // [rsp+30h] [rbp-130h]
char v16; // [rsp+6Dh] [rbp-F3h]
char v17; // [rsp+13Fh] [rbp-21h]
char *v18; // [rsp+140h] [rbp-20h]
size_t size; // [rsp+148h] [rbp-18h]
unsigned __int64 i; // [rsp+150h] [rbp-10h]
char *v21; // [rsp+158h] [rbp-8h] v7 = a3;
memset(s, , 0x100uLL);
for ( i = 0LL; i <= 0x3F; ++i )
s[(unsigned __int8)aAbcdefghijklmn[i]] = i; // base64解密
v16 = ;
size = 0LL;
for ( i = 0LL; i < a2; ++i )
{
if ( s[*(unsigned __int8 *)(a1 + i)] != - )
++size;
}
if ( size & )
return 0LL;
v18 = (char *)malloc(size);
v21 = v18;
if ( !v18 )
return 0LL;
size = 0LL;
for ( i = 0LL; i < a2; ++i )
{
v17 = s[*(unsigned __int8 *)(a1 + i)];
if ( v17 != - )
{
v12[size] = *(_BYTE *)(a1 + i);
*(&v8 + size++) = v17;
if ( size == )
{
v4 = v21++;
*v4 = (v9 >> ) | * v8;
v5 = v21++;
*v5 = (v10 >> ) | * v9;
v6 = v21++;
*v6 = v11 | (v10 << );
size = 0LL;
}
}
}
if ( v21 > v18 )
{
if ( v13 == )
{
v21 -= ;
}
else if ( v14 == )
{
--v21;
}
}
*v7 = v21 - v18;
return v18;
}
.rodata:0000000000001E80 aAbcdefghijklmn db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/%'

3.5 异或操作

最后对解密后的字符串进行异或0x25

unsigned __int64 __fastcall sub_1858(__int64 a1, unsigned __int64 a2, __int64 a3)
{
unsigned __int64 result; // rax
unsigned __int64 i; // [rsp+20h] [rbp-8h] for ( i = 0LL; ; ++i )
{
result = i;
if ( i >= a2 )
break;
*(_BYTE *)(a3 + i) = *(_BYTE *)(a1 + i) ^ 0x25;
}
return result;
}

3.6 总结

实际上就是将获得的日期date进行

base64(sub_18A4(MD5(date)+".fluxfingers.net")).decode() ^ 0x25

因此我们获取到正确时间即可。联系到玛雅社会,最出名的就是玛雅预言,因此我们可以判断这个时间就是2012-12-21

4.get flag!

flag{e3a03c6f3fe91b40eaa8e71b41f0db12}

攻防世界--The_Maya_Society的更多相关文章

  1. CTF--web 攻防世界web题 robots backup

    攻防世界web题 robots https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=506 ...

  2. CTF--web 攻防世界web题 get_post

    攻防世界web题 get_post https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=5 ...

  3. 攻防世界 web进阶练习 NewsCenter

    攻防世界 web进阶练习 NewsCenter   题目是NewsCenter,没有提示信息.打开题目,有一处搜索框,搜索新闻.考虑xss或sql注入,随便输入一个abc,没有任何搜索结果,页面也没有 ...

  4. 【攻防世界】高手进阶 pwn200 WP

    题目链接 PWN200 题目和JarvisOJ level4很像 检查保护 利用checksec --file pwn200可以看到开启了NX防护 静态反编译结构 Main函数反编译结果如下 int ...

  5. XCTF攻防世界Web之WriteUp

    XCTF攻防世界Web之WriteUp 0x00 准备 [内容] 在xctf官网注册账号,即可食用. [目录] 目录 0x01 view-source2 0x02 get post3 0x03 rob ...

  6. 攻防世界 | CAT

    来自攻防世界官方WP | darkless师傅版本 题目描述 抓住那只猫 思路 打开页面,有个输入框输入域名,输入baidu.com进行测试 发现无任何回显,输入127.0.0.1进行测试. 发现已经 ...

  7. 攻防世界 robots题

    来自攻防世界 robots [原理] robots.txt是搜索引擎中访问网站的时候要查看的第一个文件.当一个搜索蜘蛛访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在, ...

  8. 【攻防世界】 高手进阶区 Recho WP

    0x00 考察点 考察点有三个: ROP链构造 Got表劫持 pwntools的shutdown功能 0x01 程序分析 上来三板斧 file一下 checksec --file XXX chmod ...

  9. CTF -攻防世界-crypto新手区(5~11)

    easy_RSA 首先如果你没有密码学基础是得去恶补一下的 然后步骤是先算出欧拉函数 之后提交注意是cyberpeace{********}这样的 ,博主以为是flag{}耽误了很长时间  明明没算错 ...

随机推荐

  1. Pytest安装介绍--使用(html报告)

    Pytes是 一个单元测试框架,可以生成html报告. #卸载# pip uninstall pytest#安装# pip install -U pytest# 查看# pytest --versio ...

  2. JavaScript输出

    JavaScript不提供任何的内建或是打印方式 JavaScript的显示方案主要有以下四种: window.alert()  写入警告框 document.write()  写入 HTML 输出 ...

  3. 巧用SimpleDateFormat将Date类型数据按照规定类型转换。

    在使用SimpleDateFormat之前,我们来了解一下这个类.SimpleDateFormat is a concrete class for formatting and parsing dat ...

  4. [BZOJ3781]:小B的询问(离线莫队算法)

    题目传送门 题目描述 小B有一个序列,包含$N$个$1~K$之间的整数.他一共有$M$个询问,每个询问给定一个区间$[L...R]$,求$\sum \limits_{i=1}^{K}c(i)^2$的值 ...

  5. Handling Configuration Changes with Fragments

    This post addresses a common question that is frequently asked on StackOverflow: What is the best wa ...

  6. mvn 与 pom.xml

    mvn 安装 wget http://mirrors.hust.edu.cn/apache//maven/maven-3/3.0.5/binaries/apache-maven-3.0.5-bin.t ...

  7. BBED ORA-00600: internal error code, arguments: [16703], [1403], [20], [], [], [], [], [], [], [], [], []

    BBED模拟并修复 删除:$ORACLE_HOME/rdbms/admin/prvtsupp.plb SQL> alter database open;alter database open*E ...

  8. [转] python关于ctypes使用char指针与bytes相互转换的问题

    最近研究人脸识别,需要用python调用so动态库,涉及到c/c++中的指针字符串转Python的bytes对象的问题. 按照ctypes的文档,直观方式是先创建对应的类型数组,再将指针取地址一一赋值 ...

  9. day47—JavaScript事件基础应用

    转行学开发,代码100天——2018-05-02 1.事件对象 JavaScript中事件对象通常用定义变量ev或event表示.为了兼顾浏览器兼容问题,定义事件对象为 var oEvent = ev ...

  10. 006-unity3d GUI初识、贴图、自定义鼠标指针

    一.gui概念 无论摄像机拍摄到的图像怎么变换,GUI永远显示在屏幕上,不受变形.碰撞.光照的影响.对话框.战斗值.能量等.示例:用手机录像,摄像的参数不会随着拍摄场景变换.GUI基础GUI部分是每帧 ...