Hacker101 CTF Android challenges write up(一)
字数 1842 2025-08-22 12:23:00

Hacker101 CTF Android挑战解析与解题思路

1. H1 Thermostat挑战

1.1 应用概述

  • 这是一个温度计应用,包含温度显示面板和调节功能
  • 提示有两处flag需要发现

1.2 静态分析

  1. Activity分析

    • 唯一Activity:ThermostatActivity
    • 关键代码位于com.hacker101.level11包下
  2. Flag发现

    • 搜索flag关键词发现两处关键代码:
      // Flag 1
      messageDigest.update("^FLAG^911074676b0d1ed58ba09ca5755930daf7266886bbcf32ca8f785f6e5c631eb9$FLAG$".getBytes());
      
      // Flag 2
      this.mHeaders.put("X-Flag", "^FLAG^ab34de7822af3f9f75b311e0dcca2d1db34b5e63aa4fbb7386696a547405405a$FLAG$");
      
  3. 网络请求分析

    • PayloadRequest类处理网络请求
    • 请求URL:https://d7299d*****4704859cc2cc8382.ctf.hacker101.com/
    • 请求参数:
      • "d":buildPayload(JSONObject)的结果
      • "X-MAC":MD5("^FLAG^...\(FLAG\)" + buildPayload)的Base64编码
      • "X-Flag":明文flag

1.3 动态分析

  1. 请求流程

    • setDefaults()方法初始化温度并发送请求
    • 请求成功后回调更新温度值
  2. 抓包发现

    • 可以直接从X-Flag头获取第二个flag
    • 第一个flag需要从代码中获取MD5前的原始值

1.4 解题步骤

  1. 直接查看代码中的两处flag定义
  2. 验证flag:
    • 911074676b0d1ed58ba09ca5755930daf7266886bbcf32ca8f785f6e5c631eb9
    • ab34de7822af3f9f75b311e0dcca2d1db34b5e63aa4fbb7386696a547405405a

2. Intentional Exercise挑战

2.1 应用概述

  • 单一界面应用,包含一个"Flag"按钮
  • 点击按钮显示"Invalid request"

2.2 静态分析

  1. 关键代码

    Uri data = getIntent().getData();
    String str = "https://09f0e1735ea21fef3ae3c1578d677f09.ctf.hacker101.com/appRoot";
    String str2 = BuildConfig.FLAVOR;
    
    if (data != null) {
        str2 = data.toString().substring(28);
        str = str + str2;
    }
    
    if (!str.contains("?")) {
        str = str + "?";
    }
    
    MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
    messageDigest.update("s00p3rs3cr3tk3y".getBytes(StandardCharsets.UTF_8));
    messageDigest.update(str2.getBytes(StandardCharsets.UTF_8));
    webView.loadUrl(str + "&hash=" + String.format("%064x", new BigInteger(1, messageDigest.digest())));
    
  2. 哈希生成逻辑

    • 使用SHA-256算法
    • 哈希输入:"s00p3rs3cr3tk3y" + str2
    • str2为URL路径部分(去除前28个字符)

2.3 动态分析

  1. 正常流程

    • 点击Flag按钮请求URL:ctf.hacker101.com/appRoot/flagBearer
    • 响应:"Invalid request"
  2. 抓包发现

    • 需要正确的hash参数才能获取flag
    • hash = SHA256("s00p3rs3cr3tk3y/flagBearer")

2.4 解题方法

方法1:计算正确hash

  1. 计算字符串"s00p3rs3cr3tk3y/flagBearer"的SHA256哈希
  2. 将结果作为hash参数附加到URL
    https://.../appRoot/flagBearer?&hash=<calculated_hash>
    

方法2:使用ADB命令

  1. 通过ADB命令直接启动带有正确路径的Activity:
    adb shell am start -W -a "android.intent.action.VIEW" -d "http://level13.hacker101.com/flagBearer" com.hacker101.level13
    

3. Oauthbreaker挑战

3.1 应用概述

  • 单一界面,包含"认证"按钮
  • 点击后跳转浏览器进行OAuth认证
  • 认证成功后返回应用显示"成功验证"

3.2 静态分析

MainActivity关键代码:

  1. onCreate方法

    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.activity_main);
        this.authRedirectUri = "oauth://final/";
    
        try {
            Uri data = getIntent().getData();
            if (data != null && data.getQueryParameter("redirect_uri") != null) {
                this.authRedirectUri = data.getQueryParameter("redirect_uri");
            }
        } catch (Exception unused) {
        }
    
        this.button = (Button) findViewById(R.id.button);
        this.button.setOnClickListener(this);
    }
    
  2. onClick方法

    public void onClick(View view) {
        if (view.getId() != R.id.button) {
            return;
        }
    
        String str = null;
        try {
            str = "https://0b6**ded40f29af68fb3b108c.ctf.hacker101.com/oauth?redirect_url=" + 
                  URLEncoder.encode(this.authRedirectUri, StandardCharsets.UTF_8.toString()) + 
                  "login&response_type=token&scope=all";
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    
        Intent intent = new Intent("android.intent.action.VIEW");
        intent.setData(Uri.parse(str));
        startActivity(intent);
    }
    

BrowserActivity关键代码:

public void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    setContentView(R.layout.activity_browser);
    
    String str = "https://0b65afadf874ded40f29af68fb3b108c.ctf.hacker101.com/authed";
    
    try {
        Uri data = getIntent().getData();
        if (data != null && data.getQueryParameter("uri") != null) {
            str = data.getQueryParameter("uri");
        }
    } catch (Exception unused) {
    }
    
    WebView webView = (WebView) findViewById(R.id.webview);
    webView.setWebViewClient(new SSLTolerentWebViewClient(webView));
    webView.getSettings().setJavaScriptEnabled(true);
    webView.addJavascriptInterface(new WebAppInterface(getApplicationContext()), "iface");
    webView.loadUrl(str);
}

