1,做网络安全有几个月时间了,每天都在忙于事物性工作搞技术研究的时间相对比较少。但是还是接触了不少网络安全知识。
工作中经常要用到扫描工具对主机漏洞进行扫描或端口扫描。所以自己也想写个主机漏扫工具及端口扫描工具,写漏扫工具很复杂本人还做不到
呵呵就从端口扫描工具写起,首先实现TCP端口扫描,由于UDP是无连接的,端口扫描相对难点以后再实现。
2,本程序界面部分是用GTK写的,采用多线程对端口扫描,设置了TCP套接字接收超时选项为500ms,这样500ms内没收到,syn ack报文就认为端口没有开放。
这样为了节省TCP扫描时间,不然如果不设置超时时间扫65536个端口需要几天的时间不现实。
我扫描的是10000以内的端口大概20分钟,6万多个端口的话大概2个小时可以扫完。
本程序在linux下编译运行。GCC编译选项:`pkg-config --libs --cflags gtk+-2.0 gthread-2.0`
3,以下为程序代码
#include <gtk/gtk.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
GtkWidget *entry_port,*entry_ip;
GtkWidget *window;
//int sock_fd;
//int dip;
struct in_addr dip;
void show_warning(const char *message, gpointer window)
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new(window,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_WARNING,
GTK_BUTTONS_OK,
message);
gtk_window_set_title(GTK_WINDOW(dialog), "Warning");
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
void test_port(gpointer port){
struct sockaddr_in s_in;
int sock_fd;
s_in.sin_family = AF_INET;
s_in.sin_port = htons(*(short int*)port);
s_in.sin_addr=dip;
struct timeval timeout={0,500000};
char buf[10]="";
if((sock_fd=socket(AF_INET,SOCK_STREAM,0))<0){
printf("socket error\n");
g_thread_exit(NULL);
}
setsockopt(sock_fd,SOL_SOCKET,SO_RCVTIMEO,&timeout,sizeof(timeout));
if(connect(sock_fd,(struct sockaddr *)&s_in,sizeof(s_in))){
printf("connect error\n");
}else{
// gdk_threads_enter(); //进入
sprintf(buf,"%d;",*(short int*)port);
gtk_entry_append_text(GTK_ENTRY(entry_port),buf);
// gdk_threads_leave(); //离开
}
close(sock_fd);
while(gtk_events_pending()){
gtk_main_iteration();
}
// gtk_widget_set_sensitive(widget,TRUE);
g_thread_exit(NULL);
//
}
void check_port(GtkWidget *widget,gpointer data){
gchar *p_ip;
// struct in_addr dip;
// int sock_fd;
short int i;
short int p_port[65535];
GThread *thread1,*thread2,*thread3,*thread4,*thread5,*thread6;
p_ip=gtk_entry_get_text(GTK_ENTRY(entry_ip));
if(inet_aton(p_ip,&dip)==0){
show_warning("无效的ip地址",window);
return;
}
gtk_entry_set_text(GTK_ENTRY(entry_port),"");
gtk_widget_set_sensitive(widget,FALSE);
// sock_fd=socket(AF_INET,SOCK_STREAM,0);
for(i=10;i<=10000;i++){ //前10个端口基本不会对外开放所以都不用扫描了
p_port[i]=i;
thread1=g_thread_create((GThreadFunc)test_port,&p_port[i],TRUE,NULL);
i++;
p_port[i]=i;
thread2=g_thread_create((GThreadFunc)test_port,&p_port[i],TRUE,NULL);
i++;
p_port[i]=i;
thread3=g_thread_create((GThreadFunc)test_port,&p_port[i],TRUE,NULL);
i++;
p_port[i]=i;
thread4=g_thread_create((GThreadFunc)test_port,&p_port[i],TRUE,NULL);
i++;
p_port[i]=i;
thread5=g_thread_create((GThreadFunc)test_port,&p_port[i],TRUE,NULL);
i++;
p_port[i]=i;
thread6=g_thread_create((GThreadFunc)test_port,&p_port[i],TRUE,NULL);
if(thread1!=NULL)
g_thread_join(thread1);
if(thread2!=NULL)
g_thread_join(thread2);
if(thread3!=NULL)
g_thread_join(thread3);
if(thread4!=NULL)
g_thread_join(thread4);
if(thread5!=NULL)
g_thread_join(thread5);
if(thread6!=NULL)
g_thread_join(thread6);
// sock_fd=socket(AF_INET,SOCK_STREAM,0);
// test_port(i);
while(gtk_events_pending()){
gtk_main_iteration();
}
// close(sock_fd);
}
/*
while(gtk_events_pending()){
gtk_main_iteration();
}
*/
gtk_widget_set_sensitive(widget,TRUE);
return;
// close(sock_fd);
}
int main(int argc,char *argv[]){
// GtkWidget *window;
GtkWidget *table,*button,*label;
// GtkWidget *entry_port,*entry_ip;
if(!g_thread_supported())
g_thread_init(NULL);
gtk_init(&argc,&argv);
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
//window=gtk_window_new(GTK_WINDOW_POPUP);
gtk_window_set_title(GTK_WINDOW(window),"端口扫描");
gtk_widget_set_size_request(window,300,150);
gtk_window_set_resizable((GtkWindow *)window,FALSE);
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
//gtk_window_
gtk_container_set_border_width(GTK_CONTAINER(window),10);
table=gtk_table_new(4,2,TRUE);
gtk_container_add(GTK_CONTAINER(window),table);
label=gtk_label_new("主机IP");
entry_ip=gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table),label, 0 , 1, 0,1);
gtk_table_attach_defaults(GTK_TABLE(table),entry_ip, 1 , 2, 0,1);
button=gtk_button_new_with_label("确定");
label=gtk_label_new("开放的端口数");
entry_port=gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(table),button, 0 , 2, 1,2);
gtk_table_attach_defaults(GTK_TABLE(table),label, 0 , 2, 2,3);
gtk_table_attach_defaults(GTK_TABLE(table),entry_port, 0 , 2, 3,4);
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(check_port),NULL);
g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);
gtk_widget_show_all(window);
gdk_threads_enter();//
gtk_main();
gdk_threads_leave();//
return FALSE;
}
4,程序运行截图