题目
文件
先查壳,有壳脱壳,没壳拖入IDA
发现是有UPX 3.91壳的64位ELF:
脱壳
脱壳的方式很多种,根据自己的环境选择,Windows也有脱壳机。我选择使用Kali的upx命令脱壳:
upx -d 07
──(root💀kali)-[/home/CTF]
└─# file 07
07: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section header
┌──(root💀kali)-[/home/CTF]
└─# upx -d 07
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2020
UPX 3.96 Markus Oberhumer, Laszlo Molnar & John Reiser Jan 23rd 2020
File size Ratio Format Name
-------------------- ------ ----------- -----------
912808 <- 352624 38.63% linux/amd64 07
Unpacked 1 file.
┌──(root💀kali)-[/home/CTF]
└─# file 07
07: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=d2fb1adb997339317fc68e2cf960b9d38627423c, not stripped
IDA
答案
flag{Upx_1s_n0t_a_d3liv3r_c0mp4ny}
查看Writeup
解题
代码逻辑
脱壳后发现代码很简单,就是字符串对比,字符串也没有经过处理:
解题方式
- 如上图,在IDA的IDA View窗口中可以直接看到该值
- 双击这个数据,跳转到PE结构的显示,发现在PE的数据段中有该值:
- F12进入字符串窗口,注意看数据段,或者搜索flag或者CTF字符串:
签到题
做这题的时候没有什么成就感,签到题嘛😓
但是这个文章链接都开了,写都写了,想想还是要对得起自己的时间成本的本😕
突然想起来,这种简单的字符串签到题,可以用YARA规则扫描出来🧐
YARA
参数说明
--atom-quality-table=FILE path to a file with the atom quality table
-C, --compiled-rules load compiled rules
-c, --count print only number of matches
-d, --define=VAR=VALUE define external variable
--fail-on-warnings fail on warnings
-f, --fast-scan fast matching mode
-h, --help show this help and exit
-i, --identifier=IDENTIFIER print only rules named IDENTIFIER
-l, --max-rules=NUMBER abort scanning after matching a NUMBER of rules
--max-strings-per-rule=NUMBER set maximum number of strings per rule (default=10000)
-x, --module-data=MODULE=FILE pass FILE's content as extra data to MODULE
-n, --negate print only not satisfied rules (negate)
-w, --no-warnings disable warnings
-m, --print-meta print metadata
-D, --print-module-data print module data
-e, --print-namespace print rules' namespace
-S, --print-stats print rules' statistics
-s, --print-strings print matching strings
-L, --print-string-length print length of matched strings
-g, --print-tags print tags
-r, --recursive recursively search directories (follows symlinks)
--scan-list scan files listed in FILE, one per line
-k, --stack-size=SLOTS set maximum stack size (default=16384)
-t, --tag=TAG print only rules tagged as TAG
-p, --threads=NUMBER use the specified NUMBER of threads to scan a directory
-a, --timeout=SECONDS abort scanning after the given number of SECONDS
-v, --version show version information
需要用到的参数
打印匹配字符串
-s, --print-strings print matching strings
递归搜索目录(也就是扫描目录
-r, --recursive recursively search directories (follows symlinks)
只打印不满足的规则(否定)
-n, --negate print only not satisfied rules (negate)
修饰符
nocase: 匹配大小写
wide: 宽字节
ascii: ASCII码
xor: 匹配异或后的字符串
fullword: 表示匹配单个词组文本字符串
private: 定义私有字符串
做题顺序
1️⃣扫描字符串
先扫描所有文件,是否有CTF / Flag等字符串,有则打印
扫描语句 - 打印字符串
.\yara.exe .\CTF.txt -g -r -s .\CTF\
YARA规则 - 查字符串
rule CTF_CommonWordScan
{
meta:
Author = "😎建瓯最坏🐷"
Description = "签到题 - 带多重编码的Flag等字符串"
strings:
/*————————————————————flag————————————————————*/
$strFlagNoCaseWide = "flag" ascii nocase wide
//$strFlagHex = { (66|46) (6C|4C) (61|41) (67|47) }// 等价于"flag" ascii nocase
/*————————————————————CTF————————————————————*/
$strCTF = "CTF" ascii nocase wide
/*————————————————————Crack————————————————————*/
$strCrack = "Crack" ascii nocase wide
condition:
1 of them
}
扫描结果
2️⃣通过字符串查壳
扫描语句 - 筛选没有指定字符串的文件
.\yara.exe .\CTF.txt -r -n .\CTF\
扫描语句 - 查壳
.\yara.exe .\CTF.txt -r .\CTF\
YARA规则 - 查壳
rule CTF_ShellAdding
{
meta:
Author = "建瓯最坏"
Description = "签到题 - 查壳"
strings:
/*————————————————————UPX————————————————————*/
$strUPX = "This file is packed with the UPX executable packer"
condition:
1 of them
}
扫描结果
3️⃣没有字符串且带壳的文件,脱壳后分析
UPX
两个规则一起全目录扫描,发现本题07的UPX是个“假加壳”。
加壳后竟然能直接扫到flag字符串,猜测UPX壳对数据段没有处理:
对于可执行程序资源压缩,是保护文件的常用手段,俗称加壳。 加壳过的程序可以直接运行,但是不能查看源代码,要经过脱壳才可以查看源代码。
估计UPX主要是为了反反汇编,对代码段进行了处理,数据段没有什么特殊处理。比较遗憾的是暂时没有搜索到相关信息,比较多的是脱壳的技术文章:
🥳总结🥳
我没有打过真的CTF,但是如果目的是要在尽可能快的时间做完XCTF所有的题目:
- 全部文件下载到同一个父目录的不同的子目录下
- YARA扫描父目录
- 扫描到有CTF / Flag字符串的文件,查看字符串
- 推荐使用strings+grep:
- grep还可以通过-E正则配上CTF等其他字符串和条件:
┌──(root💀kali)-[/home/CTF]
└─# strings 07 | grep -E -i 'flag|CTF'
WARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1.
s->_flags2 & _IO_FLAGS2_FORTIFY
version == NULL || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_GSCOPE_LOCK)) == 0
imap->l_type == lt_loaded && (imap->l_flags_1 & DF_1_NODELETE) == 0
flag{Upx_1s_n0t_a_d3liv3r_c0mp4ny}
flag
_dl_stack_flags
//-w, --word-regexp 强制<模式>仅完全匹配字词
//⚠慎用⚠
┌──(root💀kali)-[/home/CTF]
└─# strings 07 | grep -E -i 'flag|CTF' -w
WARNING: Unsupported flag value(s) of 0x%x in DT_FLAGS_1.
flag{Upx_1s_n0t_a_d3liv3r_c0mp4ny}
flag
- 把能扫描做出来的题目剔出后(此时比如本题带壳但是可以扫出来的,已经被做完了),剩下的带壳中没有字符串的,再按传统方法,脱壳后再分析🧐