早些时间了解了竞争条件这个有趣的现象,底层原理不细讲,可以看看网上pwn college的搬运 这里还是简单描述下
众所周知,CPU从逻辑上是逐条指令执行的,但是当多个进程运行的时候,就会让他们的指令交叉进行操作,如果两个进程对同一文件进行操作时,就有可能导致两个程序对其读取时的环境与对其操作时的环境不同,这里举一个漏洞程序作为示范,大家可以自己去编译一下:
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
void intro(void)
{
printf("HaHa there's no input!\n");
printf("But i'll print Flag when num is 2!\n");
}
void check_input(char *filename)
{
int i;
FILE *f = fopen(filename, "r");
assert(f != NULL);
fscanf(f, "%d", &i);
fclose(f);
if(i != 0)
{
printf("Nah the file changed.I wont run anymore\n");
exit(0);
}
printf("check done!\n");
return;
}
int do_action(char *filename)
{
int i;
FILE *f = fopen(filename, "r");
assert(f != NULL);
fscanf(f, "%d", &i);
fclose(f);
printf("I wrote a %d to file just now!\n", i);
printf("Try 2 let me do it again(and again)!\n");
return i;
}
int main(void)
{
int i;
char *filename = "num";
intro();
check_input(filename);
do
{
sleep(1);
i = do_action(filename);
}while(i != 2);
printf("flag{FuLaGe}");
return 0;
}
(这里为了简单起见用了循环和sleep,其实正常示例程序应该去掉的,程序的逻辑也做了简化,遇到错误居然不退出而是爆出flag吗这种时候就需要去写一个过滤输出,忽略标准错误输出等处理,而且可能很久不出结果,所以这里就简化了一下逻辑.另外这题其实会跟自己竞争的,单纯两个执行这个程序的死循环应该也会爆flag)
程序很正常的打开了一个文件并检查里面的内容,再写入一个0,并且在非预期的时候退出,然而它忘了刚才写了什么再次打开并告诉你刚才写了什么,并且在奇怪的时候输出flag诶刚才明明不是这样的啊.程序没有输入点,但是与文件有交互(有点像之前做过的一道license,那道题利用文件的内容进行溢出)但是这里看得出来程序似乎没有溢出点.诶!我有一计
while :; do echo "1" > num; done
很轻易的就爆出flag啦