脑洞da开-CTF做题经验分享

作为一个 ctfer 做题时的思维真的太重要了,有的题明明很简单却总是卡在最后一步,以几个题为例说一下啥是逆向思维和发散思维

逆向思维

逆向思维当然在逆向中是最常用的,但是misc,web中也会遇到

一个misc题:

# js逆向算法
/**
 * Pseudo md5 hash function
 * @param {string} string
 * @param {string} method The function method, can be 'ENCRYPT' or 'DECRYPT'
 * @return {string}
 */
function pseudoHash(string, method) {
  // Default method is encryption
  if (!('ENCRYPT' == method || 'DECRYPT' == method)) {
    method = 'ENCRYPT';
  }
  // Run algorithm with the right method
  if ('ENCRYPT' == method) {
    // Variable for output string
    var output = '';
    // Algorithm to encrypt
    for (var x = 0, y = string.length, charCode, hexCode; x < y; ++x) {
      charCode = string.charCodeAt(x);
      if (128 > charCode) {
        charCode += 128;
      } else if (127 < charCode) {
        charCode -= 128;
      }
      charCode = 255 - charCode;
      hexCode = charCode.toString(16);
      if (2 > hexCode.length) {
        hexCode = '0' + hexCode;
      }
      
      output += hexCode;
      
    }
    // Return output

    return output;
  } else if ('DECRYPT' == method) {
    // DECODE MISS
    // Return ASCII value of character
    return string;
  }
}
document.getElementById('password').value = pseudoHash('19131e18041b1d4c47191d19194f1949481a481a1d4c1c461b4d484b191b4e474f1e4b1d4c02', 'DECRYPT');

看到这个题目一般可能直接想到去逆推过程,写一个逆向脚本

import re
str = "19131e18041b1d4c47191d19194f1949481a481a1d4c1c461b4d484b191b4e474f1e4b1d4c02"

strs = re.findall(".{2}", str)

for i in strs:
    item = 255-int(i, 16)
    if item > 128:
        item = item-128
    print(chr(item), end="")

如果你的脚本能力不太行,或者短时间内想不过来逆向过程,可以用另一种方法

仔细看下 js 脚本,是将输入的一个字符变成了两个字符,而且是固定的,比如 a 加密之后是 1e

脑洞da开-CTF做题经验分享

那么就可以直接把26个英文字符加数字全部加密一遍,19131e18041b1d4c47191d19194f1949481a481a1d4c1c461b4d484b191b4e474f1e4b1d4c02然后替换为英文字符就ok了

pseudoHash('abcdefghijklmnopqrstuvwxyz0123456789{}', 'ENCRYPT');
'1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706054f4e4d4c4b4a494847460402'

新建一个文档把字符放进去

因为 terminal 是等宽字体,可以在这里做参考,然后文本中 ctrl+h 替换第一排字符串

脑洞da开-CTF做题经验分享

脑洞da开-CTF做题经验分享

最终得到flag

flag{db38fbff0f67e7eb3c9d274fd180a4b3}

当然如果脚本写的够快,别用这种方法,只是提供一种思路

web中可能会出现游戏题目,做这种题目是就需要多方面考虑

比如2021莲城杯-Minesweepe

题目提供了三个难度的扫雷,分别是flag的三部分,如果能玩通关是可以拿到flag的,但是不是每个人都是游戏高手,靠玩游戏通过花费的时间要比较多,而且这是一个ctf题,当然会有别的方法去拿到flag

脑洞da开-CTF做题经验分享

这个题就是一个js题目,但是在源码中flag是被编码的,和上题类似你可以用逆向的方法倒推出flag

但是还有更简单的方法,你想一想,作为一个 js 本地扫雷游戏,需要啥数据直接改不就行了,找找有啥功能点、游戏是如何计分的、游戏有啥加分道具,改改改

以这个题目为例,发现js中保存了炸弹数量,那改就完了

脑洞da开-CTF做题经验分享

就出现了第一张图的效果,直接通过

发散思维

发散思维就是联想呗,比如给你一句话你就能扩展做题思路的题目描述或者hint就是发散的起点

发散思维在misc中更是常见,啥稀奇古怪的图形密码和各种隐写

misc中用到发散思维的例子:WHUCTF-版权保护

下载附件得到两个 txt 文件,查看说明

小p发现自己的文章被别人复制粘贴了,感到很气愤,于是他偷偷地将flag藏到了文章中,你能找到flag吗? 格式 whuctf{}

再查看题目. txt,能看到的里面都是重复的我很帅三个字,结合题名版权保护和题目描述,很容易想到出题人利用零宽度字符进行隐写(因为零宽度字符可以用来作为一种水印,可参考这篇文章,用 vim 查看

脑洞da开-CTF做题经验分享

这个题题目就是提示,能从版权保护想到零宽度字符就是发散思维,当然这个联想并不是凭空想象,而是做题经验

再举一个web方向的例子

web题目:virink_2019_files_share

源码中提示

<!-- Hint : flag in f1ag_Is_h3re -->

题目中存在文件读取,一般可能会想题目环境中存在一个 f1ag_Is_h3re 文件 flag 在这个文件中,但是实际上却没有这个文件,这时候就需要发散一下思维想一下会不会有别的可能,答案是有一个 f1ag_Is_h3re 文件夹,文件夹中有 flag 文件,文件包含 f1ag_Is_h3re/flag 即可

总的来说,这东西还是很靠经验和脑洞的,做的多了也就知道有啥可以利用的点了,才能确保你发散的方向是对的,所谓熟能生巧,发散逆向更是需要结合使用

上一篇:QTextEdit设置可输入字符字节限制


下一篇:CTF总结