commit 2387620fa2ecf6679f083ba4c50302a47796113a Author: aixiao Date: Sat May 7 13:18:59 2022 +0800 初次提交 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4d77de7 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +CROSS_COMPILE ?= +CC := $(CROSS_COMPILE)gcc +STRIP := $(CROSS_COMPILE)strip +CFLAGS += -g -O2 -Wall +LIBS = -lssh +OBJ := remote_libssh + +all: main.o + $(CC) $(CFLAGS) -o $(OBJ) $^ $(LIBS) +.c.o: + $(CC) $(CFLAGS) -c $< + +clean: + rm -rf *.o + rm $(OBJ) + diff --git a/README.md b/README.md new file mode 100644 index 0000000..164acf1 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# remote_libssh + 远程执行shell命令 + 支持aes 128位加密密钥文件,写入程序中 + 支持指定未加密的密钥文件 + + +# 编译 + git clone https://git.aixiao.me/aixiao/remote_libssh + cd remote_libssh + make clean; make + cd ./aes + make clean; make + + +# Help + remote command + Author: aixiao@aixiao.me + Usage: [-?hlfpkb] + + Options: + -l : host # 主机名或Ip + -f : port # 端口 + -p : passwd # 密码(当前登录的用户名,我一般是root) + -k : private key passwd # 私钥密码 + -i : private key file # 私钥文件 + -b : command # 执行的命令 + -? -h : help information diff --git a/aes/Makefile b/aes/Makefile new file mode 100644 index 0000000..5e11fe8 --- /dev/null +++ b/aes/Makefile @@ -0,0 +1,16 @@ +CROSS_COMPILE ?= +CC := $(CROSS_COMPILE)gcc +STRIP := $(CROSS_COMPILE)strip +CFLAGS += -g -O2 +LIBS = +OBJ := aes + +all: aes.o main.o + $(CC) $(CFLAGS) -o $(OBJ) $^ $(LIBS) +.c.o: + $(CC) $(CFLAGS) -c $< + +clean: + rm -rf *.o + rm $(OBJ) + diff --git a/aes/aes b/aes/aes new file mode 100644 index 0000000..1765203 Binary files /dev/null and b/aes/aes differ diff --git a/aes/aes.c b/aes/aes.c new file mode 100644 index 0000000..bf8eba6 --- /dev/null +++ b/aes/aes.c @@ -0,0 +1,607 @@ +/* + * Advanced Encryption Standard + * @author Dani Huertas + * @email huertas.dani@gmail.com + * + * Based on the document FIPS PUB 197 + */ +#include "aes.h" + +/* 128 bits */ +/* +static uint8_t key[] = +{ + 0x2b, 0x7e, 0x15, 0x16, + 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, + 0x09, 0xcf, 0x4f, 0x3c +}; +*/ + +/* + Number of columns (32-bit words) comprising the State. For this standard, Nb = 4. +*/ +static int Nb = 4; + +//Number of 32-bit words comprising the Cipher Key. For this standard, Nk = 4, 6, or 8. +static int Nk = 4; + +//Number of rounds, which is a function of Nk and Nb (which is fixed). For this standard, Nr = 10, 12, or 14. +static int Nr = 10; + +/*******************具体实现代码*********************/ + +/* + * Addition in GF(2^8) + * http://en.wikipedia.org/wiki/Finite_field_arithmetic + */ +uint8_t gadd(uint8_t a, uint8_t b) +{ + return a^b; +} + +/* + * Subtraction in GF(2^8) + * http://en.wikipedia.org/wiki/Finite_field_arithmetic + */ +uint8_t gsub(uint8_t a, uint8_t b) +{ + return a^b; +} + +/* + * Multiplication in GF(2^8) + * http://en.wikipedia.org/wiki/Finite_field_arithmetic + * Irreducible polynomial m(x) = x8 + x4 + x3 + x + 1 + */ +uint8_t gmult(uint8_t a, uint8_t b) +{ + + uint8_t p = 0, i = 0, hbs = 0; + + for (i = 0; i < 8; i++) + { + if (b & 1) + { + p ^= a; + } + + hbs = a & 0x80; + a <<= 1; + if (hbs) a ^= 0x1b; // 0000 0001 0001 1011 + b >>= 1; + } + + return (uint8_t)p; +} + +/* + * Addition of 4 byte words + * m(x) = x4+1 + */ +void coef_add(uint8_t a[], uint8_t b[], uint8_t d[]) +{ + + d[0] = a[0]^b[0]; + d[1] = a[1]^b[1]; + d[2] = a[2]^b[2]; + d[3] = a[3]^b[3]; +} + +/* + * Multiplication of 4 byte words + * m(x) = x4+1 + */ +void coef_mult(uint8_t *a, uint8_t *b, uint8_t *d) +{ + + d[0] = gmult(a[0],b[0])^gmult(a[3],b[1])^gmult(a[2],b[2])^gmult(a[1],b[3]); + d[1] = gmult(a[1],b[0])^gmult(a[0],b[1])^gmult(a[3],b[2])^gmult(a[2],b[3]); + d[2] = gmult(a[2],b[0])^gmult(a[1],b[1])^gmult(a[0],b[2])^gmult(a[3],b[3]); + d[3] = gmult(a[3],b[0])^gmult(a[2],b[1])^gmult(a[1],b[2])^gmult(a[0],b[3]); +} + +/* + * S-box transformation table + */ +static uint8_t s_box[256] = +{ + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, // 0 + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, // 1 + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, // 2 + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, // 3 + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, // 4 + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, // 5 + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, // 6 + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, // 7 + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, // 8 + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, // 9 + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, // a + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, // b + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, // c + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, // d + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, // e + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +};// f + +/* + * Inverse S-box transformation table + */ +static uint8_t inv_s_box[256] = +{ + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, // 0 + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, // 1 + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, // 2 + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, // 3 + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, // 4 + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, // 5 + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, // 6 + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, // 7 + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, // 8 + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, // 9 + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, // a + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, // b + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, // c + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, // d + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, // e + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +};// f + + +/* + * Generates the round constant Rcon[i] + */ +uint8_t R[] = {0x02, 0x00, 0x00, 0x00}; + +uint8_t * Rcon(uint8_t i) +{ + + if (i == 1) + { + R[0] = 0x01; // x^(1-1) = x^0 = 1 + } + else if (i > 1) + { + R[0] = 0x02; + i--; + while (i-1 > 0) + { + R[0] = gmult(R[0], 0x02); + i--; + } + } + + return R; +} + +/* + * Transformation in the Cipher and Inverse Cipher in which a Round + * Key is added to the State using an XOR operation. The length of a + * Round Key equals the size of the State (i.e., for Nb = 4, the Round + * Key length equals 128 bits/16 bytes). + */ +void add_round_key(uint8_t *state, uint8_t *w, uint8_t r) +{ + + uint8_t c; + + for (c = 0; c < Nb; c++) + { + state[Nb*0+c] = state[Nb*0+c]^w[4*Nb*r+4*c+0]; //debug, so it works for Nb !=4 + state[Nb*1+c] = state[Nb*1+c]^w[4*Nb*r+4*c+1]; + state[Nb*2+c] = state[Nb*2+c]^w[4*Nb*r+4*c+2]; + state[Nb*3+c] = state[Nb*3+c]^w[4*Nb*r+4*c+3]; + } +} + +/* + * Transformation in the Cipher that takes all of the columns of the + * State and mixes their data (independently of one another) to + * produce new columns. + */ +void mix_columns(uint8_t *state) +{ + + uint8_t a[] = {0x02, 0x01, 0x01, 0x03}; // a(x) = {02} + {01}x + {01}x2 + {03}x3 + uint8_t i, j, col[4], res[4]; + + for (j = 0; j < Nb; j++) + { + for (i = 0; i < 4; i++) + { + col[i] = state[Nb*i+j]; + } + + coef_mult(a, col, res); + + for (i = 0; i < 4; i++) + { + state[Nb*i+j] = res[i]; + } + } +} + +/* + * Transformation in the Inverse Cipher that is the inverse of + * MixColumns(). + */ +void inv_mix_columns(uint8_t *state) +{ + + uint8_t a[] = {0x0e, 0x09, 0x0d, 0x0b}; // a(x) = {0e} + {09}x + {0d}x2 + {0b}x3 + uint8_t i, j, col[4], res[4]; + + for (j = 0; j < Nb; j++) + { + for (i = 0; i < 4; i++) + { + col[i] = state[Nb*i+j]; + } + + coef_mult(a, col, res); + + for (i = 0; i < 4; i++) + { + state[Nb*i+j] = res[i]; + } + } +} + +/* + * Transformation in the Cipher that processes the State by cyclically + * shifting the last three rows of the State by different offsets. + */ +void shift_rows(uint8_t *state) +{ + + uint8_t i, k, s, tmp; + + for (i = 1; i < 4; i++) + { + // shift(1,4)=1; shift(2,4)=2; shift(3,4)=3 + // shift(r, 4) = r; + s = 0; + while (s < i) + { + tmp = state[Nb*i+0]; + + for (k = 1; k < Nb; k++) + { + state[Nb*i+k-1] = state[Nb*i+k]; + } + + state[Nb*i+Nb-1] = tmp; + s++; + } + } +} + +/* + * Transformation in the Inverse Cipher that is the inverse of + * ShiftRows(). + */ +void inv_shift_rows(uint8_t *state) +{ + + uint8_t i, k, s, tmp; + + for (i = 1; i < 4; i++) + { + s = 0; + while (s < i) + { + tmp = state[Nb*i+Nb-1]; + + for (k = Nb-1; k > 0; k--) + { + state[Nb*i+k] = state[Nb*i+k-1]; + } + + state[Nb*i+0] = tmp; + s++; + } + } +} + +/* + * Transformation in the Cipher that processes the State using a non­ + * linear byte substitution table (S-box) that operates on each of the + * State bytes independently. + */ +void sub_bytes(uint8_t *state) +{ + + uint8_t i, j; + uint8_t row, col; + + for (i = 0; i < 4; i++) + { + for (j = 0; j < Nb; j++) + { + row = (state[Nb*i+j] & 0xf0) >> 4; + col = state[Nb*i+j] & 0x0f; + state[Nb*i+j] = s_box[16*row+col]; + } + } +} + +/* + * Transformation in the Inverse Cipher that is the inverse of + * SubBytes(). + */ +void inv_sub_bytes(uint8_t *state) +{ + + uint8_t i, j; + uint8_t row, col; + + for (i = 0; i < 4; i++) + { + for (j = 0; j < Nb; j++) + { + row = (state[Nb*i+j] & 0xf0) >> 4; + col = state[Nb*i+j] & 0x0f; + state[Nb*i+j] = inv_s_box[16*row+col]; + } + } +} + +/* + * Function used in the Key Expansion routine that takes a four-byte + * input word and applies an S-box to each of the four bytes to + * produce an output word. + */ +void sub_word(uint8_t *w) +{ + + uint8_t i; + + for (i = 0; i < 4; i++) + { + w[i] = s_box[16*((w[i] & 0xf0) >> 4) + (w[i] & 0x0f)]; + } +} + +/* + * Function used in the Key Expansion routine that takes a four-byte + * word and performs a cyclic permutation. + */ +void rot_word(uint8_t *w) +{ + + uint8_t tmp; + uint8_t i; + + tmp = w[0]; + + for (i = 0; i < 3; i++) + { + w[i] = w[i+1]; + } + + w[3] = tmp; +} + +/* + * Key Expansion + */ +void key_expansion(uint8_t *key, uint8_t *w) +{ + + uint8_t tmp[4]; + uint8_t i; + uint8_t len = Nb*(Nr+1); + + for (i = 0; i < Nk; i++) + { + w[4*i+0] = key[4*i+0]; + w[4*i+1] = key[4*i+1]; + w[4*i+2] = key[4*i+2]; + w[4*i+3] = key[4*i+3]; + } + + for (i = Nk; i < len; i++) + { + tmp[0] = w[4*(i-1)+0]; + tmp[1] = w[4*(i-1)+1]; + tmp[2] = w[4*(i-1)+2]; + tmp[3] = w[4*(i-1)+3]; + + if (i%Nk == 0) + { + + rot_word(tmp); + sub_word(tmp); + coef_add(tmp, Rcon(i/Nk), tmp); + + } + else if (Nk > 6 && i%Nk == 4) + { + + sub_word(tmp); + + } + + w[4*i+0] = w[4*(i-Nk)+0]^tmp[0]; + w[4*i+1] = w[4*(i-Nk)+1]^tmp[1]; + w[4*i+2] = w[4*(i-Nk)+2]^tmp[2]; + w[4*i+3] = w[4*(i-Nk)+3]^tmp[3]; + } +} + +void cipher(uint8_t *in, uint8_t *out, uint8_t *w) +{ + + uint8_t state[4*Nb]; + uint8_t r, i, j; + + for (i = 0; i < 4; i++) + { + for (j = 0; j < Nb; j++) + { + state[Nb*i+j] = in[i+4*j]; + } + } + + add_round_key(state, w, 0); + + for (r = 1; r < Nr; r++) + { + sub_bytes(state); + shift_rows(state); + mix_columns(state); + add_round_key(state, w, r); + } + + sub_bytes(state); + shift_rows(state); + add_round_key(state, w, Nr); + + for (i = 0; i < 4; i++) + { + for (j = 0; j < Nb; j++) + { + out[i+4*j] = state[Nb*i+j]; + } + } +} + +void inv_cipher(uint8_t *in, uint8_t *out, uint8_t *w) +{ + + uint8_t state[4*Nb]; + uint8_t r, i, j; + + for (i = 0; i < 4; i++) + { + for (j = 0; j < Nb; j++) + { + state[Nb*i+j] = in[i+4*j]; + } + } + + add_round_key(state, w, Nr); + + for (r = Nr-1; r >= 1; r--) + { + inv_shift_rows(state); + inv_sub_bytes(state); + add_round_key(state, w, r); + inv_mix_columns(state); + } + + inv_shift_rows(state); + inv_sub_bytes(state); + add_round_key(state, w, 0); + + for (i = 0; i < 4; i++) + { + for (j = 0; j < Nb; j++) + { + out[i+4*j] = state[Nb*i+j]; + } + } +} + +/*******************结束*********************/ + +//将原始string转换为密文 +//原始数据长度: orign +//加密后的数据:text +bool EncryptDataToCipherTxt(uint8_t *orign, uint8_t *result, uint16_t length) +{ + uint8_t w[240]; //密钥扩展,定义最大长度 + + //根据密钥长度计算Nk,Nr + switch (sizeof(key)) + { + default: + case 16: + Nk = 4; + Nr = 10; + break; + case 24: + Nk = 6; + Nr = 12; + break; + case 32: + Nk = 8; + Nr = 14; + break; + } + + //计算出扩展密钥的值 + key_expansion(key, w); + + //分块加密,每段16字节 + if( length % 16 == 0 ) + { + uint16_t i; + uint16_t counter=length / 16; + uint8_t *p,*q; + + for(i=0; i +#include +#include +#include +#include + +extern uint8_t *key; + +//加密 +bool EncryptDataToCipherTxt(uint8_t *orign, uint8_t *result, uint16_t length); + +//解密 +bool DecryptCipherTxtToData(uint8_t *orign, uint8_t *result, uint16_t length); + +#endif diff --git a/aes/aes.o b/aes/aes.o new file mode 100644 index 0000000..017b97c Binary files /dev/null and b/aes/aes.o differ diff --git a/aes/main.c b/aes/main.c new file mode 100644 index 0000000..9f0dd17 --- /dev/null +++ b/aes/main.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include "aes.h" + +#define AES_ENC_MAX_LEN 8192 + +uint8_t *key; + +void from_hex(char *s, int l, char *d) +{ + while (l--) { + *(d++) = ((*s > '9' ? (*(s++) + 9) : *(s++)) << 4) + | ((*s > '9' ? (*(s++) + 9) : *(s++)) & 0x0F); + } +} + +void StringToByte(char *source, unsigned char *dest, int sourceLen) +{ + + int i; + unsigned char highByte, lowByte; + + for (i = 0; i < sourceLen; i += 2) { + highByte = toupper(source[i]); //转换为大写 + lowByte = toupper(source[i + 1]); + + if (highByte > 0x39) + highByte -= 0x37; + else + highByte -= 0x30; + + if (lowByte > 0x39) + lowByte -= 0x37; + else + lowByte -= 0x30; + + dest[i / 2] = (highByte << 4) | lowByte; + } + return; +} + +int array_len(char *str) +{ + int i = 0; + + int Len = strlen(str); + unsigned char out[AES_ENC_MAX_LEN] = { 0 }; + + StringToByte(str, out, Len); + for (i = 0; i < Len / 2; i++) { + ; + //printf("%02X ", out[i]); + } + //printf("%d\n", i); + + return i; +} + +int main(int argc, char *argv[]) +{ + key = (uint8_t *)malloc(128); + strcpy(key, "1234567890ABCDEF"); + char string[AES_ENC_MAX_LEN]; + + int opt; + char optstrs[] = ":e:d:k:h?"; + while (-1 != (opt = getopt(argc, argv, optstrs))) { + switch (opt) { + case 'k': + strcpy(key, optarg); + break; + case 'e': + { + memset(string, 0, AES_ENC_MAX_LEN); + memcpy(string, optarg, strlen(optarg)); + uint16_t i = 0; + uint8_t out[AES_ENC_MAX_LEN]; + + uint16_t length = strlen(string); + + while (length % 16) { + strcat(string, "\0"); + length++; + } + + //printf("加密数据:\n"); + EncryptDataToCipherTxt((uint8_t *) string, out, length); + //printf("密文长度=%d\n", length); + for (i = 0; i < length; i++) { + printf("%02X", out[i]); + } + printf("\n"); + ; + } + break; + case 'd': + { + memset(string, 0x00, AES_ENC_MAX_LEN); + + uint8_t out[AES_ENC_MAX_LEN]; + memset(out, 0x00, AES_ENC_MAX_LEN); + + from_hex(optarg, array_len(optarg), (char *)out); + //printf("%s\n", out); + + DecryptCipherTxtToData(out, (uint8_t *) string, array_len(optarg)); + //printf("解密报文长度=%d\n", array_len(optarg)); + printf("%s\n", string); + } + break; + case ':': + printf("\nMissing argument after: -%c\n", optopt); + case 'h': + case '?': + + default: + ; + } + } + free(key); + return 0; +} diff --git a/aes/main.o b/aes/main.o new file mode 100644 index 0000000..bbb06c3 Binary files /dev/null and b/aes/main.o differ diff --git a/main.c b/main.c new file mode 100644 index 0000000..a137aea --- /dev/null +++ b/main.c @@ -0,0 +1,289 @@ +#include +#include +#include +#include +#include + + +#define LIBSSH_STATIC 1 +#include + + +#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 show_remote_processes(ssh_session session, char *command) +{ + ssh_channel channel; + int rc; + char buffer[256]; + int nbytes; + + 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; + } + + 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; + } + + 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; +} + +int rsa_file() +{ + char rsa[8192] = {0}; + + char temp[] = + "./aes/aes -d \"FE67236A61D8D67FD4DEBFD46C9E409B94326781DAE97A7DCD84426711D4D0E078EBA98886342F1E8568828843886DCC38487ACDC9C413D73A4E0C80E6070D054FD5E0DCC0771452FC5E31FCF715EFC62177EABE9014E7F9623B4EA843A93A9020A268F9E8A300BB5D30AD22D52F6EA441222205DAF5560A82F18F28075C035205BF4A47E8E350A957B1F7E90AB63AC2FCCCAC23E1C9C3B50F34B32CDBC7BC8B2155475FBC0B794089C60BFA0EFDD2E096D65DAF31A40E31A5D2C1547A4EA622241EEDD9307CB74BFB3C82E5F48FB1A2CA6D5B223BBB9807B6E54487F4F116D7D9EA2320BFE025ED8B88DBF13F79884C8ACB9161793D59D527579319173EC5A0784398C81435FB0536C048AE656F54422BC41207E0DD3E0B66DB70D725B644915D967D9BA56FC9FE1BF8D628D00D5F6835E48CF9C2B9BCB995EC84D881444F0269272FEE8D4FD667A6C909ADB500FB83E25DB45C9CE75044D2C052E72271665BC37AF036D4A81A889BB8A211B4B9730C0ECC9C70B8B4A07BC4D5A2C274361517DE7C8E87E1AC0A66F3D99F593BE77F1B1343323C92F85B4801957E0F32CAB604252028ACB779E1DCA318A8A9F367F7BF9B4D7CDFEC06D878AF6D4EB4BD7F564BA7134479721CECA232CB0C0FD0F63C6FCC63EA393BA06E13FCF691FC40939B6B332842D8046EBC8049C0971FADACBBE3D28C80FB2F59FFCE1482D050FF3BDB22EF9E67295EB3C1F045EF3CB0F638CE5437E20F8126725E5DF1A867F59407795288B5E69385BDED43E1484886B08BCA06A84938F6BED0CF1326BA149FD3E45E533E3AC48E222025CBD27A33DD6A9BF46F35F601CE8E54DBD6E0ECECE1ECC8D6091F86836C781AC5D21E390FFF2CAAD3FA72497548365E77981C24707B3206E679035D668AE66245EA900FE533E8B935C84D5755ECA88AF396B52C7CBEDB448860D826DD0BEE671F07DE374AE31E71883AF95A45F38066C5BC78C49C783B85395A23627BF202397143F556DE4FB0C39977824834C4716C44435FC5B6286BC14E5D3DFE4C7133A88772509A54C80CCCE45433F7271E6434E37BB20754CA8C9462499BC4DA5E2010B06B05514F5FE7532E873D8918C594D28E2446D074B205589F1A50933EAE1165C48632CC110193D3CA6C6CE001E137A218AA9D09EA918881B5635BCADE6670CD061D7D9302561A5B7D4D752A67FAE30C30FD9D1C7CF83D7700ABD455CA2E190183361F9CF25D963E51CBC601E0FC9D752D45E0A72ACBDEE319927F72D023DB94BEB5DFF2153CC4D6187406A44FF8DEFD7045B3E5DF08A06851CF9B462804F339EB96F7D68BCEE2A3860E5DFD26C2884C121DCF3168185CB261FFE3C6F15343CC4769D0632214CC77EF6313D290D7F42CF317DD90FA6CC98983318863FB2A4C43E231F043CDEEF59C305F06B6AF08683B681CD6C7D7CB6B56EE778ED9FD2790C3D34C3754BD7E8A243D4813542E1DF34D127754F93A205F7889E14D9B21E1760318152E6E67FA608D1610CC1894A127595AF80A939A0FD1A18B5662F79AF3CB0EF0276767DFB062A1BD35CA95912F0B31D5951E0A4245856DDE9F11A782148ACC56F38D866B5505E5DBC2FA1204469AB5D44F996DFEE88F35E47ED8206EA5B537A77C175FAB0A392E6FA8C2BF69D63593D7F78CE72145228BD1CDC1ECC051869DF09CEC01DA31F997250D953745A28C61EB7EB379010518D83F8E1A27A81EA78C84DC7D12F64593D3051A5DA89CCF88580E4CE752F6A528041ADF62268F84F09A5CA7E66F6C4AA3E1FC481813C614BF4F783F5E9AC0846178DA1A7EB24BE1B0620826E34D4AC1C72F820DACBDA40294272093FCA2765DC7C052CCDA64A3C7998E0ADBD118FECC3260529D44D4B10BDA8CE9C9AAD5D15D799B0EB2B4976CBE99B78E4068C1105924D2CCC08FCE95B5963ABDF316D47417D7C73510450386565BDED107F4F278B6CA29D5109C5324CEEFA28A5B84F843932991DE2D1DF828916A097A53B233DF1B82DC084D624BF7F35BF0E2A551EFBCDD0A0B8324A68636B9B72BA68D1A1C6A89B7A736BC82381AE3CD6B4A5CCE0ED35C2B17ADD63BA8C908256AE5297AEC9D9ABD2EBE95A43617383F420AF893752B4B03463AAB3B88E3F835FD19504A615AFC739995D93960987235CA0FBAE7D9626045B2E6382521C4CF01C07AC26E9E1C5CFEAF782AD97E983F3A43F8E90314AC32C60D44AF7CBB1EC74C8BB5139526B2A577BCC2558503842F3AD9A2026D2ED104D462D035AB2CC3802D7136DFC938067F4EFD38ECFDBAE8FE30BC3342D3354628F0F87EDCD5F6A005F69A32A30DA6C6AC2188C3A11790867797D2D03D836B9F6FFD55C590F1AC8DF4A0F63B5201987C9AA05B4EAA91466E4D5454549E184306EB59381CAA20A3B1EFE7EFFC97A98A48E8712A0A98B4E39F050BFF5EFB72917E60DD1992DFC77840F00862FA81D34FBF774AB060B80E0805E63C65CE0B5651256D42A8376FD734BEECE02A58651CC8F567EAD91C0C60690D8C9104205A338B3DAB0F75221BE9AE505CFCB2343F9FD68CC79F96795C8ED06866B32CF12456C30232CDF5D1F8EB253777264EF7D3706E875DF54FC216B2DC90C6653D813E9135288730FC6A9178079D6E89694D9CC4CF828F06AE954224402B1FE2BBBA5A6DECA5344DD11DB77AE49D0BB3DA38FCACC15F8AD1BC5A6212F93F2AD285F5915A4AD642239CDB3240CD622E4DBEE18366BB2CB4604F92D8EFC693C3AB2F90AD84FCFD88CB461C3DF89043E94EFBF08FED2B98C5835CBFC3EDDBA653A33D35BA2E2D08F7ADA87A12FAF76DF84D170BD92A56E62DE8B8B0D1CCAEB4DB4BF7D2FA9F8F23A8443638D721BCCDD31D5396EE2BD5FB3F28BC877BF430908415DB46E3B93AF80016036B9CFA933486B83C19061387478808ABE63FDA4B0B76B3AD50343E540EC4F80400A362627273FC1EE643B6B7736B9338A7F1433780574224674D6F625BEAD125F3AD383EEAA12AFAF0DC812039741034A74423F57F82436542EE1FAA31EB72A98E8D060B992BD5954A42416C5C2A3C826D2F8743D9487DA95DF047B329E7FB125216FA1DE2577DA00998872C8B46FE665A20366EF8C839AA8F549C06917C2C752C72963FA1C619F0ADAB3E1309622E6B5EF01A31EB78380CBC657282604FA98AA9B51596F45B7CD3BEE7CD6E2AAC43224C052911EA564481B3FC4AE054BBF72666447110FA193CE8BB277F6D3D069A0BD7EE7D01075FA7E729F5F6E70E890287B52DC423180081FB7E267AC68EAB94786E73235530BB78A1C4AA5998529820572970063C09D1B15DBD2596D3BFD3DA6AA0CC600D9ADCE8D9EAAE3819B01F482BD852917CEB7C006E6E8FEB057EB0AC9A525A72EA433096C51C279506322F84D76E47612FE2BCD27849F6FE7CEC0DBEA27BEC270A696AB84DA1CCB190A97115447FDBF9362B23E89BCD9960A4436B8324903254E28344DB6376E25D2857CD37BAA99D656293E8F82D3A74DD4026D14B1F8935D581F973BBF5B75170E2655512C6CA0415193B75BE9EEB0F7F9884A7FF11BA473056D556FC7281A9DCD79B3F93515565A3079034C1C5C9DF838AD40897F37D74C090269914F89A60E3DB12CDB79E5CAE0F200310D0C1190047D314857DE44A62AFB1615CFBD25B93E2ADD774937660C9B8231D9D952E728CC0D67A74E76BEEE93189C9BA89EB55D933AD898C77ADF21C7DB40394525F0F3B1DDE711B54228DAA\""; + + FILE *fd = popen(temp, "r"); + if (fd == NULL) + perror("popen"); + + fseek(fd, 0, SEEK_END); + long file_size = ftell(fd); + rewind(fd); + fread(rsa, file_size, 1, fd); + rsa[file_size] = '\0'; + //printf("%s", rsa); + fclose(fd); + + FILE *rfd = fopen("aixiao.rsa", "w+"); + fseek(rfd, 0, SEEK_SET); + fwrite(rsa, strlen(rsa), 1, rfd); + + fclose(rfd); + + return 0; +} + +void help_information() { + puts("\n" +"remote command\n" +"Author: aixiao@aixiao.me\n" +"Usage: [-?hlfpkib]\n" +"\n" +" Options:\n" +" -l : host\n" +" -f : port\n" +" -p : passwd\n" +" -k : private key passwd\n" +" -i : private key file\n" +" -b : command\n" +" -? -h : help information\n"); + exit(0); +} + +int main(int argc, char *argv[], char **env) +{ + + int rc; + int verbosity = SSH_LOG_PROTOCOL; + ssh_session my_ssh_session; + + char host_ip[BUFFER_SIZE]; + char password[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(priv_passwd, 0, BUFFER_SIZE); + memset(command, 0, BUFFER_SIZE); + + int opt; + char optstrs[] = ":l:f:p:k:i:b:h?"; + while (-1 != (opt = getopt(argc, argv, optstrs))) { + switch (opt) { + case 'l': + strcpy(host_ip, optarg); + break; + case 'f': + host_port = atoi(optarg); + break; + case 'p': + strcpy(password, optarg); + break; + case 'k': + memset(password, 0, BUFFER_SIZE); + strcpy(priv_passwd, optarg); + rsa_file(); + break; + case 'i': + priv_name = optarg; + break; + case 'b': + strcpy(command, optarg); + break; + case ':': + printf("\nMissing argument after: -%c\n", optopt); + ; + 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, NULL, 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); + + // 从一个会话断开连接(服务器或客户端) + ssh_disconnect(my_ssh_session); + // 释放已分配的SSH会话句柄 + ssh_free(my_ssh_session); + + system("test -f aixiao.rsa && rm aixiao.rsa"); + + return 0; +} diff --git a/main.o b/main.o new file mode 100644 index 0000000..c29a465 Binary files /dev/null and b/main.o differ diff --git a/remote_libssh b/remote_libssh new file mode 100644 index 0000000..2ba3a23 Binary files /dev/null and b/remote_libssh differ