簡體   English   中英

為什么 printf 沒有打印出這個緩沖區溢出中的字符串?

[英]Why didn't printf print out the string in this buffer overflow?

我正在學習緩沖區溢出。 我寫了一個小C程序:

#include<stdio.h>
#include<string.h>
void vuln();
void win();
void main(int argc, char *argv[]){
        vuln();

}
void win (){
        printf("Pwned!!");
}
void vuln(){
        char buffer[256];
        printf("Enter a string: ");
        scanf(" %s", buffer);
}

vuln function的拆解:

gef➤  disas vuln
Dump of assembler code for function vuln:
   0x0000555555555179 <+0>:     push   rbp
   0x000055555555517a <+1>:     mov    rbp,rsp
   0x000055555555517d <+4>:     sub    rsp,0x100
   0x0000555555555184 <+11>:    lea    rdi,[rip+0xe81]        # 0x55555555600c
   0x000055555555518b <+18>:    mov    eax,0x0
   0x0000555555555190 <+23>:    call   0x555555555030 <printf@plt>
   0x0000555555555195 <+28>:    lea    rax,[rbp-0x100]
   0x000055555555519c <+35>:    mov    rsi,rax
   0x000055555555519f <+38>:    lea    rdi,[rip+0xe77]        # 0x55555555601d
   0x00005555555551a6 <+45>:    mov    eax,0x0
   0x00005555555551ab <+50>:    call   0x555555555040 <__isoc99_scanf@plt>
   0x00005555555551b0 <+55>:    nop
   0x00005555555551b1 <+56>:    leave  
   0x00005555555551b2 <+57>:    ret    
End of assembler dump.

我設法通過使用有效載荷來win

>>> payload = "A"264 + p64(0x0000555555555161)

問題是它沒有打印出 function win中的字符串。 我得到的只是分段錯誤。 這是我得到的:

Program received signal SIGSEGV, Segmentation fault.
0x00007fffffffe158 in ?? ()
[ Legend: Modified register | Code | Heap | Stack | String ]
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x7               
$rbx   : 0x0               
$rcx   : 0x0               
$rdx   : 0x0               
$rsp   : 0x00007fffffffe068  →  0x0000000200000000
$rbp   : 0x4141414141414141 ("AAAAAAAA"?)
$rsi   : 0x656e7750        
$rdi   : 0x00005555555592a0  →  "Pwned!! string: "
$rip   : 0x00007fffffffe158  →  0x00007fffffffe436  →  "/media/sf_Code/asm/vuln"
$r8    : 0x00007ffff7fb9500  →  0x00007ffff7fb9500  →  [loop detected]
$r9    : 0x7               
$r10   : 0x0000555555556004  →  0x00212164656e7750 ("Pwned!!"?)
$r11   : 0x246             
$r12   : 0x0000555555555060  →  <_start+0> xor ebp, ebp
$r13   : 0x00007fffffffe150  →  0x0000000000000002
$r14   : 0x0               
$r15   : 0x0               
$eflags: [zero carry PARITY ADJUST sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000 
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffe068│+0x0000: 0x0000000200000000   ← $rsp
0x00007fffffffe070│+0x0008: 0x00005555555551c0  →  <__libc_csu_init+0> push r15
0x00007fffffffe078│+0x0010: 0x00007ffff7e1ebbb  →  <__libc_start_main+235> mov edi, eax
0x00007fffffffe080│+0x0018: 0x0000000000000000
0x00007fffffffe088│+0x0020: 0x00007fffffffe158  →  0x00007fffffffe436  →  "/media/sf_Code/asm/vuln"
0x00007fffffffe090│+0x0028: 0x0000000200100000
0x00007fffffffe098│+0x0030: 0x0000555555555145  →  <main+0> push rbp
0x00007fffffffe0a0│+0x0038: 0x0000000000000000
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0x7fffffffe152                  add    BYTE PTR [rax], al
   0x7fffffffe154                  add    BYTE PTR [rax], al
   0x7fffffffe156                  add    BYTE PTR [rax], al
 → 0x7fffffffe158                  ss     in  al, 0xff
   0x7fffffffe15b                  (bad)  
   0x7fffffffe15c                  (bad)  
   0x7fffffffe15d                  jg     0x7fffffffe15f
   0x7fffffffe15f                  add    BYTE PTR [rsi-0x1c], cl
   0x7fffffffe162                  (bad)  
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "vuln", stopped 0x7fffffffe158 in ?? (), reason: SIGSEGV
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x7fffffffe158 → ss in  al, 0xff

printf沒有打印出字符串?

stdout 默認為行緩沖,字符串不以換行符結尾。 如果您將其更改為puts("Pwned;!"); 然后stdout將在puts返回之前被刷新。

但是使用printf ,數據只是坐在 stdio 緩沖區中,直到其他東西打印換行符,或者直到fflush(stdout) exit()或從main干凈地返回將導致 fflush,但 segfaulting 將終止進程,而無需進行系統調用以將該 I/O 數據交給操作系統。

這與在匯編中使用 printf 導致空輸出完全相同的問題,除了這種情況是使用_exit(2)系統調用而不是段錯誤。


如果目標是強制您在不中斷后續執行的情況下調用win() ,那么這是另一個級別的挑戰。

但是如果win()應該代表一個成功的 ROP 攻擊,它調用system()execve"/bin/sh" ,那么win()寫得不好。 execve將在現場發生,而不是稍后發生。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM