我有一个二进制文件,我应该破解它的密码(作业)。还给出了一个函数(一个作为二进制文件一部分的函数)。该函数显示输入字符串与正确的密码逐个字符进行比较,并在字符错误时立即返回 false (我猜这是不安全的做法,因为它正在泄漏时间,我们知道正确的密码长度为例子)。但是我们的老师添加了一个随机计时器,它返回结果(正确/错误),让我们更难...
无论如何,我已经通过逆向工程成功完成并获得了正确的密码。现在我在命令行中使用它:
/usr/bin/time -v ./program_name enter_password
使用这个命令,我得到了很多信息,例如系统时间、交换、执行时间。但是对我来说最有趣的是“自愿上下文切换”,因为我输入的密码字符越正确,“自愿上下文切换”就越少“我明白了!
我输入的错误字符越多,我得到的“自愿上下文切换”就越多。
仅通过输入该命令,输入字符并观察“自愿上下文切换”,我就花了将近两个小时来破解密码。只要一个字符是正确的,“自愿上下文切换”就会减少一。
我的问题是,“自愿上下文切换”到底是什么,为什么它们帮助我破解密码?
手册页
time
解释了自愿和非自愿上下文切换的概念:(引用来自我的 Debian 系统,链接的手册页文本略有不同)
也就是说,上下文切换是自愿的,如果进程离开 CPU 是因为它无事可做(在等待外部事件发生时)。非自愿的,如果它想继续一些计算,但操作系统决定是时候切换到其他进程了。
这与密码检查程序有什么关系,取决于程序的实际作用。
从注释中链接的源代码中,我们看到程序
usleep()
为每个不匹配的字符调用一次,然后继续对下一个字符进行比较循环。睡眠与让出 CPU 一样自愿,因此这些调用将显示为每个非匹配字符的自愿上下文切换。在 Linux 上,您也应该能够看到带有 的调用
strace
。最后的延迟来自随机睡眠
T * (rand() % 3)
,即 0、1 或 2 倍常数。这是一个相当粗略的粒度,因此应该很容易通过使用相同的密码进行多次尝试来平均化。