WebAppInterface关键方法:

@JavascriptInterface
public String getFlagPath() {
    String str = "";
    try {
        byte[] bArr = new byte[32];
        new SecureRandom().nextBytes(bArr);
        MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
        messageDigest.update(bArr);
        str = Hex.encodeHexString(messageDigest.digest()) + ".html";
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return str;
}

3.3 解题步骤

Flag 1获取:

  1. 修改redirect_url参数为"oauth://final/login"
  2. 访问修改后的OAuth URL
  3. 从响应中获取token形式的flag

Flag 2获取:

  1. 利用WebView的JavaScript接口
  2. 调用getFlagPath()方法获取flag路径
  3. 计算得到路径:48ce217fea4529a070a9d3e3c87db512b1596d413e580f7b2e1eab65f3948ab8.html
  4. 拼接完整URL访问获取flag

4. 通用解题技巧总结

  1. 静态分析优先

    • 使用Jadx等工具反编译APK
    • 搜索关键词如"flag"、"secret"等
    • 重点关注网络请求相关代码
  2. 动态分析辅助

    • 使用抓包工具分析网络请求
    • 监控Intent跳转和数据传递
    • 观察WebView加载行为
  3. 常见漏洞点

    • 硬编码的凭证或flag
    • 不安全的WebView配置(如启用JavaScript)
    • 不完善的输入验证
    • 不安全的Intent处理
  4. ADB命令使用

    • 通过ADB命令触发特定Intent
    • 测试不同URI和参数组合
  5. 加密哈希分析

    • 识别代码中的哈希算法(MD5、SHA等)
    • 分析哈希输入构造方式
    • 必要时重新实现哈希计算逻辑
Hacker101 CTF Android挑战解析与解题思路 1. H1 Thermostat挑战 1.1 应用概述 这是一个温度计应用,包含温度显示面板和调节功能 提示有两处flag需要发现 1.2 静态分析 Activity分析 : 唯一Activity:ThermostatActivity 关键代码位于com.hacker101.level11包下 Flag发现 : 搜索flag关键词发现两处关键代码: 网络请求分析 : PayloadRequest类处理网络请求 请求URL: https://d7299d*****4704859cc2cc8382.ctf.hacker101.com/ 请求参数: "d":buildPayload(JSONObject)的结果 "X-MAC":MD5("^FLAG^...$FLAG$" + buildPayload)的Base64编码 "X-Flag":明文flag 1.3 动态分析 请求流程 : setDefaults()方法初始化温度并发送请求 请求成功后回调更新温度值 抓包发现 : 可以直接从X-Flag头获取第二个flag 第一个flag需要从代码中获取MD5前的原始值 1.4 解题步骤 直接查看代码中的两处flag定义 验证flag: 911074676b0d1ed58ba09ca5755930daf7266886bbcf32ca8f785f6e5c631eb9 ab34de7822af3f9f75b311e0dcca2d1db34b5e63aa4fbb7386696a547405405a 2. Intentional Exercise挑战 2.1 应用概述 单一界面应用,包含一个"Flag"按钮 点击按钮显示"Invalid request" 2.2 静态分析 关键代码 : 哈希生成逻辑 : 使用SHA-256算法 哈希输入:"s00p3rs3cr3tk3y" + str2 str2为URL路径部分(去除前28个字符) 2.3 动态分析 正常流程 : 点击Flag按钮请求URL: ctf.hacker101.com/appRoot/flagBearer 响应:"Invalid request" 抓包发现 : 需要正确的hash参数才能获取flag hash = SHA256("s00p3rs3cr3tk3y/flagBearer") 2.4 解题方法 方法1:计算正确hash 计算字符串"s00p3rs3cr3tk3y/flagBearer"的SHA256哈希 将结果作为hash参数附加到URL 方法2:使用ADB命令 通过ADB命令直接启动带有正确路径的Activity: 3. Oauthbreaker挑战 3.1 应用概述 单一界面,包含"认证"按钮 点击后跳转浏览器进行OAuth认证 认证成功后返回应用显示"成功验证" 3.2 静态分析 MainActivity关键代码: onCreate方法 : onClick方法 : BrowserActivity关键代码: WebAppInterface关键方法: 3.3 解题步骤 Flag 1获取: 修改redirect_ url参数为"oauth://final/login" 访问修改后的OAuth URL 从响应中获取token形式的flag Flag 2获取: 利用WebView的JavaScript接口 调用getFlagPath()方法获取flag路径 计算得到路径:48ce217fea4529a070a9d3e3c87db512b1596d413e580f7b2e1eab65f3948ab8.html 拼接完整URL访问获取flag 4. 通用解题技巧总结 静态分析优先 : 使用Jadx等工具反编译APK 搜索关键词如"flag"、"secret"等 重点关注网络请求相关代码 动态分析辅助 : 使用抓包工具分析网络请求 监控Intent跳转和数据传递 观察WebView加载行为 常见漏洞点 : 硬编码的凭证或flag 不安全的WebView配置(如启用JavaScript) 不完善的输入验证 不安全的Intent处理 ADB命令使用 : 通过ADB命令触发特定Intent 测试不同URI和参数组合 加密哈希分析 : 识别代码中的哈希算法(MD5、SHA等) 分析哈希输入构造方式 必要时重新实现哈希计算逻辑