Skip to content

Commit aff618c

Browse files
authored
Merge branch 'NARKOZ:master' into master
2 parents b8dd025 + b14a0a8 commit aff618c

15 files changed

+501
-31
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
2+
English | [简体中文](./README.zh-CN.md)
3+
14
# Hacker Scripts
25

36
Based on a _[true
@@ -19,7 +22,7 @@ story](https://www.jitbit.com/alexblog/249-now-thats-what-i-call-a-hacker/)_:
1922
2023
> xxx: holy sh*t I'm keeping those
2124
22-
Original: http://bash.im/quote/436725 (in Russian)
25+
Original: http://bash.im/quote/436725 (in Russian) (Archive.org [link](https://web.archive.org/web/20210226092253/http://bash.im/quote/436725))
2326
Pull requests with other implementations (Python, Perl, Shell, etc) are welcome.
2427

2528
## Usage

README.zh-CN.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Hacker Scripts
2+
3+
根据 *[真实故事](https://www.jitbit.com/alexblog/249-now-thats-what-i-call-a-hacker/)* 改编:
4+
5+
> xxx: 是这样的,我们的构建工程师离职去了另外一家公司,这货基本算是生活在终端里。 你知道么,这人热爱Vim,用Dot作图,甚至用MarkDown来写维基帖子...,如果有什么事情要花上他超过90秒,他一定会整个脚本来让这件事变得“自动化”。
6+
7+
> xxx: 我们现在坐在他的工位上,看着他留下来的这些,呃,“遗产”?
8+
9+
> xxx: 我觉得你们会喜欢这些的
10+
11+
> xxx: [`smack-my-bitch-up.sh(拍老婆马屁脚本)`](https://github.com/NARKOZ/hacker-scripts/blob/master/smack-my-bitch-up.sh) - 它会给他的老婆(很明显是他老婆)发送一条“今晚要加班了”的短信,再自动从文本库中随机地选择一条理由。这个脚本被设置为定时触发,而且只有在工作日晚9点以后,服务器上还有他登陆的SSH进程在运行时才会执行。
12+
13+
> xxx: [`kumar-asshole.sh(库马尔个傻*)`](https://github.com/NARKOZ/hacker-scripts/blob/master/kumar-asshole.sh) - 这个脚本会自动扫描邮箱,如果发现其中有库马尔(库马尔是我们客户公司的一位数据库管理员)发来的邮件,就会在其中寻找关键字如“求助”,“遇到麻烦了”,“抱歉”等等,如果发现了这些关键字,这个脚本会通过SSH连接上客户公司的服务器,把中间数据库(staging database)回滚到最新一次的可用备份。然后它会给邮件发送回复,“没事了哥们,下次小心点哈”。
14+
15+
> xxx: [`hangover.sh(宿醉)`](https://github.com/NARKOZ/hacker-scripts/blob/master/hangover.sh) - 同样是个定时执行的任务,被设置为在特定日期触发,它会自动发送诸如“今天不太舒服”或“今天我在家上班”之类的邮件,同样会从文本库里随机选取一条理由。这个任务会在工作日清晨8点45分以后服务器上仍然没有可交互的SSH进程时真正执行。
16+
17+
> xxx: (最牛的就是接下来这个) [`fucking-coffee.sh(**的咖啡)`](https://github.com/NARKOZ/hacker-scripts/blob/master/fucking-coffee.sh) - 这个脚本在启动之后,会先等待恰好17秒(!),然后启动一个登录进程连接到我们的咖啡机(淦,我们之前完全不知道我们的咖啡机是联网的,上面还运行着Linux系统,甚至还跑着TCP socket连接!),然后它会发送类似“系统!开始煮咖啡!”之类的消息,结果这条消息会让咖啡机开始工作,煮一杯 中杯大小、半咖啡因的拿铁,再等待恰好24秒(!)后,才倒进咖啡杯里。这些时间加起来刚好就是这位程序员从自己的工位走到机器前要的时间。
18+
19+
> xxx: 天了噜我要把这些保留下来。
20+
21+
原文: http://bash.im/quote/436725 (俄语)
22+
23+
欢迎使用其它语言来实现 (Python, Perl, Shell等等)并提交PR。
24+
25+
## 用法
26+
27+
你需要以下这些环境变量:
28+
29+
```bash
30+
# used in `smack-my-bitch-up` and `hangover` scripts
31+
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
32+
TWILIO_AUTH_TOKEN=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
33+
34+
# used in `kumar_asshole` script
35+
36+
GMAIL_PASSWORD=password
37+
```
38+
39+
为了执行Ruby脚本,你需要安装gems: `gem install dotenv twilio-ruby gmail`
40+
41+
## 定时任务
42+
43+
```bash
44+
# Runs `smack-my-bitch-up.sh` monday to friday at 9:20 pm.
45+
20 21 * * 1-5 /path/to/scripts/smack-my-bitch-up.sh >> /path/to/smack-my-bitch-up.log 2>&1
46+
47+
# Runs `hangover.sh` monday to friday at 8:45 am.
48+
45 8 * * 1-5 /path/to/scripts/hangover.sh >> /path/to/hangover.log 2>&1
49+
50+
# Runs `kumar-asshole.sh` every 10 minutes.
51+
*/10 * * * * /path/to/scripts/kumar-asshole.sh
52+
53+
# Runs `fucking-coffee.sh` hourly from 9am to 6pm on weekdays.
54+
0 9-18 * * 1-5 /path/to/scripts/fucking-coffee.sh
55+
```
56+
57+
------
58+
59+
代码的使用遵循WTFPL(Do What The Fuck You Want To Public License)协议。

clojure/coffee.clj

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
(ns hacker-scripts.coffee
2+
(:require [environ.core :refer [env]])
3+
(:import
4+
(java.net Socket)
5+
(java.io BufferedReader PrintWriter InputStreamReader)))
6+
7+
(def my-username "my-username")
8+
(def my-password "my-password")
9+
10+
(def coffee-machine-ip "10.10.42.42")
11+
(def password-prompt "Password: ")
12+
(def connection-port 23)
13+
14+
(def sec-delay-before-brew 17)
15+
(def sec-delay-before-pour 24)
16+
17+
(defn logged-in? [] (= (:USER env) my-username))
18+
19+
(defn auth [in-stream out-stream]
20+
(if (= (.readLine in-stream) password-prompt)
21+
(.println out-stream my-password)
22+
(throw (RuntimeException.
23+
"Failed to authenticate with coffee machine"))))
24+
25+
(defn command-brew-pour [out-stream]
26+
(do
27+
(Thread/sleep (* 1000 sec-delay-before-brew))
28+
(.println out-stream "sys brew")
29+
(Thread/sleep (* 1000 sec-delay-before-pour))
30+
(.println out-stream "sys pour")))
31+
32+
(defn coffee []
33+
(if (logged-in?)
34+
(with-open [socket (Socket. coffee-machine-ip connection-port)
35+
out-stream (PrintWriter. (.getOutputStream socket) true)
36+
in-stream (BufferedReader. (InputStreamReader. (.getInputStream socket)))]
37+
(do
38+
(auth in-stream out-stream)
39+
(command-brew-pour out-stream)))))

clojure/hangover.clj

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
(ns hacker-scripts.hangover
2+
(:import
3+
(com.twilio Twilio)
4+
(com.twilio.rest.api.v2010.account Message)
5+
(com.twilio.type PhoneNumber)))
6+
7+
(def acc-sid "my twilio account SID")
8+
(def acc-tkn "my twilio secret token")
9+
10+
(def my-num (PhoneNumber. "+10001112222"))
11+
(def boss-num (PhoneNumber. "+19998887777"))
12+
13+
(def reasons ["Receiving delivery"
14+
"Waiting for repairman"
15+
"Nasty cold"])
16+
17+
(defn twilio-init []
18+
(Twilio/init acc-sid acc-tkn))
19+
20+
(defn send-sms [to-num from-num message]
21+
(.. Message (creator to-num from-num message) create))
22+
23+
(def send-sms-boss (partial send-sms boss-num my-num))
24+
25+
(defn hangover []
26+
(twilio-init)
27+
(let [message (rand-nth reasons)]
28+
(send-sms-boss message)))

clojure/kumar.clj

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
(ns hacker-scripts.kumar
2+
(:import
3+
(java.util Properties)
4+
(javax.mail Session Authenticator PasswordAuthentication Message$RecipientType Transport Folder Flags Flags$Flag)
5+
(javax.mail.internet MimeMessage InternetAddress)
6+
(javax.mail.search FlagTerm FromTerm AndTerm OrTerm SubjectTerm BodyTerm SearchTerm)))
7+
8+
(def host "smtp.gmail.com")
9+
(def my-email "[email protected]")
10+
(def my-password "my-gmail-password")
11+
(def kumar-email "[email protected]")
12+
13+
(def seen-flag (Flags. (Flags$Flag/SEEN)))
14+
15+
(def unread-term (FlagTerm. seen-flag false))
16+
17+
(defn get-session []
18+
(let [authenticator (proxy [Authenticator] []
19+
(getPasswordAuthentication []
20+
(PasswordAuthentication. my-email my-password)))
21+
props (Properties.)]
22+
(.put props "mail.smtp.host" "smtp.gmail.com")
23+
(.put props "mail.smtp.port" "587")
24+
(.put props "mail.smtp.auth" "true")
25+
(.put props "mail.smtp.starttls.enable" "true")
26+
(.. Session (getInstance props authenticator))))
27+
28+
(defn get-inbox [session]
29+
(let [store (.getStore session "imaps")
30+
inbox (do
31+
(.connect store host my-email my-password)
32+
(.getFolder store "inbox"))]
33+
(.open inbox Folder/READ_WRITE)
34+
inbox))
35+
36+
(defn get-no-worries-message [session]
37+
(let [message (MimeMessage. session)]
38+
(.setFrom message (InternetAddress. my-email))
39+
(.addRecipient message Message$RecipientType/TO (InternetAddress. kumar-email))
40+
(.setSubject message "Database fixes")
41+
(.setText message "No worries mate, be careful next time")
42+
message))
43+
44+
(defn search-term [pattern]
45+
(OrTerm. (into-array SearchTerm [(SubjectTerm. pattern) (BodyTerm. pattern)])))
46+
47+
(defn any-of-search-term [& patterns]
48+
(OrTerm. (into-array (map search-term patterns))))
49+
50+
(defn from-term [addr]
51+
(FromTerm. (InternetAddress. addr)))
52+
53+
(defn get-unread-sos-from-kumar [inbox]
54+
(let [flag (AndTerm. (into-array SearchTerm [unread-term
55+
(from-term kumar-email)
56+
(any-of-search-term "help" "sorry" "trouble")]))]
57+
(.search inbox flag)))
58+
59+
(defn mark-as-read [inbox messages]
60+
(.setFlags inbox messages seen-flag true))
61+
62+
(defn kumar-asshole []
63+
(let [session (get-session)
64+
inbox (get-inbox session)
65+
unread-sos-from-kumar (get-unread-sos-from-kumar inbox)]
66+
(when (seq unread-sos-from-kumar)
67+
(mark-as-read inbox unread-sos-from-kumar)
68+
(Transport/send (get-no-worries-message session)))))

clojure/smack.clj

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
(ns hacker-scripts.smack
2+
(:import
3+
(com.twilio Twilio)
4+
(com.twilio.rest.api.v2010.account Message)
5+
(com.twilio.type PhoneNumber)))
6+
7+
(def acc-sid "my twilio account SID")
8+
(def acc-tkn "my twilio secret token")
9+
10+
(def my-num (PhoneNumber. "+10001112222"))
11+
(def her-num (PhoneNumber. "+19998887777"))
12+
13+
(def reasons ["Working hard"
14+
"Gotta ship this feature"
15+
"Someone fucked the system again"])
16+
17+
(defn twilio-init []
18+
(Twilio/init acc-sid acc-tkn))
19+
20+
(defn send-sms [to-num from-num message]
21+
(.. Message (creator to-num from-num message) create))
22+
23+
(def send-sms-girlfriend (partial send-sms her-num my-num))
24+
25+
(defn smack []
26+
(twilio-init)
27+
(let [message (rand-nth reasons)]
28+
(send-sms-girlfriend message)))

go/fucking-coffee.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"os"
7+
"regexp"
8+
"time"
9+
10+
"github.com/codeskyblue/go-sh"
11+
"github.com/google/goexpect"
12+
)
13+
14+
func main() {
15+
// exit early if no sessions with my username are found
16+
currentUser, _ := sh.Command("who").Command("grep", "my_username").Output()
17+
if currentUser == nil {
18+
os.Exit(1)
19+
}
20+
21+
// info about the coffee machine
22+
coffeeMachineIP := "10.10.42.42"
23+
password := "1234"
24+
passwordPrompt := "Password: "
25+
delayBeforeBrew := 17 * time.Second
26+
delay := 24 * time.Second
27+
28+
// timeout for the telnet prompts
29+
timeout := 10 * time.Minute
30+
31+
// sleep 17 seconds before brewing coffee
32+
time.Sleep(delayBeforeBrew)
33+
34+
// spawn a new telnet session with the coffee machine
35+
t, _, err := expect.Spawn(fmt.Sprintf("telnet %s", coffeeMachineIP), -1)
36+
if err != nil {
37+
log.Fatal(err)
38+
}
39+
defer t.Close()
40+
41+
t.Expect(regexp.MustCompile(passwordPrompt), timeout)
42+
t.Send(password + "\n")
43+
t.Expect(regexp.MustCompile("telnet>"), timeout)
44+
t.Send("sys brew\n")
45+
time.Sleep(delay)
46+
t.Expect(regexp.MustCompile("telnet>"), timeout)
47+
t.Send("sys pour\n")
48+
t.Expect(regexp.MustCompile("telnet>"), timeout)
49+
t.Send("exit\n")
50+
}

java/KumarAsshole.java

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import java.io.File;
32
import java.io.FileInputStream;
43
import java.util.*;
@@ -19,15 +18,13 @@ public static void main(String[] args) {
1918
public void read() {
2019
Properties props = new Properties();
2120

22-
23-
//modify below properties to your details
24-
String host = "smtp.gmail.com";
25-
String username = "[email protected] goes here";
26-
String password = "your password goes here ";
27-
String Kumar_mail = "the mail address to be replied to !";
28-
29-
try {
21+
//modify below properties to your details
22+
String host = "smtp.gmail.com";
23+
String username = "[email protected] goes here";
24+
String password = "your password goes here ";
25+
String Kumar_mail = "the mail address to be replied to !";
3026

27+
try {
3128
Session session = Session.getDefaultInstance(props, null);
3229

3330
Store store = session.getStore("imaps");
@@ -39,29 +36,23 @@ public void read() {
3936
Message messages[] = inbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
4037

4138
for (int i = 0; i < messages.length; i++) {
42-
4339
if (messages[i].getFrom()[0].toString().contains(Kumar_mail)) {
44-
4540
String bodytext = null;
4641
Object content = messages[i].getContent();
4742
if (content instanceof String) {
4843
bodytext = (String) content;
49-
5044
} else if (content instanceof Multipart) {
51-
5245
Multipart mp = (Multipart) content;
5346

5447
BodyPart bp = mp.getBodyPart(mp.getCount() - 1);
5548
bodytext = (String) bp.getContent();
56-
5749
}
5850

5951
Pattern pattern = Pattern.compile("sorry|help|wrong", Pattern.CASE_INSENSITIVE);
6052
Matcher matcher = pattern.matcher(bodytext);
6153
// check all occurance
6254

6355
if (matcher.find()) {
64-
6556
Properties props1 = new Properties();
6657
Address[] tomail;
6758

@@ -73,23 +64,18 @@ public void read() {
7364
msg.setSubject("Database fixes");
7465
msg.setText("No problem. I've fixed it. \n\n Please be careful next time.");
7566
Transport t = null;
76-
t = session.getTransport("smtps");
77-
t.connect(host, username, password);
78-
t.sendMessage(msg, msg.getAllRecipients());
79-
80-
67+
t = session.getTransport("smtps");
68+
t.connect(host, username, password);
69+
t.sendMessage(msg, msg.getAllRecipients());
70+
}
71+
}
8172
}
82-
8373

84-
}
85-
}
8674
inbox.close(true);
8775
store.close();
8876

89-
}catch(Exception e)
90-
{
91-
77+
} catch(Exception e) {
9278
e.printStackTrace();
9379
}
9480
}
95-
}
81+
}

0 commit comments

Comments
 (0)