校赛writeup

第一届校赛,总的来说对自己所处的名次还是比较满意的,这次还是比较占便宜,做出来几道简单的逆向,要不然一个弱弱的web狗肯定要被吊打,这次的crypto的题比较难,也多,尝试做了几道,后来由于难度上升,也就没怎么看这些题。希望能从各种比赛中学习到真正的知识,毕竟自己还是跟其他人有很大的差距,总要赶上大牛学长的脚步!~

sign

得到一串字符
4C4A575851324332474E5A5445544B584B4A5446534D545947464D57594F4A544C4A4C585132544347495957595A5352485536513D3D3D3D
明显是16进制转化,写个脚本

str = '0123456789ABCDEF'

def to(s):
    s1 = ''
    i = 0
    while i < len(s):
        c1 = s[i]
        c2 = s[i+1]
        i += 2
        b1 = str.find(c1)
        b2 = str.find(c2)
        s1+=chr((b1 << 4)+b2)
    return s1

s = '4C4A575851324332474E5A5445544B584B4A5446534D545947464D57594F4A544C4A4C585132544347495957595A5352485536513D3D3D3D'
print to(s)

得到
LJWXQ2C2GNZTETKXKJTFSMTYGFMWYOJTLJLXQ2TCGIYWYZSRHU6Q====
base32解码
ZmxhZ3s2MWRfY2x1Yl93ZWxjb21lfQ==
base64解码
flag{61d_club_welcome}

flip

当初做hctf的一道题,有fp的writeup
链接(http://bobao.360.cn/ctf/learning/179.html)

BASE64?

一看就知道是base32解码
GUYDIMZVGQ2DMN3CGRQTONJXGM3TINLGG42DGMZXGM3TINLGGY4DGNBXGYZTGNLGGY3DGNBWMU3WI===
解出
504354467b4a7573745f743373745f683476335f66346e7d
貌似是16进制转化
脚本

def str2byte(s):
    base='0123456789ABCDEF'
    i = 0
    s = s.upper()
    s1=''
    while i < len(s):
        c1=s[i]
        c2=s[i+1]
        i+=2
        b1=base.find(c1)
        b2=base.find(c2)
        s1+=chr((b1 << 4)+b2)
    return s1

s ='504354467b4a7573745f743373745f683476335f66346e7d'
print str2byte(s)

flag:PCTF{Just_t3st_h4v3_f4n}

直接扔进stegsolve分析即得

AES-PIC

这个题是之前对照着bystudent的writeup做的
链接(http://www.bystudent.com/?p=234)

上帝之音

这是一段神奇的声音,可是上帝之音似乎和无字天书一样,是我们这些凡人无法理解的,你能以上帝的角度,理解这段WAV的含义么?
Hint1: 你们做音频题都不喜欢看时域图?
Hint2: 在数据传输过程中,我们往往会使用一种自带时钟的编码以减少误码率
godwave.wav.26b6f50dfb87d00b338b58924acdbea1

Audacity 打开就是一段稀奇古怪的音频信号,仔细观察,发现不同段落其幅值有明显差异,应该是调幅了,MATLAB 导入 wav 文件看数据,发现大概是以 64 个点为周期,那么取幅值高的为 1,幅值低的为 0。

clc;
clear;
y = audioread('godwave.wav');
he = 0;
data = [];
for i = 1:length(y)
    he = he + abs(y(i,1));
    if mod(i,64) == 0
        if he > 10
            data = [data,1];
        else
            data = [data,0];
        end
        he = 0;
    end
end
fid = fopen('data.txt','w');
for i = 1:length(data)
    fprintf(fid,'%d',data(1,i));
end
fclose(fid);

解出的数据是曼彻斯特编码,解码后是一张图片。

# coding=utf-8
with open('data.txt', 'r') as f:
    data = f.readline()
    print len(data)
    count = 0
    res = 0
    ans = ''
    key = ""
    while data != '':
        pac = data[:2]
        if pac != '':
            if pac[0] == '0' and pac[1] == '1':
                res = (res<<1)|0
                count += 1
            if pac[0] == '1' and pac[1] == '0':
                res = (res<<1)|1
                count += 1
            if count == 8:
                ans += chr(res)
                count = 0
                res = 0
        else:
            break
        data = data[2:]
with open('out.png', 'wb') as f2:
    f2.write(ans)

扫描二维码即可。

LOCALHOST

看来需要localhost access only!!直接利用Modify Headers直接加上X-Forwarded-For: 127.0.0.1即可

warmup-misc

一张加密的脚本图片,逆序写出解密即得flag

import base64

def decode(flag,k):
    ag=base64.b64decode(flag)
    r=""
    for i in ag:
        r+=chr(ord(i)^ord(k))
    r+=i
    return r

flag="UAUSAB1QUFBQUFAbfQ=="

print decode(flag,'f')

flag:6ctf{666666}

warmup-web

打开只有一句无意义的话,源码没有东西,看头
发现
校赛writeup_第1张图片
看见有/猜测是地址,访问即得flag
http://59.110.6.97:8559/NOTHERE
flag{OpenYourHeadHole}

web2

打开网页,提示Try to find the web directory看来需要跑目录
其实一开始尝试各种方法,burpsuite抓包,头啥的都分析构造,差一点就猜对啦,真是bi了狗~
我在kali下利用DirBuster跑,第一次用一个字典跑了好久都没跑出来
校赛writeup_第2张图片
曾经试了试/x/register.php/x/login.php发现没什么用
后来换了一个字典,几乎是瞬出
校赛writeup_第3张图片
郁闷,/flag.php一开始差一点才对,结果现在用了好长时间,真是醉啦
访问成功得到flag:flag{Quickly!!!!!!!111!!!!}

warmup-re

拖进IDA进行反编译

// local variable allocation has failed, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax@1
  __int64 v4; // rdx@1
  __int64 v5; // rax@1
  __int64 v6; // rbx@1
  __int64 v7; // rdx@1
  __int64 v8; // rax@1
  __int64 v9; // rdx@1
  __int64 v10; // rax@2
  __int64 v11; // rdx@2
  int result; // eax@2
  __int64 v13; // rax@5
  __int64 v14; // rdx@5
  unsigned __int64 v15; // rbx@7
  unsigned __int64 v16; // rax@7
  __int64 v17; // rax@8
  __int64 v18; // rdx@8
  char v19[48]; // [sp+20h] [bp-60h]@1
  char v20[48]; // [sp+50h] [bp-30h]@1
  char v21[48]; // [sp+80h] [bp+0h]@4
  int v22; // [sp+B0h] [bp+30h]@1
  int v23; // [sp+B4h] [bp+34h]@1
  int v24; // [sp+B8h] [bp+38h]@1
  int v25; // [sp+BCh] [bp+3Ch]@1
  int v26; // [sp+C0h] [bp+40h]@1
  int v27; // [sp+C4h] [bp+44h]@1
  int v28; // [sp+C8h] [bp+48h]@1
  int v29; // [sp+CCh] [bp+4Ch]@1
  int v30; // [sp+D0h] [bp+50h]@1
  int v31; // [sp+D4h] [bp+54h]@1
  int v32; // [sp+D8h] [bp+58h]@1
  int v33; // [sp+DCh] [bp+5Ch]@1
  int v34; // [sp+E0h] [bp+60h]@1
  int v35; // [sp+E4h] [bp+64h]@1
  int v36; // [sp+E8h] [bp+68h]@1
  int v37; // [sp+ECh] [bp+6Ch]@1
  int v38; // [sp+F0h] [bp+70h]@1
  int v39; // [sp+F4h] [bp+74h]@1
  int v40; // [sp+F8h] [bp+78h]@1
  int v41; // [sp+FCh] [bp+7Ch]@1
  int v42; // [sp+100h] [bp+80h]@1
  char v43; // [sp+10Ah] [bp+8Ah]@4
  char v44; // [sp+10Bh] [bp+8Bh]@4
  int i; // [sp+10Ch] [bp+8Ch]@3

  _main();
  v22 = 86;
  v23 = 30;
  v24 = 24;
  v25 = 1;
  v26 = 21;
  v27 = 90;
  v28 = 27;
  v29 = 29;
  v30 = 6;
  v31 = 29;
  v32 = 76;
  v33 = 84;
  v34 = 22;
  v35 = 20;
  v36 = 85;
  v37 = 28;
  v38 = 22;
  v39 = 21;
  v40 = 30;
  v41 = 29;
  v42 = 23;
  LODWORD(v3) = std::operator>><char,std::char_traits<char>>(*(_QWORD *)&argc, argv, v19, refptr__ZSt3cin);
  std::operator>><char,std::char_traits<char>>(*(_QWORD *)&argc, argv, v20, v3);
  LODWORD(v5) = strlen(*(_QWORD *)&argc, argv, v4, v19);
  v6 = v5;
  LODWORD(v8) = strlen(*(_QWORD *)&argc, argv, v7, v20);
  if ( v6 == v8 )
  {
    for ( i = 0; ; ++i )
    {
      v15 = i;
      LODWORD(v16) = strlen(*(_QWORD *)&argc, argv, v9, v19);
      if ( v15 >= v16 )
        break;
      v44 = v19[i];
      v43 = v20[i];
      v21[i] = v43 ^ v44;
      v9 = (unsigned int)v21[i];
      if ( (_DWORD)v9 != *(&v22 + i) )
      {
        LODWORD(v13) = std::operator<<<std::char_traits<char>>(*(_QWORD *)&argc, argv, "key error", refptr__ZSt4cout);
        std::ostream::operator<<(
          *(_QWORD *)&argc,
          argv,
          refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_,
          v13);
        system(*(_QWORD *)&argc, argv, v14, "pause");
        return 0;
      }
    }
    LODWORD(v17) = std::operator<<<std::char_traits<char>>(
                     *(_QWORD *)&argc,
                     argv,
                     "Yes!input is flag",
                     refptr__ZSt4cout);
    std::ostream::operator<<(
      *(_QWORD *)&argc,
      argv,
      refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_,
      v17);
    system(*(_QWORD *)&argc, argv, v18, "pause");
    result = 0;
  }
  else
  {
    LODWORD(v10) = std::operator<<<std::char_traits<char>>(*(_QWORD *)&argc, argv, "lenth error", refptr__ZSt4cout);
    std::ostream::operator<<(
      *(_QWORD *)&argc,
      argv,
      refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_,
      v10);
    system(*(_QWORD *)&argc, argv, v11, "pause");
    result = 0;
  }
  return result;
}

主要意思就是输两串长度相同的字符串,并逐位异或,最终得到的值与v22~v42每个进行比较,相等就输出,由于第一个字符串已经给了goodgoodstudydaydayup这样直接脚本一跑就行啦

s='goodgoodstudydaydayup'
r=""
v=[86,30,24,1,21,90,27,29,6,29,76,84,22,20,85,28,22,21,30,29,23]
j=0
for i in s:
    r+=chr(ord(i)^(v[j]))
    j = j+1

print r

得到第二个字符串1qwer5tyui90op4ertghg
然后输进去就是flag
校赛writeup_第4张图片

zlmm

打开好长的字符,不过看见了{}猜测是栅栏密码,题目名字也是,懒得分析,直接拖进工具得到flag
校赛writeup_第5张图片
发现22栏的像是文章,看完发现flag
flag{zha+lanmima666}

warmip-crypto

一串不知道是啥的字符BH=CWG=EO=IEI=;DEDEDEY
这个一直想都没想出来,最后好像跟偏移有关,顿时灵光一现,开始查相关的flag格式,就找{},这两个相差2,找与Y的偏移量是2的是W,这样的话直接计算Y}的偏移量,然后全员偏移就行

