簡析Linux與FreeBSD的syscall與shellcode

來源:互聯網
上載者:User
簡析Linux與FreeBSD的syscall與shellcode

建立時間:2006-08-23
文章屬性:原創
文章提交:7all (sgh81_at_163.com)

==www.cciss.cn.==
                           ==bbs.cciss.cn.==
                            
                    簡析Linux與FreeBSD的syscall與shellcode

|=---------------=[ 簡析Linux與FreeBSD的syscall與shellcode ]=------=|
|=-----------------------------------------------------------------=|
|=---------------=[ 7all<bloodfall_at_msn.com> ]=------------------=|
|=-----------------------------------------------------------------=|
|=---------------=[ 著作權:www.cciss.cn ]=-----------------------=|

--]概述
  又是一個不眠的夜晚,其實這篇文檔是不應該發表的,因為保密的原則吧,但是我仔細
google了下,沒有類似的文章,而且發表的這部分文檔也不至於被認為是什麼絕密資料,
但是我還是隱藏了很多發現的核心層級可能存在的問題:)單純從彙編代碼的結構來闡述
下linux與freebsd到底那個更好玩一些.或者說那個運行速度會更快一些:)
  我想大家看完這個文檔以後,或許會知道到底是Linux穩固?還是FreeBSD穩固?
  在本文的最後部分,附加了shellcode的問題,但沒有專門的論述.
  備忘:本文觀點僅代表個人觀點,如有不對的地方,歡迎大家指正:)以提高本人的水平.
  
--]編譯調試
A:編譯選項
Linux  :gcc -gdwarf-2 ***.c -o ***
FreeBSD: cc -gdwarf-2 ***.c -o ***
為了調試方便,我使用了上面的選項.
--------------------------------------
對於一般書寫shellcode的編譯選項一般為:
Linux  :gcc -static -o *** ***.c
FreeBSD: cc -static -o *** ***.c
B:調試工具
Linux/Unix下面的調試工具為GDB,但是GDB基於核心的調試有些力不從心,因為GDB的調試是
基於使用者模式(User mode).
這裡我使用了其它的調試工具,所以下面大家看到的調試代碼比較特殊,在這裡事先聲明.

--]Linux的syscall跟蹤
  寫過shellcode的人都知道syscall是寫shellcode的必需品:)當然這種概念只在Linux/Unix
的OS下才存在.最近這段時間因為一個"小小的問題"對Linux核心與FreeBSD的核心層級進行了
跟蹤和調試,然後發現一個蠻有意思的問題,自己感覺這個問題可能會與Linux下shellcode與
FreeBSD下shellcode的不同有關係,當然也和系統架構存在一些細微的關係.下面的內容是Linux
下面syscall的一些彙編代碼.
  在Linux下面,Application調用syscall的代碼如下:
