ojb*_*ass 4 c openssl corruption
如果您有一个很好的例子,只需使用openssl加密文件,这比我遇到问题的文件更好,我将非常感激.
更新:作者Myabe是正确的.在我没有分配的东西上使用memset让我想起strtok对非堆栈变量的窒息.
Update2:使用malloc使核心转储停止.更新了代码.控件Hs仍在出现.更新代码以反映这一点.
Update3:示例中的循环结构显示不正确.我不确定后续读取的发生方式是否大于初始读取的大小.
Update4:我想我找到了.decrypt loop有一个olen + = tlen,缓冲区应丢弃该组位.:( 不是.
Update99988: 我已经放弃了所有的希望.我想我需要抛弃这个例子,而是从Openssl书中开始.解密后,中间层缓冲区预先添加了^ H,但由于指针传入,我开始怀疑对齐问题.
我想我可能在一个糟糕的例子开始的船上比从头开始更糟糕.我不得不做一些更正(原件在下面的代码中注释).原作者在传递地址方面存在一些问题.作者使用的1024和1032不同大小的缓冲区正在激发我的想法,但我认为它与8位种子和链式加密调用有关.
我在(控制Hs)中获取垃圾字符,并且像解密这样的核心转储正在破坏堆栈.我对加密,openssl相当新,而且我对gdb并不熟悉.
我已尽一切努力简化这一过程
compile.sh
gcc -g -o blowfish blowfish.c -lcrypto
Run Code Online (Sandbox Code Playgroud)
run.sh
ulimit -c unlimited
./blowfish example.txt encrypted_example decrypted_example
echo diff example.txt decrypted_example
diff example.txt decrypted_example
Run Code Online (Sandbox Code Playgroud)
clean.sh
rm -rf blowfish encrypted_example decrypted_example core
Run Code Online (Sandbox Code Playgroud)
example.txt文件
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
Hydrogen H
Helium H
Lithium L
Beryllium B
Boron B
Carbon C
Nitrogen N
Oxygen O
Fluorine F
Neon N
Sodium N
Magnesium M
Aluminium A
Silicon S
Phosphorus P
Sulfur S
Chlorine C
Argon A
Potassium K
Calcium C
Scandium S
Titanium T
Vanadium V
Chromium C
Manganese M
Iron F
Cobalt C
Nickel N
Copper C
Zinc Z
Gallium G
Germanium G
Arsenic A
Selenium S
Bromine B
Krypton K
Rubidium R
Strontium S
Yttrium Y
Zirconium Z
Niobium N
Molybdenum M
Technetium T
Ruthenium R
Rhodium R
Palladium P
Silver A
Cadmium C
Indium I
Tin S
Antimony S
Tellurium T
Iodine I
Xenon X
Caesium C
Barium B
Lanthanum L
Cerium C
Praseodymium P
Neodymium N
Promethium P
Samarium S
Europium E
Gadolinium G
Terbium T
Dysprosium D
Holmium H
Erbium E
Thulium T
Ytterbium Y
Lutetium L
Hafnium H
Tantalum T
Tungsten W
Rhenium R
Osmium O
Iridium I
Platinum P
Gold A
Mercury H
Thallium T
Lead P
Bismuth B
Polonium P
Astatine A
Radon R
Francium F
Radium R
Actinium A
Thorium T
Protactinium P
Uranium U
Neptunium N
Plutonium P
Americium A
Curium C
Berkelium B
Californium C
Einsteinium E
Fermium F
Mendelevium M
Nobelium N
Lawrencium L
Rutherfordium R
Dubnium D
Seaborgium S
Bohrium B
Hassium H
Meitnerium M
Darmstadtium D
Roentgenium R
Ununbium U
Ununtrium U
Ununquadium U
Ununpentium U
Ununhexium U
Ununseptium U
Ununoctium U
Run Code Online (Sandbox Code Playgroud)
坏代码警告坏代码使用来自选定答案的blowfish.c代码
#include <openssl/blowfish.h>
#include <openssl/evp.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#define IP_SIZE 1024
#define OP_SIZE 1032
unsigned char key[16];
unsigned char iv[8];
int
generate_key ()
{
int i, j, fd;
if ((fd = open ("/dev/random", O_RDONLY)) == -1)
perror ("open error");
if ((read (fd, key, 16)) == -1)
perror ("read key error");
if ((read (fd, iv, 8)) == -1)
perror ("read iv error");
printf ("128 bit key:\n");
for (i = 0; i < 16; i++)
printf ("%4d ", key[i]);
printf ("\nInitialization vector\n");
for (i = 0; i < 8; i++)
printf ("%4d ", iv[i]);
printf ("\n");
close (fd);
return 0;
}
int
decrypt (int infd, int outfd)
{
char *inbuff, *outbuf;
int olen, tlen, n;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init (&ctx);
EVP_DecryptInit (&ctx, EVP_bf_cbc (), key, iv);
outbuf = (unsigned char *) malloc ( sizeof(unsigned char) * IP_SIZE );
inbuff = (unsigned char *) malloc ( sizeof(unsigned char) * OP_SIZE );
/* keep reading until a break */
for (;;)
{
memset(inbuff,'\0', OP_SIZE);
if ((n = read (infd, inbuff, OP_SIZE)) == -1)
{
perror ("read error");
break;
}
else if (n == 0)
break;
memset(outbuf,'\0', IP_SIZE);
if (EVP_DecryptUpdate (&ctx, outbuf, &olen, inbuff, n) != 1)
{
printf ("error in decrypt update\n");
return 0;
}
if (EVP_DecryptFinal (&ctx, outbuf + olen, &tlen) != 1)
{
printf ("error in decrypt final\n");
return 0;
}
olen += tlen;
if ((n = write (outfd, outbuf, olen)) == -1)
perror ("write error");
}
EVP_CIPHER_CTX_cleanup (&ctx);
return 1;
}
int
encrypt (int infd, int outfd)
{
char *inbuff, *outbuf;
int olen, tlen, n;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init (&ctx);
EVP_EncryptInit (&ctx, EVP_bf_cbc (), key, iv);
outbuf = (unsigned char *) malloc ( sizeof(unsigned char) * OP_SIZE );
inbuff = (unsigned char *) malloc ( sizeof(unsigned char) * IP_SIZE );
for (;;)
{
memset(inbuff,'\0', IP_SIZE);
if ((n = read (infd, inbuff, IP_SIZE)) == -1)
{
perror ("read error");
break;
}
else if (n == 0)
break;
if (EVP_EncryptUpdate (&ctx, outbuf, &olen, inbuff, n) != 1)
{
printf ("error in encrypt update\n");
return 0;
}
if (EVP_EncryptFinal (&ctx, outbuf + olen, &tlen) != 1)
{
printf ("error in encrypt final\n");
return 0;
}
olen += tlen;
if ((n = write (outfd, outbuf, olen)) == -1)
perror ("write error");
}
EVP_CIPHER_CTX_cleanup (&ctx);
return 1;
}
int
main (int argc, char *argv[])
{
int flags1 = 0, flags2 = 0, outfd, infd, decfd;
mode_t mode;
char choice, temp;
int done = 0, n, olen;
memset(key,'\0', 16);
memset(iv,'\0', 8);
memset(&mode, '\0', sizeof(mode));
flags1 = flags1 | O_RDONLY;
flags2 = flags2 | O_RDONLY;
flags2 = flags2 | O_WRONLY;
flags2 = flags2 | O_CREAT;
mode = mode | S_IRUSR;
mode = mode | S_IWUSR;
generate_key ();
if ((infd = open (argv[1], flags1, mode)) == -1)
perror ("open input file error");
if ((outfd = open (argv[2], flags2, mode)) == -1)
perror ("open output file error");
encrypt (infd, outfd);
close (infd);
close (outfd);
if ((outfd = open (argv[2], flags1, mode)) == -1)
perror ("open output file error");
if ((decfd = open (argv[3], flags2, mode)) == -1)
perror ("open output file error");
/* After much head scratching reusing the out as an in is correct here */
decrypt (outfd, decfd);
close (outfd);
fsync (decfd);
close (decfd);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
小智 8
该错误与调用EVP_DecryptFinal和EVP_EncryptFinal的方式有关.应该在for循环结束时调用这些函数,也是在olen中添加tlen并再次写入的最后部分是复制输出.以下是最终的工作版本:
#include <openssl/blowfish.h>
#include <openssl/evp.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#define IP_SIZE 1024
#define OP_SIZE 1024 + EVP_MAX_BLOCK_LENGTH
unsigned char key[16];
unsigned char iv[8];
int
generate_key()
{
int i, fd;
if ((fd = open("/dev/random", O_RDONLY)) == -1)
perror("open error");
if ((read(fd, key, 16)) == -1)
perror("read key error");
if ((read(fd, iv, 8)) == -1)
perror("read iv error");
printf("128 bit key:\n");
for (i = 0; i < 16; i++)
printf("%4d ", key[i]);
printf("\nInitialization vector\n");
for (i = 0; i < 8; i++)
printf("%4d ", iv[i]);
printf("\n");
close(fd);
return 0;
}
int
do_decrypt(int infd, int outfd)
{
unsigned char *inbuff, *outbuf;
int olen=0, tlen=0, n=0;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_DecryptInit(&ctx, EVP_bf_cbc(), key, iv);
outbuf = (unsigned char *) malloc(sizeof(unsigned char) * OP_SIZE);
inbuff = (unsigned char *) malloc(sizeof(unsigned char) * IP_SIZE);
/* keep reading until a break */
for (;;) {
memset(inbuff, 0, IP_SIZE);
if ((n = read(infd, inbuff, IP_SIZE)) == -1) {
perror("read error");
break;
} else if (n == 0)
break;
memset(outbuf, 0, OP_SIZE);
if (EVP_DecryptUpdate(&ctx, outbuf, &olen, inbuff, n) != 1) {
printf("error in decrypt update\n");
return 0;
}
if ((n = write(outfd, outbuf, olen)) == -1)
perror("write error");
}
tlen=0;
if (EVP_DecryptFinal(&ctx, outbuf + olen, &tlen) != 1) {
perror("error in decrypt final");
return 0;
}
if ((n = write(outfd, outbuf+olen, tlen)) == -1)
perror("write error");
EVP_CIPHER_CTX_cleanup(&ctx);
return 1;
}
int
do_encrypt(int infd, int outfd)
{
unsigned char *inbuff, *outbuf;
int olen=0, tlen=0, n=0;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit(&ctx, EVP_bf_cbc(), key, iv);
outbuf = (unsigned char *) malloc(sizeof(unsigned char) * OP_SIZE);
inbuff = (unsigned char *) malloc(sizeof(unsigned char) * IP_SIZE);
for (;;) {
memset(inbuff, 0, IP_SIZE);
if ((n = read(infd, inbuff, IP_SIZE)) == -1) {
perror("read error");
break;
} else if (n == 0)
break;
if (EVP_EncryptUpdate(&ctx, outbuf, &olen, inbuff, n) != 1) {
printf("error in encrypt update\n");
return 0;
}
if ((n = write(outfd, outbuf, olen)) == -1)
perror("write error");
}
tlen=0;
if (EVP_EncryptFinal(&ctx, outbuf + olen, &tlen) != 1) {
printf("error in encrypt final\n");
return 0;
}
if ((n = write(outfd, outbuf+olen, tlen)) == -1)
perror("write error");
EVP_CIPHER_CTX_cleanup(&ctx);
return 1;
}
int
main(int argc, char *argv[])
{
int flags1 = 0, flags2 = 0, outfd, infd;
mode_t mode;
memset(key, 0, 16);
memset(iv, 0, 8);
memset(&mode, 0, sizeof(mode));
flags1 = flags1 | O_RDONLY;
flags2 = flags2 | O_RDONLY;
flags2 = flags2 | O_WRONLY;
flags2 = flags2 | O_CREAT;
mode = mode | S_IRUSR;
mode = mode | S_IWUSR;
generate_key();
if ((infd = open(argv[1], flags1, mode)) == -1)
perror("open input file error");
if ((outfd = open(argv[2], flags2, mode)) == -1)
perror("open output file error");
do_encrypt(infd, outfd);
close(infd);
fsync(outfd);
close(outfd);
if ((infd = open(argv[2], flags1, mode)) == -1)
perror("open output file error");
if ((outfd = open(argv[3], flags2, mode)) == -1)
perror("open output file error");
do_decrypt(infd, outfd);
close(infd);
fsync(infd);
close(outfd);
return 0;
}
Run Code Online (Sandbox Code Playgroud)