如何扮演室友

来自翻译


塔夫茨大学的学生讲述了如何取笑他的室友。 当他开始讲故事时,他甚至把我寄托在宿舍里有4K电视这一事实。

引言


在谈论我如何带来不幸的洛根之前,我必须先解释一下我们房间中的媒体系统。 很快您就会明白为什么。

洛根,如果您读过这篇文章,希望您有更多的乐趣。

性格


我们有一台将台式机Ubunt连接到电视机的计算机。 他充当媒体服务器。 由于他仍然需要永久的Internet连接,因此具有几个页面的Web服务器,SSH服务器和许多其他服务仍在那儿旋转。

由于电视是4K,并且计算机是从手头组装的,因此其视频卡不会拉出。 Logan决定购买几代前发布的NVIDIA vidyuha(仍然比以前更好),以便正常播放4K视频。

一个想法的诞生


安装后不久,我们发现了一些驱动程序故障。 那时,我认为能够手动显示错误消息会很有趣。

在Internet上进行一些搜索之后,很明显,远程调用电视上的消息很简单:

  1. 通过SSH以运行广播的用户身份登录到计算机
  2. DISPLAY=:0 zenity --info --text '!'

DISPLAY=:0必需的,因为在我的会话中没有显示,但是我想在主屏幕上显示该消息。

由于我们在使用NVIDIA vidyuha时遇到问题,因此我决定专注于以下方面:

 DISPLAY=:0 zenity --warning --text '     .' 

它确实有效,但是每次使用SSH客户端登录到服务器以关闭Logan都是一种乐趣。 所以我决定作弊。 我考虑过要按计划激怒他的任务,但是有两个问题:

  1. 其实规律性
  2. 我们还有其他任务要做,这增加了披露我的阴险任务的风险

出于相同的原因,其他选项(如SysVInit脚本)也被删除。 因此,我决定使用“具有Logan”按钮制作一个公共网页。

抽签准备


我认为我需要从以下几件事开始:

  1. 处理用户输入的内容
  2. 以Web用户身份执行任意命令的内容

所以我来到:

  1. Nginx的
  2. NGINX的FPM扩展
  3. p
  4. 适用于PHP的FPM软件包

结果,我制作了一个包含logan.html logan.html页面和“操作页面” zenity.php

logan.html
 <!-- 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 /* zenity.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' /> 

此页面执行以下操作:

  1. 选择随机错误消息
  2. 选择对话框的类型。
  3. 在指定的时间段(10秒)内显示一条消息
  4. 他画了一个按钮并解释了发生的事情-所有这些都伴随着洛根亲自的搞笑图片

对于那些仍然无法在头脑中呈现HTML的人(同样,希望大多数人),页面如下所示:



如果您想知道为什么允许网页以这种方式执行代码,以及为什么网络服务器会话的所有者( www-data )可以以显示用户( thedisplayuser )的身份执行命令,您可能很高兴知道我将其严格限制为sudoers文件:

 # /etc/sudoers www-data ALL=(thedisplayuser) NOPASSWD: /usr/bin/zenity 

配置的这一特定部分允许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脚本:

 #!/bin/bash echo '.' >> /tmp/log.txt if [ 0 -eq $((RANDOM % 100)) ]; then /usr/bin/zenity --error --display=:0 --text "   ." --timeout 10 > /dev/null & else /usr/bin/zenity "$@" fi 

好吧,如果我遇到过类似的事情,那就是下一个废话。 99%的时间一切正常,其余的1%则弹出“ Max落后”信息。 我删除了文件(我知道这是不值得的),然后写信给sudoerszenity.php为原始格式。 消息已停止出现。 但是后来他们回来了。

第三阶段


我检查了zenity.php 。 没什么新的。 /usr/sbin/zenity ? 消失了。 我感到灰心。 然后,我决定查看/usr/bin/zenity

 #!/bin/bash # ---    --- # ---    --- # ---    --- # ---    --- # ---    --- if [ 0 -eq $((RANDOM % 70)) ]; then /usr/bin/rpmdb-client --error --display=:0 --text """"" """""" """""""""""" """"""""." --timeout 10 > /dev/null & else /usr/bin/rpmdb-client "$@" fi 

小狡猾的混蛋。 他修复了zenity二进制文件,使其成为bash脚本,该脚本可以运行70次。 什么样的rpmdb-client ? 因此,我通过更改进行了反击:

 # <> if [ 0 -eq $((RANDOM % 70)) ]; then /usr/sbin/rpmdb-client --error --display=:0 --text """"" """""" """""""""""" """"""""." --timeout 10 > /dev/null & else /usr/bin/rpmdb-client "$@" fi 

你明白了吗? 否则,将调用/usr/sbin/rpmdb-client而不是/usr/bin/rpmdb-client ,后者将启动不执行任何操作的bash脚本。 有了足够的运气,他将不会注意到其他角色,也永远不会出现他的信息。

TODO:了解ELF可执行文件/usr/sbin/zenity和克里斯创建的/usr/bin/rpmdb-client之间的区别。 我尚未理解的二进制文件之间存在一些奇怪的差异。

第四阶段


我决定加强防御,直到克里斯注意到上述一封信中的区别。 我取消了所有更改,而是决定修补zenity 。 非常感谢Tom Hebb(就像我的每篇技术文章一样)为我提供了帮助。 这是我所做的:

  1. 配置为apt以下载源(在本例中,将deb-src添加到/etc/apt/sources.list
  2. apt-get source zenity
  3. quilt做一个补丁:
    1. quilt new myPatch.diff
    2. src/msg.c补丁,用于确定消息正文中是否存在“ Max”一词:

      msg.c
       Index: zenity-3.18.1.1/src/msg.c =================================================================== --- zenity-3.18.1.1.orig/src/msg.c +++ zenity-3.18.1.1/src/msg.c @@ -21,6 +21,8 @@ * Authors: Glynn Foster <glynn.foster@sun.com> */ +#include <string.h> + #include "config.h" #include "zenity.h" @@ -85,6 +87,11 @@ zenity_msg (ZenityData *data, ZenityMsgD GObject *text; GObject *image; + if (strstr(msg_data->dialog_text, "Max") + || strstr(msg_data->dialog_text, "max")) { + return; + } + switch (msg_data->mode) { case ZENITY_MSG_WARNING: builder = zenity_util_load_ui_file ("zenity_warning_dialog", NULL); 
    3. quilt add src/msg.c
    4. quilt pop
  4. dpkg-source --commit
  5. dpkg-buildpackage -us -uc
  6. 我意识到创建和安装新程序包比替换二进制程序要苍白无力
  7. 用我的版本悄悄地替换了rpmdb-client (它的zenity )二进制文件
  8. 拍拍他的背

此修补程序以如下方式更改了zenity的行为:消息文本中出现单词“ Max”时,应用程序将无提示地执行任何操作。

结论


直到三月底,克里斯才发现我没有纠正二进制文件。 结果,Logan看不到一条带有我名字的消息。 因此,我决定继续集会,直到课程结束后我告诉他一切为止。 但是当课程结束时,我们分开了。 尽管洛根和我明年将再次生活在一起,但很可能我们不会在会议室花费太多时间,这样集会才有意义。 因此,我决定在开始新技巧之前先发布这篇文章。

Source: https://habr.com/ru/post/zh-CN417915/


All Articles