2020CTF强网杯记录

2020CTF强网杯记录

1、fun_hash

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
<?php
include 'conn.php';
highlight_file("index.php");
//level 1
if ($_GET["hash1"] != hash("md4", $_GET["hash1"]))
{
die('level 1 failed');
}

//level 2
if($_GET['hash2'] === $_GET['hash3'] || md5($_GET['hash2']) !== md5($_GET['hash3']))
{
die('level 2 failed');
}

//level 3
$query = "SELECT * FROM flag WHERE password = '" . md5($_GET["hash4"],true) . "'";
$result = $mysqli->query($query);
$row = $result->fetch_assoc();
var_dump($row);
$result->free();
$mysqli->close();


?>

Payloadhttp://39.101.177.96/?hash1=0e5882628476&hash2[]=3&hash3[]=4&hash4=ffifdyop

第一关:需要绕过这个判断式,这里通过hash碰撞脚本撞出来,绕过方式是利用的是php的弱类型变量特点,0e开头且后面所有内容都是数字的字符串会用科学计数法的方式来看,因此认为值是0。所以过第一关只需要碰撞出0eXXX的原字符串经过md4加密仍然是0eXXX的密文即可。

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
# -*- coding: utf-8 -*-
import multiprocessing
import hashlib
import random
import string
import sys
CHARS = string.digits
def cmp_md5(substr, stop_event, str_len, start=0, size=10):
global CHARS
while not stop_event.is_set():
rnds = '0e'
rnds += ''.join(random.choice(CHARS) for _ in range(size))
md4 = hashlib.new('md4', rnds)
value = md4.hexdigest()
if value[start: start+str_len] == substr and if_havechar(value[start+str_len:]):
print rnds
#stop_event.set()

#print rnds + "=>" + value + "\n"
#碰撞双md5
#md4 = hashlib.new('md4',value)
# if md4.hexdigest()[start: start+str_len] == substr and if_havechar(md4.hexdigest()[start+str_len:]):
# print rnds+ '=>' + value+'=>'+ md4.hexdigest() + '\n'
# stop_event.set()

def if_havechar(str_list):
for i in range(len(str_list)):
if (str_list[i] >= 'a' and str_list[i] <= 'z') or (str_list[i] >='A' and str_list[i] <='Z'):
return False
return True

if __name__ == '__main__':
substr = sys.argv[1].strip()
start_pos = int(sys.argv[2]) if len(sys.argv) > 1 else 0
str_len = len(substr)
cpus = multiprocessing.cpu_count()
stop_event = multiprocessing.Event()
processes = [multiprocessing.Process(target=cmp_md5, args=(substr,
stop_event, str_len, start_pos))
for i in range(cpus)]
for p in processes:
p.start()
for p in processes:
p.join()

第二关:hash2和hash3不同,但是他们md5加密后要相同,这里因为判断是用的全等判断,所以不能利用php弱类型的特点去进行绕过了,这里因为md5()函数的特点,md5函数不能处理参数是数组的情况,如果参数是数组会返回null,因此构造两个不同的数组分别作为输入就会得到两个null,就绕过了第二关

第三关:第3关依然考察hash加密并且加入了sql注入的知识点,SELECT * FROM flag WHERE password = 'md5($_GET["hash4"],true)',从查询使用的SQL语句可以看出,md5函数的第二个参数是True,这意味着加密后的MD5结果是以二进制的形式输出,那么就可以爆破一个md5结果是可以绕过判断的字符串。如果像绕过判断就需要构造一个MD5值是'or'真,这里参考一下http://mslc.ctf.su/wp/leet-more-2010-oh-those-admins-writeup/,payload` ffifdyop`

2、Upload

给的是一个data.pcapng文件,放入WireShark进行流量分析,发现就是通过一个表单上传一张图片而已,通过WireShark将图片的数据流导出为JPEG(根据数据中图片的格式),其次是流量中有POST时有表单的注释,提示是使用steghide隐写工具,将隐藏内容提取出来,并且用了一个good password加密了。

dDMSo9.png

去Kali里面直接进行Steghide工具的解密:steghide extract -sf XX.jpg -p 123456,没想到密码就是123456,没有经过爆破就得到了flag。参考下面博客。

https://blog.csdn.net/Blood_Seeker/article/details/81837571

dDKxZ4.png

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器