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