文章参考CTF-wiki
一路上踩了不少坑记录一下。
尝试用IDA打开发现section header 损坏,一路确认进去也没找到主函数,使用pintools对其进行分析。
输入命令
playmaker@playmaker-PC:~$ ~/pin-3.7-97619-g0d0c92f4f-gcc-linux/pin -t ./pin-3.7-97619-g0d0c92f4f-gcc-linux/source/tools/ManualExamples/obj-intel64/inscount0.so -- ./Desktop/crackme <<< "a";cat inscount.out
Jonathan Salwan loves you <3
----------------------------
Password: Bad password
Count 162712
playmaker@playmaker-PC:~$ ~/pin-3.7-97619-g0d0c92f4f-gcc-linux/pin -t ./pin-3.7-97619-g0d0c92f4f-gcc-linux/source/tools/ManualExamples/obj-intel64/inscount0.so -- ./Desktop/crackme <<< "aa";cat inscount.out
Jonathan Salwan loves you <3
----------------------------
Password: Bad password
Count 165508
playmaker@playmaker-PC:~$ ~/pin-3.7-97619-g0d0c92f4f-gcc-linux/pin -t ./pin-3.7-97619-g0d0c92f4f-gcc-linux/source/tools/ManualExamples/obj-intel64/inscount0.so -- ./Desktop/crackme <<< "aaa";cat inscount.out
Jonathan Salwan loves you <3
----------------------------
Password: Bad password
Count 168304
playmaker@playmaker-PC:~$ ~/pin-3.7-97619-g0d0c92f4f-gcc-linux/pin -t ./pin-3.7-97619-g0d0c92f4f-gcc-linux/source/tools/ManualExamples/obj-intel64/inscount0.so -- ./Desktop/crackme <<< "aaaa";cat inscount.out
Jonathan Salwan loves you <3
----------------------------
Password: Bad password
Count 171100
四次长度不同的数据,且执行指令数字逐渐增加,写一个脚本查看逐渐变长的规律
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from subprocess import Popen, PIPE
from sys import argv
import string
import time
pinPath = "/home/playmaker/pin-3.7-97619-g0d0c92f4f-gcc-linux/pin"
pinInit = lambda tool, elf: Popen([pinPath, '-t', tool, '--', elf], stdin = PIPE, stdout = PIPE)
pinWrite = lambda cont: pin.stdin.write(cont)
def pinRead():
f = open('./inscount.out','r')
file = f.read().strip('\n')
f.close()
return file
if __name__ == "__main__":
last = 0
for i in xrange(1, 30):
pin = pinInit("./pin-3.7-97619-g0d0c92f4f-gcc-linux/source/tools/ManualExamples/obj-intel64/inscount0.so", "./Desktop/crackme")
pinWrite("a" * i + '\n')
time.sleep(0.5)
now = int(pinRead().split("Count ")[1])
print "inputLen({:2d}) -> ins({}) -> delta({})".format(i, now, now - last)
last = now
运行结果如下
playmaker@playmaker-PC:~$ python guesslength.py
inputLen( 1) -> ins(159810) -> delta(159810)
inputLen( 2) -> ins(162606) -> delta(2796)
inputLen( 3) -> ins(165402) -> delta(2796)
inputLen( 4) -> ins(168198) -> delta(2796)
inputLen( 5) -> ins(170994) -> delta(2796)
inputLen( 6) -> ins(173790) -> delta(2796)
inputLen( 7) -> ins(176586) -> delta(2796)
inputLen( 8) -> ins(182307) -> delta(5721)
inputLen( 9) -> ins(182179) -> delta(-128)
inputLen(10) -> ins(184975) -> delta(2796)
inputLen(11) -> ins(187771) -> delta(2796)
inputLen(12) -> ins(190567) -> delta(2796)
inputLen(13) -> ins(193363) -> delta(2796)
inputLen(14) -> ins(196159) -> delta(2796)
inputLen(15) -> ins(198955) -> delta(2796)
inputLen(16) -> ins(201751) -> delta(2796)
inputLen(17) -> ins(204547) -> delta(2796)
inputLen(18) -> ins(207343) -> delta(2796)
inputLen(19) -> ins(210139) -> delta(2796)
inputLen(20) -> ins(212935) -> delta(2796)
inputLen(21) -> ins(215731) -> delta(2796)
inputLen(22) -> ins(218527) -> delta(2796)
inputLen(23) -> ins(221323) -> delta(2796)
inputLen(24) -> ins(224119) -> delta(2796)
inputLen(25) -> ins(226915) -> delta(2796)
inputLen(26) -> ins(229711) -> delta(2796)
inputLen(27) -> ins(243691) -> delta(13980)
inputLen(28) -> ins(243691) -> delta(0)
inputLen(29) -> ins(243691) -> delta(0)
长度位8时出现指令出现了激增,即可猜测flag的长度为8,接着可以猜测输入的正确的越多,执行的指令越多,于是写个逐位爆破脚本
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from subprocess import Popen, PIPE
from sys import argv
import string
import pdb
import time
pinPath = "/home/playmaker/pin-3.7-97619-g0d0c92f4f-gcc-linux/pin"
pinInit = lambda tool, elf: Popen([pinPath, '-t', tool, '--', elf], stdin = PIPE, stdout = PIPE)
pinWrite = lambda cont: pin.stdin.write(cont)
def pinRead():
#f = open('./inscount.out','r')
f = open('./inscount.out','r')
file = f.read().strip('\n')
f.close()
return file
if __name__ == "__main__":
last = 0
dic = string.ascii_letters + string.digits + "+_ "
pwd = '?' * 8
dicIdx = 0
pwdIdx = 0
while True:
pwd = pwd[: pwdIdx] + dic[dicIdx] + pwd[pwdIdx + 1: ]
pin = pinInit("./pin-3.7-97619-g0d0c92f4f-gcc-linux/source/tools/ManualExamples/obj-intel64/inscount0.so","./Desktop/crackme")
pinWrite(pwd + '\n')
time.sleep(1)
now = int(pinRead().split("Count ")[1])
print "input({}) -> now({}) -> delta({})".format(pwd, now, now - last)
if now - last > 2000 and dicIdx:
pwdIdx += 1
dicIdx = -1
last = 0
if pwdIdx >= len(pwd):
print "Found pwd: {}".format(pwd)
break
dicIdx += 1
last = now
还有一个简便工具,但是上题的题目PinCTF解决不了
下载地址以及使用教程
注:下载解压好运行./install.sh,并且pip安装好相关库即可用