来自翻译
塔夫茨大学的学生讲述了如何取笑他的室友。 当他开始讲故事时,他甚至把我寄托在宿舍里有4K电视这一事实。
引言
在谈论我如何带来不幸的洛根之前,我必须先解释一下我们房间中的媒体系统。 很快您就会明白为什么。
洛根,如果您读过这篇文章,希望您有更多的乐趣。
性格
我们有一台将台式机Ubunt连接到电视机的计算机。 他充当媒体服务器。 由于他仍然需要永久的Internet连接,因此具有几个页面的Web服务器,SSH服务器和许多其他服务仍在那儿旋转。
由于电视是4K,并且计算机是从手头组装的,因此其视频卡不会拉出。 Logan决定购买几代前发布的NVIDIA vidyuha(仍然比以前更好),以便正常播放4K视频。
一个想法的诞生
安装后不久,我们发现了一些驱动程序故障。 那时,我认为能够手动显示错误消息会很有趣。
在Internet上进行一些搜索之后,很明显,远程调用电视上的消息很简单:
- 通过SSH以运行广播的用户身份登录到计算机
DISPLAY=:0 zenity --info --text '!'
DISPLAY=:0
必需的,因为在我的会话中没有显示,但是我想在主屏幕上显示该消息。
由于我们在使用NVIDIA vidyuha时遇到问题,因此我决定专注于以下方面:
DISPLAY=:0 zenity --warning --text ' .'
它确实有效,但是每次使用SSH客户端登录到服务器以关闭Logan都是一种乐趣。 所以我决定作弊。 我考虑过要按计划激怒他的任务,但是有两个问题:
- 其实规律性
- 我们还有其他任务要做,这增加了披露我的阴险任务的风险
出于相同的原因,其他选项(如SysVInit脚本)也被删除。 因此,我决定使用“具有Logan”按钮制作一个公共网页。
抽签准备
我认为我需要从以下几件事开始:
- 处理用户输入的内容
- 以Web用户身份执行任意命令的内容
所以我来到:
- Nginx的
- NGINX的FPM扩展
- p
- 适用于PHP的FPM软件包
结果,我制作了一个包含logan.html
logan.html
页面和“操作页面”
zenity.php
:
logan.html <html> <head> <style type="text/css"> form button { font-size: 20px; } div.explanation { width: 400px; } </style> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="HandheldFriendly" content="true"> </head> <body> <form method="POST" action="/zenity.php"> <button> </button> </form> </body> </html>
在
meta
标签中有一点废话可以使页面适合移动电话(请记住,我可以随时随地使用它吗?)对于那些不知道如何在我的脑中呈现HTML的人,我向您展示它的外观:

当按下按钮时,POST请求将转到另一个页面,该页面将完成所有脏工作:
zenity.php <?php $messages = Array( " .", " .", " .", " .", " .", " .", " .", " .", " .", " .", " and has recovered.", " .", " .", " .", " .", " .", " .", " NVIDIA .", "NVIDIA - . ( 43)", " wlx10bef54d395c." ); $statuses = Array("error", "warning"); $msg = $messages[array_rand($messages)]; $status = $statuses[array_rand($statuses)]; $timeout = "--timeout 10"; exec("sudo -u thedisplayuser /usr/sbin/zenity --$status --display=:0 --text ': $msg' $timeout > /dev/null &"); include 'logan.html'; ?> <div class="explanation"> , . , // .. </div> <br /> <img src='/logan.jpg' />
此页面执行以下操作:
- 选择随机错误消息
- 选择对话框的类型。
- 在指定的时间段(10秒)内显示一条消息
- 他画了一个按钮并解释了发生的事情-所有这些都伴随着洛根亲自的搞笑图片
对于那些仍然无法在头脑中呈现HTML的人(同样,希望大多数人),页面如下所示:

