简介
是北京联合大学的一个平台,题目有在更新,但是个人感觉题目难度很迷,不过是动态积分的方式,难度也可以看出来就是了。
Write Up持续更新, 有空就刷, 希望有一天能够刷穿题库
练习平台:BUUCTF
Reverse
easyre
IDA打开,main函数:
int __cdecl main(int argc, const char **argv, const char **envp) |
helloword
jeb3打开,MainActivity:
.method protected onCreate(Bundle)V |
reverse1
IDA打开,追踪字符串到主要函数:
__int64 sub_1400118C0() |
查看Str2:
.data:000000014001C000 Str2 db '{hello_world}',0 |
flag{hello_world}
reverse2
IDA打开,主函数:
int __cdecl main(int argc, const char **argv, const char **envp) |
查看flag:
.data:0000000000601080 flag db '{' ; DATA XREF: main+34↑r |
由于前面:
for ( i = 0; i <= strlen(flag); ++i ) |
so,最终flag为:
flag{hack1ng_fo1_fun}
刮开有奖
IDA打开,查看字符串发现base64 table表
.rdata:00407830 byte_407830 db 41h ; DATA XREF: sub_401000+C0↑r |
整理一下:
.rdata:00407830 aAbcdefghijklmn db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' |
追到判断函数,根据经验修改类型和大小:
BOOL __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4) |
sub_4010F0(key, 0, 10):
int __cdecl sub_4010F0(int *a1, int a2, int num_10) |
研究一下就会发现是个从小到大的排序。
则解密脚本如下:
import base64 |
flag{UJWP1jMp}
rsa
打开来两个文件,公钥密文都有,解密脚本如下:
from Crypto.PublicKey import RSA |
flag{decrypt_256}
参考:
CrackRTF
IDA打开,追踪字符串到主要函数:
int main_0() |
输入两次验证flag。
第一次
hash值在线爆破,直接得第一部分123321,进入第二部分
D:\CTF\Games\Exam\BUUCTF\CrackRTF>CrackRTF.exe |
第二次
无法爆破,观察到sub_40100F函数中:
char __cdecl sub_4014D0(LPCSTR lpString) |
会生成一个dbapp.rtf文件。
随便输入123321得,此处用010editor打开:
在生成文件前sub_401005进行了异或操作:
unsigned int __cdecl sub_401420(LPCSTR lpString, int a2, int a3) |
则可以逆解出异或因子:
s = [0x34,0x4f,0x72,0x26,0x14,0x30,0x5c,0x61,0x6e,0x73,0x69,0x5c,0x61,0x6e,0x73,0x69,0x63,0x70,0x28,0x2a,0x33,0x64,0x2e,0x65,0x65,0x66,0x66,0x30,0x5c,0x64,0x65,0x66,0x6c,0x61,0x6e,0x67,0x7e,0x23,0x33,0x61,0x2e,0x65,0x65,0x66,0x6c,0x61,0x6e,0x67,0x66,0x65,0x32,0x30,0x35,0x32,0x34,0x4f,0x66,0x3d,0x1c,0x75,0x74,0x62,0x6c,0x7b,0x5c,0x66,0x30,0x5c,0x66,0x6d,0x6f,0x64,0x2a,0x61,0x6e,0x0e,0x14,0x71,0x72,0x71,0x36,0x5c,0x66,0x63,0x68,0x61,0x72,0x73,0x65,0x74,0x7e,0x20,0x34,0x72,0x2e,0x26,0x63,0x62,0x5c,0x27,0x63,0x65,0x5c,0x27,0x63,0x63,0x5c,0x27,0x2a,0x26,0x3b,0x2f,0x0f,0x0c,0x0a,0x7b,0x5c,0x2a,0x5c,0x67,0x65,0x6e,0x65,0x72,0x61,0x74,0x20,0x61,0x20,0x1f,0x01,0x67,0x74,0x65,0x64,0x69,0x74,0x20,0x35,0x2e,0x34,0x31,0x2e,0x31,0x7a,0x3d,0x31,0x67,0x43,0x34,0x3b,0x7d,0x5c,0x76,0x69,0x65,0x77,0x6b,0x69,0x6e,0x64,0x34,0x13,0x66,0x63,0x63,0x2e,0x71,0x61,0x72,0x64,0x5c,0x6c,0x61,0x6e,0x67,0x32,0x30,0x35,0x32,0x13,0x75,0x30,0x0e,0x14,0x72,0x32,0x30,0x20,0x46,0x6c,0x61,0x67,0x5c,0x7b,0x4e,0x30,0x5f,0x02,0x23,0x72,0x37,0x2d,0x47,0x72,0x65,0x65,0x5f,0x42,0x75,0x67,0x73,0x5c,0x7d,0x5c,0x70,0x2e,0x61,0x0d,0x58,0x0f,0x0c,0x0a,0x00] |
在本地新建RTF文件,可知文件头6位应该为”{\\rtf1“
,则可解出第二次输入的字符:
key = map(ord, "{\\rtf1") |
为:~!3a@0
输入得最终rtf文件,里面就有flag,为:
Flag{N0_M0re_Free_Bugs}(提交时要将F改为f
)
crackMe
解压得crackMe.exe,打开:
Come one! Crack Me~~~ |
user已经给出,为welcomebeijing
输入后:
password(6-16 letters or numbers): |
IDA打开,跟踪字符串到主要函数,根据经验稍做修改:
int __usercall wmain@<eax>(int a1@<ebx>) |
由调试分析得:
init_box函数会将user进行一波操作生成一个box用于后面的异或操作。
可以直接导出,但后面其实没必要用到。
init_print函数会初始化两个输出字符串,一个成功一个失败,但由于有异常花指令导致IDA无法识别为函数,根据分析,直接将异常nop掉就可以了
.text:003E11EA 0 nop |
接着就重要的check函数:
bool __cdecl check(char *user, const char *password) |
根据调试,输入的password会每两个为一组(第一个while就是在将输入转为两个为一组的十六进制字符),来与box中的特定位置的数异或,得到一组8个key,后进入check2进行验证,最终得到check_num == 43924
则成功。
check2:
_DWORD *__usercall check2@<eax>(int a1@<ebx>, _BYTE *key, _DWORD *a3) |
由分析可知,key应该为:key = [100, 98, 97, 112, 112, 115, 101, 99]
,即dbappsec
(本来key[5]可能值为115或102但前面由做过以dbappsec为密钥的题,便猜测为dbappsec)
接着,根据调试可知,xor函数是将key和user每位对应异或。
接着在调试中将box参与异或的位数提取出来,即可,但解出来本地输入就错误,故猜测下面这两处地方将异或操作进行了类似于反调试的操作,故将这两处直接nop掉
if ( *(_DWORD *)(__readfsdword(0x30u) + 104) & 0x70 ) |
if ( *(_DWORD *)(__readfsdword(0x30u) + 2) & 0xFF ) |
最终得到解密脚本:
key = [100, 98, 97, 112, 112, 115, 101, 99] |
得到:39d09ffa4cfcc4cc
本地输入不会出现Please try again
则猜测通过,但md532位小写hash加密后提交却不对,陷入自闭。
后用cmd打开crackMe.exe发现39d09ffa4cfcc4cc
是错误的!
故用cmd直接打开,用IDA attach上去调试,xor数组不变但原程序中xor函数中不执行异或操作,实际毫无效果。
因为调试直接跳过,就没有注意到下面会因为窗口的不同而不同,还是tcl…..
StartupInfo.dwX |
最终解密脚本为:
key = [100, 98, 97, 112, 112, 115, 101, 99] |
得到第二个密码4EB5F3992391A1AE
user(6-16 letters or numbers):welcomebeijing |
之后进行md5加密后提交,得正确flag:
flag{d2be2981b84f2a905669995873d6a36c}
findit
下载下来是个apk文件,就直接jeb打开,根据字符串找到主要函数:
protected void onCreate(Bundle arg8) { |
观察后发现解题方法有2:
1.逆推出输入
2.复现flag生成过程
我这里采用第2种,脚本如下:
flag = "pvkq{m164675262033l4m49lnp7p9mnk28k75}" |
得flag:
flag{c164675262033b4c49bdf7f9cda28a75}
新年快乐
IDA打开, UPX壳, 官方工具直接脱
重新打开,直接能看到flag
得flag:
flag{HappyNewYear!}
内涵的软件
IDA打开直接看到flag
得flag:
flag{49d3c93df25caad81232130f3d2ebfad}
xor
IDA打开,简单的异或题
python脚本:
s = [0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11, 0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F, 0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F, 0x47, 0x32, 0x4F] |
得到flag:
flag{QianQiuWanDai_YiTongJiangHu}
reverse3
IDA打开简单的加密
import base64 |
得到flag:
flag{i_l0ve_you}
SimpleRev
WSL子系统运行不了,file
一下是ELF 64-bit LSB
程序
IDA打开,主要逻辑如下
unsigned __int64 Decry() |
爆破脚本:
text = bytearray(b"killshadow") |
得到flag
flag{KLDQCUDFZO}
不一样的flag
主逻辑在main中,根据经验,是一道典型的迷宫题
int __cdecl main(int argc, const char **argv, const char **envp) |
迷宫在_data_start__中:
.data:00402000 __data_start__ db '*', '1', '1', '1', '1' |
因为是小迷宫,手走一遍就可以了:222441144222
即flag:
flag{222441144222}
Java逆向解密
XJad直接打开
// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov. |
主逻辑也很简单,将输入加上 64 ^ 0x20
,最后对比KEY
解密脚本:
key = [180, 136, 137, 147, 191, 137, 147, 191, 148, 136, |
得flag:
flag{This_is_the_flag_!}
简单注册机
用JEB 3打开,发现主要判断如下
这里有两种解法
- 直接构造输入
4b40000000000000000000000000000000a
,0
为任意字符,即可让app直接输出flag - 直接用python模拟flag生成流程
v5 = bytearray(b"dd2940c84462b4dd7c450528835cca15") |
得flag
flag{59acc538825054c7de4b26440c0999dd}
- 还是直接构造输入快….
[GXYCTF2019]luck_guy
IDA打开发现getflag()
函数
解密脚本:
f1 = "GXY{do_not_" |
换一下外包装,得flag:
flag{do_not_hate_me}
Pwn
jarvisoj_level0
基础栈溢出, 直接溢出到 backdoor 就可以了
exp如下
from pwn import * |
jarvisoj_level2
基础栈溢出, 没有后门函数但是有system
函数, 且 IDA 搜索字符串有/bin/sh
.data:0804A024 hint db '/bin/sh',0 |
那么思路就是栈溢出到system, 且布局栈中有参数 /bin/sh
的地址就可以 getshell 了
exp如下
from pwn import * |
0ctf 2017 babyheap
Crypto
MD5
https://www.cmd5.com/ 直接查得admin1
则flag为flag{admin1}
Url编码
https://tool.oschina.net/encode?type=4 解得 flag{and 1=1}
一眼就解密
base64 解得 flag{THE_FLAG_OF_THIS_STRING}
看我回旋踢
简单的移位密码, ROT13, 解得flag flag{5cd1004d-86a5-46d8-b720-beb5ba0417e1}
变异凯撒
观察知前四位分别与flag
相差5,6,7,8
则有
s = b"afZ_r9VYfScOeO_UL^RWUc" |
得flagflag{Caesar_variation}
Quoted-printable
http://web.chacuo.net/charsetquotedprintable 得flag{那你也很棒哦}
password
UTF-8 编码, 脑洞猜flag: flag{zs19900315}
rsarsa
import gmpy2 |
得flag flag{5577446633554466577768879988}
Rabbit
用Rabbit解密得flagflag{Cute_Rabbit}
RSA
import gmpy2 |
得flag: flag{125631357777427553}
Windows系统密码
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: |
linux的passwd文件,用https://www.cmd5.com/解密得good-luck
, 则flag: flag{good-luck}
Alice与Bob
http://factordb.com/index.php?query=98554799767 查得两个素数为101999
和966233
, 则
import hashlib |
得flag: flag{d450209323a847c8d01c6be47c81811a}
篱笆墙的影子
栅栏密码, 加密向量为2, 得到flagflag{wethinkwehavetheflag}
老文盲了
罼雧締眔擴灝淛匶襫黼瀬鎶軄鶛驕鳓哵眔鞹鰝 |
秀上天际, 生僻字谐音, flag为BJD{淛匶襫黼瀬鎶軄鶛驕鳓哵}
大帝的密码武器
凯撒密码, FRPHEVGL
通过加密向量13
解出SECURITY
则flag为flag{PbzrPuvan}