Wpis zbiera proste narzędzia, które mogą okazać się przydatne w różnych zastosowaniach.
Serwer SMTP w busybox (netcat, sh, awk)
Jest to bardzo prosty serwer SMTP (wykorzystujący do nasłuchu netcat'a). Umożliwia on sterowanie (wykonywanie zdalnych poleceń przy pomocy odpowiednio spreparowanych maili)
Pozwala na odbieranie poczty i wykorzystywanie jej do sterowania systemem na którym nie mamy serwera pocztowego, a dysponujemy jedynie podstawowymi narzędziami - w teorii powinien wystarczyć busybox.
Uruchomienie: while true; do netcat -l -p 25 -e smtp.sh; done.
Wymaga busybox z netcatem potrafiącym odpalić skrypt w -e lub innego netcata mającego taką funkcjonalność..
Kod źródłowy (do pobrania):
#!/bin/bash
DOMAIN="example.org"
IS_DATA=false; SENDER=""; RECEIVER="";
echo "220 $DOMAIN SMTP server by RRP `date -R`"
while read line; do
echo "Q (data=$IS_DATA): Y $line" >> /tmp/smtp-log.txt
if $IS_DATA; then
if echo "$line" | tr -d '\r' | awk '$0=="." {exit 0;} {exit 1}'; then
IS_DATA=false
echo -en "250 OK\r\n"
continue
fi
##########################
# WŁAŚCIWA TREŚĆ SKRYPTU #
##########################
# jest to powtarzane dla każdej linii przesyłanej jako treść maila (łącznie z nagłówkami)
# możemy sprawdzać nadawcę kopertowego: "$SENDER"
# możemy sprawdzać adresata kopertowego: "$RECEIVER"
# możemy sprawdzać aktualną linię z maila: "$line" tak jak to pokazano poniżej:
echo "$line" | tr -d '\r' | awk '
$1=="action" {
cmd=sprintf("make_action.sh %s %s", $2, $3);
}
$1=="stop" {
cmd=sprintf("killall .... ");
}
END {
system(cmd);
}
' > /dev/null 2> /dev/null &
# UWAGA: musi to być wyciszone i przechodzić w tło
else
echo "$line" | tr -d '\r' | awk -v DOMAIN="$DOMAIN" '
BEGIN {
IGNORECASE=1
FS="[ :\t]+"
}
$1 ~ "^(HE)|(EH)LO$" {
printf("250 %s Hello %s, pleased to meet you\r\n", DOMAIN, $2);
system( sprintf("echo \"R: 250 %s Hello %s, pleased to meet you\" >> /tmp/smtp-log.txt", DOMAIN, $2) );
exit 0;
}
$1 ~ "^MAIL$" && $2 ~ "^FROM$" && $3 != "" {
printf("250 OK\r\n");
system( sprintf("echo \"R: 250 OK\" >> /tmp/smtp-log.txt") );
exit 1;
}
$1 ~ "^RCPT$" && $2 ~ "^TO$" && $3 != "" {
printf("250 OK\r\n");
system( sprintf("echo \"R: 250 OK\" >> /tmp/smtp-log.txt") );
exit 2;
}
$1 ~ "^DATA$" {
printf("354 Enter message, ending with \".\" on a line by itself\r\n");
system( sprintf("echo \"R: 354 Enter message, ending with \".\" on a line by itself\" >> /tmp/smtp-log.txt") );
exit 3;
}
$1 ~ "^QUIT$" {
printf("221 %s closing connection\r\n", DOMAIN);
system( sprintf("echo \"R: 221 %s closing connection\" >> /tmp/smtp-log.txt", DOMAIN) );
exit 4;
}
{
printf("500 unrecognized command\r\n");
system( sprintf("echo \"R: 500 unrecognized command (%s)\" >> /tmp/smtp-log.txt", $1) );
exit 0;
}
'
case $? in
1) SENDER=`echo $line | tr -d '\r' | awk 'BEGIN {FS="[ :\t<>]+"} {print $3}'` ;;
2) RECEIVER=`echo $line | tr -d '\r' | awk 'BEGIN {FS="[ :\t<>]+"} {print $3}'` ;;
3) IS_DATA=true ;;
4) exit ;;
esac
fi
done;
Serwer HTTP w pythonie
Jest to prosty serwer HTTP z użyciem Pythona i jego standardowego modułu http.server. Serwer ten (w odróżnieniu od wywołania typu python3 -m http.server pozwalającego serwować zawartość katalogów) pozwala na wykonanie dowolnej akcji w odpowiedzi na żądanie HTTP i przesłanie dowolnej odpowiedzi do klienta. Może być użyty np. do zdalnego sterowania poprzez HTTP.
Kod źródłowy (do pobrania):
#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
class HttpHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-Type', 'text/plain;charset=utf-8')
self.end_headers()
# tu możemy wykonać jakąś akcję
# (w oparciu o argumenty żądania GET zawarte w self.path)
# i odesłać odpowiedź:
self.wfile.write(('Hello, world!\nŻądanie:' + self.path).encode())
httpd = HTTPServer(('localhost', 8000), HttpHandler)
httpd.serve_forever()