r="BH=CWG=EO=IEI=;DEDEDEY"
t=""
for i in r:
    t+=chr(ord(i)+36)
print t

得到flag:flag{kaisamima_hihihi}

warmup-game

hint:据说bibi师傅在无畏先锋的id就是此题flag

直接看qq好友的游戏人生,发现字符被挡住,这时候我尝试两种方法,一种猜测,差不多试了一会出来啦
另一种方法是手机下载了一个掌盟助手,通过可能认识的人就得到id
校赛writeup_第6张图片

warmup-rsa

打开得到

n1=0x18f60afa6b9938df69338805ae7fbd5652da3ac8fa5b7b65e4755149ba3f80d071fe8845fa20ea3e57e21fb2f630e47e4886de35c51d1487c170a59141f833c3aaea62c539e20664dbfa75f1b2d56ed4dbec991e5bf3306931bfda79b1dd8466f808af159b44be042499d423110ab9cfd595e370029862e2e686ed2a27fb6b459c4fddc0ebd4f112e0f3769524412e7128eb04b02de421df5a0e5b22d2c40acf1727aa9093160bf6dbd862ac136a805a4e9c760c54d28ac5bf21d509d94e9e437e2e38a13664ec104dadc66f8c21b7b82e3e3570d27326e13df07dd72b6847f8e53aadeafa54cc879cfa2ae3b8028c39df36b097ba65688abadb78a06c16f393L
n2=0x18f60afa6b9938df69338805ae7fbd5652da3ac8fa5b7b65e4755149ba3f80d071fe8845fa20ea3e57e21fb2f630e47e4886de35c51d1487c170a59141f833c3aaea62c539e20664dbfa75f1b2d56ed4dbec991e5bf3306931bfda79b1dd8466f808af159b44be042499d423110ab9cfd595e370029862e2e686ed2a27fb6b459c4fddc0ebd4f112e0f3769524412e7128eb04b02de421df5a0e5b22d2c40acf1727aa9093160bf6dbd862ac136a805a4e9c760c54d28ac5bf21d509d94e9e437e2e38a13664ec104dadc66f8c21b7b82e3e3570d27326e13df07dd72b6847f8e53aadeafa54cc879cfa2ae3b8028c39df36b097ba65688abadb78a06c16f393L
e1=0x17e1
e2=0x43a5
c1=0xb6e66aa0d4d5ad1460482f45aab87e80a99c1ff3af605fd9cea82d76d464272f3dd2e1797e3fede64cffcd54b2a7a5e21f45574783f62266cebf3cdb9764c6c04b0b30b5d065d5f6142d498506ea1f6449f428253d4d76bd96778d5f58abf313370b980dcb90daf882c5539ac3df81a431bc2c0e0911ecbe5195d94312218b3854ee14f13bd00c81d7ff11c06a9e112940b7377c20e53738a2ebb77b0534d8d9e481e60e9c87693bd9e1fd1e569083479ff8f53e42337a2b799c2325a7e2588fb046cf228d01d8596e7af4570a3cb0635d2524d234e3993d76b7e60f1c478ba45891de5cc0a1fec116f7c0dd9be7aa54226edf0196e37856afca32c69d790e1L
c2=0x9bcbfea3c3130364bbcf352b7810df031293949ed147919dec3ecfdd48f77e9486ae811d95f8c79eb477f4424d475dc611536343c7e21c427e18593aae37982323f2c0f4e840fbf89b31edc8f79ad7f6511ee0e5605cfbba7ada7d8777e81ec0ac122e0ad5108e97fafc0cd31ed8c83f3e761b92bdbea1144b0c06c5ca43a7b4e9e0a2b15ee12509235c5695be54d9fd0725ac80abbf0f5e8f43539da3ce9464020099e031d8bca899f11638169196ac72aeaeb90dab851d801cf93044cc00dd94d93c8963201b26788a7c42ce45c496c0a597ac53cd55c60b8f38f3f7d1f8ecc2e4e40ba6fe0c6e605ebbfc9aa3da5ab810c783c1d9957bb5d00a89ab1bbdeL

