Linux下pin的简单使用

文章参考CTF-wiki
一路上踩了不少坑记录一下。

例题 NDH2K13-crackme-500

尝试用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

得到flag
在这里插入图片描述

PinCTF

还有一个简便工具,但是上题的题目PinCTF解决不了
下载地址以及使用教程
注:下载解压好运行./install.sh,并且pip安装好相关库即可用

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值