420D4330 55               PUSH        EBP                                            |
420D4331 89E5             MOV         EBP,ESP                                    |->堆棧架構
420D4333 83EC18           SUB         ESP,00000018                        |
420D4336 897DFC           MOV         dword ptr [EBP]-04,EDI    |
420D4339 8B4D0C           MOV         ECX,dword ptr [EBP]+0c    |
420D433C 8B7D08           MOV         EDI,dword ptr [EBP]+08    |->syscall參數
420D433F 8975F8           MOV         dword ptr [EBP]-08,ESI    |
420D4342 8B5510           MOV         EDX,dword ptr [EBP]+10    |
420D4345 895DF4           MOV         dword ptr [EBP]-0c,EBX
420D4348 E81014F4FF       CALL        near32 ptr 4201575d
420D434D 81C3835F0500     ADD         EBX,00055f83
420D4353 8D77FF           LEA         ESI,dword ptr [EDI]-01
420D4356 83FE02           CMP         ESI,00000002
420D4359 8D75F0           LEA         ESI,dword ptr [EBP]-10
420D435C 0F477514         CMOVA       ESI,dword ptr [EBP]+14    
420D4360 53               PUSH        EBX
420D4361 89FB             MOV         EBX,EDI        
420D4363 B81A000000       MOV         EAX,0000001c  //system call    number value    
420D4368 CD80             INT         80                        //調用0x80
420D436A 5B               POP         EBX
420D436B 3D00F0FFFF       CMP         EAX,fffff000
420D4370 89C6             MOV         ESI,EAX
420D4372 760E             JBE         short ptr 420d4382
420D4374 F7DE             NEG         ESI
420D4376 E8C912F4FF       CALL        near32 ptr 42015644
420D437B 8930             MOV         dword ptr [EAX],ESI
420D437D BEFFFFFFFF       MOV         ESI,ffffffff
420D4382 85F6             TEST        ESI,ESI
420D4384 782A             JS          short ptr 420d43b0
420D4386 85FF             TEST        EDI,EDI
420D4388 7426             JE          short ptr 420d43b0
420D438A 83FF03           CMP         EDI,00000003
420D438D 7721             JA          short ptr 420d43b0
420D438F E8B012F4FF       CALL        near32 ptr 42015644
420D4394 C70000000000     MOV         dword ptr [EAX],00000000
420D439A 8B45F0           MOV         EAX,dword ptr [EBP]-10
420D439D 8B5DF4           MOV         EBX,dword ptr [EBP]-0c
420D43A0 8B75F8           MOV         ESI,dword ptr [EBP]-08
420D43A3 8B7DFC           MOV         EDI,dword ptr [EBP]-04
420D43A6 89EC             MOV         ESP,EBP
420D43A8 5D               POP         EBP
420D43A9 C3               RETN  
---------------------------------------------------------------------
為了簡單分析,我們就看這裡的代碼:
420D4330 55               PUSH        EBP                                            |
420D4331 89E5             MOV         EBP,ESP                                    |->堆棧架構
420D4333 83EC18           SUB         ESP,00000018                        |
420D4336 897DFC           MOV         dword ptr [EBP]-04,EDI    |
420D4339 8B4D0C           MOV         ECX,dword ptr [EBP]+0c    |
420D433C 8B7D08           MOV         EDI,dword ptr [EBP]+08    |->syscall參數
420D433F 8975F8           MOV         dword ptr [EBP]-08,ESI    |
420D4342 8B5510           MOV         EDX,dword ptr [EBP]+10    |
420D4345 895DF4           MOV         dword ptr [EBP]-0c,EBX
420D4348 E81014F4FF       CALL        near32 ptr 4201575d
420D434D 81C3835F0500     ADD         EBX,00055f83
420D4353 8D77FF           LEA         ESI,dword ptr [EDI]-01
420D4356 83FE02           CMP         ESI,00000002
420D4359 8D75F0           LEA         ESI,dword ptr [EBP]-10
420D435C 0F477514         CMOVA       ESI,dword ptr [EBP]+14    
420D4360 53               PUSH        EBX
420D4361 89FB             MOV         EBX,EDI        
420D4363 B81A000000       MOV         EAX,0000001c  //system call    number value    
420D4368 CD80             INT         80                        //調用0x80
----------------------------------------------------------------------
  當然從上面的代碼,我們只能看到Linux在更深的一層調用syscall的一個彙編代碼過程,換句話
說,可能上面的這些代碼都是廢話:)OK,我們繼續看下面的內容.

--]FreeBSD的syscall
  FreeBSD下面的syscall我進行了兩次跟進的操作才進入到內部,所以下面使用了兩個過程來示範
代碼,不過從下面的代碼來看FreeBSD的短了很多很多:)
trace into one step:
28080D98: 31C0             XOR         EAX,EAX
28080D9A: 53               PUSH        EBX
28080D9B: E800000000       CALL        near32 ptr 28080da0
-------------------------------------------------------------------
trace into two step:
28080DA0: 5B               POP         EBX
28080DA1: 81C3AC980600     ADD         EBX,000698ac
28080DA7: 8B934C0A0000     MOV         EDX,dword ptr [EBX]+00000a4c
28080DAD: 8902             MOV         dword ptr [EDX],EAX
28080DAF: 5B               POP         EBX
28080DB0: 8D051A000000     LEA         EAX,dword ptr [0000001c]//system call number value
28080DB6: CD80             INT         80
28080DB8: 7201             JC          short ptr 28080dbb
28080DBA: C3               RETN  
--------------------------------------------------------------------
  從上面的代碼來看,FreeBSD的syscall代碼比Linux的短了很多很多,但是僅僅是短還是不夠的,如果在看
這個文檔前你熟悉破解技術 or 溢出技術 or Intel組合語言.我想可能大家有這樣的感覺,FreeBSD的調用
syscall的過程比Linux的要安全了很多很多,為什麼這麼說呢?請再返回仔細看上面的Linux/FreeBSD的匯
編代碼:)下面我們也會大概的論證下,但僅僅是猜測而已:)

--]FreeBSD比Linux安全?
  學過破解技術的朋友,都知道通過一些跳轉指令來實現對於軟體的破解,當然使用跳轉指令可能僅僅對一些
