#include #include #include #include #include #include #define LIBSSH_STATIC 1 #include #define CBC 1 #define CTR 1 #define ECB 1 #include "aes.h" #define BUFFER_SIZE 1024 int verify_knownhost(ssh_session session) { enum ssh_known_hosts_e state; unsigned char *hash = NULL; ssh_key srv_pubkey = NULL; size_t hlen; char *hexa; int rc; rc = ssh_get_server_publickey(session, &srv_pubkey); if (rc < 0) { return -1; } rc = ssh_get_publickey_hash(srv_pubkey, SSH_PUBLICKEY_HASH_SHA1, &hash, &hlen); ssh_key_free(srv_pubkey); if (rc < 0) { return -1; } state = ssh_session_is_known_server(session); switch (state) { case SSH_KNOWN_HOSTS_OK: /* OK */ break; case SSH_KNOWN_HOSTS_CHANGED: fprintf(stderr, "Host key for server changed: it is now:\n"); ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen); fprintf(stderr, "For security reasons, connection will be stopped\n"); ssh_clean_pubkey_hash(&hash); return -1; case SSH_KNOWN_HOSTS_OTHER: fprintf(stderr, "The host key for this server was not found but an other" "type of key exists.\n"); fprintf(stderr, "An attacker might change the default server key to" "confuse your client into thinking the key does not exist\n"); ssh_clean_pubkey_hash(&hash); return -1; case SSH_KNOWN_HOSTS_NOT_FOUND: fprintf(stderr, "Could not find known host file.\n"); fprintf(stderr, "If you accept the host key here, the file will be" "automatically created.\n"); /* FALL THROUGH to SSH_SERVER_NOT_KNOWN behavior */ case SSH_KNOWN_HOSTS_UNKNOWN: hexa = ssh_get_hexa(hash, hlen); fprintf(stderr, "The server is unknown. Do you trust the host key?\n"); fprintf(stderr, "Public key hash: %s\n", hexa); ssh_string_free_char(hexa); ssh_clean_pubkey_hash(&hash); rc = ssh_session_update_known_hosts(session); if (rc < 0) { fprintf(stderr, "Error %s\n", strerror(errno)); return -1; } break; case SSH_KNOWN_HOSTS_ERROR: fprintf(stderr, "Error %s", ssh_get_error(session)); ssh_clean_pubkey_hash(&hash); return -1; } ssh_clean_pubkey_hash(&hash); return 0; } // 交互式外壳会话 int interactive_shell_session(ssh_session session, ssh_channel channel) { int rc; rc = ssh_channel_request_pty(channel); if (rc != SSH_OK) return rc; rc = ssh_channel_change_pty_size(channel, 80, 24); if (rc != SSH_OK) return rc; rc = ssh_channel_request_shell(channel); if (rc != SSH_OK) return rc; char buffer[256]; int nbytes, nwritten; while (ssh_channel_is_open(channel) && !ssh_channel_is_eof(channel)) { struct timeval timeout; ssh_channel in_channels[2], out_channels[2]; fd_set fds; int maxfd; timeout.tv_sec = 30; timeout.tv_usec = 0; in_channels[0] = channel; in_channels[1] = NULL; FD_ZERO(&fds); FD_SET(0, &fds); FD_SET(ssh_get_fd(session), &fds); maxfd = ssh_get_fd(session) + 1; ssh_select(in_channels, out_channels, maxfd, &fds, &timeout); if (out_channels[0] != NULL) { nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); if (nbytes < 0) return SSH_ERROR; if (nbytes > 0) { nwritten = write(1, buffer, nbytes); if (nwritten != nbytes) return SSH_ERROR; } } if (FD_ISSET(0, &fds)) { nbytes = read(0, buffer, sizeof(buffer)); if (nbytes < 0) return SSH_ERROR; if (nbytes > 0) { nwritten = ssh_channel_write(channel, buffer, nbytes); if (nbytes != nwritten) return SSH_ERROR; } } } return rc; } // 执行远程命令 int execute_remote_command(ssh_channel channel, char *command) { int rc; char buffer[256]; int nbytes; rc = ssh_channel_request_exec(channel, command); if (rc != SSH_OK) { ssh_channel_close(channel); ssh_channel_free(channel); return rc; } nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); while (nbytes > 0) { if (write(1, buffer, nbytes) != (unsigned int)nbytes) { ssh_channel_close(channel); ssh_channel_free(channel); return SSH_ERROR; } nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); } if (nbytes < 0) { ssh_channel_close(channel); ssh_channel_free(channel); return SSH_ERROR; } return rc; } int show_remote_processes(ssh_session session, char *command, int is) { int rc; ssh_channel channel; // 分配一个新的信道 channel = ssh_channel_new(session); if (channel == NULL) return SSH_ERROR; // 分配好的信道 rc = ssh_channel_open_session(channel); if (rc != SSH_OK) { ssh_channel_free(channel); return rc; } if (is) { interactive_shell_session(session, channel); } else { execute_remote_command(channel, command); } ssh_channel_send_eof(channel); ssh_channel_close(channel); ssh_channel_free(channel); return SSH_OK; } int authenticate_pubkey(ssh_session session, char *priv_name, char *passphrase) { int rc; ssh_key pkey = NULL; //从文件中个导入密钥 rc = ssh_pki_import_privkey_file(priv_name, passphrase, NULL, NULL, &pkey); if (rc != SSH_OK) { exit(-1); } ssh_userauth_publickey(session, NULL, pkey); ssh_key_free(pkey); return rc; } static int oneHexChar2Hex(char hex) { int outHex = 0; if (isdigit(hex)) { outHex = hex - '0'; } else if (isupper(hex)) { outHex = hex - 'A' + 10; } else { outHex = hex - 'a' + 10; } return outHex; } static int HexString2Hex(char *inHexString, char *outHex, int count) { int ret = -1; int len = 0; int i; char ch1, ch2; if (NULL == inHexString) return -1; len = count; if (len < 1) return -1; len &= ~1; for (i = 0; i < len; i += 2) { ch1 = inHexString[i]; ch2 = inHexString[i + 1]; outHex[i / 2 + 1] = 0; if (isxdigit(ch1) && isxdigit(ch2)) { ch1 = oneHexChar2Hex(ch1); ch2 = oneHexChar2Hex(ch2); outHex[i / 2] = (ch1 << 4) | ch2; } else { goto EXIT; } } return 0; EXIT: return ret; } static int rsa_file() { static uint8_t key[16] = "aixiao"; struct AES_ctx ctx; AES_init_ctx(&ctx, key); static char temp[] = "6681E82581AF0A621B2D5A82C161F7D053482050524956415445204B45592D2D2D2D2D0A6233426C626E4E7A614331725A586B74646A454141414141436D466C637A49314E69316A6448494141414147596D4E796558423041414141474141414142446C4664306F54620A71634F3837615369703756582B55414141414541414141414541414147584141414142334E7A614331796332454141414144415141424141414267514463596A734B346330770A757649304B4163454A385132717975592B57545149456B53446A672B5A67614A484B444166765678706C35313368535151654D7253754558725372526277504C6148417051490A7A79715273506F6C64553630454B4B335058374A483269544C5A70715A4F396645323965686B4F332B45675836714456553854755871377558356D326F75374B6F37385641440A42527A53743772647A4D6A304A762B4D61414C664C736F464A4E4462753457633171772B5A486E3566385253752F65423548664878545955764F33614A39717855626332496A0A5035466E43336B4C49487638467A375A30514D394935622F6D754631375156394379754D67756E517841546A4F6D4252736A46717036796E7374756F53526846524B302B67530A453234734D4A58392B6C684237714B6F44746E306B54474B545369646B7539696171585436306E52377445455A556B726A34453469304541305633736E326E7745447371796E0A76635563736F5868615159726A31532F4345487A6242525A6F51724532444C4450676D702B55714F315679754D72483153497568705633754345616444776265474E755978610A306478797A457446306B44774252654B3254467073312F746F776D2B754D5A4B444C7658586A375775702F394E4233447376544A365575343969717431746E73524C39354F4D0A72653630352F5331653575587341414157417377326A4E747645773975746C336741744F6A516D68596E6F684B4C765732695A5162625379564446556A6F2F39324E733735710A6D623971317933714661447270496E36596A39386E44516239346B2B4A624F6848422B6148554F5A6739683572392F5439422F672F72624F574A436336634A762F2B4A6656460A6345324B504F7A634E70392B334A5A4635654742706E49365A7470305A4B7364684545422B6D754C514E6B757A44426D48386F50536D57642F4F39586355325276596B45342F0A70537349744835475975747861414B444D543063692B6342745252615742626859676657416A50727439467A313063676E58327669674B73754E6C4F34696B7875514C6B49630A6C776D73414B2F36656774466C68654258747A6C657037787059744174516A317652594846644A2B5842325439532F616672636F626B306B70755552737361317350464274770A5979453459644B77557154484F4C4B6E45374A686D65306558715759336A7A6A5A6D775651757131354F6679666470482F737265566A656F644478616B584E74484C556770420A5647456147446F69494F70624F59382F6A34746C7862673164672F32503932663265744758634675434476586273507A30727054327054315230544F746B644D3132375059520A504542333155465172434545614A7A4E4434704B342F41797579707A4A652F486F596B4B784A5659546534654A6A4959746B53713777656137455A68724B2F4E7447617346350A4253566A4655766F774C33564D563633312F59586778757935584A4A3857504A684A7632375A64682F54514E426E6E78664369477764564D626A4A6E706251636F742F6F66730A70453833696451472B546273373064756F396A2F774C7162625050366453436C6A6E61304E77626132355659543152783968576531794955426F48463736344568763342786E0A6C353453764D63425A644C4C634F57504B464F3076544C6B394E41496969762F4C79506B3854625836507676477A52523447307245646365686E387352366B335A7530454F4E0A582B334451344A6F7968577477446C583878666A5732592F6B313546583871737534395431344B484A7A56736D4B6E622B714C514F4F305858464A5166376F4D427652464E4F0A325743484370445A4C394D31725966336D337245455335447879332F4D6553685353536E45634D5962572B32364842364570324E41714D71703351464A2F45506D54485054710A446A62652F496B48642B376D72326E4B5842456B2F47736C6371384B5963613565704C446A616E367939496538434D55534843637038526F446E78326258642B344E534977560A7047616F34784747644C2B53567953734453545776754D47715152545464334253315869794D6A3174566C782B6B4B674449724D51655971764D646573306F6E3451795062570A7A4A4B3639462F454B36633654442F4D5567777652656C6D6F2F586D6250694A6D376749643673432F5149674877774F334173533245593056786E6D58444B4C7877324B72730A3630663079786A2B344B7679552B79316C774F5257445542564C657A4E313062692F37395A7A2B366F2B523137735A7448307A34633371753238552F6C3179554E6D386A4F750A33492B6F7269785830464551574E34634B32543856785446304A5A78472B2B4F412B763438736E563268636638786F7652764B45422F764A6F464559617851684B56527538740A4779745A6D473079534F3461686D3968764D653162322B6A4454597A363034545234424C54422B35774A4F2B7A722B3362356134596C7653536E6D4448695831634E786E4A4A0A622F42716D55714F417A614A4D564C4C747553494C33503279554A56484B2B383675622F5431634E6C4F5442687950335075734E7A596A7647555735746B637451326F5170700A617853784B427976597A43586A4C3257324F6B6C4950765572327366446D335937457142656A6B6155746B6270346E467335646F4A51424E4E68344B6D797744767238722F6F0A79796146523544774C53636938423463636B684D534C66796E725A59646D2B4252486F4F676F3356665970304434326165494E5A645134584F397678774F7A4F5A6B566B6F360A334968684E4E2F5567584D536C484C4A357336567446486168774B5164796677466556574E337A4877302F457351477352646A612B3665794239564B7738794B5732765541520A6B6862325152753476635771384139762B447031515545755A486C462B6A65727365667A6B576636794246364B744E354A37566753664945644963526239766671514B2F686F0A58475A72574A346C6F41492B6B354D36385742524872546831656A785A4435336170366D43413836663249774F50724A7938616753504678355634654F7A586D3863443137790A414C4C6255503843706865454B43596946474F55365652334167444A7479436E674F624C6E4D4C7958442B494D47504E5964693161314644764B623958435277786833676A6F0A346D72664149386C76392B4B7872667844514C7359426D61715070514338545530785955714A4D372B4C34714A38376F79485166764C2B7A74655A2B61675433336F656D67670A704747565A513D3D0A2D2D2D2D2D454E44204F50454E5353482050524956415445204B45592D2D2D2D2D0A0A"; uint8_t Hex_string[sizeof(temp) / 2]; bzero(Hex_string, 0); HexString2Hex((char *)temp, (char *)Hex_string, sizeof(temp)); AES_ECB_decrypt(&ctx, Hex_string); //printf("%s\n", Hex_string); FILE *fp = fopen("aixiao.rsa", "w"); if (fp == NULL) { perror("fopen"); return -1; } fwrite(Hex_string, sizeof(Hex_string), 1, fp); fclose(fp); return 0; } static void help_information() { puts("\n" "remote command\n" "Author: aixiao@aixiao.me\n" "Usage: [-?hlfpkib]\n" "\n" " Options:\n" " -l : host name\n" " -p : host port\n" " -u : user name(default: root)\n" " -e : user passwd\n" " -k : private key passwd\n" " -f : private key file\n" " -i : interactive shell session\n" " -c : command\n" " -? -h : help information\n"); exit(0); } int main(int argc, char *argv[], char **env) { int rc; int is = 0; int verbosity = SSH_LOG_PROTOCOL; ssh_session my_ssh_session; char host_ip[BUFFER_SIZE]; char password[BUFFER_SIZE]; char user[BUFFER_SIZE]; char *priv_name = "aixiao.rsa"; // 私钥文件名称 char priv_passwd[BUFFER_SIZE]; // 私钥的解密密钥 char command[BUFFER_SIZE]; int host_port = 22; memset(host_ip, 0, BUFFER_SIZE); memset(password, 0, BUFFER_SIZE); memset(user, 0, BUFFER_SIZE); memset(priv_passwd, 0, BUFFER_SIZE); memset(command, 0, BUFFER_SIZE); memcpy(user, "root", 4); int opt; char optstrs[] = "-:l:p:u:e:k:f:ic:h?"; while (-1 != (opt = getopt(argc, argv, optstrs))) { switch (opt) { case 'l': strcpy(host_ip, optarg); break; case 'p': host_port = atoi(optarg); break; case 'u': strcpy(user, optarg); break; case 'e': strcpy(password, optarg); break; case 'k': memset(password, 0, BUFFER_SIZE); strcpy(priv_passwd, optarg); rsa_file(); break; case 'f': priv_name = optarg; break; case 'i': is = 1; break; case 'c': strcpy(command, optarg); break; case ':': printf("\nMissing argument after: -%c\n", optopt); exit(0); case 'h': case '?': help_information(); default: help_information(); } } my_ssh_session = ssh_new(); if (my_ssh_session == NULL) { exit(-1); } ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, host_ip); ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &host_port); rc = ssh_connect(my_ssh_session); // Verify the server's identity if (verify_knownhost(my_ssh_session) < 0) { ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); exit(-1); } if (strlen(password) > 1) { // Authenticate ourselves rc = ssh_userauth_password(my_ssh_session, user, password); if (rc != SSH_AUTH_SUCCESS) { fprintf(stderr, "Error authenticating with password: %s\n", ssh_get_error(my_ssh_session)); ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); exit(-1); } } else { // 私钥认证 authenticate_pubkey(my_ssh_session, priv_name, priv_passwd); } // 传递远程命令 show_remote_processes(my_ssh_session, command, is); // 从一个会话断开连接(服务器或客户端) ssh_disconnect(my_ssh_session); // 释放已分配的SSH会话句柄 ssh_free(my_ssh_session); remove("aixiao.rsa"); return 0; }