如果您想知道为什么允许网页以这种方式执行代码,以及为什么网络服务器会话的所有者(
www-data
)可以以显示用户(
thedisplayuser
)的身份执行命令,您可能很高兴知道我将其严格限制为
sudoers
文件:
配置的这一特定部分允许www-data作为displayuser仅以/ usr / bin / zenity身份运行,而无需输入密码。 在搞砸了PHP和NGINX设置中的愚蠢错误之后,我做到了。 然后,我将该网址发送给了几个认识洛根的校园朋友。
抽奖结果
赞美天堂,洛根尽了全力。 如果他有些生气,那以为我的努力被浪费了的想法会惹恼我。 但是不! 他发脾气了。 我无法计算重启次数,驱动程序重新安装次数和内核修改次数。 我仅遗憾的是,我没有拍摄有关他开始VLC后生气的视频,当时有人扔了一堆窗户,显示有关视频卡错误的消息。
但是我也被带走了,我们的另一位室友克里斯决定介入...
猎人狩猎
第一阶段
晴朗的一天,当洛根(Logan)睡觉时,我注意到一条错误消息,上面写着:“这一切背后都是麦克斯。 hoo? 我有一个恶作剧! 因此,我开始理解,发现有人(Chris)在
zenity.php
将此短语引入了一组随机消息中。 我迅速删除了它(直到洛根听说他们在玩它),然后确定娱乐结束了。 在那里。
第二阶段
大约一周后,该消息再次弹出。 我以为克里斯烧死了我,然后将其重新添加到列表中。 这不是该死的东西。 他不在那里。 在仔细研究文件之后,我注意到它现在被称为
/usr/sbin/zenity
而不是
/usr/bin/zenity
(系统默认值),并且
sudoers
具有相应的允许条目。 那么
/usr/sbin/zenity
什么? Shell脚本:
好吧,如果我遇到过类似的事情,那就是下一个废话。 99%的时间一切正常,其余的1%则弹出“ Max落后”信息。 我删除了文件(我知道这是不值得的),然后写信给
sudoers
将
zenity.php
为原始格式。 消息已停止出现。 但是后来他们回来了。
第三阶段
我检查了
zenity.php
。 没什么新的。
/usr/sbin/zenity
? 消失了。 我感到灰心。 然后,我决定查看
/usr/bin/zenity
:
小狡猾的混蛋。 他修复了zenity二进制文件,使其成为bash脚本,该脚本可以运行70次。 什么样的
rpmdb-client
? 因此,我通过更改进行了反击:
你明白了吗? 否则,将调用
/usr/sbin/rpmdb-client
而不是
/usr/bin/rpmdb-client
,后者将启动不执行任何操作的bash脚本。 有了足够的运气,他将不会注意到其他角色,也永远不会出现他的信息。
TODO:了解ELF可执行文件
/usr/sbin/zenity
和克里斯创建的
/usr/bin/rpmdb-client
之间的区别。 我尚未理解的二进制文件之间存在一些奇怪的差异。
第四阶段
我决定加强防御,直到克里斯注意到上述一封信中的区别。 我取消了所有更改,而是决定修补
zenity
。 非常感谢Tom Hebb(就像我的每篇技术文章一样)为我提供了帮助。 这是我所做的:
- 配置为
apt
以下载源(在本例中,将deb-src
添加到/etc/apt/sources.list
) apt-get source zenity
- 用
quilt
做一个补丁:
quilt new myPatch.diff
src/msg.c
补丁,用于确定消息正文中是否存在“ Max”一词:
quilt add src/msg.c
quilt pop
dpkg-source --commit
dpkg-buildpackage -us -uc
- 我意识到创建和安装新程序包比替换二进制程序要苍白无力
- 用我的版本悄悄地替换了
rpmdb-client
(它的zenity
)二进制文件 - 拍拍他的背
此修补程序以如下方式更改了
zenity
的行为:消息文本中出现单词“ Max”时,应用程序将无提示地执行任何操作。
结论
直到三月底,克里斯才发现我没有纠正二进制文件。 结果,Logan看不到一条带有我名字的消息。 因此,我决定继续集会,直到课程结束后我告诉他一切为止。 但是当课程结束时,我们分开了。 尽管洛根和我明年将再次生活在一起,但很可能我们不会在会议室花费太多时间,这样集会才有意义。 因此,我决定在开始新技巧之前先发布这篇文章。