簡單的軟體是有用處.突然發現我上面說的這句話是廢話,和本文沒有任何的關係,鬱悶...看來腦袋裡面裝的
東西多也不是什麼好事情:(
  言歸正傳,我們來大體的分析下為什麼說BSD比Linux要安全些!請看下面的代碼:
  Linux的syscall調用:
420D4336 897DFC           MOV         dword ptr [EBP]-04,EDI    |
420D4339 8B4D0C           MOV         ECX,dword ptr [EBP]+0c    |
420D433C 8B7D08           MOV         EDI,dword ptr [EBP]+08    |->syscall參數
420D433F 8975F8           MOV         dword ptr [EBP]-08,ESI    |
420D4342 8B5510           MOV         EDX,dword ptr [EBP]+10    |
-----------------------------------------------------------------------------
420D435C 0F477514         CMOVA       ESI,dword ptr [EBP]+14    |
420D4360 53               PUSH        EBX                                            |->syscall參數
420D4361 89FB             MOV         EBX,EDI                                    |
420D4363 B81A000000       MOV         EAX,0000001c  //system call    number value    
420D4368 CD80             INT         80                        //調用0x80
-----------------------------------------------------------------------------
  從上面的代碼我們可以看到這樣一種情況,這裡我們假設調用系統函數write來寫輸出:)
  write(filehandle, buf, buf_length)
  其彙編代碼的函數調用,基本如下:
  push buf_length
  push buf
  push filehandle
  call write
  然後進入到write函數後,我們就知道Linux的syscall的一個完整過程如下:
  進階語言調用系統函數|
    ->jump syscall(即系統對系統函數的標識)|
      ->把syscall的參數賦給寄存器|
        ->mov eax,0x**(及上面write函數針對syscall的數值)|
          ->int 0x80|
            ->返回|
  基本過程如上所示,那麼如果我們spoof(欺騙)這些傳遞參數的寄存器呢?假設spoof是成功的,
那麼很容易就會把一些壞變數值傳遞到syscall的系統調用,緊接著系統核心可能在接收到一些
壞資訊的時候,處理不當,導致系統出現異常或者系統發生溢出.當然這些僅僅是猜測,本文的很
多內容都是在猜測,至於答案嘛,可能永遠都沒有...:)
//////////////////////////////////////////////////////////////////////////////////////
  FreeBSD的syscall調用:
28080D98: 31C0             XOR         EAX,EAX
28080D9A: 53               PUSH        EBX
28080D9B: E800000000       CALL        near32 ptr 28080da0
28080DA0: 5B               POP         EBX
28080DA1: 81C3AC980600     ADD         EBX,000698ac
28080DA7: 8B934C0A0000     MOV         EDX,dword ptr [EBX]+00000a4c
28080DAD: 8902             MOV         dword ptr [EDX],EAX
28080DAF: 5B               POP         EBX
28080DB0: 8D051A000000     LEA         EAX,dword ptr [0000001c]//system call number value
28080DB6: CD80             INT         80
28080DB8: 7201             JC          short ptr 28080dbb
28080DBA: C3               RETN  
從上面的代碼我們也可以看到這樣一種情況,這裡我們假設調用系統函數write來寫輸出:)
  write(filehandle, buf, buf_length)
  其彙編代碼的函數調用,基本如下:
  push buf_length
  push buf
  push filehandle
  call write
  然後進入到write函數後,我們就知道Linux的syscall的一個完整過程如下:
  進階語言調用系統函數|
    ->jump syscall(即系統對系統函數的標識)|
        ->mov eax,0x**(及上面write函數針對syscall的數值)|
          ->int 0x80|
            ->返回|
  根據我的跟蹤分析,發現FreeBSD使用了程式裡面的參數變數,這樣的情況就是FreeBSD省去了一個寄存器調用
函數參數的過程,這樣就禁止了可能存在spoof寄存器的問題,從這點上來看,FreeBSD的確比Linux要安全很多.
------------------------------------------------------------------------------------------------
  雖然Linux的這個syscall會調用寄存器儲存參數值,可能有其好處(最起碼我感覺看代碼和分析一些核心的時,
舒服了很多:)),但是如果有些高人能夠spoof寄存器,那麼可能會引起一些麻煩,當然這樣的麻煩還需要和特定的
程式掛鈎,不是說spoof就spoof成功的:)
  FreeBSD的就優良了很多,我不得不佩服FreeBSD的優點,開始的時候我也經常被FreeBSD這樣的調用方式搞的頭大
的厲害,但是就這麼看啊看的,反而習慣了.在之前的時候,一直是一段時間Linux,一段時間BSD;只有在最近交叉跟
蹤的時候,才發現上面這個自己感覺比較有意思的問題:)