这个n1,n2明显一样,猜测是共模攻击
访问bystudent大神的博客,改变一下他的代码

#coding=utf-8 

import sys

def egcd(a, b): 
    if a == 0: 
        return (b, 0, 1) 
    else: 
        g, y, x = egcd(b % a, a) 
        return (g, x - (b // a) * y, y) 

def modinv(a, m): 
    g, x, y = egcd(a, m) 
    if g != 1: 
        raise Exception('modular inverse does not exist') 
    else: 
        return x % m 

def main(): 
    #n = int(raw_input("input n:")) 
    #c1 = int(raw_input("input c1:")) 
    #c2 = int(raw_input("input c2:")) 
    #e1 = int(raw_input("input e1:")) 
    #e2 = int(raw_input("input e2:")) 
    n=int("18f60afa6b9938df69338805ae7fbd5652da3ac8fa5b7b65e4755149ba3f80d071fe8845fa20ea3e57e21fb2f630e47e4886de35c51d1487c170a59141f833c3aaea62c539e20664dbfa75f1b2d56ed4dbec991e5bf3306931bfda79b1dd8466f808af159b44be042499d423110ab9cfd595e370029862e2e686ed2a27fb6b459c4fddc0ebd4f112e0f3769524412e7128eb04b02de421df5a0e5b22d2c40acf1727aa9093160bf6dbd862ac136a805a4e9c760c54d28ac5bf21d509d94e9e437e2e38a13664ec104dadc66f8c21b7b82e3e3570d27326e13df07dd72b6847f8e53aadeafa54cc879cfa2ae3b8028c39df36b097ba65688abadb78a06c16f393",16)
    e1=int("17e1",16)
    e2=int("43a5",16)
    c1=int("b6e66aa0d4d5ad1460482f45aab87e80a99c1ff3af605fd9cea82d76d464272f3dd2e1797e3fede64cffcd54b2a7a5e21f45574783f62266cebf3cdb9764c6c04b0b30b5d065d5f6142d498506ea1f6449f428253d4d76bd96778d5f58abf313370b980dcb90daf882c5539ac3df81a431bc2c0e0911ecbe5195d94312218b3854ee14f13bd00c81d7ff11c06a9e112940b7377c20e53738a2ebb77b0534d8d9e481e60e9c87693bd9e1fd1e569083479ff8f53e42337a2b799c2325a7e2588fb046cf228d01d8596e7af4570a3cb0635d2524d234e3993d76b7e60f1c478ba45891de5cc0a1fec116f7c0dd9be7aa54226edf0196e37856afca32c69d790e1",16)
    c2=int("9bcbfea3c3130364bbcf352b7810df031293949ed147919dec3ecfdd48f77e9486ae811d95f8c79eb477f4424d475dc611536343c7e21c427e18593aae37982323f2c0f4e840fbf89b31edc8f79ad7f6511ee0e5605cfbba7ada7d8777e81ec0ac122e0ad5108e97fafc0cd31ed8c83f3e761b92bdbea1144b0c06c5ca43a7b4e9e0a2b15ee12509235c5695be54d9fd0725ac80abbf0f5e8f43539da3ce9464020099e031d8bca899f11638169196ac72aeaeb90dab851d801cf93044cc00dd94d93c8963201b26788a7c42ce45c496c0a597ac53cd55c60b8f38f3f7d1f8ecc2e4e40ba6fe0c6e605ebbfc9aa3da5ab810c783c1d9957bb5d00a89ab1bbde",16)

    s = egcd(e1, e2) 
    s1 = s[1] 
    s2 = s[2] 
    # 求模反元素 
    if s1<0: 
        s1 = - s1 
        c1 = modinv(c1, n) 
    elif s2<0: 
        s2 = - s2 
        c2 = modinv(c2, n)

    #m = (c1**s1)*(c2**s2)%n 
    m = (pow(c1,s1,n)*pow(c2,s2,n))%n  #效率较高
    print m 

if __name__ == '__main__': 
    sys.setrecursionlimit(1000000) #例如这里设置为一百万  
    main()

在这里其实出现了一个问题,就是由于循环次数过多,导致python默认的深度不够,会报错

RuntimeError: maximum recursion depth exceeded in cmp

这时候百度得知改动技巧

import sys
sys.setrecursionlimit(1000000) #例如这里设置为一百万

这样就可以完美的运行,得到m
2511413510842060413510067286707584738156534665355713590653
转化成字符即得flag:flag{rea_is_goodd112345}
校赛writeup_第7张图片

wn

文本中给了c,e,n

c=0x63ef5dc677da219989328c3e02cf6fff8aa7a47929d5fff01808005d7abbf40d62fea27fe6ec2abe5d98915e1ecd65b4a9f6b51713b0d0a479bedead0837c7ab44ece78df9708f3bd5702ef48b8b37ddd686b1a1e397eec53779e45354479f13e8329d90c1799d3d920d072b9db39c39c4da4d154537d60080355fe1c34cfa179f5ca19fc08ef2e5f5ba23ec49c08d54bdd383d8f69b2ede5252342d14d5c11546047bd631a6fdec50dfd8f9232eab73c9cb2c9c453feda0348385a45607d04e534983a10b8fe6769002e91fc3867460c100df2b8dec3ff68ba35138677d424eeb5ccb8a8712068ad22d5d596aeb770589ffbf8732ea7fa60d86113f6aefaffL
e=0x1dd2f1e955f2b2a230e23a691dbfa129672588f4f14f20527eb6731b1c6bec25ee955e706a2c1a3e8740900e32ffa977ac899a1fb905dd7a11bc6bbd448960260c82eb6aec3f1fbeeeafc6b2e32a53369a406b7c851f3bb235b0a34699bfae43d6ac5dc3402aa52a9009f7a4c92d263eec13ed7a8d240d85d551a66b7c67a46c8d6978f609cec1ddcb3f9ca5bf173ed705dd0814182c40cbc689d5f749d83b2df753dafe484d7d5b4c3964e03c291ed822f87cbd7ed921d0aa15d33052602d19d7d54b61a6d4dea2a436d04da3bfc3c4fa12430c4eb3dbd1fca149295993fcf164a21a47b2a071169929b2d2fa7435c92ade5d9a3c9b0d76bfbc690d7ddc827L
n=0x7d7adb3106f3ed066a0a94da1822290f596f1f6bf23f0ee64ce5804d59b82458f65ad251575777edeb75abef82fb7dc8ac8b5d503e912867d644897803370a51ead9d74e42df734314af4bc8564db1714e61e7d5bdd16ec3306b2d93741a9fa4822e2cb6795a3cd0c1a6a6f8d1bd06a8fb6cb6c6acea7bdd6a247ec76cbf261e9f1f3915be37c0ec7ff44d064978857e6d05d778ef07ab84b31a8fa3d500e347c7baef85e647603dba220f570006e79deafcac7d863f3f1bc2ebcac64562984b730cf5b91cf23ff817f9dd64ac6a1cee4475a31a82180b53930dc67f40e1d6d91d1a6316af6de7e40c8ef4a76fdfe40ff352fe7dc89466a4846cb8d1a8fd025L

看来都好大啊,度娘相关攻击手段
链接(http://www.tuicool.com/articles/iYBZBfy)
看来需要采用低解密指数攻击,github得到了相关的代码,修改一下

import random, sys

def rational_to_contfrac (x, y):
    ''' 
    Converts a rational x/y fraction into
    a list of partial quotients [a0, ..., an] 
    '''
    a = x//y
    if a * y == x:
        return [a]
    else:
        pquotients = rational_to_contfrac(y, x - a * y)
        pquotients.insert(0, a)
        return pquotients

def convergents_from_contfrac(frac):    
    '''
    computes the list of convergents
    using the list of partial quotients 
    '''
    convs = [];
    for i in range(len(frac)):
        convs.append(contfrac_to_rational(frac[0:i]))
    return convs

def contfrac_to_rational (frac):
    '''Converts a finite continued fraction [a0, ..., an]
     to an x/y rational.
     '''
    if len(frac) == 0:
        return (0,1)
    elif len(frac) == 1:
        return (frac[0], 1)
    else:
        remainder = frac[1:len(frac)]
        (num, denom) = contfrac_to_rational(remainder)
        # fraction is now frac[0] + 1/(num/denom), which is 
        # frac[0] + denom/num.
        return (frac[0] * num + denom, num)
import random, sys

def bitlength(x):
    '''
    Calculates the bitlength of x
    '''
    assert x >= 0
    n = 0
    while x > 0:
        n = n+1
        x = x>>1
    return n

def isqrt(n):
    '''
    Calculates the integer square root
    for arbitrary large nonnegative integers
    '''
    if n < 0:
        raise ValueError('square root not defined for negative numbers')

    if n == 0:
        return 0
    a, b = divmod(bitlength(n), 2)
    x = 2**(a+b)
    while True:
        y = (x + n//x)//2
        if y >= x:
            return x
        x = y

def is_perfect_square(n):
    '''
    If n is a perfect square it returns sqrt(n),

    otherwise returns -1
    '''
    h = n & 0xF; #last hexadecimal "digit"

    if h > 9:
        return -1 # return immediately in 6 cases out of 16.

    # Take advantage of Boolean short-circuit evaluation
    if ( h != 2 and h != 3 and h != 5 and h != 6 and h != 7 and h != 8 ):
        # take square root if you must
        t = isqrt(n)
        if t*t == n:
            return t
        else:
            return -1

    return -1

def hack_RSA(e,n):
    '''
    Finds d knowing (e,n)
    applying the Wiener continued fraction attack
    '''
    frac = rational_to_contfrac(e, n)
    convergents = convergents_from_contfrac(frac)

    for (k,d) in convergents:

        #check if d is actually the key
        if k!=0 and (e*d-1)%k == 0:
            phi = (e*d-1)//k
            s = n - phi + 1
            # check if the equation x^2 - s*x + n = 0
            # has integer roots
            discr = s*s - 4*n
            if(discr>=0):
                t = is_perfect_square(discr)
                if t!=-1 and (s+t)%2==0:
                    print("Hacked!")
                    return d

if __name__ == "__main__":
    n=990023173701890142960417396557829467604818405521894936859951202214773485865832785292323872121243887697290422045990013422607876480641270661367864382389893789596078312082027665553855270696451019054919069134732452191977525630655976091851072534780363846681322224621650105419018181198428165007342791192003551280877541234686022585373169611329463075555962420262841398957747472053420414997254472168650615854344763306064291593967460854817443906609759558144854063757076283269500492727802851281783673232830692457911612959175538769194685797000335876443248126827447575107633034183744580751790001353796972802669451070935734931493
    e=235308230249427956073994778236213308201165228968967264823632398966978083858618015310724273760982061608902488436041676909915097228896544054764485576608147425983433627672556840438360922524333914861841915302324033903747815478440207839231405164459309430488083417021299863448530761603691583119435411334929236989305080703733969737477059347874381118819315342999662421300865938367414646348114114523518559518198427990964401454548211551305162678178910564008966603832884326159914009915068561450603480793388907172483641086337688420637151051921455148790521653521635779290202539763111269020386581967559996128236288594127596931111
    d=hack_RSA(e,n)
    print d

得到d=30011
这样直接脚本解密就行

import math
n=990023173701890142960417396557829467604818405521894936859951202214773485865832785292323872121243887697290422045990013422607876480641270661367864382389893789596078312082027665553855270696451019054919069134732452191977525630655976091851072534780363846681322224621650105419018181198428165007342791192003551280877541234686022585373169611329463075555962420262841398957747472053420414997254472168650615854344763306064291593967460854817443906609759558144854063757076283269500492727802851281783673232830692457911612959175538769194685797000335876443248126827447575107633034183744580751790001353796972802669451070935734931493
e=235308230249427956073994778236213308201165228968967264823632398966978083858618015310724273760982061608902488436041676909915097228896544054764485576608147425983433627672556840438360922524333914861841915302324033903747815478440207839231405164459309430488083417021299863448530761603691583119435411334929236989305080703733969737477059347874381118819315342999662421300865938367414646348114114523518559518198427990964401454548211551305162678178910564008966603832884326159914009915068561450603480793388907172483641086337688420637151051921455148790521653521635779290202539763111269020386581967559996128236288594127596931111
c=788476757386221543537703608890186546442886644502803697518028267920600460220013483242506024987780673274894640972913419348131638674650297913257698380629030789425241326400460779957736137653911242371819455834503315030302866040645836290957691445959653938430879900694828439435699643144568320527205094071390940553388594203187022623769818515793107513956737821245415004711757450202148161254040561612359947403387404625171790678861784947278421483221298384341596583699883571547913038896065048203584687131767988397347080214823075357248539577208665545930392234612492615041261379339566841377463503145318178415053741856403946928895

d=30011
m=pow(c,d,n)
print m
mh=hex(m)
print mh

def str2byte(s):
    base='0123456789ABCDEF'
    i = 0
    s = s.upper()
    s1=''
    while i < len(s):
        c1=s[i]
        c2=s[i+1]
        i+=2
        b1=base.find(c1)
        b2=base.find(c2)
        if b1 == -1 or b2 == -1:
            return None
        s1+=chr((b1 << 4)+b2)
    return s1

print str2byte(mh[2:-1])

得到flag:flag{wiener_attack_attack_you}
校赛writeup_第8张图片

android

本以为安卓题很难,但看到这么多人出题,尝试一下,用Jeb打开,就两个类
MainActivity里存放着gUID_P@Rt}T10n_$C#3m3Gu]d_par7|t)On_SCH3M3
a是一个判断程序,直接反编译

package com.a.sample.androidtest;

import android.content.Context;
import android.view.View;
import android.view.View$OnClickListener;
import android.widget.EditText;
import android.widget.Toast;

class a implements View$OnClickListener {
    a(MainActivity arg1, EditText arg2, Context arg3) {
        this.c = arg1;
        this.a = arg2;
        this.b = arg3;
        super();
    }

    public void onClick(View arg9) {
        if(this.a.getText().toString().equals(String.format("flag{%s}", new Object[]{MainActivity.m.
                substring(12, 24)}))) {
            Toast.makeText(this.b, "You are right!", 1).show();
        }
        else {
            Toast.makeText(this.b, "You are wrong!", 1).show();
        }
    }
}

本以为很复杂,结果就一个字符串匹配。。。比web题简单好多,通过分析,就是要12-24区间的值
flag{0n_$C#3m3Gu]}
本以为这样里面乱的需要处理,结果尝试虚拟机跑一下结果对啦。。。。
校赛writeup_第9张图片

web1

打开什么也没有,查看源码得到提示

查看得到源码


$flag="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxx"; // guess it length :)
$username = $_POST["username"];
$password = $_POST["password"];
$cookie = $_COOKIE['albert'];
if (!empty($_COOKIE['albert'])) {
if (urldecode($username) === "admin" && urldecode($password) !=="admin") {
    if ($_COOKIE['albert'] === md5($secret . urldecode($username . $password))) {
        echo "Congratulations! here is your flag.\n";
        die ("The flag is ". $flag);
    }
    else {
        die ("Cookie Not Correct");
    }
}
else {
    die ("Go AWAY");
}
}
setcookie("sample-hash", md5($secret . urldecode("admin" . "admin")), time() + (60 * 60 * 24 * 7));
?>

一看明显就是哈希扩展攻击,利用hashpump构造即得
这里写图片描述
由于长度不知道,在这里小小的额爆破了一下20-30之间的长度,发现在26的时候成功
校赛writeup_第10张图片

这期间构造POST发现点错误,发现我无论怎么改变cookie都会显示Go AWAY明显数据包没构造正确,后来检查发现忘记写Content-Type: application/x-www-form-urlencode
真是的浪费了好多时间

了解哈希长度扩展攻击

哈希长度扩展攻击适用于加密情况为:hash($SECRET, $message)的情况,其中 hash 最常见的就是 md5、hash1。我们可以在不知道$SECRET的情况下推算出另外一个匹配的值。如上例所给的 PHP 代码:

  • 我们知道md5($secret . urldecode($username . $password))的值
  • 我们知道$hsh的值
  • 我们可以算出另外一个 md5 值和另外一个 $hsh 的值,使得 $hsh == md5($SECRET . $_COOKIE["albert"]))
    这样即可通过验证。

想要知道更多的可以访问下面这个github上hash_extender作者的文章:
[(]Everything you need to know about hash length extension attacks](https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks)

D0ge

这题下载下来就是一个图片,一开始使用了各种姿势就是没有分析下来,后来出了Hint:bftools
知道需要用bftools来进行解码,度娘查一下,发现第六届西电信息安全大赛XDCTF2015有道类似的题
然后两行代码直接运行解密即得一串字符串
校赛writeup_第11张图片
GYYWIY3UMZ5UQML6IIYHSLCXMVWEGMDNMUWVI3ZNJAZVEZL5
然后发现是base32解码
脚本一跑即得
61dctf{H1~B0y,WelC0me-To-H3Re}

CrackMe

先打开看看,出现一句话
Give me your favourite prime number
拖到IDA里分析一下,有四个check一个一个分析

先分析check1:

反编译得到代码

puts("Give me your favourite prime number");
  scanf("%lld", &n);
  a = 0x100000LL;
  b = 0LL;
  c = 0LL;
  while ( !(a & 1) )
  {
    a /= 2LL;
    ++b;
  }
  while ( !(b & 1) )
  {
    b /= 2LL;
    ++c;
  }
  if ( c == n )
  {
    flag += n;
    v1 = 1;
  }
  else
  {
    puts("^^^^Your math is bad^^^^");
    v1 = 0;
  }
  return v1;
}

很好理解,就是让输入的n等于c的值,而c的值是先由a的值得到b,在由b的值得到c
懒得分析,直接便代码自己跑

#include 

using namespace std;

main()
{
    int64_t a,b,c;
    a = 1048576;
    b = 0;
    c = 0;
    while ( !(a & 1) )
    {
        a /= 2;
        ++b;
    }
    while ( !(b & 1) )
    {
        b /= 2;
        ++c;
    }
    cout<

得到c=2,其实这里还有flag=c=2先记住,后面要用

然后看check2

puts("Do you know how to calculate the number");
  puts("please enter a number");
  scanf("%lld", &n);
  v2 = n;
  if ( tmpans != n * tmp % mod || n > 999999 )
    goto LABEL_15;
  while ( n )
  {
    x[++pos] = n % 10;
    n /= 10LL;
  }
  if ( dword_448044 >= dword_448048
    || dword_448048 >= dword_44804C
    || dword_44804C >= dword_448050
    || dword_448050 >= dword_448054
    || dword_448054 >= dword_448058 )
  {
LABEL_15:
    puts("You do not know how to calculate the mod~~~~");
    v1 = 0;
  }
  else
  {
    flag += v2;
    v1 = 1;
  }
  return v1;

tmpans=779852816
tmp=123456
mod=1000000007

意思很好理解,输入n不能使得779852816!=n*123456%1000000007n>999999
然后后面的代码意思是将n的每一位给x数组,然后要求每一位都大于后面的一位。

import math

tmpans=779852816
tmp=123456
mod=1000000007

for i in range(0,1000000):
    if tmpans==(tmp*i)%mod:
        print i
        x=[]
        while i:
            x.append(i%10)
            i/=10

        print x

这样分析分析就可以知道结果n=654321
x=[1,2,3,4,5,6]
然后flag+=n 为654323

然后看check3

int check3(void)
{
  _BYTE *v0; // eax@4
  _BYTE *v1; // eax@4
  __int64 v3; // [sp+0h] [bp-C8h]@1
  __int64 v4; // [sp+8h] [bp-C0h]@9
  __int64 v5; // [sp+18h] [bp-B0h]@9
  int v6; // [sp+34h] [bp-94h]@4
  int v7; // [sp+40h] [bp-88h]@5
  char TlsValue; // [sp+44h] [bp-84h]@1
  int v9; // [sp+48h] [bp-80h]@1
  int (__cdecl *v10)(int, int, int, int, int, unsigned __int8 *); // [sp+5Ch] [bp-6Ch]@1
  int *v11; // [sp+60h] [bp-68h]@1
  char *v12; // [sp+64h] [bp-64h]@1
  void *v13; // [sp+68h] [bp-60h]@1
  __int64 *v14; // [sp+6Ch] [bp-5Ch]@1
  int j; // [sp+78h] [bp-50h]@4
  int i; // [sp+7Ch] [bp-4Ch]@2
  int v17; // [sp+80h] [bp-48h]@1
  int v18; // [sp+90h] [bp-38h]@1
  char v19; // [sp+A0h] [bp-28h]@1
  char v20; // [sp+B0h] [bp-18h]@1

  v10 = __gxx_personality_sj0;
  v11 = dword_442E70;
  v12 = &v20;
  v13 = &loc_4019EE;
  v14 = &v3;
  _Unwind_SjLj_Register(&TlsValue);
  v9 = -1;
  std::string::string((std::string *)&v19);
  std::allocator<char>::allocator(&v17);
  v9 = 2;
  std::string::string((int)&v18, "MerryChristmas", (int)&v17);
  std::allocator<char>::~allocator(&v17);
  v9 = 1;
  puts("Do you wanna enjoy the festival tomorrow?");
  std::operator>><char,std::char_traits<char>,std::allocator<char>>((std::istream *)&std::cin, (std::string *)&v19);
  if ( std::string::length((std::string *)&v19) == 14 )
  {
    for ( i = 0; i <= 13; ++i )
    {
      j = i % 6 + 1;
      v9 = 1;
      v0 = (_BYTE *)std::string::operator[]((std::string *)&v19, i);
      v6 = *v0 + x[j];
      v1 = (_BYTE *)std::string::operator[]((std::string *)&v18, i);
      if ( v6 != *v1 )
      {
        v9 = 3;
        std::string::~string((std::string *)&v18);
        v9 = -1;
        std::string::~string((std::string *)&v19);
        v7 = 0;
        goto LABEL_12;
      }
    }
    for ( j = 0; j <= 13; ++j )
    {
      v9 = 1;
      LODWORD(v5) = *(_BYTE *)std::string::operator[]((std::string *)&v19, j);
      v5 = (signed int)v5;
      v4 = mod;
      v3 = flag + (signed int)v5 * tmp;
      flag = (flag + (signed int)v5 * tmp) % mod;
    }
    v9 = 3;
    std::string::~string((std::string *)&v18);
    v9 = -1;
    std::string::~string((std::string *)&v19);
    v7 = 1;
  }
  else
  {
    v9 = 3;
    std::string::~string((std::string *)&v18);
    v9 = -1;
    std::string::~string((std::string *)&v19);
    v7 = 0;
  }

分析这代码的意思,基本上是得到一个长度为14的字符串使得按位进行模6循环加与v18=MerryChristmas比较相等输出,懒省事写个脚本

s='MerryChristmas'
r=''
j=0
for i in s:
    k=j%6+1
    r+=chr(ord(i)-k)
    j=j+1
print r

得到结果

v19= Lcont=gpfoog`q

然后后面的也有用

for ( j = 0; j <= 13; ++j )
{
v9 = 1;
LODWORD(v5) = *(_BYTE *)std::string::operator[]((std::string *)&v19, j);
v5 = (signed int)v5;
v4 = mod;
v3 = flag + (signed int)v5 * tmp;
flag = (flag + (signed int)v5 * tmp) % mod;
}

是一个flag的循环得到,将刚进去的v19每一位转成数值型进行计算得到结果,依旧代码

j=654323
st='Lcont=gpfoog`q'
mod=1000000007
tmp=123456

for i in st:
    j=(j + ord(i) * tmp)%mod

print j

得到结果flag=176455667

check4

signed int check4(void)
{
  signed int v1; // [sp+14h] [bp-4h]@2

  puts("The Final Game:");
  puts("I wanna Check YOUR HASH Math");
  scanf("%lld", &n);
  if ( flag == n )
  {
    puts("^^^^Show Flag^^^^");
    v1 = 1;
  }
  else
  {
    v1 = 0;
  }
  return v1;
}

就是输n=flag就行了
这里有一个坑。我就一直提交,结果发现一直不停,一直以为自己算错啦,结果经过提示:没停不代表不对,开始下断点,终于让他得到flag
校赛writeup_第12张图片

web4

打开网页居然出现张图片,查看源码

"http://www.w3.org/1999/xhtml">

"Content-Type" content="text/html; charset=utf-8" />

"#000000">
" margin-top:70px;color:#FFF; font-size:23px; text-align:center">Hi   "#FF0000">CTFer
"3" color="#FFFF00"> id?????????????????????????????????????????



"1.jpg" style="position:absolute; top:0px;left:0px; width:100%" />

发现有一个id????莫非这是注入点??
先尝试看看sqlmap跑跑吧,反正我懒
sqlmap.py -u http://45.32.58.123:4444/index.php?id=1 --tamper=space2comment --dump --batch
结果真的跑出来啦。。。
校赛writeup_第13张图片
访问http://45.32.58.123:4444/index.php?id=1
出来提示:

please post flag === admin’password

这样的话就是构造POST包,期间各种理解错题意尝试了好几次方式,均得不到flag,结果后来一直循环尝试之前的方法有一种就对啦。。。好吧
校赛writeup_第14张图片

web6

打开是一个这个界面
校赛writeup_第15张图片
一开始查看源代码啥的什么都没有,那么就随便输输
校赛writeup_第16张图片
发现每次输Message都在改变,查看源代码,发现
校赛writeup_第17张图片
下面一串类似乱码的字符提示是flag,看来flag就是这个,但这个每次提交也会改变,但截出来发现这个虽然都在改变,但长度都保证在512字节中,这是一个非常重要的一点
然后上面有一个重要的提示

Do You Know liumima?

百度一下,这是一个关于流密码的加密题
链接(http://wenku.baidu.com/link?url=dEDeXst74Hl-yaldjZ7vKQH8CrEpj_jScvanVqn2hyOu_tB5dQLMBj2O4c8Js3cVQjIbzwpQVbgR3x1AIdb1X0I0LZjBBXhZS8AJu6iNxJu)
里面有简要介绍解密原理
大意就是将当你输入的值与flag与message长度一直,且异或就能得到真正的Flag,这样的话就能构造脚本,由于这个不用交互,构造512字节的1,所以得到一组Flag,Message就可以
由于长度过大,所以用了点小的转换来使得三者都为10进制然后异或

Message:

\x77\x0e\x03\x73\x4a\x45\x1b\x45\x62\x60\x49\x18\x01\x57\x76\x51\x43\x14\x7e\x53\x17\x75\x06\x5a\x43\x48\x56\x41\x1d\x70\x6e\x45\x55\x7c\x56\x44\x1b\x6d\x5b\x19\x10\x7d\x63\x74\x60\x0d\x6a\x10\x75\x79\x1d\x06\x1f\x1f\x76\x1a\x46\x62\x4a\x78\x03\x44\x43\x42\x63\x09\x4f\x1a\x04\x48\x40\x6a\x69\x44\x76\x1b\x61\x59\x02\x74\x1b\x4b\x43\x52\x62\x0d\x18\x61\x1f\x60\x0c\x61\x75\x60\x52\x1c\x17\x1e\x0f\x5d\x09\x6f\x7f\x58\x7a\x12\x5e\x5a\x47\x53\x65\x0c\x0d\x1c\x18\x58\x53\x56\x53\x59\x19\x65\x4b\x02\x6f\x01\x72\x12\x42\x72\x1a\x06\x42\x60\x0d\x58\x61\x0e\x7d\x6f\x7e\x10\x57\x79\x10\x74\x1d\x77\x55\x06\x10\x51\x52\x6d\x0e\x46\x56\x67\x67\x1f\x18\x54\x0c\x67\x51\x46\x68\x06\x01\x59\x03\x45\x45\x6f\x56\x0f\x0e\x51\x54\x79\x58\x4f\x68\x46\x5c\x5b\x02\x58\x4b\x55\x6f\x4a\x1e\x15\x1e\x6a\x08\x15\x09\x05\x0f\x7a\x6b\x00\x4c\x08\x53\x7f\x50\x47\x01\x07\x61\x72\x66\x61\x5b\x6e\x5b\x42\x0c\x7d\x1b\x78\x4b\x00\x5e\x74\x7b\x6c\x10\x67\x7b\x44\x1f\x46\x5a\x76\x45\x44\x48\x07\x06\x0c\x43\x5d\x4b\x03\x0d\x65\x77\x0e\x6e\x52\x78\x40\x5c\x43\x55\x5a\x63\x6c\x48\x46\x0f\x59\x54\x7b\x4d\x58\x54\x12\x04\x07\x54\x07\x5b\x1a\x72\x69\x5c\x59\x4f\x18\x5d\x1a\x72\x55\x18\x7c\x4b\x61\x75\x01\x0e\x0f\x4b\x5b\x05\x77\x04\x6a\x41\x72\x52\x09\x00\x03\x54\x43\x12\x55\x09\x1f\x1d\x67\x1f\x49\x60\x04\x1f\x7f\x71\x64\x70\x1a\x7b\x1a\x6f\x52\x42\x61\x15\x64\x7a\x14\x45\x60\x1c\x1f\x57\x46\x50\x61\x56\x4a\x7c\x74\x7f\x4c\x59\x6e\x67\x59\x1c\x62\x50\x5c\x7c\x00\x6b\x6d\x5c\x0c\x6c\x7f\x42\x12\x0f\x48\x06\x62\x06\x65\x75\x17\x12\x0e\x1d\x07\x5f\x53\x4d\x70\x5f\x51\x65\x0c\x75\x43\x57\x7f\x04\x55\x5d\x4c\x03\x5f\x72\x67\x02\x56\x0c\x42\x64\x5a\x53\x0d\x4a\x62\x71\x79\x71\x62\x7e\x5f\x77\x12\x02\x4a\x03\x08\x46\x55\x44\x1e\x74\x60\x72\x12\x01\x7e\x4b\x1e\x70\x18\x04\x54\x44\x01\x1b\x0e\x63\x5d\x45\x0f\x7c\x4d\x71\x7c\x5f\x6e\x74\x6e\x4c\x72\x04\x7a\x75\x40\x4b\x65\x64\x63\x6a\x6c\x5b\x68\x08\x44\x6e\x7b\x42\x01\x5f\x47\x70\x46\x0d\x58\x7a\x78\x46\x1d\x7a\x5e\x60\x79\x61\x77\x65\x41\x62\x02\x7a\x50\x79\x07\x03\x15\x4b\x6d\x15\x52\x14\x7f\x02\x6b\x0f\x4a\x15\x7c

去掉\x

770e03734a451b45626049180157765143147e531775065a434856411d706e45557c56441b6d5b19107d6374600d6a1075791d061f1f761a46624a780344434263094f1a0448406a6944761b615902741b4b4352620d18611f600c617560521c171e0f5d096f7f587a125e5a4753650c0d1c18585356535919654b026f01721242721a0642600d58610e7d6f7e10577910741d7755061051526d0e465667671f18540c675146680601590345456f560f0e515479584f68465c5b02584b556f4a1e151e6a081509050f7a6b004c08537f50470107617266615b6e5b420c7d1b784b005e747b6c10677b441f465a7645444807060c435d4b030d65770e6e5278405c43555a636c48460f59547b4d585412040754075b1a72695c594f185d1a7255187c4b6175010e0f4b5b0577046a41725209000354431255091f1d671f4960041f7f7164701a7b1a6f52426115647a1445601c1f57465061564a7c747f4c596e67591c62505c7c006b6d5c0c6c7f42120f48066206657517120e1d075f534d705f51650c7543577f04555d4c035f726702560c42645a530d4a62717971627e5f7712024a03084655441e74607212017e4b1e7018045444011b0e635d450f7c4d717c5f6e746e4c72047a75404b6564636a6c5b6808446e7b42015f4770460d587a78461d7a5e60796177654162027a50790703154b6d1552147f026b0f4a157c

转化成10进制Message:

485700964415255903211113372964504659639279456393066557980938092352095890535932872895141800499542172674055216594002078657707705086575198195351428682208131140495877283514477311358768301421639299547659186891307022027815263905847304241313934106143766622301815785751373333190745939876077280211454902538341703460600307534965199849769361989935153575068578352744610554124849572899270550090023182913174979576183585648329211847665090275848137833318859407182536455706582133365281547195135144001306153325273028667831200696202276346848301014552544581407447088930823813615424255861943369056305137134053240746730368819937966101412072050811974706086725998005172473748210683139689280932100842601229098567481120394353546816761156723160451470460969259209414095847274959328896327993878537907386349220636924372103315752388117102435859478466001569838243014996482992271784112453498775825757369940660604051619133017480361227321419365456528645270085380876640526645792969840864524721672045168407340766457962743987850263143804436494509102998436311921290792873888571454270997194183067375340610165187340556010110303870844158787644613121680066900116744049058706763062267879310577394611948305325355096447299936806238513018111008897770528807543512019645066778383740

Flag:

8^GE(^ c},Sy^       7lv.r   %*OML;4 FA\E0} p%OhhaPj7:S}aE6XGys(>~@ XJ `/<A7pS&S8!!!h[!HLdD}[m%kj=jjn=SmjP%G:SBDo$V    0eNM0[        gl=2'C(>1 BM7".*sShr1?nv]O1rO{4Xc-$! x] {a#{C]SX'&3we~Z~H O]AuiwwOyPCdUDuJxtYksgDt {}INlleknXmBl{AYNxFZ~Oz]bd~cHjU
OF\~

10进制的Flag:

217980398411617158842241975551949019674179278908268446065163864232720395592880711787731069229386783564968501673773117602737758661028726600294826103915165158493215186258357403258091889460868921515259033231777509573862328713413389370918163173119043360436042790741785857908121963626221721916111022875609800847892967253491294490977259267017818692977662385731974646527196960430749324616541328134553733729323098353915990107936040714639122823647637375504905663701186783964547917462704963140467220593929427256737005036768361115362530026773874446064189273071805762301748426988174970980928873323800037359837107508225024806934485982911372984005879095446986725283306658369695649690871299031743825674950747996680771621914032183125005897296383933534053959381331753386699288258793817752884512742614795163219620092328172019734028823909968409557965859218732422971629644967916831872703498448211775651850766579684107667043180545286026275533684722101555382935934201380812018197562056436019979180657757632572563212519484116887240125441059334360911192747446636329841167196617763719319875729327931886167164503094157736530986372093182247963832674413057977832404618500734394504512104263273404008024224541759609300528009940317120545814001747213226979837154864

得到最终flag:

470455327039912774504782716414819151563525179727516887293855531622782540801134307473237930221874616439744548606090130228660470743126900461273219730845765675945537542060321870231893954535468327158741556928743771350012173229709215277120704394827433480467942008001577745638704283459509813379821479414330793448054623900950106149972269495775481725432724805887871074925101129117548255316386651349935873056420236282006186173611684502017163339985584670394516244474981909926161360799726896448456681520717157514046045691351159741420026394761561498433604917775271817540646173373980184057015484879471950633998407950086452911392096713388973855863226570658456194047876237794967783963107601267776526981884141096574381123306694225751617472404300434571201069309200342624574988675240966404876348973158865772180809219625523442615590556819828023200177764902753342744470560774856610249198443842621453485766091638378391949327192916413625827700249154962096179744431364127063653114778268222770151973576360790270361274779075365609832553577568153471870793578221181622660902400376800586636412445034796633917422332241349845426101403281504777335669106395608824582902314230888321970009718584588382110678503820652029024109045045999116002473009055676646684469637757

将flag转化成16进制
校赛writeup_第18张图片
然后转化成字符即得
这里写图片描述
脚本

def str2byte(s):
    base='0123456789ABCDEF'
    i = 0
    s = s.upper()
    s1=''
    while i < len(s):
        c1=s[i]
        c2=s[i+1]
        i+=2
        b1=base.find(c1)
        b2=base.find(c2)
        if b1 == -1 or b2 == -1:
            return None
        s1+=chr((b1 << 4)+b2)
    return s1

s ='7351574c487a6a444a65667d7d3238604f246e6d587c59633e763f636130567d292c607c7036757973663d70296f374e52446f7374232a3d32235325755569507e3e294842255d7072796b35516b7a70447a3c2f6874365f5f5d7326434f3777446c316d697c327c7d4a235b6052463c79545c377e675c5359464b232467686e4e59312452632e48383f457c7042767242727c4b5c69667026746157654a4c4d54496e2f3e7e6e5b4646407d6a7b4d71722c735331454b434d2c72353f54237b2454317e763c507b364532502d53554a5b254d574c5c48522f69323431355961444f537a2f3262725b5259754e793475217c212972774f522c635d7b5d4c75742c452c634b2d2a516d50446b6c7e443d5d6d447e264f58784a765f53282d3e3f4468614a2f2328546b575e2c5b5471505e6b5c583557645e6b6c68392f7e75633847704a24655e666e387a37486879607c766e32605f7748594a415b473f2568477726714f473e624b34634f6c71674d4824785629654f3c51705730755f77515a3837316956474e4d396c6e497a4f373d444630463631646374667b37363134383934333237383934393038343537383536383739353637383936393035383638393734363839373530393834383937303332343837333132343738393132333437383931323337343837383930343437333839355f626f795f3f24255e327d'
print str2byte(s)

flag GET!!!~
61dctf{76148943278949084578568795678969058689746897509848970324873124789123478912374878904473895_boy_?$%^2}

异或脚本如下:

#Flag 为所截取到的512字节字符
#Message 为处理后所得到的10进制
Message=
Flag=
s=''
for i in Flag:
    k = str(bin(ord(i)))[2:]
    if len(k) < 8:
        k = '0'*(8-len(k))+k
    s += k
Flag = int(s,2)

#print Flag

in_ = '11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'

s2 = ''
for i in in_:
    m = str(bin(ord(i)))[2:]
    if len(m) < 8:
        m = '0'*(8-len(m))+m
    s2 += m
in_ = int(s2,2)
#print in_
#in_ = 200686490938213618932925030686723900966346071385575706818931139925151927414142413276833387391430903367465157760813819133574082739102368183356464973743987837722948595492712901641873403594450204695713629139533103392519371071099952645246840782481900957871935637359154437252913405444179654300427180044691385965990823568106696476515287748546363867017174091051797450964111012257685851865814304288305868868796070362487761893449386893361922901844324634350334616783957894220005538964792468979405328145100453460098854853839989027847783206845004095945185162744506591411155318233223679027298329085177274095914773286471049161702613799175486411492003372288722716950913877957802694948679785419083224812096387329082981115878996013259272222472356069166820222490810121435442820722489119884073056358155724651716232802987659573867435059545130785856458655309902770151770043405778785036718566031651260115600041084237592155873140867644089767487877289411629787419400386757597222832981129288874883921314078446307643819572105712219875309974530695306897012252757579812647497998317030864635355185457048473443750962962325959236879327971895179877812488472241671023567097665713934032193125740463764283516105833757192335092325954137896621052635084041994822566883633L

flag = Flag^Message^in_
print flag

你可能感兴趣的:(WriteUp)