Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/christhecoolhut/pinctf

Using Intel's PIN tool to solve CTF problems
https://github.com/christhecoolhut/pinctf

ctf instruction-counting pin reverse-engineering

Last synced: 14 days ago
JSON representation

Using Intel's PIN tool to solve CTF problems

Awesome Lists containing this project

README

        

# PinCTF

This tool is designed to use [Intel's Pin Tool](https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool) to instrument reverse engineering binaries and count instructions.

This tool is designed to use instruction counting as an avenue for [Side Channel Analysis](https://en.wikipedia.org/wiki/Side-channel_attack). By counting the number of instruction exeuted in a given reverse engineering program we can guess (Sometimes) that the more instructions that are executed per input, the closer we are to the flag.

[![asciicast](https://asciinema.org/a/2bHy0y9MrGNa8Xp9MSPT17HTS.png)](https://asciinema.org/a/2bHy0y9MrGNa8Xp9MSPT17HTS)

## Install Pin
Included in this repo is a script for pulling down Intel's PIN and instructions for building it on Ubuntu 16.04.

```
#This script will pull PIN and install dependencies needed.
./installPin.sh
```

## Running PinCTF
PinCTF is implemented as a python script wrapping PIN. It will execute a pin command then read from PIN's produced *inscount.out* file

```
[chris@Thor pinCTF]$ ./pinCTF.py -h
usage: pinCTF.py [-h] [-f FILE] [-a] [-al] [-i] [-il] [-p PINLOCATION]
[-l PINLIBRARYLOCATION] [-c COUNT] [-s SEED] [-r RANGE]
[-sl SEEDLENGTH] [-st SEEDSTART] [-t] [-tc THREADCOUNT]

optional arguments:
-h, --help show this help message and exit
-f FILE, --file FILE file to run pin against
-a, --arg Trace instructions for passed in argument
-al, --argLength Trace instructions for passed in argument length
-i, --input Trace instructions for given input
-il, --inputLength Trace instructions for input length
-p PINLOCATION, --pinLocation PINLOCATION
Location of pin's directory
-l PINLIBRARYLOCATION, --pinLibraryLocation PINLIBRARYLOCATION
Location of pin's instruction0.so libraries
-c COUNT, --count COUNT
MaxLength to for length based pin
-s SEED, --seed SEED Initial seed for input or arg pin
-r RANGE, --range RANGE
range of characters to iterate pin over
-sl SEEDLENGTH, --seedLength SEEDLENGTH
Initial seed length for input or arg pin
-st SEEDSTART, --seedStart SEEDSTART
Initial seed index for pin
-t, --threading Enables threading
-tc THREADCOUNT, --threadCount THREADCOUNT
Number of threads
```

To compare instruction counts to length use the -il or -al commands
The -c command is used to specifyhow many A's to test

```
./pinCTF.py -f examples/wyvern_c85f1be480808a9da350faaa6104a19b -il -l obj-intel64/ -c 30

Num : Instr Count AAAAAAAAAAAAAAAAAAA
1 : 2119788
2 : 2119789
3 : 2119789
4 : 2119784
5 : 2119788
6 : 2119789
7 : 2119791
8 : 2119782
9 : 2119786
10 : 2119787
11 : 2119791
12 : 2119786
13 : 2119790
14 : 2119791
15 : 2119818
16 : 2119822
17 : 2119826
18 : 2119825
19 : 2119831
20 : 2119824
21 : 2119830
22 : 2119831
23 : 2119835
24 : 2119826
25 : 2119830
26 : 2119831
27 : 2119835
28 : 2132982
29 : 2119834
30 : 2119863
[+] Found Num 28 : Count 2132982

```
Now we know we that the flag is 28 characters long and we can start looking for a flag of 28 characters.

Once you've found a length that seems to work you can use pin to change each value testing for instruction changes
The -sl flag can be used to determine the length of the initial seed, and the -r flag can be used to choose what range to iterate over
```
./pinCTF.py -f examples/wyvern_c85f1be480808a9da350faaa6104a19b -i -l obj-intel64/ -sl 28 -r abcdefghijklmnopqrstuvwxyz012345_-+LVMA -sk
[+] iter 0 using d for dAAAAAAAAAAAAAAAAAAAAAAAAAAA
[+] iter 1 using r for drAAAAAAAAAAAAAAAAAAAAAAAAAA
[+] iter 2 using 4 for dr4AAAAAAAAAAAAAAAAAAAAAAAAA
[+] iter 3 using g for dr4gAAAAAAAAAAAAAAAAAAAAAAAA
[+] iter 4 using 0 for dr4g0AAAAAAAAAAAAAAAAAAAAAAA
[+] iter 5 using n for dr4g0nAAAAAAAAAAAAAAAAAAAAAA
[+] iter 6 using _ for dr4g0n_AAAAAAAAAAAAAAAAAAAAA
[+] iter 7 using o for dr4g0n_oAAAAAAAAAAAAAAAAAAAA
[+] iter 8 using r for dr4g0n_orAAAAAAAAAAAAAAAAAAA
[+] iter 9 using _ for dr4g0n_or_AAAAAAAAAAAAAAAAAA
[+] iter 10 using p for dr4g0n_or_pAAAAAAAAAAAAAAAAA
[+] iter 11 using 4 for dr4g0n_or_p4AAAAAAAAAAAAAAAA
[+] iter 12 using t for dr4g0n_or_p4tAAAAAAAAAAAAAAA
[+] iter 13 using r for dr4g0n_or_p4trAAAAAAAAAAAAAA
[+] iter 14 using i for dr4g0n_or_p4triAAAAAAAAAAAAA
[+] iter 15 using c for dr4g0n_or_p4tricAAAAAAAAAAAA
[+] iter 16 using 1 for dr4g0n_or_p4tric1AAAAAAAAAAA
[+] iter 17 using a for dr4g0n_or_p4tric1aAAAAAAAAAA
[+] iter 18 using n for dr4g0n_or_p4tric1anAAAAAAAAA
[+] iter 19 using _ for dr4g0n_or_p4tric1an_AAAAAAAA
[+] iter 20 using i for dr4g0n_or_p4tric1an_iAAAAAAA
[+] iter 21 using t for dr4g0n_or_p4tric1an_itAAAAAA
[+] iter 22 using 5 for dr4g0n_or_p4tric1an_it5AAAAA
[+] iter 23 using _ for dr4g0n_or_p4tric1an_it5_AAAA
[+] iter 24 using L for dr4g0n_or_p4tric1an_it5_LAAA
[+] iter 25 using L for dr4g0n_or_p4tric1an_it5_LLAA
[+] iter 26 using V for dr4g0n_or_p4tric1an_it5_LLVA
[+] iter 27 using M for dr4g0n_or_p4tric1an_it5_LLVM
[+] Found pattern dr4g0n_or_p4tric1an_it5_LLVM
```

## Script tricks for PIN

This process is pretty slow and can be sped up with threading. The -t (--threading) flag will enable threading and -tc represents the thread count

```
time ./pinCTF.py -f $(pwd)/examples/crypt4 -a -sl 26 --threading -tc 4
[+] iter 0 using d for dAAAAAAAAAAAAAAAAAAAAAAAAA
[+] iter 1 using y for dyAAAAAAAAAAAAAAAAAAAAAAAA
[+] iter 2 using n for dynAAAAAAAAAAAAAAAAAAAAAAA
[+] iter 3 using 4 for dyn4AAAAAAAAAAAAAAAAAAAAAA
[+] iter 4 using m for dyn4mAAAAAAAAAAAAAAAAAAAAA
[+] iter 5 using 1 for dyn4m1AAAAAAAAAAAAAAAAAAAA
[+] iter 6 using c for dyn4m1cAAAAAAAAAAAAAAAAAAA
[+] iter 7 using a for dyn4m1caAAAAAAAAAAAAAAAAAA
[+] iter 8 using l for dyn4m1calAAAAAAAAAAAAAAAAA
[+] iter 9 using l for dyn4m1callAAAAAAAAAAAAAAAA
[+] iter 10 using y for dyn4m1callyAAAAAAAAAAAAAAA
[+] iter 11 using _ for dyn4m1cally_AAAAAAAAAAAAAA
[+] iter 12 using d for dyn4m1cally_dAAAAAAAAAAAAA
[+] iter 13 using 3 for dyn4m1cally_d3AAAAAAAAAAAA
[+] iter 14 using c for dyn4m1cally_d3cAAAAAAAAAAA
[+] iter 15 using r for dyn4m1cally_d3crAAAAAAAAAA
[+] iter 16 using y for dyn4m1cally_d3cryAAAAAAAAA
[+] iter 17 using p for dyn4m1cally_d3crypAAAAAAAA
[+] iter 18 using t for dyn4m1cally_d3cryptAAAAAAA
[+] iter 19 using 3 for dyn4m1cally_d3crypt3AAAAAA
[+] iter 20 using d for dyn4m1cally_d3crypt3dAAAAA
[+] iter 21 using _ for dyn4m1cally_d3crypt3d_AAAA
[+] iter 22 using c for dyn4m1cally_d3crypt3d_cAAA
[+] iter 23 using 0 for dyn4m1cally_d3crypt3d_c0AA
[+] iter 24 using d for dyn4m1cally_d3crypt3d_c0dA
[~] Largest instruction count found to match several others or very close
[~] Locating largest difference from average instead
[+] iter 25 using 3 for dyn4m1cally_d3crypt3d_c0d3
[+] Found pattern dyn4m1cally_d3crypt3d_c0d3

real 3m26.511s
user 10m53.012s
sys 2m21.344s
```

Some ctf binaries will validate input backwards to throw off fuzzers. using the -rev flag PinCTF is able to alter the input backwards

```
./pinCTF.py -f $(pwd)/examples/ELF-NoSoftwareBreakpoints -i -sl 25 -rev -t -tc 4 -r abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-@
[~] Running in reverse direction
[+] iter 24 using S for AAAAAAAAAAAAAAAAAAAAAAAAS
[+] iter 23 using k for AAAAAAAAAAAAAAAAAAAAAAAkS
[+] iter 22 using c for AAAAAAAAAAAAAAAAAAAAAAckS
[+] iter 21 using 0 for AAAAAAAAAAAAAAAAAAAAA0ckS
[+] iter 20 using r for AAAAAAAAAAAAAAAAAAAAr0ckS
[+] iter 19 using _ for AAAAAAAAAAAAAAAAAAA_r0ckS
[+] iter 18 using T for AAAAAAAAAAAAAAAAAAT_r0ckS
[+] iter 17 using N for AAAAAAAAAAAAAAAAANT_r0ckS
[+] iter 16 using i for AAAAAAAAAAAAAAAAiNT_r0ckS
[+] iter 15 using o for AAAAAAAAAAAAAAAoiNT_r0ckS
[+] iter 14 using P for AAAAAAAAAAAAAAPoiNT_r0ckS
[+] iter 13 using k for AAAAAAAAAAAAAkPoiNT_r0ckS
[+] iter 12 using a for AAAAAAAAAAAAakPoiNT_r0ckS
[+] iter 11 using 3 for AAAAAAAAAAA3akPoiNT_r0ckS
[+] iter 10 using r for AAAAAAAAAAr3akPoiNT_r0ckS
[+] iter 9 using B for AAAAAAAAABr3akPoiNT_r0ckS
[+] iter 8 using _ for AAAAAAAA_Br3akPoiNT_r0ckS
[+] iter 7 using e for AAAAAAAe_Br3akPoiNT_r0ckS
[+] iter 6 using r for AAAAAAre_Br3akPoiNT_r0ckS
[+] iter 5 using @ for AAAAA@re_Br3akPoiNT_r0ckS
[+] iter 4 using W for AAAAW@re_Br3akPoiNT_r0ckS
[+] iter 3 using d for AAAdW@re_Br3akPoiNT_r0ckS
[+] iter 2 using r for AArdW@re_Br3akPoiNT_r0ckS
[+] iter 1 using a for AardW@re_Br3akPoiNT_r0ckS
[~] Largest instruction count found to match several others or very close
[~] Locating largest difference from average instead
[+] iter 0 using H for HardW@re_Br3akPoiNT_r0ckS
[+] Found pattern HardW@re_Br3akPoiNT_r0ckS
```