--]FreeBSD的程式比Linux的運行速度快?
  這個問題很難說,如果從上面的代碼來看的話,少了這麼多的彙編代碼,說FreeBSD比Linux慢估計誰都不會相信的.
當然我沒有針對FreeBSD的系統架構與Linux的系統架構進行更深入的對比分析,所以也不敢枉自下如此不清晰的結
論:)如果那位有興趣,能不能在相同的硬體平台下,對這倆OS做下測試?
  再繼續羅嗦一個問題,雖然FreeBSD比Linux少了些彙編代碼,但是syscall的參數FreeBSD肯定也是擷取的,只不過
擷取的方式比Linux更直接了一些:)

--]FreeBSD與Linux的shellcode
  先廢話一下,說到syscall如果不說些shellcode的故事,好像的確是少了那麼一點點事情...So,我們來看看FreeBSD
與Linux的shellcode.我書寫了一些簡單的shellcode,看到網上很多關於shellcode的中文教程都是拿GDB不斷調試出
來的,感覺好麻煩:(個人認為既然熟悉GDB調試技術,肯定熟悉彙編,也肯定熟悉syscall,不熟悉找下標頭檔看看不就得
了...於是我一直用彙編來寫這些可愛的shellcode,剛學會幾天,不對的地方大家明示:)
  到底是先說FreeBSD的shellcode,還是先說Linux的呢?我拿硬幣拋了下,至於為什麼拋硬幣...困了...找點刺激自己
神經的方法:)).好了,硬幣拋完了,先說FreeBSD下面的.
編譯:nasm -f elf ***.asm
     ld -s -o *** ***.o
A: FreeBSD下面的shellcode(hello.asm):
section .text
global _start
_start:
xor eax,eax
cdq
push 0x0a216472
push 0x6f57206f
push 0x6c6c6548
mov  ebx,esp
push byte 0xc
push ebx
push byte 0x1
push eax
mov  al,0x4
int  0x80
xor  eax,eax
push eax
mov  al,0x1
int  0x80
------------------------------------------------------------------------------------------------
  上面的的彙編代碼可以直接編譯來擷取shellcode,按照前面說的編譯辦法編譯,然後:
objdump -D hello > hello.txt
把獲得的機器碼copy出來就是一個freebsd下面的shellcode了.
B: Linux下面的shellcode(hello.asm):
global _start
_start:
  xor  eax,eax
  jmp  short string
code:
  pop  esi
  push byte 15
  push esi
  push byte 1
  push eax
  int  0x80
  xor  eax,eax
  push eax
  push eax
  mov  al,1
  int  0x80
string:
  call code
  db   "Hello word!", 0x0a
------------------------------------------------------------------------------------------------
  上面的的彙編代碼可以直接編譯來擷取shellcode,按照前面說的編譯辦法編譯,然後:
objdump -D hello > hello.txt
把獲得的機器碼copy出來就是一個linux下面的shellcode了.
C: 為什麼FreeBSD與Linux下面的shellcode不同?
  這個問題,我想留給大家先思考下,然後再看我的下文.如果你看了我的下文還是不瞭解的話...那麼可能的情況
是你根本還不會彙編和Unix類型的編程...還有一個情況是,你太笨了:(
  C-1: Linux的syscall的系統調用是如下的過程:
  進階語言調用系統函數|
    ->jump syscall(即系統對系統函數的標識)|
      ->把syscall的參數賦給寄存器|
        ->mov eax,0x**(及上面write函數針對syscall的數值)|
          ->int 0x80|
            ->返回|
  那麼,我們的shellcode在push參數的時候,就比較隨便一些了,因為在後面的系統層級的syscall又對參數進行了二
次的賦值,賦值給各個寄存器,然後才調用syscall.
  C-2: FreeBSD的syscall系統調用是如下的過程:
  進階語言調用系統函數|
    ->jump syscall(即系統對系統函數的標識)|
        ->mov eax,0x**(及上面write函數針對syscall的數值)|
          ->int 0x80|
  看到沒有,或者說前面的內容記憶起來了吧?freebsd的syscall調用是在進入系統syscall前就push進來的,所以我們的
shellcode必須得把參數的值先push進來,而不是象linux那樣的隨意.

--]總結
  其實,最後這部分關於shellcode的不同之處,真正要寫的話,估計還得整整的一篇內容.但是...人是鐵飯是鋼,一頓不吃
餓的慌.於是準備做下逃兵,先去添飽肚子,然後美美的睡一覺.順便做個美夢,在夢中,偶的"老大"又開始欺負偶了...  

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.