BaseCTF W2
RE
UPX!
如题,upx壳
尝试用upx快速脱壳失败,推测存在特征值修改
使用010打开i确认存在,将upx改回UPX
再次利用upx -d快速脱壳成功
用DIE检测,壳已消失
IDA打开,主函数逻辑很简单,关键在于b64函数
打开b64函数,自定义base64
码表在map中,逐步检查可找到
自定义b64解出
lk
运行之,二次元(gal?)浓度鉴定
DIE查之无壳,直接IDA
根据主函数末尾这一段ifelse的输出可以断定flag存储在668数组中
668数组数据并没有静态存储,而是由输入的答案组成
答案的验证部分在if的判断条件里,巨量算式
z3启动!
from z3 import *
# 定义内存地址和字节值
byte_14000A668 = [Int('byte_14000A668[%d]' % i) for i in range(21)]
# 转换条件表达式
exprs = [
(948 * byte_14000A668[20]
+ 887 * byte_14000A668[19]
+ 410 * byte_14000A668[18]
+ 978 * byte_14000A668[17]
+ 417 * byte_14000A668[16]
+ 908 * byte_14000A668[15]
+ 965 * byte_14000A668[14]
+ 987 * byte_14000A668[13]
+ 141 * byte_14000A668[12]
+ 257 * byte_14000A668[11]
+ 323 * byte_14000A668[10]
+ 931 * byte_14000A668[9]
+ 773 * byte_14000A668[8]
+ 851 * byte_14000A668[7]
+ 758 * byte_14000A668[6]
+ 891 * byte_14000A668[5]
+ 575 * byte_14000A668[4]
+ 616 * byte_14000A668[3]
+ 860 * byte_14000A668[2]
+ 283 * byte_14000A668[1]) == 913686,
(938 * byte_14000A668[20]
+ 490 * byte_14000A668[19]
+ 920 * byte_14000A668[18]
+ 50 * byte_14000A668[17]
+ 568 * byte_14000A668[16]
+ 68 * byte_14000A668[15]
+ 35 * byte_14000A668[14]
+ 708 * byte_14000A668[13]
+ 938 * byte_14000A668[12]
+ 718 * byte_14000A668[11]
+ 589 * byte_14000A668[10]
+ 954 * byte_14000A668[9]
+ 974 * byte_14000A668[8]
+ 62 * byte_14000A668[7]
+ 580 * byte_14000A668[6]
+ 80 * byte_14000A668[5]
+ 111 * byte_14000A668[4]
+ 151 * byte_14000A668[3]
+ 421 * byte_14000A668[2]
+ 148 * byte_14000A668[1] ) == 630335,
(908 * byte_14000A668[20]
+ 590 * byte_14000A668[19]
+ 668 * byte_14000A668[18]
+ 222 * byte_14000A668[17]
+ 489 * byte_14000A668[16]
+ 335 * byte_14000A668[15]
+ 778 * byte_14000A668[14]
+ 622 * byte_14000A668[13]
+ 95 * byte_14000A668[12]
+ 920 * byte_14000A668[11]
+ 932 * byte_14000A668[10]
+ 892 * byte_14000A668[9]
+ 409 * byte_14000A668[8]
+ 392 * byte_14000A668[7]
+ 11 * byte_14000A668[6]
+ 113 * byte_14000A668[5]
+ 948 * byte_14000A668[4]
+ 674 * byte_14000A668[3]
+ 506 * byte_14000A668[2]
+ 182 * byte_14000A668[1]) == 707525,
(479 * byte_14000A668[20]
+ 859 * byte_14000A668[19]
+ 410 * byte_14000A668[18]
+ 399 * byte_14000A668[17]
+ 891 * byte_14000A668[16]
+ 266 * byte_14000A668[15]
+ 773 * byte_14000A668[14]
+ 624 * byte_14000A668[13]
+ 34 * byte_14000A668[12]
+ 479 * byte_14000A668[11]
+ 465 * byte_14000A668[10]
+ 728 * byte_14000A668[9]
+ 447 * byte_14000A668[8]
+ 427 * byte_14000A668[7]
+ 890 * byte_14000A668[6]
+ 570 * byte_14000A668[5]
+ 716 * byte_14000A668[4]
+ 180 * byte_14000A668[3]
+ 571 * byte_14000A668[2]
+ 707 * byte_14000A668[1]) == 724203,
(556 * byte_14000A668[20]
+ 798 * byte_14000A668[19]
+ 380 * byte_14000A668[18]
+ 716 * byte_14000A668[17]
+ 71 * byte_14000A668[16]
+ 901 * byte_14000A668[15]
+ 949 * byte_14000A668[14]
+ 304 * byte_14000A668[13]
+ 142 * byte_14000A668[12]
+ 679 * byte_14000A668[11]
+ 459 * byte_14000A668[10]
+ 814 * byte_14000A668[9]
+ 282 * byte_14000A668[8]
+ 49 * byte_14000A668[7]
+ 873 * byte_14000A668[6]
+ 169 * byte_14000A668[5]
+ 437 * byte_14000A668[4]
+ 199 * byte_14000A668[3]
+ 771 * byte_14000A668[2]
+ 807 * byte_14000A668[1]) == 688899,
(465 * byte_14000A668[20]
+ 898 * byte_14000A668[19]
+ 979 * byte_14000A668[18]
+ 198 * byte_14000A668[17]
+ 156 * byte_14000A668[16]
+ 831 * byte_14000A668[15]
+ 856 * byte_14000A668[14]
+ 322 * byte_14000A668[13]
+ 25 * byte_14000A668[12]
+ 35 * byte_14000A668[11]
+ 369 * byte_14000A668[10]
+ 917 * byte_14000A668[9]
+ 522 * byte_14000A668[8]
+ 654 * byte_14000A668[7]
+ 235 * byte_14000A668[6]
+ 385 * byte_14000A668[5]
+ 469 * byte_14000A668[4]
+ 231 * byte_14000A668[3]
+ 496 * byte_14000A668[2]
+ 83 * byte_14000A668[1]) == 604784,
(305 * byte_14000A668[20]
+ 928 * byte_14000A668[19]
+ 260 * byte_14000A668[18]
+ 793 * byte_14000A668[17]
+ 787 * byte_14000A668[16]
+ 708 * byte_14000A668[15]
+ 758 * byte_14000A668[14]
+ 236 * byte_14000A668[13]
+ 688 * byte_14000A668[12]
+ 747 * byte_14000A668[11]
+ 711 * byte_14000A668[10]
+ 195 * byte_14000A668[9]
+ 50 * byte_14000A668[8]
+ 648 * byte_14000A668[7]
+ 787 * byte_14000A668[6]
+ 376 * byte_14000A668[5]
+ 220 * byte_14000A668[4]
+ 33 * byte_14000A668[3]
+ 194 * byte_14000A668[2]
+ 585 * byte_14000A668[1]) == 665485,
(767 * byte_14000A668[20]
+ 573 * byte_14000A668[19]
+ 22 * byte_14000A668[18]
+ 909 * byte_14000A668[17]
+ 598 * byte_14000A668[16]
+ 588 * byte_14000A668[15]
+ 136 * byte_14000A668[14]
+ 848 * byte_14000A668[12]
+ 964 * byte_14000A668[11]
+ 311 * byte_14000A668[10]
+ 701 * byte_14000A668[9]
+ 653 * byte_14000A668[8]
+ 541 * byte_14000A668[7]
+ 443 * byte_14000A668[6]
+ 7 * byte_14000A668[5]
+ 976 * byte_14000A668[4]
+ 803 * byte_14000A668[3]
+ 273 * byte_14000A668[2]
+ 859 * byte_14000A668[1]) == 727664,
(776 * byte_14000A668[20]
+ 59 * byte_14000A668[19]
+ 507 * byte_14000A668[18]
+ 164 * byte_14000A668[17]
+ 397 * byte_14000A668[16]
+ 744 * byte_14000A668[15]
+ 377 * byte_14000A668[14]
+ 768 * byte_14000A668[13]
+ 456 * byte_14000A668[12]
+ 799 * byte_14000A668[11]
+ 9 * byte_14000A668[10]
+ 215 * byte_14000A668[9]
+ 365 * byte_14000A668[8]
+ 181 * byte_14000A668[7]
+ 634 * byte_14000A668[6]
+ 818 * byte_14000A668[5]
+ 81 * byte_14000A668[4]
+ 236 * byte_14000A668[3]
+ 883 * byte_14000A668[2]
+ 95 * byte_14000A668[1]) == 572015,
(873 * byte_14000A668[20]
+ 234 * byte_14000A668[19]
+ 381 * byte_14000A668[18]
+ 423 * byte_14000A668[17]
+ 960 * byte_14000A668[16]
+ 689 * byte_14000A668[15]
+ 617 * byte_14000A668[14]
+ 240 * byte_14000A668[13]
+ 933 * byte_14000A668[12]
+ 300 * byte_14000A668[11]
+ 998 * byte_14000A668[10]
+ 773 * byte_14000A668[9]
+ 484 * byte_14000A668[8]
+ 905 * byte_14000A668[7]
+ 806 * byte_14000A668[6]
+ 792 * byte_14000A668[5]
+ 606 * byte_14000A668[4]
+ 942 * byte_14000A668[3]
+ 422 * byte_14000A668[2]
+ 789 * byte_14000A668[1]) == 875498,
(766 * byte_14000A668[20]
+ 7 * byte_14000A668[19]
+ 283 * byte_14000A668[18]
+ 900 * byte_14000A668[17]
+ 211 * byte_14000A668[16]
+ 305 * byte_14000A668[15]
+ 343 * byte_14000A668[14]
+ 696 * byte_14000A668[13]
+ 590 * byte_14000A668[12]
+ 736 * byte_14000A668[11]
+ 817 * byte_14000A668[10]
+ 603 * byte_14000A668[9]
+ 414 * byte_14000A668[8]
+ 828 * byte_14000A668[7]
+ 114 * byte_14000A668[6]
+ 845 * byte_14000A668[5]
+ 175 * byte_14000A668[4]
+ 212 * byte_14000A668[3]
+ 898 * byte_14000A668[2]
+ 988 * byte_14000A668[1]) == 714759,
(220 * byte_14000A668[20]
+ 30 * byte_14000A668[19]
+ 788 * byte_14000A668[18]
+ 106 * byte_14000A668[17]
+ 574 * byte_14000A668[16]
+ 501 * byte_14000A668[15]
+ 366 * byte_14000A668[14]
+ 952 * byte_14000A668[13]
+ 121 * byte_14000A668[12]
+ 996 * byte_14000A668[11]
+ 735 * byte_14000A668[10]
+ 689 * byte_14000A668[9]
+ 998 * byte_14000A668[8]
+ 689 * byte_14000A668[7]
+ 729 * byte_14000A668[6]
+ 886 * byte_14000A668[5]
+ 860 * byte_14000A668[4]
+ 70 * byte_14000A668[3]
+ 466 * byte_14000A668[2]
+ 961 * byte_14000A668[1]) == 778853,
(313 * byte_14000A668[20]
+ 748 * byte_14000A668[19]
+ 522 * byte_14000A668[18]
+ 864 * byte_14000A668[17]
+ 156 * byte_14000A668[16]
+ 362 * byte_14000A668[15]
+ 283 * byte_14000A668[14]
+ 49 * byte_14000A668[13]
+ 316 * byte_14000A668[12]
+ 79 * byte_14000A668[11]
+ 136 * byte_14000A668[10]
+ 299 * byte_14000A668[9]
+ 271 * byte_14000A668[8]
+ 604 * byte_14000A668[7]
+ 907 * byte_14000A668[6]
+ 540 * byte_14000A668[5]
+ 141 * byte_14000A668[4]
+ 620 * byte_14000A668[3]
+ 701 * byte_14000A668[2]
+ 866 * byte_14000A668[1]) == 584591,
(922 * byte_14000A668[20]
+ 399 * byte_14000A668[19]
+ 425 * byte_14000A668[18]
+ 26 * byte_14000A668[17]
+ 159 * byte_14000A668[16]
+ 224 * byte_14000A668[15]
+ 438 * byte_14000A668[14]
+ 770 * byte_14000A668[13]
+ 144 * byte_14000A668[12]
+ 406 * byte_14000A668[11]
+ 110 * byte_14000A668[10]
+ 991 * byte_14000A668[9]
+ 749 * byte_14000A668[8]
+ 701 * byte_14000A668[7]
+ 646 * byte_14000A668[6]
+ 147 * byte_14000A668[5]
+ 979 * byte_14000A668[4]
+ 674 * byte_14000A668[3]
+ 999 * byte_14000A668[2]
+ 913 * byte_14000A668[1]) == 717586,
(13 * byte_14000A668[20]
+ 537 * byte_14000A668[19]
+ 225 * byte_14000A668[18]
+ 421 * byte_14000A668[17]
+ 153 * byte_14000A668[16]
+ 484 * byte_14000A668[15]
+ 654 * byte_14000A668[14]
+ 743 * byte_14000A668[13]
+ 779 * byte_14000A668[12]
+ 74 * byte_14000A668[11]
+ 325 * byte_14000A668[10]
+ 439 * byte_14000A668[9]
+ 797 * byte_14000A668[8]
+ 41 * byte_14000A668[7]
+ 784 * byte_14000A668[6]
+ 269 * byte_14000A668[5]
+ 454 * byte_14000A668[4]
+ 725 * byte_14000A668[2]
+ 164 * byte_14000A668[1]) == 537823,
( 591 * byte_14000A668[20]
+ 210 * byte_14000A668[19]
+ 874 * byte_14000A668[18]
+ 204 * byte_14000A668[17]
+ 485 * byte_14000A668[16]
+ 42 * byte_14000A668[15]
+ 433 * byte_14000A668[14]
+ 176 * byte_14000A668[13]
+ 436 * byte_14000A668[12]
+ 634 * byte_14000A668[11]
+ 82 * byte_14000A668[10]
+ 978 * byte_14000A668[9]
+ 818 * byte_14000A668[8]
+ 683 * byte_14000A668[7]
+ 404 * byte_14000A668[6]
+ 562 * byte_14000A668[5]
+ 41 * byte_14000A668[4]
+ 789 * byte_14000A668[3]
+ 200 * byte_14000A668[2]
+ 220 * byte_14000A668[1]) == 587367,
(584 * byte_14000A668[20]
+ 597 * byte_14000A668[19]
+ 928 * byte_14000A668[18]
+ 532 * byte_14000A668[17]
+ 902 * byte_14000A668[16]
+ 858 * byte_14000A668[15]
+ 820 * byte_14000A668[14]
+ 240 * byte_14000A668[13]
+ 124 * byte_14000A668[12]
+ 899 * byte_14000A668[11]
+ 848 * byte_14000A668[10]
+ 822 * byte_14000A668[9]
+ 409 * byte_14000A668[8]
+ 491 * byte_14000A668[7]
+ 587 * byte_14000A668[6]
+ 715 * byte_14000A668[5]
+ 410 * byte_14000A668[4]
+ 268 * byte_14000A668[3]
+ 721 * byte_14000A668[2]
+ 915 * byte_14000A668[1]) == 842245,
(421 * byte_14000A668[20]
+ 302 * byte_14000A668[19]
+ 327 * byte_14000A668[18]
+ 180 * byte_14000A668[17]
+ 512 * byte_14000A668[16]
+ 160 * byte_14000A668[15]
+ 623 * byte_14000A668[14]
+ 28 * byte_14000A668[13]
+ 411 * byte_14000A668[12]
+ 53 * byte_14000A668[11]
+ 633 * byte_14000A668[10]
+ 560 * byte_14000A668[9]
+ 623 * byte_14000A668[8]
+ 477 * byte_14000A668[7]
+ 901 * byte_14000A668[6]
+ 287 * byte_14000A668[5]
+ 149 * byte_14000A668[4]
+ 726 * byte_14000A668[3]
+ 934 * byte_14000A668[2]
+ 875 * byte_14000A668[1] ) == 610801,
(838 * byte_14000A668[20]
+ 434 * byte_14000A668[19]
+ 792 * byte_14000A668[18]
+ 649 * byte_14000A668[17]
+ 462 * byte_14000A668[16]
+ 170 * byte_14000A668[15]
+ 980 * byte_14000A668[14]
+ 15 * byte_14000A668[13]
+ 295 * byte_14000A668[12]
+ 495 * byte_14000A668[11]
+ 666 * byte_14000A668[10]
+ 934 * byte_14000A668[9]
+ 17 * byte_14000A668[8]
+ 69 * byte_14000A668[7]
+ 367 * byte_14000A668[6]
+ 780 * byte_14000A668[5]
+ 291 * byte_14000A668[4]
+ 834 * byte_14000A668[3]
+ 587 * byte_14000A668[2]
+ 133 * byte_14000A668[1] ) == 653127,
(41 * byte_14000A668[20]
+ 422 * byte_14000A668[19]
+ 420 * byte_14000A668[18]
+ 224 * byte_14000A668[17]
+ 475 * byte_14000A668[16]
+ 854 * byte_14000A668[15]
+ 233 * byte_14000A668[14]
+ 179 * byte_14000A668[13]
+ 620 * byte_14000A668[12]
+ 69 * byte_14000A668[11]
+ 42 * byte_14000A668[10]
+ 684 * byte_14000A668[9]
+ 300 * byte_14000A668[8]
+ 745 * byte_14000A668[7]
+ 894 * byte_14000A668[6]
+ 554 * byte_14000A668[5]
+ 495 * byte_14000A668[4]
+ 66 * byte_14000A668[3]
+ 316 * byte_14000A668[2]
+ 391 * byte_14000A668[1]) == 533470
]
# 创建一个求解器
solver = Solver()
# 将表达式添加到求解器中
for expr in exprs:
solver.add(expr)
# 检查是否有解
if solver.check() == sat:
# 如果有解,打印出解
model = solver.model()
for i in range(20):
print(f"byte_14000A668[{i}] = {model[byte_14000A668[i]]}")
else:
print("No solution found.")
约束求解得:
还原为字符即可得到flag
感觉非预期...
MISC-SOCIAL ENGINEERING
Aura旅行日记-4
识图得到夫子庙景区
BaseCTF{江苏省南京市秦淮区夫子庙景区}
Aura旅行日记-5
第一张明显是室内环境,大概率为陈列馆/纪念馆
小红薯找到照片可作证
第二张照片谜底写在谜面上,邓小平铜像广场
BaseCTF{四川省广安市广安区邓小平故里-邓小平铜像广场and邓小平故居陈列馆}
缅怀🕯
Aura旅行日记-6
关键信息-迎泽派出所
搜索小红薯关键词 迎泽 中学
找到学校,太原五中
BaseCTF{山西省太原市迎泽区青年路49号太原市第五中学校-建校时间1906}
Aura旅行日记-7
BaseCTF W3
ezAndroid
用GDA打开,快速定位到MainActivity
关键部分在onConfirmButtonClick内
可以看到在按下按钮(存疑,我没跑)后,会从一个名字为flag的文件里读取flagBytes,再将输入的字符串用Base64encode方法加密后与其进行比较,若匹配则输出yess。
众所周知,apk本质上就是zip包
将其后缀修改为zip,可在其中的assets文件夹内找到flag文件
可以确认是hex数据,密文找到
接下来就是加密部分,使用cyberchef尝试后可以确认这里的”Base64encode“只是个幌子,实际上并不是base64
在zip内定位到该apk的so库,使用IDA进行分析
定位到Base64encode
这显然不是base64,再省去头尾一大段的地址操作,看do while循环内的加密部分
v5 = (*(__int64 (__fastcall **)(__int64, __int64))(*(_QWORD *)a1 + 0x558LL))(a1, a3);
v6 = (*(__int64 (__fastcall **)(__int64, __int64, _QWORD))(*(_QWORD *)a1 + 0x5C0LL))(a1, a3, 0LL);
v7 = operator new[](v5);
v8 = (void *)v7;
if ( v5 >= 1 )
{
v9 = 0LL;
v10 = (unsigned int)v5;
v11 = (char *)v6;
v12 = (_BYTE *)v7;
v13 = (char *)&unk_E2D9;
do
{
v14 = v9++;
v15 = *v11++;
--v10;
v16 = v13[4294967284 * (v14 / 12)];
++v13;
*v12++ = v16 ^ v15;
}
while ( v10 );
}
这里嗯看其实很难得看出来,直接凭直觉从异或开始分析比较容易,
*v12++ =v16^v15
一路往上推可以发现*v12最终指向v5,而v5操作地址,因此大概率是加密结果
同理v15可以猜测与明文有关,剩下v16。
v16是由从v13中元素按照索引每12个就回到开头来组成的,继续往上可以定位到&unk_E2D9
再rodata段找到unk_E2D9的内容,长度为12,侧面证明猜测
那么这就是密钥了
cyberchef一下即可解出
世界上最简单的题目
没什么可说的,把抽象变量名替换掉后看,就是一个简单的异或加密,添加了一个a1表。
题目:
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
a1 =[1 ,1 ,1 ,3 ,1 ,1 ,1 ,3 ,1 ,1 ,1 ,3 ,1 ,1 ,3 ,1 ,1 ,3 ,1 ,1 ,3 ,1 ,3 ,1 ,3 ,1 ,3 ]#line:6
f1 =[101 ,102 ,117 ,120 ,119 ,108 ,102 ,124 ,100 ,109 ]#line:7
def o1 ():#line:13
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
return input ("please input your flag: ")#line:14
def p1 (O0O0OOOOO00OOOOO0 ):#line:20
return list (O0O0OOOOO00OOOOO0 )#line:21
def main ():#line:27
OO0O0O00O00O00OO0 =o1 ()#line:28
O0OOOO0O0O0O0OOOO =1 #line:29
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
O00OOO0OO0000OO00 =0 #line:30
if len (OO0O0O00O00O00OO0 )!=len (f1 ):#line:36
print ("Input length does not match.")#line:37
exit ()#line:38
OOO00OOO0000OO0O0 =p1 (OO0O0O00O00O00OO0 )#line:44
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
for O0O0OOO00O000000O in range (len (a1 )):#line:50
if a1 [O0O0OOO00O000000O ]==1 :#line:51
OOO00OOO0000OO0O0 [O00OOO0OO0000OO00 ]=chr (ord (OOO00OOO0000OO0O0 [O00OOO0OO0000OO00 ])^O0OOOO0O0O0O0OOOO )#line:57
O0OOOO0O0O0O0OOOO +=1 #line:58
elif a1 [O0O0OOO00O000000O ]==3 :#line:59
O00OOO0OO0000OO00 +=1 #line:60
for O0OOOOOO000000OOO in range (len (f1 )):#line:66
if f1 [O0OOOOOO000000OOO ]!=ord (OOO00OOO0000OO0O0 [O0OOOOOO000000OOO ]):#line:67
print ("nooooo")#line:68
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# #免费的50分,复制粘贴直接秒杀!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
exit ()#line:69
print ("yes, your flag is")#line:75
print ("BaseCTF{"+''.join (OO0O0O00O00O00OO0 )+"}")#line:76
if __name__ =="__main__":#line:82
main ()#line:83
exp(上):
#include<stdio.h>
int main()
{
int enc[10]={101 ,102 ,117 ,120 ,119 ,108 ,102 ,124 ,100 ,109};
for(int i=0;i<=9;i++)
{
printf("%c",enc[i]);
}
return 0;
}
我也不知道为什么我要用C++写一半换Python..大概是因为原题能直接用吧?
exp(下):
a1 =[1 ,1 ,1 ,3 ,1 ,1 ,1 ,3 ,1 ,1 ,1 ,3 ,1 ,1 ,3 ,1 ,1 ,3 ,1 ,1 ,3 ,1 ,3 ,1 ,3 ,1 ,3 ]#line:6
f1 =[101 ,102 ,117 ,120 ,119 ,108 ,102 ,124 ,100 ,109 ]
def o1 ():#line:13
return input ("please input your flag: ")#line:14
def p1 (samp ):#line:20
return list (samp )#line:21
def main ():#line:27
src =o1 ()#line:28
one =1 #line:29
zero =0 #line:30
####长度检查##########
if len (src )!=len (f1 ):#line:36
print ("Input length does not match.")#line:37
exit ()#line:38
#########加密函数########
enc =p1 (src )#line:44
for i in range (len (a1 )):#line:50
if a1 [i ]==1 :#line:51
enc [zero ]=chr (ord (enc [zero ])^one )#line:57
one +=1 #line:58
elif a1 [i ]==3 :#line:59
zero +=1 #line:60
print(enc)
if __name__ =="__main__":#line:82
main ()#line:83
密文转成字符串后直接输入即可获得flag
出题人已疯
.Net逆向
用dnSpy打开,快速定位到MainWindow
关键部分:
private void Btn_Submit_Click(object sender, RoutedEventArgs e)
{
char[] array = this.Tb_Input.Text.ToCharArray();
char[] array2 = string.Join("", this.sentences).ToCharArray();
for (int i = 0; i < array.Length; i++)
{
array[i] *= array[i];
array[i] = (char)((int)array[i] ^ i ^ (int)array2[i % array2.Length]);
}
uint[] source = new uint[]
{
24164U,
27173U,
32145U,
17867U,
40533U,
21647U,
17418U,
30032U,
27950U,
62998U,
60750U,
64870U,
52680U,
61797U,
49234U,
59762U,
16704U,
19200U,
32132U,
24038U,
21764U,
30130U,
28113U,
23070U,
27413U,
27917U,
28938U,
50207U,
64834U,
60132U,
64832U,
63334U,
55103U,
22176U,
21991U,
20073U,
22281U,
19476U,
28302U,
24336U,
24720U,
19544U,
23018U,
43976U
};
bool flag = new string(array) != new string((from c in source
select (char)c).ToArray<char>());
if (flag)
{
MessageBox.Show("\ud83d\ude2d我有异或症!");
}
else
{
MessageBox.Show("\ud83d\ude0b异或症好了!");
}
}
// Token: 0x04000001 RID: 1
public string[] sentences = new string[]
{
"你以为我还会在乎吗?\ud83d\ude2c\ud83d\ude2c\ud83d\ude2c我在昆仑山练了六年的剑\ud83d\ude1f\ud83d\ude1f\ud83d\ude1f我的心早就和昆仑山的雪一样冷了\ud83d\ude10\ud83d\ude10\ud83d\ude10我在大润发杀了十年的鱼\ud83d\ude2b\ud83d\ude2b\ud83d\ude2b我以为我的心早已跟我的刀一样冷了\ud83d\ude29\ud83d\ude29\ud83d\ude29",
"我早上坐公交滴卡的时候和司机大叔说“两个人”,司机惊讶地看着我“你明明就是一个人,为什么要滴两个人的卡?”我回他,“我心中还有一个叫Kengwang的。”司机回我说,“天使是不用收钱的。”",
"(尖叫)(扭曲)(阴暗的爬行)(扭动)(阴暗地蠕动)(翻滚)(激烈地爬动)(痉挛)(嘶吼)(蠕动)(阴森的低吼)(爬行)(分裂)(走上岸)(扭曲的行走)(不分对象攻击)",
"地球没我照样转?硬撑罢了!地球没我照样转?硬撑罢了!地球没我照样转?硬撑罢了!地球没我照样转?硬撑罢了!地球没我照样转?硬撑罢了!地球没我照样转?硬撑罢了!",
"扭曲上勾拳!阴暗的下勾拳!尖叫左勾拳!右勾拳爬行!扭动扫堂腿!分裂回旋踢!这是蜘蛛阴暗的吃耳屎,这是龙卷风翻滚停车场!乌鸦痉挛!老鼠嘶吼!大象蠕动!愤怒的章鱼!无差别攻击!无差别攻击!无差别攻击!"
};
// Token: 0x04000002 RID: 2
public byte[] title = new byte[]
{
250,
81,
152,
152,
186,
78,
242,
93,
175,
117,
27,
103,
104,
84,
229,
119
};
// Token: 0x04000003 RID: 3
internal Label Lb_Title;
// Token: 0x04000004 RID: 4
internal TextBlock Tb_Description;
// Token: 0x04000005 RID: 5
internal TextBox Tb_Input;
// Token: 0x04000006 RID: 6
internal Button Btn_Submit;
// Token: 0x04000007 RID: 7
private bool _contentLoaded;
}
看逻辑很简单,就是从sentences中取索引为i取余其长度的元素与明文和i进行异或,再与source中进行比较,因此source即为密文,sentences即为key表,依次逻辑编写exp:
#include<bits/stdc++.h>
int main()
{
uint32_t enc[44] = {
24164U,
27173U,
32145U,
17867U,
40533U,
21647U,
17418U,
30032U,
27950U,
62998U,
60750U,
64870U,
52680U,
61797U,
49234U,
59762U,
16704U,
19200U,
32132U,
24038U,
21764U,
30130U,
28113U,
23070U,
27413U,
27917U,
28938U,
50207U,
64834U,
60132U,
64832U,
63334U,
55103U,
22176U,
21991U,
20073U,
22281U,
19476U,
28302U,
24336U,
24720U,
19544U,
23018U,
43976U
};
long long int counter=0;
unsigned char sentences[2000] ="你以为我还会在乎吗?😬😬😬我在昆仑山练了六年的剑😟😟😟我的心早就和昆仑山的雪一样冷了😐😐😐我在大润发杀了十年的鱼😫😫😫我以为我的心早已跟我的刀一样冷了😩😩😩我早上坐公交滴卡的时候和司机大叔说“两个人”,司机惊讶地看着我“你明明就是一个人,为什么要滴两个人的卡?”我回他,“我心中还有一个叫Kengwang的。”司机回我说,“天使是不用收钱的。”(尖叫)(扭曲)(阴暗的爬行)(扭动)(阴暗地蠕动)(翻滚)(激烈地爬动)(痉挛)(嘶吼)(蠕动)(阴森的低吼)(爬行)(分裂)(走上岸)(扭曲的行走)(不分对象攻击)地球没我照样转?硬撑罢了!地球没我照样转?硬撑罢了!地球没我照样转?硬撑罢了!地球没我照样转?硬撑罢了!地球没我照样转?硬撑罢了!地球没我照样转?硬撑罢了!扭曲上勾拳!阴暗的下勾拳!尖叫左勾拳!右勾拳爬行!扭动扫堂腿!分裂回旋踢!这是蜘蛛阴暗的吃耳屎,这是龙卷风翻滚停车场!乌鸦痉挛!老鼠嘶吼!大象蠕动!愤怒的章鱼!无差别攻击!无差别攻击!无差别攻击!";
while (sentences[counter]!='\0') {
counter++;
}
printf("%lld\n",counter);
for(int i = 0; i < 44; i++)
{
enc[i] =char(int(enc[i])^ i ^ int(sentences[i % counter]));
// enc[i]/=enc[i];
printf("%c", enc[i]);
}
return 0;
}
不知道哪里出问题了,猜测是中文编码读入问题导致sentences索引&长度不对
Dont-Debug-Me
反调试,nop掉两处if即可
image-20240904055840953
![image-20240904060550695]