CTF · 2024年2月21日

SICTF wp

1. OSINT

1.1. 签退(solved)

思路:谷歌识图 重点是可以看到一个疑似蜘蛛网的玩意 然后可以查到推特这里放出个链接

https://www.reddit.com/user/Lovell_mae/?rdt=40824还有篇推特更重要https://twitter.com/YesReallyAngel/status/1163448987803901953

故此可以确定loopstreet 谷歌街景慢慢找就行还是很明显的 我是从头开始找的 大概找到第四个十字路口就有了

strandst和loop交叉处,使用街景可以发现拍摄地在strandst 最明显的是STEERS的紫色招牌和几个火焰旗帜开普敦

SICTF{南非_开普敦_StrandSt_STEERS}

1.2. 真的签到(solved)

摩天轮 谷歌识图

思路:重点 观察摩天轮架子的结构模样 快速排查最后发现珠海之星的很相似另外题目说是省 所以迅速排除几个直辖市和特别行政区配合图片的绿植猜测在南方,再结合经济确定广东

最后找到 珠海之星

1.3. 这才是签到(solved)

谷歌识图轻松解决前三个空。最后一个通过给出的hint 结合地点是景点很明显可以找到(才怪,爆破一堆地址其实可以发现左中右三个小道都没景点,右侧再右边的一条小道 进去直走右拐有个教堂,就这这个啦SICTF{意大利_威尼斯_GondolaDanieli_ChiesadiSanZaccaria}

1.4. [签到]OSINT签到(solved)

百度地图识图直出,谷歌的反而不好用海口红城湖公园SICTF{x省_x市_x区_x公园}

2. Reverse

2.1. [签到]Baby_C++(solved)

直接转ascii

# numbers = "54,67,54,70,55,54,54,53,55,56,54,70,55,53,55,69" # # number_list = [int(x) for x in numbers.split(',')] # char_list = [chr(x) for x in number_list] # result = "".join(char_list) # # print(result) numbers = """0x00, 0x53, 0x49, 0x43, 0x54, 0x46, 0x7B, 0x34, 0x65, 0x34,    0x37, 0x34, 0x62, 0x38, 0x61, 0x2D, 0x39, 0x64, 0x66, 0x36,    0x2D, 0x34, 0x35, 0x34, 0x62, 0x2D, 0x39, 0x65, 0x61, 0x36,    0x2D, 0x64, 0x34, 0x66, 0x35, 0x65, 0x33, 0x37, 0x63, 0x64,    0x35, 0x31, 0x66, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00""" # 移除多余的空格并分割以获取十六进制数列表 number_strings = numbers.replace(" ", "").split(',') # 将每个十六进制数字符串转换为整数(去除“0x”前缀) number_list = [int(x, 16) for x in number_strings] # 将整数列表转换为字符列表 char_list = [chr(x) for x in number_list] 

SICTF{4e474b8a-9df6-454b-9ea6-d4f5e37cd51f}

2.2. ezpyc(solved)

简单数独

import hashlib # 初始化一个10x10的列表,用于存储密码矩阵 k = [     ['#'] * 10,      ['#', 0, 1, 9] + [0] * 3 + [3, 0, 7],      ['#', 8] + [0] * 8,      ['#', 4] + [0] * 5 + [2, 0, 0],      ['#'] + [0] * 4 + [3] + [0] * 4,      ['#', 5] + [0] * 3 + [6, 0, 0, 2, 0],      ['#', 0, 7] + [0] * 5 + [3, 1],      ['#'] + [0] * 9,      ["'#'", 0, 0, 8, 0, 9, 0, 7, 0, 0],      ['#'] + [0] * 9      ] cnt = 0 s = str(int(input(), 16)) try:     for x in s:         # 检查输入的字符是否为 1-9 的数字         if x not in [str(t) for t in range(1, 10)]:             # 如果不是数字,则将对应位置的 s 数组设置为 1             s[cnt + 43690] = 1    ##八成没用         for i in range(1, len(k)):             for j in range(1, len(k[i])):                 if k[i][j] == 0:                     # 将密码矩阵中的 0 替换为 s 数组中的对应值                     k[i][j] = int(s[cnt])                     cnt += 1         else:             for i in range(1, len(k)):                 for j in range(1, len(k)):                     if j not in k[i]:                         # 如果密码矩阵中某行缺少数字,则将对应位置的 s 数组设置为 0                         s[cnt + 3735928559] = 0             else:                 for i in range(1, len(k)):                     tmp = []                     for j in range(1, len(k)):                         tmp.append(k[j][i])                     else:                         for j in range(1, len(k)):                             if j not in tmp:                                 # 如果密码矩阵中某列缺少数字,则将对应位置的 s 数组设置为 1                                 s[cnt + 3735928559] = 1                         else:                             for i in range(1, len(k), int(len(k) ** 0.5)):                                 for j in range(1, len(k), int(len(k) ** 0.5)):                                     square = [k[x][y] for x in range(i, i + 3) for y in iter((range(j, j + 3)))]                                     for t in range(1, len(k)):                                         if t not in tmp:                                             # 如果密码矩阵中某个 3x3 的子矩阵缺少数字,则将对应位置的 s 数组设置为 2                                             s[cnt + 3735928559] = 2                                     else:                                         # 计算 s 数组的 MD5 哈希值,并输出最终结果                                         print('SICTF{%s}' % hashlib.md5(s.encode()).hexdigest())                                         input() except Exception as e:     try:         pass     finally:         e = None         del e 

找个数独解密在线网站解一下

2456835127469673891564192578837194925486324875196156342796214853MD5一下SICTF{b847b62aa1e961bad1ec8d3a1c932bd9}

2.3. ArtBreaker

题目描述:艺术毁灭者?     出题人:TokameinE 

控制流缩小 这真的是re吗

2.4. SWEETtofu(solved)

静态看不出来东西的

动调到具体函数 具体位置大概是个用toka命名的地方(好自恋观察寄存器可以看到 xor操作(懒狗不想再调试一次了,不想开虚拟机了,体谅一下总之 在进入我们找到的主函数后使用f7跟进 不要用f8大概位置在 if里面的sub_55fc 点进去有一个Toka 然后还套着一个函数 反正就是这个点 动调到这里记住f7进去然后发现 一个和f异或 以及对比 这个就不用多说了吧 写个脚本出了

# 定义原始数组 ida_chars ida_chars = [ 0x00, 0x0A, 0x07, 0x01, 0x1D, 0x3F, 0x09, 0x13, 0x39, 0x07, 0x08, 0x02, 0x39, 0x2F, 0x39, 0x21, 0x09, 0x02, 0x41, 0x15, 0x39, 0x25, 0x14, 0x03, 0x07, 0x12, 0x0F, 0x09, 0x08, 0x47, 0x22, 0x09, 0x08, 0x41, 0x12, 0x39, 0x04, 0x03, 0x39, 0x15, 0x03, 0x14, 0x0F, 0x09, 0x13, 0x15, 0x47, 0x1B, 0x00, 0x00, ] # 假设 f 是一个已知的值 f = 0x66  # 可以替换为任意你想要异或的值 # 计算异或结果并存储到新的列表 xor_result 中 xor_result = [char ^ f for char in ida_chars] # 打印异或结果 for i, result in enumerate(xor_result):     print(f"0x{result:02X},") 

flag{You_and_I_God’s_Creation!Don’t_be_serious!}ff# Reverse

2.4.1. [签到]Baby_C++(solved)

直接转ascii

# numbers = "54,67,54,70,55,54,54,53,55,56,54,70,55,53,55,69" # # number_list = [int(x) for x in numbers.split(',')] # char_list = [chr(x) for x in number_list] # result = "".join(char_list) # # print(result) numbers = """0x00, 0x53, 0x49, 0x43, 0x54, 0x46, 0x7B, 0x34, 0x65, 0x34,    0x37, 0x34, 0x62, 0x38, 0x61, 0x2D, 0x39, 0x64, 0x66, 0x36,    0x2D, 0x34, 0x35, 0x34, 0x62, 0x2D, 0x39, 0x65, 0x61, 0x36,    0x2D, 0x64, 0x34, 0x66, 0x35, 0x65, 0x33, 0x37, 0x63, 0x64,    0x35, 0x31, 0x66, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    0x00, 0x00, 0x00, 0x00""" # 移除多余的空格并分割以获取十六进制数列表 number_strings = numbers.replace(" ", "").split(',') # 将每个十六进制数字符串转换为整数(去除“0x”前缀) number_list = [int(x, 16) for x in number_strings] # 将整数列表转换为字符列表 char_list = [chr(x) for x in number_list] 

SICTF{4e474b8a-9df6-454b-9ea6-d4f5e37cd51f}

2.5. [进阶]CloseMe

❤杂鱼❤,你能关的掉吗~~❤ (虽然不是病毒,不过如果要运行的话还是建议虚拟机吧^_^), 请找到能够正常关闭的条件 (即不通过直接终止进程的方式或者程序崩溃导致的关闭) 

温馨提示,不要直接打开这道题很乱 但是我们有椰奶的提示 加密很简单 脚本可能就几行这个时候我们推测一下,异或或者移位或者加减 这是做这道题目前的心理准备

那么开始写这道题

2.5.1. 第一步

第一个难点,不知道是不是我IDA的问题 许多函数我们进去F5会发现一堆jump out爆红说实话我一开始还挺难绷的 后面发现直接tab切一下然后c一下就好了。标红的地方虽然多 但是我们可以慢慢c 别急

2.5.2. 第二步

在可以基础f5过后我们开始分析函数main函数先进第一个sub看看看了眼控制流 巨丑陋 那得认真看了在此之前我们可以通过虚拟机打开一下这个程序(当然 发现要点击 是和否结合一段很有趣的代码chatgpt分析一下

这段代码的逻辑是在逐个检查内存地址v63处的多个连续字节,并计算一个基于这些字节值的索引。每个字节被检查是否大于1,如果是,则跳转到LABEL_3标签。如果不是,则将该字节视为二进制权重的一部分来累积一个整数值。 在二进制中,10101可以表示为十进制数5,这里看起来是作为权重因子使用。然而,在实际的代码中并没有明确体现10101二进制模式,而是采用了10进制的10作为权重因子(例如10 * v26, 100 * v27...)。 代码片段最后的部分是一个复杂的嵌套乘法表达式,它通过一系列的10倍权重将各个字节值相加来计算一个整数值。这个计算过程类似于将每个字节视为一个多位数的每一位,然后将它们按照位置(从低位到高位)组合成一个大的数字。 但是需要注意的是,代码中还包括对lpWindowName指针的引用,这并不是一个简单的数值,而是一个指向字符串的指针,其参与计算的方式并不清晰且可能不合法,因为直接将指针地址当作数值参与数学运算通常是错误的做法。此外,(unsigned __int8 *)(v63 + 10) 被赋值给 lpWindowName,这可能是试图解析结构体或数据包中的字符串指针,但这样的做法具有很大的风险,容易引发未定义行为或者程序崩溃。 这段代码片段在做一系列检查和计算,主要可以分为以下几个步骤:     从内存地址 v63 开始连续读取多个字节(unsigned __int8 类型)并逐个检查它们是否大于1。如果任何一个字节大于1,则跳转到标签 LABEL_3。     如果所有字节都不大于1,则开始一个复杂的索引计算过程。该过程通过将每个字节的值与10的不同次幂相乘,并将结果累加起来形成一个整数。例如,第1个字节 v26 的值乘以10^0,第2个字节 v27 的值乘以10^1,依此类推。这种计算方式类似于将这些字节视为一个多字节无符号整数的一部分。     特别需要注意的是,这里还包括对一个指向宽字符串 (LPCWSTR) 的指针 lpWindowName 的引用,其值是通过 (unsigned __int8 *)(v63 + 10) 获得的。然后这个指针被当作数值参与了计算,但通常情况下这样做是不合理的,因为指针本身是一个地址,而不是可以用于数学运算的数值。     在计算过程中,虽然没有直接体现10101二进制模式,但是它使用了10作为权重因子,这可能是因为作者试图模拟类似二进制位权的效果,即将各个字节看作多位数中的不同位进行组合。 然而,这段代码可能存在错误或未定义行为,特别是在处理 lpWindowName 指针的方式上,它不适合用作数值计算,而应该被正确地解释为一个指向数据的指针。此外,如果此段代码是为了解析某种结构化的数据或者协议,那么这种方式显得非常原始且容易出错,一般推荐使用更明确的数据结构和解析方法来避免潜在问题。 

总结一下就是它通过一系列的10倍权重将各个字节值相加来计算一个整数值 可以猜测到我们点击的是否会被看做1或0放入最后进行解密。

因为提前得知加密逻辑简单,所以我们大概率猜测明文即使被加密也能被我们肉眼识别出来,所以

2.5.3. 第三步****

找判断。事已至此从后往前找,来当电子帕鲁。个人的思路是通过得到的大数进行链式追溯,对于函数直接默认赋值,可能加密藏在里面了,但是没必要。结合我们找的if判断,以及大数,并排除掉size相关函数。真相只有一个D2_5下个断点输点值进去(就是按是和否啦)我们试一下 0000111100001111结果是 0011110000111100猜测一下 加密就是左移两位那么 1010100111110001端序转换一下对应1000111110010101右移转换得到 0110 0011 1110 0101没有问题A9F1~~~~~那么最后来爆杀椰奶吧,实机打开一下程序,GGSICTF{0110001111100101}

3. MISC

3.1. WHO?WHO?WHO

这道题是和学姐合作写的,我在后面负责了部分思路U2FsdGVkX19uvldJ6CGUNff3B28QEdIjZqgUh98K+/0J16ELU8WVQydohw4P5+2MjbhTLQHNOpcoOd7kSRgy8pwpovCmimdD8M0IbYUeXjNKYePL/WP4PCMaOJHAW3HRb7IEoDDH1NYh3o5NwMmcFEqy1ujf72VgQIQkaeYFFFE=

U2Fsd开头识别出rabbit提示是树木是渣男,就是rabbit的key

GTAGAGCTAGTCCTT{GGGTCACGGTTC_GGGTCACGGTTC_GAACGGTTC_GTAGTG_GCTTCA_GTAGACGTGGCGGTG_GTAGACTCA_TATGACCGG_GCTCGGGCT}很眼熟,DNA秒了

SICTF{Q1A0_Q1A0_GA0_SU_N1_SHUMU_SH1_ZHA_NAN}