ISCC2017 writeup

WEB

Web签到题,来和我换flag啊!

ISCC2017 writeup_第1张图片

输两个f1ag还不够,看他的回复有个FLAG,尝试加一个,成功得到flag
ISCC2017 writeup_第2张图片

WelcomeToMySQL

打开是一个上传界面,上传一个马试试,发现.php被过滤不允许上传
ISCC2017 writeup_第3张图片

直接后缀改成.php5上传成功,菜刀链接
ISCC2017 writeup_第4张图片

在相应地方发现提示,数据库密码
ISCC2017 writeup_第5张图片

链接成功,数据库发现密码
ISCC2017 writeup_第6张图片

自相矛盾


$v1=0;$v2=0;$v3=0;
$a=(array)json_decode(@$_GET['iscc']); 

if(is_array($a)){
    is_numeric(@$a["bar1"])?die("nope"):NULL;
    if(@$a["bar1"]){
        ($a["bar1"]>2016)?$v1=1:NULL;
    }
    if(is_array(@$a["bar2"])){
        if(count($a["bar2"])!==5 OR !is_array($a["bar2"][0])) die("nope");
        $pos = array_search("nudt", $a["bar2"]);
        $pos===false?die("nope"):NULL;
        foreach($a["bar2"] as $key=>$val){
            $val==="nudt"?die("nope"):NULL;
        }
        $v2=1;

    }    
}
$c=@$_GET['cat'];
$d=@$_GET['dog'];
if(@$c[1]){
    if(!strcmp($c[1],$d) && $c[1]!==$d){

        eregi("3|1|c",$d.$c[0])?die("nope"):NULL;
        strpos(($c[0].$d), "isccctf2017")?$v3=1:NULL;

    }

}
if($v1 && $v2 && $v3){ 

   echo 12;
}
?>

可以根据他的代码直接构造
首先需要定义一个jason对象,首先第一个为bar1要求不是全数字且大于2016,简单,赋值为2017a即可,这里用到了PHP弱类型的一个特性,当一个整形和一个其他类型行比较的时候,会先把其他类型intval再比。第二个是bar2要求其是一个长度为5的数组,重点来了。

$pos = array_search("nudt", $a["bar2"]);
        $pos===false?die("nope"):NULL;
        foreach($a["bar2"] as $key=>$val){
            $val==="nudt"?die("nope"):NULL;
        }

这两个其实是互相矛盾的,如何绕过?这时利用第一个"nudt"字符串与0弱类型比较相等,就可以绕过,方法:“bar2”:[[1],2,3,4,0]
后面arraystring进行strcmp比较的时候会返回一个nulleregi直接用%00截断即可
最终构造
iscc={"bar1":"2017a","bar2":[[1],2,3,4,0]}&cat[1][]=1&dog=%00&cat[0]=0isccctf2017
ISCC2017 writeup_第7张图片

我们一起来日站

打开,直接用御剑扫一下目录好了
这里写图片描述

访问,得到下一层目录
ISCC2017 writeup_第8张图片

访问,要求找admin页面
ISCC2017 writeup_第9张图片

直接admin.php,得到界面
ISCC2017 writeup_第10张图片

抓包,结果测试的时候就得到flag,还以为是什么sql注入呢
ISCC2017 writeup_第11张图片

I have a jpg,i upload a txt.

先分析一下源码,发现没什么具体的漏洞,不过有个加密解密的函数,看看能不能逆出来


include 'hanshu.php';
if(isset($_GET['do']))
{
    $do=$_GET['do'];
    if($do==upload)
    {
        if(empty($_FILES))
        {
            $html1=<<
                             
            
            
HTML1;
            echo $html1;
        }
        else
        {   $file=@file_get_contents($_FILES["filename"]["tmp_name"]);
            if(empty($file))
            {
                die('do you upload a file?');
            }
            else
            {
                if((strpos($file,')>-1)||(strpos($file,'?>')>-1)||(stripos($file,'php')>-1)||(stripos($file,')>-1)||(stripos($file,')>-1))
                {
                    die('you can\' upload this!');
                }
                else
                {
                    $rand=mt_rand();
                    $path='/var/www/html/web-03/uploads/'.$rand.'.txt';
                    file_put_contents($path, $file);
                    echo 'your upload success!./uploads/'.$rand.'.txt';
                }
            }

        }

    }
    elseif($do==rename)
    {
        if(isset($_GET['re']))
        {
            $re=$_GET['re'];
            $re2=@unserialize(base64_decode(unKaIsA($re,6)));
            if(is_array($re2))
            {
                if(count($re2)==2)
                {   
                    $rename='txt';
                    $rand=mt_rand();
                    $fp=fopen('./uploads/'.$rand.'.txt','w');
                    foreach($re2 as $key=>$value)
                    {
                        if($key==0)
                        {
                            $rename=$value;
                        }
                        else
                        {
                            if(file_exists('./uploads/'.$value.'.txt')&&is_numeric($value))
                            {
                                $file=file_get_contents('./uploads/'.$value.'.txt');
                                fwrite($fp,$file);
                            }
                        }
                    }
                    fclose($fp);
                    waf($rand,$rename);
                    rename('./uploads/'.$rand.'.txt','./uploads/'.$rand.'.'.$rename);
                    echo "you success rename!./uploads/$rand.$rename";
                }
            }
            else
            {
                echo 'please not hack me!';
            }
        }
        elseif(isset($_POST['filetype'])&&isset($_POST['filename']))
        {
            $filetype=$_POST['filetype'];
            $filename=$_POST['filename'];
            if((($filetype=='jpg')||($filetype=='png')||($filetype=='gif'))&&is_numeric($filename))
            {   
                $re=KaIsA(base64_encode(serialize(array($filetype,$filename))),6);
                header("Location:index.php?do=rename&re=$re");
                exit();
            }
            else
            {
                echo 'you do something wrong';
            }
        }
        else
        {
            $html2=<<          
filetype:  please input the your file's type

filename: please input your file's numeric name,like 12345678
HTML2;
echo $html2; } } } else { show_source(__FILE__); } ?>

首先随便上传一个文件
ISCC2017 writeup_第12张图片

利用文中的机制本地测试一下,发现是大写字母+6小写字母-6
脚本


    function KaIsA($text,$j)
    {
        echo $text."
"
; for($i=0; $i < strlen($text); $i++) { $te = ord($text[$i]); //echo $te."
";
if($te <=90 && $te >=65) { $te += $j; if($te > 90 ) { $te = $te - 26; } } else if($te >=97 && $te <=122) { $te -= $j; if($te < 97) { $te = $te + 26; } } $text[$i] = chr($te); } echo $text."
"
; return $text; } //$a[1]='728032523'; //$a[2]='53858205'; //$f1=base64_encode(serialize($a)); //KaIsA($f1,6); $filename = '1909367105'; $filetype = 'php'; $re2 = KaIsA(base64_encode(serialize(array($filetype,$filename))),6); ?>

这样的话可以任意的更改后缀,好,现在就要开始上传一句话木马,由于有很强的绕过,但是代码中只要绕过key==0就可以两次上传两个文件进行fwrite拼接
定义一个数组,使第一位值空,然后后两位放两个文件,利用自己做的加密脚本加密,直接do=rename&re=字符串
拼接完以后改下后缀名,访问即可
ISCC2017 writeup_第13张图片

ISCC2017 writeup_第14张图片

ISCC2017 writeup_第15张图片

where is your flag

打开这个界面,其他没有发现异常之处
ISCC2017 writeup_第16张图片

猜测是sql注入的题,先测试一下
一开始测试id,结果发现消失,看来id是注入点
但之后无论怎么尝试都没见回显,一开始以为都被过滤,但后来经测试不是,猜测可能是'被转义了
ISCC2017 writeup_第17张图片

果真报错了,直接利用报错注入即可
这里写图片描述

这里写图片描述

在这里需要分片一下
ISCC2017 writeup_第18张图片

ISCC2017 writeup_第19张图片

不过其实还有简单的,通过扫目录发现有个flag.php有句提示
ISCC2017 writeup_第20张图片

这都已经说明了hisisflag是列名,flag是表名

反正得到flag
flag:flag:{441b7fa1617307be9632263a4497871e}

Simple sqli

直接username=' union select md5(1)#
password=1
然后验证码碰一个就好,出来flag

MISC

眼见非实

下载下来是一个.docx文件,但通过分析,改成.zip打开,在document.xml中发现flag
这里写图片描述

ISCC2017 writeup_第21张图片

很普通的Disco

是一段音频,直接看波形,发现最前面隐藏了一段,猜测有问题
ISCC2017 writeup_第22张图片

差不多有105个点,可以是7的倍数,猜测是ascii
高位为1,低位为0,写出来,7位一组,直接转换
脚本


a = ['1100110',
'1101100',
'1100001',
'1100111',
'1111011',
'1010111',
'110000',
'1010111',
'101010',
'1100110',
'1110101',
'1101110',
'1101110',
'1111001',
'1111101']
flag = ''
for i in a:
    #print i
    flag += chr(int(i,2))
print flag

这里写图片描述

再见李华

一开始是一张图片,用binwalk分析发现里面有一个zip压缩包,抠出来解压缩时发现需要密码
一开始真心不知道密码怎么解,想过爆破,不过后来仔细看题还是发现隐藏的hint,说是大于1000字,且落款为LiHua,也就是密码大致为????LiHua这样的话,尝试一下掩码爆破,直接出来
ISCC2017 writeup_第23张图片

就在其中

是一个数据包,分析一下,发现是用ftp下载文件
其中是一个key.txt的压缩包,解压缩是密文
ISCC2017 writeup_第24张图片

里面还有公钥私钥

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0UN0A+70iM0VCJ1ni0n/U1BRj
0u8yMWH4Qi+xTbjHgbE7wOukOaO+2PyQXiqIzZnf5jCkJuVDYjALGcKrZM4OCQBB
d85B/LTc36XZ7JVfX5kGy5tIR3tquuPIVKNdAsHlSqh9S7YSS39RdnSa5rOUyGhr
LzxwzzM9IO4e+QQ+CQIDAQAB
-----END PUBLIC KEY-----

-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQD0UN0A+70iM0VCJ1ni0n/U1BRj0u8yMWH4Qi+xTbjHgbE7wOuk
OaO+2PyQXiqIzZnf5jCkJuVDYjALGcKrZM4OCQBBd85B/LTc36XZ7JVfX5kGy5tI
R3tquuPIVKNdAsHlSqh9S7YSS39RdnSa5rOUyGhrLzxwzzM9IO4e+QQ+CQIDAQAB
AoGADiaw5mGubtCxbkeBOVYf+V/fXnjVSf76QbrzsD1kOooUjfV6sKR2C5Pd7S7H
H+1owENBBgEKvoBtb/cqA2tvU9vQ4l5TMBJcHv6LEcb9WPpnMxPV2GNjO+DTPGPy
Xnu1UZlZjwx+NaF5rESoSSVS2ZaaIixBs4RWRXk+lHEbTFECQQD6Rp6jMweRgPHO
pR3mgIK83zL+kzqYM5isIPv3DIC5JQN2kXqK73IDQCFVlfXnr9lAAVRzLDsAXLqv
le/o6yQLAkEA+edY+GERlLuD1t2k9Js0Dc7EwnLcxoFUE60ivj8Gf9jzLskGHxsv
0IV6J5OHwPh54kAxAnqCjSqNRAWGNzr+uwJBALYEjDUm1LdGrxXZ0jAkgHC6Z0zs
aK3uwHdXGcinqCp+t9EQpq3KzQF+L4AeKxRQONEq5m9I2LQ/vGocwrmD4dcCQQDb
rTyOinWz8upAFPKOe2hUwvA/pkzgyosoCMhDyI9kD0gmVlvlODbd7Jem9o8dWM97
zcXHUf41LbSkmN6U6m1FAkEAqmZbr35bPfkeoiikwNl6OVQytg12TZjw2vIbvfub
f9Rvti8Lh/tbrmhZroiz8/l3aAZmugI1NBcbeZR0gz8ggg==
-----END RSA PRIVATE KEY-----

直接利用openssl解密就行
这里写图片描述

-in指定被加密的文件,-inkey指定私钥文件,-out为解密后的文件。

ISCC2017 writeup_第25张图片

很普通的数独

下载下来居然有25张图片。。。猜测肯定是拼成一张二维码,就看怎么拼。。。试了试,直接 55 排列发现有数字的地方涂黑就行
没有什么方法,只能利用表格默默的涂黑
这里有个坑就是他的二维码3个角需要根据二维码的特点调换下顺序
ISCC2017 writeup_第26张图片

扫出来一堆字符

Vm0xd1NtUXlWa1pPVldoVFlUSlNjRlJVVGtOamJGWnlWMjFHVlUxV1ZqTldNakZIWVcxS1IxTnNhRmhoTVZweVdWUkdXbVZHWkhOWGJGcHBWa1paZWxaclpEUmhNVXBYVW14V2FHVnFRVGs9

一看就是base64解密,还好几层,解就行
flag:flag{y0ud1any1s1}

basic

Wheel Cipher

加密表:
1:    < ZWAXJGDLUBVIQHKYPNTCRMOSFE <
2:    < KPBELNACZDTRXMJQOYHGVSFUWI <
3:    < BDMAIZVRNSJUWFHTEQGYXPLOCK <
4:    < RPLNDVHGFCUKTEBSXQYIZMJWAO <
5:    < IHFRLABEUOTSGJVDKCPMNZQWXY <
6:    < AMKGHIWPNYCJBFZDRUSLOQXVET <
7:    < GWTHSPYBXIZULVKMRAFDCEONJQ <
8:    < NOZUTWDCVRJLXKISEFAPMYGHBQ <
9:    < XPLTDSRFHENYVUBMCQWAOIKZGJ <
10:   < UDNAJFBOWTGVRSCZQKELMXYIHP <
11:  < MNBVCXZQWERTPOIUYALSKDJFHG <
12:  < LVNCMXZPQOWEIURYTASBKJDFHG <
13:  < JZQAWSXCDERFVBGTYHNUMKILOP <

密钥为:2,3,7,5,13,12,9,1,8,10,4,11,6
密文为:NFQKSEVOQOFNP

既然是车轮,看来需要轮换,一开始以为是将密文对应密钥位置进行替换,发现不对,查了查发现Jefferson wheel cipher(杰弗逊转轮加密器),差不多重新排一下序,并把密文转到第一个位置,发现flag:FIREINTHEHOLE
ISCC2017 writeup_第27张图片

公邮密码

。。。不知道这题是让干啥的,直接纯暴力密码,还非常短的密码
ISCC2017 writeup_第28张图片

然后是base64加密,直接解码就好
flag:Flag:{Ly319.i5d1f*iCult!}

你猜猜。。

下载下来得到一串数字。。。感觉有点像16进制,但转码得不到什么实质性的东西,突然发现开头是504B,是.zip的头,估计就是文件的16进制
保存为zip格式,结果有密码,爆破吧
ISCC2017 writeup_第29张图片

得到flag:daczcasdqwdcsdzasd

神秘图片

打开时一张图片,利用binwalk分析
ISCC2017 writeup_第30张图片

发现另一张图片,抠出来
ISCC2017 writeup_第31张图片

明显是猪圈密码,对应即可
flag:goodluck

告诉你个秘密

得到两串字符

636A56355279427363446C4A49454A7154534230526D6843
56445A31614342354E326C4B4946467A5769426961453067

一看就很像16进制,转一下字符

cjV5RyBscDlJIEJqTSB0RmhC
VDZ1aCB5N2lKIFFzWiBiaE0g

似乎可以base64解密,试一下

r5yG lp9I BjM tFhB
T6uh y7iJ QsZ bhM

这里卡了有段时间,后来发现似乎跟键盘有关,围成圈
flag:TONGYUAN

说我作弊,需要证据

通过提示,明显就是RSA的解密
首先看下下载的数据包文件,发现全是base64加密过的,解密发现有三个部分
ISCC2017 writeup_第32张图片

SEQ有顺序,那明显就是最后的字符顺序
DATA明显是需要解密的密文
DATA是发送给Bob的实际密文,使用Bob的公钥对DATA进行了加密。所以先使用factor-db并解出私钥来解密数据。
一开始不知道SIG的作用,后来查资料发现是RSA的签名,利用Alice的公钥对数据进行一次签名验证
懒省事,直接写了一个大脚本

import base64

def iterative_egcd(a, b):
    x,y, u,v = 0,1, 1,0
    while a != 0:
        q,r = b//a,b%a; m,n = x-u*q,y-v*q # use x//y for floor "floor division"
        b,a, x,y, u,v = a,r, u,v, m,n
    return b, x, y

def modinv(a, m):
    g, x, y = iterative_egcd(a, m) 
    if g != 1:
        return None
    else:
        return x % m

def base_convert():
    f = open('C:\\Users\\lanlan\\Desktop\\out.txt','w+')

    with open('C:\\Users\\lanlan\\Desktop\\1.txt') as lines:
        for line in lines:
            line = base64.b64decode(line)
            f.write(line+'\n')

    f.close()

def sort():
    with open('C:\\Users\\lanlan\\Desktop\\out.txt') as lines:
        line = lines.read()
        f = open('C:\\Users\\lanlan\\Desktop\\outstream.txt','w+')
        for i in range(0,34):
            index = 0
            for j in range(1,10):
                b = line.find('SEQ = {};'.format(i),index)
                if b == -1:
                    break
                c = line.find('L;',b+55)
                str = line[b:c+1]
                f.write(str+'\n')
                #print str
                index = b+1
        f.close()

def flag():
    with open('C:\\Users\\lanlan\\Desktop\\outstream.txt') as lines:
        B_p = 49662237675630289
        B_q = 62515288803124247
        B_s = (B_p-1)*(B_q-1)
        B_n = 3104649130901425335933838103517383

        A_p = 38456719616722997
        A_q = 44106885765559411
        A_n = 1696206139052948924304948333474767

        e = 0x10001
        d = modinv(e,B_s)

        da = []
        si = []
        for line in lines:
            begin_num = line.find('DATA')
            end_num = line.find('L')
            data = line[begin_num + 7: end_num]
            #print data
            data_c = int(data,16)
            data_m = pow(data_c,d,B_n)
            da.append(data_m)
            #print data_m,

            begin_n = line.find('SIG')
            sig = line[begin_n + 6:-2]
            #print sig
            sig_c = int(sig,16)
            sig_m = pow(sig_c,e,A_n)
            si.append(sig_m)
            #print sig_m,
    #print da
    #print si
    flag = ''
    for i in xrange(148):
        #print i,da[i],si[i]
        if da[i] == si[i]:
            flag += chr(da[i])
    print flag

if __name__ == '__main__':
    base_convert()
    sort()
    flag()

flag:flag{n0th1ng_t0_533_h3r3_m0v3_0n}

二维码

首先下载下来是一个二维码,用binwalk分析
ISCC2017 writeup_第33张图片

发现藏了一个zip文件,还是加密的,直接暴力
ISCC2017 writeup_第34张图片

得到一个hint和一个数据包
首先发开数据包发现是一个无线的协议,估计要破解wifi密码,利用aircrack-ng工具
ISCC2017 writeup_第35张图片

果真发现一个,首先利用hint:前四位是ISCC 后四位由大写字母和数字构成生成一个字典
脚本

import itertools
import string

hex_chars = '0123456789'+string.ascii_uppercase

print hex_chars

wordlist = open('C:\\Users\\lanlan\\Desktop\\wordlist','a')

for words in itertools.product(hex_chars,repeat=4):
    wordlist.write('ISCC' + ''.join(words) + '\n')

然后直接利用工具跑出flag:ISCC16BA
ISCC2017 writeup_第36张图片

PHP_encrypt_1

下载是一个加密脚本


function encrypt($data,$key)
{
    $key = md5('ISCC');
    $x = 0;
    $len = strlen($data);
    $klen = strlen($key);
    for ($i=0; $i < $len; $i++) { 
        if ($x == $klen)
        {
            $x = 0;
        }
        $char .= $key[$x];
        $x+=1;
    }
    for ($i=0; $i < $len; $i++) {
        $str .= chr((ord($data[$i]) + ord($char[$i])) % 128);
    }
    return base64_encode($str);
}
?>

解密脚本


    function decrypt($str)
    {
        $key = md5("ISCC");
        $str = base64_decode($str);
        $len = strlen($str);
        $x = 0;
        for($i=0; $i < $len; $i++)
        {
            if($x == 32)
            {
                $x = 0;
            }
            $char .= $key[$x];
            $x +=1;
        }
        for($i=0; $i < $len; $i++)
        {
            if((ord($str[$i])-ord($char[$i])) <= 0)
                $data .= chr((ord($str[$i])+128-ord($char[$i])));
            else
                $data .= chr((ord($str[$i])-ord($char[$i])));
        }
        echo $data.'
'
; } $mi = 'fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA='; decrypt($mi); ?>

python脚本方便

import base64
import string

def decrypt(str):
    data = ""
    char1 = ""
    str = base64.b64decode(str)
    #print str
    key = '729623334f0aa2784a1599fd374c120d'
    len1 = len(str)
    klen = len(key)
    x = 0
    #print len1,klen

    for i in range(0,len1):
        if x == klen:
            x = 0
        char1 += key[x]
        x = x+1
    #print char1
    for i in range(0,len1):
        if (ord(str[i])-ord(char1[i])) <= 0:
            data += chr((ord(str[i])+128-ord(char1[i])))
        else:
            data += chr((ord(str[i])-ord(char1[i])))
    print data

if __name__ == '__main__':
    a = 'fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA='
    decrypt(a)

flag:Flag:{asdqwdfasfdawfefqwdqwdadwqadawd}

Reverse

你猜

直接IDA反编译
主函数

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  __int64 result; // rax@3
  __int64 v4; // rdx@7
  char v5; // [sp+10h] [bp-10h]@4
  __int64 v6; // [sp+18h] [bp-8h]@1

  v6 = *MK_FP(__FS__, 40LL);
  if ( a1 != 3 && (unsigned int)sub_400646((__int64)a2) )
  {
    puts("Keep thinking!");
    result = 0LL;
  }
  else
  {
    printf("Please input your password(5 words):", a2, a2);
    __isoc99_scanf("%5s", &v5);
    if ( (unsigned int)sub_400755((__int64)&v5) == 1 )
    {
      printf("Good Job!\nThe password:%s", &v5);
      result = 0LL;
    }
    else
    {
      puts("Wrong!");
      result = 0LL;
    }
  }
  v4 = *MK_FP(__FS__, 40LL) ^ v6;
  return result;
}

首先是第一个函数的判定,必须返回0

signed __int64 __fastcall sub_400646(__int64 a1)
{
  signed __int64 result; // rax@3
  __int64 v2; // rcx@12
  signed int i; // [sp+18h] [bp-48h]@1
  signed int j; // [sp+1Ch] [bp-44h]@6
  int v5; // [sp+20h] [bp-40h]@1
  int v6; // [sp+24h] [bp-3Ch]@1
  int v7; // [sp+28h] [bp-38h]@1
  int v8; // [sp+2Ch] [bp-34h]@1
  int v9; // [sp+30h] [bp-30h]@1
  int v10; // [sp+40h] [bp-20h]@1
  int v11; // [sp+44h] [bp-1Ch]@1
  int v12; // [sp+48h] [bp-18h]@1
  int v13; // [sp+4Ch] [bp-14h]@1
  int v14; // [sp+50h] [bp-10h]@1
  __int64 v15; // [sp+58h] [bp-8h]@1

  v15 = *MK_FP(__FS__, 40LL);
  puts(*(const char **)(a1 + 8));
  v5 = 108;
  v6 = 49;
  v7 = 110;
  v8 = 117;
  v9 = 120;
  v10 = 99;
  v11 = 114;
  v12 = 97;
  v13 = 99;
  v14 = 107;
  for ( i = 0; i <= 4; ++i )
  {
    if ( *(_BYTE *)(*(_QWORD *)(a1 + 8) + i) != *(&v5 + i) )
    {
      result = 1LL;
      goto LABEL_12;
    }
  }
  for ( j = 0; j <= 4; ++j )
  {
    if ( *(_BYTE *)(*(_QWORD *)(a1 + 16) + j) != *(&v10 + j) )
    {
      result = 1LL;
      goto LABEL_12;
    }
  }
  result = 0LL;
LABEL_12:
  v2 = *MK_FP(__FS__, 40LL) ^ v15;
  return result;
}

很简单,10个字符意义对应即可
l1nux,crack
然后第二个函数

__int64 __usercall sub_400755@(__int64 a1@)
{
  __int64 result; // rax@6

  if ( *(_BYTE *)a1 + *(_BYTE *)(a1 + 4) != 106 || *(_BYTE *)a1 != 73 )
  {
    result = 0LL;
  }
  else if ( *(_BYTE *)(a1 + 1) == 76 )
  {
    result = *(_BYTE *)(a1 + 2) + *(_BYTE *)(a1 + 3) == 137 && *(_BYTE *)(a1 + 3) == 70;
  }
  else
  {
    result = 0LL;
  }
  return result;
}

简单的逻辑
ILCF!
综上,flag:flag{l1nux_crack_ILCF!}

小试牛刀

这题需要在gdb中动态调试看一下,直接看IDA的话,一些字符串看的不是很清楚,结合gdb 之后就很清楚了。 代码逻辑就是将已知的一个flag,进行一些移位变换,并将其中的_ 改为 . ,然后就得到了最终真正的flag: flag{1t.is.5O.easy}

大杂烩

首先PEID,32位无壳程序,丢到IDA中看看逻辑:
ISCC2017 writeup_第37张图片

前面对注册表的操作都不用管,其实最关键的就是这个函数 sub_401210,跟进去:

int __usercall sub_401210@(char *a1@)
{ 
    wchar_t *v1; // eax@1 
    char *v2; // ecx@1 
    __int16 v3; // dx@2 
    wchar_t *v4; // eax@9 
    wchar_t *v5; // eax@11 
    unsigned int v6; // eax@11 
    wchar_t *v7; // eax@12 
    wchar_t *v8; // eax@13 
    int result; // eax@14 

    v1 = (wchar_t *)unknown_libname_1(0x32u); 
    v2 = a1; 
    // 这块代码没有什么意义,没有改变字符串 
    do 
    { 
      v3 = *(_WORD *)v2; 
      *(_WORD *)&v2[(char *)v1 ‐ a1] = *(_WORD *)v2; 
      v2 += 2; 
    } 
    while ( v3 ); 
    result = 0; 
    // flag长为25位,并且形式是flag{xxx_x_xxxx_xxxxxxxx} 
    if ( wcslen(v1) == 25 && '{' == v1[4] && '_' == v1[8] && '_' == v1[10] && '_' == v1[15] && '}' == v1[24] )
    { 
      wcstok(v1, L"{_}"); 
      v4 = wcstok(0, L"{_}"); 
      if ( *(_DWORD *)v4 == 6815860 && 52 == v4[4] ) 
      { 
         v5 = wcstok(0, L"{_}");
         // 数字型字符串转为整数 
         v6 = wtoi(v5); 
         if ( v6 >> 1 == v6 ‐ 2 )  // 3,4都可以,根据52 == v4[4]可以具体判断 
         { 
           v7 = wcstok(0, L"{_}"); 
           if ( sub_401000(v7) ) 
           { 
             v8 = wcstok(0, L"{_}"); 
             if ( sub_401180(v8) ) 
               result = 1; 
           } 
         } 
       } 
     } 
     return result; 
}

首先确定flag的形式为 flag{xxx_x_xxxx_xxxxxxxx},然后根据wcstok将其分割为四个小部分,分别进行判断,最后还有一位是无法判断的,猜测吧,最后给出flag: flag{thx_4_your_register}

你可能感兴趣的:(WriteUp)